parser: trafgen: rnd, fill, number working
[netsniff-ng.git] / src / trafgen_parser.y
blob32075495bde40ea4545fcf66d32c2355f8fe25a8
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2012 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
5 * Swiss federal institute of technology (ETH Zurich)
6 * Subject to the GPL, version 2.
7 */
9 %{
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <signal.h>
14 #include <stdint.h>
15 #include <errno.h>
17 #include "xmalloc.h"
18 #include "trafgen_parser.tab.h"
19 #include "trafgen_conf.h"
20 #include "built_in.h"
21 #include "die.h"
22 #include "mtrand.h"
24 #define YYERROR_VERBOSE 0
25 #define YYDEBUG 0
26 #define YYENABLE_NLS 1
27 #define YYLTYPE_IS_TRIVIAL 1
28 #define ENABLE_NLS 1
30 extern FILE *yyin;
31 extern int yylex(void);
32 extern void yyerror(const char *);
33 extern int yylineno;
34 extern char *yytext;
36 static struct pktconf *conf = NULL;
38 #define am(x) ((x)->len - 1)
40 static void dump_conf(struct pktconf *cfg)
42 size_t i, j;
44 printf("n %lu, gap %lu us, pkts %zu\n", cfg->num, cfg->gap, cfg->len);
45 if (cfg->len == 0)
46 return;
47 for (i = 0; i < cfg->len; ++i) {
48 printf("[%zu] pkt\n", i);
49 printf(" len %zu cnts %zu rnds %zu\n", cfg->pkts[i].plen,
50 cfg->pkts[i].clen, cfg->pkts[i].rlen);
51 printf(" payload ");
52 for (j = 0; j < cfg->pkts[i].plen; ++j)
53 printf("%02x ", cfg->pkts[i].payload[j]);
54 printf("\n");
55 for (j = 0; j < cfg->pkts[i].clen; ++j)
56 printf(" cnt%zu [%u,%u], inc %u, off %ld\n",
57 j, cfg->pkts[i].cnt[j].min,
58 cfg->pkts[i].cnt[j].max,
59 cfg->pkts[i].cnt[j].inc,
60 cfg->pkts[i].cnt[j].off);
61 for (j = 0; j < cfg->pkts[i].rlen; ++j)
62 printf(" rnd%zu off %ld\n",
63 j, cfg->pkts[i].rnd[j].off);
67 static void realloc_packet(void)
69 conf->len++;
70 conf->pkts = xrealloc(conf->pkts, 1, conf->len * sizeof(*conf->pkts));
71 fmemset(&conf->pkts[am(conf)], 0, sizeof(conf->pkts[am(conf)]));
74 static void set_byte(uint8_t val)
76 conf->pkts[am(conf)].plen++;
77 conf->pkts[am(conf)].payload = xrealloc(conf->pkts[am(conf)].payload,
78 1, conf->pkts[am(conf)].plen);
80 conf->pkts[am(conf)].payload[conf->pkts[am(conf)].plen - 1] = val;
83 static void set_fill(uint8_t val, size_t len)
85 int i;
87 conf->pkts[am(conf)].plen += len;
88 conf->pkts[am(conf)].payload = xrealloc(conf->pkts[am(conf)].payload,
89 1, conf->pkts[am(conf)].plen);
91 for (i = 0; i < len; ++i) {
92 conf->pkts[am(conf)].
93 payload[conf->pkts[am(conf)].plen - 1 - i] = val;
97 static void set_rnd(size_t len)
99 int i;
101 conf->pkts[am(conf)].plen += len;
102 conf->pkts[am(conf)].payload = xrealloc(conf->pkts[am(conf)].payload,
103 1, conf->pkts[am(conf)].plen);
105 for (i = 0; i < len; ++i) {
106 conf->pkts[am(conf)].
107 payload[conf->pkts[am(conf)].plen - 1 - i] =
108 (uint8_t) mt_rand_int32();
116 %union {
117 long int number;
120 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC
122 %token ' ' ',' '{' '}' '(' ')' '[' ']'
124 %token number_hex number_dec number_ascii number_bin number_oct
126 %type <number> number_hex number_dec number_ascii number_bin number_oct number
130 packets
131 : { }
132 | packets packet { }
133 | packets inline_comment { }
136 inline_comment
137 : K_COMMENT { }
140 packet
141 : '{' ' ' payload ' ' '}' { realloc_packet(); }
144 payload
145 : elem { }
146 | payload elem_delimiter { }
149 delimiter
150 : ','
151 | ' '
152 | ',' ' '
155 elem_delimiter
156 : delimiter elem { }
159 number
160 : number_dec { $$ = $1; }
161 | number_hex { $$ = $1; }
162 | number_ascii { $$ = $1; }
163 | number_bin { $$ = $1; }
164 | number_oct { $$ = $1; }
167 fill
168 : K_FILL '(' number delimiter number ')' { set_fill($3, $5); }
172 : K_RND '(' number ')' { set_rnd($3); }
175 drnd
176 : K_DRND '(' number ')'
177 { printf("Drnd times %u\n", $3); }
180 seqinc
181 : K_SEQINC '(' number delimiter number ')'
182 { printf("Seqinc from %u times %u\n", $3, $5); }
183 | K_SEQINC '(' number delimiter number delimiter number ')'
184 { printf("Seqinc from %u times %u steps %u\n", $3, $5, $7); }
187 seqdec
188 : K_SEQDEC '(' number delimiter number ')'
189 { printf("Seqdec from %u times %u\n", $3, $5); }
190 | K_SEQDEC '(' number delimiter number delimiter number ')'
191 { printf("Seqdec from %u times %u steps %u\n", $3, $5, $7); }
194 dinc
195 : K_DINC '(' number delimiter number ')'
196 { printf("Dinc from %u to %u\n", $3, $5); }
197 | K_DINC '(' number delimiter number delimiter number ')'
198 { printf("Seqinc from %u to %u stepping %u\n", $3, $5, $7); }
201 ddec
202 : K_DDEC '(' number delimiter number ')'
203 { printf("Ddec from %u to %u\n", $3, $5); }
204 | K_DDEC '(' number delimiter number delimiter number ')'
205 { printf("Ddec from %u to %u stepping %u\n", $3, $5, $7); }
208 elem
209 : number { set_byte((uint8_t) $1); }
210 | fill { }
211 | rnd { }
212 | drnd { }
213 | seqinc { }
214 | seqdec { }
215 | dinc { }
216 | ddec { }
217 | inline_comment { }
222 int compile_packets(char *file, struct pktconf *cfg, int verbose)
224 yyin = fopen(file, "r");
225 if (!yyin)
226 panic("Cannot open file!\n");
227 if (!cfg)
228 panic("No config given!\n");
230 mt_init_by_seed_time();
231 conf = cfg;
232 realloc_packet();
234 yyparse();
235 /* hack ... */
236 conf->len--;
238 if (verbose)
239 dump_conf(cfg);
241 fclose(yyin);
242 return 0;
245 void yyerror(const char *err)
247 panic("Syntax error at line %d: '%s'! %s!\n",
248 yylineno, yytext, err);