3 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
4 * The Regents of the University of California. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that: (1) source code distributions
8 * retain the above copyright notice and this paragraph in its entirety, (2)
9 * distributions including binary code include the above copyright notice and
10 * this paragraph in its entirety in the documentation or other materials
11 * provided with the distribution, and (3) all advertising materials mentioning
12 * features or use of this software display the following acknowledgement:
13 * ``This product includes software developed by the University of California,
14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15 * the University nor the names of its contributors may be used to endorse
16 * or promote products derived from this software without specific prior
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 #include <pcap-stdinc.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
53 #ifdef HAVE_NET_PFVAR_H
55 #include <netpfil/pf/pf.h>
56 #include <net/if_pflog.h>
59 #include "ieee80211.h"
60 #include <pcap/namedb.h>
62 #ifdef HAVE_OS_PROTO_H
66 #define QSET(q, p, d, a) (q).proto = (p),\
72 const char *s
; /* string */
75 static const struct tok ieee80211_types
[] = {
76 { IEEE80211_FC0_TYPE_DATA
, "data" },
77 { IEEE80211_FC0_TYPE_MGT
, "mgt" },
78 { IEEE80211_FC0_TYPE_MGT
, "management" },
79 { IEEE80211_FC0_TYPE_CTL
, "ctl" },
80 { IEEE80211_FC0_TYPE_CTL
, "control" },
83 static const struct tok ieee80211_mgt_subtypes
[] = {
84 { IEEE80211_FC0_SUBTYPE_ASSOC_REQ
, "assocreq" },
85 { IEEE80211_FC0_SUBTYPE_ASSOC_REQ
, "assoc-req" },
86 { IEEE80211_FC0_SUBTYPE_ASSOC_RESP
, "assocresp" },
87 { IEEE80211_FC0_SUBTYPE_ASSOC_RESP
, "assoc-resp" },
88 { IEEE80211_FC0_SUBTYPE_REASSOC_REQ
, "reassocreq" },
89 { IEEE80211_FC0_SUBTYPE_REASSOC_REQ
, "reassoc-req" },
90 { IEEE80211_FC0_SUBTYPE_REASSOC_RESP
, "reassocresp" },
91 { IEEE80211_FC0_SUBTYPE_REASSOC_RESP
, "reassoc-resp" },
92 { IEEE80211_FC0_SUBTYPE_PROBE_REQ
, "probereq" },
93 { IEEE80211_FC0_SUBTYPE_PROBE_REQ
, "probe-req" },
94 { IEEE80211_FC0_SUBTYPE_PROBE_RESP
, "proberesp" },
95 { IEEE80211_FC0_SUBTYPE_PROBE_RESP
, "probe-resp" },
96 { IEEE80211_FC0_SUBTYPE_BEACON
, "beacon" },
97 { IEEE80211_FC0_SUBTYPE_ATIM
, "atim" },
98 { IEEE80211_FC0_SUBTYPE_DISASSOC
, "disassoc" },
99 { IEEE80211_FC0_SUBTYPE_DISASSOC
, "disassociation" },
100 { IEEE80211_FC0_SUBTYPE_AUTH
, "auth" },
101 { IEEE80211_FC0_SUBTYPE_AUTH
, "authentication" },
102 { IEEE80211_FC0_SUBTYPE_DEAUTH
, "deauth" },
103 { IEEE80211_FC0_SUBTYPE_DEAUTH
, "deauthentication" },
106 static const struct tok ieee80211_ctl_subtypes
[] = {
107 { IEEE80211_FC0_SUBTYPE_PS_POLL
, "ps-poll" },
108 { IEEE80211_FC0_SUBTYPE_RTS
, "rts" },
109 { IEEE80211_FC0_SUBTYPE_CTS
, "cts" },
110 { IEEE80211_FC0_SUBTYPE_ACK
, "ack" },
111 { IEEE80211_FC0_SUBTYPE_CF_END
, "cf-end" },
112 { IEEE80211_FC0_SUBTYPE_CF_END_ACK
, "cf-end-ack" },
115 static const struct tok ieee80211_data_subtypes
[] = {
116 { IEEE80211_FC0_SUBTYPE_DATA
, "data" },
117 { IEEE80211_FC0_SUBTYPE_CF_ACK
, "data-cf-ack" },
118 { IEEE80211_FC0_SUBTYPE_CF_POLL
, "data-cf-poll" },
119 { IEEE80211_FC0_SUBTYPE_CF_ACPL
, "data-cf-ack-poll" },
120 { IEEE80211_FC0_SUBTYPE_NODATA
, "null" },
121 { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK
, "cf-ack" },
122 { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL
, "cf-poll" },
123 { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL
, "cf-ack-poll" },
124 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA
, "qos-data" },
125 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK
, "qos-data-cf-ack" },
126 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL
, "qos-data-cf-poll" },
127 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL
, "qos-data-cf-ack-poll" },
128 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA
, "qos" },
129 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL
, "qos-cf-poll" },
130 { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL
, "qos-cf-ack-poll" },
133 static const struct tok llc_s_subtypes
[] = {
139 static const struct tok llc_u_subtypes
[] = {
142 { LLC_DISC
, "disc" },
144 { LLC_SABME
, "sabme" },
145 { LLC_TEST
, "test" },
147 { LLC_FRMR
, "frmr" },
152 const struct tok
*tok
;
154 static const struct type2tok ieee80211_type_subtypes
[] = {
155 { IEEE80211_FC0_TYPE_MGT
, ieee80211_mgt_subtypes
},
156 { IEEE80211_FC0_TYPE_CTL
, ieee80211_ctl_subtypes
},
157 { IEEE80211_FC0_TYPE_DATA
, ieee80211_data_subtypes
},
162 str2tok
(const char *str
, const struct tok
*toks
)
166 for
(i
= 0; toks
[i
].s
!= NULL
; i
++) {
167 if
(pcap_strcasecmp
(toks
[i
].s
, str
) == 0)
175 static struct qual qerr
= { Q_UNDEF
, Q_UNDEF
, Q_UNDEF
, Q_UNDEF
};
178 yyerror(const char *msg
)
181 bpf_error
("%s", msg
);
185 #ifdef NEED_YYPARSE_WRAPPER
195 #ifdef HAVE_NET_PFVAR_H
197 pfreason_to_num
(const char *reason
)
199 const char *reasons
[] = PFRES_NAMES
;
202 for
(i
= 0; reasons
[i
]; i
++) {
203 if
(pcap_strcasecmp
(reason
, reasons
[i
]) == 0)
206 bpf_error
("unknown PF reason");
211 pfaction_to_num
(const char *action
)
213 if
(pcap_strcasecmp
(action
, "pass") == 0 ||
214 pcap_strcasecmp
(action
, "accept") == 0)
216 else if
(pcap_strcasecmp
(action
, "drop") == 0 ||
217 pcap_strcasecmp
(action
, "block") == 0)
219 #if HAVE_PF_NAT_THROUGH_PF_NORDR
220 else if
(pcap_strcasecmp
(action
, "rdr") == 0)
222 else if
(pcap_strcasecmp
(action
, "nat") == 0)
224 else if
(pcap_strcasecmp
(action
, "binat") == 0)
226 else if
(pcap_strcasecmp
(action
, "nordr") == 0)
230 bpf_error
("unknown PF action");
234 #else /* !HAVE_NET_PFVAR_H */
236 pfreason_to_num
(const char *reason
)
238 bpf_error
("libpcap was compiled on a machine without pf support");
241 /* this is to make the VC compiler happy */
246 pfaction_to_num
(const char *action
)
248 bpf_error
("libpcap was compiled on a machine without pf support");
251 /* this is to make the VC compiler happy */
254 #endif /* HAVE_NET_PFVAR_H */
273 %type
<blk
> expr id nid pid term rterm qid
275 %type
<i
> pqual dqual aqual ndaqual
277 %type
<i
> byteop pname pnum relop irelop
278 %type
<blk
> and or paren not null prog
279 %type
<rblk
> other pfvar p80211 pllc
280 %type
<i
> atmtype atmmultitype
282 %type
<blk
> atmfieldvalue atmvalue atmlistvalue
284 %type
<blk
> mtp3field
285 %type
<blk
> mtp3fieldvalue mtp3value mtp3listvalue
288 %token DST SRC HOST GATEWAY
289 %token NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
290 %token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
291 %token ATALK AARP DECNET LAT SCA MOPRC MOPDL
292 %token TK_BROADCAST TK_MULTICAST
293 %token NUM INBOUND OUTBOUND
294 %token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
295 %token TYPE SUBTYPE
DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
298 %token ID EID HID HID6 AID
301 %token IPV6 ICMPV6 AH ESP
304 %token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
308 %token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
309 %token OAM OAMF4 CONNECTMSG METACONNECT
312 %token FISU LSSU MSU HFISU HLSSU HMSU
313 %token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
320 %type
<i
> NUM action reason type subtype type_subtype dir
337 null: /* null */ { $$.q
= qerr
; }
340 | expr and term
{ gen_and
($1.b
, $3.b
); $$
= $3; }
341 | expr and id
{ gen_and
($1.b
, $3.b
); $$
= $3; }
342 | expr or term
{ gen_or
($1.b
, $3.b
); $$
= $3; }
343 | expr or id
{ gen_or
($1.b
, $3.b
); $$
= $3; }
345 and: AND
{ $$
= $
<blk
>0; }
347 or: OR
{ $$
= $
<blk
>0; }
350 | pnum
{ $$.b
= gen_ncode
(NULL
, (bpf_u_int32
)$1,
352 | paren pid
')' { $$
= $2; }
354 nid: ID
{ $$.b
= gen_scode
($1, $$.q
= $
<blk
>0.q
); }
355 | HID
'/' NUM
{ $$.b
= gen_mcode
($1, NULL
, $3,
357 | HID NETMASK HID
{ $$.b
= gen_mcode
($1, $3, 0,
360 /* Decide how to parse HID based on proto */
362 if
($$.q.addr
== Q_PORT
)
363 bpf_error
("'port' modifier applied to ip host");
364 else if
($$.q.addr
== Q_PORTRANGE
)
365 bpf_error
("'portrange' modifier applied to ip host");
366 else if
($$.q.addr
== Q_PROTO
)
367 bpf_error
("'proto' modifier applied to ip host");
368 else if
($$.q.addr
== Q_PROTOCHAIN
)
369 bpf_error
("'protochain' modifier applied to ip host");
370 $$.b
= gen_ncode
($1, 0, $$.q
);
374 $$.b
= gen_mcode6
($1, NULL
, $3,
377 bpf_error
("'ip6addr/prefixlen' not supported "
378 "in this configuration");
383 $$.b
= gen_mcode6
($1, 0, 128,
386 bpf_error
("'ip6addr' not supported "
387 "in this configuration");
391 $$.b
= gen_ecode
($1, $$.q
= $
<blk
>0.q
);
393 * $1 was allocated by "pcap_ether_aton()",
394 * so we must free it now that we're done
400 $$.b
= gen_acode
($1, $$.q
= $
<blk
>0.q
);
402 * $1 was allocated by "pcap_ether_aton()",
403 * so we must free it now that we're done
408 | not id
{ gen_not
($2.b
); $$
= $2; }
410 not: '!' { $$
= $
<blk
>0; }
412 paren: '(' { $$
= $
<blk
>0; }
415 | qid and id
{ gen_and
($1.b
, $3.b
); $$
= $3; }
416 | qid or id
{ gen_or
($1.b
, $3.b
); $$
= $3; }
418 qid: pnum
{ $$.b
= gen_ncode
(NULL
, (bpf_u_int32
)$1,
423 | not term
{ gen_not
($2.b
); $$
= $2; }
425 head: pqual dqual aqual
{ QSET
($$.q
, $1, $2, $3); }
426 | pqual dqual
{ QSET
($$.q
, $1, $2, Q_DEFAULT
); }
427 | pqual aqual
{ QSET
($$.q
, $1, Q_DEFAULT
, $2); }
428 | pqual PROTO
{ QSET
($$.q
, $1, Q_DEFAULT
, Q_PROTO
); }
429 | pqual PROTOCHAIN
{ QSET
($$.q
, $1, Q_DEFAULT
, Q_PROTOCHAIN
); }
430 | pqual ndaqual
{ QSET
($$.q
, $1, Q_DEFAULT
, $2); }
432 rterm: head id
{ $$
= $2; }
433 | paren expr
')' { $$.b
= $2.b
; $$.q
= $1.q
; }
434 | pname
{ $$.b
= gen_proto_abbrev
($1); $$.q
= qerr
; }
435 | arth relop arth
{ $$.b
= gen_relation
($2, $1, $3, 0);
437 | arth irelop arth
{ $$.b
= gen_relation
($2, $1, $3, 1);
439 | other
{ $$.b
= $1; $$.q
= qerr
; }
440 | atmtype
{ $$.b
= gen_atmtype_abbrev
($1); $$.q
= qerr
; }
441 | atmmultitype
{ $$.b
= gen_atmmulti_abbrev
($1); $$.q
= qerr
; }
442 | atmfield atmvalue
{ $$.b
= $2.b
; $$.q
= qerr
; }
443 | mtp2type
{ $$.b
= gen_mtp2type_abbrev
($1); $$.q
= qerr
; }
444 | mtp3field mtp3value
{ $$.b
= $2.b
; $$.q
= qerr
; }
446 /* protocol level qualifiers */
448 |
{ $$
= Q_DEFAULT
; }
450 /* 'direction' qualifiers */
451 dqual: SRC
{ $$
= Q_SRC
; }
452 | DST
{ $$
= Q_DST
; }
453 | SRC OR DST
{ $$
= Q_OR
; }
454 | DST OR SRC
{ $$
= Q_OR
; }
455 | SRC AND DST
{ $$
= Q_AND
; }
456 | DST AND SRC
{ $$
= Q_AND
; }
457 | ADDR1
{ $$
= Q_ADDR1
; }
458 | ADDR2
{ $$
= Q_ADDR2
; }
459 | ADDR3
{ $$
= Q_ADDR3
; }
460 | ADDR4
{ $$
= Q_ADDR4
; }
464 /* address type qualifiers */
465 aqual: HOST
{ $$
= Q_HOST
; }
466 | NET
{ $$
= Q_NET
; }
467 | PORT
{ $$
= Q_PORT
; }
468 | PORTRANGE
{ $$
= Q_PORTRANGE
; }
470 /* non-directional address type qualifiers */
471 ndaqual: GATEWAY
{ $$
= Q_GATEWAY
; }
473 pname: LINK
{ $$
= Q_LINK
; }
475 | ARP
{ $$
= Q_ARP
; }
476 | RARP
{ $$
= Q_RARP
; }
477 | SCTP
{ $$
= Q_SCTP
; }
478 | TCP
{ $$
= Q_TCP
; }
479 | UDP
{ $$
= Q_UDP
; }
480 | ICMP
{ $$
= Q_ICMP
; }
481 | IGMP
{ $$
= Q_IGMP
; }
482 | IGRP
{ $$
= Q_IGRP
; }
483 | PIM
{ $$
= Q_PIM
; }
484 | VRRP
{ $$
= Q_VRRP
; }
485 | CARP
{ $$
= Q_CARP
; }
486 | ATALK
{ $$
= Q_ATALK
; }
487 | AARP
{ $$
= Q_AARP
; }
488 | DECNET
{ $$
= Q_DECNET
; }
489 | LAT
{ $$
= Q_LAT
; }
490 | SCA
{ $$
= Q_SCA
; }
491 | MOPDL
{ $$
= Q_MOPDL
; }
492 | MOPRC
{ $$
= Q_MOPRC
; }
493 | IPV6
{ $$
= Q_IPV6
; }
494 | ICMPV6
{ $$
= Q_ICMPV6
; }
496 | ESP
{ $$
= Q_ESP
; }
497 | ISO
{ $$
= Q_ISO
; }
498 | ESIS
{ $$
= Q_ESIS
; }
499 | ISIS
{ $$
= Q_ISIS
; }
500 | L1
{ $$
= Q_ISIS_L1
; }
501 | L2
{ $$
= Q_ISIS_L2
; }
502 | IIH
{ $$
= Q_ISIS_IIH
; }
503 | LSP
{ $$
= Q_ISIS_LSP
; }
504 | SNP
{ $$
= Q_ISIS_SNP
; }
505 | PSNP
{ $$
= Q_ISIS_PSNP
; }
506 | CSNP
{ $$
= Q_ISIS_CSNP
; }
507 | CLNP
{ $$
= Q_CLNP
; }
508 | STP
{ $$
= Q_STP
; }
509 | IPX
{ $$
= Q_IPX
; }
510 | NETBEUI
{ $$
= Q_NETBEUI
; }
511 | RADIO
{ $$
= Q_RADIO
; }
513 other: pqual TK_BROADCAST
{ $$
= gen_broadcast
($1); }
514 | pqual TK_MULTICAST
{ $$
= gen_multicast
($1); }
515 | LESS NUM
{ $$
= gen_less
($2); }
516 | GREATER NUM
{ $$
= gen_greater
($2); }
517 | CBYTE NUM byteop NUM
{ $$
= gen_byteop
($3, $2, $4); }
518 | INBOUND
{ $$
= gen_inbound
(0); }
519 | OUTBOUND
{ $$
= gen_inbound
(1); }
520 | VLAN pnum
{ $$
= gen_vlan
($2); }
521 | VLAN
{ $$
= gen_vlan
(-1); }
522 | MPLS pnum
{ $$
= gen_mpls
($2); }
523 | MPLS
{ $$
= gen_mpls
(-1); }
524 | PPPOED
{ $$
= gen_pppoed
(); }
525 | PPPOES pnum
{ $$
= gen_pppoes
($2); }
526 | PPPOES
{ $$
= gen_pppoes
(-1); }
528 | pqual p80211
{ $$
= $2; }
532 pfvar: PF_IFNAME ID
{ $$
= gen_pf_ifname
($2); }
533 | PF_RSET ID
{ $$
= gen_pf_ruleset
($2); }
534 | PF_RNR NUM
{ $$
= gen_pf_rnr
($2); }
535 | PF_SRNR NUM
{ $$
= gen_pf_srnr
($2); }
536 | PF_REASON reason
{ $$
= gen_pf_reason
($2); }
537 | PF_ACTION action
{ $$
= gen_pf_action
($2); }
540 p80211: TYPE type SUBTYPE subtype
541 { $$
= gen_p80211_type
($2 |
$4,
542 IEEE80211_FC0_TYPE_MASK |
543 IEEE80211_FC0_SUBTYPE_MASK
);
545 | TYPE type
{ $$
= gen_p80211_type
($2,
546 IEEE80211_FC0_TYPE_MASK
);
548 | SUBTYPE type_subtype
{ $$
= gen_p80211_type
($2,
549 IEEE80211_FC0_TYPE_MASK |
550 IEEE80211_FC0_SUBTYPE_MASK
);
552 |
DIR dir
{ $$
= gen_p80211_fcdir
($2); }
556 | ID
{ $$
= str2tok
($1, ieee80211_types
);
558 bpf_error
("unknown 802.11 type name");
563 | ID
{ const struct tok
*types
= NULL
;
566 if
(ieee80211_type_subtypes
[i
].tok
== NULL
) {
567 /* Ran out of types */
568 bpf_error
("unknown 802.11 type");
571 if
($
<i
>-1 == ieee80211_type_subtypes
[i
].type
) {
572 types
= ieee80211_type_subtypes
[i
].tok
;
577 $$
= str2tok
($1, types
);
579 bpf_error
("unknown 802.11 subtype name");
583 type_subtype: ID
{ int i
;
585 if
(ieee80211_type_subtypes
[i
].tok
== NULL
) {
586 /* Ran out of types */
587 bpf_error
("unknown 802.11 type name");
590 $$
= str2tok
($1, ieee80211_type_subtypes
[i
].tok
);
592 $$ |
= ieee80211_type_subtypes
[i
].type
;
599 pllc: LLC
{ $$
= gen_llc
(); }
600 | LLC ID
{ if
(pcap_strcasecmp
($2, "i") == 0)
602 else if
(pcap_strcasecmp
($2, "s") == 0)
604 else if
(pcap_strcasecmp
($2, "u") == 0)
609 subtype
= str2tok
($2, llc_s_subtypes
);
611 $$
= gen_llc_s_subtype
(subtype
);
613 subtype
= str2tok
($2, llc_u_subtypes
);
615 bpf_error
("unknown LLC type name \"%s\"", $2);
616 $$
= gen_llc_u_subtype
(subtype
);
620 /* sigh, "rnr" is already a keyword for PF */
621 | LLC PF_RNR
{ $$
= gen_llc_s_subtype
(LLC_RNR
); }
625 | ID
{ if
(pcap_strcasecmp
($1, "nods") == 0)
626 $$
= IEEE80211_FC1_DIR_NODS
;
627 else if
(pcap_strcasecmp
($1, "tods") == 0)
628 $$
= IEEE80211_FC1_DIR_TODS
;
629 else if
(pcap_strcasecmp
($1, "fromds") == 0)
630 $$
= IEEE80211_FC1_DIR_FROMDS
;
631 else if
(pcap_strcasecmp
($1, "dstods") == 0)
632 $$
= IEEE80211_FC1_DIR_DSTODS
;
634 bpf_error
("unknown 802.11 direction");
638 reason: NUM
{ $$
= $1; }
639 | ID
{ $$
= pfreason_to_num
($1); }
642 action: ID
{ $$
= pfaction_to_num
($1); }
645 relop: '>' { $$
= BPF_JGT
; }
646 | GEQ
{ $$
= BPF_JGE
; }
647 |
'=' { $$
= BPF_JEQ
; }
649 irelop: LEQ
{ $$
= BPF_JGT
; }
650 |
'<' { $$
= BPF_JGE
; }
651 | NEQ
{ $$
= BPF_JEQ
; }
653 arth: pnum
{ $$
= gen_loadi
($1); }
656 narth: pname
'[' arth
']' { $$
= gen_load
($1, $3, 1); }
657 | pname
'[' arth
':' NUM
']' { $$
= gen_load
($1, $3, $5); }
658 | arth
'+' arth
{ $$
= gen_arth
(BPF_ADD
, $1, $3); }
659 | arth
'-' arth
{ $$
= gen_arth
(BPF_SUB
, $1, $3); }
660 | arth
'*' arth
{ $$
= gen_arth
(BPF_MUL
, $1, $3); }
661 | arth
'/' arth
{ $$
= gen_arth
(BPF_DIV
, $1, $3); }
662 | arth
'%' arth
{ $$
= gen_arth
(BPF_MOD
, $1, $3); }
663 | arth
'&' arth
{ $$
= gen_arth
(BPF_AND
, $1, $3); }
664 | arth
'|' arth
{ $$
= gen_arth
(BPF_OR
, $1, $3); }
665 | arth
'^' arth
{ $$
= gen_arth
(BPF_XOR
, $1, $3); }
666 | arth LSH arth
{ $$
= gen_arth
(BPF_LSH
, $1, $3); }
667 | arth RSH arth
{ $$
= gen_arth
(BPF_RSH
, $1, $3); }
668 |
'-' arth %prec UMINUS
{ $$
= gen_neg
($2); }
669 | paren narth
')' { $$
= $2; }
670 | LEN
{ $$
= gen_loadlen
(); }
672 byteop: '&' { $$
= '&'; }
679 | paren pnum
')' { $$
= $2; }
681 atmtype: LANE
{ $$
= A_LANE
; }
682 | METAC
{ $$
= A_METAC
; }
683 | BCC
{ $$
= A_BCC
; }
684 | OAMF4EC
{ $$
= A_OAMF4EC
; }
685 | OAMF4SC
{ $$
= A_OAMF4SC
; }
687 | ILMIC
{ $$
= A_ILMIC
; }
689 atmmultitype: OAM
{ $$
= A_OAM
; }
690 | OAMF4
{ $$
= A_OAMF4
; }
691 | CONNECTMSG
{ $$
= A_CONNECTMSG
; }
692 | METACONNECT
{ $$
= A_METACONNECT
; }
694 /* ATM field types quantifier */
695 atmfield: VPI
{ $$.atmfieldtype
= A_VPI
; }
696 | VCI
{ $$.atmfieldtype
= A_VCI
; }
698 atmvalue: atmfieldvalue
699 | relop NUM
{ $$.b
= gen_atmfield_code
($
<blk
>0.atmfieldtype
, (bpf_int32
)$2, (bpf_u_int32
)$1, 0); }
700 | irelop NUM
{ $$.b
= gen_atmfield_code
($
<blk
>0.atmfieldtype
, (bpf_int32
)$2, (bpf_u_int32
)$1, 1); }
701 | paren atmlistvalue
')' { $$.b
= $2.b
; $$.q
= qerr
; }
704 $$.atmfieldtype
= $
<blk
>0.atmfieldtype
;
705 if
($$.atmfieldtype
== A_VPI ||
706 $$.atmfieldtype
== A_VCI
)
707 $$.b
= gen_atmfield_code
($$.atmfieldtype
, (bpf_int32
) $1, BPF_JEQ
, 0);
710 atmlistvalue: atmfieldvalue
711 | atmlistvalue or atmfieldvalue
{ gen_or
($1.b
, $3.b
); $$
= $3; }
713 /* MTP2 types quantifier */
714 mtp2type: FISU
{ $$
= M_FISU
; }
715 | LSSU
{ $$
= M_LSSU
; }
716 | MSU
{ $$
= M_MSU
; }
717 | HFISU
{ $$
= MH_FISU
; }
718 | HLSSU
{ $$
= MH_LSSU
; }
719 | HMSU
{ $$
= MH_MSU
; }
721 /* MTP3 field types quantifier */
722 mtp3field: SIO
{ $$.mtp3fieldtype
= M_SIO
; }
723 | OPC
{ $$.mtp3fieldtype
= M_OPC
; }
724 | DPC
{ $$.mtp3fieldtype
= M_DPC
; }
725 | SLS
{ $$.mtp3fieldtype
= M_SLS
; }
726 | HSIO
{ $$.mtp3fieldtype
= MH_SIO
; }
727 | HOPC
{ $$.mtp3fieldtype
= MH_OPC
; }
728 | HDPC
{ $$.mtp3fieldtype
= MH_DPC
; }
729 | HSLS
{ $$.mtp3fieldtype
= MH_SLS
; }
731 mtp3value: mtp3fieldvalue
732 | relop NUM
{ $$.b
= gen_mtp3field_code
($
<blk
>0.mtp3fieldtype
, (u_int
)$2, (u_int
)$1, 0); }
733 | irelop NUM
{ $$.b
= gen_mtp3field_code
($
<blk
>0.mtp3fieldtype
, (u_int
)$2, (u_int
)$1, 1); }
734 | paren mtp3listvalue
')' { $$.b
= $2.b
; $$.q
= qerr
; }
736 mtp3fieldvalue: NUM
{
737 $$.mtp3fieldtype
= $
<blk
>0.mtp3fieldtype
;
738 if
($$.mtp3fieldtype
== M_SIO ||
739 $$.mtp3fieldtype
== M_OPC ||
740 $$.mtp3fieldtype
== M_DPC ||
741 $$.mtp3fieldtype
== M_SLS ||
742 $$.mtp3fieldtype
== MH_SIO ||
743 $$.mtp3fieldtype
== MH_OPC ||
744 $$.mtp3fieldtype
== MH_DPC ||
745 $$.mtp3fieldtype
== MH_SLS
)
746 $$.b
= gen_mtp3field_code
($$.mtp3fieldtype
, (u_int
) $1, BPF_JEQ
, 0);
749 mtp3listvalue: mtp3fieldvalue
750 | mtp3listvalue or mtp3fieldvalue
{ gen_or
($1.b
, $3.b
); $$
= $3; }