Home | History | Annotate | Download | only in libpcap
      1 /*
      2  * We want a reentrant parser.
      3  */
      4 %pure-parser
      5 
      6 /*
      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.
     10  *
     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 *.
     17  */
     18 %parse-param   {void *yyscanner}
     19 %lex-param   {void *yyscanner}
     20 
     21 /*
     22  * And we need to pass the compiler state to the scanner.
     23  */
     24 %parse-param {compiler_state_t *cstate}
     25 
     26 %{
     27 /*
     28  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
     29  *	The Regents of the University of California.  All rights reserved.
     30  *
     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
     42  * written permission.
     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.
     46  *
     47  */
     48 
     49 #ifdef HAVE_CONFIG_H
     50 #include "config.h"
     51 #endif
     52 
     53 #ifdef _WIN32
     54 #include <pcap-stdinc.h>
     55 #else /* _WIN32 */
     56 #include <sys/types.h>
     57 #include <sys/socket.h>
     58 #endif /* _WIN32 */
     59 
     60 #include <stdlib.h>
     61 
     62 #ifndef _WIN32
     63 #if __STDC__
     64 struct mbuf;
     65 struct rtentry;
     66 #endif
     67 
     68 #include <netinet/in.h>
     69 #include <arpa/inet.h>
     70 #endif /* _WIN32 */
     71 
     72 #include <stdio.h>
     73 
     74 #include "pcap-int.h"
     75 
     76 #include "gencode.h"
     77 #include "grammar.h"
     78 #include "scanner.h"
     79 
     80 #ifdef HAVE_NET_PFVAR_H
     81 #include <net/if.h>
     82 #include <net/pfvar.h>
     83 #include <net/if_pflog.h>
     84 #endif
     85 #include "llc.h"
     86 #include "ieee80211.h"
     87 #include <pcap/namedb.h>
     88 
     89 #ifdef HAVE_OS_PROTO_H
     90 #include "os-proto.h"
     91 #endif
     92 
     93 #define QSET(q, p, d, a) (q).proto = (p),\
     94 			 (q).dir = (d),\
     95 			 (q).addr = (a)
     96 
     97 struct tok {
     98 	int v;			/* value */
     99 	const char *s;		/* string */
    100 };
    101 
    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" },
    108 	{ 0, NULL }
    109 };
    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" },
    131 	{ 0, NULL }
    132 };
    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" },
    140 	{ 0, NULL }
    141 };
    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" },
    158 	{ 0, NULL }
    159 };
    160 static const struct tok llc_s_subtypes[] = {
    161 	{ LLC_RR, "rr" },
    162 	{ LLC_RNR, "rnr" },
    163 	{ LLC_REJ, "rej" },
    164 	{ 0, NULL }
    165 };
    166 static const struct tok llc_u_subtypes[] = {
    167 	{ LLC_UI, "ui" },
    168 	{ LLC_UA, "ua" },
    169 	{ LLC_DISC, "disc" },
    170 	{ LLC_DM, "dm" },
    171 	{ LLC_SABME, "sabme" },
    172 	{ LLC_TEST, "test" },
    173 	{ LLC_XID, "xid" },
    174 	{ LLC_FRMR, "frmr" },
    175 	{ 0, NULL }
    176 };
    177 struct type2tok {
    178 	int type;
    179 	const struct tok *tok;
    180 };
    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 },
    185 	{ 0, NULL }
    186 };
    187 
    188 static int
    189 str2tok(const char *str, const struct tok *toks)
    190 {
    191 	int i;
    192 
    193 	for (i = 0; toks[i].s != NULL; i++) {
    194 		if (pcap_strcasecmp(toks[i].s, str) == 0)
    195 			return (toks[i].v);
    196 	}
    197 	return (-1);
    198 }
    199 
    200 static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
    201 
    202 static void
    203 yyerror(void *yyscanner, compiler_state_t *cstate, const char *msg)
    204 {
    205 	bpf_syntax_error(cstate, msg);
    206 	/* NOTREACHED */
    207 }
    208 
    209 #ifdef HAVE_NET_PFVAR_H
    210 static int
    211 pfreason_to_num(compiler_state_t *cstate, const char *reason)
    212 {
    213 	const char *reasons[] = PFRES_NAMES;
    214 	int i;
    215 
    216 	for (i = 0; reasons[i]; i++) {
    217 		if (pcap_strcasecmp(reason, reasons[i]) == 0)
    218 			return (i);
    219 	}
    220 	bpf_error(cstate, "unknown PF reason");
    221 	/*NOTREACHED*/
    222 }
    223 
    224 static int
    225 pfaction_to_num(compiler_state_t *cstate, const char *action)
    226 {
    227 	if (pcap_strcasecmp(action, "pass") == 0 ||
    228 	    pcap_strcasecmp(action, "accept") == 0)
    229 		return (PF_PASS);
    230 	else if (pcap_strcasecmp(action, "drop") == 0 ||
    231 		pcap_strcasecmp(action, "block") == 0)
    232 		return (PF_DROP);
    233 #if HAVE_PF_NAT_THROUGH_PF_NORDR
    234 	else if (pcap_strcasecmp(action, "rdr") == 0)
    235 		return (PF_RDR);
    236 	else if (pcap_strcasecmp(action, "nat") == 0)
    237 		return (PF_NAT);
    238 	else if (pcap_strcasecmp(action, "binat") == 0)
    239 		return (PF_BINAT);
    240 	else if (pcap_strcasecmp(action, "nordr") == 0)
    241 		return (PF_NORDR);
    242 #endif
    243 	else {
    244 		bpf_error(cstate, "unknown PF action");
    245 		/*NOTREACHED*/
    246 	}
    247 }
    248 #else /* !HAVE_NET_PFVAR_H */
    249 static int
    250 pfreason_to_num(compiler_state_t *cstate, const char *reason)
    251 {
    252 	bpf_error(cstate, "libpcap was compiled on a machine without pf support");
    253 	/*NOTREACHED*/
    254 
    255 	/* this is to make the VC compiler happy */
    256 	return -1;
    257 }
    258 
    259 static int
    260 pfaction_to_num(compiler_state_t *cstate, const char *action)
    261 {
    262 	bpf_error(cstate, "libpcap was compiled on a machine without pf support");
    263 	/*NOTREACHED*/
    264 
    265 	/* this is to make the VC compiler happy */
    266 	return -1;
    267 }
    268 #endif /* HAVE_NET_PFVAR_H */
    269 %}
    270 
    271 %union {
    272 	int i;
    273 	bpf_u_int32 h;
    274 	u_char *e;
    275 	char *s;
    276 	struct stmt *stmt;
    277 	struct arth *a;
    278 	struct {
    279 		struct qual q;
    280 		int atmfieldtype;
    281 		int mtp3fieldtype;
    282 		struct block *b;
    283 	} blk;
    284 	struct block *rblk;
    285 }
    286 
    287 %type	<blk>	expr id nid pid term rterm qid
    288 %type	<blk>	head
    289 %type	<i>	pqual dqual aqual ndaqual
    290 %type	<a>	arth narth
    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
    295 %type	<blk>	atmfield
    296 %type	<blk>	atmfieldvalue atmvalue atmlistvalue
    297 %type	<i>	mtp2type
    298 %type	<blk>	mtp3field
    299 %type	<blk>	mtp3fieldvalue mtp3value mtp3listvalue
    300 
    301 
    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
    310 %token  LINK
    311 %token	GEQ LEQ NEQ
    312 %token	ID EID HID HID6 AID
    313 %token	LSH RSH
    314 %token  LEN
    315 %token  IPV6 ICMPV6 AH ESP
    316 %token	VLAN MPLS
    317 %token	PPPOED PPPOES GENEVE
    318 %token  ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
    319 %token  STP
    320 %token  IPX
    321 %token  NETBEUI
    322 %token	LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
    323 %token	OAM OAMF4 CONNECTMSG METACONNECT
    324 %token	VPI VCI
    325 %token	RADIO
    326 %token	FISU LSSU MSU HFISU HLSSU HMSU
    327 %token	SIO OPC DPC SLS HSIO HOPC HDPC HSLS
    328 
    329 
    330 %type	<s> ID
    331 %type	<e> EID
    332 %type	<e> AID
    333 %type	<s> HID HID6
    334 %type	<i> NUM action reason type subtype type_subtype dir
    335 
    336 %left OR AND
    337 %nonassoc  '!'
    338 %left '|'
    339 %left '&'
    340 %left LSH RSH
    341 %left '+' '-'
    342 %left '*' '/'
    343 %nonassoc UMINUS
    344 %%
    345 prog:	  null expr
    346 {
    347 	finish_parse(cstate, $2.b);
    348 }
    349 	| null
    350 	;
    351 null:	  /* null */		{ $$.q = qerr; }
    352 	;
    353 expr:	  term
    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; }
    358 	;
    359 and:	  AND			{ $$ = $<blk>0; }
    360 	;
    361 or:	  OR			{ $$ = $<blk>0; }
    362 	;
    363 id:	  nid
    364 	| pnum			{ $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
    365 						   $$.q = $<blk>0.q); }
    366 	| paren pid ')'		{ $$ = $2; }
    367 	;
    368 nid:	  ID			{ $$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q); }
    369 	| HID '/' NUM		{ $$.b = gen_mcode(cstate, $1, NULL, $3,
    370 				    $$.q = $<blk>0.q); }
    371 	| HID NETMASK HID	{ $$.b = gen_mcode(cstate, $1, $3, 0,
    372 				    $$.q = $<blk>0.q); }
    373 	| HID			{
    374 				  /* Decide how to parse HID based on proto */
    375 				  $$.q = $<blk>0.q;
    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);
    385 				}
    386 	| HID6 '/' NUM		{
    387 #ifdef INET6
    388 				  $$.b = gen_mcode6(cstate, $1, NULL, $3,
    389 				    $$.q = $<blk>0.q);
    390 #else
    391 				  bpf_error(cstate, "'ip6addr/prefixlen' not supported "
    392 					"in this configuration");
    393 #endif /*INET6*/
    394 				}
    395 	| HID6			{
    396 #ifdef INET6
    397 				  $$.b = gen_mcode6(cstate, $1, 0, 128,
    398 				    $$.q = $<blk>0.q);
    399 #else
    400 				  bpf_error(cstate, "'ip6addr' not supported "
    401 					"in this configuration");
    402 #endif /*INET6*/
    403 				}
    404 	| EID			{
    405 				  $$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q);
    406 				  /*
    407 				   * $1 was allocated by "pcap_ether_aton()",
    408 				   * so we must free it now that we're done
    409 				   * with it.
    410 				   */
    411 				  free($1);
    412 				}
    413 	| AID			{
    414 				  $$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q);
    415 				  /*
    416 				   * $1 was allocated by "pcap_ether_aton()",
    417 				   * so we must free it now that we're done
    418 				   * with it.
    419 				   */
    420 				  free($1);
    421 				}
    422 	| not id		{ gen_not($2.b); $$ = $2; }
    423 	;
    424 not:	  '!'			{ $$ = $<blk>0; }
    425 	;
    426 paren:	  '('			{ $$ = $<blk>0; }
    427 	;
    428 pid:	  nid
    429 	| qid and id		{ gen_and($1.b, $3.b); $$ = $3; }
    430 	| qid or id		{ gen_or($1.b, $3.b); $$ = $3; }
    431 	;
    432 qid:	  pnum			{ $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
    433 						   $$.q = $<blk>0.q); }
    434 	| pid
    435 	;
    436 term:	  rterm
    437 	| not term		{ gen_not($2.b); $$ = $2; }
    438 	;
    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); }
    445 	;
    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);
    450 				  $$.q = qerr; }
    451 	| arth irelop arth	{ $$.b = gen_relation(cstate, $2, $1, $3, 1);
    452 				  $$.q = qerr; }
    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; }
    459 	;
    460 /* protocol level qualifiers */
    461 pqual:	  pname
    462 	|			{ $$ = Q_DEFAULT; }
    463 	;
    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; }
    475 	| RA			{ $$ = Q_RA; }
    476 	| TA			{ $$ = Q_TA; }
    477 	;
    478 /* address type qualifiers */
    479 aqual:	  HOST			{ $$ = Q_HOST; }
    480 	| NET			{ $$ = Q_NET; }
    481 	| PORT			{ $$ = Q_PORT; }
    482 	| PORTRANGE		{ $$ = Q_PORTRANGE; }
    483 	;
    484 /* non-directional address type qualifiers */
    485 ndaqual:  GATEWAY		{ $$ = Q_GATEWAY; }
    486 	;
    487 pname:	  LINK			{ $$ = Q_LINK; }
    488 	| IP			{ $$ = Q_IP; }
    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; }
    509 	| AH			{ $$ = Q_AH; }
    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; }
    526 	;
    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); }
    543 	| pfvar			{ $$ = $1; }
    544 	| pqual p80211		{ $$ = $2; }
    545 	| pllc			{ $$ = $1; }
    546 	;
    547 
    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); }
    554 	;
    555 
    556 p80211:   TYPE type SUBTYPE subtype
    557 				{ $$ = gen_p80211_type(cstate, $2 | $4,
    558 					IEEE80211_FC0_TYPE_MASK |
    559 					IEEE80211_FC0_SUBTYPE_MASK);
    560 				}
    561 	| TYPE type		{ $$ = gen_p80211_type(cstate, $2,
    562 					IEEE80211_FC0_TYPE_MASK);
    563 				}
    564 	| SUBTYPE type_subtype	{ $$ = gen_p80211_type(cstate, $2,
    565 					IEEE80211_FC0_TYPE_MASK |
    566 					IEEE80211_FC0_SUBTYPE_MASK);
    567 				}
    568 	| DIR dir		{ $$ = gen_p80211_fcdir(cstate, $2); }
    569 	;
    570 
    571 type:	  NUM
    572 	| ID			{ $$ = str2tok($1, ieee80211_types);
    573 				  if ($$ == -1)
    574 				  	bpf_error(cstate, "unknown 802.11 type name");
    575 				}
    576 	;
    577 
    578 subtype:  NUM
    579 	| ID			{ const struct tok *types = NULL;
    580 				  int i;
    581 				  for (i = 0;; i++) {
    582 				  	if (ieee80211_type_subtypes[i].tok == NULL) {
    583 				  		/* Ran out of types */
    584 						bpf_error(cstate, "unknown 802.11 type");
    585 						break;
    586 					}
    587 					if ($<i>-1 == ieee80211_type_subtypes[i].type) {
    588 						types = ieee80211_type_subtypes[i].tok;
    589 						break;
    590 					}
    591 				  }
    592 
    593 				  $$ = str2tok($1, types);
    594 				  if ($$ == -1)
    595 					bpf_error(cstate, "unknown 802.11 subtype name");
    596 				}
    597 	;
    598 
    599 type_subtype:	ID		{ int i;
    600 				  for (i = 0;; i++) {
    601 				  	if (ieee80211_type_subtypes[i].tok == NULL) {
    602 				  		/* Ran out of types */
    603 						bpf_error(cstate, "unknown 802.11 type name");
    604 						break;
    605 					}
    606 					$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
    607 					if ($$ != -1) {
    608 						$$ |= ieee80211_type_subtypes[i].type;
    609 						break;
    610 					}
    611 				  }
    612 				}
    613 		;
    614 
    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);
    622 				  else {
    623 					int subtype;
    624 
    625 					subtype = str2tok($2, llc_s_subtypes);
    626 					if (subtype != -1)
    627 						$$ = gen_llc_s_subtype(cstate, subtype);
    628 					else {
    629 						subtype = str2tok($2, llc_u_subtypes);
    630 						if (subtype == -1)
    631 					  		bpf_error(cstate, "unknown LLC type name \"%s\"", $2);
    632 						$$ = gen_llc_u_subtype(cstate, subtype);
    633 					}
    634 				  }
    635 				}
    636 				/* sigh, "rnr" is already a keyword for PF */
    637 	| LLC PF_RNR		{ $$ = gen_llc_s_subtype(cstate, LLC_RNR); }
    638 	;
    639 
    640 dir:	  NUM
    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;
    649 				  else
    650 					bpf_error(cstate, "unknown 802.11 direction");
    651 				}
    652 	;
    653 
    654 reason:	  NUM			{ $$ = $1; }
    655 	| ID			{ $$ = pfreason_to_num(cstate, $1); }
    656 	;
    657 
    658 action:	  ID			{ $$ = pfaction_to_num(cstate, $1); }
    659 	;
    660 
    661 relop:	  '>'			{ $$ = BPF_JGT; }
    662 	| GEQ			{ $$ = BPF_JGE; }
    663 	| '='			{ $$ = BPF_JEQ; }
    664 	;
    665 irelop:	  LEQ			{ $$ = BPF_JGT; }
    666 	| '<'			{ $$ = BPF_JGE; }
    667 	| NEQ			{ $$ = BPF_JEQ; }
    668 	;
    669 arth:	  pnum			{ $$ = gen_loadi(cstate, $1); }
    670 	| narth
    671 	;
    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); }
    687 	;
    688 byteop:	  '&'			{ $$ = '&'; }
    689 	| '|'			{ $$ = '|'; }
    690 	| '<'			{ $$ = '<'; }
    691 	| '>'			{ $$ = '>'; }
    692 	| '='			{ $$ = '='; }
    693 	;
    694 pnum:	  NUM
    695 	| paren pnum ')'	{ $$ = $2; }
    696 	;
    697 atmtype: LANE			{ $$ = A_LANE; }
    698 	| METAC			{ $$ = A_METAC;	}
    699 	| BCC			{ $$ = A_BCC; }
    700 	| OAMF4EC		{ $$ = A_OAMF4EC; }
    701 	| OAMF4SC		{ $$ = A_OAMF4SC; }
    702 	| SC			{ $$ = A_SC; }
    703 	| ILMIC			{ $$ = A_ILMIC; }
    704 	;
    705 atmmultitype: OAM		{ $$ = A_OAM; }
    706 	| OAMF4			{ $$ = A_OAMF4; }
    707 	| CONNECTMSG		{ $$ = A_CONNECTMSG; }
    708 	| METACONNECT		{ $$ = A_METACONNECT; }
    709 	;
    710 	/* ATM field types quantifier */
    711 atmfield: VPI			{ $$.atmfieldtype = A_VPI; }
    712 	| VCI			{ $$.atmfieldtype = A_VCI; }
    713 	;
    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; }
    718 	;
    719 atmfieldvalue: NUM {
    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);
    724 	}
    725 	;
    726 atmlistvalue: atmfieldvalue
    727 	| atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
    728 	;
    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; }
    736 	;
    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; }
    746 	;
    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; }
    751 	;
    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);
    763 	}
    764 	;
    765 mtp3listvalue: mtp3fieldvalue
    766 	| mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
    767 	;
    768 %%
    769