xref: /freebsd/contrib/libpcap/grammar.y.in (revision afdbf109c6a661a729938f68211054a0a50d38ac)
16f9cba8fSJoseph Mingrone/*
26f9cba8fSJoseph Mingrone * We want a reentrant parser.
36f9cba8fSJoseph Mingrone */
46f9cba8fSJoseph Mingrone@REENTRANT_PARSER@
56f9cba8fSJoseph Mingrone
66f9cba8fSJoseph Mingrone/*
76f9cba8fSJoseph Mingrone * We also want a reentrant scanner, so we have to pass the
86f9cba8fSJoseph Mingrone * handle for the reentrant scanner to the parser, and the
96f9cba8fSJoseph Mingrone * parser has to pass it to the lexical analyzer.
106f9cba8fSJoseph Mingrone *
116f9cba8fSJoseph Mingrone * We use void * rather than yyscan_t because, at least with some
126f9cba8fSJoseph Mingrone * versions of Flex and Bison, if you use yyscan_t in %parse-param and
136f9cba8fSJoseph Mingrone * %lex-param, you have to include scanner.h before grammar.h to get
146f9cba8fSJoseph Mingrone * yyscan_t declared, and you have to include grammar.h before scanner.h
156f9cba8fSJoseph Mingrone * to get YYSTYPE declared.  Using void * breaks the cycle; the Flex
166f9cba8fSJoseph Mingrone * documentation says yyscan_t is just a void *.
176f9cba8fSJoseph Mingrone */
186f9cba8fSJoseph Mingrone%parse-param   {void *yyscanner}
196f9cba8fSJoseph Mingrone%lex-param   {void *yyscanner}
206f9cba8fSJoseph Mingrone
216f9cba8fSJoseph Mingrone/*
226f9cba8fSJoseph Mingrone * According to bison documentation, shift/reduce conflicts are not an issue
236f9cba8fSJoseph Mingrone * in most parsers as long as the number does not evolve over time:
246f9cba8fSJoseph Mingrone * https://www.gnu.org/software/bison/manual/html_node/Expect-Decl.html
256f9cba8fSJoseph Mingrone * So, following the advice use %expect to check the amount of shift/reduce
266f9cba8fSJoseph Mingrone * warnings.
276f9cba8fSJoseph Mingrone *
286f9cba8fSJoseph Mingrone * This doesn't appear to work in Berkeley YACC - 1.9 20170709; it still
296f9cba8fSJoseph Mingrone * warns of 38 shift/reduce conflicts.
306f9cba8fSJoseph Mingrone *
316f9cba8fSJoseph Mingrone * The Berkeley YACC documentation:
326f9cba8fSJoseph Mingrone *
336f9cba8fSJoseph Mingrone *    https://invisible-island.net/byacc/manpage/yacc.html
346f9cba8fSJoseph Mingrone *
356f9cba8fSJoseph Mingrone * claims that "Bison's support for "%expect" is broken in more than one
366f9cba8fSJoseph Mingrone * release.", but doesn't give details.  Hopefully, that only means that
376f9cba8fSJoseph Mingrone * you get warnings even if you have the expected number of shift/reduce
386f9cba8fSJoseph Mingrone * conflicts, not that anything else fails.
396f9cba8fSJoseph Mingrone */
406f9cba8fSJoseph Mingrone%expect 38
416f9cba8fSJoseph Mingrone
426f9cba8fSJoseph Mingrone/*
436f9cba8fSJoseph Mingrone * And we need to pass the compiler state to the scanner.
446f9cba8fSJoseph Mingrone */
456f9cba8fSJoseph Mingrone%parse-param { compiler_state_t *cstate }
466f9cba8fSJoseph Mingrone
476f9cba8fSJoseph Mingrone%{
486f9cba8fSJoseph Mingrone/*
496f9cba8fSJoseph Mingrone * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
506f9cba8fSJoseph Mingrone *	The Regents of the University of California.  All rights reserved.
516f9cba8fSJoseph Mingrone *
526f9cba8fSJoseph Mingrone * Redistribution and use in source and binary forms, with or without
536f9cba8fSJoseph Mingrone * modification, are permitted provided that: (1) source code distributions
546f9cba8fSJoseph Mingrone * retain the above copyright notice and this paragraph in its entirety, (2)
556f9cba8fSJoseph Mingrone * distributions including binary code include the above copyright notice and
566f9cba8fSJoseph Mingrone * this paragraph in its entirety in the documentation or other materials
576f9cba8fSJoseph Mingrone * provided with the distribution, and (3) all advertising materials mentioning
586f9cba8fSJoseph Mingrone * features or use of this software display the following acknowledgement:
596f9cba8fSJoseph Mingrone * ``This product includes software developed by the University of California,
606f9cba8fSJoseph Mingrone * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
616f9cba8fSJoseph Mingrone * the University nor the names of its contributors may be used to endorse
626f9cba8fSJoseph Mingrone * or promote products derived from this software without specific prior
636f9cba8fSJoseph Mingrone * written permission.
646f9cba8fSJoseph Mingrone * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
656f9cba8fSJoseph Mingrone * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
666f9cba8fSJoseph Mingrone * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
676f9cba8fSJoseph Mingrone *
686f9cba8fSJoseph Mingrone */
696f9cba8fSJoseph Mingrone
706f9cba8fSJoseph Mingrone#include <config.h>
716f9cba8fSJoseph Mingrone
726f9cba8fSJoseph Mingrone/*
736f9cba8fSJoseph Mingrone * grammar.h requires gencode.h and sometimes breaks in a polluted namespace
746f9cba8fSJoseph Mingrone * (see ftmacros.h), so include it early.
756f9cba8fSJoseph Mingrone */
766f9cba8fSJoseph Mingrone#include "gencode.h"
776f9cba8fSJoseph Mingrone#include "grammar.h"
786f9cba8fSJoseph Mingrone
796f9cba8fSJoseph Mingrone#include <stdlib.h>
806f9cba8fSJoseph Mingrone
816f9cba8fSJoseph Mingrone#ifndef _WIN32
826f9cba8fSJoseph Mingrone#include <sys/types.h>
836f9cba8fSJoseph Mingrone#include <sys/socket.h>
846f9cba8fSJoseph Mingrone
856f9cba8fSJoseph Mingrone#if __STDC__
866f9cba8fSJoseph Mingronestruct mbuf;
876f9cba8fSJoseph Mingronestruct rtentry;
886f9cba8fSJoseph Mingrone#endif
896f9cba8fSJoseph Mingrone
906f9cba8fSJoseph Mingrone#include <netinet/in.h>
916f9cba8fSJoseph Mingrone#include <arpa/inet.h>
926f9cba8fSJoseph Mingrone#endif /* _WIN32 */
936f9cba8fSJoseph Mingrone
946f9cba8fSJoseph Mingrone#include <stdio.h>
956f9cba8fSJoseph Mingrone
966f9cba8fSJoseph Mingrone#include "diag-control.h"
976f9cba8fSJoseph Mingrone
986f9cba8fSJoseph Mingrone#include "pcap-int.h"
996f9cba8fSJoseph Mingrone
1006f9cba8fSJoseph Mingrone#include "scanner.h"
1016f9cba8fSJoseph Mingrone
1026f9cba8fSJoseph Mingrone#include "llc.h"
1036f9cba8fSJoseph Mingrone#include "ieee80211.h"
1046f9cba8fSJoseph Mingrone#include "pflog.h"
1056f9cba8fSJoseph Mingrone#include <pcap/namedb.h>
1066f9cba8fSJoseph Mingrone
1076f9cba8fSJoseph Mingrone#ifdef HAVE_OS_PROTO_H
1086f9cba8fSJoseph Mingrone#include "os-proto.h"
1096f9cba8fSJoseph Mingrone#endif
1106f9cba8fSJoseph Mingrone
111*afdbf109SJoseph Mingrone/*
112*afdbf109SJoseph Mingrone * Work around some bugs in Berkeley YACC prior to the 2017-07-09
113*afdbf109SJoseph Mingrone * release.
114*afdbf109SJoseph Mingrone *
115*afdbf109SJoseph Mingrone * The 2005-05-05 release was the first one to define YYPATCH, so
116*afdbf109SJoseph Mingrone * we treat any release that either 1) doesn't define YYPATCH or
117*afdbf109SJoseph Mingrone * 2) defines it to a value < 20170709 as being buggy.
118*afdbf109SJoseph Mingrone */
119*afdbf109SJoseph Mingrone#if defined(YYBYACC) && (!defined(YYPATCH) || YYPATCH < 20170709)
1206f9cba8fSJoseph Mingrone/*
1216f9cba8fSJoseph Mingrone * Both Berkeley YACC and Bison define yydebug (under whatever name
1226f9cba8fSJoseph Mingrone * it has) as a global, but Bison does so only if YYDEBUG is defined.
123*afdbf109SJoseph Mingrone * Berkeley YACC, prior to the 2017-07-09 release, defines it even if
124*afdbf109SJoseph Mingrone * YYDEBUG isn't defined; declare it here to suppress a warning.  The
125*afdbf109SJoseph Mingrone * 2017-07-09 release fixes that.
1266f9cba8fSJoseph Mingrone */
1276f9cba8fSJoseph Mingrone#if !defined(YYDEBUG)
1286f9cba8fSJoseph Mingroneextern int yydebug;
1296f9cba8fSJoseph Mingrone#endif
1306f9cba8fSJoseph Mingrone
1316f9cba8fSJoseph Mingrone/*
132*afdbf109SJoseph Mingrone * In Berkeley YACC, prior to the 2017-07-09 release, yynerrs (under
133*afdbf109SJoseph Mingrone * whatever name it has) is global, even if it's building a reentrant
134*afdbf109SJoseph Mingrone * parser.  In Bison, and in the Berkeley YACC 2017-07-09 release and
135*afdbf109SJoseph Mingrone * later, it's local in reentrant parsers.
1366f9cba8fSJoseph Mingrone *
1376f9cba8fSJoseph Mingrone * Declare it to squelch a warning.
1386f9cba8fSJoseph Mingrone */
1396f9cba8fSJoseph Mingroneextern int yynerrs;
1406f9cba8fSJoseph Mingrone#endif
1416f9cba8fSJoseph Mingrone
1426f9cba8fSJoseph Mingrone#define QSET(q, p, d, a) (q).proto = (unsigned char)(p),\
1436f9cba8fSJoseph Mingrone			 (q).dir = (unsigned char)(d),\
1446f9cba8fSJoseph Mingrone			 (q).addr = (unsigned char)(a)
1456f9cba8fSJoseph Mingrone
1466f9cba8fSJoseph Mingronestruct tok {
1476f9cba8fSJoseph Mingrone	int v;			/* value */
1486f9cba8fSJoseph Mingrone	const char *s;		/* string */
1496f9cba8fSJoseph Mingrone};
1506f9cba8fSJoseph Mingrone
1516f9cba8fSJoseph Mingronestatic const struct tok ieee80211_types[] = {
1526f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_TYPE_DATA, "data" },
1536f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_TYPE_MGT, "mgt" },
1546f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_TYPE_MGT, "management" },
1556f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_TYPE_CTL, "ctl" },
1566f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_TYPE_CTL, "control" },
1576f9cba8fSJoseph Mingrone	{ 0, NULL }
1586f9cba8fSJoseph Mingrone};
1596f9cba8fSJoseph Mingronestatic const struct tok ieee80211_mgt_subtypes[] = {
1606f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
1616f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
1626f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
1636f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
1646f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
1656f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
1666f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
1676f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
1686f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
1696f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
1706f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
1716f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
1726f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
1736f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
1746f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
1756f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
1766f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
1776f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
1786f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
1796f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
1806f9cba8fSJoseph Mingrone	{ 0, NULL }
1816f9cba8fSJoseph Mingrone};
1826f9cba8fSJoseph Mingronestatic const struct tok ieee80211_ctl_subtypes[] = {
1836f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
1846f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_RTS, "rts" },
1856f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_CTS, "cts" },
1866f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_ACK, "ack" },
1876f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
1886f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
1896f9cba8fSJoseph Mingrone	{ 0, NULL }
1906f9cba8fSJoseph Mingrone};
1916f9cba8fSJoseph Mingronestatic const struct tok ieee80211_data_subtypes[] = {
1926f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_DATA, "data" },
1936f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
1946f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
1956f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
1966f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_NODATA, "null" },
1976f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
1986f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll"  },
1996f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
2006f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
2016f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
2026f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
2036f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
2046f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
2056f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
2066f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
2076f9cba8fSJoseph Mingrone	{ 0, NULL }
2086f9cba8fSJoseph Mingrone};
2096f9cba8fSJoseph Mingronestatic const struct tok llc_s_subtypes[] = {
2106f9cba8fSJoseph Mingrone	{ LLC_RR, "rr" },
2116f9cba8fSJoseph Mingrone	{ LLC_RNR, "rnr" },
2126f9cba8fSJoseph Mingrone	{ LLC_REJ, "rej" },
2136f9cba8fSJoseph Mingrone	{ 0, NULL }
2146f9cba8fSJoseph Mingrone};
2156f9cba8fSJoseph Mingronestatic const struct tok llc_u_subtypes[] = {
2166f9cba8fSJoseph Mingrone	{ LLC_UI, "ui" },
2176f9cba8fSJoseph Mingrone	{ LLC_UA, "ua" },
2186f9cba8fSJoseph Mingrone	{ LLC_DISC, "disc" },
2196f9cba8fSJoseph Mingrone	{ LLC_DM, "dm" },
2206f9cba8fSJoseph Mingrone	{ LLC_SABME, "sabme" },
2216f9cba8fSJoseph Mingrone	{ LLC_TEST, "test" },
2226f9cba8fSJoseph Mingrone	{ LLC_XID, "xid" },
2236f9cba8fSJoseph Mingrone	{ LLC_FRMR, "frmr" },
2246f9cba8fSJoseph Mingrone	{ 0, NULL }
2256f9cba8fSJoseph Mingrone};
2266f9cba8fSJoseph Mingronestruct type2tok {
2276f9cba8fSJoseph Mingrone	int type;
2286f9cba8fSJoseph Mingrone	const struct tok *tok;
2296f9cba8fSJoseph Mingrone};
2306f9cba8fSJoseph Mingronestatic const struct type2tok ieee80211_type_subtypes[] = {
2316f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
2326f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
2336f9cba8fSJoseph Mingrone	{ IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
2346f9cba8fSJoseph Mingrone	{ 0, NULL }
2356f9cba8fSJoseph Mingrone};
2366f9cba8fSJoseph Mingrone
2376f9cba8fSJoseph Mingronestatic int
2386f9cba8fSJoseph Mingronestr2tok(const char *str, const struct tok *toks)
2396f9cba8fSJoseph Mingrone{
2406f9cba8fSJoseph Mingrone	int i;
2416f9cba8fSJoseph Mingrone
2426f9cba8fSJoseph Mingrone	for (i = 0; toks[i].s != NULL; i++) {
243*afdbf109SJoseph Mingrone		if (pcapint_strcasecmp(toks[i].s, str) == 0) {
2446f9cba8fSJoseph Mingrone			/*
2456f9cba8fSJoseph Mingrone			 * Just in case somebody is using this to
2466f9cba8fSJoseph Mingrone			 * generate values of -1/0xFFFFFFFF.
2476f9cba8fSJoseph Mingrone			 * That won't work, as it's indistinguishable
2486f9cba8fSJoseph Mingrone			 * from an error.
2496f9cba8fSJoseph Mingrone			 */
2506f9cba8fSJoseph Mingrone			if (toks[i].v == -1)
2516f9cba8fSJoseph Mingrone				abort();
2526f9cba8fSJoseph Mingrone			return (toks[i].v);
2536f9cba8fSJoseph Mingrone		}
2546f9cba8fSJoseph Mingrone	}
2556f9cba8fSJoseph Mingrone	return (-1);
2566f9cba8fSJoseph Mingrone}
2576f9cba8fSJoseph Mingrone
2586f9cba8fSJoseph Mingronestatic const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
2596f9cba8fSJoseph Mingrone
2606f9cba8fSJoseph Mingronestatic void
2616f9cba8fSJoseph Mingroneyyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
2626f9cba8fSJoseph Mingrone{
2636f9cba8fSJoseph Mingrone	bpf_set_error(cstate, "can't parse filter expression: %s", msg);
2646f9cba8fSJoseph Mingrone}
2656f9cba8fSJoseph Mingrone
2666f9cba8fSJoseph Mingronestatic const struct tok pflog_reasons[] = {
2676f9cba8fSJoseph Mingrone	{ PFRES_MATCH,		"match" },
2686f9cba8fSJoseph Mingrone	{ PFRES_BADOFF,		"bad-offset" },
2696f9cba8fSJoseph Mingrone	{ PFRES_FRAG,		"fragment" },
2706f9cba8fSJoseph Mingrone	{ PFRES_SHORT,		"short" },
2716f9cba8fSJoseph Mingrone	{ PFRES_NORM,		"normalize" },
2726f9cba8fSJoseph Mingrone	{ PFRES_MEMORY,		"memory" },
2736f9cba8fSJoseph Mingrone	{ PFRES_TS,		"bad-timestamp" },
2746f9cba8fSJoseph Mingrone	{ PFRES_CONGEST,	"congestion" },
2756f9cba8fSJoseph Mingrone	{ PFRES_IPOPTIONS,	"ip-option" },
2766f9cba8fSJoseph Mingrone	{ PFRES_PROTCKSUM,	"proto-cksum" },
2776f9cba8fSJoseph Mingrone	{ PFRES_BADSTATE,	"state-mismatch" },
2786f9cba8fSJoseph Mingrone	{ PFRES_STATEINS,	"state-insert" },
2796f9cba8fSJoseph Mingrone	{ PFRES_MAXSTATES,	"state-limit" },
2806f9cba8fSJoseph Mingrone	{ PFRES_SRCLIMIT,	"src-limit" },
2816f9cba8fSJoseph Mingrone	{ PFRES_SYNPROXY,	"synproxy" },
2826f9cba8fSJoseph Mingrone#if defined(__FreeBSD__)
2836f9cba8fSJoseph Mingrone	{ PFRES_MAPFAILED,	"map-failed" },
2846f9cba8fSJoseph Mingrone#elif defined(__NetBSD__)
2856f9cba8fSJoseph Mingrone	{ PFRES_STATELOCKED,	"state-locked" },
2866f9cba8fSJoseph Mingrone#elif defined(__OpenBSD__)
2876f9cba8fSJoseph Mingrone	{ PFRES_TRANSLATE,	"translate" },
2886f9cba8fSJoseph Mingrone	{ PFRES_NOROUTE,	"no-route" },
2896f9cba8fSJoseph Mingrone#elif defined(__APPLE__)
2906f9cba8fSJoseph Mingrone	{ PFRES_DUMMYNET,	"dummynet" },
2916f9cba8fSJoseph Mingrone#endif
2926f9cba8fSJoseph Mingrone	{ 0, NULL }
2936f9cba8fSJoseph Mingrone};
2946f9cba8fSJoseph Mingrone
2956f9cba8fSJoseph Mingronestatic int
2966f9cba8fSJoseph Mingronepfreason_to_num(compiler_state_t *cstate, const char *reason)
2976f9cba8fSJoseph Mingrone{
2986f9cba8fSJoseph Mingrone	int i;
2996f9cba8fSJoseph Mingrone
3006f9cba8fSJoseph Mingrone	i = str2tok(reason, pflog_reasons);
3016f9cba8fSJoseph Mingrone	if (i == -1)
3026f9cba8fSJoseph Mingrone		bpf_set_error(cstate, "unknown PF reason \"%s\"", reason);
3036f9cba8fSJoseph Mingrone	return (i);
3046f9cba8fSJoseph Mingrone}
3056f9cba8fSJoseph Mingrone
3066f9cba8fSJoseph Mingronestatic const struct tok pflog_actions[] = {
3076f9cba8fSJoseph Mingrone	{ PF_PASS,		"pass" },
3086f9cba8fSJoseph Mingrone	{ PF_PASS,		"accept" },	/* alias for "pass" */
3096f9cba8fSJoseph Mingrone	{ PF_DROP,		"drop" },
3106f9cba8fSJoseph Mingrone	{ PF_DROP,		"block" },	/* alias for "drop" */
3116f9cba8fSJoseph Mingrone	{ PF_SCRUB,		"scrub" },
3126f9cba8fSJoseph Mingrone	{ PF_NOSCRUB,		"noscrub" },
3136f9cba8fSJoseph Mingrone	{ PF_NAT,		"nat" },
3146f9cba8fSJoseph Mingrone	{ PF_NONAT,		"nonat" },
3156f9cba8fSJoseph Mingrone	{ PF_BINAT,		"binat" },
3166f9cba8fSJoseph Mingrone	{ PF_NOBINAT,		"nobinat" },
3176f9cba8fSJoseph Mingrone	{ PF_RDR,		"rdr" },
3186f9cba8fSJoseph Mingrone	{ PF_NORDR,		"nordr" },
3196f9cba8fSJoseph Mingrone	{ PF_SYNPROXY_DROP,	"synproxy-drop" },
3206f9cba8fSJoseph Mingrone#if defined(__FreeBSD__)
3216f9cba8fSJoseph Mingrone	{ PF_DEFER,		"defer" },
3226f9cba8fSJoseph Mingrone#elif defined(__OpenBSD__)
3236f9cba8fSJoseph Mingrone	{ PF_DEFER,		"defer" },
3246f9cba8fSJoseph Mingrone	{ PF_MATCH,		"match" },
3256f9cba8fSJoseph Mingrone	{ PF_DIVERT,		"divert" },
3266f9cba8fSJoseph Mingrone	{ PF_RT,		"rt" },
3276f9cba8fSJoseph Mingrone	{ PF_AFRT,		"afrt" },
3286f9cba8fSJoseph Mingrone#elif defined(__APPLE__)
3296f9cba8fSJoseph Mingrone	{ PF_DUMMYNET,		"dummynet" },
3306f9cba8fSJoseph Mingrone	{ PF_NODUMMYNET,	"nodummynet" },
3316f9cba8fSJoseph Mingrone	{ PF_NAT64,		"nat64" },
3326f9cba8fSJoseph Mingrone	{ PF_NONAT64,		"nonat64" },
3336f9cba8fSJoseph Mingrone#endif
3346f9cba8fSJoseph Mingrone	{ 0, NULL },
3356f9cba8fSJoseph Mingrone};
3366f9cba8fSJoseph Mingrone
3376f9cba8fSJoseph Mingronestatic int
3386f9cba8fSJoseph Mingronepfaction_to_num(compiler_state_t *cstate, const char *action)
3396f9cba8fSJoseph Mingrone{
3406f9cba8fSJoseph Mingrone	int i;
3416f9cba8fSJoseph Mingrone
3426f9cba8fSJoseph Mingrone	i = str2tok(action, pflog_actions);
3436f9cba8fSJoseph Mingrone	if (i == -1)
3446f9cba8fSJoseph Mingrone		bpf_set_error(cstate, "unknown PF action \"%s\"", action);
3456f9cba8fSJoseph Mingrone	return (i);
3466f9cba8fSJoseph Mingrone}
3476f9cba8fSJoseph Mingrone
3486f9cba8fSJoseph Mingrone/*
3496f9cba8fSJoseph Mingrone * For calls that might return an "an error occurred" value.
3506f9cba8fSJoseph Mingrone */
3516f9cba8fSJoseph Mingrone#define CHECK_INT_VAL(val)	if (val == -1) YYABORT
3526f9cba8fSJoseph Mingrone#define CHECK_PTR_VAL(val)	if (val == NULL) YYABORT
3536f9cba8fSJoseph Mingrone
3546f9cba8fSJoseph MingroneDIAG_OFF_BISON_BYACC
3556f9cba8fSJoseph Mingrone%}
3566f9cba8fSJoseph Mingrone
3576f9cba8fSJoseph Mingrone%union {
3586f9cba8fSJoseph Mingrone	int i;
3596f9cba8fSJoseph Mingrone	bpf_u_int32 h;
3606f9cba8fSJoseph Mingrone	char *s;
3616f9cba8fSJoseph Mingrone	struct stmt *stmt;
3626f9cba8fSJoseph Mingrone	struct arth *a;
3636f9cba8fSJoseph Mingrone	struct {
3646f9cba8fSJoseph Mingrone		struct qual q;
3656f9cba8fSJoseph Mingrone		int atmfieldtype;
3666f9cba8fSJoseph Mingrone		int mtp3fieldtype;
3676f9cba8fSJoseph Mingrone		struct block *b;
3686f9cba8fSJoseph Mingrone	} blk;
3696f9cba8fSJoseph Mingrone	struct block *rblk;
3706f9cba8fSJoseph Mingrone}
3716f9cba8fSJoseph Mingrone
3726f9cba8fSJoseph Mingrone%type	<blk>	expr id nid pid term rterm qid
3736f9cba8fSJoseph Mingrone%type	<blk>	head
3746f9cba8fSJoseph Mingrone%type	<i>	pqual dqual aqual ndaqual
3756f9cba8fSJoseph Mingrone%type	<a>	arth narth
3766f9cba8fSJoseph Mingrone%type	<i>	byteop pname relop irelop
3776f9cba8fSJoseph Mingrone%type	<h>	pnum
3786f9cba8fSJoseph Mingrone%type	<blk>	and or paren not null prog
3796f9cba8fSJoseph Mingrone%type	<rblk>	other pfvar p80211 pllc
3806f9cba8fSJoseph Mingrone%type	<i>	atmtype atmmultitype
3816f9cba8fSJoseph Mingrone%type	<blk>	atmfield
3826f9cba8fSJoseph Mingrone%type	<blk>	atmfieldvalue atmvalue atmlistvalue
3836f9cba8fSJoseph Mingrone%type	<i>	mtp2type
3846f9cba8fSJoseph Mingrone%type	<blk>	mtp3field
3856f9cba8fSJoseph Mingrone%type	<blk>	mtp3fieldvalue mtp3value mtp3listvalue
3866f9cba8fSJoseph Mingrone
3876f9cba8fSJoseph Mingrone
3886f9cba8fSJoseph Mingrone%token  DST SRC HOST GATEWAY
3896f9cba8fSJoseph Mingrone%token  NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
3906f9cba8fSJoseph Mingrone%token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
3916f9cba8fSJoseph Mingrone%token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
3926f9cba8fSJoseph Mingrone%token  TK_BROADCAST TK_MULTICAST
3936f9cba8fSJoseph Mingrone%token  NUM INBOUND OUTBOUND
3946f9cba8fSJoseph Mingrone%token  IFINDEX
3956f9cba8fSJoseph Mingrone%token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
3966f9cba8fSJoseph Mingrone%token	TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
3976f9cba8fSJoseph Mingrone%token  LINK
3986f9cba8fSJoseph Mingrone%token	GEQ LEQ NEQ
3996f9cba8fSJoseph Mingrone%token	ID EID HID HID6 AID
4006f9cba8fSJoseph Mingrone%token	LSH RSH
4016f9cba8fSJoseph Mingrone%token  LEN
4026f9cba8fSJoseph Mingrone%token  IPV6 ICMPV6 AH ESP
4036f9cba8fSJoseph Mingrone%token	VLAN MPLS
4046f9cba8fSJoseph Mingrone%token	PPPOED PPPOES GENEVE
4056f9cba8fSJoseph Mingrone%token  ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
4066f9cba8fSJoseph Mingrone%token  STP
4076f9cba8fSJoseph Mingrone%token  IPX
4086f9cba8fSJoseph Mingrone%token  NETBEUI
4096f9cba8fSJoseph Mingrone%token	LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
4106f9cba8fSJoseph Mingrone%token	OAM OAMF4 CONNECTMSG METACONNECT
4116f9cba8fSJoseph Mingrone%token	VPI VCI
4126f9cba8fSJoseph Mingrone%token	RADIO
4136f9cba8fSJoseph Mingrone%token	FISU LSSU MSU HFISU HLSSU HMSU
4146f9cba8fSJoseph Mingrone%token	SIO OPC DPC SLS HSIO HOPC HDPC HSLS
4156f9cba8fSJoseph Mingrone%token	LEX_ERROR
4166f9cba8fSJoseph Mingrone
4176f9cba8fSJoseph Mingrone%type	<s> ID EID AID
4186f9cba8fSJoseph Mingrone%type	<s> HID HID6
4196f9cba8fSJoseph Mingrone%type	<h> NUM
4206f9cba8fSJoseph Mingrone%type	<i> action reason type subtype type_subtype dir
4216f9cba8fSJoseph Mingrone
4226f9cba8fSJoseph Mingrone%left OR AND
4236f9cba8fSJoseph Mingrone%nonassoc  '!'
4246f9cba8fSJoseph Mingrone%left '|'
4256f9cba8fSJoseph Mingrone%left '&'
4266f9cba8fSJoseph Mingrone%left LSH RSH
4276f9cba8fSJoseph Mingrone%left '+' '-'
4286f9cba8fSJoseph Mingrone%left '*' '/'
4296f9cba8fSJoseph Mingrone%nonassoc UMINUS
4306f9cba8fSJoseph Mingrone%%
4316f9cba8fSJoseph Mingroneprog:	  null expr
4326f9cba8fSJoseph Mingrone{
433*afdbf109SJoseph Mingrone	/*
434*afdbf109SJoseph Mingrone	 * I'm not sure we have a reason to use yynerrs, but it's
435*afdbf109SJoseph Mingrone	 * declared, and incremented, whether we need it or not,
436*afdbf109SJoseph Mingrone	 * which means that Clang 15 will give a "used but not
437*afdbf109SJoseph Mingrone	 * set" warning.  This should suppress the warning for
438*afdbf109SJoseph Mingrone	 * yynerrs without suppressing it for other variables.
439*afdbf109SJoseph Mingrone	 */
440*afdbf109SJoseph Mingrone	(void) yynerrs;
4416f9cba8fSJoseph Mingrone	CHECK_INT_VAL(finish_parse(cstate, $2.b));
4426f9cba8fSJoseph Mingrone}
4436f9cba8fSJoseph Mingrone	| null
4446f9cba8fSJoseph Mingrone	;
4456f9cba8fSJoseph Mingronenull:	  /* null */		{ $$.q = qerr; }
4466f9cba8fSJoseph Mingrone	;
4476f9cba8fSJoseph Mingroneexpr:	  term
4486f9cba8fSJoseph Mingrone	| expr and term		{ gen_and($1.b, $3.b); $$ = $3; }
4496f9cba8fSJoseph Mingrone	| expr and id		{ gen_and($1.b, $3.b); $$ = $3; }
4506f9cba8fSJoseph Mingrone	| expr or term		{ gen_or($1.b, $3.b); $$ = $3; }
4516f9cba8fSJoseph Mingrone	| expr or id		{ gen_or($1.b, $3.b); $$ = $3; }
4526f9cba8fSJoseph Mingrone	;
4536f9cba8fSJoseph Mingroneand:	  AND			{ $$ = $<blk>0; }
4546f9cba8fSJoseph Mingrone	;
4556f9cba8fSJoseph Mingroneor:	  OR			{ $$ = $<blk>0; }
4566f9cba8fSJoseph Mingrone	;
4576f9cba8fSJoseph Mingroneid:	  nid
4586f9cba8fSJoseph Mingrone	| pnum			{ CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1,
4596f9cba8fSJoseph Mingrone						   $$.q = $<blk>0.q))); }
4606f9cba8fSJoseph Mingrone	| paren pid ')'		{ $$ = $2; }
4616f9cba8fSJoseph Mingrone	;
4626f9cba8fSJoseph Mingronenid:	  ID			{ CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q))); }
463*afdbf109SJoseph Mingrone	| HID '/' NUM		{
4646f9cba8fSJoseph Mingrone				  CHECK_PTR_VAL($1);
465*afdbf109SJoseph Mingrone				  /* Check whether HID/NUM is being used when appropriate */
4666f9cba8fSJoseph Mingrone				  $$.q = $<blk>0.q;
4676f9cba8fSJoseph Mingrone				  if ($$.q.addr == Q_PORT) {
468*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'port' modifier applied to IP address and prefix length");
4696f9cba8fSJoseph Mingrone					YYABORT;
4706f9cba8fSJoseph Mingrone				  } else if ($$.q.addr == Q_PORTRANGE) {
471*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'portrange' modifier applied to IP address and prefix length");
4726f9cba8fSJoseph Mingrone					YYABORT;
4736f9cba8fSJoseph Mingrone				  } else if ($$.q.addr == Q_PROTO) {
474*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'proto' modifier applied to IP address and prefix length");
4756f9cba8fSJoseph Mingrone					YYABORT;
4766f9cba8fSJoseph Mingrone				  } else if ($$.q.addr == Q_PROTOCHAIN) {
477*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'protochain' modifier applied to IP address and prefix length");
478*afdbf109SJoseph Mingrone					YYABORT;
479*afdbf109SJoseph Mingrone				  }
480*afdbf109SJoseph Mingrone				  CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3, $$.q)));
481*afdbf109SJoseph Mingrone				}
482*afdbf109SJoseph Mingrone	| HID NETMASK HID	{
483*afdbf109SJoseph Mingrone				  CHECK_PTR_VAL($1);
484*afdbf109SJoseph Mingrone				  /* Check whether HID mask HID is being used when appropriate */
485*afdbf109SJoseph Mingrone				  $$.q = $<blk>0.q;
486*afdbf109SJoseph Mingrone				  if ($$.q.addr == Q_PORT) {
487*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'port' modifier applied to IP address and netmask");
488*afdbf109SJoseph Mingrone					YYABORT;
489*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PORTRANGE) {
490*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'portrange' modifier applied to IP address and netmask");
491*afdbf109SJoseph Mingrone					YYABORT;
492*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PROTO) {
493*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'proto' modifier applied to IP address and netmask");
494*afdbf109SJoseph Mingrone					YYABORT;
495*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PROTOCHAIN) {
496*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'protochain' modifier applied to IP address and netmask");
497*afdbf109SJoseph Mingrone					YYABORT;
498*afdbf109SJoseph Mingrone				  }
499*afdbf109SJoseph Mingrone				  CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0, $$.q)));
500*afdbf109SJoseph Mingrone				}
501*afdbf109SJoseph Mingrone	| HID			{
502*afdbf109SJoseph Mingrone				  CHECK_PTR_VAL($1);
503*afdbf109SJoseph Mingrone				  /* Check whether HID is being used when appropriate */
504*afdbf109SJoseph Mingrone				  $$.q = $<blk>0.q;
505*afdbf109SJoseph Mingrone				  if ($$.q.addr == Q_PORT) {
506*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'port' modifier applied to IP address");
507*afdbf109SJoseph Mingrone					YYABORT;
508*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PORTRANGE) {
509*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'portrange' modifier applied to IP address");
510*afdbf109SJoseph Mingrone					YYABORT;
511*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PROTO) {
512*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'proto' modifier applied to IP address");
513*afdbf109SJoseph Mingrone					YYABORT;
514*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PROTOCHAIN) {
515*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'protochain' modifier applied to IP address");
5166f9cba8fSJoseph Mingrone					YYABORT;
5176f9cba8fSJoseph Mingrone				  }
5186f9cba8fSJoseph Mingrone				  CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q)));
5196f9cba8fSJoseph Mingrone				}
5206f9cba8fSJoseph Mingrone	| HID6 '/' NUM		{
5216f9cba8fSJoseph Mingrone				  CHECK_PTR_VAL($1);
5226f9cba8fSJoseph Mingrone#ifdef INET6
523*afdbf109SJoseph Mingrone				  /* Check whether HID6/NUM is being used when appropriate */
524*afdbf109SJoseph Mingrone				  $$.q = $<blk>0.q;
525*afdbf109SJoseph Mingrone				  if ($$.q.addr == Q_PORT) {
526*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'port' modifier applied to IP address and prefix length");
527*afdbf109SJoseph Mingrone					YYABORT;
528*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PORTRANGE) {
529*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'portrange' modifier applied to IP address and prefix length");
530*afdbf109SJoseph Mingrone					YYABORT;
531*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PROTO) {
532*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'proto' modifier applied to IP address and prefix length ");
533*afdbf109SJoseph Mingrone					YYABORT;
534*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PROTOCHAIN) {
535*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'protochain' modifier applied to IP address and prefix length");
536*afdbf109SJoseph Mingrone					YYABORT;
537*afdbf109SJoseph Mingrone				  }
538*afdbf109SJoseph Mingrone				  CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, $3, $$.q)));
5396f9cba8fSJoseph Mingrone#else
540*afdbf109SJoseph Mingrone				  bpf_set_error(cstate, "IPv6 addresses not supported "
5416f9cba8fSJoseph Mingrone					"in this configuration");
5426f9cba8fSJoseph Mingrone				  YYABORT;
5436f9cba8fSJoseph Mingrone#endif /*INET6*/
5446f9cba8fSJoseph Mingrone				}
5456f9cba8fSJoseph Mingrone	| HID6			{
5466f9cba8fSJoseph Mingrone				  CHECK_PTR_VAL($1);
5476f9cba8fSJoseph Mingrone#ifdef INET6
548*afdbf109SJoseph Mingrone				  /* Check whether HID6 is being used when appropriate */
549*afdbf109SJoseph Mingrone				  $$.q = $<blk>0.q;
550*afdbf109SJoseph Mingrone				  if ($$.q.addr == Q_PORT) {
551*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'port' modifier applied to IP address");
552*afdbf109SJoseph Mingrone					YYABORT;
553*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PORTRANGE) {
554*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'portrange' modifier applied to IP address");
555*afdbf109SJoseph Mingrone					YYABORT;
556*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PROTO) {
557*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'proto' modifier applied to 'ip6addr/prefixlen");
558*afdbf109SJoseph Mingrone					YYABORT;
559*afdbf109SJoseph Mingrone				  } else if ($$.q.addr == Q_PROTOCHAIN) {
560*afdbf109SJoseph Mingrone					bpf_set_error(cstate, "'protochain' modifier applied to IP address");
561*afdbf109SJoseph Mingrone					YYABORT;
562*afdbf109SJoseph Mingrone				  }
563*afdbf109SJoseph Mingrone				  CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 128, $$.q)));
5646f9cba8fSJoseph Mingrone#else
565*afdbf109SJoseph Mingrone				  bpf_set_error(cstate, "IPv6 addresses not supported "
5666f9cba8fSJoseph Mingrone					"in this configuration");
5676f9cba8fSJoseph Mingrone				  YYABORT;
5686f9cba8fSJoseph Mingrone#endif /*INET6*/
5696f9cba8fSJoseph Mingrone				}
5706f9cba8fSJoseph Mingrone	| EID			{ CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q))); }
5716f9cba8fSJoseph Mingrone	| AID			{ CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q))); }
5726f9cba8fSJoseph Mingrone	| not id		{ gen_not($2.b); $$ = $2; }
5736f9cba8fSJoseph Mingrone	;
5746f9cba8fSJoseph Mingronenot:	  '!'			{ $$ = $<blk>0; }
5756f9cba8fSJoseph Mingrone	;
5766f9cba8fSJoseph Mingroneparen:	  '('			{ $$ = $<blk>0; }
5776f9cba8fSJoseph Mingrone	;
5786f9cba8fSJoseph Mingronepid:	  nid
5796f9cba8fSJoseph Mingrone	| qid and id		{ gen_and($1.b, $3.b); $$ = $3; }
5806f9cba8fSJoseph Mingrone	| qid or id		{ gen_or($1.b, $3.b); $$ = $3; }
5816f9cba8fSJoseph Mingrone	;
5826f9cba8fSJoseph Mingroneqid:	  pnum			{ CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1,
5836f9cba8fSJoseph Mingrone						   $$.q = $<blk>0.q))); }
5846f9cba8fSJoseph Mingrone	| pid
5856f9cba8fSJoseph Mingrone	;
5866f9cba8fSJoseph Mingroneterm:	  rterm
5876f9cba8fSJoseph Mingrone	| not term		{ gen_not($2.b); $$ = $2; }
5886f9cba8fSJoseph Mingrone	;
5896f9cba8fSJoseph Mingronehead:	  pqual dqual aqual	{ QSET($$.q, $1, $2, $3); }
5906f9cba8fSJoseph Mingrone	| pqual dqual		{ QSET($$.q, $1, $2, Q_DEFAULT); }
5916f9cba8fSJoseph Mingrone	| pqual aqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
5926f9cba8fSJoseph Mingrone	| pqual PROTO		{ QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
5936f9cba8fSJoseph Mingrone	| pqual PROTOCHAIN	{
5946f9cba8fSJoseph Mingrone#ifdef NO_PROTOCHAIN
5956f9cba8fSJoseph Mingrone				  bpf_set_error(cstate, "protochain not supported");
5966f9cba8fSJoseph Mingrone				  YYABORT;
5976f9cba8fSJoseph Mingrone#else
5986f9cba8fSJoseph Mingrone				  QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN);
5996f9cba8fSJoseph Mingrone#endif
6006f9cba8fSJoseph Mingrone				}
6016f9cba8fSJoseph Mingrone	| pqual ndaqual		{ QSET($$.q, $1, Q_DEFAULT, $2); }
6026f9cba8fSJoseph Mingrone	;
6036f9cba8fSJoseph Mingronerterm:	  head id		{ $$ = $2; }
6046f9cba8fSJoseph Mingrone	| paren expr ')'	{ $$.b = $2.b; $$.q = $1.q; }
6056f9cba8fSJoseph Mingrone	| pname			{ CHECK_PTR_VAL(($$.b = gen_proto_abbrev(cstate, $1))); $$.q = qerr; }
6066f9cba8fSJoseph Mingrone	| arth relop arth	{ CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 0)));
6076f9cba8fSJoseph Mingrone				  $$.q = qerr; }
6086f9cba8fSJoseph Mingrone	| arth irelop arth	{ CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 1)));
6096f9cba8fSJoseph Mingrone				  $$.q = qerr; }
6106f9cba8fSJoseph Mingrone	| other			{ $$.b = $1; $$.q = qerr; }
6116f9cba8fSJoseph Mingrone	| atmtype		{ CHECK_PTR_VAL(($$.b = gen_atmtype_abbrev(cstate, $1))); $$.q = qerr; }
6126f9cba8fSJoseph Mingrone	| atmmultitype		{ CHECK_PTR_VAL(($$.b = gen_atmmulti_abbrev(cstate, $1))); $$.q = qerr; }
6136f9cba8fSJoseph Mingrone	| atmfield atmvalue	{ $$.b = $2.b; $$.q = qerr; }
6146f9cba8fSJoseph Mingrone	| mtp2type		{ CHECK_PTR_VAL(($$.b = gen_mtp2type_abbrev(cstate, $1))); $$.q = qerr; }
6156f9cba8fSJoseph Mingrone	| mtp3field mtp3value	{ $$.b = $2.b; $$.q = qerr; }
6166f9cba8fSJoseph Mingrone	;
6176f9cba8fSJoseph Mingrone/* protocol level qualifiers */
6186f9cba8fSJoseph Mingronepqual:	  pname
6196f9cba8fSJoseph Mingrone	|			{ $$ = Q_DEFAULT; }
6206f9cba8fSJoseph Mingrone	;
6216f9cba8fSJoseph Mingrone/* 'direction' qualifiers */
6226f9cba8fSJoseph Mingronedqual:	  SRC			{ $$ = Q_SRC; }
6236f9cba8fSJoseph Mingrone	| DST			{ $$ = Q_DST; }
6246f9cba8fSJoseph Mingrone	| SRC OR DST		{ $$ = Q_OR; }
6256f9cba8fSJoseph Mingrone	| DST OR SRC		{ $$ = Q_OR; }
6266f9cba8fSJoseph Mingrone	| SRC AND DST		{ $$ = Q_AND; }
6276f9cba8fSJoseph Mingrone	| DST AND SRC		{ $$ = Q_AND; }
6286f9cba8fSJoseph Mingrone	| ADDR1			{ $$ = Q_ADDR1; }
6296f9cba8fSJoseph Mingrone	| ADDR2			{ $$ = Q_ADDR2; }
6306f9cba8fSJoseph Mingrone	| ADDR3			{ $$ = Q_ADDR3; }
6316f9cba8fSJoseph Mingrone	| ADDR4			{ $$ = Q_ADDR4; }
6326f9cba8fSJoseph Mingrone	| RA			{ $$ = Q_RA; }
6336f9cba8fSJoseph Mingrone	| TA			{ $$ = Q_TA; }
6346f9cba8fSJoseph Mingrone	;
6356f9cba8fSJoseph Mingrone/* address type qualifiers */
6366f9cba8fSJoseph Mingroneaqual:	  HOST			{ $$ = Q_HOST; }
6376f9cba8fSJoseph Mingrone	| NET			{ $$ = Q_NET; }
6386f9cba8fSJoseph Mingrone	| PORT			{ $$ = Q_PORT; }
6396f9cba8fSJoseph Mingrone	| PORTRANGE		{ $$ = Q_PORTRANGE; }
6406f9cba8fSJoseph Mingrone	;
6416f9cba8fSJoseph Mingrone/* non-directional address type qualifiers */
6426f9cba8fSJoseph Mingronendaqual:  GATEWAY		{ $$ = Q_GATEWAY; }
6436f9cba8fSJoseph Mingrone	;
6446f9cba8fSJoseph Mingronepname:	  LINK			{ $$ = Q_LINK; }
6456f9cba8fSJoseph Mingrone	| IP			{ $$ = Q_IP; }
6466f9cba8fSJoseph Mingrone	| ARP			{ $$ = Q_ARP; }
6476f9cba8fSJoseph Mingrone	| RARP			{ $$ = Q_RARP; }
6486f9cba8fSJoseph Mingrone	| SCTP			{ $$ = Q_SCTP; }
6496f9cba8fSJoseph Mingrone	| TCP			{ $$ = Q_TCP; }
6506f9cba8fSJoseph Mingrone	| UDP			{ $$ = Q_UDP; }
6516f9cba8fSJoseph Mingrone	| ICMP			{ $$ = Q_ICMP; }
6526f9cba8fSJoseph Mingrone	| IGMP			{ $$ = Q_IGMP; }
6536f9cba8fSJoseph Mingrone	| IGRP			{ $$ = Q_IGRP; }
6546f9cba8fSJoseph Mingrone	| PIM			{ $$ = Q_PIM; }
6556f9cba8fSJoseph Mingrone	| VRRP			{ $$ = Q_VRRP; }
6566f9cba8fSJoseph Mingrone	| CARP			{ $$ = Q_CARP; }
6576f9cba8fSJoseph Mingrone	| ATALK			{ $$ = Q_ATALK; }
6586f9cba8fSJoseph Mingrone	| AARP			{ $$ = Q_AARP; }
6596f9cba8fSJoseph Mingrone	| DECNET		{ $$ = Q_DECNET; }
6606f9cba8fSJoseph Mingrone	| LAT			{ $$ = Q_LAT; }
6616f9cba8fSJoseph Mingrone	| SCA			{ $$ = Q_SCA; }
6626f9cba8fSJoseph Mingrone	| MOPDL			{ $$ = Q_MOPDL; }
6636f9cba8fSJoseph Mingrone	| MOPRC			{ $$ = Q_MOPRC; }
6646f9cba8fSJoseph Mingrone	| IPV6			{ $$ = Q_IPV6; }
6656f9cba8fSJoseph Mingrone	| ICMPV6		{ $$ = Q_ICMPV6; }
6666f9cba8fSJoseph Mingrone	| AH			{ $$ = Q_AH; }
6676f9cba8fSJoseph Mingrone	| ESP			{ $$ = Q_ESP; }
6686f9cba8fSJoseph Mingrone	| ISO			{ $$ = Q_ISO; }
6696f9cba8fSJoseph Mingrone	| ESIS			{ $$ = Q_ESIS; }
6706f9cba8fSJoseph Mingrone	| ISIS			{ $$ = Q_ISIS; }
6716f9cba8fSJoseph Mingrone	| L1			{ $$ = Q_ISIS_L1; }
6726f9cba8fSJoseph Mingrone	| L2			{ $$ = Q_ISIS_L2; }
6736f9cba8fSJoseph Mingrone	| IIH			{ $$ = Q_ISIS_IIH; }
6746f9cba8fSJoseph Mingrone	| LSP			{ $$ = Q_ISIS_LSP; }
6756f9cba8fSJoseph Mingrone	| SNP			{ $$ = Q_ISIS_SNP; }
6766f9cba8fSJoseph Mingrone	| PSNP			{ $$ = Q_ISIS_PSNP; }
6776f9cba8fSJoseph Mingrone	| CSNP			{ $$ = Q_ISIS_CSNP; }
6786f9cba8fSJoseph Mingrone	| CLNP			{ $$ = Q_CLNP; }
6796f9cba8fSJoseph Mingrone	| STP			{ $$ = Q_STP; }
6806f9cba8fSJoseph Mingrone	| IPX			{ $$ = Q_IPX; }
6816f9cba8fSJoseph Mingrone	| NETBEUI		{ $$ = Q_NETBEUI; }
6826f9cba8fSJoseph Mingrone	| RADIO			{ $$ = Q_RADIO; }
6836f9cba8fSJoseph Mingrone	;
6846f9cba8fSJoseph Mingroneother:	  pqual TK_BROADCAST	{ CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
6856f9cba8fSJoseph Mingrone	| pqual TK_MULTICAST	{ CHECK_PTR_VAL(($$ = gen_multicast(cstate, $1))); }
6866f9cba8fSJoseph Mingrone	| LESS NUM		{ CHECK_PTR_VAL(($$ = gen_less(cstate, $2))); }
6876f9cba8fSJoseph Mingrone	| GREATER NUM		{ CHECK_PTR_VAL(($$ = gen_greater(cstate, $2))); }
6886f9cba8fSJoseph Mingrone	| CBYTE NUM byteop NUM	{ CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); }
6896f9cba8fSJoseph Mingrone	| INBOUND		{ CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); }
6906f9cba8fSJoseph Mingrone	| OUTBOUND		{ CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); }
6916f9cba8fSJoseph Mingrone	| IFINDEX NUM		{ CHECK_PTR_VAL(($$ = gen_ifindex(cstate, $2))); }
6926f9cba8fSJoseph Mingrone	| VLAN pnum		{ CHECK_PTR_VAL(($$ = gen_vlan(cstate, $2, 1))); }
6936f9cba8fSJoseph Mingrone	| VLAN			{ CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
6946f9cba8fSJoseph Mingrone	| MPLS pnum		{ CHECK_PTR_VAL(($$ = gen_mpls(cstate, $2, 1))); }
6956f9cba8fSJoseph Mingrone	| MPLS			{ CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); }
6966f9cba8fSJoseph Mingrone	| PPPOED		{ CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); }
6976f9cba8fSJoseph Mingrone	| PPPOES pnum		{ CHECK_PTR_VAL(($$ = gen_pppoes(cstate, $2, 1))); }
6986f9cba8fSJoseph Mingrone	| PPPOES		{ CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }
6996f9cba8fSJoseph Mingrone	| GENEVE pnum		{ CHECK_PTR_VAL(($$ = gen_geneve(cstate, $2, 1))); }
7006f9cba8fSJoseph Mingrone	| GENEVE		{ CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
7016f9cba8fSJoseph Mingrone	| pfvar			{ $$ = $1; }
7026f9cba8fSJoseph Mingrone	| pqual p80211		{ $$ = $2; }
7036f9cba8fSJoseph Mingrone	| pllc			{ $$ = $1; }
7046f9cba8fSJoseph Mingrone	;
7056f9cba8fSJoseph Mingrone
7066f9cba8fSJoseph Mingronepfvar:	  PF_IFNAME ID		{ CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ifname(cstate, $2))); }
7076f9cba8fSJoseph Mingrone	| PF_RSET ID		{ CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ruleset(cstate, $2))); }
7086f9cba8fSJoseph Mingrone	| PF_RNR NUM		{ CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); }
7096f9cba8fSJoseph Mingrone	| PF_SRNR NUM		{ CHECK_PTR_VAL(($$ = gen_pf_srnr(cstate, $2))); }
7106f9cba8fSJoseph Mingrone	| PF_REASON reason	{ CHECK_PTR_VAL(($$ = gen_pf_reason(cstate, $2))); }
7116f9cba8fSJoseph Mingrone	| PF_ACTION action	{ CHECK_PTR_VAL(($$ = gen_pf_action(cstate, $2))); }
7126f9cba8fSJoseph Mingrone	;
7136f9cba8fSJoseph Mingrone
7146f9cba8fSJoseph Mingronep80211:   TYPE type SUBTYPE subtype
7156f9cba8fSJoseph Mingrone				{ CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2 | $4,
7166f9cba8fSJoseph Mingrone					IEEE80211_FC0_TYPE_MASK |
7176f9cba8fSJoseph Mingrone					IEEE80211_FC0_SUBTYPE_MASK)));
7186f9cba8fSJoseph Mingrone				}
7196f9cba8fSJoseph Mingrone	| TYPE type		{ CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
7206f9cba8fSJoseph Mingrone					IEEE80211_FC0_TYPE_MASK)));
7216f9cba8fSJoseph Mingrone				}
7226f9cba8fSJoseph Mingrone	| SUBTYPE type_subtype	{ CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
7236f9cba8fSJoseph Mingrone					IEEE80211_FC0_TYPE_MASK |
7246f9cba8fSJoseph Mingrone					IEEE80211_FC0_SUBTYPE_MASK)));
7256f9cba8fSJoseph Mingrone				}
7266f9cba8fSJoseph Mingrone	| DIR dir		{ CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); }
7276f9cba8fSJoseph Mingrone	;
7286f9cba8fSJoseph Mingrone
7296f9cba8fSJoseph Mingronetype:	  NUM			{ if (($1 & (~IEEE80211_FC0_TYPE_MASK)) != 0) {
7306f9cba8fSJoseph Mingrone					bpf_set_error(cstate, "invalid 802.11 type value 0x%02x", $1);
7316f9cba8fSJoseph Mingrone					YYABORT;
7326f9cba8fSJoseph Mingrone				  }
7336f9cba8fSJoseph Mingrone				  $$ = (int)$1;
7346f9cba8fSJoseph Mingrone				}
7356f9cba8fSJoseph Mingrone	| ID			{ CHECK_PTR_VAL($1);
7366f9cba8fSJoseph Mingrone				  $$ = str2tok($1, ieee80211_types);
7376f9cba8fSJoseph Mingrone				  if ($$ == -1) {
7386f9cba8fSJoseph Mingrone					bpf_set_error(cstate, "unknown 802.11 type name \"%s\"", $1);
7396f9cba8fSJoseph Mingrone					YYABORT;
7406f9cba8fSJoseph Mingrone				  }
7416f9cba8fSJoseph Mingrone				}
7426f9cba8fSJoseph Mingrone	;
7436f9cba8fSJoseph Mingrone
7446f9cba8fSJoseph Mingronesubtype:  NUM			{ if (($1 & (~IEEE80211_FC0_SUBTYPE_MASK)) != 0) {
7456f9cba8fSJoseph Mingrone					bpf_set_error(cstate, "invalid 802.11 subtype value 0x%02x", $1);
7466f9cba8fSJoseph Mingrone					YYABORT;
7476f9cba8fSJoseph Mingrone				  }
7486f9cba8fSJoseph Mingrone				  $$ = (int)$1;
7496f9cba8fSJoseph Mingrone				}
7506f9cba8fSJoseph Mingrone	| ID			{ const struct tok *types = NULL;
7516f9cba8fSJoseph Mingrone				  int i;
7526f9cba8fSJoseph Mingrone				  CHECK_PTR_VAL($1);
7536f9cba8fSJoseph Mingrone				  for (i = 0;; i++) {
7546f9cba8fSJoseph Mingrone					if (ieee80211_type_subtypes[i].tok == NULL) {
7556f9cba8fSJoseph Mingrone						/* Ran out of types */
7566f9cba8fSJoseph Mingrone						bpf_set_error(cstate, "unknown 802.11 type");
7576f9cba8fSJoseph Mingrone						YYABORT;
7586f9cba8fSJoseph Mingrone					}
7596f9cba8fSJoseph Mingrone					if ($<i>-1 == ieee80211_type_subtypes[i].type) {
7606f9cba8fSJoseph Mingrone						types = ieee80211_type_subtypes[i].tok;
7616f9cba8fSJoseph Mingrone						break;
7626f9cba8fSJoseph Mingrone					}
7636f9cba8fSJoseph Mingrone				  }
7646f9cba8fSJoseph Mingrone
7656f9cba8fSJoseph Mingrone				  $$ = str2tok($1, types);
7666f9cba8fSJoseph Mingrone				  if ($$ == -1) {
7676f9cba8fSJoseph Mingrone					bpf_set_error(cstate, "unknown 802.11 subtype name \"%s\"", $1);
7686f9cba8fSJoseph Mingrone					YYABORT;
7696f9cba8fSJoseph Mingrone				  }
7706f9cba8fSJoseph Mingrone				}
7716f9cba8fSJoseph Mingrone	;
7726f9cba8fSJoseph Mingrone
7736f9cba8fSJoseph Mingronetype_subtype:	ID		{ int i;
7746f9cba8fSJoseph Mingrone				  CHECK_PTR_VAL($1);
7756f9cba8fSJoseph Mingrone				  for (i = 0;; i++) {
7766f9cba8fSJoseph Mingrone					if (ieee80211_type_subtypes[i].tok == NULL) {
7776f9cba8fSJoseph Mingrone						/* Ran out of types */
7786f9cba8fSJoseph Mingrone						bpf_set_error(cstate, "unknown 802.11 type name");
7796f9cba8fSJoseph Mingrone						YYABORT;
7806f9cba8fSJoseph Mingrone					}
7816f9cba8fSJoseph Mingrone					$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
7826f9cba8fSJoseph Mingrone					if ($$ != -1) {
7836f9cba8fSJoseph Mingrone						$$ |= ieee80211_type_subtypes[i].type;
7846f9cba8fSJoseph Mingrone						break;
7856f9cba8fSJoseph Mingrone					}
7866f9cba8fSJoseph Mingrone				  }
7876f9cba8fSJoseph Mingrone				}
7886f9cba8fSJoseph Mingrone		;
7896f9cba8fSJoseph Mingrone
7906f9cba8fSJoseph Mingronepllc:	LLC			{ CHECK_PTR_VAL(($$ = gen_llc(cstate))); }
7916f9cba8fSJoseph Mingrone	| LLC ID		{ CHECK_PTR_VAL($2);
792*afdbf109SJoseph Mingrone				  if (pcapint_strcasecmp($2, "i") == 0) {
7936f9cba8fSJoseph Mingrone					CHECK_PTR_VAL(($$ = gen_llc_i(cstate)));
794*afdbf109SJoseph Mingrone				  } else if (pcapint_strcasecmp($2, "s") == 0) {
7956f9cba8fSJoseph Mingrone					CHECK_PTR_VAL(($$ = gen_llc_s(cstate)));
796*afdbf109SJoseph Mingrone				  } else if (pcapint_strcasecmp($2, "u") == 0) {
7976f9cba8fSJoseph Mingrone					CHECK_PTR_VAL(($$ = gen_llc_u(cstate)));
7986f9cba8fSJoseph Mingrone				  } else {
7996f9cba8fSJoseph Mingrone					int subtype;
8006f9cba8fSJoseph Mingrone
8016f9cba8fSJoseph Mingrone					subtype = str2tok($2, llc_s_subtypes);
8026f9cba8fSJoseph Mingrone					if (subtype != -1) {
8036f9cba8fSJoseph Mingrone						CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, subtype)));
8046f9cba8fSJoseph Mingrone					} else {
8056f9cba8fSJoseph Mingrone						subtype = str2tok($2, llc_u_subtypes);
8066f9cba8fSJoseph Mingrone						if (subtype == -1) {
8076f9cba8fSJoseph Mingrone							bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2);
8086f9cba8fSJoseph Mingrone							YYABORT;
8096f9cba8fSJoseph Mingrone						}
8106f9cba8fSJoseph Mingrone						CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype)));
8116f9cba8fSJoseph Mingrone					}
8126f9cba8fSJoseph Mingrone				  }
8136f9cba8fSJoseph Mingrone				}
8146f9cba8fSJoseph Mingrone				/* sigh, "rnr" is already a keyword for PF */
8156f9cba8fSJoseph Mingrone	| LLC PF_RNR		{ CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); }
8166f9cba8fSJoseph Mingrone	;
8176f9cba8fSJoseph Mingrone
8186f9cba8fSJoseph Mingronedir:	  NUM			{ $$ = (int)$1; }
8196f9cba8fSJoseph Mingrone	| ID			{ CHECK_PTR_VAL($1);
820*afdbf109SJoseph Mingrone				  if (pcapint_strcasecmp($1, "nods") == 0)
8216f9cba8fSJoseph Mingrone					$$ = IEEE80211_FC1_DIR_NODS;
822*afdbf109SJoseph Mingrone				  else if (pcapint_strcasecmp($1, "tods") == 0)
8236f9cba8fSJoseph Mingrone					$$ = IEEE80211_FC1_DIR_TODS;
824*afdbf109SJoseph Mingrone				  else if (pcapint_strcasecmp($1, "fromds") == 0)
8256f9cba8fSJoseph Mingrone					$$ = IEEE80211_FC1_DIR_FROMDS;
826*afdbf109SJoseph Mingrone				  else if (pcapint_strcasecmp($1, "dstods") == 0)
8276f9cba8fSJoseph Mingrone					$$ = IEEE80211_FC1_DIR_DSTODS;
8286f9cba8fSJoseph Mingrone				  else {
8296f9cba8fSJoseph Mingrone					bpf_set_error(cstate, "unknown 802.11 direction");
8306f9cba8fSJoseph Mingrone					YYABORT;
8316f9cba8fSJoseph Mingrone				  }
8326f9cba8fSJoseph Mingrone				}
8336f9cba8fSJoseph Mingrone	;
8346f9cba8fSJoseph Mingrone
8356f9cba8fSJoseph Mingronereason:	  NUM			{ $$ = $1; }
8366f9cba8fSJoseph Mingrone	| ID			{ CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfreason_to_num(cstate, $1))); }
8376f9cba8fSJoseph Mingrone	;
8386f9cba8fSJoseph Mingrone
8396f9cba8fSJoseph Mingroneaction:	  ID			{ CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfaction_to_num(cstate, $1))); }
8406f9cba8fSJoseph Mingrone	;
8416f9cba8fSJoseph Mingrone
8426f9cba8fSJoseph Mingronerelop:	  '>'			{ $$ = BPF_JGT; }
8436f9cba8fSJoseph Mingrone	| GEQ			{ $$ = BPF_JGE; }
8446f9cba8fSJoseph Mingrone	| '='			{ $$ = BPF_JEQ; }
8456f9cba8fSJoseph Mingrone	;
8466f9cba8fSJoseph Mingroneirelop:	  LEQ			{ $$ = BPF_JGT; }
8476f9cba8fSJoseph Mingrone	| '<'			{ $$ = BPF_JGE; }
8486f9cba8fSJoseph Mingrone	| NEQ			{ $$ = BPF_JEQ; }
8496f9cba8fSJoseph Mingrone	;
8506f9cba8fSJoseph Mingronearth:	  pnum			{ CHECK_PTR_VAL(($$ = gen_loadi(cstate, $1))); }
8516f9cba8fSJoseph Mingrone	| narth
8526f9cba8fSJoseph Mingrone	;
8536f9cba8fSJoseph Mingronenarth:	  pname '[' arth ']'		{ CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, 1))); }
8546f9cba8fSJoseph Mingrone	| pname '[' arth ':' NUM ']'	{ CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, $5))); }
8556f9cba8fSJoseph Mingrone	| arth '+' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_ADD, $1, $3))); }
8566f9cba8fSJoseph Mingrone	| arth '-' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_SUB, $1, $3))); }
8576f9cba8fSJoseph Mingrone	| arth '*' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MUL, $1, $3))); }
8586f9cba8fSJoseph Mingrone	| arth '/' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_DIV, $1, $3))); }
8596f9cba8fSJoseph Mingrone	| arth '%' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MOD, $1, $3))); }
8606f9cba8fSJoseph Mingrone	| arth '&' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_AND, $1, $3))); }
8616f9cba8fSJoseph Mingrone	| arth '|' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_OR, $1, $3))); }
8626f9cba8fSJoseph Mingrone	| arth '^' arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_XOR, $1, $3))); }
8636f9cba8fSJoseph Mingrone	| arth LSH arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_LSH, $1, $3))); }
8646f9cba8fSJoseph Mingrone	| arth RSH arth			{ CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_RSH, $1, $3))); }
8656f9cba8fSJoseph Mingrone	| '-' arth %prec UMINUS		{ CHECK_PTR_VAL(($$ = gen_neg(cstate, $2))); }
8666f9cba8fSJoseph Mingrone	| paren narth ')'		{ $$ = $2; }
8676f9cba8fSJoseph Mingrone	| LEN				{ CHECK_PTR_VAL(($$ = gen_loadlen(cstate))); }
8686f9cba8fSJoseph Mingrone	;
8696f9cba8fSJoseph Mingronebyteop:	  '&'			{ $$ = '&'; }
8706f9cba8fSJoseph Mingrone	| '|'			{ $$ = '|'; }
8716f9cba8fSJoseph Mingrone	| '<'			{ $$ = '<'; }
8726f9cba8fSJoseph Mingrone	| '>'			{ $$ = '>'; }
8736f9cba8fSJoseph Mingrone	| '='			{ $$ = '='; }
8746f9cba8fSJoseph Mingrone	;
8756f9cba8fSJoseph Mingronepnum:	  NUM
8766f9cba8fSJoseph Mingrone	| paren pnum ')'	{ $$ = $2; }
8776f9cba8fSJoseph Mingrone	;
8786f9cba8fSJoseph Mingroneatmtype: LANE			{ $$ = A_LANE; }
8796f9cba8fSJoseph Mingrone	| METAC			{ $$ = A_METAC;	}
8806f9cba8fSJoseph Mingrone	| BCC			{ $$ = A_BCC; }
8816f9cba8fSJoseph Mingrone	| OAMF4EC		{ $$ = A_OAMF4EC; }
8826f9cba8fSJoseph Mingrone	| OAMF4SC		{ $$ = A_OAMF4SC; }
8836f9cba8fSJoseph Mingrone	| SC			{ $$ = A_SC; }
8846f9cba8fSJoseph Mingrone	| ILMIC			{ $$ = A_ILMIC; }
8856f9cba8fSJoseph Mingrone	;
8866f9cba8fSJoseph Mingroneatmmultitype: OAM		{ $$ = A_OAM; }
8876f9cba8fSJoseph Mingrone	| OAMF4			{ $$ = A_OAMF4; }
8886f9cba8fSJoseph Mingrone	| CONNECTMSG		{ $$ = A_CONNECTMSG; }
8896f9cba8fSJoseph Mingrone	| METACONNECT		{ $$ = A_METACONNECT; }
8906f9cba8fSJoseph Mingrone	;
8916f9cba8fSJoseph Mingrone	/* ATM field types quantifier */
8926f9cba8fSJoseph Mingroneatmfield: VPI			{ $$.atmfieldtype = A_VPI; }
8936f9cba8fSJoseph Mingrone	| VCI			{ $$.atmfieldtype = A_VCI; }
8946f9cba8fSJoseph Mingrone	;
8956f9cba8fSJoseph Mingroneatmvalue: atmfieldvalue
8966f9cba8fSJoseph Mingrone	| relop NUM		{ CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, $2, $1, 0))); }
8976f9cba8fSJoseph Mingrone	| irelop NUM		{ CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, $2, $1, 1))); }
8986f9cba8fSJoseph Mingrone	| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
8996f9cba8fSJoseph Mingrone	;
9006f9cba8fSJoseph Mingroneatmfieldvalue: NUM {
9016f9cba8fSJoseph Mingrone	$$.atmfieldtype = $<blk>0.atmfieldtype;
9026f9cba8fSJoseph Mingrone	if ($$.atmfieldtype == A_VPI ||
9036f9cba8fSJoseph Mingrone	    $$.atmfieldtype == A_VCI)
9046f9cba8fSJoseph Mingrone		CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, $1, BPF_JEQ, 0)));
9056f9cba8fSJoseph Mingrone	}
9066f9cba8fSJoseph Mingrone	;
9076f9cba8fSJoseph Mingroneatmlistvalue: atmfieldvalue
9086f9cba8fSJoseph Mingrone	| atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
9096f9cba8fSJoseph Mingrone	;
9106f9cba8fSJoseph Mingrone	/* MTP2 types quantifier */
9116f9cba8fSJoseph Mingronemtp2type: FISU			{ $$ = M_FISU; }
9126f9cba8fSJoseph Mingrone	| LSSU			{ $$ = M_LSSU; }
9136f9cba8fSJoseph Mingrone	| MSU			{ $$ = M_MSU; }
9146f9cba8fSJoseph Mingrone	| HFISU			{ $$ = MH_FISU; }
9156f9cba8fSJoseph Mingrone	| HLSSU			{ $$ = MH_LSSU; }
9166f9cba8fSJoseph Mingrone	| HMSU			{ $$ = MH_MSU; }
9176f9cba8fSJoseph Mingrone	;
9186f9cba8fSJoseph Mingrone	/* MTP3 field types quantifier */
9196f9cba8fSJoseph Mingronemtp3field: SIO			{ $$.mtp3fieldtype = M_SIO; }
9206f9cba8fSJoseph Mingrone	| OPC			{ $$.mtp3fieldtype = M_OPC; }
9216f9cba8fSJoseph Mingrone	| DPC			{ $$.mtp3fieldtype = M_DPC; }
9226f9cba8fSJoseph Mingrone	| SLS                   { $$.mtp3fieldtype = M_SLS; }
9236f9cba8fSJoseph Mingrone	| HSIO			{ $$.mtp3fieldtype = MH_SIO; }
9246f9cba8fSJoseph Mingrone	| HOPC			{ $$.mtp3fieldtype = MH_OPC; }
9256f9cba8fSJoseph Mingrone	| HDPC			{ $$.mtp3fieldtype = MH_DPC; }
9266f9cba8fSJoseph Mingrone	| HSLS                  { $$.mtp3fieldtype = MH_SLS; }
9276f9cba8fSJoseph Mingrone	;
9286f9cba8fSJoseph Mingronemtp3value: mtp3fieldvalue
9296f9cba8fSJoseph Mingrone	| relop NUM		{ CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, $2, $1, 0))); }
9306f9cba8fSJoseph Mingrone	| irelop NUM		{ CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, $2, $1, 1))); }
9316f9cba8fSJoseph Mingrone	| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
9326f9cba8fSJoseph Mingrone	;
9336f9cba8fSJoseph Mingronemtp3fieldvalue: NUM {
9346f9cba8fSJoseph Mingrone	$$.mtp3fieldtype = $<blk>0.mtp3fieldtype;
9356f9cba8fSJoseph Mingrone	if ($$.mtp3fieldtype == M_SIO ||
9366f9cba8fSJoseph Mingrone	    $$.mtp3fieldtype == M_OPC ||
9376f9cba8fSJoseph Mingrone	    $$.mtp3fieldtype == M_DPC ||
9386f9cba8fSJoseph Mingrone	    $$.mtp3fieldtype == M_SLS ||
9396f9cba8fSJoseph Mingrone	    $$.mtp3fieldtype == MH_SIO ||
9406f9cba8fSJoseph Mingrone	    $$.mtp3fieldtype == MH_OPC ||
9416f9cba8fSJoseph Mingrone	    $$.mtp3fieldtype == MH_DPC ||
9426f9cba8fSJoseph Mingrone	    $$.mtp3fieldtype == MH_SLS)
9436f9cba8fSJoseph Mingrone		CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, $1, BPF_JEQ, 0)));
9446f9cba8fSJoseph Mingrone	}
9456f9cba8fSJoseph Mingrone	;
9466f9cba8fSJoseph Mingronemtp3listvalue: mtp3fieldvalue
9476f9cba8fSJoseph Mingrone	| mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
9486f9cba8fSJoseph Mingrone	;
9496f9cba8fSJoseph Mingrone%%
950