mausezahn: use getopt_long instead of getopt
[netsniff-ng.git] / trafgen_parser.y
blob53723dd4bbb6d42f4e14d670b3dffa1d63d961b0
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 /* yacc-func-prefix: yy */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stdint.h>
16 #include <stdbool.h>
17 #include <errno.h>
18 #include <libgen.h>
19 #include <signal.h>
20 #include <unistd.h>
21 #include <net/if_arp.h>
22 #include <netinet/in.h>
23 #include <linux/icmp.h>
24 #include <linux/if_ether.h>
25 #include <linux/icmpv6.h>
27 #include "xmalloc.h"
28 #include "trafgen_parser.tab.h"
29 #include "trafgen_conf.h"
30 #include "trafgen_proto.h"
31 #include "trafgen_l2.h"
32 #include "trafgen_l3.h"
33 #include "trafgen_l4.h"
34 #include "trafgen_l7.h"
35 #include "built_in.h"
36 #include "die.h"
37 #include "str.h"
38 #include "csum.h"
39 #include "cpp.h"
41 #ifndef ETH_P_8021AD
42 #define ETH_P_8021AD 0x88A8
43 #endif
45 #define YYERROR_VERBOSE 0
46 #define YYDEBUG 0
47 #define YYLTYPE_IS_TRIVIAL 1
49 extern FILE *yyin;
50 extern int yylex(void);
51 extern void yy_scan_string(char *);
52 extern void yylex_destroy();
53 extern void yyerror(const char *);
54 extern int yylineno;
55 extern char *yytext;
57 extern struct packet *packets;
58 extern size_t plen;
60 #define packet_last (plen - 1)
62 #define payload_last (packets[packet_last].len - 1)
64 extern struct packet_dyn *packet_dyn;
65 extern size_t dlen;
67 #define packetd_last (dlen - 1)
69 #define packetdc_last (packet_dyn[packetd_last].clen - 1)
70 #define packetdr_last (packet_dyn[packetd_last].rlen - 1)
71 #define packetds_last (packet_dyn[packetd_last].slen - 1)
73 static int our_cpu, min_cpu = -1, max_cpu = -1;
75 enum field_expr_type_t {
76 FIELD_EXPR_UNKNOWN = 0,
77 FIELD_EXPR_NUMB = 1 << 0,
78 FIELD_EXPR_MAC = 1 << 1,
79 FIELD_EXPR_IP4_ADDR = 1 << 2,
80 FIELD_EXPR_IP6_ADDR = 1 << 3,
81 FIELD_EXPR_INC = 1 << 4,
82 FIELD_EXPR_RND = 1 << 5,
83 FIELD_EXPR_OFFSET = 1 << 6,
84 FIELD_EXPR_STRING = 1 << 7,
85 FIELD_EXPR_FQDN = 1 << 8,
88 struct proto_field_expr {
89 enum field_expr_type_t type;
90 struct proto_field *field;
92 union {
93 struct in_addr ip4_addr;
94 struct in6_addr ip6_addr;
95 long long int number;
96 uint8_t mac[256];
97 char *str;
98 struct proto_field_func func;
99 } val;
102 static struct proto_field_expr field_expr;
103 static struct proto_hdr *hdr;
105 static inline int test_ignore(void)
107 if (min_cpu < 0 && max_cpu < 0)
108 return 0;
109 else if (max_cpu >= our_cpu && min_cpu <= our_cpu)
110 return 0;
111 else
112 return 1;
115 static inline void __init_new_packet_slot(struct packet *slot)
117 memset(slot, 0, sizeof(*slot));
120 static inline void __init_new_counter_slot(struct packet_dyn *slot)
122 slot->cnt = NULL;
123 slot->clen = 0;
126 static inline void __init_new_randomizer_slot(struct packet_dyn *slot)
128 slot->rnd = NULL;
129 slot->rlen = 0;
132 static inline void __init_new_csum_slot(struct packet_dyn *slot)
134 slot->csum = NULL;
135 slot->slen = 0;
138 static inline void __init_new_fields_slot(struct packet_dyn *slot)
140 slot->fields = NULL;
141 slot->flen = 0;
144 static inline void __setup_new_counter(struct counter *c, uint8_t start,
145 uint8_t stop, uint8_t stepping,
146 int type)
148 c->min = start;
149 c->max = stop;
150 c->inc = (type == TYPE_INC) ? stepping : -stepping;
151 c->val = (type == TYPE_INC) ? start : stop;
152 c->off = payload_last;
153 c->type = type;
156 static inline void __setup_new_randomizer(struct randomizer *r)
158 r->off = payload_last;
161 static inline void __setup_new_csum16(struct csum16 *s, off_t from, off_t to,
162 enum csum which)
164 s->off = payload_last - 1;
165 s->from = from;
166 s->to = to;
167 s->which = which;
170 struct packet *realloc_packet(void)
172 uint32_t i;
174 if (test_ignore())
175 return NULL;
177 plen++;
178 packets = xrealloc(packets, plen * sizeof(*packets));
180 __init_new_packet_slot(&packets[packet_last]);
182 dlen++;
183 packet_dyn = xrealloc(packet_dyn, dlen * sizeof(*packet_dyn));
185 __init_new_counter_slot(&packet_dyn[packetd_last]);
186 __init_new_randomizer_slot(&packet_dyn[packetd_last]);
187 __init_new_csum_slot(&packet_dyn[packetd_last]);
188 __init_new_fields_slot(&packet_dyn[packetd_last]);
190 for (i = 0; i < plen; i++)
191 packets[i].id = i;
193 return &packets[packet_last];
196 struct packet *current_packet(void)
198 return &packets[packet_last];
201 uint32_t current_packet_id(void)
203 return packet_last;
206 struct packet *packet_get(uint32_t id)
208 return &packets[id];
211 static void set_byte(uint8_t val)
213 struct packet *pkt = &packets[packet_last];
215 if (test_ignore())
216 return;
218 pkt->len++;
219 pkt->payload = xrealloc(pkt->payload, pkt->len);
220 pkt->payload[payload_last] = val;
223 static void set_multi_byte(uint8_t *s, size_t len)
225 size_t i;
227 for (i = 0; i < len; ++i)
228 set_byte(s[i]);
231 void set_fill(uint8_t val, size_t len)
233 size_t i;
234 struct packet *pkt = &packets[packet_last];
236 if (test_ignore())
237 return;
239 pkt->len += len;
240 pkt->payload = xrealloc(pkt->payload, pkt->len);
241 for (i = 0; i < len; ++i)
242 pkt->payload[payload_last - i] = val;
245 static void __set_csum16_dynamic(size_t from, size_t to, enum csum which)
247 struct packet *pkt = &packets[packet_last];
248 struct packet_dyn *pktd = &packet_dyn[packetd_last];
250 pkt->len += 2;
251 pkt->payload = xrealloc(pkt->payload, pkt->len);
253 pktd->slen++;
254 pktd->csum = xrealloc(pktd->csum, pktd->slen * sizeof(struct csum16));
256 __setup_new_csum16(&pktd->csum[packetds_last], from, to, which);
259 static void __set_csum16_static(size_t from, size_t to, enum csum which __maybe_unused)
261 struct packet *pkt = &packets[packet_last];
262 uint16_t sum;
263 uint8_t *psum;
265 sum = htons(calc_csum(pkt->payload + from, to - from));
266 psum = (uint8_t *) &sum;
268 set_byte(psum[0]);
269 set_byte(psum[1]);
272 static inline bool is_dynamic_csum(enum csum which)
274 switch (which) {
275 case CSUM_UDP:
276 case CSUM_TCP:
277 case CSUM_UDP6:
278 case CSUM_TCP6:
279 case CSUM_ICMP6:
280 return true;
281 default:
282 return false;
286 static void set_csum16(size_t from, size_t to, enum csum which)
288 struct packet *pkt = &packets[packet_last];
289 struct packet_dyn *pktd = &packet_dyn[packetd_last];
291 if (test_ignore())
292 return;
294 if (to < from) {
295 size_t tmp = to;
297 to = from;
298 from = tmp;
301 bug_on(!(from < to));
303 if (packet_dyn_has_elems(pktd) || to >= pkt->len || is_dynamic_csum(which))
304 __set_csum16_dynamic(from, to, which);
305 else
306 __set_csum16_static(from, to, which);
309 static void set_rnd(size_t len)
311 size_t i;
312 struct packet *pkt = &packets[packet_last];
314 if (test_ignore())
315 return;
317 pkt->len += len;
318 pkt->payload = xrealloc(pkt->payload, pkt->len);
319 for (i = 0; i < len; ++i)
320 pkt->payload[payload_last - i] = (uint8_t) rand();
323 static void set_sequential_inc(uint8_t start, size_t len, uint8_t stepping)
325 size_t i;
326 struct packet *pkt = &packets[packet_last];
328 if (test_ignore())
329 return;
331 pkt->len += len;
332 pkt->payload = xrealloc(pkt->payload, pkt->len);
333 for (i = 0; i < len; ++i) {
334 off_t off = len - 1 - i;
336 pkt->payload[payload_last - off] = start;
337 start += stepping;
341 static void set_sequential_dec(uint8_t start, size_t len, uint8_t stepping)
343 size_t i;
344 struct packet *pkt = &packets[packet_last];
346 if (test_ignore())
347 return;
349 pkt->len += len;
350 pkt->payload = xrealloc(pkt->payload, pkt->len);
351 for (i = 0; i < len; ++i) {
352 int off = len - 1 - i;
354 pkt->payload[payload_last - off] = start;
355 start -= stepping;
359 static void set_dynamic_rnd(void)
361 struct packet *pkt = &packets[packet_last];
362 struct packet_dyn *pktd = &packet_dyn[packetd_last];
364 if (test_ignore())
365 return;
367 pkt->len++;
368 pkt->payload = xrealloc(pkt->payload, pkt->len);
370 pktd->rlen++;
371 pktd->rnd = xrealloc(pktd->rnd, pktd->rlen * sizeof(struct randomizer));
373 __setup_new_randomizer(&pktd->rnd[packetdr_last]);
376 static void set_dynamic_incdec(uint8_t start, uint8_t stop, uint8_t stepping,
377 int type)
379 struct packet *pkt = &packets[packet_last];
380 struct packet_dyn *pktd = &packet_dyn[packetd_last];
382 if (test_ignore())
383 return;
385 pkt->len++;
386 pkt->payload = xrealloc(pkt->payload, pkt->len);
388 pktd->clen++;
389 pktd->cnt = xrealloc(pktd->cnt, pktd->clen * sizeof(struct counter));
391 __setup_new_counter(&pktd->cnt[packetdc_last], start, stop, stepping, type);
394 static void proto_add(enum proto_id pid)
396 hdr = proto_header_push(pid);
399 static void proto_field_set(uint32_t fid)
401 memset(&field_expr, 0, sizeof(field_expr));
402 field_expr.field = proto_hdr_field_by_id(hdr, fid);
405 static void proto_field_func_setup(struct proto_field *field, struct proto_field_func *func)
407 struct proto_field *field_copy;
408 struct packet_dyn *pkt_dyn;
410 field_copy = xmalloc(sizeof(*field));
411 memcpy(field_copy, field, sizeof(*field));
413 field_copy->pkt_offset += func->offset;
414 if (func->len)
415 field_copy->len = func->len;
417 proto_field_func_add(field_copy, func);
419 pkt_dyn = &packet_dyn[packetd_last];
420 pkt_dyn->flen++;
421 pkt_dyn->fields = xrealloc(pkt_dyn->fields, pkt_dyn->flen *
422 sizeof(struct proto_field *));
424 pkt_dyn->fields[pkt_dyn->flen - 1] = field_copy;
427 static void proto_field_expr_eval(void)
429 struct proto_field *field = field_expr.field;
431 if ((field_expr.type & FIELD_EXPR_OFFSET) &&
432 !((field_expr.type & FIELD_EXPR_INC) ||
433 (field_expr.type & FIELD_EXPR_RND))) {
435 panic("Field offset expression is valid only with function expression\n");
438 if (field_expr.type & FIELD_EXPR_NUMB) {
439 if (field->len == 1)
440 proto_field_set_u8(field, field_expr.val.number);
441 else if (field->len == 2)
442 proto_field_set_be16(field, field_expr.val.number);
443 else if (field->len == 4)
444 proto_field_set_be32(field, field_expr.val.number);
445 else
446 panic("Invalid value length %zu, can be 1,2 or 4\n", field->len);
447 } else if (field_expr.type & FIELD_EXPR_MAC) {
448 proto_field_set_bytes(field, field_expr.val.mac, 6);
449 } else if (field_expr.type & FIELD_EXPR_FQDN) {
450 char *fqdn = str2fqdn(field_expr.val.str);
451 proto_field_set_bytes(field, (uint8_t *) fqdn, strlen(fqdn) + 1);
452 xfree(field_expr.val.str);
453 xfree(fqdn);
454 } else if (field_expr.type & FIELD_EXPR_STRING) {
455 proto_field_set_string(field, field_expr.val.str);
456 xfree(field_expr.val.str);
457 } else if (field_expr.type & FIELD_EXPR_IP4_ADDR) {
458 proto_field_set_u32(field, field_expr.val.ip4_addr.s_addr);
459 } else if (field_expr.type & FIELD_EXPR_IP6_ADDR) {
460 proto_field_set_bytes(field, (uint8_t *)&field_expr.val.ip6_addr.s6_addr, 16);
461 } else if ((field_expr.type & FIELD_EXPR_INC) ||
462 (field_expr.type & FIELD_EXPR_RND)) {
464 if (field_expr.val.func.min
465 && field_expr.val.func.min >= field_expr.val.func.max)
466 panic("dinc(): min(%u) can't be >= max(%u)\n",
467 field_expr.val.func.min, field_expr.val.func.max);
469 proto_field_func_setup(field, &field_expr.val.func);
470 } else if ((field_expr.type & FIELD_EXPR_OFFSET) &&
471 !((field_expr.type & FIELD_EXPR_INC) ||
472 (field_expr.type & FIELD_EXPR_RND))) {
474 panic("Field expression is valid only for function value expression\n");
475 } else {
476 bug();
479 memset(&field_expr, 0, sizeof(field_expr));
482 static void field_index_validate(struct proto_field *field, uint16_t index, size_t len)
484 if (field_expr.field->len <= index) {
485 yyerror("Invalid [index] parameter");
486 panic("Index (%u) is bigger than field's length (%zu)\n",
487 index, field->len);
489 if (len != 1 && len != 2 && len != 4) {
490 yyerror("Invalid [index:len] parameter");
491 panic("Invalid index length - 1,2 or 4 is only allowed\n");
495 static void proto_push_sub_hdr(uint32_t id)
497 hdr = proto_hdr_push_sub_header(hdr, id);
500 static void proto_pop_sub_hdr(void)
502 if (hdr->ops->header_finish)
503 hdr->ops->header_finish(hdr);
505 hdr = hdr->parent;
510 %union {
511 struct in_addr ip4_addr;
512 struct in6_addr ip6_addr;
513 long long int number;
514 uint8_t mac[6];
515 char *str;
518 %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC K_WHITE
519 %token K_CPU K_CSUMIP K_CSUMUDP K_CSUMTCP K_CSUMUDP6 K_CSUMTCP6 K_CSUMICMP6 K_CONST8 K_CONST16 K_CONST32 K_CONST64
521 %token K_DADDR K_SADDR K_ETYPE K_TYPE
522 %token K_TIME K_PRIO
523 %token K_OPER K_SHA K_SPA K_THA K_TPA K_REQUEST K_REPLY K_PTYPE K_HTYPE
524 %token K_PROT K_TTL K_DSCP K_ECN K_TOS K_LEN K_ID K_FLAGS K_FRAG K_IHL K_VER K_CSUM K_DF K_MF
525 %token K_FLOW K_NEXT_HDR K_HOP_LIMIT
526 %token K_CODE K_ECHO_REQUEST K_ECHO_REPLY
527 %token K_SPORT K_DPORT
528 %token K_SEQ K_ACK_SEQ K_DOFF K_CWR K_ECE K_URG K_ACK K_PSH K_RST K_SYN K_FIN K_WINDOW K_URG_PTR
529 %token K_TPID K_TCI K_PCP K_DEI K_1Q K_1AD
530 %token K_LABEL K_TC K_LAST K_EXP
532 %token K_ADDR K_MTU
534 %token K_QR K_AANSWER K_TRUNC K_RAVAIL K_RDESIRED K_ZERO K_RCODE K_QDCOUNT K_ANCOUNT K_NSCOUNT K_ARCOUNT
535 %token K_QUERY K_ANSWER K_AUTH K_ADD
536 %token K_NAME K_CLASS K_DATA K_NS K_CNAME K_PTR
538 %token K_ETH
539 %token K_PAUSE
540 %token K_PFC
541 %token K_VLAN K_MPLS
542 %token K_ARP
543 %token K_IP4 K_IP6
544 %token K_ICMP4 K_ICMP6
545 %token K_UDP K_TCP
546 %token K_DNS
548 %token ',' '{' '}' '(' ')' '[' ']' ':' '-' '+' '*' '/' '%' '&' '|' '<' '>' '^'
550 %token number string mac ip4_addr ip6_addr
552 %type <number> number expression
553 %type <str> string
554 %type <mac> mac
555 %type <ip4_addr> ip4_addr
556 %type <ip6_addr> ip6_addr
558 %left '-' '+' '*' '/' '%' '&' '|' '<' '>' '^'
562 packets
563 : { }
564 | packets packet { }
565 | packets inline_comment { }
566 | packets K_WHITE { }
569 inline_comment
570 : K_COMMENT { }
573 cpu_delim
574 : ':' { }
575 | '-' { }
578 delimiter_nowhite
579 : ',' { }
580 | ',' K_WHITE { }
583 noenforce_white
584 : { }
585 | K_WHITE { }
586 | delimiter_nowhite { }
589 skip_white
590 : { }
591 | K_WHITE { }
593 packet
594 : '{' noenforce_white payload noenforce_white '}' {
595 min_cpu = max_cpu = -1;
597 proto_packet_finish();
599 realloc_packet();
601 | K_CPU '(' number cpu_delim number ')' ':' noenforce_white '{' noenforce_white payload noenforce_white '}' {
602 min_cpu = $3;
603 max_cpu = $5;
605 if (min_cpu > max_cpu) {
606 int tmp = min_cpu;
608 min_cpu = max_cpu;
609 max_cpu = tmp;
612 proto_packet_finish();
614 realloc_packet();
616 | K_CPU '(' number ')' ':' noenforce_white '{' noenforce_white payload noenforce_white '}' {
617 min_cpu = max_cpu = $3;
619 proto_packet_finish();
621 realloc_packet();
625 payload
626 : elem { }
627 | payload elem_delimiter { }
630 delimiter
631 : delimiter_nowhite { }
632 | K_WHITE { }
635 elem_delimiter
636 : delimiter elem { }
639 elem
640 : number { set_byte((uint8_t) $1); }
641 | string { set_multi_byte((uint8_t *) $1 + 1, strlen($1) - 2); }
642 | fill { }
643 | rnd { }
644 | drnd { }
645 | seqinc { }
646 | seqdec { }
647 | dinc { }
648 | ddec { }
649 | csum { }
650 | const { }
651 | proto { proto_header_finish(hdr); }
652 | inline_comment { }
655 expression
656 : number
657 { $$ = $1; }
658 | expression '+' expression
659 { $$ = $1 + $3; }
660 | expression '-' expression
661 { $$ = $1 - $3; }
662 | expression '*' expression
663 { $$ = $1 * $3; }
664 | expression '/' expression
665 { $$ = $1 / $3; }
666 | expression '%' expression
667 { $$ = $1 % $3; }
668 | expression '&' expression
669 { $$ = $1 & $3; }
670 | expression '|' expression
671 { $$ = $1 | $3; }
672 | expression '^' expression
673 { $$ = $1 ^ $3; }
674 | expression '<' '<' expression
675 { $$ = $1 << $4; }
676 | expression '>' '>' expression
677 { $$ = $1 >> $4; }
678 | '-' expression
679 { $$ = -1 * $2; }
680 | '(' expression ')'
681 { $$ = $2;}
684 fill
685 : K_FILL '(' number delimiter number ')'
686 { set_fill($3, $5); }
689 const
690 : K_CONST8 '(' expression ')'
691 { set_byte((uint8_t) $3); }
692 | K_CONST16 '(' expression ')' {
693 uint16_t __c = cpu_to_be16((uint16_t) $3);
695 set_multi_byte((uint8_t *) &__c, sizeof(__c));
697 | K_CONST32 '(' expression ')' {
698 uint32_t __c = cpu_to_be32((uint32_t) $3);
700 set_multi_byte((uint8_t *) &__c, sizeof(__c));
702 | K_CONST64 '(' expression ')' {
703 uint64_t __c = cpu_to_be64((uint64_t) $3);
705 set_multi_byte((uint8_t *) &__c, sizeof(__c));
710 : K_RND '(' number ')'
711 { set_rnd($3); }
714 csum
715 : K_CSUMIP '(' number delimiter number ')'
716 { set_csum16($3, $5, CSUM_IP); }
717 | K_CSUMTCP '(' number delimiter number ')'
718 { set_csum16($3, $5, CSUM_TCP); }
719 | K_CSUMUDP '(' number delimiter number ')'
720 { set_csum16($3, $5, CSUM_UDP); }
721 | K_CSUMTCP6 '(' number delimiter number ')'
722 { set_csum16($3, $5, CSUM_TCP6); }
723 | K_CSUMUDP6 '(' number delimiter number ')'
724 { set_csum16($3, $5, CSUM_UDP6); }
725 | K_CSUMICMP6 '(' number delimiter number ')'
726 { set_csum16($3, $5, CSUM_ICMP6); }
729 seqinc
730 : K_SEQINC '(' number delimiter number ')'
731 { set_sequential_inc($3, $5, 1); }
732 | K_SEQINC '(' number delimiter number delimiter number ')'
733 { set_sequential_inc($3, $5, $7); }
736 seqdec
737 : K_SEQDEC '(' number delimiter number ')'
738 { set_sequential_dec($3, $5, 1); }
739 | K_SEQDEC '(' number delimiter number delimiter number ')'
740 { set_sequential_dec($3, $5, $7); }
743 drnd
744 : K_DRND '(' ')'
745 { set_dynamic_rnd(); }
746 | K_DRND '(' number ')'
748 int i, max = $3;
749 for (i = 0; i < max; ++i)
750 set_dynamic_rnd();
754 dinc
755 : K_DINC '(' number delimiter number ')'
756 { set_dynamic_incdec($3, $5, 1, TYPE_INC); }
757 | K_DINC '(' number delimiter number delimiter number ')'
758 { set_dynamic_incdec($3, $5, $7, TYPE_INC); }
761 ddec
762 : K_DDEC '(' number delimiter number ')'
763 { set_dynamic_incdec($3, $5, 1, TYPE_DEC); }
764 | K_DDEC '(' number delimiter number delimiter number ')'
765 { set_dynamic_incdec($3, $5, $7, TYPE_DEC); }
768 proto
769 : eth_proto { }
770 | pause_proto { }
771 | pfc_proto { }
772 | vlan_proto { }
773 | mpls_proto { }
774 | arp_proto { }
775 | ip4_proto { }
776 | ip6_proto { }
777 | icmp4_proto { }
778 | icmpv6_proto { }
779 | udp_proto { }
780 | tcp_proto { }
781 | dns_proto { }
784 field_expr
785 : '[' skip_white number skip_white ']'
786 { field_index_validate(field_expr.field, $3, 1);
787 field_expr.type |= FIELD_EXPR_OFFSET;
788 field_expr.val.func.offset = $3;
789 field_expr.val.func.len = 1; }
790 | '[' skip_white number skip_white ':' skip_white number skip_white ']'
791 { field_index_validate(field_expr.field, $3, $7);
792 field_expr.type |= FIELD_EXPR_OFFSET;
793 field_expr.val.func.offset = $3;
794 field_expr.val.func.len = $7; }
797 field_value_expr
798 : number { field_expr.type |= FIELD_EXPR_NUMB;
799 field_expr.val.number = $1; }
800 | mac { field_expr.type |= FIELD_EXPR_MAC;
801 memcpy(field_expr.val.mac, $1, sizeof(field_expr.val.mac)); }
802 | string { field_expr.type |= FIELD_EXPR_STRING;
803 field_expr.val.str = xstrdup($1 + 1);
804 field_expr.val.str[strlen($1 + 1) - 1] = '\0'; }
805 | ip4_addr { field_expr.type |= FIELD_EXPR_IP4_ADDR;
806 field_expr.val.ip4_addr = $1; }
807 | ip6_addr { field_expr.type |= FIELD_EXPR_IP6_ADDR;
808 field_expr.val.ip6_addr = $1; }
809 | K_DINC '(' ')' { field_expr.type |= FIELD_EXPR_INC;
810 field_expr.val.func.type = PROTO_FIELD_FUNC_INC;
811 field_expr.val.func.inc = 1; }
812 | K_DINC '(' number ')'
813 { field_expr.type |= FIELD_EXPR_INC;
814 field_expr.val.func.type = PROTO_FIELD_FUNC_INC;
815 field_expr.val.func.inc = $3; }
816 | K_DINC '(' number delimiter number ')'
817 { field_expr.type |= FIELD_EXPR_INC;
818 field_expr.val.func.type = PROTO_FIELD_FUNC_INC;
819 field_expr.val.func.type |= PROTO_FIELD_FUNC_MIN;
820 field_expr.val.func.min = $3;
821 field_expr.val.func.max = $5;
822 field_expr.val.func.inc = 1; }
823 | K_DINC '(' number delimiter number delimiter number ')'
824 { field_expr.type |= FIELD_EXPR_INC;
825 field_expr.val.func.type = PROTO_FIELD_FUNC_INC;
826 field_expr.val.func.type |= PROTO_FIELD_FUNC_MIN;
827 field_expr.val.func.min = $3;
828 field_expr.val.func.max = $5;
829 field_expr.val.func.inc = $7; }
830 | K_DRND '(' ')' { field_expr.type |= FIELD_EXPR_RND;
831 field_expr.val.func.type = PROTO_FIELD_FUNC_RND; }
832 | K_DRND '(' number delimiter number ')'
833 { field_expr.type |= FIELD_EXPR_RND;
834 field_expr.val.func.type = PROTO_FIELD_FUNC_RND;
835 field_expr.val.func.min = $3;
836 field_expr.val.func.max = $5; }
839 eth_proto
840 : eth '(' eth_param_list ')' { }
844 : K_ETH { proto_add(PROTO_ETH); }
847 eth_param_list
848 : { }
849 | eth_expr { }
850 | eth_expr delimiter eth_param_list { }
853 eth_type
854 : K_ETYPE { }
855 | K_TYPE { }
856 | K_PROT { }
859 eth_field
860 : K_DADDR { proto_field_set(ETH_DST_ADDR); }
861 | K_SADDR { proto_field_set(ETH_SRC_ADDR); }
862 | eth_type { proto_field_set(ETH_TYPE); }
864 eth_expr
865 : eth_field field_expr skip_white '=' skip_white field_value_expr
866 { proto_field_expr_eval(); }
867 | eth_field skip_white '=' skip_white field_value_expr
868 { proto_field_expr_eval(); }
871 pause_proto
872 : pause '(' pause_param_list ')' { }
875 pause
876 : K_PAUSE { proto_add(PROTO_PAUSE); }
879 pause_param_list
880 : { }
881 | pause_expr { }
882 | pause_expr delimiter pause_param_list { }
885 pause_field
886 : K_CODE { proto_field_set(PAUSE_OPCODE); }
887 | K_TIME { proto_field_set(PAUSE_TIME); }
890 pause_expr
891 : pause_field field_expr skip_white '=' skip_white field_value_expr
892 { proto_field_expr_eval(); }
893 | pause_field skip_white '=' skip_white field_value_expr
894 { proto_field_expr_eval(); }
897 pfc_proto
898 : pfc '(' pfc_param_list ')' { }
902 : K_PFC { proto_add(PROTO_PFC); }
905 pfc_param_list
906 : { }
907 | pfc_expr { }
908 | pfc_expr delimiter pfc_param_list { }
911 pfc_field
912 : K_CODE { proto_field_set(PFC_OPCODE); }
913 | K_PRIO { proto_field_set(PFC_PRIO); }
914 | K_PRIO '(' number ')'
915 { if ($3 > 7) {
916 yyerror("pfc: Invalid prio(index) parameter");
917 panic("pfc: prio(0)..prio(7) is allowed only\n");
919 proto_field_set(PFC_PRIO_0 + $3); }
920 | K_TIME '(' number ')'
921 { if ($3 > 7) {
922 yyerror("pfc: Invalid time(index) parameter");
923 panic("pfc: time(0)..time(7) is allowed only\n");
925 proto_field_set(PFC_TIME_0 + $3); }
928 pfc_expr
929 : pfc_field field_expr skip_white '=' skip_white field_value_expr
930 { proto_field_expr_eval(); }
931 | pfc_field skip_white '=' skip_white field_value_expr
932 { proto_field_expr_eval(); }
935 vlan_proto
936 : vlan '(' vlan_param_list ')' { }
939 vlan
940 : K_VLAN { proto_add(PROTO_VLAN); }
943 vlan_param_list
944 : { }
945 | vlan_expr { }
946 | vlan_expr delimiter vlan_param_list { }
949 vlan_type
950 : K_TPID { }
951 | K_PROT
954 vlan_field
955 : vlan_type { proto_field_set(VLAN_TPID); }
956 | K_TCI { proto_field_set(VLAN_TCI); }
957 | K_PCP { proto_field_set(VLAN_PCP); }
958 | K_DEI { proto_field_set(VLAN_DEI); }
959 | K_ID { proto_field_set(VLAN_VID); }
962 vlan_expr
963 : vlan_field field_expr skip_white '=' skip_white field_value_expr
964 { proto_field_expr_eval(); }
965 | vlan_field skip_white '=' skip_white field_value_expr
966 { proto_field_expr_eval(); }
967 | K_1Q
968 { proto_hdr_field_set_be16(hdr, VLAN_TPID, ETH_P_8021Q); }
969 | K_1AD
970 { proto_hdr_field_set_be16(hdr, VLAN_TPID, ETH_P_8021AD); }
973 mpls_proto
974 : mpls '(' mpls_param_list ')' { }
977 mpls
978 : K_MPLS { proto_add(PROTO_MPLS); }
981 mpls_param_list
982 : { }
983 | mpls_expr { }
984 | mpls_expr delimiter mpls_param_list { }
987 mpls_tc
988 : K_TC { }
989 | K_EXP { }
992 mpls_field
993 : K_LABEL { proto_field_set(MPLS_LABEL); }
994 | mpls_tc { proto_field_set(MPLS_TC); }
995 | K_LAST { proto_field_set(MPLS_LAST); }
996 | K_TTL { proto_field_set(MPLS_TTL); }
999 mpls_expr
1000 : mpls_field field_expr skip_white '=' skip_white field_value_expr
1001 { proto_field_expr_eval(); }
1002 | mpls_field skip_white '=' skip_white field_value_expr
1003 { proto_field_expr_eval(); }
1006 arp_proto
1007 : arp '(' arp_param_list ')' { }
1010 arp_param_list
1011 : { }
1012 | arp_expr { }
1013 | arp_expr delimiter arp_param_list { }
1016 arp_field
1017 : K_HTYPE
1018 { proto_field_set(ARP_HTYPE); }
1019 | K_PTYPE
1020 { proto_field_set(ARP_PTYPE); }
1021 | K_SHA
1022 { proto_field_set(ARP_SHA); }
1023 | K_THA
1024 { proto_field_set(ARP_THA); }
1025 | K_SPA
1026 { proto_field_set(ARP_SPA); }
1027 | K_TPA
1028 { proto_field_set(ARP_TPA); }
1031 arp_expr
1032 : arp_field field_expr skip_white '=' skip_white field_value_expr
1033 { proto_field_expr_eval(); }
1034 | arp_field skip_white '=' skip_white field_value_expr
1035 { proto_field_expr_eval(); }
1036 | K_OPER field_expr skip_white '=' skip_white field_value_expr
1037 { proto_field_set(ARP_OPER);
1038 proto_field_expr_eval(); }
1039 | K_OPER skip_white '=' skip_white field_value_expr
1040 { proto_field_set(ARP_OPER);
1041 proto_field_expr_eval(); }
1042 | K_OPER skip_white '=' skip_white K_REQUEST
1043 { proto_hdr_field_set_be16(hdr, ARP_OPER, ARPOP_REQUEST); }
1044 | K_OPER skip_white '=' skip_white K_REPLY
1045 { proto_hdr_field_set_be16(hdr, ARP_OPER, ARPOP_REPLY); }
1046 | K_REQUEST
1047 { proto_hdr_field_set_be16(hdr, ARP_OPER, ARPOP_REQUEST); }
1048 | K_REPLY
1049 { proto_hdr_field_set_be16(hdr, ARP_OPER, ARPOP_REPLY); }
1053 : K_ARP { proto_add(PROTO_ARP); }
1056 ip4_proto
1057 : ip4 '(' ip4_param_list ')' { }
1060 ip4_param_list
1061 : { }
1062 | ip4_expr { }
1063 | ip4_expr delimiter ip4_param_list { }
1066 ip4_field
1067 : K_VER { proto_field_set(IP4_VER); }
1068 | K_IHL { proto_field_set(IP4_IHL); }
1069 | K_DADDR { proto_field_set(IP4_DADDR); }
1070 | K_SADDR { proto_field_set(IP4_SADDR); }
1071 | K_PROT { proto_field_set(IP4_PROTO); }
1072 | K_TTL { proto_field_set(IP4_TTL); }
1073 | K_DSCP { proto_field_set(IP4_DSCP); }
1074 | K_ECN { proto_field_set(IP4_ECN); }
1075 | K_TOS { proto_field_set(IP4_TOS); }
1076 | K_LEN { proto_field_set(IP4_LEN); }
1077 | K_ID { proto_field_set(IP4_ID); }
1078 | K_FLAGS { proto_field_set(IP4_FLAGS); }
1079 | K_FRAG { proto_field_set(IP4_FRAG_OFFS); }
1080 | K_CSUM { proto_field_set(IP4_CSUM); }
1083 ip4_expr
1084 : ip4_field field_expr skip_white '=' skip_white field_value_expr
1085 { proto_field_expr_eval(); }
1086 | ip4_field skip_white '=' skip_white field_value_expr
1087 { proto_field_expr_eval(); }
1088 | K_DF { proto_hdr_field_set_be16(hdr, IP4_DF, 1); }
1089 | K_MF { proto_hdr_field_set_be16(hdr, IP4_MF, 1); }
1093 : K_IP4 { proto_add(PROTO_IP4); }
1096 ip6_proto
1097 : ip6 '(' ip6_param_list ')' { }
1100 ip6_param_list
1101 : { }
1102 | ip6_expr { }
1103 | ip6_expr delimiter ip6_param_list { }
1106 ip6_hop_limit
1107 : K_HOP_LIMIT { }
1108 | K_TTL { }
1111 ip6_field
1112 : K_VER { proto_field_set(IP6_VER); }
1113 | K_TC { proto_field_set(IP6_CLASS); }
1114 | K_FLOW { proto_field_set(IP6_FLOW_LBL); }
1115 | K_LEN { proto_field_set(IP6_LEN); }
1116 | K_NEXT_HDR { proto_field_set(IP6_NEXT_HDR); }
1117 | ip6_hop_limit { proto_field_set(IP6_HOP_LIMIT); }
1118 | K_SADDR { proto_field_set(IP6_SADDR); }
1119 | K_DADDR { proto_field_set(IP6_DADDR) ; }
1122 ip6_expr
1123 : ip6_field field_expr skip_white '=' skip_white field_value_expr
1124 { proto_field_expr_eval(); }
1125 | ip6_field skip_white '=' skip_white field_value_expr
1126 { proto_field_expr_eval(); }
1130 : K_IP6 { proto_add(PROTO_IP6); }
1133 icmp4_proto
1134 : icmp4 '(' icmp4_param_list ')' { }
1137 icmp4_param_list
1138 : { }
1139 | icmp4_expr { }
1140 | icmp4_expr delimiter icmp4_param_list { }
1143 icmp4_field
1144 : K_TYPE { proto_field_set(ICMPV4_TYPE); }
1145 | K_CODE { proto_field_set(ICMPV4_CODE); }
1146 | K_ID { proto_field_set(ICMPV4_ID); }
1147 | K_SEQ { proto_field_set(ICMPV4_SEQ); }
1148 | K_MTU { proto_field_set(ICMPV4_MTU); }
1149 | K_ADDR { proto_field_set(ICMPV4_REDIR_ADDR); }
1152 icmp4_expr
1153 : icmp4_field field_expr skip_white '=' skip_white field_value_expr
1154 { proto_field_expr_eval(); }
1155 | icmp4_field skip_white '=' skip_white field_value_expr
1156 { proto_field_expr_eval(); }
1157 | K_ECHO_REQUEST
1158 { proto_hdr_field_set_u8(hdr, ICMPV4_TYPE, ICMP_ECHO);
1159 proto_hdr_field_set_u8(hdr, ICMPV4_CODE, 0); }
1160 | K_ECHO_REPLY
1161 { proto_hdr_field_set_u8(hdr, ICMPV4_TYPE, ICMP_ECHOREPLY);
1162 proto_hdr_field_set_u8(hdr, ICMPV4_CODE, 0); }
1165 icmp4
1166 : K_ICMP4 { proto_add(PROTO_ICMP4); }
1169 icmpv6_proto
1170 : icmp6 '(' icmp6_param_list ')' { }
1173 icmp6_param_list
1174 : { }
1175 | icmp6_expr { }
1176 | icmp6_expr delimiter icmp6_param_list { }
1179 icmp6_field
1180 : K_CODE { proto_field_set(ICMPV6_CODE); }
1181 | K_CSUM { proto_field_set(ICMPV6_CSUM); }
1184 icmp6_expr
1185 : icmp6_field field_expr skip_white '=' skip_white field_value_expr
1186 { proto_field_expr_eval(); }
1187 | icmp6_field skip_white '=' skip_white field_value_expr
1188 { proto_field_expr_eval(); }
1189 | K_TYPE field_expr skip_white '=' skip_white field_value_expr
1190 { proto_field_set(ICMPV6_TYPE);
1191 proto_field_expr_eval(); }
1192 | K_TYPE skip_white '=' skip_white field_value_expr
1193 { proto_field_set(ICMPV6_TYPE);
1194 proto_field_expr_eval(); }
1195 | K_TYPE skip_white '=' K_ECHO_REQUEST
1196 { proto_hdr_field_set_u8(hdr, ICMPV6_TYPE, ICMPV6_ECHO_REQUEST); }
1197 | K_ECHO_REQUEST
1198 { proto_hdr_field_set_u8(hdr, ICMPV6_TYPE, ICMPV6_ECHO_REQUEST); }
1199 | K_TYPE skip_white '=' K_ECHO_REPLY
1200 { proto_hdr_field_set_u8(hdr, ICMPV6_TYPE, ICMPV6_ECHO_REPLY); }
1201 | K_ECHO_REPLY
1202 { proto_hdr_field_set_u8(hdr, ICMPV6_TYPE, ICMPV6_ECHO_REPLY); }
1204 icmp6
1205 : K_ICMP6 { proto_add(PROTO_ICMP6); }
1208 udp_proto
1209 : udp '(' udp_param_list ')' { }
1212 udp_param_list
1213 : { }
1214 | udp_expr { }
1215 | udp_expr delimiter udp_param_list { }
1218 udp_field
1219 : K_SPORT { proto_field_set(UDP_SPORT); }
1220 | K_DPORT { proto_field_set(UDP_DPORT); }
1221 | K_LEN { proto_field_set(UDP_LEN); }
1222 | K_CSUM { proto_field_set(UDP_CSUM); }
1225 udp_expr
1226 : udp_field field_expr skip_white '=' skip_white field_value_expr
1227 { proto_field_expr_eval(); }
1228 | udp_field skip_white '=' skip_white field_value_expr
1229 { proto_field_expr_eval(); }
1233 : K_UDP { proto_add(PROTO_UDP); }
1236 tcp_proto
1237 : tcp '(' tcp_param_list ')' { }
1240 tcp_param_list
1241 : { }
1242 | tcp_expr { }
1243 | tcp_expr delimiter tcp_param_list { }
1246 tcp_field
1247 : K_SPORT { proto_field_set(TCP_SPORT); }
1248 | K_DPORT { proto_field_set(TCP_DPORT); }
1249 | K_SEQ { proto_field_set(TCP_SEQ); }
1250 | K_ACK_SEQ { proto_field_set(TCP_ACK_SEQ); }
1251 | K_DOFF { proto_field_set(TCP_DOFF); }
1252 | K_WINDOW { proto_field_set(TCP_WINDOW); }
1253 | K_CSUM { proto_field_set(TCP_CSUM); }
1254 | K_URG_PTR { proto_field_set(TCP_URG_PTR); }
1257 tcp_expr
1258 : tcp_field field_expr skip_white '=' skip_white field_value_expr
1259 { proto_field_expr_eval(); }
1260 | tcp_field skip_white '=' skip_white field_value_expr
1261 { proto_field_expr_eval(); }
1262 | K_CWR { proto_hdr_field_set_be16(hdr, TCP_CWR, 1); }
1263 | K_ECE { proto_hdr_field_set_be16(hdr, TCP_ECE, 1); }
1264 | K_URG { proto_hdr_field_set_be16(hdr, TCP_URG, 1); }
1265 | K_ACK { proto_hdr_field_set_be16(hdr, TCP_ACK, 1); }
1266 | K_PSH { proto_hdr_field_set_be16(hdr, TCP_PSH, 1); }
1267 | K_RST { proto_hdr_field_set_be16(hdr, TCP_RST, 1); }
1268 | K_SYN { proto_hdr_field_set_be16(hdr, TCP_SYN, 1); }
1269 | K_FIN { proto_hdr_field_set_be16(hdr, TCP_FIN, 1); }
1273 : K_TCP { proto_add(PROTO_TCP); }
1276 dns_proto
1277 : dns '(' dns_param_list ')' { }
1280 dns_param_list
1281 : { }
1282 | dns_expr { }
1283 | dns_expr delimiter dns_param_list { }
1286 dns_field
1287 : K_ID { proto_field_set(DNS_ID); }
1288 | K_QR { proto_field_set(DNS_QR); }
1289 | K_OPER { proto_field_set(DNS_OPCODE); }
1290 | K_AANSWER { proto_field_set(DNS_AA); }
1291 | K_TRUNC { proto_field_set(DNS_TC); }
1292 | K_RDESIRED { proto_field_set(DNS_RD); }
1293 | K_RAVAIL { proto_field_set(DNS_RA); }
1294 | K_ZERO { proto_field_set(DNS_ZERO); }
1295 | K_RCODE { proto_field_set(DNS_RCODE); }
1296 | K_QDCOUNT { proto_field_set(DNS_QD_COUNT); }
1297 | K_ANCOUNT { proto_field_set(DNS_AN_COUNT); }
1298 | K_NSCOUNT { proto_field_set(DNS_NS_COUNT); }
1299 | K_ARCOUNT { proto_field_set(DNS_AR_COUNT); }
1302 dns_query
1303 : K_QUERY { proto_push_sub_hdr(DNS_QUERY_HDR); }
1306 dns_query_name
1307 : K_NAME { proto_field_set(DNS_QUERY_NAME); }
1310 dns_query_field
1311 : K_TYPE { proto_field_set(DNS_QUERY_TYPE); }
1312 | K_CLASS { proto_field_set(DNS_QUERY_CLASS); }
1315 dns_query_expr
1316 : dns_query_field field_expr skip_white '=' skip_white field_value_expr
1317 { proto_field_expr_eval(); }
1318 | dns_query_field skip_white '=' skip_white field_value_expr
1319 { proto_field_expr_eval(); }
1320 | dns_query_name field_expr skip_white '=' skip_white field_value_expr
1321 { if (field_expr.type & FIELD_EXPR_STRING)
1322 field_expr.type = FIELD_EXPR_FQDN;
1323 proto_field_expr_eval(); }
1324 | dns_query_name skip_white '=' skip_white field_value_expr
1325 { if (field_expr.type & FIELD_EXPR_STRING)
1326 field_expr.type = FIELD_EXPR_FQDN;
1327 proto_field_expr_eval(); }
1330 dns_query_param_list
1331 : { }
1332 | dns_query_expr { }
1333 | dns_query_expr delimiter dns_query_param_list { }
1336 dns_query_hdr
1337 : dns_query '(' dns_query_param_list ')' { }
1340 dns_rrecord
1341 : K_ANSWER { proto_push_sub_hdr(DNS_ANSWER_HDR); }
1342 | K_AUTH { proto_push_sub_hdr(DNS_AUTH_HDR); }
1343 | K_ADD { proto_push_sub_hdr(DNS_ADD_HDR); }
1346 dns_rrecord_name
1347 : K_NAME { proto_field_set(DNS_RRECORD_NAME); }
1350 dns_rrecord_data_addr
1351 : ip4_addr
1352 { proto_hdr_field_set_u32(hdr, DNS_RRECORD_DATA, $1.s_addr);
1353 proto_hdr_field_set_be16(hdr, DNS_RRECORD_TYPE, 1); }
1354 | ip6_addr
1355 { proto_hdr_field_set_bytes(hdr, DNS_RRECORD_DATA, (uint8_t *)&$1.s6_addr, 16);
1356 proto_hdr_field_set_be16(hdr, DNS_RRECORD_TYPE, 28); }
1359 dns_rrecord_data_fqdn
1360 : string
1361 { char *str = xstrdup($1 + 1);
1362 char *fqdn;
1363 str[strlen($1 + 1) - 1] = '\0';
1364 fqdn = str2fqdn(str);
1365 proto_hdr_field_set_bytes(hdr, DNS_RRECORD_DATA, (uint8_t *) fqdn, strlen(fqdn) + 1);
1366 xfree(str);
1367 xfree(fqdn); }
1370 dns_rrecord_data_expr
1371 : K_ADDR '(' skip_white dns_rrecord_data_addr skip_white ')'
1373 | K_NS '(' skip_white dns_rrecord_data_fqdn skip_white ')'
1374 { proto_hdr_field_set_be16(hdr, DNS_RRECORD_TYPE, 2); }
1375 | K_CNAME '(' skip_white dns_rrecord_data_fqdn skip_white ')'
1376 { proto_hdr_field_set_be16(hdr, DNS_RRECORD_TYPE, 5); }
1377 | K_PTR '(' skip_white dns_rrecord_data_fqdn skip_white ')'
1378 { proto_hdr_field_set_be16(hdr, DNS_RRECORD_TYPE, 12); }
1381 dns_rrecord_field
1382 : K_TYPE { proto_field_set(DNS_RRECORD_TYPE); }
1383 | K_CLASS { proto_field_set(DNS_RRECORD_CLASS); }
1384 | K_TTL { proto_field_set(DNS_RRECORD_TTL); }
1385 | K_LEN { proto_field_set(DNS_RRECORD_LEN); }
1386 | K_DATA { proto_field_set(DNS_RRECORD_DATA); }
1389 dns_rrecord_expr
1390 : dns_rrecord_field field_expr skip_white '=' skip_white field_value_expr
1391 { proto_field_expr_eval(); }
1392 | dns_rrecord_field skip_white '=' skip_white field_value_expr
1393 { proto_field_expr_eval(); }
1394 | dns_rrecord_name field_expr skip_white '=' skip_white field_value_expr
1395 { if (field_expr.type & FIELD_EXPR_STRING)
1396 field_expr.type = FIELD_EXPR_FQDN;
1397 proto_field_expr_eval(); }
1398 | dns_rrecord_name skip_white '=' skip_white field_value_expr
1399 { if (field_expr.type & FIELD_EXPR_STRING)
1400 field_expr.type = FIELD_EXPR_FQDN;
1401 proto_field_expr_eval(); }
1402 | dns_rrecord_data_expr
1406 dns_rrecord_param_list
1407 : { }
1408 | dns_rrecord_expr { }
1409 | dns_rrecord_expr delimiter dns_rrecord_param_list { }
1412 dns_rrecord_hdr
1413 : dns_rrecord '(' dns_rrecord_param_list ')' { }
1416 dns_expr
1417 : dns_field field_expr skip_white '=' skip_white field_value_expr
1418 { proto_field_expr_eval(); }
1419 | dns_field skip_white '=' skip_white field_value_expr
1420 { proto_field_expr_eval(); }
1421 | dns_query_hdr { proto_pop_sub_hdr(); }
1422 | dns_rrecord_hdr { proto_pop_sub_hdr(); }
1426 : K_DNS { proto_add(PROTO_DNS); }
1430 static void finalize_packet(void)
1432 /* XXX hack ... we allocated one packet pointer too much */
1433 plen--;
1434 dlen--;
1437 static void dump_conf(void)
1439 size_t i, j;
1441 for (i = 0; i < plen; ++i) {
1442 printf("[%zu] pkt\n", i);
1443 printf(" len %zu cnts %zu rnds %zu\n",
1444 packets[i].len,
1445 packet_dyn[i].clen,
1446 packet_dyn[i].rlen);
1448 printf(" payload ");
1449 for (j = 0; j < packets[i].len; ++j)
1450 printf("%02x ", packets[i].payload[j]);
1451 printf("\n");
1453 for (j = 0; j < packet_dyn[i].clen; ++j)
1454 printf(" cnt%zu [%u,%u], inc %u, off %jd type %s\n", j,
1455 packet_dyn[i].cnt[j].min,
1456 packet_dyn[i].cnt[j].max,
1457 packet_dyn[i].cnt[j].inc,
1458 (intmax_t)packet_dyn[i].cnt[j].off,
1459 packet_dyn[i].cnt[j].type == TYPE_INC ?
1460 "inc" : "dec");
1462 for (j = 0; j < packet_dyn[i].rlen; ++j)
1463 printf(" rnd%zu off %jd\n", j,
1464 (intmax_t)packet_dyn[i].rnd[j].off);
1468 void cleanup_packets(void)
1470 size_t i, j;
1472 for (i = 0; i < plen; ++i) {
1473 struct packet *pkt = &packets[i];
1475 if (pkt->len > 0)
1476 xfree(pkt->payload);
1478 for (j = 0; j < pkt->headers_count; j++) {
1479 struct proto_hdr *hdr = pkt->headers[j];
1480 uint32_t k;
1482 for (k = 0; k < hdr->sub_headers_count; k++)
1483 xfree(hdr->sub_headers[k]);
1485 if (hdr->sub_headers)
1486 xfree(hdr->sub_headers);
1488 if (hdr->fields)
1489 xfree(hdr->fields);
1491 xfree(hdr);
1495 free(packets);
1497 for (i = 0; i < dlen; ++i) {
1498 free(packet_dyn[i].cnt);
1499 free(packet_dyn[i].rnd);
1501 for (j = 0; j < packet_dyn[j].flen; j++)
1502 xfree(packet_dyn[i].fields[j]);
1504 free(packet_dyn[i].fields);
1507 free(packet_dyn);
1510 void compile_packets(char *file, bool verbose, unsigned int cpu,
1511 bool invoke_cpp, char *const cpp_argv[])
1513 char tmp_file[128];
1514 int ret = -1;
1516 if (strncmp("-", file, strlen("-")) && access(file, R_OK)) {
1517 fprintf(stderr, "Cannot access %s: %s!\n", file, strerror(errno));
1518 die();
1521 memset(tmp_file, 0, sizeof(tmp_file));
1522 our_cpu = cpu;
1524 if (invoke_cpp) {
1525 if (cpp_exec(file, tmp_file, sizeof(tmp_file), cpp_argv)) {
1526 fprintf(stderr, "Failed to invoke C preprocessor!\n");
1527 goto err;
1529 file = tmp_file;
1532 if (!strncmp("-", file, strlen("-")))
1533 yyin = stdin;
1534 else
1535 yyin = fopen(file, "r");
1536 if (!yyin) {
1537 fprintf(stderr, "Cannot open %s: %s!\n", file, strerror(errno));
1538 goto err;
1541 realloc_packet();
1542 if (yyparse() != 0)
1543 goto err;
1544 finalize_packet();
1546 if (our_cpu == 0 && verbose)
1547 dump_conf();
1549 ret = 0;
1550 err:
1551 if (yyin && yyin != stdin)
1552 fclose(yyin);
1554 if (invoke_cpp)
1555 unlink(tmp_file);
1556 if (ret)
1557 die();
1560 void compile_packets_str(char *str, bool verbose, unsigned int cpu)
1562 int ret = 1;
1564 our_cpu = cpu;
1565 realloc_packet();
1567 yy_scan_string(str);
1568 if (yyparse() != 0)
1569 goto err;
1571 finalize_packet();
1572 if (our_cpu == 0 && verbose)
1573 dump_conf();
1575 ret = 0;
1576 err:
1577 yylex_destroy();
1579 if (ret)
1580 die();
1583 void yyerror(const char *err)
1585 fprintf(stderr, "Syntax error at line %d, char '%s': %s\n", yylineno, yytext, err);