xref: /freebsd/contrib/libpcap/grammar.y.in (revision 16cef5f7a65588def71db4fdfa961f959847e3b6)
1/*
2 * We want a reentrant parser.
3 */
4@REENTRANT_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 * According to bison documentation, shift/reduce conflicts are not an issue
23 * in most parsers as long as the number does not evolve over time:
24 * https://www.gnu.org/software/bison/manual/html_node/Expect-Decl.html
25 * So, following the advice use %expect to check the amount of shift/reduce
26 * warnings.
27 *
28 * This doesn't appear to work in Berkeley YACC - 1.9 20170709; it still
29 * warns of 38 shift/reduce conflicts.
30 *
31 * The Berkeley YACC documentation:
32 *
33 *    https://invisible-island.net/byacc/manpage/yacc.html
34 *
35 * claims that "Bison's support for "%expect" is broken in more than one
36 * release.", but doesn't give details.  Hopefully, that only means that
37 * you get warnings even if you have the expected number of shift/reduce
38 * conflicts, not that anything else fails.
39 */
40%expect 38
41
42/*
43 * And we need to pass the compiler state to the scanner.
44 */
45%parse-param { compiler_state_t *cstate }
46
47%{
48/*
49 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
50 *	The Regents of the University of California.  All rights reserved.
51 *
52 * Redistribution and use in source and binary forms, with or without
53 * modification, are permitted provided that: (1) source code distributions
54 * retain the above copyright notice and this paragraph in its entirety, (2)
55 * distributions including binary code include the above copyright notice and
56 * this paragraph in its entirety in the documentation or other materials
57 * provided with the distribution, and (3) all advertising materials mentioning
58 * features or use of this software display the following acknowledgement:
59 * ``This product includes software developed by the University of California,
60 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
61 * the University nor the names of its contributors may be used to endorse
62 * or promote products derived from this software without specific prior
63 * written permission.
64 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
65 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
66 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
67 *
68 */
69
70#include <config.h>
71
72/*
73 * grammar.h requires gencode.h and sometimes breaks in a polluted namespace
74 * (see ftmacros.h), so include it early.
75 */
76#include "gencode.h"
77#include "grammar.h"
78
79#include <stdlib.h>
80
81#include <stdio.h>
82
83#include "diag-control.h"
84
85#include "pcap-int.h"
86
87#include "scanner.h"
88
89#include "llc.h"
90#include "ieee80211.h"
91#include "pflog.h"
92#include <pcap/namedb.h>
93
94#ifdef HAVE_OS_PROTO_H
95#include "os-proto.h"
96#endif
97
98/*
99 * Work around some bugs in Berkeley YACC prior to the 2017-07-09
100 * release.
101 *
102 * The 2005-05-05 release was the first one to define YYPATCH, so
103 * we treat any release that either 1) doesn't define YYPATCH or
104 * 2) defines it to a value < 20170709 as being buggy.
105 */
106#if defined(YYBYACC) && (!defined(YYPATCH) || YYPATCH < 20170709)
107/*
108 * Both Berkeley YACC and Bison define yydebug (under whatever name
109 * it has) as a global, but Bison does so only if YYDEBUG is defined.
110 * Berkeley YACC, prior to the 2017-07-09 release, defines it even if
111 * YYDEBUG isn't defined; declare it here to suppress a warning.  The
112 * 2017-07-09 release fixes that.
113 */
114#if !defined(YYDEBUG)
115extern int yydebug;
116#endif
117
118/*
119 * In Berkeley YACC, prior to the 2017-07-09 release, yynerrs (under
120 * whatever name it has) is global, even if it's building a reentrant
121 * parser.  In Bison, and in the Berkeley YACC 2017-07-09 release and
122 * later, it's local in reentrant parsers.
123 *
124 * Declare it to squelch a warning.
125 */
126extern int yynerrs;
127#endif
128
129#define QSET(q, p, d, a) (q).proto = (unsigned char)(p),\
130			 (q).dir = (unsigned char)(d),\
131			 (q).addr = (unsigned char)(a)
132
133struct tok {
134	int v;			/* value */
135	const char *s;		/* string */
136};
137
138static const struct tok ieee80211_types[] = {
139	{ IEEE80211_FC0_TYPE_DATA, "data" },
140	{ IEEE80211_FC0_TYPE_MGT, "mgt" },
141	{ IEEE80211_FC0_TYPE_MGT, "management" },
142	{ IEEE80211_FC0_TYPE_CTL, "ctl" },
143	{ IEEE80211_FC0_TYPE_CTL, "control" },
144	{ 0, NULL }
145};
146static const struct tok ieee80211_mgt_subtypes[] = {
147	{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
148	{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
149	{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
150	{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
151	{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
152	{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
153	{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
154	{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
155	{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
156	{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
157	{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
158	{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
159	{ IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
160	{ IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
161	{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
162	{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
163	{ IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
164	{ IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
165	{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
166	{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
167	{ 0, NULL }
168};
169static const struct tok ieee80211_ctl_subtypes[] = {
170	{ IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
171	{ IEEE80211_FC0_SUBTYPE_RTS, "rts" },
172	{ IEEE80211_FC0_SUBTYPE_CTS, "cts" },
173	{ IEEE80211_FC0_SUBTYPE_ACK, "ack" },
174	{ IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
175	{ IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
176	{ 0, NULL }
177};
178static const struct tok ieee80211_data_subtypes[] = {
179	{ IEEE80211_FC0_SUBTYPE_DATA, "data" },
180	{ IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
181	{ IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
182	{ IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
183	{ IEEE80211_FC0_SUBTYPE_NODATA, "null" },
184	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
185	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll"  },
186	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
187	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
188	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
189	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
190	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
191	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
192	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
193	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
194	{ 0, NULL }
195};
196static const struct tok llc_s_subtypes[] = {
197	{ LLC_RR, "rr" },
198	{ LLC_RNR, "rnr" },
199	{ LLC_REJ, "rej" },
200	{ 0, NULL }
201};
202static const struct tok llc_u_subtypes[] = {
203	{ LLC_UI, "ui" },
204	{ LLC_UA, "ua" },
205	{ LLC_DISC, "disc" },
206	{ LLC_DM, "dm" },
207	{ LLC_SABME, "sabme" },
208	{ LLC_TEST, "test" },
209	{ LLC_XID, "xid" },
210	{ LLC_FRMR, "frmr" },
211	{ 0, NULL }
212};
213struct type2tok {
214	int type;
215	const struct tok *tok;
216};
217static const struct type2tok ieee80211_type_subtypes[] = {
218	{ IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
219	{ IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
220	{ IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
221	{ 0, NULL }
222};
223
224static int
225str2tok(const char *str, const struct tok *toks)
226{
227	int i;
228
229	for (i = 0; toks[i].s != NULL; i++) {
230		if (pcapint_strcasecmp(toks[i].s, str) == 0) {
231			/*
232			 * Just in case somebody is using this to
233			 * generate values of -1/0xFFFFFFFF.
234			 * That won't work, as it's indistinguishable
235			 * from an error.
236			 */
237			if (toks[i].v == -1)
238				abort();
239			return (toks[i].v);
240		}
241	}
242	return (-1);
243}
244
245static const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
246
247static void
248yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
249{
250	bpf_set_error(cstate, "can't parse filter expression: %s", msg);
251}
252
253static const struct tok pflog_reasons[] = {
254	{ PFRES_MATCH,		"match" },
255	{ PFRES_BADOFF,		"bad-offset" },
256	{ PFRES_FRAG,		"fragment" },
257	{ PFRES_SHORT,		"short" },
258	{ PFRES_NORM,		"normalize" },
259	{ PFRES_MEMORY,		"memory" },
260	{ PFRES_TS,		"bad-timestamp" },
261	{ PFRES_CONGEST,	"congestion" },
262	{ PFRES_IPOPTIONS,	"ip-option" },
263	{ PFRES_PROTCKSUM,	"proto-cksum" },
264	{ PFRES_BADSTATE,	"state-mismatch" },
265	{ PFRES_STATEINS,	"state-insert" },
266	{ PFRES_MAXSTATES,	"state-limit" },
267	{ PFRES_SRCLIMIT,	"src-limit" },
268	{ PFRES_SYNPROXY,	"synproxy" },
269#if defined(__FreeBSD__)
270	{ PFRES_MAPFAILED,	"map-failed" },
271#elif defined(__NetBSD__)
272	{ PFRES_STATELOCKED,	"state-locked" },
273#elif defined(__OpenBSD__)
274	{ PFRES_TRANSLATE,	"translate" },
275	{ PFRES_NOROUTE,	"no-route" },
276#elif defined(__APPLE__)
277	{ PFRES_DUMMYNET,	"dummynet" },
278#endif
279	{ 0, NULL }
280};
281
282static int
283pfreason_to_num(compiler_state_t *cstate, const char *reason)
284{
285	int i;
286
287	i = str2tok(reason, pflog_reasons);
288	if (i == -1)
289		bpf_set_error(cstate, "unknown PF reason \"%s\"", reason);
290	return (i);
291}
292
293static const struct tok pflog_actions[] = {
294	{ PF_PASS,		"pass" },
295	{ PF_PASS,		"accept" },	/* alias for "pass" */
296	{ PF_DROP,		"drop" },
297	{ PF_DROP,		"block" },	/* alias for "drop" */
298	{ PF_SCRUB,		"scrub" },
299	{ PF_NOSCRUB,		"noscrub" },
300	{ PF_NAT,		"nat" },
301	{ PF_NONAT,		"nonat" },
302	{ PF_BINAT,		"binat" },
303	{ PF_NOBINAT,		"nobinat" },
304	{ PF_RDR,		"rdr" },
305	{ PF_NORDR,		"nordr" },
306	{ PF_SYNPROXY_DROP,	"synproxy-drop" },
307#if defined(__FreeBSD__)
308	{ PF_DEFER,		"defer" },
309#elif defined(__OpenBSD__)
310	{ PF_DEFER,		"defer" },
311	{ PF_MATCH,		"match" },
312	{ PF_DIVERT,		"divert" },
313	{ PF_RT,		"rt" },
314	{ PF_AFRT,		"afrt" },
315#elif defined(__APPLE__)
316	{ PF_DUMMYNET,		"dummynet" },
317	{ PF_NODUMMYNET,	"nodummynet" },
318	{ PF_NAT64,		"nat64" },
319	{ PF_NONAT64,		"nonat64" },
320#endif
321	{ 0, NULL },
322};
323
324static int
325pfaction_to_num(compiler_state_t *cstate, const char *action)
326{
327	int i;
328
329	i = str2tok(action, pflog_actions);
330	if (i == -1)
331		bpf_set_error(cstate, "unknown PF action \"%s\"", action);
332	return (i);
333}
334
335/*
336 * For calls that might return an "an error occurred" value.
337 */
338#define CHECK_INT_VAL(val)	if (val == -1) YYABORT
339#define CHECK_PTR_VAL(val)	if (val == NULL) YYABORT
340
341DIAG_OFF_BISON_BYACC
342%}
343
344%union {
345	int i;
346	bpf_u_int32 h;
347	char *s;
348	struct stmt *stmt;
349	struct arth *a;
350	struct {
351		struct qual q;
352		int atmfieldtype;
353		int mtp3fieldtype;
354		struct block *b;
355	} blk;
356	struct block *rblk;
357}
358
359%type	<blk>	expr id nid pid term rterm qid
360%type	<blk>	head
361%type	<i>	pqual dqual aqual ndaqual
362%type	<a>	arth narth
363%type	<i>	byteop pname relop irelop
364%type	<h>	pnum
365%type	<blk>	and or paren not null prog
366%type	<rblk>	other pfvar p80211 pllc
367%type	<i>	atmtype atmmultitype
368%type	<blk>	atmfield
369%type	<blk>	atmfieldvalue atmvalue atmlistvalue
370%type	<i>	mtp2type
371%type	<blk>	mtp3field
372%type	<blk>	mtp3fieldvalue mtp3value mtp3listvalue
373
374
375%token  DST SRC HOST GATEWAY
376%token  NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
377%token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
378%token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
379%token  TK_BROADCAST TK_MULTICAST
380%token  NUM INBOUND OUTBOUND
381%token  IFINDEX
382%token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
383%token	TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
384%token  LINK
385%token	GEQ LEQ NEQ
386%token	ID EID HID HID6 AID
387%token	LSH RSH
388%token  LEN
389%token  IPV6 ICMPV6 AH ESP
390%token	VLAN MPLS
391%token	PPPOED PPPOES GENEVE
392%token  ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
393%token  STP
394%token  IPX
395%token  NETBEUI
396%token	LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
397%token	OAM OAMF4 CONNECTMSG METACONNECT
398%token	VPI VCI
399%token	RADIO
400%token	FISU LSSU MSU HFISU HLSSU HMSU
401%token	SIO OPC DPC SLS HSIO HOPC HDPC HSLS
402%token	LEX_ERROR
403
404%type	<s> ID EID AID
405%type	<s> HID HID6
406%type	<h> NUM
407%type	<i> action reason type subtype type_subtype dir
408
409%left OR AND
410%nonassoc  '!'
411%left '|'
412%left '&'
413%left LSH RSH
414%left '+' '-'
415%left '*' '/'
416%nonassoc UMINUS
417%%
418prog:	  null expr
419{
420	/*
421	 * I'm not sure we have a reason to use yynerrs, but it's
422	 * declared, and incremented, whether we need it or not,
423	 * which means that Clang 15 will give a "used but not
424	 * set" warning.  This should suppress the warning for
425	 * yynerrs without suppressing it for other variables.
426	 */
427	(void) yynerrs;
428	CHECK_INT_VAL(finish_parse(cstate, $2.b));
429}
430	| null
431	;
432null:	  /* null */		{ $$.q = qerr; }
433	;
434expr:	  term
435	| expr and term		{ gen_and($1.b, $3.b); $$ = $3; }
436	| expr and id		{ gen_and($1.b, $3.b); $$ = $3; }
437	| expr or term		{ gen_or($1.b, $3.b); $$ = $3; }
438	| expr or id		{ gen_or($1.b, $3.b); $$ = $3; }
439	;
440and:	  AND			{ $$ = $<blk>0; }
441	;
442or:	  OR			{ $$ = $<blk>0; }
443	;
444id:	  nid
445	| pnum			{ CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1,
446						   $$.q = $<blk>0.q))); }
447	| paren pid ')'		{ $$ = $2; }
448	;
449nid:	  ID			{ CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q))); }
450	| HID '/' NUM		{
451				  CHECK_PTR_VAL($1);
452				  /* Check whether HID/NUM is being used when appropriate */
453				  $$.q = $<blk>0.q;
454				  if ($$.q.addr == Q_PORT) {
455					bpf_set_error(cstate, "'port' modifier applied to IP address and prefix length");
456					YYABORT;
457				  } else if ($$.q.addr == Q_PORTRANGE) {
458					bpf_set_error(cstate, "'portrange' modifier applied to IP address and prefix length");
459					YYABORT;
460				  } else if ($$.q.addr == Q_PROTO) {
461					bpf_set_error(cstate, "'proto' modifier applied to IP address and prefix length");
462					YYABORT;
463				  } else if ($$.q.addr == Q_PROTOCHAIN) {
464					bpf_set_error(cstate, "'protochain' modifier applied to IP address and prefix length");
465					YYABORT;
466				  }
467				  CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3, $$.q)));
468				}
469	| HID NETMASK HID	{
470				  CHECK_PTR_VAL($1);
471				  /* Check whether HID mask HID is being used when appropriate */
472				  $$.q = $<blk>0.q;
473				  if ($$.q.addr == Q_PORT) {
474					bpf_set_error(cstate, "'port' modifier applied to IP address and netmask");
475					YYABORT;
476				  } else if ($$.q.addr == Q_PORTRANGE) {
477					bpf_set_error(cstate, "'portrange' modifier applied to IP address and netmask");
478					YYABORT;
479				  } else if ($$.q.addr == Q_PROTO) {
480					bpf_set_error(cstate, "'proto' modifier applied to IP address and netmask");
481					YYABORT;
482				  } else if ($$.q.addr == Q_PROTOCHAIN) {
483					bpf_set_error(cstate, "'protochain' modifier applied to IP address and netmask");
484					YYABORT;
485				  }
486				  CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0, $$.q)));
487				}
488	| HID			{
489				  CHECK_PTR_VAL($1);
490				  /* Check whether HID is being used when appropriate */
491				  $$.q = $<blk>0.q;
492				  if ($$.q.addr == Q_PORT) {
493					bpf_set_error(cstate, "'port' modifier applied to IP address");
494					YYABORT;
495				  } else if ($$.q.addr == Q_PORTRANGE) {
496					bpf_set_error(cstate, "'portrange' modifier applied to IP address");
497					YYABORT;
498				  } else if ($$.q.addr == Q_PROTO) {
499					bpf_set_error(cstate, "'proto' modifier applied to IP address");
500					YYABORT;
501				  } else if ($$.q.addr == Q_PROTOCHAIN) {
502					bpf_set_error(cstate, "'protochain' modifier applied to IP address");
503					YYABORT;
504				  }
505				  CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q)));
506				}
507	| HID6 '/' NUM		{
508				  CHECK_PTR_VAL($1);
509#ifdef INET6
510				  /* Check whether HID6/NUM is being used when appropriate */
511				  $$.q = $<blk>0.q;
512				  if ($$.q.addr == Q_PORT) {
513					bpf_set_error(cstate, "'port' modifier applied to IP address and prefix length");
514					YYABORT;
515				  } else if ($$.q.addr == Q_PORTRANGE) {
516					bpf_set_error(cstate, "'portrange' modifier applied to IP address and prefix length");
517					YYABORT;
518				  } else if ($$.q.addr == Q_PROTO) {
519					bpf_set_error(cstate, "'proto' modifier applied to IP address and prefix length ");
520					YYABORT;
521				  } else if ($$.q.addr == Q_PROTOCHAIN) {
522					bpf_set_error(cstate, "'protochain' modifier applied to IP address and prefix length");
523					YYABORT;
524				  }
525				  CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, $3, $$.q)));
526#else
527				  bpf_set_error(cstate, "IPv6 addresses not supported "
528					"in this configuration");
529				  YYABORT;
530#endif /*INET6*/
531				}
532	| HID6			{
533				  CHECK_PTR_VAL($1);
534#ifdef INET6
535				  /* Check whether HID6 is being used when appropriate */
536				  $$.q = $<blk>0.q;
537				  if ($$.q.addr == Q_PORT) {
538					bpf_set_error(cstate, "'port' modifier applied to IP address");
539					YYABORT;
540				  } else if ($$.q.addr == Q_PORTRANGE) {
541					bpf_set_error(cstate, "'portrange' modifier applied to IP address");
542					YYABORT;
543				  } else if ($$.q.addr == Q_PROTO) {
544					bpf_set_error(cstate, "'proto' modifier applied to 'ip6addr/prefixlen");
545					YYABORT;
546				  } else if ($$.q.addr == Q_PROTOCHAIN) {
547					bpf_set_error(cstate, "'protochain' modifier applied to IP address");
548					YYABORT;
549				  }
550				  CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 128, $$.q)));
551#else
552				  bpf_set_error(cstate, "IPv6 addresses not supported "
553					"in this configuration");
554				  YYABORT;
555#endif /*INET6*/
556				}
557	| EID			{ CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q))); }
558	| AID			{ CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q))); }
559	| not id		{ gen_not($2.b); $$ = $2; }
560	;
561not:	  '!'			{ $$ = $<blk>0; }
562	;
563paren:	  '('			{ $$ = $<blk>0; }
564	;
565pid:	  nid
566	| qid and id		{ gen_and($1.b, $3.b); $$ = $3; }
567	| qid or id		{ gen_or($1.b, $3.b); $$ = $3; }
568	;
569qid:	  pnum			{ CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1,
570						   $$.q = $<blk>0.q))); }
571	| pid
572	;
573term:	  rterm
574	| not term		{ gen_not($2.b); $$ = $2; }
575	;
576head:	  pqual dqual aqual	{ QSET($$.q, $1, $2, $3); }
577	| pqual dqual		{ QSET($$.q, $1, $2, Q_DEFAULT); }
578	| pqual aqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
579	| pqual PROTO		{ QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
580	| pqual PROTOCHAIN	{
581#ifdef NO_PROTOCHAIN
582				  bpf_set_error(cstate, "protochain not supported");
583				  YYABORT;
584#else
585				  QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN);
586#endif
587				}
588	| pqual ndaqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
589	;
590rterm:	  head id		{ $$ = $2; }
591	| paren expr ')'	{ $$.b = $2.b; $$.q = $1.q; }
592	| pname			{ CHECK_PTR_VAL(($$.b = gen_proto_abbrev(cstate, $1))); $$.q = qerr; }
593	| arth relop arth	{ CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 0)));
594				  $$.q = qerr; }
595	| arth irelop arth	{ CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 1)));
596				  $$.q = qerr; }
597	| other			{ $$.b = $1; $$.q = qerr; }
598	| atmtype		{ CHECK_PTR_VAL(($$.b = gen_atmtype_abbrev(cstate, $1))); $$.q = qerr; }
599	| atmmultitype		{ CHECK_PTR_VAL(($$.b = gen_atmmulti_abbrev(cstate, $1))); $$.q = qerr; }
600	| atmfield atmvalue	{ $$.b = $2.b; $$.q = qerr; }
601	| mtp2type		{ CHECK_PTR_VAL(($$.b = gen_mtp2type_abbrev(cstate, $1))); $$.q = qerr; }
602	| mtp3field mtp3value	{ $$.b = $2.b; $$.q = qerr; }
603	;
604/* protocol level qualifiers */
605pqual:	  pname
606	|			{ $$ = Q_DEFAULT; }
607	;
608/* 'direction' qualifiers */
609dqual:	  SRC			{ $$ = Q_SRC; }
610	| DST			{ $$ = Q_DST; }
611	| SRC OR DST		{ $$ = Q_OR; }
612	| DST OR SRC		{ $$ = Q_OR; }
613	| SRC AND DST		{ $$ = Q_AND; }
614	| DST AND SRC		{ $$ = Q_AND; }
615	| ADDR1			{ $$ = Q_ADDR1; }
616	| ADDR2			{ $$ = Q_ADDR2; }
617	| ADDR3			{ $$ = Q_ADDR3; }
618	| ADDR4			{ $$ = Q_ADDR4; }
619	| RA			{ $$ = Q_RA; }
620	| TA			{ $$ = Q_TA; }
621	;
622/* address type qualifiers */
623aqual:	  HOST			{ $$ = Q_HOST; }
624	| NET			{ $$ = Q_NET; }
625	| PORT			{ $$ = Q_PORT; }
626	| PORTRANGE		{ $$ = Q_PORTRANGE; }
627	;
628/* non-directional address type qualifiers */
629ndaqual:  GATEWAY		{ $$ = Q_GATEWAY; }
630	;
631pname:	  LINK			{ $$ = Q_LINK; }
632	| IP			{ $$ = Q_IP; }
633	| ARP			{ $$ = Q_ARP; }
634	| RARP			{ $$ = Q_RARP; }
635	| SCTP			{ $$ = Q_SCTP; }
636	| TCP			{ $$ = Q_TCP; }
637	| UDP			{ $$ = Q_UDP; }
638	| ICMP			{ $$ = Q_ICMP; }
639	| IGMP			{ $$ = Q_IGMP; }
640	| IGRP			{ $$ = Q_IGRP; }
641	| PIM			{ $$ = Q_PIM; }
642	| VRRP			{ $$ = Q_VRRP; }
643	| CARP			{ $$ = Q_CARP; }
644	| ATALK			{ $$ = Q_ATALK; }
645	| AARP			{ $$ = Q_AARP; }
646	| DECNET		{ $$ = Q_DECNET; }
647	| LAT			{ $$ = Q_LAT; }
648	| SCA			{ $$ = Q_SCA; }
649	| MOPDL			{ $$ = Q_MOPDL; }
650	| MOPRC			{ $$ = Q_MOPRC; }
651	| IPV6			{ $$ = Q_IPV6; }
652	| ICMPV6		{ $$ = Q_ICMPV6; }
653	| AH			{ $$ = Q_AH; }
654	| ESP			{ $$ = Q_ESP; }
655	| ISO			{ $$ = Q_ISO; }
656	| ESIS			{ $$ = Q_ESIS; }
657	| ISIS			{ $$ = Q_ISIS; }
658	| L1			{ $$ = Q_ISIS_L1; }
659	| L2			{ $$ = Q_ISIS_L2; }
660	| IIH			{ $$ = Q_ISIS_IIH; }
661	| LSP			{ $$ = Q_ISIS_LSP; }
662	| SNP			{ $$ = Q_ISIS_SNP; }
663	| PSNP			{ $$ = Q_ISIS_PSNP; }
664	| CSNP			{ $$ = Q_ISIS_CSNP; }
665	| CLNP			{ $$ = Q_CLNP; }
666	| STP			{ $$ = Q_STP; }
667	| IPX			{ $$ = Q_IPX; }
668	| NETBEUI		{ $$ = Q_NETBEUI; }
669	| RADIO			{ $$ = Q_RADIO; }
670	;
671other:	  pqual TK_BROADCAST	{ CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
672	| pqual TK_MULTICAST	{ CHECK_PTR_VAL(($$ = gen_multicast(cstate, $1))); }
673	| LESS NUM		{ CHECK_PTR_VAL(($$ = gen_less(cstate, $2))); }
674	| GREATER NUM		{ CHECK_PTR_VAL(($$ = gen_greater(cstate, $2))); }
675	| CBYTE NUM byteop NUM	{ CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); }
676	| INBOUND		{ CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); }
677	| OUTBOUND		{ CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); }
678	| IFINDEX NUM		{ CHECK_PTR_VAL(($$ = gen_ifindex(cstate, $2))); }
679	| VLAN pnum		{ CHECK_PTR_VAL(($$ = gen_vlan(cstate, $2, 1))); }
680	| VLAN			{ CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
681	| MPLS pnum		{ CHECK_PTR_VAL(($$ = gen_mpls(cstate, $2, 1))); }
682	| MPLS			{ CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); }
683	| PPPOED		{ CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); }
684	| PPPOES pnum		{ CHECK_PTR_VAL(($$ = gen_pppoes(cstate, $2, 1))); }
685	| PPPOES		{ CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }
686	| GENEVE pnum		{ CHECK_PTR_VAL(($$ = gen_geneve(cstate, $2, 1))); }
687	| GENEVE		{ CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
688	| pfvar			{ $$ = $1; }
689	| pqual p80211		{ $$ = $2; }
690	| pllc			{ $$ = $1; }
691	;
692
693pfvar:	  PF_IFNAME ID		{ CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ifname(cstate, $2))); }
694	| PF_RSET ID		{ CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ruleset(cstate, $2))); }
695	| PF_RNR NUM		{ CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); }
696	| PF_SRNR NUM		{ CHECK_PTR_VAL(($$ = gen_pf_srnr(cstate, $2))); }
697	| PF_REASON reason	{ CHECK_PTR_VAL(($$ = gen_pf_reason(cstate, $2))); }
698	| PF_ACTION action	{ CHECK_PTR_VAL(($$ = gen_pf_action(cstate, $2))); }
699	;
700
701p80211:   TYPE type SUBTYPE subtype
702				{ CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2 | $4,
703					IEEE80211_FC0_TYPE_MASK |
704					IEEE80211_FC0_SUBTYPE_MASK)));
705				}
706	| TYPE type		{ CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
707					IEEE80211_FC0_TYPE_MASK)));
708				}
709	| SUBTYPE type_subtype	{ CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
710					IEEE80211_FC0_TYPE_MASK |
711					IEEE80211_FC0_SUBTYPE_MASK)));
712				}
713	| DIR dir		{ CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); }
714	;
715
716type:	  NUM			{ if (($1 & (~IEEE80211_FC0_TYPE_MASK)) != 0) {
717					bpf_set_error(cstate, "invalid 802.11 type value 0x%02x", $1);
718					YYABORT;
719				  }
720				  $$ = (int)$1;
721				}
722	| ID			{ CHECK_PTR_VAL($1);
723				  $$ = str2tok($1, ieee80211_types);
724				  if ($$ == -1) {
725					bpf_set_error(cstate, "unknown 802.11 type name \"%s\"", $1);
726					YYABORT;
727				  }
728				}
729	;
730
731subtype:  NUM			{ if (($1 & (~IEEE80211_FC0_SUBTYPE_MASK)) != 0) {
732					bpf_set_error(cstate, "invalid 802.11 subtype value 0x%02x", $1);
733					YYABORT;
734				  }
735				  $$ = (int)$1;
736				}
737	| ID			{ const struct tok *types = NULL;
738				  int i;
739				  CHECK_PTR_VAL($1);
740				  for (i = 0;; i++) {
741					if (ieee80211_type_subtypes[i].tok == NULL) {
742						/* Ran out of types */
743						bpf_set_error(cstate, "unknown 802.11 type");
744						YYABORT;
745					}
746					if ($<i>-1 == ieee80211_type_subtypes[i].type) {
747						types = ieee80211_type_subtypes[i].tok;
748						break;
749					}
750				  }
751
752				  $$ = str2tok($1, types);
753				  if ($$ == -1) {
754					bpf_set_error(cstate, "unknown 802.11 subtype name \"%s\"", $1);
755					YYABORT;
756				  }
757				}
758	;
759
760type_subtype:	ID		{ int i;
761				  CHECK_PTR_VAL($1);
762				  for (i = 0;; i++) {
763					if (ieee80211_type_subtypes[i].tok == NULL) {
764						/* Ran out of types */
765						bpf_set_error(cstate, "unknown 802.11 type name");
766						YYABORT;
767					}
768					$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
769					if ($$ != -1) {
770						$$ |= ieee80211_type_subtypes[i].type;
771						break;
772					}
773				  }
774				}
775		;
776
777pllc:	LLC			{ CHECK_PTR_VAL(($$ = gen_llc(cstate))); }
778	| LLC ID		{ CHECK_PTR_VAL($2);
779				  if (pcapint_strcasecmp($2, "i") == 0) {
780					CHECK_PTR_VAL(($$ = gen_llc_i(cstate)));
781				  } else if (pcapint_strcasecmp($2, "s") == 0) {
782					CHECK_PTR_VAL(($$ = gen_llc_s(cstate)));
783				  } else if (pcapint_strcasecmp($2, "u") == 0) {
784					CHECK_PTR_VAL(($$ = gen_llc_u(cstate)));
785				  } else {
786					int subtype;
787
788					subtype = str2tok($2, llc_s_subtypes);
789					if (subtype != -1) {
790						CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, subtype)));
791					} else {
792						subtype = str2tok($2, llc_u_subtypes);
793						if (subtype == -1) {
794							bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2);
795							YYABORT;
796						}
797						CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype)));
798					}
799				  }
800				}
801				/* sigh, "rnr" is already a keyword for PF */
802	| LLC PF_RNR		{ CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); }
803	;
804
805dir:	  NUM			{ $$ = (int)$1; }
806	| ID			{ CHECK_PTR_VAL($1);
807				  if (pcapint_strcasecmp($1, "nods") == 0)
808					$$ = IEEE80211_FC1_DIR_NODS;
809				  else if (pcapint_strcasecmp($1, "tods") == 0)
810					$$ = IEEE80211_FC1_DIR_TODS;
811				  else if (pcapint_strcasecmp($1, "fromds") == 0)
812					$$ = IEEE80211_FC1_DIR_FROMDS;
813				  else if (pcapint_strcasecmp($1, "dstods") == 0)
814					$$ = IEEE80211_FC1_DIR_DSTODS;
815				  else {
816					bpf_set_error(cstate, "unknown 802.11 direction");
817					YYABORT;
818				  }
819				}
820	;
821
822reason:	  NUM			{ $$ = $1; }
823	| ID			{ CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfreason_to_num(cstate, $1))); }
824	;
825
826action:	  ID			{ CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfaction_to_num(cstate, $1))); }
827	;
828
829relop:	  '>'			{ $$ = BPF_JGT; }
830	| GEQ			{ $$ = BPF_JGE; }
831	| '='			{ $$ = BPF_JEQ; }
832	;
833irelop:	  LEQ			{ $$ = BPF_JGT; }
834	| '<'			{ $$ = BPF_JGE; }
835	| NEQ			{ $$ = BPF_JEQ; }
836	;
837arth:	  pnum			{ CHECK_PTR_VAL(($$ = gen_loadi(cstate, $1))); }
838	| narth
839	;
840narth:	  pname '[' arth ']'		{ CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, 1))); }
841	| pname '[' arth ':' NUM ']'	{ CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, $5))); }
842	| arth '+' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_ADD, $1, $3))); }
843	| arth '-' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_SUB, $1, $3))); }
844	| arth '*' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MUL, $1, $3))); }
845	| arth '/' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_DIV, $1, $3))); }
846	| arth '%' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MOD, $1, $3))); }
847	| arth '&' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_AND, $1, $3))); }
848	| arth '|' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_OR, $1, $3))); }
849	| arth '^' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_XOR, $1, $3))); }
850	| arth LSH arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_LSH, $1, $3))); }
851	| arth RSH arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_RSH, $1, $3))); }
852	| '-' arth %prec UMINUS		{ CHECK_PTR_VAL(($$ = gen_neg(cstate, $2))); }
853	| paren narth ')'		{ $$ = $2; }
854	| LEN				{ CHECK_PTR_VAL(($$ = gen_loadlen(cstate))); }
855	;
856byteop:	  '&'			{ $$ = '&'; }
857	| '|'			{ $$ = '|'; }
858	| '<'			{ $$ = '<'; }
859	| '>'			{ $$ = '>'; }
860	| '='			{ $$ = '='; }
861	;
862pnum:	  NUM
863	| paren pnum ')'	{ $$ = $2; }
864	;
865atmtype: LANE			{ $$ = A_LANE; }
866	| METAC			{ $$ = A_METAC;	}
867	| BCC			{ $$ = A_BCC; }
868	| OAMF4EC		{ $$ = A_OAMF4EC; }
869	| OAMF4SC		{ $$ = A_OAMF4SC; }
870	| SC			{ $$ = A_SC; }
871	| ILMIC			{ $$ = A_ILMIC; }
872	;
873atmmultitype: OAM		{ $$ = A_OAM; }
874	| OAMF4			{ $$ = A_OAMF4; }
875	| CONNECTMSG		{ $$ = A_CONNECTMSG; }
876	| METACONNECT		{ $$ = A_METACONNECT; }
877	;
878	/* ATM field types quantifier */
879atmfield: VPI			{ $$.atmfieldtype = A_VPI; }
880	| VCI			{ $$.atmfieldtype = A_VCI; }
881	;
882atmvalue: atmfieldvalue
883	| relop NUM		{ CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, $2, $1, 0))); }
884	| irelop NUM		{ CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, $2, $1, 1))); }
885	| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
886	;
887atmfieldvalue: NUM {
888	$$.atmfieldtype = $<blk>0.atmfieldtype;
889	if ($$.atmfieldtype == A_VPI ||
890	    $$.atmfieldtype == A_VCI)
891		CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, $1, BPF_JEQ, 0)));
892	}
893	;
894atmlistvalue: atmfieldvalue
895	| atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
896	;
897	/* MTP2 types quantifier */
898mtp2type: FISU			{ $$ = M_FISU; }
899	| LSSU			{ $$ = M_LSSU; }
900	| MSU			{ $$ = M_MSU; }
901	| HFISU			{ $$ = MH_FISU; }
902	| HLSSU			{ $$ = MH_LSSU; }
903	| HMSU			{ $$ = MH_MSU; }
904	;
905	/* MTP3 field types quantifier */
906mtp3field: SIO			{ $$.mtp3fieldtype = M_SIO; }
907	| OPC			{ $$.mtp3fieldtype = M_OPC; }
908	| DPC			{ $$.mtp3fieldtype = M_DPC; }
909	| SLS                   { $$.mtp3fieldtype = M_SLS; }
910	| HSIO			{ $$.mtp3fieldtype = MH_SIO; }
911	| HOPC			{ $$.mtp3fieldtype = MH_OPC; }
912	| HDPC			{ $$.mtp3fieldtype = MH_DPC; }
913	| HSLS                  { $$.mtp3fieldtype = MH_SLS; }
914	;
915mtp3value: mtp3fieldvalue
916	| relop NUM		{ CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, $2, $1, 0))); }
917	| irelop NUM		{ CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, $2, $1, 1))); }
918	| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
919	;
920mtp3fieldvalue: NUM {
921	$$.mtp3fieldtype = $<blk>0.mtp3fieldtype;
922	if ($$.mtp3fieldtype == M_SIO ||
923	    $$.mtp3fieldtype == M_OPC ||
924	    $$.mtp3fieldtype == M_DPC ||
925	    $$.mtp3fieldtype == M_SLS ||
926	    $$.mtp3fieldtype == MH_SIO ||
927	    $$.mtp3fieldtype == MH_OPC ||
928	    $$.mtp3fieldtype == MH_DPC ||
929	    $$.mtp3fieldtype == MH_SLS)
930		CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, $1, BPF_JEQ, 0)));
931	}
932	;
933mtp3listvalue: mtp3fieldvalue
934	| mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
935	;
936%%
937