proto_80211_mac_hdr.c: complete tclas element
[netsniff-ng.git] / src / trafgen_parser.y
blob573a16213bb0de4e531ee209e3a1b8445c6c304f
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 /* yaac-func-prefix: yy */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <signal.h>
16 #include <stdint.h>
17 #include <errno.h>
19 #include "xmalloc.h"
20 #include "trafgen_parser.tab.h"
21 #include "trafgen_conf.h"
22 #include "built_in.h"
23 #include "die.h"
24 #include "mtrand.h"
26 #define YYERROR_VERBOSE 0
27 #define YYDEBUG 0
28 #define YYENABLE_NLS 1
29 #define YYLTYPE_IS_TRIVIAL 1
30 #define ENABLE_NLS 1
32 extern FILE *yyin;
33 extern int yylex(void);
34 extern void yyerror(const char *);
35 extern int yylineno;
36 extern char *yytext;
38 extern struct packet *packets;
39 extern unsigned int packets_len;
40 #define packets_last (packets_len - 1)
41 #define payload_last (packets[packets_last].len - 1)
43 extern struct packet_dynamics *packet_dyns;
44 extern unsigned int packet_dyn_len;
45 #define packetds_last (packet_dyn_len - 1)
46 #define packetds_c_last (packet_dyns[packetds_last].counter_len - 1)
47 #define packetds_r_last (packet_dyns[packetds_last].randomizer_len - 1)
49 static int dfunc_note_flag = 0;
51 static void give_note_dynamic(void)
53 if (!dfunc_note_flag) {
54 printf("Note: dynamic elements like drnd, dinc, ddec and "
55 "others make trafgen slower!\n");
56 dfunc_note_flag = 1;
60 static inline void init_new_packet_slot(struct packet *slot)
62 slot->payload = NULL;
63 slot->len = 0;
66 static inline void init_new_counter_slot(struct packet_dynamics *slot)
68 slot->counter = NULL;
69 slot->counter_len = 0;
72 static inline void init_new_randomizer_slot(struct packet_dynamics *slot)
74 slot->randomizer = NULL;
75 slot->randomizer_len = 0;
78 static void realloc_packet(void)
80 packets_len++;
81 packets = xrealloc(packets, 1, packets_len * sizeof(*packets));
83 init_new_packet_slot(&packets[packets_last]);
85 packet_dyn_len++;
86 packet_dyns = xrealloc(packet_dyns, 1,
87 packet_dyn_len * sizeof(*packet_dyns));
89 init_new_counter_slot(&packet_dyns[packetds_last]);
90 init_new_randomizer_slot(&packet_dyns[packetds_last]);
93 static void set_byte(uint8_t val)
95 packets[packets_last].len++;
96 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
97 1, packets[packets_last].len);
98 packets[packets_last].payload[payload_last] = val;
101 static void set_fill(uint8_t val, size_t len)
103 int i;
105 packets[packets_last].len += len;
106 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
107 1, packets[packets_last].len);
108 for (i = 0; i < len; ++i)
109 packets[packets_last].payload[payload_last - i] = val;
112 static void set_rnd(size_t len)
114 int i;
116 packets[packets_last].len += len;
117 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
118 1, packets[packets_last].len);
119 for (i = 0; i < len; ++i)
120 packets[packets_last].payload[payload_last - i] =
121 (uint8_t) mt_rand_int32();
124 static void set_seqinc(uint8_t start, size_t len, uint8_t stepping)
126 int i;
128 packets[packets_last].len += len;
129 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
130 1, packets[packets_last].len);
131 for (i = 0; i < len; ++i) {
132 int off = len - 1 - i;
133 packets[packets_last].payload[payload_last - off] = start;
134 start += stepping;
138 static void set_seqdec(uint8_t start, size_t len, uint8_t stepping)
140 int i;
142 packets[packets_last].len += len;
143 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
144 1, packets[packets_last].len);
145 for (i = 0; i < len; ++i) {
146 int off = len - 1 - i;
147 packets[packets_last].payload[payload_last - off] = start;
148 start -= stepping;
152 static inline void setup_new_counter(struct counter *counter, uint8_t start,
153 uint8_t stop, uint8_t stepping, int type)
155 counter->min = start;
156 counter->max = stop;
157 counter->inc = stepping;
158 counter->val = (type == TYPE_INC) ? start : stop;
159 counter->off = payload_last;
160 counter->type = type;
163 static inline void setup_new_randomizer(struct randomizer *randomizer)
165 randomizer->val = (uint8_t) mt_rand_int32();
166 randomizer->off = payload_last;
169 static void set_drnd(void)
171 give_note_dynamic();
173 packets[packets_last].len++;
174 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
175 1, packets[packets_last].len);
177 packet_dyns[packetds_last].randomizer_len++;
178 packet_dyns[packetds_last].randomizer =
179 xrealloc(packet_dyns[packetds_last].randomizer, 1,
180 packet_dyns[packetds_last].randomizer_len *
181 sizeof(struct randomizer));
183 setup_new_randomizer(&packet_dyns[packetds_last].
184 randomizer[packetds_r_last]);
187 static void set_dincdec(uint8_t start, uint8_t stop, uint8_t stepping, int type)
189 give_note_dynamic();
191 packets[packets_last].len++;
192 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
193 1, packets[packets_last].len);
195 packet_dyns[packetds_last].counter_len++;
196 packet_dyns[packetds_last].counter =
197 xrealloc(packet_dyns[packetds_last].counter, 1,
198 packet_dyns[packetds_last].counter_len *
199 sizeof(struct counter));
201 setup_new_counter(&packet_dyns[packetds_last].counter[packetds_c_last],
202 start, stop, stepping, type);
207 %union {
208 long int number;
211 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC K_WHITE
212 %token K_NEWL
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 { }
226 | packets white { }
229 inline_comment
230 : K_COMMENT { }
233 packet
234 : '{' delimiter payload delimiter '}' { realloc_packet(); }
237 payload
238 : elem { }
239 | payload elem_delimiter { }
242 white
243 : white K_WHITE { }
244 | white K_NEWL { }
245 | K_WHITE { }
246 | K_NEWL { }
249 delimiter
250 : ',' { }
251 | white { }
252 | ',' white { }
255 elem_delimiter
256 : delimiter elem { }
259 number
260 : number_dec { $$ = $1; }
261 | number_hex { $$ = $1; }
262 | number_ascii { $$ = $1; }
263 | number_bin { $$ = $1; }
264 | number_oct { $$ = $1; }
267 fill
268 : K_FILL '(' number delimiter number ')'
269 { set_fill($3, $5); }
273 : K_RND '(' number ')'
274 { set_rnd($3); }
277 seqinc
278 : K_SEQINC '(' number delimiter number ')'
279 { set_seqinc($3, $5, 1); }
280 | K_SEQINC '(' number delimiter number delimiter number ')'
281 { set_seqinc($3, $5, $7); }
284 seqdec
285 : K_SEQDEC '(' number delimiter number ')'
286 { set_seqdec($3, $5, 1); }
287 | K_SEQDEC '(' number delimiter number delimiter number ')'
288 { set_seqdec($3, $5, $7); }
291 drnd
292 : K_DRND '(' ')'
293 { set_drnd(); }
294 | K_DRND '(' number ')'
296 int i, max = $3;
297 for (i = 0; i < max; ++i)
298 set_drnd();
302 dinc
303 : K_DINC '(' number delimiter number ')'
304 { set_dincdec($3, $5, 1, TYPE_INC); }
305 | K_DINC '(' number delimiter number delimiter number ')'
306 { set_dincdec($3, $5, $7, TYPE_INC); }
309 ddec
310 : K_DDEC '(' number delimiter number ')'
311 { set_dincdec($3, $5, 1, TYPE_DEC); }
312 | K_DDEC '(' number delimiter number delimiter number ')'
313 { set_dincdec($3, $5, $7, TYPE_DEC); }
316 elem
317 : number { set_byte((uint8_t) $1); }
318 | fill { }
319 | rnd { }
320 | drnd { }
321 | seqinc { }
322 | seqdec { }
323 | dinc { }
324 | ddec { }
325 | inline_comment { }
330 static void finalize_packet(void)
332 /* XXX hack ... we allocated one packet pointer too much */
333 packets_len--;
334 packet_dyn_len--;
337 static void dump_conf(void)
339 size_t i, j;
341 for (i = 0; i < packets_len; ++i) {
342 printf("[%zu] pkt\n", i);
343 printf(" len %zu cnts %zu rnds %zu\n",
344 packets[i].len,
345 packet_dyns[i].counter_len,
346 packet_dyns[i].randomizer_len);
348 printf(" payload ");
349 for (j = 0; j < packets[i].len; ++j)
350 printf("%02x ", packets[i].payload[j]);
351 printf("\n");
353 for (j = 0; j < packet_dyns[i].counter_len; ++j)
354 printf(" cnt%zu [%u,%u], inc %u, off %ld type %s\n", j,
355 packet_dyns[i].counter[j].min,
356 packet_dyns[i].counter[j].max,
357 packet_dyns[i].counter[j].inc,
358 packet_dyns[i].counter[j].off,
359 packet_dyns[i].counter[j].type == TYPE_INC ?
360 "inc" : "dec");
362 for (j = 0; j < packet_dyns[i].randomizer_len; ++j)
363 printf(" rnd%zu off %ld\n", j,
364 packet_dyns[i].randomizer[j].off);
368 void cleanup_packets(void)
370 int i;
372 for (i = 0; i < packets_len; ++i) {
373 if (packets[i].len > 0)
374 xfree(packets[i].payload);
377 if (packets_len > 0)
378 xfree(packets);
380 for (i = 0; i < packet_dyn_len; ++i) {
381 if (packet_dyns[i].counter_len > 0)
382 xfree(packet_dyns[i].counter);
384 if (packet_dyns[i].randomizer_len > 0)
385 xfree(packet_dyns[i].randomizer);
388 if (packet_dyn_len > 0)
389 xfree(packet_dyns);
392 int compile_packets(char *file, int verbose)
394 mt_init_by_seed_time();
396 yyin = fopen(file, "r");
397 if (!yyin)
398 panic("Cannot open file!\n");
400 realloc_packet();
401 yyparse();
402 finalize_packet();
404 if (verbose) {
405 dump_conf();
406 } else {
407 int i;
408 size_t total_len = 0;
410 printf("%u packets to schedule\n", packets_len);
411 for (i = 0; i < packets_len; ++i)
412 total_len += packets[i].len;
413 printf("%zu bytes in total\n", total_len);
416 fclose(yyin);
417 return 0;
420 void yyerror(const char *err)
422 panic("Syntax error at line %d: '%s'! %s!\n", yylineno, yytext, err);