info_elements: add some more PCAPs, 802.11 bugfixing
[netsniff-ng.git] / src / trafgen_parser.y
blobc473e4ae2188f34b706ad2264ab285e7e504b1bd
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"
25 #define YYERROR_VERBOSE 0
26 #define YYDEBUG 0
27 #define YYENABLE_NLS 1
28 #define YYLTYPE_IS_TRIVIAL 1
29 #define ENABLE_NLS 1
31 extern FILE *yyin;
32 extern int yylex(void);
33 extern void yyerror(const char *);
34 extern int yylineno;
35 extern char *yytext;
37 extern struct packet *packets;
38 extern size_t plen;
39 #define packet_last (plen - 1)
40 #define payload_last (packets[packet_last].len - 1)
42 extern struct packet_dyn *packet_dyn;
43 extern size_t dlen;
44 #define packetd_last (dlen - 1)
45 #define packetdc_last (packet_dyn[packetd_last].clen - 1)
46 #define packetdr_last (packet_dyn[packetd_last].rlen - 1)
48 static int dfunc_note_flag = 0;
50 static void give_note_dynamic(void)
52 if (!dfunc_note_flag) {
53 printf("Note: dynamic elements like drnd, dinc, ddec and "
54 "others make trafgen slower!\n");
55 dfunc_note_flag = 1;
59 static inline void init_new_packet_slot(struct packet *slot)
61 slot->payload = NULL;
62 slot->len = 0;
65 static inline void init_new_counter_slot(struct packet_dyn *slot)
67 slot->cnt = NULL;
68 slot->clen = 0;
71 static inline void init_new_randomizer_slot(struct packet_dyn *slot)
73 slot->rnd = NULL;
74 slot->rlen = 0;
77 static void realloc_packet(void)
79 plen++;
80 packets = xrealloc(packets, 1, plen * sizeof(*packets));
81 init_new_packet_slot(&packets[packet_last]);
83 dlen++;
84 packet_dyn = xrealloc(packet_dyn, 1, dlen * sizeof(*packet_dyn));
85 init_new_counter_slot(&packet_dyn[packetd_last]);
86 init_new_randomizer_slot(&packet_dyn[packetd_last]);
89 static void set_byte(uint8_t val)
91 struct packet *pkt = &packets[packet_last];
93 pkt->len++;
94 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
95 pkt->payload[payload_last] = val;
98 static void set_fill(uint8_t val, size_t len)
100 int i;
101 struct packet *pkt = &packets[packet_last];
103 pkt->len += len;
104 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
105 for (i = 0; i < len; ++i)
106 pkt->payload[payload_last - i] = val;
109 static void set_rnd(size_t len)
111 int i;
112 struct packet *pkt = &packets[packet_last];
114 pkt->len += len;
115 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
116 for (i = 0; i < len; ++i)
117 pkt->payload[payload_last - i] = (uint8_t) rand();
120 static void set_seqinc(uint8_t start, size_t len, uint8_t stepping)
122 int i;
123 struct packet *pkt = &packets[packet_last];
125 pkt->len += len;
126 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
127 for (i = 0; i < len; ++i) {
128 off_t off = len - 1 - i;
130 pkt->payload[payload_last - off] = start;
131 start += stepping;
135 static void set_seqdec(uint8_t start, size_t len, uint8_t stepping)
137 int i;
138 struct packet *pkt = &packets[packet_last];
140 pkt->len += len;
141 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
142 for (i = 0; i < len; ++i) {
143 int off = len - 1 - i;
145 pkt->payload[payload_last - off] = start;
146 start -= stepping;
150 static inline void setup_new_counter(struct counter *c, uint8_t start, uint8_t stop,
151 uint8_t stepping, int type)
153 c->min = start;
154 c->max = stop;
155 c->inc = stepping;
156 c->val = (type == TYPE_INC) ? start : stop;
157 c->off = payload_last;
158 c->type = type;
161 static inline void setup_new_randomizer(struct randomizer *r)
163 r->val = (uint8_t) rand();
164 r->off = payload_last;
167 static void set_drnd(void)
169 struct packet *pkt = &packets[packet_last];
170 struct packet_dyn *pktd = &packet_dyn[packetd_last];
172 give_note_dynamic();
174 pkt->len++;
175 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
177 pktd->rlen++;
178 pktd->rnd = xrealloc(pktd->rnd, 1, pktd->rlen * sizeof(struct randomizer));
180 setup_new_randomizer(&pktd->rnd[packetdr_last]);
183 static void set_dincdec(uint8_t start, uint8_t stop, uint8_t stepping, int type)
185 struct packet *pkt = &packets[packet_last];
186 struct packet_dyn *pktd = &packet_dyn[packetd_last];
188 give_note_dynamic();
190 pkt->len++;
191 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
193 pktd->clen++;
194 pktd->cnt =xrealloc(pktd->cnt, 1, pktd->clen * sizeof(struct counter));
196 setup_new_counter(&pktd->cnt[packetdc_last], start, stop, stepping, type);
201 %union {
202 long int number;
205 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC K_WHITE
206 %token K_NEWL
208 %token ',' '{' '}' '(' ')' '[' ']'
210 %token number
212 %type <number> number
216 packets
217 : { }
218 | packets packet { }
219 | packets inline_comment { }
220 | packets white { }
223 inline_comment
224 : K_COMMENT { }
227 packet
228 : '{' delimiter payload delimiter '}' { realloc_packet(); }
231 payload
232 : elem { }
233 | payload elem_delimiter { }
236 white
237 : white K_WHITE { }
238 | white K_NEWL { }
239 | K_WHITE { }
240 | K_NEWL { }
243 delimiter
244 : ',' { }
245 | white { }
246 | ',' white { }
249 elem_delimiter
250 : delimiter elem { }
253 fill
254 : K_FILL '(' number delimiter number ')'
255 { set_fill($3, $5); }
259 : K_RND '(' number ')'
260 { set_rnd($3); }
263 seqinc
264 : K_SEQINC '(' number delimiter number ')'
265 { set_seqinc($3, $5, 1); }
266 | K_SEQINC '(' number delimiter number delimiter number ')'
267 { set_seqinc($3, $5, $7); }
270 seqdec
271 : K_SEQDEC '(' number delimiter number ')'
272 { set_seqdec($3, $5, 1); }
273 | K_SEQDEC '(' number delimiter number delimiter number ')'
274 { set_seqdec($3, $5, $7); }
277 drnd
278 : K_DRND '(' ')'
279 { set_drnd(); }
280 | K_DRND '(' number ')'
282 int i, max = $3;
283 for (i = 0; i < max; ++i)
284 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 static void finalize_packet(void)
318 /* XXX hack ... we allocated one packet pointer too much */
319 plen--;
320 dlen--;
323 static void dump_conf(void)
325 size_t i, j;
327 for (i = 0; i < plen; ++i) {
328 printf("[%zu] pkt\n", i);
329 printf(" len %zu cnts %zu rnds %zu\n",
330 packets[i].len,
331 packet_dyn[i].clen,
332 packet_dyn[i].rlen);
334 printf(" payload ");
335 for (j = 0; j < packets[i].len; ++j)
336 printf("%02x ", packets[i].payload[j]);
337 printf("\n");
339 for (j = 0; j < packet_dyn[i].clen; ++j)
340 printf(" cnt%zu [%u,%u], inc %u, off %ld type %s\n", j,
341 packet_dyn[i].cnt[j].min,
342 packet_dyn[i].cnt[j].max,
343 packet_dyn[i].cnt[j].inc,
344 packet_dyn[i].cnt[j].off,
345 packet_dyn[i].cnt[j].type == TYPE_INC ?
346 "inc" : "dec");
348 for (j = 0; j < packet_dyn[i].rlen; ++j)
349 printf(" rnd%zu off %ld\n", j,
350 packet_dyn[i].rnd[j].off);
354 void cleanup_packets(void)
356 int i;
358 for (i = 0; i < plen; ++i) {
359 if (packets[i].len > 0)
360 xfree(packets[i].payload);
363 free(packets);
365 for (i = 0; i < dlen; ++i) {
366 free(packet_dyn[i].cnt);
367 free(packet_dyn[i].rnd);
370 free(packet_dyn);
373 int compile_packets(char *file, int verbose)
375 yyin = fopen(file, "r");
376 if (!yyin)
377 panic("Cannot open file!\n");
379 realloc_packet();
380 yyparse();
381 finalize_packet();
383 if (verbose) {
384 dump_conf();
385 } else {
386 int i;
387 size_t total_len = 0;
389 printf("%6zu packets to schedule\n", plen);
390 for (i = 0; i < plen; ++i)
391 total_len += packets[i].len;
392 printf("%6zu bytes in total\n", total_len);
395 fclose(yyin);
396 return 0;
399 void yyerror(const char *err)
401 panic("Syntax error at line %d: '%s'! %s!\n", yylineno, yytext, err);