make: add flags and fix some warnings
[netsniff-ng.git] / src / trafgen_parser.y
blobbbd48cddaf61325a2b3b0061bb5629681e7cb5db
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, our_cpu, min_cpu = -1, max_cpu = -1;
50 static inline int test_ignore(void)
52 if (min_cpu < 0 && max_cpu < 0)
53 return 0;
54 else if (max_cpu >= our_cpu && min_cpu <= our_cpu)
55 return 0;
56 else
57 return 1;
60 static void give_note_dynamic(void)
62 if (!dfunc_note_flag) {
63 printf("Note: dynamic elements like drnd, dinc, ddec and "
64 "others make trafgen slower!\n");
65 dfunc_note_flag = 1;
69 static inline void __init_new_packet_slot(struct packet *slot)
71 slot->payload = NULL;
72 slot->len = 0;
75 static inline void __init_new_counter_slot(struct packet_dyn *slot)
77 slot->cnt = NULL;
78 slot->clen = 0;
81 static inline void __init_new_randomizer_slot(struct packet_dyn *slot)
83 slot->rnd = NULL;
84 slot->rlen = 0;
87 static void realloc_packet(void)
89 if (test_ignore())
90 return;
92 plen++;
93 packets = xrealloc(packets, 1, plen * sizeof(*packets));
95 __init_new_packet_slot(&packets[packet_last]);
97 dlen++;
98 packet_dyn = xrealloc(packet_dyn, 1, dlen * sizeof(*packet_dyn));
100 __init_new_counter_slot(&packet_dyn[packetd_last]);
101 __init_new_randomizer_slot(&packet_dyn[packetd_last]);
104 static void set_byte(uint8_t val)
106 struct packet *pkt = &packets[packet_last];
108 if (test_ignore())
109 return;
111 pkt->len++;
112 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
113 pkt->payload[payload_last] = val;
116 static void set_fill(uint8_t val, size_t len)
118 size_t i;
119 struct packet *pkt = &packets[packet_last];
121 if (test_ignore())
122 return;
124 pkt->len += len;
125 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
126 for (i = 0; i < len; ++i)
127 pkt->payload[payload_last - i] = val;
130 static void set_rnd(size_t len)
132 size_t i;
133 struct packet *pkt = &packets[packet_last];
135 if (test_ignore())
136 return;
138 pkt->len += len;
139 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
140 for (i = 0; i < len; ++i)
141 pkt->payload[payload_last - i] = (uint8_t) rand();
144 static void set_seqinc(uint8_t start, size_t len, uint8_t stepping)
146 size_t i;
147 struct packet *pkt = &packets[packet_last];
149 if (test_ignore())
150 return;
152 pkt->len += len;
153 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
154 for (i = 0; i < len; ++i) {
155 off_t off = len - 1 - i;
157 pkt->payload[payload_last - off] = start;
158 start += stepping;
162 static void set_seqdec(uint8_t start, size_t len, uint8_t stepping)
164 size_t i;
165 struct packet *pkt = &packets[packet_last];
167 if (test_ignore())
168 return;
170 pkt->len += len;
171 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
172 for (i = 0; i < len; ++i) {
173 int off = len - 1 - i;
175 pkt->payload[payload_last - off] = start;
176 start -= stepping;
180 static inline void __setup_new_counter(struct counter *c, uint8_t start,
181 uint8_t stop, uint8_t stepping,
182 int type)
184 c->min = start;
185 c->max = stop;
186 c->inc = stepping;
187 c->val = (type == TYPE_INC) ? start : stop;
188 c->off = payload_last;
189 c->type = type;
192 static inline void __setup_new_randomizer(struct randomizer *r)
194 r->val = (uint8_t) rand();
195 r->off = payload_last;
198 static void set_drnd(void)
200 struct packet *pkt = &packets[packet_last];
201 struct packet_dyn *pktd = &packet_dyn[packetd_last];
203 if (test_ignore())
204 return;
206 give_note_dynamic();
208 pkt->len++;
209 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
211 pktd->rlen++;
212 pktd->rnd = xrealloc(pktd->rnd, 1, pktd->rlen * sizeof(struct randomizer));
214 __setup_new_randomizer(&pktd->rnd[packetdr_last]);
217 static void set_dincdec(uint8_t start, uint8_t stop, uint8_t stepping, int type)
219 struct packet *pkt = &packets[packet_last];
220 struct packet_dyn *pktd = &packet_dyn[packetd_last];
222 if (test_ignore())
223 return;
225 give_note_dynamic();
227 pkt->len++;
228 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
230 pktd->clen++;
231 pktd->cnt =xrealloc(pktd->cnt, 1, pktd->clen * sizeof(struct counter));
233 __setup_new_counter(&pktd->cnt[packetdc_last], start, stop, stepping, type);
238 %union {
239 long int number;
242 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC K_WHITE K_CPU
244 %token ',' '{' '}' '(' ')' '[' ']' ':'
246 %token number
248 %type <number> number
252 packets
253 : { }
254 | packets packet { }
255 | packets inline_comment { }
256 | packets K_WHITE { }
259 inline_comment
260 : K_COMMENT { }
263 packet
264 : '{' delimiter payload delimiter '}' {
265 min_cpu = max_cpu = -1;
266 realloc_packet();
268 | K_CPU '(' number ':' number ')' ':' K_WHITE '{' delimiter payload delimiter '}' {
269 min_cpu = $3;
270 max_cpu = $5;
272 if (min_cpu > max_cpu) {
273 int tmp = min_cpu;
274 min_cpu = max_cpu;
275 max_cpu = tmp;
278 realloc_packet();
280 | K_CPU '(' number ')' ':' K_WHITE '{' delimiter payload delimiter '}' {
281 min_cpu = max_cpu = $3;
282 realloc_packet();
286 payload
287 : elem { }
288 | payload elem_delimiter { }
291 delimiter
292 : ',' { }
293 | K_WHITE { }
294 | ',' K_WHITE { }
297 elem_delimiter
298 : delimiter elem { }
301 fill
302 : K_FILL '(' number delimiter number ')'
303 { set_fill($3, $5); }
307 : K_RND '(' number ')'
308 { set_rnd($3); }
311 seqinc
312 : K_SEQINC '(' number delimiter number ')'
313 { set_seqinc($3, $5, 1); }
314 | K_SEQINC '(' number delimiter number delimiter number ')'
315 { set_seqinc($3, $5, $7); }
318 seqdec
319 : K_SEQDEC '(' number delimiter number ')'
320 { set_seqdec($3, $5, 1); }
321 | K_SEQDEC '(' number delimiter number delimiter number ')'
322 { set_seqdec($3, $5, $7); }
325 drnd
326 : K_DRND '(' ')'
327 { set_drnd(); }
328 | K_DRND '(' number ')'
330 int i, max = $3;
331 for (i = 0; i < max; ++i)
332 set_drnd();
336 dinc
337 : K_DINC '(' number delimiter number ')'
338 { set_dincdec($3, $5, 1, TYPE_INC); }
339 | K_DINC '(' number delimiter number delimiter number ')'
340 { set_dincdec($3, $5, $7, TYPE_INC); }
343 ddec
344 : K_DDEC '(' number delimiter number ')'
345 { set_dincdec($3, $5, 1, TYPE_DEC); }
346 | K_DDEC '(' number delimiter number delimiter number ')'
347 { set_dincdec($3, $5, $7, TYPE_DEC); }
350 elem
351 : number { set_byte((uint8_t) $1); }
352 | fill { }
353 | rnd { }
354 | drnd { }
355 | seqinc { }
356 | seqdec { }
357 | dinc { }
358 | ddec { }
359 | inline_comment { }
364 static void finalize_packet(void)
366 /* XXX hack ... we allocated one packet pointer too much */
367 plen--;
368 dlen--;
371 static void dump_conf(void)
373 size_t i, j;
375 for (i = 0; i < plen; ++i) {
376 printf("[%zu] pkt\n", i);
377 printf(" len %zu cnts %zu rnds %zu\n",
378 packets[i].len,
379 packet_dyn[i].clen,
380 packet_dyn[i].rlen);
382 printf(" payload ");
383 for (j = 0; j < packets[i].len; ++j)
384 printf("%02x ", packets[i].payload[j]);
385 printf("\n");
387 for (j = 0; j < packet_dyn[i].clen; ++j)
388 printf(" cnt%zu [%u,%u], inc %u, off %ld type %s\n", j,
389 packet_dyn[i].cnt[j].min,
390 packet_dyn[i].cnt[j].max,
391 packet_dyn[i].cnt[j].inc,
392 packet_dyn[i].cnt[j].off,
393 packet_dyn[i].cnt[j].type == TYPE_INC ?
394 "inc" : "dec");
396 for (j = 0; j < packet_dyn[i].rlen; ++j)
397 printf(" rnd%zu off %ld\n", j,
398 packet_dyn[i].rnd[j].off);
402 void cleanup_packets(void)
404 size_t i;
406 for (i = 0; i < plen; ++i) {
407 if (packets[i].len > 0)
408 xfree(packets[i].payload);
411 free(packets);
413 for (i = 0; i < dlen; ++i) {
414 free(packet_dyn[i].cnt);
415 free(packet_dyn[i].rnd);
418 free(packet_dyn);
421 int compile_packets(char *file, int verbose, int cpu)
423 our_cpu = cpu;
425 yyin = fopen(file, "r");
426 if (!yyin)
427 panic("Cannot open file!\n");
429 realloc_packet();
430 yyparse();
431 finalize_packet();
433 if (our_cpu == 0 && verbose)
434 dump_conf();
436 fclose(yyin);
437 return 0;
440 void yyerror(const char *err)
442 panic("Syntax error at line%d, at char '%s'! %s!\n", yylineno, yytext, err);