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.
9 /* yaac-func-prefix: yy */
21 #include "trafgen_parser.tab.h"
22 #include "trafgen_conf.h"
28 #define YYERROR_VERBOSE 0
30 #define YYENABLE_NLS 1
31 #define YYLTYPE_IS_TRIVIAL 1
35 extern
int yylex(void);
36 extern
void yyerror(const char *);
40 extern
struct packet
*packets
;
43 #define packet_last (plen - 1)
45 #define payload_last (packets[packet_last].len - 1)
47 extern
struct packet_dyn
*packet_dyn
;
50 #define packetd_last (dlen - 1)
52 #define packetdc_last (packet_dyn[packetd_last].clen - 1)
53 #define packetdr_last (packet_dyn[packetd_last].rlen - 1)
54 #define packetds_last (packet_dyn[packetd_last].slen - 1)
56 static int our_cpu
, min_cpu
= -1, max_cpu
= -1;
58 static inline
int test_ignore
(void)
60 if
(min_cpu
< 0 && max_cpu
< 0)
62 else if
(max_cpu
>= our_cpu
&& min_cpu
<= our_cpu
)
68 static inline
int has_dynamic_elems
(struct packet_dyn
*p
)
70 return
(p
->rlen
+ p
->slen
+ p
->clen
);
73 static inline
void __init_new_packet_slot
(struct packet
*slot
)
79 static inline
void __init_new_counter_slot
(struct packet_dyn
*slot
)
85 static inline
void __init_new_randomizer_slot
(struct packet_dyn
*slot
)
91 static inline
void __init_new_csum_slot
(struct packet_dyn
*slot
)
97 static inline
void __setup_new_counter
(struct counter
*c
, uint8_t start
,
98 uint8_t stop
, uint8_t stepping
,
104 c
->val
= (type
== TYPE_INC
) ? start
: stop
;
105 c
->off
= payload_last
;
109 static inline
void __setup_new_randomizer
(struct randomizer
*r
)
111 r
->off
= payload_last
;
114 static inline
void __setup_new_csum16
(struct csum16
*s
, off_t from
, off_t to
,
117 s
->off
= payload_last
- 1;
123 static void realloc_packet
(void)
129 packets
= xrealloc
(packets
, 1, plen
* sizeof
(*packets
));
131 __init_new_packet_slot
(&packets
[packet_last
]);
134 packet_dyn
= xrealloc
(packet_dyn
, 1, dlen
* sizeof
(*packet_dyn
));
136 __init_new_counter_slot
(&packet_dyn
[packetd_last
]);
137 __init_new_randomizer_slot
(&packet_dyn
[packetd_last
]);
138 __init_new_csum_slot
(&packet_dyn
[packetd_last
]);
141 static void set_byte
(uint8_t val
)
143 struct packet
*pkt
= &packets
[packet_last
];
149 pkt
->payload
= xrealloc
(pkt
->payload
, 1, pkt
->len
);
150 pkt
->payload
[payload_last
] = val
;
153 static void set_multi_byte
(uint8_t *s
, size_t len
)
157 for
(i
= 0; i
< len
; ++i
)
161 static void set_fill
(uint8_t val
, size_t len
)
164 struct packet
*pkt
= &packets
[packet_last
];
170 pkt
->payload
= xrealloc
(pkt
->payload
, 1, pkt
->len
);
171 for
(i
= 0; i
< len
; ++i
)
172 pkt
->payload
[payload_last
- i
] = val
;
175 static void __set_csum16_dynamic
(size_t from
, size_t to
, enum csum which
)
177 struct packet
*pkt
= &packets
[packet_last
];
178 struct packet_dyn
*pktd
= &packet_dyn
[packetd_last
];
181 pkt
->payload
= xrealloc
(pkt
->payload
, 1, pkt
->len
);
184 pktd
->csum
= xrealloc
(pktd
->csum
, 1, pktd
->slen
* sizeof
(struct csum16
));
186 __setup_new_csum16
(&pktd
->csum
[packetds_last
], from
, to
, which
);
189 static void __set_csum16_static
(size_t from
, size_t to
, enum csum which
)
191 struct packet
*pkt
= &packets
[packet_last
];
195 sum
= htons
(calc_csum
(pkt
->payload
+ from
, to
- from
, 0));
196 psum
= (uint8_t *) &sum
;
202 static void set_csum16
(size_t from
, size_t to
, enum csum which
)
204 int make_it_dynamic
= 0;
205 struct packet
*pkt
= &packets
[packet_last
];
206 struct packet_dyn
*pktd
= &packet_dyn
[packetd_last
];
218 bug_on
(!(from
< to
));
220 if
(to
>= pkt
->len || which
== CSUM_TCP || which
== CSUM_UDP
)
223 if
(has_dynamic_elems
(pktd
) || make_it_dynamic
)
224 __set_csum16_dynamic
(from
, to
, which
);
226 __set_csum16_static
(from
, to
, which
);
229 static void set_rnd
(size_t len
)
232 struct packet
*pkt
= &packets
[packet_last
];
238 pkt
->payload
= xrealloc
(pkt
->payload
, 1, pkt
->len
);
239 for
(i
= 0; i
< len
; ++i
)
240 pkt
->payload
[payload_last
- i
] = (uint8_t) rand
();
243 static void set_sequential_inc
(uint8_t start
, size_t len
, uint8_t stepping
)
246 struct packet
*pkt
= &packets
[packet_last
];
252 pkt
->payload
= xrealloc
(pkt
->payload
, 1, pkt
->len
);
253 for
(i
= 0; i
< len
; ++i
) {
254 off_t off
= len
- 1 - i
;
256 pkt
->payload
[payload_last
- off
] = start
;
261 static void set_sequential_dec
(uint8_t start
, size_t len
, uint8_t stepping
)
264 struct packet
*pkt
= &packets
[packet_last
];
270 pkt
->payload
= xrealloc
(pkt
->payload
, 1, pkt
->len
);
271 for
(i
= 0; i
< len
; ++i
) {
272 int off
= len
- 1 - i
;
274 pkt
->payload
[payload_last
- off
] = start
;
279 static void set_dynamic_rnd
(void)
281 struct packet
*pkt
= &packets
[packet_last
];
282 struct packet_dyn
*pktd
= &packet_dyn
[packetd_last
];
288 pkt
->payload
= xrealloc
(pkt
->payload
, 1, pkt
->len
);
291 pktd
->rnd
= xrealloc
(pktd
->rnd
, 1, pktd
->rlen
* sizeof
(struct randomizer
));
293 __setup_new_randomizer
(&pktd
->rnd
[packetdr_last
]);
296 static void set_dynamic_incdec
(uint8_t start
, uint8_t stop
, uint8_t stepping
,
299 struct packet
*pkt
= &packets
[packet_last
];
300 struct packet_dyn
*pktd
= &packet_dyn
[packetd_last
];
306 pkt
->payload
= xrealloc
(pkt
->payload
, 1, pkt
->len
);
309 pktd
->cnt
=xrealloc
(pktd
->cnt
, 1, pktd
->clen
* sizeof
(struct counter
));
311 __setup_new_counter
(&pktd
->cnt
[packetdc_last
], start
, stop
, stepping
, type
);
317 long long int number
;
321 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC K_WHITE
322 %token K_CPU K_CSUMIP K_CSUMUDP K_CSUMTCP K_CONST8 K_CONST16 K_CONST32 K_CONST64
324 %token
',' '{' '}' '(' ')' '[' ']' ':' '-' '+' '*' '/' '%' '&' '|' '<' '>' '^'
328 %type
<number
> number expression
331 %left
'-' '+' '*' '/' '%' '&' '|' '<' '>' '^'
338 | packets inline_comment
{ }
339 | packets K_WHITE
{ }
347 : '{' delimiter payload delimiter
'}' {
348 min_cpu
= max_cpu
= -1;
351 | K_CPU
'(' number
':' number
')' ':' K_WHITE
'{' delimiter payload delimiter
'}' {
355 if
(min_cpu
> max_cpu
) {
364 | K_CPU
'(' number
')' ':' K_WHITE
'{' delimiter payload delimiter
'}' {
365 min_cpu
= max_cpu
= $3;
372 | payload elem_delimiter
{ }
386 : number
{ set_byte
((uint8_t) $1); }
387 |
string { set_multi_byte
((uint8_t *) $1 + 1, strlen
($1) - 2); }
403 | expression
'+' expression
405 | expression
'-' expression
407 | expression
'*' expression
409 | expression
'/' expression
411 | expression
'%' expression
413 | expression
'&' expression
415 | expression
'|' expression
417 | expression
'^' expression
419 | expression
'<' '<' expression
421 | expression
'>' '>' expression
428 : K_FILL
'(' number delimiter number
')'
429 { set_fill
($3, $5); }
433 : K_CONST8
'(' expression
')'
434 { set_byte
((uint8_t) $3); }
435 | K_CONST16
'(' expression
')' {
436 uint16_t __c
= cpu_to_be16
((uint16_t) $3);
438 set_multi_byte
((uint8_t *) &__c
, sizeof
(__c
));
440 | K_CONST32
'(' expression
')' {
441 uint32_t __c
= cpu_to_be32
((uint32_t) $3);
443 set_multi_byte
((uint8_t *) &__c
, sizeof
(__c
));
445 | K_CONST64
'(' expression
')' {
446 uint64_t __c
= cpu_to_be64
((uint64_t) $3);
448 set_multi_byte
((uint8_t *) &__c
, sizeof
(__c
));
453 : K_RND
'(' number
')'
458 : K_CSUMIP
'(' number delimiter number
')'
459 { set_csum16
($3, $5, CSUM_IP
); }
460 | K_CSUMTCP
'(' number delimiter number
')'
461 { set_csum16
($3, $5, CSUM_TCP
); }
462 | K_CSUMUDP
'(' number delimiter number
')'
463 { set_csum16
($3, $5, CSUM_UDP
); }
467 : K_SEQINC
'(' number delimiter number
')'
468 { set_sequential_inc
($3, $5, 1); }
469 | K_SEQINC
'(' number delimiter number delimiter number
')'
470 { set_sequential_inc
($3, $5, $7); }
474 : K_SEQDEC
'(' number delimiter number
')'
475 { set_sequential_dec
($3, $5, 1); }
476 | K_SEQDEC
'(' number delimiter number delimiter number
')'
477 { set_sequential_dec
($3, $5, $7); }
482 { set_dynamic_rnd
(); }
483 | K_DRND
'(' number
')'
486 for
(i
= 0; i
< max
; ++i
)
492 : K_DINC
'(' number delimiter number
')'
493 { set_dynamic_incdec
($3, $5, 1, TYPE_INC
); }
494 | K_DINC
'(' number delimiter number delimiter number
')'
495 { set_dynamic_incdec
($3, $5, $7, TYPE_INC
); }
499 : K_DDEC
'(' number delimiter number
')'
500 { set_dynamic_incdec
($3, $5, 1, TYPE_DEC
); }
501 | K_DDEC
'(' number delimiter number delimiter number
')'
502 { set_dynamic_incdec
($3, $5, $7, TYPE_DEC
); }
507 static void finalize_packet
(void)
509 /* XXX hack ... we allocated one packet pointer too much */
514 static void dump_conf
(void)
518 for
(i
= 0; i
< plen
; ++i
) {
519 printf
("[%zu] pkt\n", i
);
520 printf
(" len %zu cnts %zu rnds %zu\n",
526 for
(j
= 0; j
< packets
[i
].len
; ++j
)
527 printf
("%02x ", packets
[i
].payload
[j
]);
530 for
(j
= 0; j
< packet_dyn
[i
].clen
; ++j
)
531 printf
(" cnt%zu [%u,%u], inc %u, off %ld type %s\n", j
,
532 packet_dyn
[i
].cnt
[j
].min
,
533 packet_dyn
[i
].cnt
[j
].max
,
534 packet_dyn
[i
].cnt
[j
].inc
,
535 packet_dyn
[i
].cnt
[j
].off
,
536 packet_dyn
[i
].cnt
[j
].type
== TYPE_INC ?
539 for
(j
= 0; j
< packet_dyn
[i
].rlen
; ++j
)
540 printf
(" rnd%zu off %ld\n", j
,
541 packet_dyn
[i
].rnd
[j
].off
);
545 void cleanup_packets
(void)
549 for
(i
= 0; i
< plen
; ++i
) {
550 if
(packets
[i
].len
> 0)
551 xfree
(packets
[i
].payload
);
556 for
(i
= 0; i
< dlen
; ++i
) {
557 free
(packet_dyn
[i
].cnt
);
558 free
(packet_dyn
[i
].rnd
);
564 int compile_packets
(char *file
, int verbose
, int cpu
, bool invoke_cpp
)
568 memset
(tmp_file
, 0, sizeof
(tmp_file
));
574 slprintf
(tmp_file
, sizeof
(tmp_file
), ".tmp-%u-%s", rand
(), file
);
575 slprintf
(cmd
, sizeof
(cmd
), "cpp %s > %s", file
, tmp_file
);
581 if
(!strncmp
("-", file
, strlen
("-")))
584 yyin
= fopen
(file
, "r");
586 panic
("Cannot open %s: %s!\n", file
, strerror
(errno
));
592 if
(our_cpu
== 0 && verbose
)
602 void yyerror(const char *err
)
604 panic
("Syntax error at line%d, at char '%s'! %s!\n", yylineno
, yytext
, err
);