Home | History | Annotate | Download | only in libpcap
      1 %{
      2 /*
      3  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
      4  *	The Regents of the University of California.  All rights reserved.
      5  *
      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
     17  * written permission.
     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.
     21  *
     22  */
     23 #ifndef lint
     24 static const char rcsid[] _U_ =
     25     "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.101 2007-11-18 02:03:52 guy Exp $ (LBL)";
     26 #endif
     27 
     28 #ifdef HAVE_CONFIG_H
     29 #include "config.h"
     30 #endif
     31 
     32 #ifdef WIN32
     33 #include <pcap-stdinc.h>
     34 #else /* WIN32 */
     35 #include <sys/types.h>
     36 #include <sys/socket.h>
     37 #endif /* WIN32 */
     38 
     39 #include <stdlib.h>
     40 
     41 #ifndef WIN32
     42 #if __STDC__
     43 struct mbuf;
     44 struct rtentry;
     45 #endif
     46 
     47 #include <netinet/in.h>
     48 #include <arpa/inet.h>
     49 #endif /* WIN32 */
     50 
     51 #include <stdio.h>
     52 
     53 #include "pcap-int.h"
     54 
     55 #include "gencode.h"
     56 #ifdef HAVE_NET_PFVAR_H
     57 #include <net/if.h>
     58 #include <net/pfvar.h>
     59 #include <net/if_pflog.h>
     60 #endif
     61 #include "ieee80211.h"
     62 #include <pcap/namedb.h>
     63 
     64 #ifdef HAVE_OS_PROTO_H
     65 #include "os-proto.h"
     66 #endif
     67 
     68 #define QSET(q, p, d, a) (q).proto = (p),\
     69 			 (q).dir = (d),\
     70 			 (q).addr = (a)
     71 
     72 struct tok {
     73 	int v;			/* value */
     74 	const char *s;		/* string */
     75 };
     76 
     77 static const struct tok ieee80211_types[] = {
     78 	{ IEEE80211_FC0_TYPE_DATA, "data" },
     79 	{ IEEE80211_FC0_TYPE_MGT, "mgt" },
     80 	{ IEEE80211_FC0_TYPE_MGT, "management" },
     81 	{ IEEE80211_FC0_TYPE_CTL, "ctl" },
     82 	{ IEEE80211_FC0_TYPE_CTL, "control" },
     83 	{ 0, NULL }
     84 };
     85 static const struct tok ieee80211_mgt_subtypes[] = {
     86 	{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
     87 	{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
     88 	{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
     89 	{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
     90 	{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
     91 	{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
     92 	{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
     93 	{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
     94 	{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
     95 	{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
     96 	{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
     97 	{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
     98 	{ IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
     99 	{ IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
    100 	{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
    101 	{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
    102 	{ IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
    103 	{ IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
    104 	{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
    105 	{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
    106 	{ 0, NULL }
    107 };
    108 static const struct tok ieee80211_ctl_subtypes[] = {
    109 	{ IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
    110 	{ IEEE80211_FC0_SUBTYPE_RTS, "rts" },
    111 	{ IEEE80211_FC0_SUBTYPE_CTS, "cts" },
    112 	{ IEEE80211_FC0_SUBTYPE_ACK, "ack" },
    113 	{ IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
    114 	{ IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
    115 	{ 0, NULL }
    116 };
    117 static const struct tok ieee80211_data_subtypes[] = {
    118 	{ IEEE80211_FC0_SUBTYPE_DATA, "data" },
    119 	{ IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
    120 	{ IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
    121 	{ IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
    122 	{ IEEE80211_FC0_SUBTYPE_NODATA, "null" },
    123 	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
    124 	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll"  },
    125 	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
    126 	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
    127 	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
    128 	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
    129 	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
    130 	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
    131 	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
    132 	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
    133 	{ 0, NULL }
    134 };
    135 struct type2tok {
    136 	int type;
    137 	const struct tok *tok;
    138 };
    139 static const struct type2tok ieee80211_type_subtypes[] = {
    140 	{ IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
    141 	{ IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
    142 	{ IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
    143 	{ 0, NULL }
    144 };
    145 
    146 static int
    147 str2tok(const char *str, const struct tok *toks)
    148 {
    149 	int i;
    150 
    151 	for (i = 0; toks[i].s != NULL; i++) {
    152 		if (pcap_strcasecmp(toks[i].s, str) == 0)
    153 			return (toks[i].v);
    154 	}
    155 	return (-1);
    156 }
    157 
    158 int n_errors = 0;
    159 
    160 static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
    161 
    162 static void
    163 yyerror(const char *msg)
    164 {
    165 	++n_errors;
    166 	bpf_error("%s", msg);
    167 	/* NOTREACHED */
    168 }
    169 
    170 #ifdef NEED_YYPARSE_WRAPPER
    171 int yyparse(void);
    172 
    173 int
    174 pcap_parse()
    175 {
    176 	return (yyparse());
    177 }
    178 #endif
    179 
    180 #ifdef HAVE_NET_PFVAR_H
    181 static int
    182 pfreason_to_num(const char *reason)
    183 {
    184 	const char *reasons[] = PFRES_NAMES;
    185 	int i;
    186 
    187 	for (i = 0; reasons[i]; i++) {
    188 		if (pcap_strcasecmp(reason, reasons[i]) == 0)
    189 			return (i);
    190 	}
    191 	bpf_error("unknown PF reason");
    192 	/*NOTREACHED*/
    193 }
    194 
    195 static int
    196 pfaction_to_num(const char *action)
    197 {
    198 	if (pcap_strcasecmp(action, "pass") == 0 ||
    199 	    pcap_strcasecmp(action, "accept") == 0)
    200 		return (PF_PASS);
    201 	else if (pcap_strcasecmp(action, "drop") == 0 ||
    202 		pcap_strcasecmp(action, "block") == 0)
    203 		return (PF_DROP);
    204 #if HAVE_PF_NAT_THROUGH_PF_NORDR
    205 	else if (pcap_strcasecmp(action, "rdr") == 0)
    206 		return (PF_RDR);
    207 	else if (pcap_strcasecmp(action, "nat") == 0)
    208 		return (PF_NAT);
    209 	else if (pcap_strcasecmp(action, "binat") == 0)
    210 		return (PF_BINAT);
    211 	else if (pcap_strcasecmp(action, "nordr") == 0)
    212 		return (PF_NORDR);
    213 #endif
    214 	else {
    215 		bpf_error("unknown PF action");
    216 		/*NOTREACHED*/
    217 	}
    218 }
    219 #else /* !HAVE_NET_PFVAR_H */
    220 static int
    221 pfreason_to_num(const char *reason)
    222 {
    223 	bpf_error("libpcap was compiled on a machine without pf support");
    224 	/*NOTREACHED*/
    225 
    226 	/* this is to make the VC compiler happy */
    227 	return -1;
    228 }
    229 
    230 static int
    231 pfaction_to_num(const char *action)
    232 {
    233 	bpf_error("libpcap was compiled on a machine without pf support");
    234 	/*NOTREACHED*/
    235 
    236 	/* this is to make the VC compiler happy */
    237 	return -1;
    238 }
    239 #endif /* HAVE_NET_PFVAR_H */
    240 %}
    241 
    242 %union {
    243 	int i;
    244 	bpf_u_int32 h;
    245 	u_char *e;
    246 	char *s;
    247 	struct stmt *stmt;
    248 	struct arth *a;
    249 	struct {
    250 		struct qual q;
    251 		int atmfieldtype;
    252 		int mtp3fieldtype;
    253 		struct block *b;
    254 	} blk;
    255 	struct block *rblk;
    256 }
    257 
    258 %type	<blk>	expr id nid pid term rterm qid
    259 %type	<blk>	head
    260 %type	<i>	pqual dqual aqual ndaqual
    261 %type	<a>	arth narth
    262 %type	<i>	byteop pname pnum relop irelop
    263 %type	<blk>	and or paren not null prog
    264 %type	<rblk>	other pfvar p80211
    265 %type	<i>	atmtype atmmultitype
    266 %type	<blk>	atmfield
    267 %type	<blk>	atmfieldvalue atmvalue atmlistvalue
    268 %type	<i>	mtp2type
    269 %type	<blk>	mtp3field
    270 %type	<blk>	mtp3fieldvalue mtp3value mtp3listvalue
    271 
    272 
    273 %token  DST SRC HOST GATEWAY
    274 %token  NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
    275 %token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
    276 %token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
    277 %token  TK_BROADCAST TK_MULTICAST
    278 %token  NUM INBOUND OUTBOUND
    279 %token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
    280 %token	TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
    281 %token  LINK
    282 %token	GEQ LEQ NEQ
    283 %token	ID EID HID HID6 AID
    284 %token	LSH RSH
    285 %token  LEN
    286 %token  IPV6 ICMPV6 AH ESP
    287 %token	VLAN MPLS
    288 %token	PPPOED PPPOES
    289 %token  ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
    290 %token  STP
    291 %token  IPX
    292 %token  NETBEUI
    293 %token	LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
    294 %token	OAM OAMF4 CONNECTMSG METACONNECT
    295 %token	VPI VCI
    296 %token	RADIO
    297 %token	FISU LSSU MSU HFISU HLSSU HMSU
    298 %token	SIO OPC DPC SLS HSIO HOPC HDPC HSLS
    299 
    300 
    301 %type	<s> ID
    302 %type	<e> EID
    303 %type	<e> AID
    304 %type	<s> HID HID6
    305 %type	<i> NUM action reason type subtype type_subtype dir
    306 
    307 %left OR AND
    308 %nonassoc  '!'
    309 %left '|'
    310 %left '&'
    311 %left LSH RSH
    312 %left '+' '-'
    313 %left '*' '/'
    314 %nonassoc UMINUS
    315 %%
    316 prog:	  null expr
    317 {
    318 	finish_parse($2.b);
    319 }
    320 	| null
    321 	;
    322 null:	  /* null */		{ $$.q = qerr; }
    323 	;
    324 expr:	  term
    325 	| expr and term		{ gen_and($1.b, $3.b); $$ = $3; }
    326 	| expr and id		{ gen_and($1.b, $3.b); $$ = $3; }
    327 	| expr or term		{ gen_or($1.b, $3.b); $$ = $3; }
    328 	| expr or id		{ gen_or($1.b, $3.b); $$ = $3; }
    329 	;
    330 and:	  AND			{ $$ = $<blk>0; }
    331 	;
    332 or:	  OR			{ $$ = $<blk>0; }
    333 	;
    334 id:	  nid
    335 	| pnum			{ $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
    336 						   $$.q = $<blk>0.q); }
    337 	| paren pid ')'		{ $$ = $2; }
    338 	;
    339 nid:	  ID			{ $$.b = gen_scode($1, $$.q = $<blk>0.q); }
    340 	| HID '/' NUM		{ $$.b = gen_mcode($1, NULL, $3,
    341 				    $$.q = $<blk>0.q); }
    342 	| HID NETMASK HID	{ $$.b = gen_mcode($1, $3, 0,
    343 				    $$.q = $<blk>0.q); }
    344 	| HID			{
    345 				  /* Decide how to parse HID based on proto */
    346 				  $$.q = $<blk>0.q;
    347 				  if ($$.q.addr == Q_PORT)
    348 				  	bpf_error("'port' modifier applied to ip host");
    349 				  else if ($$.q.addr == Q_PORTRANGE)
    350 				  	bpf_error("'portrange' modifier applied to ip host");
    351 				  else if ($$.q.addr == Q_PROTO)
    352 				  	bpf_error("'proto' modifier applied to ip host");
    353 				  else if ($$.q.addr == Q_PROTOCHAIN)
    354 				  	bpf_error("'protochain' modifier applied to ip host");
    355 				  $$.b = gen_ncode($1, 0, $$.q);
    356 				}
    357 	| HID6 '/' NUM		{
    358 #ifdef INET6
    359 				  $$.b = gen_mcode6($1, NULL, $3,
    360 				    $$.q = $<blk>0.q);
    361 #else
    362 				  bpf_error("'ip6addr/prefixlen' not supported "
    363 					"in this configuration");
    364 #endif /*INET6*/
    365 				}
    366 	| HID6			{
    367 #ifdef INET6
    368 				  $$.b = gen_mcode6($1, 0, 128,
    369 				    $$.q = $<blk>0.q);
    370 #else
    371 				  bpf_error("'ip6addr' not supported "
    372 					"in this configuration");
    373 #endif /*INET6*/
    374 				}
    375 	| EID			{
    376 				  $$.b = gen_ecode($1, $$.q = $<blk>0.q);
    377 				  /*
    378 				   * $1 was allocated by "pcap_ether_aton()",
    379 				   * so we must free it now that we're done
    380 				   * with it.
    381 				   */
    382 				  free($1);
    383 				}
    384 	| AID			{
    385 				  $$.b = gen_acode($1, $$.q = $<blk>0.q);
    386 				  /*
    387 				   * $1 was allocated by "pcap_ether_aton()",
    388 				   * so we must free it now that we're done
    389 				   * with it.
    390 				   */
    391 				  free($1);
    392 				}
    393 	| not id		{ gen_not($2.b); $$ = $2; }
    394 	;
    395 not:	  '!'			{ $$ = $<blk>0; }
    396 	;
    397 paren:	  '('			{ $$ = $<blk>0; }
    398 	;
    399 pid:	  nid
    400 	| qid and id		{ gen_and($1.b, $3.b); $$ = $3; }
    401 	| qid or id		{ gen_or($1.b, $3.b); $$ = $3; }
    402 	;
    403 qid:	  pnum			{ $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
    404 						   $$.q = $<blk>0.q); }
    405 	| pid
    406 	;
    407 term:	  rterm
    408 	| not term		{ gen_not($2.b); $$ = $2; }
    409 	;
    410 head:	  pqual dqual aqual	{ QSET($$.q, $1, $2, $3); }
    411 	| pqual dqual		{ QSET($$.q, $1, $2, Q_DEFAULT); }
    412 	| pqual aqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
    413 	| pqual PROTO		{ QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
    414 	| pqual PROTOCHAIN	{ QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
    415 	| pqual ndaqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
    416 	;
    417 rterm:	  head id		{ $$ = $2; }
    418 	| paren expr ')'	{ $$.b = $2.b; $$.q = $1.q; }
    419 	| pname			{ $$.b = gen_proto_abbrev($1); $$.q = qerr; }
    420 	| arth relop arth	{ $$.b = gen_relation($2, $1, $3, 0);
    421 				  $$.q = qerr; }
    422 	| arth irelop arth	{ $$.b = gen_relation($2, $1, $3, 1);
    423 				  $$.q = qerr; }
    424 	| other			{ $$.b = $1; $$.q = qerr; }
    425 	| atmtype		{ $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
    426 	| atmmultitype		{ $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
    427 	| atmfield atmvalue	{ $$.b = $2.b; $$.q = qerr; }
    428 	| mtp2type		{ $$.b = gen_mtp2type_abbrev($1); $$.q = qerr; }
    429 	| mtp3field mtp3value	{ $$.b = $2.b; $$.q = qerr; }
    430 	;
    431 /* protocol level qualifiers */
    432 pqual:	  pname
    433 	|			{ $$ = Q_DEFAULT; }
    434 	;
    435 /* 'direction' qualifiers */
    436 dqual:	  SRC			{ $$ = Q_SRC; }
    437 	| DST			{ $$ = Q_DST; }
    438 	| SRC OR DST		{ $$ = Q_OR; }
    439 	| DST OR SRC		{ $$ = Q_OR; }
    440 	| SRC AND DST		{ $$ = Q_AND; }
    441 	| DST AND SRC		{ $$ = Q_AND; }
    442 	| ADDR1			{ $$ = Q_ADDR1; }
    443 	| ADDR2			{ $$ = Q_ADDR2; }
    444 	| ADDR3			{ $$ = Q_ADDR3; }
    445 	| ADDR4			{ $$ = Q_ADDR4; }
    446 	| RA			{ $$ = Q_RA; }
    447 	| TA			{ $$ = Q_TA; }
    448 	;
    449 /* address type qualifiers */
    450 aqual:	  HOST			{ $$ = Q_HOST; }
    451 	| NET			{ $$ = Q_NET; }
    452 	| PORT			{ $$ = Q_PORT; }
    453 	| PORTRANGE		{ $$ = Q_PORTRANGE; }
    454 	;
    455 /* non-directional address type qualifiers */
    456 ndaqual:  GATEWAY		{ $$ = Q_GATEWAY; }
    457 	;
    458 pname:	  LINK			{ $$ = Q_LINK; }
    459 	| IP			{ $$ = Q_IP; }
    460 	| ARP			{ $$ = Q_ARP; }
    461 	| RARP			{ $$ = Q_RARP; }
    462 	| SCTP			{ $$ = Q_SCTP; }
    463 	| TCP			{ $$ = Q_TCP; }
    464 	| UDP			{ $$ = Q_UDP; }
    465 	| ICMP			{ $$ = Q_ICMP; }
    466 	| IGMP			{ $$ = Q_IGMP; }
    467 	| IGRP			{ $$ = Q_IGRP; }
    468 	| PIM			{ $$ = Q_PIM; }
    469 	| VRRP			{ $$ = Q_VRRP; }
    470 	| CARP 			{ $$ = Q_CARP; }
    471 	| ATALK			{ $$ = Q_ATALK; }
    472 	| AARP			{ $$ = Q_AARP; }
    473 	| DECNET		{ $$ = Q_DECNET; }
    474 	| LAT			{ $$ = Q_LAT; }
    475 	| SCA			{ $$ = Q_SCA; }
    476 	| MOPDL			{ $$ = Q_MOPDL; }
    477 	| MOPRC			{ $$ = Q_MOPRC; }
    478 	| IPV6			{ $$ = Q_IPV6; }
    479 	| ICMPV6		{ $$ = Q_ICMPV6; }
    480 	| AH			{ $$ = Q_AH; }
    481 	| ESP			{ $$ = Q_ESP; }
    482 	| ISO			{ $$ = Q_ISO; }
    483 	| ESIS			{ $$ = Q_ESIS; }
    484 	| ISIS			{ $$ = Q_ISIS; }
    485 	| L1			{ $$ = Q_ISIS_L1; }
    486 	| L2			{ $$ = Q_ISIS_L2; }
    487 	| IIH			{ $$ = Q_ISIS_IIH; }
    488 	| LSP			{ $$ = Q_ISIS_LSP; }
    489 	| SNP			{ $$ = Q_ISIS_SNP; }
    490 	| PSNP			{ $$ = Q_ISIS_PSNP; }
    491 	| CSNP			{ $$ = Q_ISIS_CSNP; }
    492 	| CLNP			{ $$ = Q_CLNP; }
    493 	| STP			{ $$ = Q_STP; }
    494 	| IPX			{ $$ = Q_IPX; }
    495 	| NETBEUI		{ $$ = Q_NETBEUI; }
    496 	| RADIO			{ $$ = Q_RADIO; }
    497 	;
    498 other:	  pqual TK_BROADCAST	{ $$ = gen_broadcast($1); }
    499 	| pqual TK_MULTICAST	{ $$ = gen_multicast($1); }
    500 	| LESS NUM		{ $$ = gen_less($2); }
    501 	| GREATER NUM		{ $$ = gen_greater($2); }
    502 	| CBYTE NUM byteop NUM	{ $$ = gen_byteop($3, $2, $4); }
    503 	| INBOUND		{ $$ = gen_inbound(0); }
    504 	| OUTBOUND		{ $$ = gen_inbound(1); }
    505 	| VLAN pnum		{ $$ = gen_vlan($2); }
    506 	| VLAN			{ $$ = gen_vlan(-1); }
    507 	| MPLS pnum		{ $$ = gen_mpls($2); }
    508 	| MPLS			{ $$ = gen_mpls(-1); }
    509 	| PPPOED		{ $$ = gen_pppoed(); }
    510 	| PPPOES pnum		{ $$ = gen_pppoes($2); }
    511 	| PPPOES		{ $$ = gen_pppoes(-1); }
    512 	| pfvar			{ $$ = $1; }
    513 	| pqual p80211		{ $$ = $2; }
    514 	;
    515 
    516 pfvar:	  PF_IFNAME ID		{ $$ = gen_pf_ifname($2); }
    517 	| PF_RSET ID		{ $$ = gen_pf_ruleset($2); }
    518 	| PF_RNR NUM		{ $$ = gen_pf_rnr($2); }
    519 	| PF_SRNR NUM		{ $$ = gen_pf_srnr($2); }
    520 	| PF_REASON reason	{ $$ = gen_pf_reason($2); }
    521 	| PF_ACTION action	{ $$ = gen_pf_action($2); }
    522 	;
    523 
    524 p80211:   TYPE type SUBTYPE subtype
    525 				{ $$ = gen_p80211_type($2 | $4,
    526 					IEEE80211_FC0_TYPE_MASK |
    527 					IEEE80211_FC0_SUBTYPE_MASK);
    528 				}
    529 	| TYPE type		{ $$ = gen_p80211_type($2,
    530 					IEEE80211_FC0_TYPE_MASK);
    531 				}
    532 	| SUBTYPE type_subtype	{ $$ = gen_p80211_type($2,
    533 					IEEE80211_FC0_TYPE_MASK |
    534 					IEEE80211_FC0_SUBTYPE_MASK);
    535 				}
    536 	| DIR dir		{ $$ = gen_p80211_fcdir($2); }
    537 	;
    538 
    539 type:	  NUM
    540 	| ID			{ $$ = str2tok($1, ieee80211_types);
    541 				  if ($$ == -1)
    542 				  	bpf_error("unknown 802.11 type name");
    543 				}
    544 	;
    545 
    546 subtype:  NUM
    547 	| ID			{ const struct tok *types = NULL;
    548 				  int i;
    549 				  for (i = 0;; i++) {
    550 				  	if (ieee80211_type_subtypes[i].tok == NULL) {
    551 				  		/* Ran out of types */
    552 						bpf_error("unknown 802.11 type");
    553 						break;
    554 					}
    555 					if ($<i>-1 == ieee80211_type_subtypes[i].type) {
    556 						types = ieee80211_type_subtypes[i].tok;
    557 						break;
    558 					}
    559 				  }
    560 
    561 				  $$ = str2tok($1, types);
    562 				  if ($$ == -1)
    563 					bpf_error("unknown 802.11 subtype name");
    564 				}
    565 	;
    566 
    567 type_subtype:	ID		{ int i;
    568 				  for (i = 0;; i++) {
    569 				  	if (ieee80211_type_subtypes[i].tok == NULL) {
    570 				  		/* Ran out of types */
    571 						bpf_error("unknown 802.11 type name");
    572 						break;
    573 					}
    574 					$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
    575 					if ($$ != -1) {
    576 						$$ |= ieee80211_type_subtypes[i].type;
    577 						break;
    578 					}
    579 				  }
    580 				}
    581 		;
    582 
    583 dir:	  NUM
    584 	| ID			{ if (pcap_strcasecmp($1, "nods") == 0)
    585 					$$ = IEEE80211_FC1_DIR_NODS;
    586 				  else if (pcap_strcasecmp($1, "tods") == 0)
    587 					$$ = IEEE80211_FC1_DIR_TODS;
    588 				  else if (pcap_strcasecmp($1, "fromds") == 0)
    589 					$$ = IEEE80211_FC1_DIR_FROMDS;
    590 				  else if (pcap_strcasecmp($1, "dstods") == 0)
    591 					$$ = IEEE80211_FC1_DIR_DSTODS;
    592 				  else
    593 					bpf_error("unknown 802.11 direction");
    594 				}
    595 	;
    596 
    597 reason:	  NUM			{ $$ = $1; }
    598 	| ID			{ $$ = pfreason_to_num($1); }
    599 	;
    600 
    601 action:	  ID			{ $$ = pfaction_to_num($1); }
    602 	;
    603 
    604 relop:	  '>'			{ $$ = BPF_JGT; }
    605 	| GEQ			{ $$ = BPF_JGE; }
    606 	| '='			{ $$ = BPF_JEQ; }
    607 	;
    608 irelop:	  LEQ			{ $$ = BPF_JGT; }
    609 	| '<'			{ $$ = BPF_JGE; }
    610 	| NEQ			{ $$ = BPF_JEQ; }
    611 	;
    612 arth:	  pnum			{ $$ = gen_loadi($1); }
    613 	| narth
    614 	;
    615 narth:	  pname '[' arth ']'		{ $$ = gen_load($1, $3, 1); }
    616 	| pname '[' arth ':' NUM ']'	{ $$ = gen_load($1, $3, $5); }
    617 	| arth '+' arth			{ $$ = gen_arth(BPF_ADD, $1, $3); }
    618 	| arth '-' arth			{ $$ = gen_arth(BPF_SUB, $1, $3); }
    619 	| arth '*' arth			{ $$ = gen_arth(BPF_MUL, $1, $3); }
    620 	| arth '/' arth			{ $$ = gen_arth(BPF_DIV, $1, $3); }
    621 	| arth '&' arth			{ $$ = gen_arth(BPF_AND, $1, $3); }
    622 	| arth '|' arth			{ $$ = gen_arth(BPF_OR, $1, $3); }
    623 	| arth LSH arth			{ $$ = gen_arth(BPF_LSH, $1, $3); }
    624 	| arth RSH arth			{ $$ = gen_arth(BPF_RSH, $1, $3); }
    625 	| '-' arth %prec UMINUS		{ $$ = gen_neg($2); }
    626 	| paren narth ')'		{ $$ = $2; }
    627 	| LEN				{ $$ = gen_loadlen(); }
    628 	;
    629 byteop:	  '&'			{ $$ = '&'; }
    630 	| '|'			{ $$ = '|'; }
    631 	| '<'			{ $$ = '<'; }
    632 	| '>'			{ $$ = '>'; }
    633 	| '='			{ $$ = '='; }
    634 	;
    635 pnum:	  NUM
    636 	| paren pnum ')'	{ $$ = $2; }
    637 	;
    638 atmtype: LANE			{ $$ = A_LANE; }
    639 	| LLC			{ $$ = A_LLC; }
    640 	| METAC			{ $$ = A_METAC;	}
    641 	| BCC			{ $$ = A_BCC; }
    642 	| OAMF4EC		{ $$ = A_OAMF4EC; }
    643 	| OAMF4SC		{ $$ = A_OAMF4SC; }
    644 	| SC			{ $$ = A_SC; }
    645 	| ILMIC			{ $$ = A_ILMIC; }
    646 	;
    647 atmmultitype: OAM		{ $$ = A_OAM; }
    648 	| OAMF4			{ $$ = A_OAMF4; }
    649 	| CONNECTMSG		{ $$ = A_CONNECTMSG; }
    650 	| METACONNECT		{ $$ = A_METACONNECT; }
    651 	;
    652 	/* ATM field types quantifier */
    653 atmfield: VPI			{ $$.atmfieldtype = A_VPI; }
    654 	| VCI			{ $$.atmfieldtype = A_VCI; }
    655 	;
    656 atmvalue: atmfieldvalue
    657 	| relop NUM		{ $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
    658 	| irelop NUM		{ $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
    659 	| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
    660 	;
    661 atmfieldvalue: NUM {
    662 	$$.atmfieldtype = $<blk>0.atmfieldtype;
    663 	if ($$.atmfieldtype == A_VPI ||
    664 	    $$.atmfieldtype == A_VCI)
    665 		$$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
    666 	}
    667 	;
    668 atmlistvalue: atmfieldvalue
    669 	| atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
    670 	;
    671 	/* MTP2 types quantifier */
    672 mtp2type: FISU			{ $$ = M_FISU; }
    673 	| LSSU			{ $$ = M_LSSU; }
    674 	| MSU			{ $$ = M_MSU; }
    675 	| HFISU			{ $$ = MH_FISU; }
    676 	| HLSSU			{ $$ = MH_LSSU; }
    677 	| HMSU			{ $$ = MH_MSU; }
    678 	;
    679 	/* MTP3 field types quantifier */
    680 mtp3field: SIO			{ $$.mtp3fieldtype = M_SIO; }
    681 	| OPC			{ $$.mtp3fieldtype = M_OPC; }
    682 	| DPC			{ $$.mtp3fieldtype = M_DPC; }
    683 	| SLS                   { $$.mtp3fieldtype = M_SLS; }
    684 	| HSIO			{ $$.mtp3fieldtype = MH_SIO; }
    685 	| HOPC			{ $$.mtp3fieldtype = MH_OPC; }
    686 	| HDPC			{ $$.mtp3fieldtype = MH_DPC; }
    687 	| HSLS                  { $$.mtp3fieldtype = MH_SLS; }
    688 	;
    689 mtp3value: mtp3fieldvalue
    690 	| relop NUM		{ $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
    691 	| irelop NUM		{ $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
    692 	| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
    693 	;
    694 mtp3fieldvalue: NUM {
    695 	$$.mtp3fieldtype = $<blk>0.mtp3fieldtype;
    696 	if ($$.mtp3fieldtype == M_SIO ||
    697 	    $$.mtp3fieldtype == M_OPC ||
    698 	    $$.mtp3fieldtype == M_DPC ||
    699 	    $$.mtp3fieldtype == M_SLS ||
    700 	    $$.mtp3fieldtype == MH_SIO ||
    701 	    $$.mtp3fieldtype == MH_OPC ||
    702 	    $$.mtp3fieldtype == MH_DPC ||
    703 	    $$.mtp3fieldtype == MH_SLS)
    704 		$$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
    705 	}
    706 	;
    707 mtp3listvalue: mtp3fieldvalue
    708 	| mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
    709 	;
    710 %%
    711