docs: add Jon as minor contributor
[netsniff-ng.git] / src / trafgen_parser.y
blobf2ab8b135be4ed564a50df02446e922b16fb5a4c
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 extern struct packet *packets;
37 extern unsigned int packets_len;
38 #define packets_last (packets_len - 1)
39 #define payload_last (packets[packets_last].len - 1)
41 extern struct packet_dynamics *packet_dyns;
42 extern unsigned int packet_dyn_len;
43 #define packetds_last (packet_dyn_len - 1)
44 #define packetds_c_last (packet_dyns[packetds_last].counter_len - 1)
45 #define packetds_r_last (packet_dyns[packetds_last].randomizer_len - 1)
47 static int dfunc_note_flag = 0;
49 static void give_note_dynamic(void)
51 if (!dfunc_note_flag) {
52 printf("Note: dynamic elements like drnd, dinc, ddec and "
53 "others make trafgen slower!\n");
54 dfunc_note_flag = 1;
58 static inline void init_new_packet_slot(struct packet *slot)
60 slot->payload = NULL;
61 slot->len = 0;
64 static inline void init_new_counter_slot(struct packet_dynamics *slot)
66 slot->counter = NULL;
67 slot->counter_len = 0;
70 static inline void init_new_randomizer_slot(struct packet_dynamics *slot)
72 slot->randomizer = NULL;
73 slot->randomizer_len = 0;
76 static void realloc_packet(void)
78 packets_len++;
79 packets = xrealloc(packets, 1, packets_len * sizeof(*packets));
81 init_new_packet_slot(&packets[packets_last]);
83 packet_dyn_len++;
84 packet_dyns = xrealloc(packet_dyns, 1,
85 packet_dyn_len * sizeof(*packet_dyns));
87 init_new_counter_slot(&packet_dyns[packetds_last]);
88 init_new_randomizer_slot(&packet_dyns[packetds_last]);
91 static void set_byte(uint8_t val)
93 packets[packets_last].len++;
94 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
95 1, packets[packets_last].len);
96 packets[packets_last].payload[payload_last] = val;
99 static void set_fill(uint8_t val, size_t len)
101 int i;
103 packets[packets_last].len += len;
104 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
105 1, packets[packets_last].len);
106 for (i = 0; i < len; ++i)
107 packets[packets_last].payload[payload_last - i] = val;
110 static void set_rnd(size_t len)
112 int i;
114 packets[packets_last].len += len;
115 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
116 1, packets[packets_last].len);
117 for (i = 0; i < len; ++i)
118 packets[packets_last].payload[payload_last - i] =
119 (uint8_t) mt_rand_int32();
122 static void set_seqinc(uint8_t start, size_t len, uint8_t stepping)
124 int i;
126 packets[packets_last].len += len;
127 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
128 1, packets[packets_last].len);
129 for (i = 0; i < len; ++i) {
130 int off = len - 1 - i;
131 packets[packets_last].payload[payload_last - off] = start;
132 start += stepping;
136 static void set_seqdec(uint8_t start, size_t len, uint8_t stepping)
138 int i;
140 packets[packets_last].len += len;
141 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
142 1, packets[packets_last].len);
143 for (i = 0; i < len; ++i) {
144 int off = len - 1 - i;
145 packets[packets_last].payload[payload_last - off] = start;
146 start -= stepping;
150 static inline void setup_new_counter(struct counter *counter, uint8_t start,
151 uint8_t stop, uint8_t stepping, int type)
153 counter->min = start;
154 counter->max = stop;
155 counter->inc = stepping;
156 counter->val = (type == TYPE_INC) ? start : stop;
157 counter->off = payload_last;
158 counter->type = type;
161 static inline void setup_new_randomizer(struct randomizer *randomizer)
163 randomizer->val = (uint8_t) mt_rand_int32();
164 randomizer->off = payload_last;
167 static void set_drnd(void)
169 give_note_dynamic();
171 packets[packets_last].len++;
172 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
173 1, packets[packets_last].len);
175 packet_dyns[packetds_last].randomizer_len++;
176 packet_dyns[packetds_last].randomizer =
177 xrealloc(packet_dyns[packetds_last].randomizer, 1,
178 packet_dyns[packetds_last].randomizer_len *
179 sizeof(struct randomizer));
181 setup_new_randomizer(&packet_dyns[packetds_last].
182 randomizer[packetds_r_last]);
185 static void set_dincdec(uint8_t start, uint8_t stop, uint8_t stepping, int type)
187 give_note_dynamic();
189 packets[packets_last].len++;
190 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
191 1, packets[packets_last].len);
193 packet_dyns[packetds_last].counter_len++;
194 packet_dyns[packetds_last].counter =
195 xrealloc(packet_dyns[packetds_last].counter, 1,
196 packet_dyns[packetds_last].counter_len *
197 sizeof(struct counter));
199 setup_new_counter(&packet_dyns[packetds_last].counter[packetds_c_last],
200 start, stop, stepping, type);
205 %union {
206 long int number;
209 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC K_WHITE
210 %token K_NEWL
212 %token ',' '{' '}' '(' ')' '[' ']'
214 %token number_hex number_dec number_ascii number_bin number_oct
216 %type <number> number_hex number_dec number_ascii number_bin number_oct number
220 packets
221 : { }
222 | packets packet { }
223 | packets inline_comment { }
224 | packets white { }
227 inline_comment
228 : K_COMMENT { }
231 packet
232 : '{' delimiter payload delimiter '}' { realloc_packet(); }
235 payload
236 : elem { }
237 | payload elem_delimiter { }
240 white
241 : white K_WHITE { }
242 | white K_NEWL { }
243 | K_WHITE { }
244 | K_NEWL { }
247 delimiter
248 : ',' { }
249 | white { }
250 | ',' white { }
253 elem_delimiter
254 : delimiter elem { }
257 number
258 : number_dec { $$ = $1; }
259 | number_hex { $$ = $1; }
260 | number_ascii { $$ = $1; }
261 | number_bin { $$ = $1; }
262 | number_oct { $$ = $1; }
265 fill
266 : K_FILL '(' number delimiter number ')'
267 { set_fill($3, $5); }
271 : K_RND '(' number ')'
272 { set_rnd($3); }
275 seqinc
276 : K_SEQINC '(' number delimiter number ')'
277 { set_seqinc($3, $5, 1); }
278 | K_SEQINC '(' number delimiter number delimiter number ')'
279 { set_seqinc($3, $5, $7); }
282 seqdec
283 : K_SEQDEC '(' number delimiter number ')'
284 { set_seqdec($3, $5, 1); }
285 | K_SEQDEC '(' number delimiter number delimiter number ')'
286 { set_seqdec($3, $5, $7); }
289 drnd
290 : K_DRND '(' ')'
291 { set_drnd(); }
292 | K_DRND '(' number ')'
294 int i, max = $3;
295 for (i = 0; i < max; ++i)
296 set_drnd();
300 dinc
301 : K_DINC '(' number delimiter number ')'
302 { set_dincdec($3, $5, 1, TYPE_INC); }
303 | K_DINC '(' number delimiter number delimiter number ')'
304 { set_dincdec($3, $5, $7, TYPE_INC); }
307 ddec
308 : K_DDEC '(' number delimiter number ')'
309 { set_dincdec($3, $5, 1, TYPE_DEC); }
310 | K_DDEC '(' number delimiter number delimiter number ')'
311 { set_dincdec($3, $5, $7, TYPE_DEC); }
314 elem
315 : number { set_byte((uint8_t) $1); }
316 | fill { }
317 | rnd { }
318 | drnd { }
319 | seqinc { }
320 | seqdec { }
321 | dinc { }
322 | ddec { }
323 | inline_comment { }
328 static void finalize_packet(void)
330 /* XXX hack ... we allocated one packet pointer too much */
331 packets_len--;
332 packet_dyn_len--;
335 static void dump_conf(void)
337 size_t i, j;
339 for (i = 0; i < packets_len; ++i) {
340 printf("[%zu] pkt\n", i);
341 printf(" len %zu cnts %zu rnds %zu\n",
342 packets[i].len,
343 packet_dyns[i].counter_len,
344 packet_dyns[i].randomizer_len);
346 printf(" payload ");
347 for (j = 0; j < packets[i].len; ++j)
348 printf("%02x ", packets[i].payload[j]);
349 printf("\n");
351 for (j = 0; j < packet_dyns[i].counter_len; ++j)
352 printf(" cnt%zu [%u,%u], inc %u, off %ld type %s\n", j,
353 packet_dyns[i].counter[j].min,
354 packet_dyns[i].counter[j].max,
355 packet_dyns[i].counter[j].inc,
356 packet_dyns[i].counter[j].off,
357 packet_dyns[i].counter[j].type == TYPE_INC ?
358 "inc" : "dec");
360 for (j = 0; j < packet_dyns[i].randomizer_len; ++j)
361 printf(" rnd%zu off %ld\n", j,
362 packet_dyns[i].randomizer[j].off);
366 void cleanup_packets(void)
368 int i;
370 for (i = 0; i < packets_len; ++i) {
371 if (packets[i].len > 0)
372 xfree(packets[i].payload);
375 if (packets_len > 0)
376 xfree(packets);
378 for (i = 0; i < packet_dyn_len; ++i) {
379 if (packet_dyns[i].counter_len > 0)
380 xfree(packet_dyns[i].counter);
382 if (packet_dyns[i].randomizer_len > 0)
383 xfree(packet_dyns[i].randomizer);
386 if (packet_dyn_len > 0)
387 xfree(packet_dyns);
390 int compile_packets(char *file, int verbose)
392 mt_init_by_seed_time();
394 yyin = fopen(file, "r");
395 if (!yyin)
396 panic("Cannot open file!\n");
398 realloc_packet();
399 yyparse();
400 finalize_packet();
402 if (verbose) {
403 dump_conf();
404 } else {
405 int i;
406 size_t total_len = 0;
408 printf("%u packets to schedule\n", packets_len);
409 for (i = 0; i < packets_len; ++i)
410 total_len += packets[i].len;
411 printf("%zu bytes in total\n", total_len);
414 fclose(yyin);
415 return 0;
418 void yyerror(const char *err)
420 panic("Syntax error at line %d: '%s'! %s!\n", yylineno, yytext, err);