2 * We want a reentrant parser.
7 * We also want a reentrant scanner, so we have to pass the
8 * handle for the reentrant scanner to the parser, and the
9 * parser has to pass it to the lexical analyzer.
11 * We use void * rather than yyscan_t because, at least with some
12 * versions of Flex and Bison, if you use yyscan_t in %parse-param and
13 * %lex-param, you have to include scanner.h before grammar.h to get
14 * yyscan_t declared, and you have to include grammar.h before scanner.h
15 * to get YYSTYPE declared. Using void * breaks the cycle; the Flex
16 * documentation says yyscan_t is just a void *.
18 %parse
-param
{void *yyscanner
}
19 %lex
-param
{void *yyscanner
}
22 * According to bison documentation, shift/reduce conflicts are not an issue
23 * in most parsers as long as the number does not evolve over time:
24 * https://www.gnu.org/software/bison/manual/html_node/Expect-Decl.html
25 * So, following the advice use %expect to check the amount of shift/reduce
28 * This doesn't appear to work in Berkeley YACC - 1.9 20170709; it still
29 * warns of 38 shift/reduce conflicts.
31 * The Berkeley YACC documentation:
33 * https://invisible-island.net/byacc/manpage/yacc.html
35 * claims that "Bison's support for "%expect" is broken in more than one
36 * release.", but doesn't give details. Hopefully, that only means that
37 * you get warnings even if you have the expected number of shift/reduce
38 * conflicts, not that anything else fails.
43 * And we need to pass the compiler state to the scanner.
45 %parse
-param
{ compiler_state_t
*cstate
}
49 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
50 * The Regents of the University of California. All rights reserved.
52 * Redistribution and use in source and binary forms, with or without
53 * modification, are permitted provided that: (1) source code distributions
54 * retain the above copyright notice and this paragraph in its entirety, (2)
55 * distributions including binary code include the above copyright notice and
56 * this paragraph in its entirety in the documentation or other materials
57 * provided with the distribution, and (3) all advertising materials mentioning
58 * features or use of this software display the following acknowledgement:
59 * ``This product includes software developed by the University of California,
60 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
61 * the University nor the names of its contributors may be used to endorse
62 * or promote products derived from this software without specific prior
64 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
65 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
66 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
77 #include <sys/types.h>
78 #include <sys/socket.h>
85 #include <netinet/in.h>
86 #include <arpa/inet.h>
91 #include "diag-control.h"
100 * TODO(tuxillo): Upstream this change to libpcap since our pfvar.h headers
101 * are in a different path.
104 #ifdef HAVE_NET_PF_PFVAR_H
106 #include <net/pf/pfvar.h>
107 #include <net/pf/if_pflog.h>
110 #include "ieee80211.h"
111 #include <pcap/namedb.h>
113 #ifdef HAVE_OS_PROTO_H
114 #include "os-proto.h"
119 * Both Berkeley YACC and Bison define yydebug (under whatever name
120 * it has) as a global, but Bison does so only if YYDEBUG is defined.
121 * Berkeley YACC define it even if YYDEBUG isn't defined; declare it
122 * here to suppress a warning.
124 #if !defined(YYDEBUG)
129 * In Berkeley YACC, yynerrs (under whatever name it has) is global,
130 * even if it's building a reentrant parser. In Bison, it's local
131 * in reentrant parsers.
133 * Declare it to squelch a warning.
138 #define QSET(q, p, d, a) (q).proto = (unsigned char)(p),\
139 (q
).dir
= (unsigned char)(d
),\
140 (q
).addr
= (unsigned char)(a
)
144 const char *s
; /* string */
147 static const struct tok ieee80211_types
[] = {
148 { IEEE80211_FC0_TYPE_DATA
, "data" },
149 { IEEE80211_FC0_TYPE_MGT
, "mgt" },
150 { IEEE80211_FC0_TYPE_MGT
, "management" },
151 { IEEE80211_FC0_TYPE_CTL
, "ctl" },
152 { IEEE80211_FC0_TYPE_CTL
, "control" },
155 static const struct tok ieee80211_mgt_subtypes
[] = {
156 { IEEE80211_FC0_SUBTYPE_ASSOC_REQ
, "assocreq" },
157 { IEEE80211_FC0_SUBTYPE_ASSOC_REQ
, "assoc-req" },
158 { IEEE80211_FC0_SUBTYPE_ASSOC_RESP
, "assocresp" },
159 { IEEE80211_FC0_SUBTYPE_ASSOC_RESP
, "assoc-resp" },
160 { IEEE80211_FC0_SUBTYPE_REASSOC_REQ
, "reassocreq" },
161 { IEEE80211_FC0_SUBTYPE_REASSOC_REQ
, "reassoc-req" },
162 { IEEE80211_FC0_SUBTYPE_REASSOC_RESP
, "reassocresp" },
163 { IEEE80211_FC0_SUBTYPE_REASSOC_RESP
, "reassoc-resp" },
164 { IEEE80211_FC0_SUBTYPE_PROBE_REQ
, "probereq" },
165 { IEEE80211_FC0_SUBTYPE_PROBE_REQ
, "probe-req" },
166 { IEEE80211_FC0_SUBTYPE_PROBE_RESP
, "proberesp" },
167 { IEEE80211_FC0_SUBTYPE_PROBE_RESP
, "probe-resp" },
168 { IEEE80211_FC0_SUBTYPE_BEACON
, "beacon" },
169 { IEEE80211_FC0_SUBTYPE_ATIM
, "atim" },
170 { IEEE80211_FC0_SUBTYPE_DISASSOC
, "disassoc" },
171 { IEEE80211_FC0_SUBTYPE_DISASSOC
, "disassociation" },
172 { IEEE80211_FC0_SUBTYPE_AUTH
, "auth" },
173 { IEEE80211_FC0_SUBTYPE_AUTH
, "authentication" },
174 { IEEE80211_FC0_SUBTYPE_DEAUTH
, "deauth" },
175 { IEEE80211_FC0_SUBTYPE_DEAUTH
, "deauthentication" },
178 static const struct tok ieee80211_ctl_subtypes
[] = {
179 { IEEE80211_FC0_SUBTYPE_PS_POLL
, "ps-poll" },
180 { IEEE80211_FC0_SUBTYPE_RTS
, "rts" },
181 { IEEE80211_FC0_SUBTYPE_CTS
, "cts" },
182 { IEEE80211_FC0_SUBTYPE_ACK
, "ack" },
183 { IEEE80211_FC0_SUBTYPE_CF_END
, "cf-end" },
184 { IEEE80211_FC0_SUBTYPE_CF_END_ACK
, "cf-end-ack" },
187 static const struct tok ieee80211_data_subtypes
[] = {
188 { IEEE80211_FC0_SUBTYPE_DATA
, "data" },
189 { IEEE80211_FC0_SUBTYPE_CF_ACK
, "data-cf-ack" },
190 { IEEE80211_FC0_SUBTYPE_CF_POLL
, "data-cf-poll" },
191 { IEEE80211_FC0_SUBTYPE_CF_ACPL
, "data-cf-ack-poll" },
192 { IEEE80211_FC0_SUBTYPE_NODATA
, "null" },
193 { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK
, "cf-ack" },
194 { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL
, "cf-poll" },
195 { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL
, "cf-ack-poll" },
196 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA
, "qos-data" },
197 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK
, "qos-data-cf-ack" },
198 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL
, "qos-data-cf-poll" },
199 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL
, "qos-data-cf-ack-poll" },
200 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA
, "qos" },
201 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL
, "qos-cf-poll" },
202 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL
, "qos-cf-ack-poll" },
205 static const struct tok llc_s_subtypes
[] = {
211 static const struct tok llc_u_subtypes
[] = {
214 { LLC_DISC
, "disc" },
216 { LLC_SABME
, "sabme" },
217 { LLC_TEST
, "test" },
219 { LLC_FRMR
, "frmr" },
224 const struct tok
*tok
;
226 static const struct type2tok ieee80211_type_subtypes
[] = {
227 { IEEE80211_FC0_TYPE_MGT
, ieee80211_mgt_subtypes
},
228 { IEEE80211_FC0_TYPE_CTL
, ieee80211_ctl_subtypes
},
229 { IEEE80211_FC0_TYPE_DATA
, ieee80211_data_subtypes
},
234 str2tok
(const char *str
, const struct tok
*toks
)
238 for
(i
= 0; toks
[i
].s
!= NULL
; i
++) {
239 if
(pcap_strcasecmp
(toks
[i
].s
, str
) == 0) {
241 * Just in case somebody is using this to
242 * generate values of -1/0xFFFFFFFF.
243 * That won't work, as it's indistinguishable
254 static const struct qual qerr
= { Q_UNDEF
, Q_UNDEF
, Q_UNDEF
, Q_UNDEF
};
257 yyerror(void *yyscanner _U_
, compiler_state_t
*cstate
, const char *msg
)
259 bpf_set_error
(cstate
, "can't parse filter expression: %s", msg
);
262 #ifdef HAVE_NET_PFVAR_H
264 pfreason_to_num
(compiler_state_t
*cstate
, const char *reason
)
266 const char *reasons
[] = PFRES_NAMES
;
269 for
(i
= 0; reasons
[i
]; i
++) {
270 if
(pcap_strcasecmp
(reason
, reasons
[i
]) == 0)
273 bpf_set_error
(cstate
, "unknown PF reason \"%s\"", reason
);
278 pfaction_to_num
(compiler_state_t
*cstate
, const char *action
)
280 if
(pcap_strcasecmp
(action
, "pass") == 0 ||
281 pcap_strcasecmp
(action
, "accept") == 0)
283 else if
(pcap_strcasecmp
(action
, "drop") == 0 ||
284 pcap_strcasecmp
(action
, "block") == 0)
286 #if HAVE_PF_NAT_THROUGH_PF_NORDR
287 else if
(pcap_strcasecmp
(action
, "rdr") == 0)
289 else if
(pcap_strcasecmp
(action
, "nat") == 0)
291 else if
(pcap_strcasecmp
(action
, "binat") == 0)
293 else if
(pcap_strcasecmp
(action
, "nordr") == 0)
297 bpf_set_error
(cstate
, "unknown PF action \"%s\"", action
);
301 #else /* !HAVE_NET_PFVAR_H */
303 pfreason_to_num
(compiler_state_t
*cstate
, const char *reason _U_
)
305 bpf_set_error
(cstate
, "libpcap was compiled on a machine without pf support");
310 pfaction_to_num
(compiler_state_t
*cstate
, const char *action _U_
)
312 bpf_set_error
(cstate
, "libpcap was compiled on a machine without pf support");
315 #endif /* HAVE_NET_PFVAR_H */
318 * For calls that might return an "an error occurred" value.
320 #define CHECK_INT_VAL(val) if (val == -1) YYABORT
321 #define CHECK_PTR_VAL(val) if (val == NULL) YYABORT
341 %type
<blk
> expr id nid pid term rterm qid
343 %type
<i
> pqual dqual aqual ndaqual
345 %type
<i
> byteop pname relop irelop
347 %type
<blk
> and or paren not null prog
348 %type
<rblk
> other pfvar p80211 pllc
349 %type
<i
> atmtype atmmultitype
351 %type
<blk
> atmfieldvalue atmvalue atmlistvalue
353 %type
<blk
> mtp3field
354 %type
<blk
> mtp3fieldvalue mtp3value mtp3listvalue
357 %token DST SRC HOST GATEWAY
358 %token NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
359 %token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
360 %token ATALK AARP DECNET LAT SCA MOPRC MOPDL
361 %token TK_BROADCAST TK_MULTICAST
362 %token NUM INBOUND OUTBOUND
364 %token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
365 %token TYPE SUBTYPE
DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
368 %token ID EID HID HID6 AID
371 %token IPV6 ICMPV6 AH ESP
373 %token PPPOED PPPOES GENEVE
374 %token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
378 %token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
379 %token OAM OAMF4 CONNECTMSG METACONNECT
382 %token FISU LSSU MSU HFISU HLSSU HMSU
383 %token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
389 %type
<i
> action reason type subtype type_subtype dir
402 CHECK_INT_VAL
(finish_parse
(cstate
, $2.b
));
406 null: /* null */ { $$.q
= qerr
; }
409 | expr and term
{ gen_and
($1.b
, $3.b
); $$
= $3; }
410 | expr and id
{ gen_and
($1.b
, $3.b
); $$
= $3; }
411 | expr or term
{ gen_or
($1.b
, $3.b
); $$
= $3; }
412 | expr or id
{ gen_or
($1.b
, $3.b
); $$
= $3; }
414 and: AND
{ $$
= $
<blk
>0; }
416 or: OR
{ $$
= $
<blk
>0; }
419 | pnum
{ CHECK_PTR_VAL
(($$.b
= gen_ncode
(cstate
, NULL
, $1,
420 $$.q
= $
<blk
>0.q
))); }
421 | paren pid
')' { $$
= $2; }
423 nid: ID
{ CHECK_PTR_VAL
($1); CHECK_PTR_VAL
(($$.b
= gen_scode
(cstate
, $1, $$.q
= $
<blk
>0.q
))); }
424 | HID
'/' NUM
{ CHECK_PTR_VAL
($1); CHECK_PTR_VAL
(($$.b
= gen_mcode
(cstate
, $1, NULL
, $3,
425 $$.q
= $
<blk
>0.q
))); }
426 | HID NETMASK HID
{ CHECK_PTR_VAL
($1); CHECK_PTR_VAL
(($$.b
= gen_mcode
(cstate
, $1, $3, 0,
427 $$.q
= $
<blk
>0.q
))); }
430 /* Decide how to parse HID based on proto */
432 if
($$.q.addr
== Q_PORT
) {
433 bpf_set_error
(cstate
, "'port' modifier applied to ip host");
435 } else if
($$.q.addr
== Q_PORTRANGE
) {
436 bpf_set_error
(cstate
, "'portrange' modifier applied to ip host");
438 } else if
($$.q.addr
== Q_PROTO
) {
439 bpf_set_error
(cstate
, "'proto' modifier applied to ip host");
441 } else if
($$.q.addr
== Q_PROTOCHAIN
) {
442 bpf_set_error
(cstate
, "'protochain' modifier applied to ip host");
445 CHECK_PTR_VAL
(($$.b
= gen_ncode
(cstate
, $1, 0, $$.q
)));
450 CHECK_PTR_VAL
(($$.b
= gen_mcode6
(cstate
, $1, NULL
, $3,
453 bpf_set_error
(cstate
, "'ip6addr/prefixlen' not supported "
454 "in this configuration");
461 CHECK_PTR_VAL
(($$.b
= gen_mcode6
(cstate
, $1, 0, 128,
464 bpf_set_error
(cstate
, "'ip6addr' not supported "
465 "in this configuration");
469 | EID
{ CHECK_PTR_VAL
($1); CHECK_PTR_VAL
(($$.b
= gen_ecode
(cstate
, $1, $$.q
= $
<blk
>0.q
))); }
470 | AID
{ CHECK_PTR_VAL
($1); CHECK_PTR_VAL
(($$.b
= gen_acode
(cstate
, $1, $$.q
= $
<blk
>0.q
))); }
471 | not id
{ gen_not
($2.b
); $$
= $2; }
473 not: '!' { $$
= $
<blk
>0; }
475 paren: '(' { $$
= $
<blk
>0; }
478 | qid and id
{ gen_and
($1.b
, $3.b
); $$
= $3; }
479 | qid or id
{ gen_or
($1.b
, $3.b
); $$
= $3; }
481 qid: pnum
{ CHECK_PTR_VAL
(($$.b
= gen_ncode
(cstate
, NULL
, $1,
482 $$.q
= $
<blk
>0.q
))); }
486 | not term
{ gen_not
($2.b
); $$
= $2; }
488 head: pqual dqual aqual
{ QSET
($$.q
, $1, $2, $3); }
489 | pqual dqual
{ QSET
($$.q
, $1, $2, Q_DEFAULT
); }
490 | pqual aqual
{ QSET
($$.q
, $1, Q_DEFAULT
, $2); }
491 | pqual PROTO
{ QSET
($$.q
, $1, Q_DEFAULT
, Q_PROTO
); }
494 bpf_set_error
(cstate
, "protochain not supported");
497 QSET
($$.q
, $1, Q_DEFAULT
, Q_PROTOCHAIN
);
500 | pqual ndaqual
{ QSET
($$.q
, $1, Q_DEFAULT
, $2); }
502 rterm: head id
{ $$
= $2; }
503 | paren expr
')' { $$.b
= $2.b
; $$.q
= $1.q
; }
504 | pname
{ CHECK_PTR_VAL
(($$.b
= gen_proto_abbrev
(cstate
, $1))); $$.q
= qerr
; }
505 | arth relop arth
{ CHECK_PTR_VAL
(($$.b
= gen_relation
(cstate
, $2, $1, $3, 0)));
507 | arth irelop arth
{ CHECK_PTR_VAL
(($$.b
= gen_relation
(cstate
, $2, $1, $3, 1)));
509 | other
{ $$.b
= $1; $$.q
= qerr
; }
510 | atmtype
{ CHECK_PTR_VAL
(($$.b
= gen_atmtype_abbrev
(cstate
, $1))); $$.q
= qerr
; }
511 | atmmultitype
{ CHECK_PTR_VAL
(($$.b
= gen_atmmulti_abbrev
(cstate
, $1))); $$.q
= qerr
; }
512 | atmfield atmvalue
{ $$.b
= $2.b
; $$.q
= qerr
; }
513 | mtp2type
{ CHECK_PTR_VAL
(($$.b
= gen_mtp2type_abbrev
(cstate
, $1))); $$.q
= qerr
; }
514 | mtp3field mtp3value
{ $$.b
= $2.b
; $$.q
= qerr
; }
516 /* protocol level qualifiers */
518 |
{ $$
= Q_DEFAULT
; }
520 /* 'direction' qualifiers */
521 dqual: SRC
{ $$
= Q_SRC
; }
522 | DST
{ $$
= Q_DST
; }
523 | SRC OR DST
{ $$
= Q_OR
; }
524 | DST OR SRC
{ $$
= Q_OR
; }
525 | SRC AND DST
{ $$
= Q_AND
; }
526 | DST AND SRC
{ $$
= Q_AND
; }
527 | ADDR1
{ $$
= Q_ADDR1
; }
528 | ADDR2
{ $$
= Q_ADDR2
; }
529 | ADDR3
{ $$
= Q_ADDR3
; }
530 | ADDR4
{ $$
= Q_ADDR4
; }
534 /* address type qualifiers */
535 aqual: HOST
{ $$
= Q_HOST
; }
536 | NET
{ $$
= Q_NET
; }
537 | PORT
{ $$
= Q_PORT
; }
538 | PORTRANGE
{ $$
= Q_PORTRANGE
; }
540 /* non-directional address type qualifiers */
541 ndaqual: GATEWAY
{ $$
= Q_GATEWAY
; }
543 pname: LINK
{ $$
= Q_LINK
; }
545 | ARP
{ $$
= Q_ARP
; }
546 | RARP
{ $$
= Q_RARP
; }
547 | SCTP
{ $$
= Q_SCTP
; }
548 | TCP
{ $$
= Q_TCP
; }
549 | UDP
{ $$
= Q_UDP
; }
550 | ICMP
{ $$
= Q_ICMP
; }
551 | IGMP
{ $$
= Q_IGMP
; }
552 | IGRP
{ $$
= Q_IGRP
; }
553 | PIM
{ $$
= Q_PIM
; }
554 | VRRP
{ $$
= Q_VRRP
; }
555 | CARP
{ $$
= Q_CARP
; }
556 | ATALK
{ $$
= Q_ATALK
; }
557 | AARP
{ $$
= Q_AARP
; }
558 | DECNET
{ $$
= Q_DECNET
; }
559 | LAT
{ $$
= Q_LAT
; }
560 | SCA
{ $$
= Q_SCA
; }
561 | MOPDL
{ $$
= Q_MOPDL
; }
562 | MOPRC
{ $$
= Q_MOPRC
; }
563 | IPV6
{ $$
= Q_IPV6
; }
564 | ICMPV6
{ $$
= Q_ICMPV6
; }
566 | ESP
{ $$
= Q_ESP
; }
567 | ISO
{ $$
= Q_ISO
; }
568 | ESIS
{ $$
= Q_ESIS
; }
569 | ISIS
{ $$
= Q_ISIS
; }
570 | L1
{ $$
= Q_ISIS_L1
; }
571 | L2
{ $$
= Q_ISIS_L2
; }
572 | IIH
{ $$
= Q_ISIS_IIH
; }
573 | LSP
{ $$
= Q_ISIS_LSP
; }
574 | SNP
{ $$
= Q_ISIS_SNP
; }
575 | PSNP
{ $$
= Q_ISIS_PSNP
; }
576 | CSNP
{ $$
= Q_ISIS_CSNP
; }
577 | CLNP
{ $$
= Q_CLNP
; }
578 | STP
{ $$
= Q_STP
; }
579 | IPX
{ $$
= Q_IPX
; }
580 | NETBEUI
{ $$
= Q_NETBEUI
; }
581 | RADIO
{ $$
= Q_RADIO
; }
583 other: pqual TK_BROADCAST
{ CHECK_PTR_VAL
(($$
= gen_broadcast
(cstate
, $1))); }
584 | pqual TK_MULTICAST
{ CHECK_PTR_VAL
(($$
= gen_multicast
(cstate
, $1))); }
585 | LESS NUM
{ CHECK_PTR_VAL
(($$
= gen_less
(cstate
, $2))); }
586 | GREATER NUM
{ CHECK_PTR_VAL
(($$
= gen_greater
(cstate
, $2))); }
587 | CBYTE NUM byteop NUM
{ CHECK_PTR_VAL
(($$
= gen_byteop
(cstate
, $3, $2, $4))); }
588 | INBOUND
{ CHECK_PTR_VAL
(($$
= gen_inbound
(cstate
, 0))); }
589 | OUTBOUND
{ CHECK_PTR_VAL
(($$
= gen_inbound
(cstate
, 1))); }
590 | IFINDEX NUM
{ CHECK_PTR_VAL
(($$
= gen_ifindex
(cstate
, $2))); }
591 | VLAN pnum
{ CHECK_PTR_VAL
(($$
= gen_vlan
(cstate
, $2, 1))); }
592 | VLAN
{ CHECK_PTR_VAL
(($$
= gen_vlan
(cstate
, 0, 0))); }
593 | MPLS pnum
{ CHECK_PTR_VAL
(($$
= gen_mpls
(cstate
, $2, 1))); }
594 | MPLS
{ CHECK_PTR_VAL
(($$
= gen_mpls
(cstate
, 0, 0))); }
595 | PPPOED
{ CHECK_PTR_VAL
(($$
= gen_pppoed
(cstate
))); }
596 | PPPOES pnum
{ CHECK_PTR_VAL
(($$
= gen_pppoes
(cstate
, $2, 1))); }
597 | PPPOES
{ CHECK_PTR_VAL
(($$
= gen_pppoes
(cstate
, 0, 0))); }
598 | GENEVE pnum
{ CHECK_PTR_VAL
(($$
= gen_geneve
(cstate
, $2, 1))); }
599 | GENEVE
{ CHECK_PTR_VAL
(($$
= gen_geneve
(cstate
, 0, 0))); }
601 | pqual p80211
{ $$
= $2; }
605 pfvar: PF_IFNAME ID
{ CHECK_PTR_VAL
($2); CHECK_PTR_VAL
(($$
= gen_pf_ifname
(cstate
, $2))); }
606 | PF_RSET ID
{ CHECK_PTR_VAL
($2); CHECK_PTR_VAL
(($$
= gen_pf_ruleset
(cstate
, $2))); }
607 | PF_RNR NUM
{ CHECK_PTR_VAL
(($$
= gen_pf_rnr
(cstate
, $2))); }
608 | PF_SRNR NUM
{ CHECK_PTR_VAL
(($$
= gen_pf_srnr
(cstate
, $2))); }
609 | PF_REASON reason
{ CHECK_PTR_VAL
(($$
= gen_pf_reason
(cstate
, $2))); }
610 | PF_ACTION action
{ CHECK_PTR_VAL
(($$
= gen_pf_action
(cstate
, $2))); }
613 p80211: TYPE type SUBTYPE subtype
614 { CHECK_PTR_VAL
(($$
= gen_p80211_type
(cstate
, $2 |
$4,
615 IEEE80211_FC0_TYPE_MASK |
616 IEEE80211_FC0_SUBTYPE_MASK
)));
618 | TYPE type
{ CHECK_PTR_VAL
(($$
= gen_p80211_type
(cstate
, $2,
619 IEEE80211_FC0_TYPE_MASK
)));
621 | SUBTYPE type_subtype
{ CHECK_PTR_VAL
(($$
= gen_p80211_type
(cstate
, $2,
622 IEEE80211_FC0_TYPE_MASK |
623 IEEE80211_FC0_SUBTYPE_MASK
)));
625 |
DIR dir
{ CHECK_PTR_VAL
(($$
= gen_p80211_fcdir
(cstate
, $2))); }
628 type: NUM
{ if
(($1 & (~IEEE80211_FC0_TYPE_MASK
)) != 0) {
629 bpf_set_error
(cstate
, "invalid 802.11 type value 0x%02x", $1);
634 | ID
{ CHECK_PTR_VAL
($1);
635 $$
= str2tok
($1, ieee80211_types
);
637 bpf_set_error
(cstate
, "unknown 802.11 type name \"%s\"", $1);
643 subtype: NUM
{ if
(($1 & (~IEEE80211_FC0_SUBTYPE_MASK
)) != 0) {
644 bpf_set_error
(cstate
, "invalid 802.11 subtype value 0x%02x", $1);
649 | ID
{ const struct tok
*types
= NULL
;
653 if
(ieee80211_type_subtypes
[i
].tok
== NULL
) {
654 /* Ran out of types */
655 bpf_set_error
(cstate
, "unknown 802.11 type");
658 if
($
<i
>-1 == ieee80211_type_subtypes
[i
].type
) {
659 types
= ieee80211_type_subtypes
[i
].tok
;
664 $$
= str2tok
($1, types
);
666 bpf_set_error
(cstate
, "unknown 802.11 subtype name \"%s\"", $1);
672 type_subtype: ID
{ int i
;
675 if
(ieee80211_type_subtypes
[i
].tok
== NULL
) {
676 /* Ran out of types */
677 bpf_set_error
(cstate
, "unknown 802.11 type name");
680 $$
= str2tok
($1, ieee80211_type_subtypes
[i
].tok
);
682 $$ |
= ieee80211_type_subtypes
[i
].type
;
689 pllc: LLC
{ CHECK_PTR_VAL
(($$
= gen_llc
(cstate
))); }
690 | LLC ID
{ CHECK_PTR_VAL
($2);
691 if
(pcap_strcasecmp
($2, "i") == 0) {
692 CHECK_PTR_VAL
(($$
= gen_llc_i
(cstate
)));
693 } else if
(pcap_strcasecmp
($2, "s") == 0) {
694 CHECK_PTR_VAL
(($$
= gen_llc_s
(cstate
)));
695 } else if
(pcap_strcasecmp
($2, "u") == 0) {
696 CHECK_PTR_VAL
(($$
= gen_llc_u
(cstate
)));
700 subtype
= str2tok
($2, llc_s_subtypes
);
702 CHECK_PTR_VAL
(($$
= gen_llc_s_subtype
(cstate
, subtype
)));
704 subtype
= str2tok
($2, llc_u_subtypes
);
706 bpf_set_error
(cstate
, "unknown LLC type name \"%s\"", $2);
709 CHECK_PTR_VAL
(($$
= gen_llc_u_subtype
(cstate
, subtype
)));
713 /* sigh, "rnr" is already a keyword for PF */
714 | LLC PF_RNR
{ CHECK_PTR_VAL
(($$
= gen_llc_s_subtype
(cstate
, LLC_RNR
))); }
717 dir: NUM
{ $$
= (int)$1; }
718 | ID
{ CHECK_PTR_VAL
($1);
719 if
(pcap_strcasecmp
($1, "nods") == 0)
720 $$
= IEEE80211_FC1_DIR_NODS
;
721 else if
(pcap_strcasecmp
($1, "tods") == 0)
722 $$
= IEEE80211_FC1_DIR_TODS
;
723 else if
(pcap_strcasecmp
($1, "fromds") == 0)
724 $$
= IEEE80211_FC1_DIR_FROMDS
;
725 else if
(pcap_strcasecmp
($1, "dstods") == 0)
726 $$
= IEEE80211_FC1_DIR_DSTODS
;
728 bpf_set_error
(cstate
, "unknown 802.11 direction");
734 reason: NUM
{ $$
= $1; }
735 | ID
{ CHECK_PTR_VAL
($1); CHECK_INT_VAL
(($$
= pfreason_to_num
(cstate
, $1))); }
738 action: ID
{ CHECK_PTR_VAL
($1); CHECK_INT_VAL
(($$
= pfaction_to_num
(cstate
, $1))); }
741 relop: '>' { $$
= BPF_JGT
; }
742 | GEQ
{ $$
= BPF_JGE
; }
743 |
'=' { $$
= BPF_JEQ
; }
745 irelop: LEQ
{ $$
= BPF_JGT
; }
746 |
'<' { $$
= BPF_JGE
; }
747 | NEQ
{ $$
= BPF_JEQ
; }
749 arth: pnum
{ CHECK_PTR_VAL
(($$
= gen_loadi
(cstate
, $1))); }
752 narth: pname
'[' arth
']' { CHECK_PTR_VAL
(($$
= gen_load
(cstate
, $1, $3, 1))); }
753 | pname
'[' arth
':' NUM
']' { CHECK_PTR_VAL
(($$
= gen_load
(cstate
, $1, $3, $5))); }
754 | arth
'+' arth
{ CHECK_PTR_VAL
(($$
= gen_arth
(cstate
, BPF_ADD
, $1, $3))); }
755 | arth
'-' arth
{ CHECK_PTR_VAL
(($$
= gen_arth
(cstate
, BPF_SUB
, $1, $3))); }
756 | arth
'*' arth
{ CHECK_PTR_VAL
(($$
= gen_arth
(cstate
, BPF_MUL
, $1, $3))); }
757 | arth
'/' arth
{ CHECK_PTR_VAL
(($$
= gen_arth
(cstate
, BPF_DIV
, $1, $3))); }
758 | arth
'%' arth
{ CHECK_PTR_VAL
(($$
= gen_arth
(cstate
, BPF_MOD
, $1, $3))); }
759 | arth
'&' arth
{ CHECK_PTR_VAL
(($$
= gen_arth
(cstate
, BPF_AND
, $1, $3))); }
760 | arth
'|' arth
{ CHECK_PTR_VAL
(($$
= gen_arth
(cstate
, BPF_OR
, $1, $3))); }
761 | arth
'^' arth
{ CHECK_PTR_VAL
(($$
= gen_arth
(cstate
, BPF_XOR
, $1, $3))); }
762 | arth LSH arth
{ CHECK_PTR_VAL
(($$
= gen_arth
(cstate
, BPF_LSH
, $1, $3))); }
763 | arth RSH arth
{ CHECK_PTR_VAL
(($$
= gen_arth
(cstate
, BPF_RSH
, $1, $3))); }
764 |
'-' arth %prec UMINUS
{ CHECK_PTR_VAL
(($$
= gen_neg
(cstate
, $2))); }
765 | paren narth
')' { $$
= $2; }
766 | LEN
{ CHECK_PTR_VAL
(($$
= gen_loadlen
(cstate
))); }
768 byteop: '&' { $$
= '&'; }
775 | paren pnum
')' { $$
= $2; }
777 atmtype: LANE
{ $$
= A_LANE
; }
778 | METAC
{ $$
= A_METAC
; }
779 | BCC
{ $$
= A_BCC
; }
780 | OAMF4EC
{ $$
= A_OAMF4EC
; }
781 | OAMF4SC
{ $$
= A_OAMF4SC
; }
783 | ILMIC
{ $$
= A_ILMIC
; }
785 atmmultitype: OAM
{ $$
= A_OAM
; }
786 | OAMF4
{ $$
= A_OAMF4
; }
787 | CONNECTMSG
{ $$
= A_CONNECTMSG
; }
788 | METACONNECT
{ $$
= A_METACONNECT
; }
790 /* ATM field types quantifier */
791 atmfield: VPI
{ $$.atmfieldtype
= A_VPI
; }
792 | VCI
{ $$.atmfieldtype
= A_VCI
; }
794 atmvalue: atmfieldvalue
795 | relop NUM
{ CHECK_PTR_VAL
(($$.b
= gen_atmfield_code
(cstate
, $
<blk
>0.atmfieldtype
, $2, $1, 0))); }
796 | irelop NUM
{ CHECK_PTR_VAL
(($$.b
= gen_atmfield_code
(cstate
, $
<blk
>0.atmfieldtype
, $2, $1, 1))); }
797 | paren atmlistvalue
')' { $$.b
= $2.b
; $$.q
= qerr
; }
800 $$.atmfieldtype
= $
<blk
>0.atmfieldtype
;
801 if
($$.atmfieldtype
== A_VPI ||
802 $$.atmfieldtype
== A_VCI
)
803 CHECK_PTR_VAL
(($$.b
= gen_atmfield_code
(cstate
, $$.atmfieldtype
, $1, BPF_JEQ
, 0)));
806 atmlistvalue: atmfieldvalue
807 | atmlistvalue or atmfieldvalue
{ gen_or
($1.b
, $3.b
); $$
= $3; }
809 /* MTP2 types quantifier */
810 mtp2type: FISU
{ $$
= M_FISU
; }
811 | LSSU
{ $$
= M_LSSU
; }
812 | MSU
{ $$
= M_MSU
; }
813 | HFISU
{ $$
= MH_FISU
; }
814 | HLSSU
{ $$
= MH_LSSU
; }
815 | HMSU
{ $$
= MH_MSU
; }
817 /* MTP3 field types quantifier */
818 mtp3field: SIO
{ $$.mtp3fieldtype
= M_SIO
; }
819 | OPC
{ $$.mtp3fieldtype
= M_OPC
; }
820 | DPC
{ $$.mtp3fieldtype
= M_DPC
; }
821 | SLS
{ $$.mtp3fieldtype
= M_SLS
; }
822 | HSIO
{ $$.mtp3fieldtype
= MH_SIO
; }
823 | HOPC
{ $$.mtp3fieldtype
= MH_OPC
; }
824 | HDPC
{ $$.mtp3fieldtype
= MH_DPC
; }
825 | HSLS
{ $$.mtp3fieldtype
= MH_SLS
; }
827 mtp3value: mtp3fieldvalue
828 | relop NUM
{ CHECK_PTR_VAL
(($$.b
= gen_mtp3field_code
(cstate
, $
<blk
>0.mtp3fieldtype
, $2, $1, 0))); }
829 | irelop NUM
{ CHECK_PTR_VAL
(($$.b
= gen_mtp3field_code
(cstate
, $
<blk
>0.mtp3fieldtype
, $2, $1, 1))); }
830 | paren mtp3listvalue
')' { $$.b
= $2.b
; $$.q
= qerr
; }
832 mtp3fieldvalue: NUM
{
833 $$.mtp3fieldtype
= $
<blk
>0.mtp3fieldtype
;
834 if
($$.mtp3fieldtype
== M_SIO ||
835 $$.mtp3fieldtype
== M_OPC ||
836 $$.mtp3fieldtype
== M_DPC ||
837 $$.mtp3fieldtype
== M_SLS ||
838 $$.mtp3fieldtype
== MH_SIO ||
839 $$.mtp3fieldtype
== MH_OPC ||
840 $$.mtp3fieldtype
== MH_DPC ||
841 $$.mtp3fieldtype
== MH_SLS
)
842 CHECK_PTR_VAL
(($$.b
= gen_mtp3field_code
(cstate
, $$.mtp3fieldtype
, $1, BPF_JEQ
, 0)));
845 mtp3listvalue: mtp3fieldvalue
846 | mtp3listvalue or mtp3fieldvalue
{ gen_or
($1.b
, $3.b
); $$
= $3; }