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