trafgen: first version with new parser
[netsniff-ng.git] / src / trafgen_parser.y
blob94d86649683b83feabbfb972b126152fd852045a
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;
37 static int note_flag = 0;
39 #define am(x) ((x)->len - 1)
41 static void give_note_dynamic(void)
43 if (!note_flag) {
44 printf("Note: dynamic elements like drnd, dinc, ddec and "
45 "others make trafgen slower!\n");
46 note_flag = 1;
50 static void dump_conf(struct pktconf *cfg)
52 size_t i, j;
54 printf("n %lu, gap %lu us, pkts %zu\n", cfg->num, cfg->gap, cfg->len);
55 if (cfg->len == 0)
56 return;
57 for (i = 0; i < cfg->len; ++i) {
58 printf("[%zu] pkt\n", i);
59 printf(" len %zu cnts %zu rnds %zu\n", cfg->pkts[i].plen,
60 cfg->pkts[i].clen, cfg->pkts[i].rlen);
61 printf(" payload ");
62 for (j = 0; j < cfg->pkts[i].plen; ++j)
63 printf("%02x ", cfg->pkts[i].payload[j]);
64 printf("\n");
65 for (j = 0; j < cfg->pkts[i].clen; ++j)
66 printf(" cnt%zu [%u,%u], inc %u, off %ld type %s\n",
67 j, cfg->pkts[i].cnt[j].min,
68 cfg->pkts[i].cnt[j].max,
69 cfg->pkts[i].cnt[j].inc,
70 cfg->pkts[i].cnt[j].off,
71 cfg->pkts[i].cnt[j].type == TYPE_INC ?
72 "inc" : "dec");
73 for (j = 0; j < cfg->pkts[i].rlen; ++j)
74 printf(" rnd%zu off %ld\n",
75 j, cfg->pkts[i].rnd[j].off);
79 static void realloc_packet(void)
81 conf->len++;
82 conf->pkts = xrealloc(conf->pkts, 1, conf->len * sizeof(*conf->pkts));
83 fmemset(&conf->pkts[am(conf)], 0, sizeof(conf->pkts[am(conf)]));
86 static void set_byte(uint8_t val)
88 int base;
90 conf->pkts[am(conf)].plen++;
91 conf->pkts[am(conf)].payload = xrealloc(conf->pkts[am(conf)].payload,
92 1, conf->pkts[am(conf)].plen);
94 base = conf->pkts[am(conf)].plen - 1;
95 conf->pkts[am(conf)].payload[base] = val;
98 static void set_fill(uint8_t val, size_t len)
100 int i, base;
102 conf->pkts[am(conf)].plen += len;
103 conf->pkts[am(conf)].payload = xrealloc(conf->pkts[am(conf)].payload,
104 1, conf->pkts[am(conf)].plen);
106 base = conf->pkts[am(conf)].plen - 1;
107 for (i = 0; i < len; ++i) {
108 conf->pkts[am(conf)].payload[base - i] = val;
112 static void set_rnd(size_t len)
114 int i, base;
116 conf->pkts[am(conf)].plen += len;
117 conf->pkts[am(conf)].payload = xrealloc(conf->pkts[am(conf)].payload,
118 1, conf->pkts[am(conf)].plen);
120 base = conf->pkts[am(conf)].plen - 1;
121 for (i = 0; i < len; ++i) {
122 conf->pkts[am(conf)].payload[base - i] = (uint8_t) mt_rand_int32();
126 static void set_seqinc(uint8_t start, size_t len, uint8_t stepping)
128 int i, base;
130 conf->pkts[am(conf)].plen += len;
131 conf->pkts[am(conf)].payload = xrealloc(conf->pkts[am(conf)].payload,
132 1, conf->pkts[am(conf)].plen);
134 base = conf->pkts[am(conf)].plen - 1;
135 for (i = 0; i < len; ++i) {
136 int off = len - 1 - i;
137 conf->pkts[am(conf)].payload[base - off] = start;
138 start += stepping;
142 static void set_seqdec(uint8_t start, size_t len, uint8_t stepping)
144 int i, base;
146 conf->pkts[am(conf)].plen += len;
147 conf->pkts[am(conf)].payload = xrealloc(conf->pkts[am(conf)].payload,
148 1, conf->pkts[am(conf)].plen);
150 base = conf->pkts[am(conf)].plen - 1;
151 for (i = 0; i < len; ++i) {
152 int off = len - 1 - i;
153 conf->pkts[am(conf)].payload[base - off] = start;
154 start -= stepping;
158 static void set_drnd(void)
160 int base, rnds;
161 struct randomizer *new;
163 give_note_dynamic();
165 conf->pkts[am(conf)].plen++;
166 conf->pkts[am(conf)].payload = xrealloc(conf->pkts[am(conf)].payload,
167 1, conf->pkts[am(conf)].plen);
169 base = conf->pkts[am(conf)].plen - 1;
170 rnds = ++(conf->pkts[am(conf)].rlen);
172 conf->pkts[am(conf)].rnd = xrealloc(conf->pkts[am(conf)].rnd,
173 1, rnds * sizeof(struct randomizer));
175 new = &conf->pkts[am(conf)].rnd[rnds - 1];
176 new->val = (uint8_t) mt_rand_int32();
177 new->off = base;
180 static void set_dincdec(uint8_t start, uint8_t stop, uint8_t stepping, int type)
182 int base, cnts;
183 struct counter *new;
185 give_note_dynamic();
187 conf->pkts[am(conf)].plen++;
188 conf->pkts[am(conf)].payload = xrealloc(conf->pkts[am(conf)].payload,
189 1, conf->pkts[am(conf)].plen);
191 base = conf->pkts[am(conf)].plen - 1;
192 cnts = ++(conf->pkts[am(conf)].clen);
194 conf->pkts[am(conf)].cnt = xrealloc(conf->pkts[am(conf)].cnt,
195 1, cnts * sizeof(struct counter));
197 new = &conf->pkts[am(conf)].cnt[cnts - 1];
198 new->min = start;
199 new->max = stop;
200 new->inc = stepping;
201 new->val = type == TYPE_INC ? start : stop;
202 new->off = base;
203 new->type = type;
208 %union {
209 long int number;
212 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC
214 %token ' ' ',' '{' '}' '(' ')' '[' ']'
216 %token number_hex number_dec number_ascii number_bin number_oct
218 %type <number> number_hex number_dec number_ascii number_bin number_oct number
222 packets
223 : { }
224 | packets packet { }
225 | packets inline_comment { }
228 inline_comment
229 : K_COMMENT { }
232 packet
233 : '{' ' ' payload ' ' '}' { realloc_packet(); }
236 payload
237 : elem { }
238 | payload elem_delimiter { }
241 delimiter
242 : ','
243 | ' '
244 | ',' ' '
247 elem_delimiter
248 : delimiter elem { }
251 number
252 : number_dec { $$ = $1; }
253 | number_hex { $$ = $1; }
254 | number_ascii { $$ = $1; }
255 | number_bin { $$ = $1; }
256 | number_oct { $$ = $1; }
259 fill
260 : K_FILL '(' number delimiter number ')'
261 { set_fill($3, $5); }
265 : K_RND '(' number ')'
266 { set_rnd($3); }
269 seqinc
270 : K_SEQINC '(' number delimiter number ')'
271 { set_seqinc($3, $5, 1); }
272 | K_SEQINC '(' number delimiter number delimiter number ')'
273 { set_seqinc($3, $5, $7); }
276 seqdec
277 : K_SEQDEC '(' number delimiter number ')'
278 { set_seqdec($3, $5, 1); }
279 | K_SEQDEC '(' number delimiter number delimiter number ')'
280 { set_seqdec($3, $5, $7); }
283 drnd
284 : K_DRND '(' ')'
285 { set_drnd(); }
288 dinc
289 : K_DINC '(' number delimiter number ')'
290 { set_dincdec($3, $5, 1, TYPE_INC); }
291 | K_DINC '(' number delimiter number delimiter number ')'
292 { set_dincdec($3, $5, $7, TYPE_INC); }
295 ddec
296 : K_DDEC '(' number delimiter number ')'
297 { set_dincdec($3, $5, 1, TYPE_DEC); }
298 | K_DDEC '(' number delimiter number delimiter number ')'
299 { set_dincdec($3, $5, $7, TYPE_DEC); }
302 elem
303 : number { set_byte((uint8_t) $1); }
304 | fill { }
305 | rnd { }
306 | drnd { }
307 | seqinc { }
308 | seqdec { }
309 | dinc { }
310 | ddec { }
311 | inline_comment { }
316 int compile_packets(char *file, struct pktconf *cfg, int verbose)
318 yyin = fopen(file, "r");
319 if (!yyin)
320 panic("Cannot open file!\n");
321 if (!cfg)
322 panic("No config given!\n");
324 mt_init_by_seed_time();
325 conf = cfg;
326 realloc_packet();
328 yyparse();
329 /* hack ... */
330 conf->len--;
332 if (verbose)
333 dump_conf(cfg);
335 fclose(yyin);
336 return 0;
339 void yyerror(const char *err)
341 panic("Syntax error at line %d: '%s'! %s!\n",
342 yylineno, yytext, err);