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 * And we need to pass the compiler state to the scanner.
24 %parse
-param
{compiler_state_t
*cstate
}
28 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
29 * The Regents of the University of California. All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that: (1) source code distributions
33 * retain the above copyright notice and this paragraph in its entirety, (2)
34 * distributions including binary code include the above copyright notice and
35 * this paragraph in its entirety in the documentation or other materials
36 * provided with the distribution, and (3) all advertising materials mentioning
37 * features or use of this software display the following acknowledgement:
38 * ``This product includes software developed by the University of California,
39 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
40 * the University nor the names of its contributors may be used to endorse
41 * or promote products derived from this software without specific prior
43 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
44 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
45 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
54 #include <pcap-stdinc.h>
56 #include <sys/types.h>
57 #include <sys/socket.h>
68 #include <netinet/in.h>
69 #include <arpa/inet.h>
80 #ifdef HAVE_NET_PFVAR_H
82 #include <net/pfvar.h>
83 #include <net/if_pflog.h>
86 #include "ieee80211.h"
87 #include <pcap/namedb.h>
89 #ifdef HAVE_OS_PROTO_H
93 #define QSET(q, p, d, a) (q).proto = (p),\
99 const char *s
; /* string */
102 static const struct tok ieee80211_types
[] = {
103 { IEEE80211_FC0_TYPE_DATA
, "data" },
104 { IEEE80211_FC0_TYPE_MGT
, "mgt" },
105 { IEEE80211_FC0_TYPE_MGT
, "management" },
106 { IEEE80211_FC0_TYPE_CTL
, "ctl" },
107 { IEEE80211_FC0_TYPE_CTL
, "control" },
110 static const struct tok ieee80211_mgt_subtypes
[] = {
111 { IEEE80211_FC0_SUBTYPE_ASSOC_REQ
, "assocreq" },
112 { IEEE80211_FC0_SUBTYPE_ASSOC_REQ
, "assoc-req" },
113 { IEEE80211_FC0_SUBTYPE_ASSOC_RESP
, "assocresp" },
114 { IEEE80211_FC0_SUBTYPE_ASSOC_RESP
, "assoc-resp" },
115 { IEEE80211_FC0_SUBTYPE_REASSOC_REQ
, "reassocreq" },
116 { IEEE80211_FC0_SUBTYPE_REASSOC_REQ
, "reassoc-req" },
117 { IEEE80211_FC0_SUBTYPE_REASSOC_RESP
, "reassocresp" },
118 { IEEE80211_FC0_SUBTYPE_REASSOC_RESP
, "reassoc-resp" },
119 { IEEE80211_FC0_SUBTYPE_PROBE_REQ
, "probereq" },
120 { IEEE80211_FC0_SUBTYPE_PROBE_REQ
, "probe-req" },
121 { IEEE80211_FC0_SUBTYPE_PROBE_RESP
, "proberesp" },
122 { IEEE80211_FC0_SUBTYPE_PROBE_RESP
, "probe-resp" },
123 { IEEE80211_FC0_SUBTYPE_BEACON
, "beacon" },
124 { IEEE80211_FC0_SUBTYPE_ATIM
, "atim" },
125 { IEEE80211_FC0_SUBTYPE_DISASSOC
, "disassoc" },
126 { IEEE80211_FC0_SUBTYPE_DISASSOC
, "disassociation" },
127 { IEEE80211_FC0_SUBTYPE_AUTH
, "auth" },
128 { IEEE80211_FC0_SUBTYPE_AUTH
, "authentication" },
129 { IEEE80211_FC0_SUBTYPE_DEAUTH
, "deauth" },
130 { IEEE80211_FC0_SUBTYPE_DEAUTH
, "deauthentication" },
133 static const struct tok ieee80211_ctl_subtypes
[] = {
134 { IEEE80211_FC0_SUBTYPE_PS_POLL
, "ps-poll" },
135 { IEEE80211_FC0_SUBTYPE_RTS
, "rts" },
136 { IEEE80211_FC0_SUBTYPE_CTS
, "cts" },
137 { IEEE80211_FC0_SUBTYPE_ACK
, "ack" },
138 { IEEE80211_FC0_SUBTYPE_CF_END
, "cf-end" },
139 { IEEE80211_FC0_SUBTYPE_CF_END_ACK
, "cf-end-ack" },
142 static const struct tok ieee80211_data_subtypes
[] = {
143 { IEEE80211_FC0_SUBTYPE_DATA
, "data" },
144 { IEEE80211_FC0_SUBTYPE_CF_ACK
, "data-cf-ack" },
145 { IEEE80211_FC0_SUBTYPE_CF_POLL
, "data-cf-poll" },
146 { IEEE80211_FC0_SUBTYPE_CF_ACPL
, "data-cf-ack-poll" },
147 { IEEE80211_FC0_SUBTYPE_NODATA
, "null" },
148 { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK
, "cf-ack" },
149 { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL
, "cf-poll" },
150 { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL
, "cf-ack-poll" },
151 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA
, "qos-data" },
152 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK
, "qos-data-cf-ack" },
153 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL
, "qos-data-cf-poll" },
154 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL
, "qos-data-cf-ack-poll" },
155 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA
, "qos" },
156 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL
, "qos-cf-poll" },
157 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL
, "qos-cf-ack-poll" },
160 static const struct tok llc_s_subtypes
[] = {
166 static const struct tok llc_u_subtypes
[] = {
169 { LLC_DISC
, "disc" },
171 { LLC_SABME
, "sabme" },
172 { LLC_TEST
, "test" },
174 { LLC_FRMR
, "frmr" },
179 const struct tok
*tok
;
181 static const struct type2tok ieee80211_type_subtypes
[] = {
182 { IEEE80211_FC0_TYPE_MGT
, ieee80211_mgt_subtypes
},
183 { IEEE80211_FC0_TYPE_CTL
, ieee80211_ctl_subtypes
},
184 { IEEE80211_FC0_TYPE_DATA
, ieee80211_data_subtypes
},
189 str2tok
(const char *str
, const struct tok
*toks
)
193 for
(i
= 0; toks
[i
].s
!= NULL
; i
++) {
194 if
(pcap_strcasecmp
(toks
[i
].s
, str
) == 0)
200 static struct qual qerr
= { Q_UNDEF
, Q_UNDEF
, Q_UNDEF
, Q_UNDEF
};
203 yyerror(void *yyscanner
, compiler_state_t
*cstate
, const char *msg
)
205 bpf_syntax_error
(cstate
, msg
);
209 #ifdef HAVE_NET_PFVAR_H
211 pfreason_to_num
(compiler_state_t
*cstate
, const char *reason
)
213 const char *reasons
[] = PFRES_NAMES
;
216 for
(i
= 0; reasons
[i
]; i
++) {
217 if
(pcap_strcasecmp
(reason
, reasons
[i
]) == 0)
220 bpf_error
(cstate
, "unknown PF reason");
225 pfaction_to_num
(compiler_state_t
*cstate
, const char *action
)
227 if
(pcap_strcasecmp
(action
, "pass") == 0 ||
228 pcap_strcasecmp
(action
, "accept") == 0)
230 else if
(pcap_strcasecmp
(action
, "drop") == 0 ||
231 pcap_strcasecmp
(action
, "block") == 0)
233 #if HAVE_PF_NAT_THROUGH_PF_NORDR
234 else if
(pcap_strcasecmp
(action
, "rdr") == 0)
236 else if
(pcap_strcasecmp
(action
, "nat") == 0)
238 else if
(pcap_strcasecmp
(action
, "binat") == 0)
240 else if
(pcap_strcasecmp
(action
, "nordr") == 0)
244 bpf_error
(cstate
, "unknown PF action");
248 #else /* !HAVE_NET_PFVAR_H */
250 pfreason_to_num
(compiler_state_t
*cstate
, const char *reason
)
252 bpf_error
(cstate
, "libpcap was compiled on a machine without pf support");
255 /* this is to make the VC compiler happy */
260 pfaction_to_num
(compiler_state_t
*cstate
, const char *action
)
262 bpf_error
(cstate
, "libpcap was compiled on a machine without pf support");
265 /* this is to make the VC compiler happy */
268 #endif /* HAVE_NET_PFVAR_H */
287 %type
<blk
> expr id nid pid term rterm qid
289 %type
<i
> pqual dqual aqual ndaqual
291 %type
<i
> byteop pname pnum relop irelop
292 %type
<blk
> and or paren not null prog
293 %type
<rblk
> other pfvar p80211 pllc
294 %type
<i
> atmtype atmmultitype
296 %type
<blk
> atmfieldvalue atmvalue atmlistvalue
298 %type
<blk
> mtp3field
299 %type
<blk
> mtp3fieldvalue mtp3value mtp3listvalue
302 %token DST SRC HOST GATEWAY
303 %token NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
304 %token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
305 %token ATALK AARP DECNET LAT SCA MOPRC MOPDL
306 %token TK_BROADCAST TK_MULTICAST
307 %token NUM INBOUND OUTBOUND
308 %token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
309 %token TYPE SUBTYPE
DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
312 %token ID EID HID HID6 AID
315 %token IPV6 ICMPV6 AH ESP
317 %token PPPOED PPPOES GENEVE
318 %token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
322 %token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
323 %token OAM OAMF4 CONNECTMSG METACONNECT
326 %token FISU LSSU MSU HFISU HLSSU HMSU
327 %token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
334 %type
<i
> NUM action reason type subtype type_subtype dir
347 finish_parse
(cstate
, $2.b
);
351 null: /* null */ { $$.q
= qerr
; }
354 | expr and term
{ gen_and
($1.b
, $3.b
); $$
= $3; }
355 | expr and id
{ gen_and
($1.b
, $3.b
); $$
= $3; }
356 | expr or term
{ gen_or
($1.b
, $3.b
); $$
= $3; }
357 | expr or id
{ gen_or
($1.b
, $3.b
); $$
= $3; }
359 and: AND
{ $$
= $
<blk
>0; }
361 or: OR
{ $$
= $
<blk
>0; }
364 | pnum
{ $$.b
= gen_ncode
(cstate
, NULL
, (bpf_u_int32
)$1,
366 | paren pid
')' { $$
= $2; }
368 nid: ID
{ $$.b
= gen_scode
(cstate
, $1, $$.q
= $
<blk
>0.q
); }
369 | HID
'/' NUM
{ $$.b
= gen_mcode
(cstate
, $1, NULL
, $3,
371 | HID NETMASK HID
{ $$.b
= gen_mcode
(cstate
, $1, $3, 0,
374 /* Decide how to parse HID based on proto */
376 if
($$.q.addr
== Q_PORT
)
377 bpf_error
(cstate
, "'port' modifier applied to ip host");
378 else if
($$.q.addr
== Q_PORTRANGE
)
379 bpf_error
(cstate
, "'portrange' modifier applied to ip host");
380 else if
($$.q.addr
== Q_PROTO
)
381 bpf_error
(cstate
, "'proto' modifier applied to ip host");
382 else if
($$.q.addr
== Q_PROTOCHAIN
)
383 bpf_error
(cstate
, "'protochain' modifier applied to ip host");
384 $$.b
= gen_ncode
(cstate
, $1, 0, $$.q
);
388 $$.b
= gen_mcode6
(cstate
, $1, NULL
, $3,
391 bpf_error
(cstate
, "'ip6addr/prefixlen' not supported "
392 "in this configuration");
397 $$.b
= gen_mcode6
(cstate
, $1, 0, 128,
400 bpf_error
(cstate
, "'ip6addr' not supported "
401 "in this configuration");
405 $$.b
= gen_ecode
(cstate
, $1, $$.q
= $
<blk
>0.q
);
407 * $1 was allocated by "pcap_ether_aton()",
408 * so we must free it now that we're done
414 $$.b
= gen_acode
(cstate
, $1, $$.q
= $
<blk
>0.q
);
416 * $1 was allocated by "pcap_ether_aton()",
417 * so we must free it now that we're done
422 | not id
{ gen_not
($2.b
); $$
= $2; }
424 not: '!' { $$
= $
<blk
>0; }
426 paren: '(' { $$
= $
<blk
>0; }
429 | qid and id
{ gen_and
($1.b
, $3.b
); $$
= $3; }
430 | qid or id
{ gen_or
($1.b
, $3.b
); $$
= $3; }
432 qid: pnum
{ $$.b
= gen_ncode
(cstate
, NULL
, (bpf_u_int32
)$1,
437 | not term
{ gen_not
($2.b
); $$
= $2; }
439 head: pqual dqual aqual
{ QSET
($$.q
, $1, $2, $3); }
440 | pqual dqual
{ QSET
($$.q
, $1, $2, Q_DEFAULT
); }
441 | pqual aqual
{ QSET
($$.q
, $1, Q_DEFAULT
, $2); }
442 | pqual PROTO
{ QSET
($$.q
, $1, Q_DEFAULT
, Q_PROTO
); }
443 | pqual PROTOCHAIN
{ QSET
($$.q
, $1, Q_DEFAULT
, Q_PROTOCHAIN
); }
444 | pqual ndaqual
{ QSET
($$.q
, $1, Q_DEFAULT
, $2); }
446 rterm: head id
{ $$
= $2; }
447 | paren expr
')' { $$.b
= $2.b
; $$.q
= $1.q
; }
448 | pname
{ $$.b
= gen_proto_abbrev
(cstate
, $1); $$.q
= qerr
; }
449 | arth relop arth
{ $$.b
= gen_relation
(cstate
, $2, $1, $3, 0);
451 | arth irelop arth
{ $$.b
= gen_relation
(cstate
, $2, $1, $3, 1);
453 | other
{ $$.b
= $1; $$.q
= qerr
; }
454 | atmtype
{ $$.b
= gen_atmtype_abbrev
(cstate
, $1); $$.q
= qerr
; }
455 | atmmultitype
{ $$.b
= gen_atmmulti_abbrev
(cstate
, $1); $$.q
= qerr
; }
456 | atmfield atmvalue
{ $$.b
= $2.b
; $$.q
= qerr
; }
457 | mtp2type
{ $$.b
= gen_mtp2type_abbrev
(cstate
, $1); $$.q
= qerr
; }
458 | mtp3field mtp3value
{ $$.b
= $2.b
; $$.q
= qerr
; }
460 /* protocol level qualifiers */
462 |
{ $$
= Q_DEFAULT
; }
464 /* 'direction' qualifiers */
465 dqual: SRC
{ $$
= Q_SRC
; }
466 | DST
{ $$
= Q_DST
; }
467 | SRC OR DST
{ $$
= Q_OR
; }
468 | DST OR SRC
{ $$
= Q_OR
; }
469 | SRC AND DST
{ $$
= Q_AND
; }
470 | DST AND SRC
{ $$
= Q_AND
; }
471 | ADDR1
{ $$
= Q_ADDR1
; }
472 | ADDR2
{ $$
= Q_ADDR2
; }
473 | ADDR3
{ $$
= Q_ADDR3
; }
474 | ADDR4
{ $$
= Q_ADDR4
; }
478 /* address type qualifiers */
479 aqual: HOST
{ $$
= Q_HOST
; }
480 | NET
{ $$
= Q_NET
; }
481 | PORT
{ $$
= Q_PORT
; }
482 | PORTRANGE
{ $$
= Q_PORTRANGE
; }
484 /* non-directional address type qualifiers */
485 ndaqual: GATEWAY
{ $$
= Q_GATEWAY
; }
487 pname: LINK
{ $$
= Q_LINK
; }
489 | ARP
{ $$
= Q_ARP
; }
490 | RARP
{ $$
= Q_RARP
; }
491 | SCTP
{ $$
= Q_SCTP
; }
492 | TCP
{ $$
= Q_TCP
; }
493 | UDP
{ $$
= Q_UDP
; }
494 | ICMP
{ $$
= Q_ICMP
; }
495 | IGMP
{ $$
= Q_IGMP
; }
496 | IGRP
{ $$
= Q_IGRP
; }
497 | PIM
{ $$
= Q_PIM
; }
498 | VRRP
{ $$
= Q_VRRP
; }
499 | CARP
{ $$
= Q_CARP
; }
500 | ATALK
{ $$
= Q_ATALK
; }
501 | AARP
{ $$
= Q_AARP
; }
502 | DECNET
{ $$
= Q_DECNET
; }
503 | LAT
{ $$
= Q_LAT
; }
504 | SCA
{ $$
= Q_SCA
; }
505 | MOPDL
{ $$
= Q_MOPDL
; }
506 | MOPRC
{ $$
= Q_MOPRC
; }
507 | IPV6
{ $$
= Q_IPV6
; }
508 | ICMPV6
{ $$
= Q_ICMPV6
; }
510 | ESP
{ $$
= Q_ESP
; }
511 | ISO
{ $$
= Q_ISO
; }
512 | ESIS
{ $$
= Q_ESIS
; }
513 | ISIS
{ $$
= Q_ISIS
; }
514 | L1
{ $$
= Q_ISIS_L1
; }
515 | L2
{ $$
= Q_ISIS_L2
; }
516 | IIH
{ $$
= Q_ISIS_IIH
; }
517 | LSP
{ $$
= Q_ISIS_LSP
; }
518 | SNP
{ $$
= Q_ISIS_SNP
; }
519 | PSNP
{ $$
= Q_ISIS_PSNP
; }
520 | CSNP
{ $$
= Q_ISIS_CSNP
; }
521 | CLNP
{ $$
= Q_CLNP
; }
522 | STP
{ $$
= Q_STP
; }
523 | IPX
{ $$
= Q_IPX
; }
524 | NETBEUI
{ $$
= Q_NETBEUI
; }
525 | RADIO
{ $$
= Q_RADIO
; }
527 other: pqual TK_BROADCAST
{ $$
= gen_broadcast
(cstate
, $1); }
528 | pqual TK_MULTICAST
{ $$
= gen_multicast
(cstate
, $1); }
529 | LESS NUM
{ $$
= gen_less
(cstate
, $2); }
530 | GREATER NUM
{ $$
= gen_greater
(cstate
, $2); }
531 | CBYTE NUM byteop NUM
{ $$
= gen_byteop
(cstate
, $3, $2, $4); }
532 | INBOUND
{ $$
= gen_inbound
(cstate
, 0); }
533 | OUTBOUND
{ $$
= gen_inbound
(cstate
, 1); }
534 | VLAN pnum
{ $$
= gen_vlan
(cstate
, $2); }
535 | VLAN
{ $$
= gen_vlan
(cstate
, -1); }
536 | MPLS pnum
{ $$
= gen_mpls
(cstate
, $2); }
537 | MPLS
{ $$
= gen_mpls
(cstate
, -1); }
538 | PPPOED
{ $$
= gen_pppoed
(cstate
); }
539 | PPPOES pnum
{ $$
= gen_pppoes
(cstate
, $2); }
540 | PPPOES
{ $$
= gen_pppoes
(cstate
, -1); }
541 | GENEVE pnum
{ $$
= gen_geneve
(cstate
, $2); }
542 | GENEVE
{ $$
= gen_geneve
(cstate
, -1); }
544 | pqual p80211
{ $$
= $2; }
548 pfvar: PF_IFNAME ID
{ $$
= gen_pf_ifname
(cstate
, $2); }
549 | PF_RSET ID
{ $$
= gen_pf_ruleset
(cstate
, $2); }
550 | PF_RNR NUM
{ $$
= gen_pf_rnr
(cstate
, $2); }
551 | PF_SRNR NUM
{ $$
= gen_pf_srnr
(cstate
, $2); }
552 | PF_REASON reason
{ $$
= gen_pf_reason
(cstate
, $2); }
553 | PF_ACTION action
{ $$
= gen_pf_action
(cstate
, $2); }
556 p80211: TYPE type SUBTYPE subtype
557 { $$
= gen_p80211_type
(cstate
, $2 |
$4,
558 IEEE80211_FC0_TYPE_MASK |
559 IEEE80211_FC0_SUBTYPE_MASK
);
561 | TYPE type
{ $$
= gen_p80211_type
(cstate
, $2,
562 IEEE80211_FC0_TYPE_MASK
);
564 | SUBTYPE type_subtype
{ $$
= gen_p80211_type
(cstate
, $2,
565 IEEE80211_FC0_TYPE_MASK |
566 IEEE80211_FC0_SUBTYPE_MASK
);
568 |
DIR dir
{ $$
= gen_p80211_fcdir
(cstate
, $2); }
572 | ID
{ $$
= str2tok
($1, ieee80211_types
);
574 bpf_error
(cstate
, "unknown 802.11 type name");
579 | ID
{ const struct tok
*types
= NULL
;
582 if
(ieee80211_type_subtypes
[i
].tok
== NULL
) {
583 /* Ran out of types */
584 bpf_error
(cstate
, "unknown 802.11 type");
587 if
($
<i
>-1 == ieee80211_type_subtypes
[i
].type
) {
588 types
= ieee80211_type_subtypes
[i
].tok
;
593 $$
= str2tok
($1, types
);
595 bpf_error
(cstate
, "unknown 802.11 subtype name");
599 type_subtype: ID
{ int i
;
601 if
(ieee80211_type_subtypes
[i
].tok
== NULL
) {
602 /* Ran out of types */
603 bpf_error
(cstate
, "unknown 802.11 type name");
606 $$
= str2tok
($1, ieee80211_type_subtypes
[i
].tok
);
608 $$ |
= ieee80211_type_subtypes
[i
].type
;
615 pllc: LLC
{ $$
= gen_llc
(cstate
); }
616 | LLC ID
{ if
(pcap_strcasecmp
($2, "i") == 0)
617 $$
= gen_llc_i
(cstate
);
618 else if
(pcap_strcasecmp
($2, "s") == 0)
619 $$
= gen_llc_s
(cstate
);
620 else if
(pcap_strcasecmp
($2, "u") == 0)
621 $$
= gen_llc_u
(cstate
);
625 subtype
= str2tok
($2, llc_s_subtypes
);
627 $$
= gen_llc_s_subtype
(cstate
, subtype
);
629 subtype
= str2tok
($2, llc_u_subtypes
);
631 bpf_error
(cstate
, "unknown LLC type name \"%s\"", $2);
632 $$
= gen_llc_u_subtype
(cstate
, subtype
);
636 /* sigh, "rnr" is already a keyword for PF */
637 | LLC PF_RNR
{ $$
= gen_llc_s_subtype
(cstate
, LLC_RNR
); }
641 | ID
{ if
(pcap_strcasecmp
($1, "nods") == 0)
642 $$
= IEEE80211_FC1_DIR_NODS
;
643 else if
(pcap_strcasecmp
($1, "tods") == 0)
644 $$
= IEEE80211_FC1_DIR_TODS
;
645 else if
(pcap_strcasecmp
($1, "fromds") == 0)
646 $$
= IEEE80211_FC1_DIR_FROMDS
;
647 else if
(pcap_strcasecmp
($1, "dstods") == 0)
648 $$
= IEEE80211_FC1_DIR_DSTODS
;
650 bpf_error
(cstate
, "unknown 802.11 direction");
654 reason: NUM
{ $$
= $1; }
655 | ID
{ $$
= pfreason_to_num
(cstate
, $1); }
658 action: ID
{ $$
= pfaction_to_num
(cstate
, $1); }
661 relop: '>' { $$
= BPF_JGT
; }
662 | GEQ
{ $$
= BPF_JGE
; }
663 |
'=' { $$
= BPF_JEQ
; }
665 irelop: LEQ
{ $$
= BPF_JGT
; }
666 |
'<' { $$
= BPF_JGE
; }
667 | NEQ
{ $$
= BPF_JEQ
; }
669 arth: pnum
{ $$
= gen_loadi
(cstate
, $1); }
672 narth: pname
'[' arth
']' { $$
= gen_load
(cstate
, $1, $3, 1); }
673 | pname
'[' arth
':' NUM
']' { $$
= gen_load
(cstate
, $1, $3, $5); }
674 | arth
'+' arth
{ $$
= gen_arth
(cstate
, BPF_ADD
, $1, $3); }
675 | arth
'-' arth
{ $$
= gen_arth
(cstate
, BPF_SUB
, $1, $3); }
676 | arth
'*' arth
{ $$
= gen_arth
(cstate
, BPF_MUL
, $1, $3); }
677 | arth
'/' arth
{ $$
= gen_arth
(cstate
, BPF_DIV
, $1, $3); }
678 | arth
'%' arth
{ $$
= gen_arth
(cstate
, BPF_MOD
, $1, $3); }
679 | arth
'&' arth
{ $$
= gen_arth
(cstate
, BPF_AND
, $1, $3); }
680 | arth
'|' arth
{ $$
= gen_arth
(cstate
, BPF_OR
, $1, $3); }
681 | arth
'^' arth
{ $$
= gen_arth
(cstate
, BPF_XOR
, $1, $3); }
682 | arth LSH arth
{ $$
= gen_arth
(cstate
, BPF_LSH
, $1, $3); }
683 | arth RSH arth
{ $$
= gen_arth
(cstate
, BPF_RSH
, $1, $3); }
684 |
'-' arth %prec UMINUS
{ $$
= gen_neg
(cstate
, $2); }
685 | paren narth
')' { $$
= $2; }
686 | LEN
{ $$
= gen_loadlen
(cstate
); }
688 byteop: '&' { $$
= '&'; }
695 | paren pnum
')' { $$
= $2; }
697 atmtype: LANE
{ $$
= A_LANE
; }
698 | METAC
{ $$
= A_METAC
; }
699 | BCC
{ $$
= A_BCC
; }
700 | OAMF4EC
{ $$
= A_OAMF4EC
; }
701 | OAMF4SC
{ $$
= A_OAMF4SC
; }
703 | ILMIC
{ $$
= A_ILMIC
; }
705 atmmultitype: OAM
{ $$
= A_OAM
; }
706 | OAMF4
{ $$
= A_OAMF4
; }
707 | CONNECTMSG
{ $$
= A_CONNECTMSG
; }
708 | METACONNECT
{ $$
= A_METACONNECT
; }
710 /* ATM field types quantifier */
711 atmfield: VPI
{ $$.atmfieldtype
= A_VPI
; }
712 | VCI
{ $$.atmfieldtype
= A_VCI
; }
714 atmvalue: atmfieldvalue
715 | relop NUM
{ $$.b
= gen_atmfield_code
(cstate
, $
<blk
>0.atmfieldtype
, (bpf_int32
)$2, (bpf_u_int32
)$1, 0); }
716 | irelop NUM
{ $$.b
= gen_atmfield_code
(cstate
, $
<blk
>0.atmfieldtype
, (bpf_int32
)$2, (bpf_u_int32
)$1, 1); }
717 | paren atmlistvalue
')' { $$.b
= $2.b
; $$.q
= qerr
; }
720 $$.atmfieldtype
= $
<blk
>0.atmfieldtype
;
721 if
($$.atmfieldtype
== A_VPI ||
722 $$.atmfieldtype
== A_VCI
)
723 $$.b
= gen_atmfield_code
(cstate
, $$.atmfieldtype
, (bpf_int32
) $1, BPF_JEQ
, 0);
726 atmlistvalue: atmfieldvalue
727 | atmlistvalue or atmfieldvalue
{ gen_or
($1.b
, $3.b
); $$
= $3; }
729 /* MTP2 types quantifier */
730 mtp2type: FISU
{ $$
= M_FISU
; }
731 | LSSU
{ $$
= M_LSSU
; }
732 | MSU
{ $$
= M_MSU
; }
733 | HFISU
{ $$
= MH_FISU
; }
734 | HLSSU
{ $$
= MH_LSSU
; }
735 | HMSU
{ $$
= MH_MSU
; }
737 /* MTP3 field types quantifier */
738 mtp3field: SIO
{ $$.mtp3fieldtype
= M_SIO
; }
739 | OPC
{ $$.mtp3fieldtype
= M_OPC
; }
740 | DPC
{ $$.mtp3fieldtype
= M_DPC
; }
741 | SLS
{ $$.mtp3fieldtype
= M_SLS
; }
742 | HSIO
{ $$.mtp3fieldtype
= MH_SIO
; }
743 | HOPC
{ $$.mtp3fieldtype
= MH_OPC
; }
744 | HDPC
{ $$.mtp3fieldtype
= MH_DPC
; }
745 | HSLS
{ $$.mtp3fieldtype
= MH_SLS
; }
747 mtp3value: mtp3fieldvalue
748 | relop NUM
{ $$.b
= gen_mtp3field_code
(cstate
, $
<blk
>0.mtp3fieldtype
, (u_int
)$2, (u_int
)$1, 0); }
749 | irelop NUM
{ $$.b
= gen_mtp3field_code
(cstate
, $
<blk
>0.mtp3fieldtype
, (u_int
)$2, (u_int
)$1, 1); }
750 | paren mtp3listvalue
')' { $$.b
= $2.b
; $$.q
= qerr
; }
752 mtp3fieldvalue: NUM
{
753 $$.mtp3fieldtype
= $
<blk
>0.mtp3fieldtype
;
754 if
($$.mtp3fieldtype
== M_SIO ||
755 $$.mtp3fieldtype
== M_OPC ||
756 $$.mtp3fieldtype
== M_DPC ||
757 $$.mtp3fieldtype
== M_SLS ||
758 $$.mtp3fieldtype
== MH_SIO ||
759 $$.mtp3fieldtype
== MH_OPC ||
760 $$.mtp3fieldtype
== MH_DPC ||
761 $$.mtp3fieldtype
== MH_SLS
)
762 $$.b
= gen_mtp3field_code
(cstate
, $$.mtp3fieldtype
, (u_int
) $1, BPF_JEQ
, 0);
765 mtp3listvalue: mtp3fieldvalue
766 | mtp3listvalue or mtp3fieldvalue
{ gen_or
($1.b
, $3.b
); $$
= $3; }