trafgen: remove pointer fiddling, improve code
[netsniff-ng-old.git] / src / trafgen_parser.y
blobe741a0f1fca0ec18f19b8ce029ea1dcfcaad70b8
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;
35 extern int compile_packets(char *file, int verbose);
37 __import struct packet *packets;
38 __import unsigned int packets_len;
39 #define packets_last (packets_len - 1)
40 #define payload_last (packets[packets_last].len - 1)
42 __import struct packet_dynamics *packet_dyns;
43 __import unsigned int packet_dyn_len;
44 #define packetds_last (packet_dyn_len - 1)
45 #define packetds_c_last (packet_dyns[packetds_last].counter_len - 1)
46 #define packetds_r_last (packet_dyns[packetds_last].randomizer_len - 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_dynamics *slot)
67 slot->counter = NULL;
68 slot->counter_len = 0;
71 static inline void init_new_randomizer_slot(struct packet_dynamics *slot)
73 slot->randomizer = NULL;
74 slot->randomizer_len = 0;
77 static void realloc_packet(void)
79 packets_len++;
80 packets = xrealloc(packets, 1, packets_len * sizeof(*packets));
82 init_new_packet_slot(&packets[packets_last]);
84 packet_dyn_len++;
85 packet_dyns = xrealloc(packet_dyns, 1,
86 packet_dyn_len * sizeof(*packet_dyns));
88 init_new_counter_slot(&packet_dyns[packetds_last]);
89 init_new_randomizer_slot(&packet_dyns[packetds_last]);
92 static void set_byte(uint8_t val)
94 packets[packets_last].len++;
95 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
96 1, packets[packets_last].len);
97 packets[packets_last].payload[payload_last] = val;
100 static void set_fill(uint8_t val, size_t len)
102 int i;
104 packets[packets_last].len += len;
105 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
106 1, packets[packets_last].len);
107 for (i = 0; i < len; ++i)
108 packets[packets_last].payload[payload_last - i] = val;
111 static void set_rnd(size_t len)
113 int i;
115 packets[packets_last].len += len;
116 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
117 1, packets[packets_last].len);
118 for (i = 0; i < len; ++i)
119 packets[packets_last].payload[payload_last - i] =
120 (uint8_t) mt_rand_int32();
123 static void set_seqinc(uint8_t start, size_t len, uint8_t stepping)
125 int i;
127 packets[packets_last].len += len;
128 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
129 1, packets[packets_last].len);
130 for (i = 0; i < len; ++i) {
131 int off = len - 1 - i;
132 packets[packets_last].payload[payload_last - off] = start;
133 start += stepping;
137 static void set_seqdec(uint8_t start, size_t len, uint8_t stepping)
139 int i;
141 packets[packets_last].len += len;
142 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
143 1, packets[packets_last].len);
144 for (i = 0; i < len; ++i) {
145 int off = len - 1 - i;
146 packets[packets_last].payload[payload_last - off] = start;
147 start -= stepping;
151 static inline void setup_new_counter(struct counter *counter, uint8_t start,
152 uint8_t stop, uint8_t stepping, int type)
154 counter->min = start;
155 counter->max = stop;
156 counter->inc = stepping;
157 counter->val = (type == TYPE_INC) ? start : stop;
158 counter->off = payload_last;
159 counter->type = type;
162 static inline void setup_new_randomizer(struct randomizer *randomizer)
164 randomizer->val = (uint8_t) mt_rand_int32();
165 randomizer->off = payload_last;
168 static void set_drnd(void)
170 give_note_dynamic();
172 packets[packets_last].len++;
173 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
174 1, packets[packets_last].len);
176 packet_dyns[packetds_last].randomizer_len++;
177 packet_dyns[packetds_last].randomizer =
178 xrealloc(packet_dyns[packetds_last].randomizer, 1,
179 packet_dyns[packetds_last].randomizer_len *
180 sizeof(struct randomizer));
182 setup_new_randomizer(&packet_dyns[packetds_last].
183 randomizer[packetds_r_last]);
186 static void set_dincdec(uint8_t start, uint8_t stop, uint8_t stepping, int type)
188 give_note_dynamic();
190 packets[packets_last].len++;
191 packets[packets_last].payload = xrealloc(packets[packets_last].payload,
192 1, packets[packets_last].len);
194 packet_dyns[packetds_last].counter_len++;
195 packet_dyns[packetds_last].counter =
196 xrealloc(packet_dyns[packetds_last].counter, 1,
197 packet_dyns[packetds_last].counter_len *
198 sizeof(struct counter));
200 setup_new_counter(&packet_dyns[packetds_last].counter[packetds_c_last],
201 start, stop, stepping, type);
206 %union {
207 long int number;
210 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC K_WHITE
211 %token K_NEWL
213 %token ',' '{' '}' '(' ')' '[' ']'
215 %token number_hex number_dec number_ascii number_bin number_oct
217 %type <number> number_hex number_dec number_ascii number_bin number_oct number
221 packets
222 : { }
223 | packets packet { }
224 | packets inline_comment { }
225 | packets white { }
228 inline_comment
229 : K_COMMENT { }
232 packet
233 : '{' delimiter payload delimiter '}' { realloc_packet(); }
236 payload
237 : elem { }
238 | payload elem_delimiter { }
241 white
242 : white K_WHITE
243 | white K_NEWL
244 | K_WHITE
245 | K_NEWL
248 delimiter
249 : ','
250 | white
251 | ',' white
254 elem_delimiter
255 : delimiter elem { }
258 number
259 : number_dec { $$ = $1; }
260 | number_hex { $$ = $1; }
261 | number_ascii { $$ = $1; }
262 | number_bin { $$ = $1; }
263 | number_oct { $$ = $1; }
266 fill
267 : K_FILL '(' number delimiter number ')'
268 { set_fill($3, $5); }
272 : K_RND '(' number ')'
273 { set_rnd($3); }
276 seqinc
277 : K_SEQINC '(' number delimiter number ')'
278 { set_seqinc($3, $5, 1); }
279 | K_SEQINC '(' number delimiter number delimiter number ')'
280 { set_seqinc($3, $5, $7); }
283 seqdec
284 : K_SEQDEC '(' number delimiter number ')'
285 { set_seqdec($3, $5, 1); }
286 | K_SEQDEC '(' number delimiter number delimiter number ')'
287 { set_seqdec($3, $5, $7); }
290 drnd
291 : K_DRND '(' ')'
292 { set_drnd(); }
295 dinc
296 : K_DINC '(' number delimiter number ')'
297 { set_dincdec($3, $5, 1, TYPE_INC); }
298 | K_DINC '(' number delimiter number delimiter number ')'
299 { set_dincdec($3, $5, $7, TYPE_INC); }
302 ddec
303 : K_DDEC '(' number delimiter number ')'
304 { set_dincdec($3, $5, 1, TYPE_DEC); }
305 | K_DDEC '(' number delimiter number delimiter number ')'
306 { set_dincdec($3, $5, $7, TYPE_DEC); }
309 elem
310 : number { set_byte((uint8_t) $1); }
311 | fill { }
312 | rnd { }
313 | drnd { }
314 | seqinc { }
315 | seqdec { }
316 | dinc { }
317 | ddec { }
318 | inline_comment { }
323 static void dump_conf(void)
325 size_t i, j;
327 for (i = 0; i < packets_len; ++i) {
328 printf("[%zu] pkt\n", i);
329 printf(" len %zu cnts %zu rnds %zu\n",
330 packets[i].len,
331 packet_dyns[i].counter_len,
332 packet_dyns[i].randomizer_len);
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_dyns[i].counter_len; ++j)
340 printf(" cnt%zu [%u,%u], inc %u, off %ld type %s\n", j,
341 packet_dyns[i].counter[j].min,
342 packet_dyns[i].counter[j].max,
343 packet_dyns[i].counter[j].inc,
344 packet_dyns[i].counter[j].off,
345 packet_dyns[i].counter[j].type == TYPE_INC ?
346 "inc" : "dec");
348 for (j = 0; j < packet_dyns[i].randomizer_len; ++j)
349 printf(" rnd%zu off %ld\n", j,
350 packet_dyns[i].randomizer[j].off);
354 int compile_packets(char *file, int verbose)
356 mt_init_by_seed_time();
358 yyin = fopen(file, "r");
359 if (!yyin)
360 panic("Cannot open file!\n");
362 realloc_packet();
363 yyparse();
364 /* XXX hack ... */
365 packets_len--;
366 packet_dyn_len--;
368 if (verbose) {
369 dump_conf();
370 } else {
371 int i;
372 size_t total_len = 0;
374 printf("%u packets to schedule\n", packets_len);
375 for (i = 0; i < packets_len; ++i)
376 total_len += packets[i].len;
377 printf("%zu bytes in total\n", total_len);
380 fclose(yyin);
381 return 0;
384 void yyerror(const char *err)
386 panic("Syntax error at line %d: '%s'! %s!\n", yylineno, yytext, err);