117683Spst%{
217683Spst/*
317683Spst * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
417683Spst *	The Regents of the University of California.  All rights reserved.
517683Spst *
617683Spst * Redistribution and use in source and binary forms, with or without
717683Spst * modification, are permitted provided that: (1) source code distributions
817683Spst * retain the above copyright notice and this paragraph in its entirety, (2)
917683Spst * distributions including binary code include the above copyright notice and
1017683Spst * this paragraph in its entirety in the documentation or other materials
1117683Spst * provided with the distribution, and (3) all advertising materials mentioning
1217683Spst * features or use of this software display the following acknowledgement:
1317683Spst * ``This product includes software developed by the University of California,
1417683Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1517683Spst * the University nor the names of its contributors may be used to endorse
1617683Spst * or promote products derived from this software without specific prior
1717683Spst * written permission.
1817683Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1917683Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
2017683Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2117683Spst *
2256891Sfenner * $FreeBSD$
2317683Spst */
2417683Spst#ifndef lint
25127667Sbmsstatic const char rcsid[] _U_ =
26214518Srpaulo    "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.101 2007-11-18 02:03:52 guy Exp $ (LBL)";
2717683Spst#endif
2817683Spst
2975110Sfenner#ifdef HAVE_CONFIG_H
3075110Sfenner#include "config.h"
3175110Sfenner#endif
3275110Sfenner
33127667Sbms#ifdef WIN32
34127667Sbms#include <pcap-stdinc.h>
35127667Sbms#else /* WIN32 */
3617683Spst#include <sys/types.h>
3717683Spst#include <sys/socket.h>
38127667Sbms#endif /* WIN32 */
39127667Sbms
4075110Sfenner#include <stdlib.h>
4117683Spst
42127667Sbms#ifndef WIN32
4317683Spst#if __STDC__
4417683Spststruct mbuf;
4517683Spststruct rtentry;
4617683Spst#endif
4717683Spst
4817683Spst#include <netinet/in.h>
49214518Srpaulo#include <arpa/inet.h>
50127667Sbms#endif /* WIN32 */
5117683Spst
5217683Spst#include <stdio.h>
5317683Spst
5417683Spst#include "pcap-int.h"
5517683Spst
5617683Spst#include "gencode.h"
57172680Smlaier#ifdef HAVE_NET_PFVAR_H
58172680Smlaier#include <net/if.h>
59263086Sglebius#include <netpfil/pf/pf.h>
60172680Smlaier#include <net/if_pflog.h>
61172680Smlaier#endif
62190225Srpaulo#include "ieee80211.h"
63190225Srpaulo#include <pcap/namedb.h>
6417683Spst
6517683Spst#ifdef HAVE_OS_PROTO_H
6617683Spst#include "os-proto.h"
6717683Spst#endif
6817683Spst
6917683Spst#define QSET(q, p, d, a) (q).proto = (p),\
7017683Spst			 (q).dir = (d),\
7117683Spst			 (q).addr = (a)
7217683Spst
73190225Srpaulostruct tok {
74190225Srpaulo	int v;			/* value */
75190225Srpaulo	const char *s;		/* string */
76190225Srpaulo};
77190225Srpaulo
78190225Srpaulostatic const struct tok ieee80211_types[] = {
79190225Srpaulo	{ IEEE80211_FC0_TYPE_DATA, "data" },
80190225Srpaulo	{ IEEE80211_FC0_TYPE_MGT, "mgt" },
81190225Srpaulo	{ IEEE80211_FC0_TYPE_MGT, "management" },
82190225Srpaulo	{ IEEE80211_FC0_TYPE_CTL, "ctl" },
83190225Srpaulo	{ IEEE80211_FC0_TYPE_CTL, "control" },
84190225Srpaulo	{ 0, NULL }
85190225Srpaulo};
86190225Srpaulostatic const struct tok ieee80211_mgt_subtypes[] = {
87190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
88190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
89190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
90190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
91190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
92190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
93190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
94190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
95190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
96190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
97190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
98190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
99190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
100190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
101190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
102190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
103190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
104190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
105190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
106190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
107190225Srpaulo	{ 0, NULL }
108190225Srpaulo};
109190225Srpaulostatic const struct tok ieee80211_ctl_subtypes[] = {
110190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
111190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_RTS, "rts" },
112190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_CTS, "cts" },
113190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_ACK, "ack" },
114190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
115190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
116190225Srpaulo	{ 0, NULL }
117190225Srpaulo};
118190225Srpaulostatic const struct tok ieee80211_data_subtypes[] = {
119190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_DATA, "data" },
120190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
121190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
122190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
123190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_NODATA, "null" },
124190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
125190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll"  },
126190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
127190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
128190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
129190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
130190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
131190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
132190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
133190225Srpaulo	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
134190225Srpaulo	{ 0, NULL }
135190225Srpaulo};
136190225Srpaulostruct type2tok {
137190225Srpaulo	int type;
138190225Srpaulo	const struct tok *tok;
139190225Srpaulo};
140190225Srpaulostatic const struct type2tok ieee80211_type_subtypes[] = {
141190225Srpaulo	{ IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
142190225Srpaulo	{ IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
143190225Srpaulo	{ IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
144190225Srpaulo	{ 0, NULL }
145190225Srpaulo};
146190225Srpaulo
147190225Srpaulostatic int
148190225Srpaulostr2tok(const char *str, const struct tok *toks)
149190225Srpaulo{
150190225Srpaulo	int i;
151190225Srpaulo
152190225Srpaulo	for (i = 0; toks[i].s != NULL; i++) {
153190225Srpaulo		if (pcap_strcasecmp(toks[i].s, str) == 0)
154190225Srpaulo			return (toks[i].v);
155190225Srpaulo	}
156190225Srpaulo	return (-1);
157190225Srpaulo}
158190225Srpaulo
15917683Spstint n_errors = 0;
16017683Spst
16117683Spststatic struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
16217683Spst
16317683Spststatic void
164172680Smlaieryyerror(const char *msg)
16517683Spst{
16617683Spst	++n_errors;
16726178Sfenner	bpf_error("%s", msg);
16817683Spst	/* NOTREACHED */
16917683Spst}
17017683Spst
171251129Sdelphij#ifdef NEED_YYPARSE_WRAPPER
17217683Spstint yyparse(void);
17317683Spst
17417683Spstint
17517683Spstpcap_parse()
17617683Spst{
17717683Spst	return (yyparse());
17817683Spst}
17917683Spst#endif
18017683Spst
181172680Smlaier#ifdef HAVE_NET_PFVAR_H
182172680Smlaierstatic int
183172680Smlaierpfreason_to_num(const char *reason)
184172680Smlaier{
185172680Smlaier	const char *reasons[] = PFRES_NAMES;
186172680Smlaier	int i;
187172680Smlaier
188172680Smlaier	for (i = 0; reasons[i]; i++) {
189172680Smlaier		if (pcap_strcasecmp(reason, reasons[i]) == 0)
190172680Smlaier			return (i);
191172680Smlaier	}
192172680Smlaier	bpf_error("unknown PF reason");
193172680Smlaier	/*NOTREACHED*/
194172680Smlaier}
195172680Smlaier
196172680Smlaierstatic int
197172680Smlaierpfaction_to_num(const char *action)
198172680Smlaier{
199172680Smlaier	if (pcap_strcasecmp(action, "pass") == 0 ||
200172680Smlaier	    pcap_strcasecmp(action, "accept") == 0)
201172680Smlaier		return (PF_PASS);
202172680Smlaier	else if (pcap_strcasecmp(action, "drop") == 0 ||
203172680Smlaier		pcap_strcasecmp(action, "block") == 0)
204172680Smlaier		return (PF_DROP);
205190225Srpaulo#if HAVE_PF_NAT_THROUGH_PF_NORDR
206190225Srpaulo	else if (pcap_strcasecmp(action, "rdr") == 0)
207190225Srpaulo		return (PF_RDR);
208190225Srpaulo	else if (pcap_strcasecmp(action, "nat") == 0)
209190225Srpaulo		return (PF_NAT);
210190225Srpaulo	else if (pcap_strcasecmp(action, "binat") == 0)
211190225Srpaulo		return (PF_BINAT);
212190225Srpaulo	else if (pcap_strcasecmp(action, "nordr") == 0)
213190225Srpaulo		return (PF_NORDR);
214190225Srpaulo#endif
215172680Smlaier	else {
216172680Smlaier		bpf_error("unknown PF action");
217172680Smlaier		/*NOTREACHED*/
218172680Smlaier	}
219172680Smlaier}
220172680Smlaier#else /* !HAVE_NET_PFVAR_H */
221172680Smlaierstatic int
222172680Smlaierpfreason_to_num(const char *reason)
223172680Smlaier{
224172680Smlaier	bpf_error("libpcap was compiled on a machine without pf support");
225172680Smlaier	/*NOTREACHED*/
226190225Srpaulo
227190225Srpaulo	/* this is to make the VC compiler happy */
228190225Srpaulo	return -1;
229172680Smlaier}
230172680Smlaier
231172680Smlaierstatic int
232172680Smlaierpfaction_to_num(const char *action)
233172680Smlaier{
234172680Smlaier	bpf_error("libpcap was compiled on a machine without pf support");
235172680Smlaier	/*NOTREACHED*/
236190225Srpaulo
237190225Srpaulo	/* this is to make the VC compiler happy */
238190225Srpaulo	return -1;
239172680Smlaier}
240172680Smlaier#endif /* HAVE_NET_PFVAR_H */
24117683Spst%}
24217683Spst
24317683Spst%union {
24417683Spst	int i;
24517683Spst	bpf_u_int32 h;
24617683Spst	u_char *e;
24717683Spst	char *s;
24817683Spst	struct stmt *stmt;
24917683Spst	struct arth *a;
25017683Spst	struct {
25117683Spst		struct qual q;
252127667Sbms		int atmfieldtype;
253147897Ssam		int mtp3fieldtype;
25417683Spst		struct block *b;
25517683Spst	} blk;
25617683Spst	struct block *rblk;
25717683Spst}
25817683Spst
25917683Spst%type	<blk>	expr id nid pid term rterm qid
26017683Spst%type	<blk>	head
26117683Spst%type	<i>	pqual dqual aqual ndaqual
26217683Spst%type	<a>	arth narth
26317683Spst%type	<i>	byteop pname pnum relop irelop
26417683Spst%type	<blk>	and or paren not null prog
265190225Srpaulo%type	<rblk>	other pfvar p80211
266127667Sbms%type	<i>	atmtype atmmultitype
267127667Sbms%type	<blk>	atmfield
268127667Sbms%type	<blk>	atmfieldvalue atmvalue atmlistvalue
269172680Smlaier%type	<i>	mtp2type
270172680Smlaier%type	<blk>	mtp3field
271172680Smlaier%type	<blk>	mtp3fieldvalue mtp3value mtp3listvalue
27217683Spst
273147897Ssam
27417683Spst%token  DST SRC HOST GATEWAY
275147897Ssam%token  NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
276235426Sdelphij%token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
27775110Sfenner%token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
27817683Spst%token  TK_BROADCAST TK_MULTICAST
27917683Spst%token  NUM INBOUND OUTBOUND
280127667Sbms%token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
281235426Sdelphij%token	TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
28217683Spst%token  LINK
28317683Spst%token	GEQ LEQ NEQ
28498533Sfenner%token	ID EID HID HID6 AID
28517683Spst%token	LSH RSH
28617683Spst%token  LEN
28756891Sfenner%token  IPV6 ICMPV6 AH ESP
288146771Ssam%token	VLAN MPLS
289162015Ssam%token	PPPOED PPPOES
290127667Sbms%token  ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
29198533Sfenner%token  STP
29298533Sfenner%token  IPX
29398533Sfenner%token  NETBEUI
294127667Sbms%token	LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
295127667Sbms%token	OAM OAMF4 CONNECTMSG METACONNECT
296127667Sbms%token	VPI VCI
297147897Ssam%token	RADIO
298172680Smlaier%token	FISU LSSU MSU
299172680Smlaier%token	SIO OPC DPC SLS
30017683Spst
30117683Spst%type	<s> ID
30217683Spst%type	<e> EID
30398533Sfenner%type	<e> AID
30456891Sfenner%type	<s> HID HID6
305190225Srpaulo%type	<i> NUM action reason type subtype type_subtype dir
30617683Spst
30717683Spst%left OR AND
30817683Spst%nonassoc  '!'
30917683Spst%left '|'
31017683Spst%left '&'
31117683Spst%left LSH RSH
31217683Spst%left '+' '-'
31317683Spst%left '*' '/'
31417683Spst%nonassoc UMINUS
31517683Spst%%
31617683Spstprog:	  null expr
31717683Spst{
31817683Spst	finish_parse($2.b);
31917683Spst}
32017683Spst	| null
32117683Spst	;
32217683Spstnull:	  /* null */		{ $$.q = qerr; }
32317683Spst	;
32417683Spstexpr:	  term
32517683Spst	| expr and term		{ gen_and($1.b, $3.b); $$ = $3; }
32617683Spst	| expr and id		{ gen_and($1.b, $3.b); $$ = $3; }
32717683Spst	| expr or term		{ gen_or($1.b, $3.b); $$ = $3; }
32817683Spst	| expr or id		{ gen_or($1.b, $3.b); $$ = $3; }
32917683Spst	;
33017683Spstand:	  AND			{ $$ = $<blk>0; }
33117683Spst	;
33217683Spstor:	  OR			{ $$ = $<blk>0; }
33317683Spst	;
33417683Spstid:	  nid
33517683Spst	| pnum			{ $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
33617683Spst						   $$.q = $<blk>0.q); }
33717683Spst	| paren pid ')'		{ $$ = $2; }
33817683Spst	;
33917683Spstnid:	  ID			{ $$.b = gen_scode($1, $$.q = $<blk>0.q); }
34017683Spst	| HID '/' NUM		{ $$.b = gen_mcode($1, NULL, $3,
34117683Spst				    $$.q = $<blk>0.q); }
342127667Sbms	| HID NETMASK HID	{ $$.b = gen_mcode($1, $3, 0,
34317683Spst				    $$.q = $<blk>0.q); }
34417683Spst	| HID			{
34517683Spst				  /* Decide how to parse HID based on proto */
34617683Spst				  $$.q = $<blk>0.q;
347190225Srpaulo				  if ($$.q.addr == Q_PORT)
348190225Srpaulo				  	bpf_error("'port' modifier applied to ip host");
349190225Srpaulo				  else if ($$.q.addr == Q_PORTRANGE)
350190225Srpaulo				  	bpf_error("'portrange' modifier applied to ip host");
351190225Srpaulo				  else if ($$.q.addr == Q_PROTO)
352190225Srpaulo				  	bpf_error("'proto' modifier applied to ip host");
353190225Srpaulo				  else if ($$.q.addr == Q_PROTOCHAIN)
354190225Srpaulo				  	bpf_error("'protochain' modifier applied to ip host");
35575110Sfenner				  $$.b = gen_ncode($1, 0, $$.q);
35617683Spst				}
35756891Sfenner	| HID6 '/' NUM		{
35856891Sfenner#ifdef INET6
35956891Sfenner				  $$.b = gen_mcode6($1, NULL, $3,
36056891Sfenner				    $$.q = $<blk>0.q);
36156891Sfenner#else
36256891Sfenner				  bpf_error("'ip6addr/prefixlen' not supported "
36356891Sfenner					"in this configuration");
36456891Sfenner#endif /*INET6*/
36556891Sfenner				}
36656891Sfenner	| HID6			{
36756891Sfenner#ifdef INET6
36856891Sfenner				  $$.b = gen_mcode6($1, 0, 128,
36956891Sfenner				    $$.q = $<blk>0.q);
37056891Sfenner#else
37156891Sfenner				  bpf_error("'ip6addr' not supported "
37256891Sfenner					"in this configuration");
37356891Sfenner#endif /*INET6*/
37456891Sfenner				}
37598533Sfenner	| EID			{
37698533Sfenner				  $$.b = gen_ecode($1, $$.q = $<blk>0.q);
37798533Sfenner				  /*
37898533Sfenner				   * $1 was allocated by "pcap_ether_aton()",
37998533Sfenner				   * so we must free it now that we're done
38098533Sfenner				   * with it.
38198533Sfenner				   */
38298533Sfenner				  free($1);
38398533Sfenner				}
38498533Sfenner	| AID			{
38598533Sfenner				  $$.b = gen_acode($1, $$.q = $<blk>0.q);
38698533Sfenner				  /*
38798533Sfenner				   * $1 was allocated by "pcap_ether_aton()",
38898533Sfenner				   * so we must free it now that we're done
38998533Sfenner				   * with it.
39098533Sfenner				   */
39198533Sfenner				  free($1);
39298533Sfenner				}
39317683Spst	| not id		{ gen_not($2.b); $$ = $2; }
39417683Spst	;
39517683Spstnot:	  '!'			{ $$ = $<blk>0; }
39617683Spst	;
39717683Spstparen:	  '('			{ $$ = $<blk>0; }
39817683Spst	;
39917683Spstpid:	  nid
40017683Spst	| qid and id		{ gen_and($1.b, $3.b); $$ = $3; }
40117683Spst	| qid or id		{ gen_or($1.b, $3.b); $$ = $3; }
40217683Spst	;
40317683Spstqid:	  pnum			{ $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
40417683Spst						   $$.q = $<blk>0.q); }
40517683Spst	| pid
40617683Spst	;
40717683Spstterm:	  rterm
40817683Spst	| not term		{ gen_not($2.b); $$ = $2; }
40917683Spst	;
41017683Spsthead:	  pqual dqual aqual	{ QSET($$.q, $1, $2, $3); }
41117683Spst	| pqual dqual		{ QSET($$.q, $1, $2, Q_DEFAULT); }
41217683Spst	| pqual aqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
41317683Spst	| pqual PROTO		{ QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
41456891Sfenner	| pqual PROTOCHAIN	{ QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
41517683Spst	| pqual ndaqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
41617683Spst	;
41717683Spstrterm:	  head id		{ $$ = $2; }
41817683Spst	| paren expr ')'	{ $$.b = $2.b; $$.q = $1.q; }
41917683Spst	| pname			{ $$.b = gen_proto_abbrev($1); $$.q = qerr; }
42017683Spst	| arth relop arth	{ $$.b = gen_relation($2, $1, $3, 0);
42117683Spst				  $$.q = qerr; }
42217683Spst	| arth irelop arth	{ $$.b = gen_relation($2, $1, $3, 1);
42317683Spst				  $$.q = qerr; }
42417683Spst	| other			{ $$.b = $1; $$.q = qerr; }
425127667Sbms	| atmtype		{ $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
426127667Sbms	| atmmultitype		{ $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
427127667Sbms	| atmfield atmvalue	{ $$.b = $2.b; $$.q = qerr; }
428172680Smlaier	| mtp2type		{ $$.b = gen_mtp2type_abbrev($1); $$.q = qerr; }
429147897Ssam	| mtp3field mtp3value	{ $$.b = $2.b; $$.q = qerr; }
43017683Spst	;
43117683Spst/* protocol level qualifiers */
43217683Spstpqual:	  pname
43317683Spst	|			{ $$ = Q_DEFAULT; }
43417683Spst	;
43517683Spst/* 'direction' qualifiers */
43617683Spstdqual:	  SRC			{ $$ = Q_SRC; }
43717683Spst	| DST			{ $$ = Q_DST; }
43817683Spst	| SRC OR DST		{ $$ = Q_OR; }
43917683Spst	| DST OR SRC		{ $$ = Q_OR; }
44017683Spst	| SRC AND DST		{ $$ = Q_AND; }
44117683Spst	| DST AND SRC		{ $$ = Q_AND; }
442190225Srpaulo	| ADDR1			{ $$ = Q_ADDR1; }
443190225Srpaulo	| ADDR2			{ $$ = Q_ADDR2; }
444190225Srpaulo	| ADDR3			{ $$ = Q_ADDR3; }
445190225Srpaulo	| ADDR4			{ $$ = Q_ADDR4; }
446235426Sdelphij	| RA			{ $$ = Q_RA; }
447235426Sdelphij	| TA			{ $$ = Q_TA; }
44817683Spst	;
44917683Spst/* address type qualifiers */
45017683Spstaqual:	  HOST			{ $$ = Q_HOST; }
45117683Spst	| NET			{ $$ = Q_NET; }
45217683Spst	| PORT			{ $$ = Q_PORT; }
453147897Ssam	| PORTRANGE		{ $$ = Q_PORTRANGE; }
45417683Spst	;
45517683Spst/* non-directional address type qualifiers */
45617683Spstndaqual:  GATEWAY		{ $$ = Q_GATEWAY; }
45717683Spst	;
45817683Spstpname:	  LINK			{ $$ = Q_LINK; }
45917683Spst	| IP			{ $$ = Q_IP; }
46017683Spst	| ARP			{ $$ = Q_ARP; }
46117683Spst	| RARP			{ $$ = Q_RARP; }
46298533Sfenner	| SCTP			{ $$ = Q_SCTP; }
46317683Spst	| TCP			{ $$ = Q_TCP; }
46417683Spst	| UDP			{ $$ = Q_UDP; }
46517683Spst	| ICMP			{ $$ = Q_ICMP; }
46617683Spst	| IGMP			{ $$ = Q_IGMP; }
46717683Spst	| IGRP			{ $$ = Q_IGRP; }
46856891Sfenner	| PIM			{ $$ = Q_PIM; }
46998533Sfenner	| VRRP			{ $$ = Q_VRRP; }
470235426Sdelphij	| CARP 			{ $$ = Q_CARP; }
47117683Spst	| ATALK			{ $$ = Q_ATALK; }
47275110Sfenner	| AARP			{ $$ = Q_AARP; }
47317683Spst	| DECNET		{ $$ = Q_DECNET; }
47417683Spst	| LAT			{ $$ = Q_LAT; }
47517683Spst	| SCA			{ $$ = Q_SCA; }
47617683Spst	| MOPDL			{ $$ = Q_MOPDL; }
47717683Spst	| MOPRC			{ $$ = Q_MOPRC; }
47856891Sfenner	| IPV6			{ $$ = Q_IPV6; }
47956891Sfenner	| ICMPV6		{ $$ = Q_ICMPV6; }
48056891Sfenner	| AH			{ $$ = Q_AH; }
48156891Sfenner	| ESP			{ $$ = Q_ESP; }
48217749Spst	| ISO			{ $$ = Q_ISO; }
48317749Spst	| ESIS			{ $$ = Q_ESIS; }
48417749Spst	| ISIS			{ $$ = Q_ISIS; }
485127667Sbms	| L1			{ $$ = Q_ISIS_L1; }
486127667Sbms	| L2			{ $$ = Q_ISIS_L2; }
487127667Sbms	| IIH			{ $$ = Q_ISIS_IIH; }
488127667Sbms	| LSP			{ $$ = Q_ISIS_LSP; }
489127667Sbms	| SNP			{ $$ = Q_ISIS_SNP; }
490127667Sbms	| PSNP			{ $$ = Q_ISIS_PSNP; }
491127667Sbms	| CSNP			{ $$ = Q_ISIS_CSNP; }
49275110Sfenner	| CLNP			{ $$ = Q_CLNP; }
49398533Sfenner	| STP			{ $$ = Q_STP; }
49498533Sfenner	| IPX			{ $$ = Q_IPX; }
49598533Sfenner	| NETBEUI		{ $$ = Q_NETBEUI; }
496147897Ssam	| RADIO			{ $$ = Q_RADIO; }
49717683Spst	;
49817683Spstother:	  pqual TK_BROADCAST	{ $$ = gen_broadcast($1); }
49917683Spst	| pqual TK_MULTICAST	{ $$ = gen_multicast($1); }
50017683Spst	| LESS NUM		{ $$ = gen_less($2); }
50117683Spst	| GREATER NUM		{ $$ = gen_greater($2); }
502127667Sbms	| CBYTE NUM byteop NUM	{ $$ = gen_byteop($3, $2, $4); }
50317683Spst	| INBOUND		{ $$ = gen_inbound(0); }
50417683Spst	| OUTBOUND		{ $$ = gen_inbound(1); }
50575110Sfenner	| VLAN pnum		{ $$ = gen_vlan($2); }
50675110Sfenner	| VLAN			{ $$ = gen_vlan(-1); }
507146771Ssam	| MPLS pnum		{ $$ = gen_mpls($2); }
508146771Ssam	| MPLS			{ $$ = gen_mpls(-1); }
509162015Ssam	| PPPOED		{ $$ = gen_pppoed(); }
510162015Ssam	| PPPOES		{ $$ = gen_pppoes(); }
511127667Sbms	| pfvar			{ $$ = $1; }
512190225Srpaulo	| pqual p80211		{ $$ = $2; }
51317683Spst	;
514127667Sbms
515127667Sbmspfvar:	  PF_IFNAME ID		{ $$ = gen_pf_ifname($2); }
516127667Sbms	| PF_RSET ID		{ $$ = gen_pf_ruleset($2); }
517127667Sbms	| PF_RNR NUM		{ $$ = gen_pf_rnr($2); }
518127667Sbms	| PF_SRNR NUM		{ $$ = gen_pf_srnr($2); }
519127667Sbms	| PF_REASON reason	{ $$ = gen_pf_reason($2); }
520127667Sbms	| PF_ACTION action	{ $$ = gen_pf_action($2); }
521127667Sbms	;
522127667Sbms
523190225Srpaulop80211:   TYPE type SUBTYPE subtype
524190225Srpaulo				{ $$ = gen_p80211_type($2 | $4,
525190225Srpaulo					IEEE80211_FC0_TYPE_MASK |
526190225Srpaulo					IEEE80211_FC0_SUBTYPE_MASK);
527190225Srpaulo				}
528190225Srpaulo	| TYPE type		{ $$ = gen_p80211_type($2,
529190225Srpaulo					IEEE80211_FC0_TYPE_MASK);
530190225Srpaulo				}
531190225Srpaulo	| SUBTYPE type_subtype	{ $$ = gen_p80211_type($2,
532190225Srpaulo					IEEE80211_FC0_TYPE_MASK |
533190225Srpaulo					IEEE80211_FC0_SUBTYPE_MASK);
534190225Srpaulo				}
535190225Srpaulo	| DIR dir		{ $$ = gen_p80211_fcdir($2); }
536190225Srpaulo	;
537190225Srpaulo
538190225Srpaulotype:	  NUM
539190225Srpaulo	| ID			{ $$ = str2tok($1, ieee80211_types);
540190225Srpaulo				  if ($$ == -1)
541190225Srpaulo				  	bpf_error("unknown 802.11 type name");
542190225Srpaulo				}
543190225Srpaulo	;
544190225Srpaulo
545190225Srpaulosubtype:  NUM
546190225Srpaulo	| ID			{ const struct tok *types = NULL;
547190225Srpaulo				  int i;
548190225Srpaulo				  for (i = 0;; i++) {
549190225Srpaulo				  	if (ieee80211_type_subtypes[i].tok == NULL) {
550190225Srpaulo				  		/* Ran out of types */
551190225Srpaulo						bpf_error("unknown 802.11 type");
552190225Srpaulo						break;
553190225Srpaulo					}
554190225Srpaulo					if ($<i>-1 == ieee80211_type_subtypes[i].type) {
555190225Srpaulo						types = ieee80211_type_subtypes[i].tok;
556190225Srpaulo						break;
557190225Srpaulo					}
558190225Srpaulo				  }
559190225Srpaulo
560190225Srpaulo				  $$ = str2tok($1, types);
561190225Srpaulo				  if ($$ == -1)
562190225Srpaulo					bpf_error("unknown 802.11 subtype name");
563190225Srpaulo				}
564190225Srpaulo	;
565190225Srpaulo
566190225Srpaulotype_subtype:	ID		{ int i;
567190225Srpaulo				  for (i = 0;; i++) {
568190225Srpaulo				  	if (ieee80211_type_subtypes[i].tok == NULL) {
569190225Srpaulo				  		/* Ran out of types */
570190225Srpaulo						bpf_error("unknown 802.11 type name");
571190225Srpaulo						break;
572190225Srpaulo					}
573190225Srpaulo					$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
574190225Srpaulo					if ($$ != -1) {
575190225Srpaulo						$$ |= ieee80211_type_subtypes[i].type;
576190225Srpaulo						break;
577190225Srpaulo					}
578190225Srpaulo				  }
579190225Srpaulo				}
580190225Srpaulo		;
581190225Srpaulo
582190225Srpaulodir:	  NUM
583190225Srpaulo	| ID			{ if (pcap_strcasecmp($1, "nods") == 0)
584190225Srpaulo					$$ = IEEE80211_FC1_DIR_NODS;
585190225Srpaulo				  else if (pcap_strcasecmp($1, "tods") == 0)
586190225Srpaulo					$$ = IEEE80211_FC1_DIR_TODS;
587190225Srpaulo				  else if (pcap_strcasecmp($1, "fromds") == 0)
588190225Srpaulo					$$ = IEEE80211_FC1_DIR_FROMDS;
589190225Srpaulo				  else if (pcap_strcasecmp($1, "dstods") == 0)
590190225Srpaulo					$$ = IEEE80211_FC1_DIR_DSTODS;
591190225Srpaulo				  else
592190225Srpaulo					bpf_error("unknown 802.11 direction");
593190225Srpaulo				}
594190225Srpaulo	;
595190225Srpaulo
596127667Sbmsreason:	  NUM			{ $$ = $1; }
597172680Smlaier	| ID			{ $$ = pfreason_to_num($1); }
598127667Sbms	;
599127667Sbms
600172680Smlaieraction:	  ID			{ $$ = pfaction_to_num($1); }
601127667Sbms	;
602127667Sbms
60317683Spstrelop:	  '>'			{ $$ = BPF_JGT; }
60417683Spst	| GEQ			{ $$ = BPF_JGE; }
60517683Spst	| '='			{ $$ = BPF_JEQ; }
60617683Spst	;
60717683Spstirelop:	  LEQ			{ $$ = BPF_JGT; }
60817683Spst	| '<'			{ $$ = BPF_JGE; }
60917683Spst	| NEQ			{ $$ = BPF_JEQ; }
61017683Spst	;
61117683Spstarth:	  pnum			{ $$ = gen_loadi($1); }
61217683Spst	| narth
61317683Spst	;
61417683Spstnarth:	  pname '[' arth ']'		{ $$ = gen_load($1, $3, 1); }
61517683Spst	| pname '[' arth ':' NUM ']'	{ $$ = gen_load($1, $3, $5); }
61617683Spst	| arth '+' arth			{ $$ = gen_arth(BPF_ADD, $1, $3); }
61717683Spst	| arth '-' arth			{ $$ = gen_arth(BPF_SUB, $1, $3); }
61817683Spst	| arth '*' arth			{ $$ = gen_arth(BPF_MUL, $1, $3); }
61917683Spst	| arth '/' arth			{ $$ = gen_arth(BPF_DIV, $1, $3); }
62017683Spst	| arth '&' arth			{ $$ = gen_arth(BPF_AND, $1, $3); }
62117683Spst	| arth '|' arth			{ $$ = gen_arth(BPF_OR, $1, $3); }
62217683Spst	| arth LSH arth			{ $$ = gen_arth(BPF_LSH, $1, $3); }
62317683Spst	| arth RSH arth			{ $$ = gen_arth(BPF_RSH, $1, $3); }
62417683Spst	| '-' arth %prec UMINUS		{ $$ = gen_neg($2); }
62517683Spst	| paren narth ')'		{ $$ = $2; }
62617683Spst	| LEN				{ $$ = gen_loadlen(); }
62717683Spst	;
62817683Spstbyteop:	  '&'			{ $$ = '&'; }
62917683Spst	| '|'			{ $$ = '|'; }
63017683Spst	| '<'			{ $$ = '<'; }
63117683Spst	| '>'			{ $$ = '>'; }
63217683Spst	| '='			{ $$ = '='; }
63317683Spst	;
63417683Spstpnum:	  NUM
63517683Spst	| paren pnum ')'	{ $$ = $2; }
63617683Spst	;
637127667Sbmsatmtype: LANE			{ $$ = A_LANE; }
638127667Sbms	| LLC			{ $$ = A_LLC; }
639127667Sbms	| METAC			{ $$ = A_METAC;	}
640127667Sbms	| BCC			{ $$ = A_BCC; }
641127667Sbms	| OAMF4EC		{ $$ = A_OAMF4EC; }
642127667Sbms	| OAMF4SC		{ $$ = A_OAMF4SC; }
643127667Sbms	| SC			{ $$ = A_SC; }
644127667Sbms	| ILMIC			{ $$ = A_ILMIC; }
645127667Sbms	;
646127667Sbmsatmmultitype: OAM		{ $$ = A_OAM; }
647127667Sbms	| OAMF4			{ $$ = A_OAMF4; }
648127667Sbms	| CONNECTMSG		{ $$ = A_CONNECTMSG; }
649127667Sbms	| METACONNECT		{ $$ = A_METACONNECT; }
650127667Sbms	;
651127667Sbms	/* ATM field types quantifier */
652127667Sbmsatmfield: VPI			{ $$.atmfieldtype = A_VPI; }
653127667Sbms	| VCI			{ $$.atmfieldtype = A_VCI; }
654127667Sbms	;
655127667Sbmsatmvalue: atmfieldvalue
656147897Ssam	| relop NUM		{ $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
657147897Ssam	| irelop NUM		{ $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
658127667Sbms	| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
659127667Sbms	;
660127667Sbmsatmfieldvalue: NUM {
661127667Sbms	$$.atmfieldtype = $<blk>0.atmfieldtype;
662127667Sbms	if ($$.atmfieldtype == A_VPI ||
663127667Sbms	    $$.atmfieldtype == A_VCI)
664147897Ssam		$$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
665127667Sbms	}
666127667Sbms	;
667127667Sbmsatmlistvalue: atmfieldvalue
668127667Sbms	| atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
669127667Sbms	;
670172680Smlaier	/* MTP2 types quantifier */
671172680Smlaiermtp2type: FISU			{ $$ = M_FISU; }
672172680Smlaier	| LSSU			{ $$ = M_LSSU; }
673172680Smlaier	| MSU			{ $$ = M_MSU; }
674172680Smlaier	;
675147897Ssam	/* MTP3 field types quantifier */
676147897Ssammtp3field: SIO			{ $$.mtp3fieldtype = M_SIO; }
677147897Ssam	| OPC			{ $$.mtp3fieldtype = M_OPC; }
678147897Ssam	| DPC			{ $$.mtp3fieldtype = M_DPC; }
679147897Ssam	| SLS                   { $$.mtp3fieldtype = M_SLS; }
680147897Ssam	;
681147897Ssammtp3value: mtp3fieldvalue
682147897Ssam	| relop NUM		{ $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
683147897Ssam	| irelop NUM		{ $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
684147897Ssam	| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
685147897Ssam	;
686147897Ssammtp3fieldvalue: NUM {
687147897Ssam	$$.mtp3fieldtype = $<blk>0.mtp3fieldtype;
688147897Ssam	if ($$.mtp3fieldtype == M_SIO ||
689147897Ssam	    $$.mtp3fieldtype == M_OPC ||
690147897Ssam	    $$.mtp3fieldtype == M_DPC ||
691147897Ssam	    $$.mtp3fieldtype == M_SLS )
692147897Ssam		$$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
693147897Ssam	}
694147897Ssam	;
695147897Ssammtp3listvalue: mtp3fieldvalue
696147897Ssam	| mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
697147897Ssam	;
69817683Spst%%
699