trafgen: be non-verbose on default
[netsniff-ng-old.git] / src / trafgen_parser.y
blobbcc75189dc8f70c28b5f190aec8553b214eaf6e8
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 K_WHITE
213 %token K_NEWL
215 %token ',' '{' '}' '(' ')' '[' ']'
217 %token number_hex number_dec number_ascii number_bin number_oct
219 %type <number> number_hex number_dec number_ascii number_bin number_oct number
223 packets
224 : { }
225 | packets packet { }
226 | packets inline_comment { }
227 | packets white { }
230 inline_comment
231 : K_COMMENT { }
234 packet
235 : '{' delimiter payload delimiter '}' { realloc_packet(); }
238 payload
239 : elem { }
240 | payload elem_delimiter { }
243 white
244 : white K_WHITE
245 | white K_NEWL
246 | K_WHITE
247 | K_NEWL
250 delimiter
251 : ','
252 | white
253 | ',' white
256 elem_delimiter
257 : delimiter elem { }
260 number
261 : number_dec { $$ = $1; }
262 | number_hex { $$ = $1; }
263 | number_ascii { $$ = $1; }
264 | number_bin { $$ = $1; }
265 | number_oct { $$ = $1; }
268 fill
269 : K_FILL '(' number delimiter number ')'
270 { set_fill($3, $5); }
274 : K_RND '(' number ')'
275 { set_rnd($3); }
278 seqinc
279 : K_SEQINC '(' number delimiter number ')'
280 { set_seqinc($3, $5, 1); }
281 | K_SEQINC '(' number delimiter number delimiter number ')'
282 { set_seqinc($3, $5, $7); }
285 seqdec
286 : K_SEQDEC '(' number delimiter number ')'
287 { set_seqdec($3, $5, 1); }
288 | K_SEQDEC '(' number delimiter number delimiter number ')'
289 { set_seqdec($3, $5, $7); }
292 drnd
293 : K_DRND '(' ')'
294 { set_drnd(); }
297 dinc
298 : K_DINC '(' number delimiter number ')'
299 { set_dincdec($3, $5, 1, TYPE_INC); }
300 | K_DINC '(' number delimiter number delimiter number ')'
301 { set_dincdec($3, $5, $7, TYPE_INC); }
304 ddec
305 : K_DDEC '(' number delimiter number ')'
306 { set_dincdec($3, $5, 1, TYPE_DEC); }
307 | K_DDEC '(' number delimiter number delimiter number ')'
308 { set_dincdec($3, $5, $7, TYPE_DEC); }
311 elem
312 : number { set_byte((uint8_t) $1); }
313 | fill { }
314 | rnd { }
315 | drnd { }
316 | seqinc { }
317 | seqdec { }
318 | dinc { }
319 | ddec { }
320 | inline_comment { }
325 int compile_packets(char *file, struct pktconf *cfg, int verbose)
327 yyin = fopen(file, "r");
328 if (!yyin)
329 panic("Cannot open file!\n");
330 if (!cfg)
331 panic("No config given!\n");
333 mt_init_by_seed_time();
334 conf = cfg;
335 realloc_packet();
337 yyparse();
338 /* hack ... */
339 conf->len--;
341 if (verbose)
342 dump_conf(cfg);
343 else {
344 int i;
345 size_t total_len = 0;
347 printf("%zu packets to schedule\n", conf->len);
349 for (i = 0; i < conf->len; ++i)
350 total_len += conf->pkts[i].plen;
351 printf("%zu bytes in total\n", total_len);
354 fclose(yyin);
355 return 0;
358 void yyerror(const char *err)
360 panic("Syntax error at line %d: '%s'! %s!\n",
361 yylineno, yytext, err);