trafgen: add csum calculation, fix deadlock
[netsniff-ng.git] / src / trafgen_parser.y
blobc546a339765b9ed1e0d0bce8e1f617e62b593fec
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 "csum.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 size_t plen;
40 #define packet_last (plen - 1)
41 #define payload_last (packets[packet_last].len - 1)
43 extern struct packet_dyn *packet_dyn;
44 extern size_t dlen;
45 #define packetd_last (dlen - 1)
46 #define packetdc_last (packet_dyn[packetd_last].clen - 1)
47 #define packetdr_last (packet_dyn[packetd_last].rlen - 1)
49 static int dfunc_note_flag = 0, our_cpu, min_cpu = -1, max_cpu = -1;
51 static inline int test_ignore(void)
53 if (min_cpu < 0 && max_cpu < 0)
54 return 0;
55 else if (max_cpu >= our_cpu && min_cpu <= our_cpu)
56 return 0;
57 else
58 return 1;
61 static void give_note_dynamic(void)
63 if (!dfunc_note_flag) {
64 printf("Note: dynamic elements like drnd, dinc, ddec and "
65 "others make trafgen slower!\n");
66 dfunc_note_flag = 1;
70 static inline void __init_new_packet_slot(struct packet *slot)
72 slot->payload = NULL;
73 slot->len = 0;
76 static inline void __init_new_counter_slot(struct packet_dyn *slot)
78 slot->cnt = NULL;
79 slot->clen = 0;
82 static inline void __init_new_randomizer_slot(struct packet_dyn *slot)
84 slot->rnd = NULL;
85 slot->rlen = 0;
88 static void realloc_packet(void)
90 if (test_ignore())
91 return;
93 plen++;
94 packets = xrealloc(packets, 1, plen * sizeof(*packets));
96 __init_new_packet_slot(&packets[packet_last]);
98 dlen++;
99 packet_dyn = xrealloc(packet_dyn, 1, dlen * sizeof(*packet_dyn));
101 __init_new_counter_slot(&packet_dyn[packetd_last]);
102 __init_new_randomizer_slot(&packet_dyn[packetd_last]);
105 static void set_byte(uint8_t val)
107 struct packet *pkt = &packets[packet_last];
109 if (test_ignore())
110 return;
112 pkt->len++;
113 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
114 pkt->payload[payload_last] = val;
117 static void set_fill(uint8_t val, size_t len)
119 size_t i;
120 struct packet *pkt = &packets[packet_last];
122 if (test_ignore())
123 return;
125 pkt->len += len;
126 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
127 for (i = 0; i < len; ++i)
128 pkt->payload[payload_last - i] = val;
131 static void set_csum16(size_t from, size_t to)
133 struct packet *pkt = &packets[packet_last];
134 uint16_t sum;
135 uint8_t *psum;
137 if (test_ignore())
138 return;
140 if (to < from) {
141 size_t tmp = to;
143 to = from;
144 from = tmp;
147 bug_on(!(from < to));
149 if (to >= pkt->len)
150 to = pkt->len - 1;
152 sum = htons(calc_csum(pkt->payload + from, to - from, 0));
153 psum = (uint8_t *) &sum;
155 set_byte(psum[0]);
156 set_byte(psum[1]);
159 static void set_rnd(size_t len)
161 size_t i;
162 struct packet *pkt = &packets[packet_last];
164 if (test_ignore())
165 return;
167 pkt->len += len;
168 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
169 for (i = 0; i < len; ++i)
170 pkt->payload[payload_last - i] = (uint8_t) rand();
173 static void set_seqinc(uint8_t start, size_t len, uint8_t stepping)
175 size_t i;
176 struct packet *pkt = &packets[packet_last];
178 if (test_ignore())
179 return;
181 pkt->len += len;
182 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
183 for (i = 0; i < len; ++i) {
184 off_t off = len - 1 - i;
186 pkt->payload[payload_last - off] = start;
187 start += stepping;
191 static void set_seqdec(uint8_t start, size_t len, uint8_t stepping)
193 size_t i;
194 struct packet *pkt = &packets[packet_last];
196 if (test_ignore())
197 return;
199 pkt->len += len;
200 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
201 for (i = 0; i < len; ++i) {
202 int off = len - 1 - i;
204 pkt->payload[payload_last - off] = start;
205 start -= stepping;
209 static inline void __setup_new_counter(struct counter *c, uint8_t start,
210 uint8_t stop, uint8_t stepping,
211 int type)
213 c->min = start;
214 c->max = stop;
215 c->inc = stepping;
216 c->val = (type == TYPE_INC) ? start : stop;
217 c->off = payload_last;
218 c->type = type;
221 static inline void __setup_new_randomizer(struct randomizer *r)
223 r->val = (uint8_t) rand();
224 r->off = payload_last;
227 static void set_drnd(void)
229 struct packet *pkt = &packets[packet_last];
230 struct packet_dyn *pktd = &packet_dyn[packetd_last];
232 if (test_ignore())
233 return;
235 give_note_dynamic();
237 pkt->len++;
238 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
240 pktd->rlen++;
241 pktd->rnd = xrealloc(pktd->rnd, 1, pktd->rlen * sizeof(struct randomizer));
243 __setup_new_randomizer(&pktd->rnd[packetdr_last]);
246 static void set_dincdec(uint8_t start, uint8_t stop, uint8_t stepping, int type)
248 struct packet *pkt = &packets[packet_last];
249 struct packet_dyn *pktd = &packet_dyn[packetd_last];
251 if (test_ignore())
252 return;
254 give_note_dynamic();
256 pkt->len++;
257 pkt->payload = xrealloc(pkt->payload, 1, pkt->len);
259 pktd->clen++;
260 pktd->cnt =xrealloc(pktd->cnt, 1, pktd->clen * sizeof(struct counter));
262 __setup_new_counter(&pktd->cnt[packetdc_last], start, stop, stepping, type);
267 %union {
268 long int number;
271 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC K_WHITE
272 %token K_CPU K_CSUM16
274 %token ',' '{' '}' '(' ')' '[' ']' ':'
276 %token number
278 %type <number> number
282 packets
283 : { }
284 | packets packet { }
285 | packets inline_comment { }
286 | packets K_WHITE { }
289 inline_comment
290 : K_COMMENT { }
293 packet
294 : '{' delimiter payload delimiter '}' {
295 min_cpu = max_cpu = -1;
296 realloc_packet();
298 | K_CPU '(' number ':' number ')' ':' K_WHITE '{' delimiter payload delimiter '}' {
299 min_cpu = $3;
300 max_cpu = $5;
302 if (min_cpu > max_cpu) {
303 int tmp = min_cpu;
305 min_cpu = max_cpu;
306 max_cpu = tmp;
309 realloc_packet();
311 | K_CPU '(' number ')' ':' K_WHITE '{' delimiter payload delimiter '}' {
312 min_cpu = max_cpu = $3;
313 realloc_packet();
317 payload
318 : elem { }
319 | payload elem_delimiter { }
322 delimiter
323 : ',' { }
324 | K_WHITE { }
325 | ',' K_WHITE { }
328 elem_delimiter
329 : delimiter elem { }
332 elem
333 : number { set_byte((uint8_t) $1); }
334 | fill { }
335 | rnd { }
336 | drnd { }
337 | seqinc { }
338 | seqdec { }
339 | dinc { }
340 | ddec { }
341 | csum { }
342 | inline_comment { }
345 fill
346 : K_FILL '(' number delimiter number ')'
347 { set_fill($3, $5); }
351 : K_RND '(' number ')'
352 { set_rnd($3); }
355 csum
356 : K_CSUM16 '(' number delimiter number ')'
357 { set_csum16($3, $5); }
360 seqinc
361 : K_SEQINC '(' number delimiter number ')'
362 { set_seqinc($3, $5, 1); }
363 | K_SEQINC '(' number delimiter number delimiter number ')'
364 { set_seqinc($3, $5, $7); }
367 seqdec
368 : K_SEQDEC '(' number delimiter number ')'
369 { set_seqdec($3, $5, 1); }
370 | K_SEQDEC '(' number delimiter number delimiter number ')'
371 { set_seqdec($3, $5, $7); }
374 drnd
375 : K_DRND '(' ')'
376 { set_drnd(); }
377 | K_DRND '(' number ')'
379 int i, max = $3;
380 for (i = 0; i < max; ++i)
381 set_drnd();
385 dinc
386 : K_DINC '(' number delimiter number ')'
387 { set_dincdec($3, $5, 1, TYPE_INC); }
388 | K_DINC '(' number delimiter number delimiter number ')'
389 { set_dincdec($3, $5, $7, TYPE_INC); }
392 ddec
393 : K_DDEC '(' number delimiter number ')'
394 { set_dincdec($3, $5, 1, TYPE_DEC); }
395 | K_DDEC '(' number delimiter number delimiter number ')'
396 { set_dincdec($3, $5, $7, TYPE_DEC); }
401 static void finalize_packet(void)
403 /* XXX hack ... we allocated one packet pointer too much */
404 plen--;
405 dlen--;
408 static void dump_conf(void)
410 size_t i, j;
412 for (i = 0; i < plen; ++i) {
413 printf("[%zu] pkt\n", i);
414 printf(" len %zu cnts %zu rnds %zu\n",
415 packets[i].len,
416 packet_dyn[i].clen,
417 packet_dyn[i].rlen);
419 printf(" payload ");
420 for (j = 0; j < packets[i].len; ++j)
421 printf("%02x ", packets[i].payload[j]);
422 printf("\n");
424 for (j = 0; j < packet_dyn[i].clen; ++j)
425 printf(" cnt%zu [%u,%u], inc %u, off %ld type %s\n", j,
426 packet_dyn[i].cnt[j].min,
427 packet_dyn[i].cnt[j].max,
428 packet_dyn[i].cnt[j].inc,
429 packet_dyn[i].cnt[j].off,
430 packet_dyn[i].cnt[j].type == TYPE_INC ?
431 "inc" : "dec");
433 for (j = 0; j < packet_dyn[i].rlen; ++j)
434 printf(" rnd%zu off %ld\n", j,
435 packet_dyn[i].rnd[j].off);
439 void cleanup_packets(void)
441 size_t i;
443 for (i = 0; i < plen; ++i) {
444 if (packets[i].len > 0)
445 xfree(packets[i].payload);
448 free(packets);
450 for (i = 0; i < dlen; ++i) {
451 free(packet_dyn[i].cnt);
452 free(packet_dyn[i].rnd);
455 free(packet_dyn);
458 int compile_packets(char *file, int verbose, int cpu)
460 our_cpu = cpu;
462 yyin = fopen(file, "r");
463 if (!yyin)
464 panic("Cannot open file!\n");
466 realloc_packet();
467 yyparse();
468 finalize_packet();
470 if (our_cpu == 0 && verbose)
471 dump_conf();
473 fclose(yyin);
474 return 0;
477 void yyerror(const char *err)
479 panic("Syntax error at line%d, at char '%s'! %s!\n", yylineno, yytext, err);