ipf_y.y revision 170268
1161748Scperciva/*	$FreeBSD: head/contrib/ipfilter/tools/ipf_y.y 170268 2007-06-04 02:54:36Z darrenr $	*/
2161748Scperciva
3161748Scperciva/*
4173441Scperciva * Copyright (C) 2001-2006 by Darren Reed.
5161748Scperciva *
6161748Scperciva * See the IPFILTER.LICENCE file for details on licencing.
7161748Scperciva */
8161748Scperciva%{
9161748Scperciva#include "ipf.h"
10161748Scperciva#include <sys/ioctl.h>
11161748Scperciva#include <syslog.h>
12161748Scperciva#ifdef IPFILTER_BPF
13161748Scperciva# include "pcap-bpf.h"
14161748Scperciva# define _NET_BPF_H_
15161748Scperciva# include <pcap.h>
16161748Scperciva#endif
17161748Scperciva#include "netinet/ip_pool.h"
18161748Scperciva#include "netinet/ip_htable.h"
19161748Scperciva#include "netinet/ipl.h"
20161748Scperciva#include "ipf_l.h"
21161748Scperciva
22161748Scperciva#define	YYDEBUG	1
23161748Scperciva#define	DOALL(x)	for (fr = frc; fr != NULL; fr = fr->fr_next) { x }
24161748Scperciva#define	DOREM(x)	for (; fr != NULL; fr = fr->fr_next) { x }
25161748Scperciva
26161748Scpercivaextern	void	yyerror __P((char *));
27161748Scpercivaextern	int	yyparse __P((void));
28161748Scpercivaextern	int	yylex __P((void));
29161748Scpercivaextern	int	yydebug;
30161748Scpercivaextern	FILE	*yyin;
31161748Scpercivaextern	int	yylineNum;
32161748Scperciva
33161748Scpercivastatic	void	newrule __P((void));
34161748Scpercivastatic	void	setipftype __P((void));
35161748Scpercivastatic	u_32_t	lookuphost __P((char *));
36161748Scpercivastatic	void	dobpf __P((int, char *));
37161748Scpercivastatic	void	resetaddr __P((void));
38161748Scpercivastatic	struct	alist_s	*newalist __P((struct alist_s *));
39161748Scpercivastatic	u_int	makehash __P((struct alist_s *));
40161748Scpercivastatic	int	makepool __P((struct alist_s *));
41161748Scpercivastatic	frentry_t *addrule __P((void));
42161748Scpercivastatic	void	setsyslog __P((void));
43161748Scpercivastatic	void	unsetsyslog __P((void));
44161748Scpercivastatic	void	fillgroup __P((frentry_t *));
45161748Scperciva
46161748Scpercivafrentry_t	*fr = NULL, *frc = NULL, *frtop = NULL, *frold = NULL;
47173564Scperciva
48161748Scpercivastatic	int		ifpflag = 0;
49161748Scpercivastatic	int		nowith = 0;
50161748Scpercivastatic	int		dynamic = -1;
51161748Scpercivastatic	int		pooled = 0;
52161748Scpercivastatic	int		hashed = 0;
53161748Scpercivastatic	int		nrules = 0;
54161748Scpercivastatic	int		newlist = 0;
55161748Scpercivastatic	int		added = 0;
56173564Scpercivastatic	int		ipffd = -1;
57173564Scpercivastatic	int		*yycont = 0;
58161748Scpercivastatic	ioctlfunc_t	ipfioctl[IPL_LOGSIZE];
59181142Scpercivastatic	addfunc_t	ipfaddfunc = NULL;
60161748Scpercivastatic	struct	wordtab ipfwords[95];
61161748Scpercivastatic	struct	wordtab	addrwords[4];
62161748Scpercivastatic	struct	wordtab	maskwords[5];
63161748Scpercivastatic	struct	wordtab icmpcodewords[17];
64161748Scpercivastatic	struct	wordtab icmptypewords[16];
65161748Scpercivastatic	struct	wordtab ipv4optwords[25];
66161748Scpercivastatic	struct	wordtab ipv4secwords[9];
67161748Scpercivastatic	struct	wordtab ipv6optwords[9];
68161748Scpercivastatic	struct	wordtab logwords[33];
69161748Scperciva
70161748Scperciva%}
71161748Scperciva%union	{
72161748Scperciva	char	*str;
73161748Scperciva	u_32_t	num;
74161748Scperciva	struct	in_addr	ipa;
75161748Scperciva	frentry_t	fr;
76161748Scperciva	frtuc_t	*frt;
77161748Scperciva	struct	alist_s	*alist;
78161748Scperciva	u_short	port;
79161748Scperciva	struct	{
80161748Scperciva		u_short	p1;
81161748Scperciva		u_short	p2;
82161748Scperciva		int	pc;
83161748Scperciva	} pc;
84161748Scperciva	struct	{
85161748Scperciva		union	i6addr	a;
86161748Scperciva		union	i6addr	m;
87161748Scperciva	} ipp;
88161748Scperciva	union	i6addr	ip6;
89161748Scperciva	struct	{
90181142Scperciva		char	*if1;
91196392Ssimon		char	*if2;
92161748Scperciva	} ifs;
93161748Scperciva};
94161748Scperciva
95161748Scperciva%type	<port>	portnum
96161748Scperciva%type	<num>	facility priority icmpcode seclevel secname icmptype
97161748Scperciva%type	<num>	opt compare range opttype flagset optlist ipv6hdrlist ipv6hdr
98161748Scperciva%type	<num>	portc porteq
99161748Scperciva%type	<ipa>	hostname ipv4 ipv4mask ipv4_16 ipv4_24
100161748Scperciva%type	<ip6>	ipv6mask
101161748Scperciva%type	<ipp>	addr ipaddr
102161748Scperciva%type	<str>	servicename name interfacename
103161748Scperciva%type	<pc>	portrange portcomp
104161748Scperciva%type	<alist>	addrlist poollist
105161748Scperciva%type	<ifs>	onname
106161748Scperciva
107161748Scperciva%token	<num>	YY_NUMBER YY_HEX
108161748Scperciva%token	<str>	YY_STR
109161748Scperciva%token		YY_COMMENT
110161748Scperciva%token		YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
111161748Scperciva%token		YY_RANGE_OUT YY_RANGE_IN
112161748Scperciva%token	<ip6>	YY_IPV6
113161748Scperciva
114161748Scperciva%token	IPFY_PASS IPFY_BLOCK IPFY_COUNT IPFY_CALL IPFY_NOMATCH
115161748Scperciva%token	IPFY_RETICMP IPFY_RETRST IPFY_RETICMPASDST
116161748Scperciva%token	IPFY_IN IPFY_OUT
117161748Scperciva%token	IPFY_QUICK IPFY_ON IPFY_OUTVIA IPFY_INVIA
118161748Scperciva%token	IPFY_DUPTO IPFY_TO IPFY_FROUTE IPFY_REPLY_TO IPFY_ROUTETO
119161748Scperciva%token	IPFY_TOS IPFY_TTL IPFY_PROTO
120161748Scperciva%token	IPFY_HEAD IPFY_GROUP
121161748Scperciva%token	IPFY_AUTH IPFY_PREAUTH
122161748Scperciva%token	IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK
123161748Scperciva%token	IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP
124161748Scperciva%token	IPFY_FROM IPFY_ALL IPFY_ANY IPFY_BPFV4 IPFY_BPFV6 IPFY_POOL IPFY_HASH
125161748Scperciva%token	IPFY_PPS
126161748Scperciva%token	IPFY_ESP IPFY_AH
127161748Scperciva%token	IPFY_WITH IPFY_AND IPFY_NOT IPFY_NO IPFY_OPT
128161748Scperciva%token	IPFY_TCPUDP IPFY_TCP IPFY_UDP
129161748Scperciva%token	IPFY_FLAGS IPFY_MULTICAST
130161748Scperciva%token	IPFY_MASK IPFY_BROADCAST IPFY_NETWORK IPFY_NETMASKED IPFY_PEER
131161748Scperciva%token	IPFY_PORT
132161748Scperciva%token	IPFY_NOW
133161748Scperciva%token	IPFY_ICMP IPFY_ICMPTYPE IPFY_ICMPCODE
134161748Scperciva%token	IPFY_IPOPTS IPFY_SHORT IPFY_NAT IPFY_BADSRC IPFY_LOWTTL IPFY_FRAG
135161748Scperciva%token	IPFY_MBCAST IPFY_BAD IPFY_BADNAT IPFY_OOW IPFY_NEWISN IPFY_NOICMPERR
136161748Scperciva%token	IPFY_KEEP IPFY_STATE IPFY_FRAGS IPFY_LIMIT IPFY_STRICT IPFY_AGE
137161748Scperciva%token	IPFY_SYNC IPFY_FRAGBODY
138161748Scperciva%token	IPFY_IPOPT_NOP IPFY_IPOPT_RR IPFY_IPOPT_ZSU IPFY_IPOPT_MTUP
139161748Scperciva%token	IPFY_IPOPT_MTUR IPFY_IPOPT_ENCODE IPFY_IPOPT_TS IPFY_IPOPT_TR
140161748Scperciva%token	IPFY_IPOPT_SEC IPFY_IPOPT_LSRR IPFY_IPOPT_ESEC IPFY_IPOPT_CIPSO
141161748Scperciva%token	IPFY_IPOPT_SATID IPFY_IPOPT_SSRR IPFY_IPOPT_ADDEXT IPFY_IPOPT_VISA
142161748Scperciva%token	IPFY_IPOPT_IMITD IPFY_IPOPT_EIP IPFY_IPOPT_FINN IPFY_IPOPT_DPS
143161748Scperciva%token	IPFY_IPOPT_SDB IPFY_IPOPT_NSAPA IPFY_IPOPT_RTRALRT IPFY_IPOPT_UMP
144161748Scperciva%token	IPFY_SECCLASS IPFY_SEC_UNC IPFY_SEC_CONF IPFY_SEC_RSV1 IPFY_SEC_RSV2
145161748Scperciva%token	IPFY_SEC_RSV4 IPFY_SEC_SEC IPFY_SEC_TS IPFY_SEC_RSV3
146161748Scperciva
147161748Scperciva%token	IPF6_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS
148161748Scperciva%token	IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING
149161748Scperciva%token	IPFY_IPV6OPT_MOBILITY IPFY_IPV6OPT_ESP IPFY_IPV6OPT_FRAG
150161748Scperciva
151161748Scperciva%token	IPFY_ICMPT_UNR IPFY_ICMPT_ECHO IPFY_ICMPT_ECHOR IPFY_ICMPT_SQUENCH
152161748Scperciva%token	IPFY_ICMPT_REDIR IPFY_ICMPT_TIMEX IPFY_ICMPT_PARAMP IPFY_ICMPT_TIMEST
153161748Scperciva%token	IPFY_ICMPT_TIMESTREP IPFY_ICMPT_INFOREQ IPFY_ICMPT_INFOREP
154161748Scperciva%token	IPFY_ICMPT_MASKREQ IPFY_ICMPT_MASKREP IPFY_ICMPT_ROUTERAD
155161748Scperciva%token	IPFY_ICMPT_ROUTERSOL
156161748Scperciva
157161748Scperciva%token	IPFY_ICMPC_NETUNR IPFY_ICMPC_HSTUNR IPFY_ICMPC_PROUNR IPFY_ICMPC_PORUNR
158161748Scperciva%token	IPFY_ICMPC_NEEDF IPFY_ICMPC_SRCFAIL IPFY_ICMPC_NETUNK IPFY_ICMPC_HSTUNK
159161748Scperciva%token	IPFY_ICMPC_ISOLATE IPFY_ICMPC_NETPRO IPFY_ICMPC_HSTPRO
160161748Scperciva%token	IPFY_ICMPC_NETTOS IPFY_ICMPC_HSTTOS IPFY_ICMPC_FLTPRO IPFY_ICMPC_HSTPRE
161161748Scperciva%token	IPFY_ICMPC_CUTPRE
162161748Scperciva
163161748Scperciva%token	IPFY_FAC_KERN IPFY_FAC_USER IPFY_FAC_MAIL IPFY_FAC_DAEMON IPFY_FAC_AUTH
164161748Scperciva%token	IPFY_FAC_SYSLOG IPFY_FAC_LPR IPFY_FAC_NEWS IPFY_FAC_UUCP IPFY_FAC_CRON
165161748Scperciva%token	IPFY_FAC_LOCAL0 IPFY_FAC_LOCAL1 IPFY_FAC_LOCAL2 IPFY_FAC_LOCAL3
166161748Scperciva%token	IPFY_FAC_LOCAL4 IPFY_FAC_LOCAL5 IPFY_FAC_LOCAL6 IPFY_FAC_LOCAL7
167161748Scperciva%token	IPFY_FAC_SECURITY IPFY_FAC_FTP IPFY_FAC_AUTHPRIV IPFY_FAC_AUDIT
168161748Scperciva%token	IPFY_FAC_LFMT IPFY_FAC_CONSOLE
169161748Scperciva
170161748Scperciva%token	IPFY_PRI_EMERG IPFY_PRI_ALERT IPFY_PRI_CRIT IPFY_PRI_ERR IPFY_PRI_WARN
171161748Scperciva%token	IPFY_PRI_NOTICE IPFY_PRI_INFO IPFY_PRI_DEBUG
172161748Scperciva%%
173161748Scpercivafile:	line
174161748Scperciva	| assign
175161748Scperciva	| file line
176161748Scperciva	| file assign
177161748Scperciva	;
178161748Scperciva
179161748Scpercivaline:	rule		{ while ((fr = frtop) != NULL) {
180161748Scperciva				frtop = fr->fr_next;
181161748Scperciva				fr->fr_next = NULL;
182161748Scperciva				(*ipfaddfunc)(ipffd, ipfioctl[IPL_LOGIPF], fr);
183161748Scperciva				fr->fr_next = frold;
184161748Scperciva				frold = fr;
185161748Scperciva			  }
186161748Scperciva			  resetlexer();
187161748Scperciva			}
188161748Scperciva	| YY_COMMENT
189161748Scperciva	;
190161748Scperciva
191161748Scpercivaxx:					{ newrule(); }
192161748Scperciva	;
193161748Scperciva
194161748Scpercivaassign:	YY_STR assigning YY_STR ';'	{ set_variable($1, $3);
195161748Scperciva					  resetlexer();
196161748Scperciva					  free($1);
197161748Scperciva					  free($3);
198161748Scperciva					  yyvarnext = 0;
199161748Scperciva					}
200161748Scperciva	;
201161748Scperciva
202161748Scpercivaassigning:
203161748Scperciva	'='				{ yyvarnext = 1; }
204161748Scperciva	;
205161748Scperciva
206161748Scpercivarule:	inrule eol
207161748Scperciva	| outrule eol
208161748Scperciva	;
209161748Scperciva
210161748Scpercivaeol:	| ';'
211161748Scperciva	;
212161748Scperciva
213161748Scpercivainrule:
214161748Scperciva	rulehead markin inopts rulemain ruletail intag ruletail2
215161748Scperciva	;
216161748Scperciva
217161748Scpercivaoutrule:
218161748Scperciva	rulehead markout outopts rulemain ruletail outtag ruletail2
219161748Scperciva	;
220161748Scperciva
221161748Scpercivarulehead:
222161748Scperciva	xx collection action
223161748Scperciva	| xx insert collection action
224161748Scperciva	;
225161748Scperciva
226161748Scpercivamarkin:	IPFY_IN				{ fr->fr_flags |= FR_INQUE; }
227181142Scperciva	;
228181142Scperciva
229181142Scpercivamarkout:
230181142Scperciva	IPFY_OUT			{ fr->fr_flags |= FR_OUTQUE; }
231181142Scperciva	;
232181142Scperciva
233181142Scpercivarulemain:
234161748Scperciva	ipfrule
235161748Scperciva	| bpfrule
236161748Scperciva	;
237161748Scperciva
238161748Scpercivaipfrule:
239161748Scperciva	tos ttl proto ip
240161748Scperciva	;
241161748Scperciva
242173564Scpercivabpfrule:
243173564Scperciva	IPFY_BPFV4 '{' YY_STR '}' 	{ dobpf(4, $3); free($3); }
244173564Scperciva	| IPFY_BPFV6 '{' YY_STR '}' 	{ dobpf(6, $3); free($3); }
245173564Scperciva	;
246173564Scperciva
247173564Scpercivaruletail:
248173564Scperciva	with keep head group
249173564Scperciva	;
250161748Scperciva
251161748Scpercivaruletail2:
252161748Scperciva	pps age new
253161748Scperciva	;
254161748Scperciva
255161748Scpercivaintag:	settagin matchtagin
256161748Scperciva	;
257161748Scperciva
258161748Scpercivaouttag:	settagout matchtagout
259173564Scperciva	;
260173564Scperciva
261173564Scpercivainsert:
262173564Scperciva	'@' YY_NUMBER			{ fr->fr_hits = (U_QUAD_T)$2 + 1; }
263173564Scperciva	;
264173564Scperciva
265173564Scpercivacollection:
266173564Scperciva	| YY_NUMBER			{ fr->fr_collect = $1; }
267173564Scperciva	;
268173564Scperciva
269173564Scpercivaaction:	block
270173564Scperciva	| IPFY_PASS			{ fr->fr_flags |= FR_PASS; }
271173564Scperciva	| IPFY_NOMATCH			{ fr->fr_flags |= FR_NOMATCH; }
272173564Scperciva	| log
273173564Scperciva	| IPFY_COUNT			{ fr->fr_flags |= FR_ACCOUNT; }
274173564Scperciva	| auth
275173564Scperciva	| IPFY_SKIP YY_NUMBER		{ fr->fr_flags |= FR_SKIP;
276173564Scperciva					  fr->fr_arg = $2; }
277173564Scperciva	| IPFY_CALL func
278173564Scperciva	| IPFY_CALL IPFY_NOW func	{ fr->fr_flags |= FR_CALLNOW; }
279173564Scperciva	;
280173564Scperciva
281173564Scpercivablock:	blocked
282173564Scperciva	| blocked blockreturn
283173564Scperciva	;
284173564Scperciva
285173564Scpercivablocked:
286173564Scperciva	IPFY_BLOCK			{ fr->fr_flags = FR_BLOCK; }
287197618Scperciva	;
288197618Scpercivablockreturn:
289197618Scperciva	IPFY_RETICMP			{ fr->fr_flags |= FR_RETICMP; }
290173564Scperciva	| IPFY_RETICMP returncode	{ fr->fr_flags |= FR_RETICMP; }
291173564Scperciva	| IPFY_RETICMPASDST		{ fr->fr_flags |= FR_FAKEICMP; }
292161748Scperciva	| IPFY_RETICMPASDST returncode	{ fr->fr_flags |= FR_FAKEICMP; }
293161748Scperciva	| IPFY_RETRST			{ fr->fr_flags |= FR_RETRST; }
294161748Scperciva	;
295161748Scperciva
296161748Scpercivalog:	IPFY_LOG			{ fr->fr_flags |= FR_LOG; }
297161748Scperciva	| IPFY_LOG logoptions		{ fr->fr_flags |= FR_LOG; }
298161748Scperciva	;
299161748Scperciva
300161748Scpercivaauth:	IPFY_AUTH			{ fr->fr_flags |= FR_AUTH; }
301161748Scperciva	| IPFY_AUTH blockreturn		{ fr->fr_flags |= FR_AUTH;}
302161748Scperciva	| IPFY_PREAUTH			{ fr->fr_flags |= FR_PREAUTH; }
303161748Scperciva	;
304161748Scperciva
305161748Scpercivafunc:	YY_STR '/' YY_NUMBER	{ fr->fr_func = nametokva($1,
306161748Scperciva							  ipfioctl[IPL_LOGIPF]);
307161748Scperciva				  fr->fr_arg = $3;
308161748Scperciva				  free($1); }
309161748Scperciva	;
310161748Scperciva
311161748Scpercivainopts:
312161748Scperciva	| inopts inopt
313161748Scperciva	;
314196392Ssimon
315196392Ssimoninopt:
316196392Ssimon	logopt
317196392Ssimon	| quick
318196392Ssimon	| on
319196392Ssimon	| dup
320196392Ssimon	| froute
321196392Ssimon	| proute
322196392Ssimon	| replyto
323196392Ssimon	;
324196392Ssimon
325196392Ssimonoutopts:
326196392Ssimon	| outopts outopt
327196392Ssimon	;
328196392Ssimon
329196392Ssimonoutopt:
330196392Ssimon	logopt
331196392Ssimon	| quick
332196392Ssimon	| on
333196392Ssimon	| dup
334196392Ssimon	| proute
335196392Ssimon	| replyto
336196392Ssimon	;
337196392Ssimon
338196392Ssimontos:	| settos YY_NUMBER	{ DOALL(fr->fr_tos = $2; fr->fr_mtos = 0xff;) }
339196392Ssimon	| settos YY_HEX	{ DOALL(fr->fr_tos = $2; fr->fr_mtos = 0xff;) }
340196392Ssimon	| settos lstart toslist lend
341196392Ssimon	;
342196392Ssimon
343196392Ssimonsettos:	IPFY_TOS			{ setipftype(); }
344196392Ssimon	;
345196392Ssimon
346196392Ssimontoslist:
347196392Ssimon	YY_NUMBER	{ DOALL(fr->fr_tos = $1; fr->fr_mtos = 0xff;) }
348196392Ssimon	| YY_HEX	{ DOREM(fr->fr_tos = $1; fr->fr_mtos = 0xff;) }
349196392Ssimon	| toslist lmore YY_NUMBER
350196392Ssimon			{ DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) }
351196392Ssimon	| toslist lmore YY_HEX
352196392Ssimon			{ DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) }
353196392Ssimon	;
354196392Ssimon
355196392Ssimonttl:	| setttl YY_NUMBER
356196392Ssimon			{ DOALL(fr->fr_ttl = $2; fr->fr_mttl = 0xff;) }
357196392Ssimon	| setttl lstart ttllist lend
358196392Ssimon	;
359196392Ssimon
360196392Ssimonlstart:	'('				{ newlist = 1; fr = frc; added = 0; }
361196392Ssimon	;
362196392Ssimon
363196392Ssimonlend:	')'				{ nrules += added; }
364196392Ssimon	;
365196392Ssimon
366196392Ssimonlmore:	lanother			{ if (newlist == 1) {
367196392Ssimon						newlist = 0;
368196392Ssimon					  }
369196392Ssimon					  fr = addrule();
370196392Ssimon					  if (yycont != NULL)
371196392Ssimon						*yycont = 1;
372196392Ssimon					}
373196392Ssimon	;
374196392Ssimon
375196392Ssimonlanother:
376196392Ssimon	| ','
377196392Ssimon	;
378161748Scperciva
379161748Scpercivasetttl:	IPFY_TTL			{ setipftype(); }
380161748Scperciva	;
381161748Scperciva
382161748Scpercivattllist:
383161748Scperciva	YY_NUMBER	{ DOREM(fr->fr_ttl = $1; fr->fr_mttl = 0xff;) }
384161748Scperciva	| ttllist lmore YY_NUMBER
385161748Scperciva			{ DOREM(fr->fr_ttl = $3; fr->fr_mttl = 0xff;) }
386161748Scperciva	;
387161748Scperciva
388161748Scpercivaproto:	| protox protocol		{ yyresetdict(); }
389161748Scperciva	;
390161748Scperciva
391161748Scpercivaprotox:	IPFY_PROTO			{ setipftype();
392161748Scperciva					  fr = frc;
393161748Scperciva					  yysetdict(NULL); }
394161748Scperciva	;
395161748Scperciva
396161748Scpercivaip:	srcdst flags icmp
397161748Scperciva	;
398161748Scperciva
399161748Scpercivagroup:	| IPFY_GROUP YY_STR		{ DOALL(strncpy(fr->fr_group, $2, \
400161748Scperciva							FR_GROUPLEN); \
401161748Scperciva							fillgroup(fr););
402161748Scperciva					  free($2); }
403161748Scperciva	| IPFY_GROUP YY_NUMBER		{ DOALL(sprintf(fr->fr_group, "%d", \
404161748Scperciva							$2); \
405161748Scperciva							fillgroup(fr);) }
406161748Scperciva	;
407161748Scperciva
408161748Scpercivahead:	| IPFY_HEAD YY_STR		{ DOALL(strncpy(fr->fr_grhead, $2, \
409161748Scperciva							FR_GROUPLEN););
410161748Scperciva					  free($2); }
411161748Scperciva	| IPFY_HEAD YY_NUMBER		{ DOALL(sprintf(fr->fr_grhead, "%d", \
412161748Scperciva							$2);) }
413161748Scperciva	;
414161748Scperciva
415161748Scpercivasettagin:
416161748Scperciva	| IPFY_SETTAG '(' taginlist ')'
417161748Scperciva	;
418161748Scperciva
419161748Scpercivataginlist:
420161748Scperciva	taginspec
421161748Scperciva	| taginlist ',' taginspec
422161748Scperciva	;
423161748Scperciva
424161748Scpercivataginspec:
425161748Scperciva	logtag
426161748Scperciva	;
427161748Scperciva
428161748Scpercivanattag:	IPFY_NAT '=' YY_STR		{ DOALL(strncpy(fr->fr_nattag.ipt_tag,\
429161748Scperciva						$3, IPFTAG_LEN););
430161748Scperciva					  free($3); }
431161748Scperciva	| IPFY_NAT '=' YY_NUMBER	{ DOALL(sprintf(fr->fr_nattag.ipt_tag,\
432173564Scperciva						"%d", $3 & 0xffffffff);) }
433173564Scperciva	;
434173564Scperciva
435173564Scpercivalogtag:	IPFY_LOG '=' YY_NUMBER		{ DOALL(fr->fr_logtag = $3;) }
436161748Scperciva	;
437161748Scperciva
438161748Scpercivasettagout:
439161748Scperciva	| IPFY_SETTAG '(' tagoutlist ')'
440161748Scperciva	;
441161748Scperciva
442161748Scpercivatagoutlist:
443161748Scperciva	tagoutspec
444161748Scperciva	| tagoutlist ',' tagoutspec
445161748Scperciva	;
446161748Scperciva
447161748Scpercivatagoutspec:
448161748Scperciva	logtag
449161748Scperciva	| nattag
450161748Scperciva	;
451161748Scperciva
452161748Scpercivamatchtagin:
453161748Scperciva	| IPFY_MATCHTAG '(' tagoutlist ')'
454181142Scperciva	;
455161748Scperciva
456161748Scpercivamatchtagout:
457161748Scperciva	| IPFY_MATCHTAG '(' taginlist ')'
458161748Scperciva	;
459161748Scperciva
460161748Scpercivapps:	| IPFY_PPS YY_NUMBER		{ DOALL(fr->fr_pps = $2;) }
461161748Scperciva	;
462161748Scperciva
463161748Scpercivanew:	| savegroup file restoregroup
464161748Scperciva	;
465161748Scperciva
466161748Scpercivasavegroup:
467161748Scperciva	'{'
468161748Scperciva	;
469161748Scperciva
470161748Scpercivarestoregroup:
471161748Scperciva	'}'
472161748Scperciva	;
473161748Scperciva
474161748Scpercivalogopt:	log
475161748Scperciva	;
476161748Scperciva
477161748Scpercivaquick:
478161748Scperciva	IPFY_QUICK			{ fr->fr_flags |= FR_QUICK; }
479161748Scperciva	;
480161748Scperciva
481161748Scpercivaon:	IPFY_ON onname
482161748Scperciva	| IPFY_ON lstart onlist lend
483161748Scperciva	| IPFY_ON onname IPFY_INVIA vianame
484161748Scperciva	| IPFY_ON onname IPFY_OUTVIA vianame
485161748Scperciva	;
486161748Scperciva
487161748Scpercivaonlist:	onname			{ DOREM(strncpy(fr->fr_ifnames[0], $1.if1, \
488161748Scperciva					sizeof(fr->fr_ifnames[0])); 	   \
489161748Scperciva					if ($1.if2 != NULL) {		   \
490161748Scperciva						strncpy(fr->fr_ifnames[1], \
491161748Scperciva							$1.if2,		   \
492161748Scperciva						sizeof(fr->fr_ifnames[1]));\
493161748Scperciva					}				   \
494161748Scperciva					) }
495161748Scperciva	| onlist lmore onname	{ DOREM(strncpy(fr->fr_ifnames[0], $3.if1, \
496161748Scperciva					sizeof(fr->fr_ifnames[0])); 	   \
497161748Scperciva					if ($3.if2 != NULL) {		   \
498161748Scperciva						strncpy(fr->fr_ifnames[1], \
499161748Scperciva							$3.if2,		   \
500161748Scperciva						sizeof(fr->fr_ifnames[1]));\
501161748Scperciva					}				   \
502161748Scperciva					) }
503161748Scperciva	;
504161748Scperciva
505161748Scpercivaonname:	interfacename
506161748Scperciva		{ strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0]));
507161748Scperciva		  $$.if1 = fr->fr_ifnames[0];
508161748Scperciva		  $$.if2 = NULL;
509161748Scperciva		  free($1);
510161748Scperciva		}
511161748Scperciva	| interfacename ',' interfacename
512161748Scperciva		{ strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0]));
513161748Scperciva		  $$.if1 = fr->fr_ifnames[0];
514161748Scperciva		  free($1);
515161748Scperciva		  strncpy(fr->fr_ifnames[1], $3, sizeof(fr->fr_ifnames[1]));
516161748Scperciva		  $$.if1 = fr->fr_ifnames[1];
517161748Scperciva		  free($3);
518161748Scperciva		}
519161748Scperciva	;
520161748Scperciva
521161748Scpercivavianame:
522161748Scperciva	name
523161748Scperciva		{ strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2]));
524161748Scperciva		  free($1);
525161748Scperciva		}
526161748Scperciva	| name ',' name
527161748Scperciva		{ strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2]));
528161748Scperciva		  free($1);
529161748Scperciva		  strncpy(fr->fr_ifnames[3], $3, sizeof(fr->fr_ifnames[3]));
530173564Scperciva		  free($3);
531196392Ssimon		}
532196392Ssimon	;
533196392Ssimon
534161748Scpercivadup:	IPFY_DUPTO name
535161748Scperciva	{ strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
536161748Scperciva	  free($2);
537161748Scperciva	}
538161748Scperciva	| IPFY_DUPTO name duptoseparator hostname
539161748Scperciva	{ strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
540161748Scperciva	  fr->fr_dif.fd_ip = $4;
541161748Scperciva	  yyexpectaddr = 0;
542161748Scperciva	  free($2);
543161748Scperciva	}
544161748Scperciva	| IPFY_DUPTO name duptoseparator YY_IPV6
545161748Scperciva	{ strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
546161748Scperciva	  bcopy(&$4, &fr->fr_dif.fd_ip6, sizeof(fr->fr_dif.fd_ip6));
547161748Scperciva	  yyexpectaddr = 0;
548161748Scperciva	  free($2);
549161748Scperciva	}
550161748Scperciva	;
551161748Scperciva
552161748Scpercivaduptoseparator:
553161748Scperciva	':'	{ yyexpectaddr = 1; yycont = &yyexpectaddr; resetaddr(); }
554161748Scperciva	;
555161748Scperciva
556161748Scpercivafroute:	IPFY_FROUTE			{ fr->fr_flags |= FR_FASTROUTE; }
557161748Scperciva	;
558161748Scperciva
559161748Scpercivaproute:	routeto name
560161748Scperciva	{ strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
561161748Scperciva	  free($2);
562161748Scperciva	}
563161748Scperciva	| routeto name duptoseparator hostname
564161748Scperciva	{ strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
565161748Scperciva	  fr->fr_tif.fd_ip = $4;
566161748Scperciva	  yyexpectaddr = 0;
567161748Scperciva	  free($2);
568161748Scperciva	}
569161748Scperciva	| routeto name duptoseparator YY_IPV6
570161748Scperciva	{ strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
571161748Scperciva	  bcopy(&$4, &fr->fr_tif.fd_ip6, sizeof(fr->fr_tif.fd_ip6));
572161748Scperciva	  yyexpectaddr = 0;
573161748Scperciva	  free($2);
574161748Scperciva	}
575212434Scperciva	;
576161748Scperciva
577161748Scpercivarouteto:
578161748Scperciva	IPFY_TO
579161748Scperciva	| IPFY_ROUTETO
580161748Scperciva	;
581161748Scperciva
582161748Scpercivareplyto:
583161748Scperciva	IPFY_REPLY_TO name
584161748Scperciva	{ strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname));
585161748Scperciva	  free($2);
586161748Scperciva	}
587161748Scperciva	| IPFY_REPLY_TO name duptoseparator hostname
588161748Scperciva	{ strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname));
589161748Scperciva	  fr->fr_rif.fd_ip = $4;
590161748Scperciva	  free($2);
591161748Scperciva	}
592161748Scperciva	;
593161748Scperciva
594161748Scpercivalogoptions:
595161748Scperciva	logoption
596161748Scperciva	| logoptions logoption
597161748Scperciva	;
598161748Scperciva
599161748Scpercivalogoption:
600161748Scperciva	IPFY_BODY			{ fr->fr_flags |= FR_LOGBODY; }
601161748Scperciva	| IPFY_FIRST			{ fr->fr_flags |= FR_LOGFIRST; }
602161748Scperciva	| IPFY_ORBLOCK			{ fr->fr_flags |= FR_LOGORBLOCK; }
603161748Scperciva	| level loglevel		{ unsetsyslog(); }
604161748Scperciva	;
605161748Scperciva
606200054Scpercivareturncode:
607161748Scperciva	starticmpcode icmpcode ')'	{ fr->fr_icode = $2; yyresetdict(); }
608161748Scperciva	;
609161748Scperciva
610161748Scpercivastarticmpcode:
611161748Scperciva	'('				{ yysetdict(icmpcodewords); }
612161748Scperciva	;
613161748Scperciva
614161748Scpercivasrcdst:	| IPFY_ALL
615161748Scperciva	| fromto
616161748Scperciva	;
617161748Scperciva
618173564Scpercivaprotocol:
619161748Scperciva	YY_NUMBER		{ DOREM(fr->fr_proto = $1; \
620161748Scperciva					fr->fr_mproto = 0xff;) }
621161748Scperciva	| YY_STR		{ if (!strcmp($1, "tcp-udp")) {
622161748Scperciva					DOREM(fr->fr_flx |= FI_TCPUDP; \
623161748Scperciva					      fr->fr_mflx |= FI_TCPUDP;)
624161748Scperciva				  } else {
625161748Scperciva					int p = getproto($1);
626161748Scperciva					if (p == -1)
627161748Scperciva						yyerror("protocol unknown");
628167189Scperciva					DOREM(fr->fr_proto = p; \
629167189Scperciva						fr->fr_mproto = 0xff;)
630167189Scperciva				  }
631167189Scperciva				  free($1);
632167189Scperciva					}
633167189Scperciva	| YY_STR nextstring YY_STR
634167189Scperciva				{ if (!strcmp($1, "tcp") &&
635167189Scperciva				      !strcmp($3, "udp")) {
636167189Scperciva					DOREM(fr->fr_flx |= FI_TCPUDP; \
637167189Scperciva					      fr->fr_mflx |= FI_TCPUDP;)
638167189Scperciva				  } else
639167189Scperciva					YYERROR;
640167189Scperciva				  free($1);
641167189Scperciva				  free($3);
642167189Scperciva				}
643167189Scperciva	;
644167189Scperciva
645167189Scpercivanextstring:
646161748Scperciva	'/'			{ yysetdict(NULL); }
647161748Scperciva	;
648161748Scperciva
649161748Scpercivafromto:	from srcobject to dstobject	{ yyexpectaddr = 0; yycont = NULL; }
650161748Scperciva	| to dstobject			{ yyexpectaddr = 0; yycont = NULL; }
651161748Scperciva	| from srcobject		{ yyexpectaddr = 0; yycont = NULL; }
652161748Scperciva	;
653161748Scperciva
654161748Scpercivafrom:	IPFY_FROM			{ setipftype();
655161748Scperciva					  if (fr == NULL)
656161748Scperciva						fr = frc;
657161748Scperciva					  yyexpectaddr = 1;
658212434Scperciva					  if (yydebug)
659212434Scperciva						printf("set yyexpectaddr\n");
660212434Scperciva					  yycont = &yyexpectaddr;
661212434Scperciva					  yysetdict(addrwords);
662212434Scperciva					  resetaddr(); }
663212434Scperciva	;
664212434Scperciva
665212434Scpercivato:	IPFY_TO				{ if (fr == NULL)
666212434Scperciva						fr = frc;
667212434Scperciva					  yyexpectaddr = 1;
668212434Scperciva					  if (yydebug)
669212434Scperciva						printf("set yyexpectaddr\n");
670173564Scperciva					  yycont = &yyexpectaddr;
671173564Scperciva					  yysetdict(addrwords);
672212434Scperciva					  resetaddr(); }
673173564Scperciva	;
674173564Scperciva
675173564Scpercivawith:	| andwith withlist
676173564Scperciva	;
677173564Scperciva
678173564Scpercivaandwith:
679173564Scperciva	IPFY_WITH			{ nowith = 0; setipftype(); }
680173564Scperciva	| IPFY_AND			{ nowith = 0; setipftype(); }
681173564Scperciva	;
682173564Scperciva
683173564Scpercivaflags:	| startflags flagset
684173564Scperciva		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) }
685173564Scperciva	| startflags flagset '/' flagset
686173564Scperciva		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
687173564Scperciva	| startflags '/' flagset
688173564Scperciva		{ DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) }
689173564Scperciva	| startflags YY_NUMBER
690173564Scperciva		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) }
691173564Scperciva	| startflags '/' YY_NUMBER
692173564Scperciva		{ DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) }
693173564Scperciva	| startflags YY_NUMBER '/' YY_NUMBER
694173564Scperciva		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
695173564Scperciva	| startflags flagset '/' YY_NUMBER
696173564Scperciva		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
697173564Scperciva	| startflags YY_NUMBER '/' flagset
698173564Scperciva		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
699173564Scperciva	;
700173564Scperciva
701173564Scpercivastartflags:
702173564Scperciva	IPFY_FLAGS	{ if (frc->fr_type != FR_T_IPF)
703173564Scperciva				yyerror("flags with non-ipf type rule");
704173564Scperciva			  if (frc->fr_proto != IPPROTO_TCP)
705173564Scperciva				yyerror("flags with non-TCP rule");
706173564Scperciva			}
707173564Scperciva	;
708173564Scperciva
709173564Scpercivaflagset:
710161748Scperciva	YY_STR				{ $$ = tcpflags($1); free($1); }
711161748Scperciva	| YY_HEX			{ $$ = $1; }
712161748Scperciva	;
713161748Scperciva
714161748Scpercivasrcobject:
715161748Scperciva	{ yyresetdict(); } fromport
716161748Scperciva	| srcaddr srcport
717161748Scperciva	| '!' srcaddr srcport
718161748Scperciva		{ DOALL(fr->fr_flags |= FR_NOTSRCIP;) }
719173441Scperciva	;
720173441Scperciva
721173441Scpercivasrcaddr:
722173441Scperciva	addr	{ DOREM(bcopy(&($1.a), &fr->fr_ip.fi_src, sizeof($1.a)); \
723173441Scperciva			bcopy(&($1.m), &fr->fr_mip.fi_src, sizeof($1.m)); \
724173441Scperciva			if (dynamic != -1) { \
725173441Scperciva				fr->fr_satype = ifpflag; \
726161748Scperciva				fr->fr_ipf->fri_sifpidx = dynamic; \
727161748Scperciva			} else if (pooled || hashed) \
728161748Scperciva				fr->fr_satype = FRI_LOOKUP;)
729161748Scperciva		}
730161748Scperciva	| lstart srcaddrlist lend
731161748Scperciva	;
732161748Scperciva
733161748Scpercivasrcaddrlist:
734161748Scperciva	addr	{ DOREM(bcopy(&($1.a), &fr->fr_ip.fi_src, sizeof($1.a)); \
735161748Scperciva			bcopy(&($1.m), &fr->fr_mip.fi_src, sizeof($1.m)); \
736161748Scperciva			if (dynamic != -1) { \
737161748Scperciva				fr->fr_satype = ifpflag; \
738161748Scperciva				fr->fr_ipf->fri_sifpidx = dynamic; \
739161748Scperciva			} else if (pooled || hashed) \
740161748Scperciva				fr->fr_satype = FRI_LOOKUP;)
741161748Scperciva		}
742161748Scperciva	| srcaddrlist lmore addr
743161748Scperciva		{ DOREM(bcopy(&($3.a), &fr->fr_ip.fi_src, sizeof($3.a)); \
744161748Scperciva			bcopy(&($3.m), &fr->fr_mip.fi_src, sizeof($3.m)); \
745161748Scperciva			if (dynamic != -1) { \
746161748Scperciva				fr->fr_satype = ifpflag; \
747161748Scperciva				fr->fr_ipf->fri_sifpidx = dynamic; \
748161748Scperciva			} else if (pooled || hashed) \
749161748Scperciva				fr->fr_satype = FRI_LOOKUP;)
750161748Scperciva		}
751196392Ssimon	;
752196392Ssimon
753196392Ssimonsrcport:
754196392Ssimon	| portcomp
755196392Ssimon		{ DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1;) }
756196392Ssimon	| portrange
757196392Ssimon		{ DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1; \
758196392Ssimon			fr->fr_stop = $1.p2;) }
759161748Scperciva	| porteq lstart srcportlist lend
760161748Scperciva		{ yyresetdict(); }
761161748Scperciva	;
762161748Scperciva
763161748Scpercivafromport:
764161748Scperciva	portcomp
765161748Scperciva		{ DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1;) }
766161748Scperciva	| portrange
767161748Scperciva		{ DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1; \
768161748Scperciva			fr->fr_stop = $1.p2;) }
769161748Scperciva	| porteq lstart srcportlist lend
770161748Scperciva		{ yyresetdict(); }
771161748Scperciva	;
772161748Scperciva
773161748Scpercivasrcportlist:
774161748Scperciva	portnum		{ DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $1;) }
775161748Scperciva	| srcportlist lmore portnum
776161748Scperciva			{ DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $3;) }
777161748Scperciva	;
778161748Scperciva
779161748Scpercivadstobject:
780161748Scperciva	{ yyresetdict(); } toport
781161748Scperciva	| dstaddr dstport
782161748Scperciva	| '!' dstaddr dstport
783161748Scperciva			{ DOALL(fr->fr_flags |= FR_NOTDSTIP;) }
784161748Scperciva	;
785161748Scperciva
786161748Scpercivadstaddr:
787161748Scperciva	addr	{ DOREM(bcopy(&($1.a), &fr->fr_ip.fi_dst, sizeof($1.a)); \
788161748Scperciva			bcopy(&($1.m), &fr->fr_mip.fi_dst, sizeof($1.m)); \
789161748Scperciva			if (dynamic != -1) { \
790161748Scperciva				fr->fr_datype = ifpflag; \
791161748Scperciva				fr->fr_ipf->fri_difpidx = dynamic; \
792161748Scperciva			  } else if (pooled || hashed) \
793161748Scperciva				fr->fr_datype = FRI_LOOKUP;)
794161748Scperciva		}
795181142Scperciva	| lstart dstaddrlist lend
796181142Scperciva	;
797181142Scperciva
798181142Scpercivadstaddrlist:
799181142Scperciva	addr	{ DOREM(bcopy(&($1.a), &fr->fr_ip.fi_dst, sizeof($1.a)); \
800181142Scperciva			bcopy(&($1.m), &fr->fr_mip.fi_dst, sizeof($1.m)); \
801181142Scperciva			if (dynamic != -1) { \
802181142Scperciva				fr->fr_datype = ifpflag; \
803181142Scperciva				fr->fr_ipf->fri_difpidx = dynamic; \
804181142Scperciva			} else if (pooled || hashed) \
805181142Scperciva				fr->fr_datype = FRI_LOOKUP;)
806181142Scperciva		}
807181142Scperciva	| dstaddrlist lmore addr
808181142Scperciva		{ DOREM(bcopy(&($3.a), &fr->fr_ip.fi_dst, sizeof($3.a)); \
809181142Scperciva			bcopy(&($3.m), &fr->fr_mip.fi_dst, sizeof($3.m)); \
810181142Scperciva			if (dynamic != -1) { \
811181142Scperciva				fr->fr_datype = ifpflag; \
812181142Scperciva				fr->fr_ipf->fri_difpidx = dynamic; \
813181142Scperciva			} else if (pooled || hashed) \
814181142Scperciva				fr->fr_datype = FRI_LOOKUP;)
815181142Scperciva		}
816181142Scperciva	;
817181142Scperciva
818181142Scperciva
819181142Scpercivadstport:
820181142Scperciva	| portcomp
821181142Scperciva		{ DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1;) }
822181142Scperciva	| portrange
823181142Scperciva		{ DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1; \
824181142Scperciva			fr->fr_dtop = $1.p2;) }
825181142Scperciva	| porteq lstart dstportlist lend
826181142Scperciva		{ yyresetdict(); }
827181142Scperciva	;
828181142Scperciva
829181142Scpercivatoport:
830181142Scperciva	portcomp
831181142Scperciva		{ DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1;) }
832181142Scperciva	| portrange
833181142Scperciva		{ DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1; \
834181142Scperciva			fr->fr_dtop = $1.p2;) }
835181142Scperciva	| porteq lstart dstportlist lend
836181142Scperciva		{ yyresetdict(); }
837181142Scperciva	;
838181142Scperciva
839181142Scpercivadstportlist:
840181142Scperciva	portnum		{ DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $1;) }
841181142Scperciva	| dstportlist lmore portnum
842181142Scperciva			{ DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $3;) }
843181142Scperciva	;
844181142Scperciva
845181142Scpercivaaddr:	pool '/' YY_NUMBER		{ pooled = 1;
846181142Scperciva					  $$.a.iplookuptype = IPLT_POOL;
847181142Scperciva					  $$.a.iplookupsubtype = 0;
848181142Scperciva					  $$.a.iplookupnum = $3; }
849181142Scperciva	| pool '/' YY_STR		{ pooled = 1;
850181142Scperciva					  $$.a.iplookuptype = IPLT_POOL;
851181142Scperciva					  $$.a.iplookupsubtype = 1;
852181142Scperciva					  strncpy($$.a.iplookupname, $3,
853181142Scperciva						  sizeof($$.a.iplookupname));
854181142Scperciva					}
855181142Scperciva	| pool '=' '(' poollist ')'	{ pooled = 1;
856181142Scperciva					  $$.a.iplookuptype = IPLT_POOL;
857181142Scperciva					  $$.a.iplookupsubtype = 0;
858181142Scperciva					  $$.a.iplookupnum = makepool($4); }
859181142Scperciva	| hash '/' YY_NUMBER		{ hashed = 1;
860181142Scperciva					  $$.a.iplookuptype = IPLT_HASH;
861181142Scperciva					  $$.a.iplookupsubtype = 0;
862181142Scperciva					  $$.a.iplookupnum = $3; }
863181142Scperciva	| hash '/' YY_STR		{ pooled = 1;
864181142Scperciva					  $$.a.iplookuptype = IPLT_HASH;
865181142Scperciva					  $$.a.iplookupsubtype = 1;
866181142Scperciva					  strncpy($$.a.iplookupname, $3,
867181142Scperciva						  sizeof($$.a.iplookupname));
868181142Scperciva					}
869181142Scperciva	| hash '=' '(' addrlist ')'	{ hashed = 1;
870181142Scperciva					  $$.a.iplookuptype = IPLT_HASH;
871181142Scperciva					  $$.a.iplookupsubtype = 0;
872181142Scperciva					  $$.a.iplookupnum = makehash($4); }
873181142Scperciva	| ipaddr			{ bcopy(&$1, &$$, sizeof($$));
874181142Scperciva					  yyexpectaddr = 0; }
875181142Scperciva	;
876181142Scperciva
877181142Scpercivaipaddr:	IPFY_ANY			{ bzero(&($$), sizeof($$));
878181142Scperciva					  yyresetdict();
879181142Scperciva					  yyexpectaddr = 0; }
880161748Scperciva	| hostname			{ $$.a.in4 = $1;
881161748Scperciva					  $$.m.in4_addr = 0xffffffff;
882161748Scperciva					  yyexpectaddr = 0; }
883161748Scperciva	| hostname			{ yyresetdict();
884161748Scperciva					  $$.a.in4_addr = $1.s_addr; }
885161748Scperciva		maskspace		{ yysetdict(maskwords); }
886161748Scperciva		ipv4mask		{ $$.m.in4_addr = $5.s_addr;
887161748Scperciva					  $$.a.in4_addr &= $5.s_addr;
888161748Scperciva					  yyresetdict();
889161748Scperciva					  yyexpectaddr = 0; }
890161748Scperciva	| YY_IPV6			{ bcopy(&$1, &$$.a, sizeof($$.a));
891161748Scperciva					  fill6bits(128, (u_32_t *)&$$.m);
892161748Scperciva					  yyresetdict();
893161748Scperciva					  yyexpectaddr = 0; }
894161748Scperciva	| YY_IPV6			{ yyresetdict();
895161748Scperciva					  bcopy(&$1, &$$.a, sizeof($$.a)); }
896161748Scperciva		maskspace		{ yysetdict(maskwords); }
897161748Scperciva		ipv6mask		{ bcopy(&$5, &$$.m, sizeof($$.m));
898161748Scperciva					  yyresetdict();
899161748Scperciva					  yyexpectaddr = 0; }
900161748Scperciva	;
901161748Scpercivamaskspace:
902161748Scperciva	'/'
903161748Scperciva	| IPFY_MASK
904161748Scperciva	;
905161748Scperciva
906161748Scpercivaipv4mask:
907161748Scperciva	ipv4				{ $$ = $1; }
908161748Scperciva	| YY_HEX			{ $$.s_addr = htonl($1); }
909161748Scperciva	| YY_NUMBER			{ ntomask(4, $1, (u_32_t *)&$$); }
910161748Scperciva	| IPFY_BROADCAST		{ if (ifpflag == FRI_DYNAMIC) {
911161748Scperciva						$$.s_addr = 0;
912161748Scperciva						ifpflag = FRI_BROADCAST;
913161748Scperciva					  } else
914161748Scperciva						YYERROR;
915161748Scperciva					}
916161748Scperciva	| IPFY_NETWORK			{ if (ifpflag == FRI_DYNAMIC) {
917161748Scperciva						$$.s_addr = 0;
918161748Scperciva						ifpflag = FRI_NETWORK;
919161748Scperciva					  } else
920161748Scperciva						YYERROR;
921161748Scperciva					}
922161748Scperciva	| IPFY_NETMASKED		{ if (ifpflag == FRI_DYNAMIC) {
923161748Scperciva						$$.s_addr = 0;
924161748Scperciva						ifpflag = FRI_NETMASKED;
925161748Scperciva					  } else
926161748Scperciva						YYERROR;
927161748Scperciva					}
928161748Scperciva	| IPFY_PEER			{ if (ifpflag == FRI_DYNAMIC) {
929161748Scperciva						$$.s_addr = 0;
930161748Scperciva						ifpflag = FRI_PEERADDR;
931161748Scperciva					  } else
932161748Scperciva						YYERROR;
933161748Scperciva					}
934161748Scperciva	;
935161748Scperciva
936161748Scpercivaipv6mask:
937161748Scperciva	YY_NUMBER			{ ntomask(6, $1, $$.i6); }
938161748Scperciva	| IPFY_BROADCAST		{ if (ifpflag == FRI_DYNAMIC) {
939161748Scperciva						bzero(&$$, sizeof($$));
940161748Scperciva						ifpflag = FRI_BROADCAST;
941161748Scperciva					  } else
942161748Scperciva						YYERROR;
943161748Scperciva					}
944161748Scperciva	| IPFY_NETWORK			{ if (ifpflag == FRI_DYNAMIC) {
945161748Scperciva						bzero(&$$, sizeof($$));
946161748Scperciva						ifpflag = FRI_BROADCAST;
947161748Scperciva					  } else
948161748Scperciva						YYERROR;
949161748Scperciva					}
950161748Scperciva	| IPFY_NETMASKED		{ if (ifpflag == FRI_DYNAMIC) {
951161748Scperciva						bzero(&$$, sizeof($$));
952161748Scperciva						ifpflag = FRI_BROADCAST;
953161748Scperciva					  } else
954161748Scperciva						YYERROR;
955161748Scperciva					}
956161748Scperciva	| IPFY_PEER			{ if (ifpflag == FRI_DYNAMIC) {
957161748Scperciva						bzero(&$$, sizeof($$));
958161748Scperciva						ifpflag = FRI_BROADCAST;
959161748Scperciva					  } else
960161748Scperciva						YYERROR;
961161748Scperciva					}
962161748Scperciva	;
963161748Scperciva
964161748Scpercivahostname:
965161748Scperciva	ipv4				{ $$ = $1; }
966161748Scperciva	| YY_NUMBER			{ $$.s_addr = $1; }
967161748Scperciva	| YY_HEX			{ $$.s_addr = $1; }
968161748Scperciva	| YY_STR			{ $$.s_addr = lookuphost($1);
969161748Scperciva					  free($1);
970161748Scperciva					}
971161748Scperciva	;
972161748Scperciva
973161748Scpercivaaddrlist:
974161748Scperciva	ipaddr		{ $$ = newalist(NULL);
975161748Scperciva			  bcopy(&($1.a), &($$->al_i6addr), sizeof($1.a));
976161748Scperciva			  bcopy(&($1.m), &($$->al_i6mask), sizeof($1.m)); }
977161748Scperciva	| addrlist ',' ipaddr
978161748Scperciva			{ $$ = newalist($1);
979161748Scperciva			  bcopy(&($3.a), &($$->al_i6addr), sizeof($3.a));
980161748Scperciva			  bcopy(&($3.m), &($$->al_i6mask), sizeof($3.m)); }
981161748Scperciva	;
982161748Scperciva
983161748Scpercivapool:	IPFY_POOL	{ yyexpectaddr = 0; yycont = NULL; yyresetdict(); }
984161748Scperciva	;
985161748Scperciva
986161748Scpercivahash:	IPFY_HASH	{ yyexpectaddr = 0; yycont = NULL; yyresetdict(); }
987161748Scperciva	;
988161748Scperciva
989161748Scpercivapoollist:
990161748Scperciva	ipaddr		{ $$ = newalist(NULL);
991161748Scperciva			  bcopy(&($1.a), &($$->al_i6addr), sizeof($1.a));
992161748Scperciva			  bcopy(&($1.m), &($$->al_i6mask), sizeof($1.m)); }
993161748Scperciva	| '!' ipaddr	{ $$ = newalist(NULL);
994161748Scperciva			  $$->al_not = 1;
995161748Scperciva			  bcopy(&($2.a), &($$->al_i6addr), sizeof($2.a));
996161748Scperciva			  bcopy(&($2.m), &($$->al_i6mask), sizeof($2.m)); }
997161748Scperciva	| poollist ',' ipaddr
998161748Scperciva			{ $$ = newalist($1);
999161748Scperciva			  bcopy(&($3.a), &($$->al_i6addr), sizeof($3.a));
1000161748Scperciva			  bcopy(&($3.m), &($$->al_i6mask), sizeof($3.m)); }
1001161748Scperciva	| poollist ',' '!' ipaddr
1002161748Scperciva			{ $$ = newalist($1);
1003161748Scperciva			  $$->al_not = 1;
1004161748Scperciva			  bcopy(&($4.a), &($$->al_i6addr), sizeof($4.a));
1005161748Scperciva			  bcopy(&($4.m), &($$->al_i6mask), sizeof($4.m)); }
1006161748Scperciva	;
1007161748Scperciva
1008161748Scpercivaport:	IPFY_PORT			{ yyexpectaddr = 0;
1009161748Scperciva					  yycont = NULL;
1010161748Scperciva					}
1011161748Scperciva	;
1012161748Scperciva
1013161748Scpercivaportc:	port compare			{ $$ = $2;
1014161748Scperciva					  yysetdict(NULL); }
1015161748Scperciva	| porteq			{ $$ = $1; }
1016161748Scperciva	;
1017161748Scperciva
1018161748Scpercivaporteq:	port '='			{ $$ = FR_EQUAL;
1019161748Scperciva					  yysetdict(NULL); }
1020161748Scperciva	;
1021161748Scperciva
1022161748Scpercivaportr:	IPFY_PORT			{ yyexpectaddr = 0;
1023173564Scperciva					  yycont = NULL;
1024173564Scperciva					  yysetdict(NULL); }
1025173564Scperciva	;
1026173564Scperciva
1027173564Scpercivaportcomp:
1028173564Scperciva	portc portnum			{ $$.pc = $1;
1029173564Scperciva					  $$.p1 = $2;
1030173564Scperciva					  yyresetdict(); }
1031173564Scperciva	;
1032173564Scperciva
1033173564Scpercivaportrange:
1034173564Scperciva	portr portnum range portnum	{ $$.p1 = $2;
1035173564Scperciva					  $$.pc = $3;
1036173564Scperciva					  $$.p2 = $4;
1037161748Scperciva					  yyresetdict(); }
1038161748Scperciva	;
1039161748Scperciva
1040161748Scpercivaicmp:	| itype icode
1041161748Scperciva	;
1042161748Scperciva
1043161748Scpercivaitype:	seticmptype icmptype
1044161748Scperciva	{ DOALL(fr->fr_icmp = htons($2 << 8); fr->fr_icmpm = htons(0xff00););
1045161748Scperciva	  yyresetdict();
1046161748Scperciva	}
1047161748Scperciva	| seticmptype lstart typelist lend	{ yyresetdict(); }
1048161748Scperciva	;
1049161748Scperciva
1050161748Scpercivaseticmptype:
1051161748Scperciva	IPFY_ICMPTYPE				{ setipftype();
1052161748Scperciva						  yysetdict(icmptypewords); }
1053161748Scperciva	;
1054161748Scperciva
1055161748Scpercivaicode:	| seticmpcode icmpcode
1056161748Scperciva	{ DOALL(fr->fr_icmp |= htons($2); fr->fr_icmpm |= htons(0xff););
1057161748Scperciva	  yyresetdict();
1058161748Scperciva	}
1059161748Scperciva	| seticmpcode lstart codelist lend	{ yyresetdict(); }
1060161748Scperciva	;
1061161748Scperciva
1062161748Scpercivaseticmpcode:
1063161748Scperciva	IPFY_ICMPCODE				{ yysetdict(icmpcodewords); }
1064161748Scperciva	;
1065161748Scperciva
1066161748Scpercivatypelist:
1067161748Scperciva	icmptype
1068161748Scperciva	{ DOREM(fr->fr_icmp = htons($1 << 8); fr->fr_icmpm = htons(0xff00);) }
1069173564Scperciva	| typelist lmore icmptype
1070173564Scperciva	{ DOREM(fr->fr_icmp = htons($3 << 8); fr->fr_icmpm = htons(0xff00);) }
1071161748Scperciva	;
1072161748Scperciva
1073161748Scpercivacodelist:
1074161748Scperciva	icmpcode
1075161748Scperciva	{ DOREM(fr->fr_icmp |= htons($1); fr->fr_icmpm |= htons(0xff);) }
1076161748Scperciva	| codelist lmore icmpcode
1077161748Scperciva	{ DOREM(fr->fr_icmp &= htons(0xff00); fr->fr_icmp |= htons($3); \
1078161748Scperciva		fr->fr_icmpm |= htons(0xff);) }
1079161748Scperciva	;
1080161748Scperciva
1081161748Scpercivaage:	| IPFY_AGE YY_NUMBER		{ DOALL(fr->fr_age[0] = $2; \
1082161748Scperciva						fr->fr_age[1] = $2;) }
1083161748Scperciva	| IPFY_AGE YY_NUMBER '/' YY_NUMBER
1084161748Scperciva					{ DOALL(fr->fr_age[0] = $2; \
1085161748Scperciva						fr->fr_age[1] = $4;) }
1086161748Scperciva	;
1087161748Scperciva
1088161748Scpercivakeep:	| IPFY_KEEP keepstate keep
1089161748Scperciva	| IPFY_KEEP keepfrag keep
1090161748Scperciva	;
1091161748Scperciva
1092161748Scpercivakeepstate:
1093161748Scperciva	IPFY_STATE stateoptlist		{ DOALL(fr->fr_flags |= FR_KEEPSTATE;)}
1094161748Scperciva	;
1095161748Scperciva
1096161748Scpercivakeepfrag:
1097161748Scperciva	IPFY_FRAGS fragoptlist		{ DOALL(fr->fr_flags |= FR_KEEPFRAG;) }
1098161748Scperciva	| IPFY_FRAG fragoptlist		{ DOALL(fr->fr_flags |= FR_KEEPFRAG;) }
1099161748Scperciva	;
1100161748Scperciva
1101161748Scpercivafragoptlist:
1102161748Scperciva	| '(' fragopts ')'
1103161748Scperciva	;
1104161748Scperciva
1105161748Scpercivafragopts:
1106161748Scperciva	fragopt lanother fragopts
1107161748Scperciva	| fragopt
1108161748Scperciva	;
1109161748Scperciva
1110161748Scpercivafragopt:
1111161748Scperciva	IPFY_STRICT			{ DOALL(fr->fr_flags |= FR_FRSTRICT;) }
1112161748Scperciva	;
1113161748Scperciva
1114161748Scpercivastateoptlist:
1115161748Scperciva	| '(' stateopts ')'
1116161748Scperciva	;
1117161748Scperciva
1118161748Scpercivastateopts:
1119161748Scperciva	stateopt lanother stateopts
1120161748Scperciva	| stateopt
1121161748Scperciva	;
1122161748Scperciva
1123161748Scpercivastateopt:
1124161748Scperciva	IPFY_LIMIT YY_NUMBER	{ DOALL(fr->fr_statemax = $2;) }
1125161748Scperciva	| IPFY_STRICT		{ DOALL(if (fr->fr_proto != IPPROTO_TCP) { \
1126161748Scperciva						YYERROR; \
1127161748Scperciva					  } else \
1128161748Scperciva						fr->fr_flags |= FR_STSTRICT;)
1129161748Scperciva				}
1130161748Scperciva	| IPFY_NEWISN		{ DOALL(if (fr->fr_proto != IPPROTO_TCP) { \
1131161748Scperciva						YYERROR; \
1132161748Scperciva					  } else \
1133161748Scperciva						fr->fr_flags |= FR_NEWISN;)
1134161748Scperciva				}
1135161748Scperciva	| IPFY_NOICMPERR	{ DOALL(fr->fr_flags |= FR_NOICMPERR;) }
1136161748Scperciva
1137161748Scperciva	| IPFY_SYNC		{ DOALL(fr->fr_flags |= FR_STATESYNC;) }
1138161748Scperciva	| IPFY_AGE YY_NUMBER		{ DOALL(fr->fr_age[0] = $2; \
1139161748Scperciva						fr->fr_age[1] = $2;) }
1140161748Scperciva	| IPFY_AGE YY_NUMBER '/' YY_NUMBER
1141161748Scperciva					{ DOALL(fr->fr_age[0] = $2; \
1142161748Scperciva						fr->fr_age[1] = $4;) }
1143161748Scperciva	;
1144161748Scperciva
1145161748Scpercivaportnum:
1146161748Scperciva	servicename			{ if (getport(frc, $1, &($$)) == -1)
1147161748Scperciva						yyerror("service unknown");
1148161748Scperciva					  $$ = ntohs($$);
1149161748Scperciva					  free($1);
1150161748Scperciva					}
1151161748Scperciva	| YY_NUMBER			{ if ($1 > 65535)	/* Unsigned */
1152161748Scperciva						yyerror("invalid port number");
1153161748Scperciva					  else
1154161748Scperciva						$$ = $1;
1155161748Scperciva					}
1156161748Scperciva	;
1157161748Scperciva
1158161748Scpercivawithlist:
1159161748Scperciva	withopt				{ nowith = 0; }
1160161748Scperciva	| withlist withopt		{ nowith = 0; }
1161161748Scperciva	| withlist ',' withopt		{ nowith = 0; }
1162161748Scperciva	;
1163161748Scperciva
1164161748Scpercivawithopt:
1165161748Scperciva	opttype		{ DOALL(fr->fr_flx |= $1; fr->fr_mflx |= $1;) }
1166161748Scperciva	| notwith opttype		{ DOALL(fr->fr_mflx |= $2;) }
1167161748Scperciva	| ipopt ipopts			{ yyresetdict(); }
1168161748Scperciva	| notwith ipopt ipopts		{ yyresetdict(); }
1169161748Scperciva	| startv6hdrs ipv6hdrs		{ yyresetdict(); }
1170161748Scperciva	;
1171161748Scperciva
1172161748Scpercivaipopt:	IPFY_OPT			{ yysetdict(ipv4optwords); }
1173161748Scperciva	;
1174161748Scperciva
1175161748Scpercivastartv6hdrs:
1176161748Scperciva	IPF6_V6HDRS	{ if (use_inet6 == 0)
1177161748Scperciva				yyerror("only available with IPv6");
1178161748Scperciva			  yysetdict(ipv6optwords);
1179161748Scperciva			}
1180161748Scperciva	;
1181161748Scperciva
1182161748Scpercivanotwith:
1183161748Scperciva	IPFY_NOT			{ nowith = 1; }
1184161748Scperciva	| IPFY_NO			{ nowith = 1; }
1185161748Scperciva	;
1186161748Scperciva
1187161748Scpercivaopttype:
1188161748Scperciva	IPFY_IPOPTS			{ $$ = FI_OPTIONS; }
1189161748Scperciva	| IPFY_SHORT			{ $$ = FI_SHORT; }
1190161748Scperciva	| IPFY_NAT			{ $$ = FI_NATED; }
1191161748Scperciva	| IPFY_BAD			{ $$ = FI_BAD; }
1192161748Scperciva	| IPFY_BADNAT			{ $$ = FI_BADNAT; }
1193161748Scperciva	| IPFY_BADSRC			{ $$ = FI_BADSRC; }
1194161748Scperciva	| IPFY_LOWTTL			{ $$ = FI_LOWTTL; }
1195161748Scperciva	| IPFY_FRAG			{ $$ = FI_FRAG; }
1196161748Scperciva	| IPFY_FRAGBODY			{ $$ = FI_FRAGBODY; }
1197161748Scperciva	| IPFY_FRAGS			{ $$ = FI_FRAG; }
1198161748Scperciva	| IPFY_MBCAST			{ $$ = FI_MBCAST; }
1199161748Scperciva	| IPFY_MULTICAST		{ $$ = FI_MULTICAST; }
1200161748Scperciva	| IPFY_BROADCAST		{ $$ = FI_BROADCAST; }
1201161748Scperciva	| IPFY_STATE			{ $$ = FI_STATE; }
1202161748Scperciva	| IPFY_OOW			{ $$ = FI_OOW; }
1203161748Scperciva	;
1204161748Scperciva
1205161748Scpercivaipopts:	optlist		{ DOALL(fr->fr_mip.fi_optmsk |= $1;
1206161748Scperciva				if (!nowith)
1207161748Scperciva					fr->fr_ip.fi_optmsk |= $1;)
1208161748Scperciva			}
1209161748Scperciva	;
1210161748Scperciva
1211161748Scpercivaoptlist:
1212161748Scperciva	opt				{ $$ |= $1; }
1213161748Scperciva	| optlist ',' opt		{ $$ |= $1 | $3; }
1214161748Scperciva	;
1215161748Scperciva
1216161748Scpercivaipv6hdrs:
1217161748Scperciva	ipv6hdrlist	{ DOALL(fr->fr_mip.fi_optmsk |= $1;
1218161748Scperciva				if (!nowith)
1219161748Scperciva					fr->fr_ip.fi_optmsk |= $1;)
1220161748Scperciva			}
1221161748Scperciva	;
1222161748Scperciva
1223161748Scpercivaipv6hdrlist:
1224161748Scperciva	ipv6hdr				{ $$ |= $1; }
1225161748Scperciva	| ipv6hdrlist ',' ipv6hdr	{ $$ |= $1 | $3; }
1226161748Scperciva	;
1227161748Scperciva
1228161748Scpercivasecname:
1229161748Scperciva	seclevel			{ $$ |= $1; }
1230161748Scperciva	| secname ',' seclevel		{ $$ |= $1 | $3; }
1231161748Scperciva	;
1232161748Scperciva
1233161748Scpercivaseclevel:
1234161748Scperciva	IPFY_SEC_UNC			{ $$ = secbit(IPSO_CLASS_UNCL); }
1235161748Scperciva	| IPFY_SEC_CONF			{ $$ = secbit(IPSO_CLASS_CONF); }
1236161748Scperciva	| IPFY_SEC_RSV1			{ $$ = secbit(IPSO_CLASS_RES1); }
1237161748Scperciva	| IPFY_SEC_RSV2			{ $$ = secbit(IPSO_CLASS_RES2); }
1238161748Scperciva	| IPFY_SEC_RSV3			{ $$ = secbit(IPSO_CLASS_RES3); }
1239161748Scperciva	| IPFY_SEC_RSV4			{ $$ = secbit(IPSO_CLASS_RES4); }
1240161748Scperciva	| IPFY_SEC_SEC			{ $$ = secbit(IPSO_CLASS_SECR); }
1241161748Scperciva	| IPFY_SEC_TS			{ $$ = secbit(IPSO_CLASS_TOPS); }
1242161748Scperciva	;
1243161748Scperciva
1244161748Scpercivaicmptype:
1245161748Scperciva	YY_NUMBER			{ $$ = $1; }
1246161748Scperciva	| IPFY_ICMPT_UNR		{ $$ = ICMP_UNREACH; }
1247161748Scperciva	| IPFY_ICMPT_ECHO		{ $$ = ICMP_ECHO; }
1248161748Scperciva	| IPFY_ICMPT_ECHOR		{ $$ = ICMP_ECHOREPLY; }
1249161748Scperciva	| IPFY_ICMPT_SQUENCH		{ $$ = ICMP_SOURCEQUENCH; }
1250161748Scperciva	| IPFY_ICMPT_REDIR		{ $$ = ICMP_REDIRECT; }
1251161748Scperciva	| IPFY_ICMPT_TIMEX		{ $$ = ICMP_TIMXCEED; }
1252161748Scperciva	| IPFY_ICMPT_PARAMP		{ $$ = ICMP_PARAMPROB; }
1253161748Scperciva	| IPFY_ICMPT_TIMEST		{ $$ = ICMP_TSTAMP; }
1254161748Scperciva	| IPFY_ICMPT_TIMESTREP		{ $$ = ICMP_TSTAMPREPLY; }
1255161748Scperciva	| IPFY_ICMPT_INFOREQ		{ $$ = ICMP_IREQ; }
1256161748Scperciva	| IPFY_ICMPT_INFOREP		{ $$ = ICMP_IREQREPLY; }
1257161748Scperciva	| IPFY_ICMPT_MASKREQ		{ $$ = ICMP_MASKREQ; }
1258161748Scperciva	| IPFY_ICMPT_MASKREP		{ $$ = ICMP_MASKREPLY; }
1259161748Scperciva	| IPFY_ICMPT_ROUTERAD		{ $$ = ICMP_ROUTERADVERT; }
1260161748Scperciva	| IPFY_ICMPT_ROUTERSOL		{ $$ = ICMP_ROUTERSOLICIT; }
1261161748Scperciva	;
1262161748Scperciva
1263161748Scpercivaicmpcode:
1264161748Scperciva	YY_NUMBER			{ $$ = $1; }
1265161748Scperciva	| IPFY_ICMPC_NETUNR		{ $$ = ICMP_UNREACH_NET; }
1266161748Scperciva	| IPFY_ICMPC_HSTUNR		{ $$ = ICMP_UNREACH_HOST; }
1267161748Scperciva	| IPFY_ICMPC_PROUNR		{ $$ = ICMP_UNREACH_PROTOCOL; }
1268161748Scperciva	| IPFY_ICMPC_PORUNR		{ $$ = ICMP_UNREACH_PORT; }
1269161748Scperciva	| IPFY_ICMPC_NEEDF		{ $$ = ICMP_UNREACH_NEEDFRAG; }
1270161748Scperciva	| IPFY_ICMPC_SRCFAIL		{ $$ = ICMP_UNREACH_SRCFAIL; }
1271161748Scperciva	| IPFY_ICMPC_NETUNK		{ $$ = ICMP_UNREACH_NET_UNKNOWN; }
1272161748Scperciva	| IPFY_ICMPC_HSTUNK		{ $$ = ICMP_UNREACH_HOST_UNKNOWN; }
1273161748Scperciva	| IPFY_ICMPC_ISOLATE		{ $$ = ICMP_UNREACH_ISOLATED; }
1274161748Scperciva	| IPFY_ICMPC_NETPRO		{ $$ = ICMP_UNREACH_NET_PROHIB; }
1275161748Scperciva	| IPFY_ICMPC_HSTPRO		{ $$ = ICMP_UNREACH_HOST_PROHIB; }
1276161748Scperciva	| IPFY_ICMPC_NETTOS		{ $$ = ICMP_UNREACH_TOSNET; }
1277161748Scperciva	| IPFY_ICMPC_HSTTOS		{ $$ = ICMP_UNREACH_TOSHOST; }
1278161748Scperciva	| IPFY_ICMPC_FLTPRO		{ $$ = ICMP_UNREACH_ADMIN_PROHIBIT; }
1279161748Scperciva	| IPFY_ICMPC_HSTPRE		{ $$ = 14; }
1280161748Scperciva	| IPFY_ICMPC_CUTPRE		{ $$ = 15; }
1281161748Scperciva	;
1282161748Scperciva
1283161748Scpercivaopt:
1284161748Scperciva	IPFY_IPOPT_NOP			{ $$ = getoptbyvalue(IPOPT_NOP); }
1285161748Scperciva	| IPFY_IPOPT_RR			{ $$ = getoptbyvalue(IPOPT_RR); }
1286161748Scperciva	| IPFY_IPOPT_ZSU		{ $$ = getoptbyvalue(IPOPT_ZSU); }
1287161748Scperciva	| IPFY_IPOPT_MTUP		{ $$ = getoptbyvalue(IPOPT_MTUP); }
1288161748Scperciva	| IPFY_IPOPT_MTUR		{ $$ = getoptbyvalue(IPOPT_MTUR); }
1289161748Scperciva	| IPFY_IPOPT_ENCODE		{ $$ = getoptbyvalue(IPOPT_ENCODE); }
1290161748Scperciva	| IPFY_IPOPT_TS			{ $$ = getoptbyvalue(IPOPT_TS); }
1291161748Scperciva	| IPFY_IPOPT_TR			{ $$ = getoptbyvalue(IPOPT_TR); }
1292161748Scperciva	| IPFY_IPOPT_SEC		{ $$ = getoptbyvalue(IPOPT_SECURITY); }
1293161748Scperciva	| IPFY_IPOPT_LSRR		{ $$ = getoptbyvalue(IPOPT_LSRR); }
1294161748Scperciva	| IPFY_IPOPT_ESEC		{ $$ = getoptbyvalue(IPOPT_E_SEC); }
1295161748Scperciva	| IPFY_IPOPT_CIPSO		{ $$ = getoptbyvalue(IPOPT_CIPSO); }
1296161748Scperciva	| IPFY_IPOPT_SATID		{ $$ = getoptbyvalue(IPOPT_SATID); }
1297161748Scperciva	| IPFY_IPOPT_SSRR		{ $$ = getoptbyvalue(IPOPT_SSRR); }
1298161748Scperciva	| IPFY_IPOPT_ADDEXT		{ $$ = getoptbyvalue(IPOPT_ADDEXT); }
1299161748Scperciva	| IPFY_IPOPT_VISA		{ $$ = getoptbyvalue(IPOPT_VISA); }
1300161748Scperciva	| IPFY_IPOPT_IMITD		{ $$ = getoptbyvalue(IPOPT_IMITD); }
1301161748Scperciva	| IPFY_IPOPT_EIP		{ $$ = getoptbyvalue(IPOPT_EIP); }
1302161748Scperciva	| IPFY_IPOPT_FINN		{ $$ = getoptbyvalue(IPOPT_FINN); }
1303161748Scperciva	| IPFY_IPOPT_DPS		{ $$ = getoptbyvalue(IPOPT_DPS); }
1304161748Scperciva	| IPFY_IPOPT_SDB		{ $$ = getoptbyvalue(IPOPT_SDB); }
1305161748Scperciva	| IPFY_IPOPT_NSAPA		{ $$ = getoptbyvalue(IPOPT_NSAPA); }
1306161748Scperciva	| IPFY_IPOPT_RTRALRT		{ $$ = getoptbyvalue(IPOPT_RTRALRT); }
1307161748Scperciva	| IPFY_IPOPT_UMP		{ $$ = getoptbyvalue(IPOPT_UMP); }
1308161748Scperciva	| setsecclass secname
1309161748Scperciva			{ DOALL(fr->fr_mip.fi_secmsk |= $2;
1310161748Scperciva				if (!nowith)
1311164600Scperciva					fr->fr_ip.fi_secmsk |= $2;)
1312164600Scperciva			  $$ = 0;
1313161748Scperciva			  yyresetdict();
1314161748Scperciva			}
1315161748Scperciva	;
1316161748Scperciva
1317161748Scpercivasetsecclass:
1318161748Scperciva	IPFY_SECCLASS	{ yysetdict(ipv4secwords); }
1319161748Scperciva	;
1320161748Scperciva
1321161748Scpercivaipv6hdr:
1322161748Scperciva	IPFY_AH			{ $$ = getv6optbyvalue(IPPROTO_AH); }
1323161748Scperciva	| IPFY_IPV6OPT_DSTOPTS	{ $$ = getv6optbyvalue(IPPROTO_DSTOPTS); }
1324161748Scperciva	| IPFY_IPV6OPT_ESP	{ $$ = getv6optbyvalue(IPPROTO_ESP); }
1325161748Scperciva	| IPFY_IPV6OPT_HOPOPTS	{ $$ = getv6optbyvalue(IPPROTO_HOPOPTS); }
1326161748Scperciva	| IPFY_IPV6OPT_IPV6	{ $$ = getv6optbyvalue(IPPROTO_IPV6); }
1327161748Scperciva	| IPFY_IPV6OPT_NONE	{ $$ = getv6optbyvalue(IPPROTO_NONE); }
1328161748Scperciva	| IPFY_IPV6OPT_ROUTING	{ $$ = getv6optbyvalue(IPPROTO_ROUTING); }
1329161748Scperciva	| IPFY_IPV6OPT_FRAG	{ $$ = getv6optbyvalue(IPPROTO_FRAGMENT); }
1330161748Scperciva	| IPFY_IPV6OPT_MOBILITY	{ $$ = getv6optbyvalue(IPPROTO_MOBILITY); }
1331161748Scperciva	;
1332161748Scperciva
1333161748Scpercivalevel:	IPFY_LEVEL			{ setsyslog(); }
1334161748Scperciva	;
1335161748Scperciva
1336161748Scpercivaloglevel:
1337161748Scperciva	priority			{ fr->fr_loglevel = LOG_LOCAL0|$1; }
1338161748Scperciva	| facility '.' priority		{ fr->fr_loglevel = $1 | $3; }
1339161748Scperciva	;
1340161748Scperciva
1341161748Scpercivafacility:
1342161748Scperciva	IPFY_FAC_KERN			{ $$ = LOG_KERN; }
1343161748Scperciva	| IPFY_FAC_USER			{ $$ = LOG_USER; }
1344161748Scperciva	| IPFY_FAC_MAIL			{ $$ = LOG_MAIL; }
1345161748Scperciva	| IPFY_FAC_DAEMON		{ $$ = LOG_DAEMON; }
1346161748Scperciva	| IPFY_FAC_AUTH			{ $$ = LOG_AUTH; }
1347161748Scperciva	| IPFY_FAC_SYSLOG		{ $$ = LOG_SYSLOG; }
1348161748Scperciva	| IPFY_FAC_LPR			{ $$ = LOG_LPR; }
1349161748Scperciva	| IPFY_FAC_NEWS			{ $$ = LOG_NEWS; }
1350161748Scperciva	| IPFY_FAC_UUCP			{ $$ = LOG_UUCP; }
1351161748Scperciva	| IPFY_FAC_CRON			{ $$ = LOG_CRON; }
1352161748Scperciva	| IPFY_FAC_FTP			{ $$ = LOG_FTP; }
1353161748Scperciva	| IPFY_FAC_AUTHPRIV		{ $$ = LOG_AUTHPRIV; }
1354161748Scperciva	| IPFY_FAC_AUDIT		{ $$ = LOG_AUDIT; }
1355161748Scperciva	| IPFY_FAC_LFMT			{ $$ = LOG_LFMT; }
1356161748Scperciva	| IPFY_FAC_LOCAL0		{ $$ = LOG_LOCAL0; }
1357161748Scperciva	| IPFY_FAC_LOCAL1		{ $$ = LOG_LOCAL1; }
1358161748Scperciva	| IPFY_FAC_LOCAL2		{ $$ = LOG_LOCAL2; }
1359161748Scperciva	| IPFY_FAC_LOCAL3		{ $$ = LOG_LOCAL3; }
1360161748Scperciva	| IPFY_FAC_LOCAL4		{ $$ = LOG_LOCAL4; }
1361173564Scperciva	| IPFY_FAC_LOCAL5		{ $$ = LOG_LOCAL5; }
1362173564Scperciva	| IPFY_FAC_LOCAL6		{ $$ = LOG_LOCAL6; }
1363173564Scperciva	| IPFY_FAC_LOCAL7		{ $$ = LOG_LOCAL7; }
1364173564Scperciva	| IPFY_FAC_SECURITY		{ $$ = LOG_SECURITY; }
1365173564Scperciva	;
1366173564Scperciva
1367173564Scpercivapriority:
1368173564Scperciva	IPFY_PRI_EMERG			{ $$ = LOG_EMERG; }
1369173564Scperciva	| IPFY_PRI_ALERT		{ $$ = LOG_ALERT; }
1370173564Scperciva	| IPFY_PRI_CRIT			{ $$ = LOG_CRIT; }
1371173564Scperciva	| IPFY_PRI_ERR			{ $$ = LOG_ERR; }
1372173564Scperciva	| IPFY_PRI_WARN			{ $$ = LOG_WARNING; }
1373173564Scperciva	| IPFY_PRI_NOTICE		{ $$ = LOG_NOTICE; }
1374173564Scperciva	| IPFY_PRI_INFO			{ $$ = LOG_INFO; }
1375173564Scperciva	| IPFY_PRI_DEBUG		{ $$ = LOG_DEBUG; }
1376161869Scperciva	;
1377161748Scperciva
1378161748Scpercivacompare:
1379161748Scperciva	YY_CMP_EQ			{ $$ = FR_EQUAL; }
1380161748Scperciva	| YY_CMP_NE			{ $$ = FR_NEQUAL; }
1381173564Scperciva	| YY_CMP_LT			{ $$ = FR_LESST; }
1382173564Scperciva	| YY_CMP_LE			{ $$ = FR_LESSTE; }
1383161748Scperciva	| YY_CMP_GT			{ $$ = FR_GREATERT; }
1384161748Scperciva	| YY_CMP_GE			{ $$ = FR_GREATERTE; }
1385161748Scperciva	;
1386161748Scperciva
1387161748Scpercivarange:	YY_RANGE_IN			{ $$ = FR_INRANGE; }
1388173564Scperciva	| YY_RANGE_OUT			{ $$ = FR_OUTRANGE; }
1389161748Scperciva	| ':'				{ $$ = FR_INCRANGE; }
1390161748Scperciva	;
1391161748Scperciva
1392161748Scpercivaservicename:
1393161748Scperciva	YY_STR				{ $$ = $1; }
1394161748Scperciva	;
1395161748Scperciva
1396161748Scpercivainterfacename:	name				{ $$ = $1; }
1397161748Scperciva	| name ':' YY_NUMBER
1398161748Scperciva		{ $$ = $1;
1399161748Scperciva		  fprintf(stderr, "%d: Logical interface %s:%d unsupported, "
1400173564Scperciva			  "use the physical interface %s instead.\n",
1401161748Scperciva			  yylineNum, $1, $3, $1);
1402161748Scperciva		}
1403173564Scperciva	;
1404164600Scperciva
1405173564Scpercivaname:	YY_STR				{ $$ = $1; }
1406164600Scperciva	| '-'				{ $$ = strdup("-"); }
1407164600Scperciva	;
1408164600Scperciva
1409161748Scpercivaipv4_16:
1410173564Scperciva	YY_NUMBER '.' YY_NUMBER
1411173564Scperciva		{ if ($1 > 255 || $3 > 255) {
1412161748Scperciva			yyerror("Invalid octet string for IP address");
1413161748Scperciva			return 0;
1414164600Scperciva		  }
1415173564Scperciva		  $$.s_addr = ($1 << 24) | ($3 << 16);
1416173564Scperciva		  $$.s_addr = htonl($$.s_addr);
1417164600Scperciva		}
1418164600Scperciva	;
1419161748Scperciva
1420161748Scpercivaipv4_24:
1421161748Scperciva	ipv4_16 '.' YY_NUMBER
1422161748Scperciva		{ if ($3 > 255) {
1423161748Scperciva			yyerror("Invalid octet string for IP address");
1424161748Scperciva			return 0;
1425161748Scperciva		  }
1426161748Scperciva		  $$.s_addr |= htonl($3 << 8);
1427161748Scperciva		}
1428161748Scperciva	;
1429161748Scperciva
1430161748Scpercivaipv4:	ipv4_24 '.' YY_NUMBER
1431161748Scperciva		{ if ($3 > 255) {
1432161748Scperciva			yyerror("Invalid octet string for IP address");
1433161748Scperciva			return 0;
1434161748Scperciva		  }
1435161748Scperciva		  $$.s_addr |= htonl($3);
1436161748Scperciva		}
1437161748Scperciva	| ipv4_24
1438161748Scperciva	| ipv4_16
1439161748Scperciva	;
1440161748Scperciva
1441161748Scperciva%%
1442161748Scperciva
1443161748Scperciva
1444161748Scpercivastatic	struct	wordtab ipfwords[95] = {
1445161748Scperciva	{ "age",			IPFY_AGE },
1446161748Scperciva	{ "ah",				IPFY_AH },
1447161748Scperciva	{ "all",			IPFY_ALL },
1448161748Scperciva	{ "and",			IPFY_AND },
1449161748Scperciva	{ "auth",			IPFY_AUTH },
1450161748Scperciva	{ "bad",			IPFY_BAD },
1451161748Scperciva	{ "bad-nat",			IPFY_BADNAT },
1452161748Scperciva	{ "bad-src",			IPFY_BADSRC },
1453161748Scperciva	{ "bcast",			IPFY_BROADCAST },
1454161748Scperciva	{ "block",			IPFY_BLOCK },
1455161748Scperciva	{ "body",			IPFY_BODY },
1456161748Scperciva	{ "bpf-v4",			IPFY_BPFV4 },
1457161748Scperciva#ifdef USE_INET6
1458161748Scperciva	{ "bpf-v6",			IPFY_BPFV6 },
1459161748Scperciva#endif
1460161748Scperciva	{ "call",			IPFY_CALL },
1461161748Scperciva	{ "code",			IPFY_ICMPCODE },
1462161748Scperciva	{ "count",			IPFY_COUNT },
1463161748Scperciva	{ "dup-to",			IPFY_DUPTO },
1464161748Scperciva	{ "eq",				YY_CMP_EQ },
1465161748Scperciva	{ "esp",			IPFY_ESP },
1466161748Scperciva	{ "fastroute",			IPFY_FROUTE },
1467161748Scperciva	{ "first",			IPFY_FIRST },
1468161748Scperciva	{ "flags",			IPFY_FLAGS },
1469161748Scperciva	{ "frag",			IPFY_FRAG },
1470161748Scperciva	{ "frag-body",			IPFY_FRAGBODY },
1471161748Scperciva	{ "frags",			IPFY_FRAGS },
1472161748Scperciva	{ "from",			IPFY_FROM },
1473161748Scperciva	{ "ge",				YY_CMP_GE },
1474161748Scperciva	{ "group",			IPFY_GROUP },
1475161748Scperciva	{ "gt",				YY_CMP_GT },
1476161748Scperciva	{ "head",			IPFY_HEAD },
1477161748Scperciva	{ "icmp",			IPFY_ICMP },
1478161748Scperciva	{ "icmp-type",			IPFY_ICMPTYPE },
1479161748Scperciva	{ "in",				IPFY_IN },
1480161748Scperciva	{ "in-via",			IPFY_INVIA },
1481161748Scperciva	{ "ipopt",			IPFY_IPOPTS },
1482161748Scperciva	{ "ipopts",			IPFY_IPOPTS },
1483161748Scperciva	{ "keep",			IPFY_KEEP },
1484161748Scperciva	{ "le",				YY_CMP_LE },
1485161748Scperciva	{ "level",			IPFY_LEVEL },
1486161748Scperciva	{ "limit",			IPFY_LIMIT },
1487161748Scperciva	{ "log",			IPFY_LOG },
1488161748Scperciva	{ "lowttl",			IPFY_LOWTTL },
1489161748Scperciva	{ "lt",				YY_CMP_LT },
1490161748Scperciva	{ "mask",			IPFY_MASK },
1491161748Scperciva	{ "match-tag",			IPFY_MATCHTAG },
1492161748Scperciva	{ "mbcast",			IPFY_MBCAST },
1493161748Scperciva	{ "mcast",			IPFY_MULTICAST },
1494161748Scperciva	{ "multicast",			IPFY_MULTICAST },
1495161748Scperciva	{ "nat",			IPFY_NAT },
1496161748Scperciva	{ "ne",				YY_CMP_NE },
1497161748Scperciva	{ "net",			IPFY_NETWORK },
1498161748Scperciva	{ "newisn",			IPFY_NEWISN },
1499173564Scperciva	{ "no",				IPFY_NO },
1500173564Scperciva	{ "no-icmp-err",		IPFY_NOICMPERR },
1501173564Scperciva	{ "nomatch",			IPFY_NOMATCH },
1502173564Scperciva	{ "now",			IPFY_NOW },
1503173564Scperciva	{ "not",			IPFY_NOT },
1504173564Scperciva	{ "oow",			IPFY_OOW },
1505173564Scperciva	{ "on",				IPFY_ON },
1506173564Scperciva	{ "opt",			IPFY_OPT },
1507173564Scperciva	{ "or-block",			IPFY_ORBLOCK },
1508173564Scperciva	{ "out",			IPFY_OUT },
1509173564Scperciva	{ "out-via",			IPFY_OUTVIA },
1510173564Scperciva	{ "pass",			IPFY_PASS },
1511173564Scperciva	{ "port",			IPFY_PORT },
1512173564Scperciva	{ "pps",			IPFY_PPS },
1513173564Scperciva	{ "preauth",			IPFY_PREAUTH },
1514173564Scperciva	{ "proto",			IPFY_PROTO },
1515173564Scperciva	{ "quick",			IPFY_QUICK },
1516173564Scperciva	{ "reply-to",			IPFY_REPLY_TO },
1517173564Scperciva	{ "return-icmp",		IPFY_RETICMP },
1518173564Scperciva	{ "return-icmp-as-dest",	IPFY_RETICMPASDST },
1519173564Scperciva	{ "return-rst",			IPFY_RETRST },
1520173564Scperciva	{ "route-to",			IPFY_ROUTETO },
1521173564Scperciva	{ "sec-class",			IPFY_SECCLASS },
1522173564Scperciva	{ "set-tag",			IPFY_SETTAG },
1523173564Scperciva	{ "skip",			IPFY_SKIP },
1524173564Scperciva	{ "short",			IPFY_SHORT },
1525173564Scperciva	{ "state",			IPFY_STATE },
1526173564Scperciva	{ "state-age",			IPFY_AGE },
1527173564Scperciva	{ "strict",			IPFY_STRICT },
1528173564Scperciva	{ "sync",			IPFY_SYNC },
1529173564Scperciva	{ "tcp",			IPFY_TCP },
1530173564Scperciva	{ "tcp-udp",			IPFY_TCPUDP },
1531161748Scperciva	{ "tos",			IPFY_TOS },
1532173564Scperciva	{ "to",				IPFY_TO },
1533173564Scperciva	{ "ttl",			IPFY_TTL },
1534173564Scperciva	{ "udp",			IPFY_UDP },
1535173564Scperciva	{ "v6hdrs",			IPF6_V6HDRS },
1536161748Scperciva	{ "with",			IPFY_WITH },
1537161748Scperciva	{ NULL,				0 }
1538161748Scperciva};
1539161748Scperciva
1540161748Scpercivastatic	struct	wordtab	addrwords[4] = {
1541161748Scperciva	{ "any",			IPFY_ANY },
1542161748Scperciva	{ "hash",			IPFY_HASH },
1543161748Scperciva	{ "pool",			IPFY_POOL },
1544161748Scperciva	{ NULL,				0 }
1545161748Scperciva};
1546161748Scperciva
1547161748Scpercivastatic	struct	wordtab	maskwords[5] = {
1548161748Scperciva	{ "broadcast",			IPFY_BROADCAST },
1549161748Scperciva	{ "netmasked",			IPFY_NETMASKED },
1550161748Scperciva	{ "network",			IPFY_NETWORK },
1551161748Scperciva	{ "peer",			IPFY_PEER },
1552161748Scperciva	{ NULL,				0 }
1553161748Scperciva};
1554161748Scperciva
1555161748Scpercivastatic	struct	wordtab icmptypewords[16] = {
1556161748Scperciva	{ "echo",			IPFY_ICMPT_ECHO },
1557173564Scperciva	{ "echorep",			IPFY_ICMPT_ECHOR },
1558173564Scperciva	{ "inforeq",			IPFY_ICMPT_INFOREQ },
1559173564Scperciva	{ "inforep",			IPFY_ICMPT_INFOREP },
1560173564Scperciva	{ "maskrep",			IPFY_ICMPT_MASKREP },
1561173564Scperciva	{ "maskreq",			IPFY_ICMPT_MASKREQ },
1562173564Scperciva	{ "paramprob",			IPFY_ICMPT_PARAMP },
1563173564Scperciva	{ "redir",			IPFY_ICMPT_REDIR },
1564173564Scperciva	{ "unreach",			IPFY_ICMPT_UNR },
1565173564Scperciva	{ "routerad",			IPFY_ICMPT_ROUTERAD },
1566161748Scperciva	{ "routersol",			IPFY_ICMPT_ROUTERSOL },
1567161748Scperciva	{ "squench",			IPFY_ICMPT_SQUENCH },
1568161748Scperciva	{ "timest",			IPFY_ICMPT_TIMEST },
1569161748Scperciva	{ "timestrep",			IPFY_ICMPT_TIMESTREP },
1570161748Scperciva	{ "timex",			IPFY_ICMPT_TIMEX },
1571161748Scperciva	{ NULL,				0 },
1572161748Scperciva};
1573161748Scperciva
1574161748Scpercivastatic	struct	wordtab icmpcodewords[17] = {
1575161748Scperciva	{ "cutoff-preced",		IPFY_ICMPC_CUTPRE },
1576161748Scperciva	{ "filter-prohib",		IPFY_ICMPC_FLTPRO },
1577161748Scperciva	{ "isolate",			IPFY_ICMPC_ISOLATE },
1578161748Scperciva	{ "needfrag",			IPFY_ICMPC_NEEDF },
1579161748Scperciva	{ "net-prohib",			IPFY_ICMPC_NETPRO },
1580161748Scperciva	{ "net-tos",			IPFY_ICMPC_NETTOS },
1581161748Scperciva	{ "host-preced",		IPFY_ICMPC_HSTPRE },
1582161748Scperciva	{ "host-prohib",		IPFY_ICMPC_HSTPRO },
1583161748Scperciva	{ "host-tos",			IPFY_ICMPC_HSTTOS },
1584161748Scperciva	{ "host-unk",			IPFY_ICMPC_HSTUNK },
1585161748Scperciva	{ "host-unr",			IPFY_ICMPC_HSTUNR },
1586161748Scperciva	{ "net-unk",			IPFY_ICMPC_NETUNK },
1587161748Scperciva	{ "net-unr",			IPFY_ICMPC_NETUNR },
1588161748Scperciva	{ "port-unr",			IPFY_ICMPC_PORUNR },
1589161748Scperciva	{ "proto-unr",			IPFY_ICMPC_PROUNR },
1590161748Scperciva	{ "srcfail",			IPFY_ICMPC_SRCFAIL },
1591161748Scperciva	{ NULL,				0 },
1592161748Scperciva};
1593161748Scperciva
1594161748Scpercivastatic	struct	wordtab ipv4optwords[25] = {
1595161748Scperciva	{ "addext",			IPFY_IPOPT_ADDEXT },
1596161748Scperciva	{ "cipso",			IPFY_IPOPT_CIPSO },
1597161748Scperciva	{ "dps",			IPFY_IPOPT_DPS },
1598161748Scperciva	{ "e-sec",			IPFY_IPOPT_ESEC },
1599161748Scperciva	{ "eip",			IPFY_IPOPT_EIP },
1600161748Scperciva	{ "encode",			IPFY_IPOPT_ENCODE },
1601161748Scperciva	{ "finn",			IPFY_IPOPT_FINN },
1602161748Scperciva	{ "imitd",			IPFY_IPOPT_IMITD },
1603161748Scperciva	{ "lsrr",			IPFY_IPOPT_LSRR },
1604161748Scperciva	{ "mtup",			IPFY_IPOPT_MTUP },
1605161748Scperciva	{ "mtur",			IPFY_IPOPT_MTUR },
1606161748Scperciva	{ "nop",			IPFY_IPOPT_NOP },
1607161748Scperciva	{ "nsapa",			IPFY_IPOPT_NSAPA },
1608161748Scperciva	{ "rr",				IPFY_IPOPT_RR },
1609161748Scperciva	{ "rtralrt",			IPFY_IPOPT_RTRALRT },
1610161748Scperciva	{ "satid",			IPFY_IPOPT_SATID },
1611161748Scperciva	{ "sdb",			IPFY_IPOPT_SDB },
1612161748Scperciva	{ "sec",			IPFY_IPOPT_SEC },
1613161748Scperciva	{ "ssrr",			IPFY_IPOPT_SSRR },
1614161748Scperciva	{ "tr",				IPFY_IPOPT_TR },
1615161748Scperciva	{ "ts",				IPFY_IPOPT_TS },
1616161748Scperciva	{ "ump",			IPFY_IPOPT_UMP },
1617161748Scperciva	{ "visa",			IPFY_IPOPT_VISA },
1618161748Scperciva	{ "zsu",			IPFY_IPOPT_ZSU },
1619161748Scperciva	{ NULL,				0 },
1620161748Scperciva};
1621161748Scperciva
1622161748Scpercivastatic	struct	wordtab ipv4secwords[9] = {
1623161748Scperciva	{ "confid",			IPFY_SEC_CONF },
1624161748Scperciva	{ "reserv-1",			IPFY_SEC_RSV1 },
1625161748Scperciva	{ "reserv-2",			IPFY_SEC_RSV2 },
1626161748Scperciva	{ "reserv-3",			IPFY_SEC_RSV3 },
1627161748Scperciva	{ "reserv-4",			IPFY_SEC_RSV4 },
1628161748Scperciva	{ "secret",			IPFY_SEC_SEC },
1629161748Scperciva	{ "topsecret",			IPFY_SEC_TS },
1630161748Scperciva	{ "unclass",			IPFY_SEC_UNC },
1631161748Scperciva	{ NULL,				0 },
1632161748Scperciva};
1633161748Scperciva
1634161748Scpercivastatic	struct	wordtab ipv6optwords[9] = {
1635161748Scperciva	{ "dstopts",			IPFY_IPV6OPT_DSTOPTS },
1636161748Scperciva	{ "esp",			IPFY_IPV6OPT_ESP },
1637161748Scperciva	{ "frag",			IPFY_IPV6OPT_FRAG },
1638161748Scperciva	{ "hopopts",			IPFY_IPV6OPT_HOPOPTS },
1639161748Scperciva	{ "ipv6",			IPFY_IPV6OPT_IPV6 },
1640161748Scperciva	{ "mobility",			IPFY_IPV6OPT_MOBILITY },
1641161748Scperciva	{ "none",			IPFY_IPV6OPT_NONE },
1642161748Scperciva	{ "routing",			IPFY_IPV6OPT_ROUTING },
1643161748Scperciva	{ NULL,				0 },
1644161748Scperciva};
1645161748Scperciva
1646161748Scpercivastatic	struct	wordtab logwords[33] = {
1647161748Scperciva	{ "kern",			IPFY_FAC_KERN },
1648161748Scperciva	{ "user",			IPFY_FAC_USER },
1649161748Scperciva	{ "mail",			IPFY_FAC_MAIL },
1650161748Scperciva	{ "daemon",			IPFY_FAC_DAEMON },
1651161748Scperciva	{ "auth",			IPFY_FAC_AUTH },
1652161748Scperciva	{ "syslog",			IPFY_FAC_SYSLOG },
1653161748Scperciva	{ "lpr",			IPFY_FAC_LPR },
1654161748Scperciva	{ "news",			IPFY_FAC_NEWS },
1655161748Scperciva	{ "uucp",			IPFY_FAC_UUCP },
1656161748Scperciva	{ "cron",			IPFY_FAC_CRON },
1657161748Scperciva	{ "ftp",			IPFY_FAC_FTP },
1658161748Scperciva	{ "authpriv",			IPFY_FAC_AUTHPRIV },
1659161748Scperciva	{ "audit",			IPFY_FAC_AUDIT },
1660161748Scperciva	{ "logalert",			IPFY_FAC_LFMT },
1661161748Scperciva	{ "console",			IPFY_FAC_CONSOLE },
1662161748Scperciva	{ "security",			IPFY_FAC_SECURITY },
1663161748Scperciva	{ "local0",			IPFY_FAC_LOCAL0 },
1664161748Scperciva	{ "local1",			IPFY_FAC_LOCAL1 },
1665161748Scperciva	{ "local2",			IPFY_FAC_LOCAL2 },
1666161748Scperciva	{ "local3",			IPFY_FAC_LOCAL3 },
1667161748Scperciva	{ "local4",			IPFY_FAC_LOCAL4 },
1668161748Scperciva	{ "local5",			IPFY_FAC_LOCAL5 },
1669161748Scperciva	{ "local6",			IPFY_FAC_LOCAL6 },
1670161748Scperciva	{ "local7",			IPFY_FAC_LOCAL7 },
1671161748Scperciva	{ "emerg",			IPFY_PRI_EMERG },
1672161748Scperciva	{ "alert",			IPFY_PRI_ALERT },
1673161748Scperciva	{ "crit",			IPFY_PRI_CRIT },
1674161748Scperciva	{ "err",			IPFY_PRI_ERR },
1675161748Scperciva	{ "warn",			IPFY_PRI_WARN },
1676161748Scperciva	{ "notice",			IPFY_PRI_NOTICE },
1677161748Scperciva	{ "info",			IPFY_PRI_INFO },
1678161748Scperciva	{ "debug",			IPFY_PRI_DEBUG },
1679161748Scperciva	{ NULL,				0 },
1680161748Scperciva};
1681161748Scperciva
1682161748Scperciva
1683161748Scperciva
1684173564Scperciva
1685173564Scpercivaint ipf_parsefile(fd, addfunc, iocfuncs, filename)
1686173564Scpercivaint fd;
1687173564Scpercivaaddfunc_t addfunc;
1688173564Scpercivaioctlfunc_t *iocfuncs;
1689173564Scpercivachar *filename;
1690173564Scperciva{
1691173564Scperciva	FILE *fp = NULL;
1692173564Scperciva	char *s;
1693173564Scperciva
1694173564Scperciva	yylineNum = 1;
1695173564Scperciva	yysettab(ipfwords);
1696173564Scperciva
1697173564Scperciva	s = getenv("YYDEBUG");
1698173564Scperciva	if (s != NULL)
1699173564Scperciva		yydebug = atoi(s);
1700173564Scperciva	else
1701173564Scperciva		yydebug = 0;
1702173564Scperciva
1703173564Scperciva	if (strcmp(filename, "-")) {
1704173564Scperciva		fp = fopen(filename, "r");
1705173564Scperciva		if (fp == NULL) {
1706173564Scperciva			fprintf(stderr, "fopen(%s) failed: %s\n", filename,
1707173564Scperciva				STRERROR(errno));
1708173564Scperciva			return -1;
1709173564Scperciva		}
1710173564Scperciva	} else
1711173564Scperciva		fp = stdin;
1712173564Scperciva
1713173564Scperciva	while (ipf_parsesome(fd, addfunc, iocfuncs, fp) == 1)
1714173564Scperciva		;
1715173564Scperciva	if (fp != NULL)
1716173564Scperciva		fclose(fp);
1717173564Scperciva	return 0;
1718173564Scperciva}
1719173564Scperciva
1720173564Scperciva
1721173564Scpercivaint ipf_parsesome(fd, addfunc, iocfuncs, fp)
1722173564Scpercivaint fd;
1723173564Scpercivaaddfunc_t addfunc;
1724173564Scpercivaioctlfunc_t *iocfuncs;
1725173564ScpercivaFILE *fp;
1726173564Scperciva{
1727173564Scperciva	char *s;
1728173564Scperciva	int i;
1729161748Scperciva
1730161748Scperciva	ipffd = fd;
1731161748Scperciva	for (i = 0; i <= IPL_LOGMAX; i++)
1732161748Scperciva		ipfioctl[i] = iocfuncs[i];
1733161748Scperciva	ipfaddfunc = addfunc;
1734161748Scperciva
1735161748Scperciva	if (feof(fp))
1736161748Scperciva		return 0;
1737161748Scperciva	i = fgetc(fp);
1738161748Scperciva	if (i == EOF)
1739161748Scperciva		return 0;
1740161748Scperciva	if (ungetc(i, fp) == 0)
1741161748Scperciva		return 0;
1742161748Scperciva	if (feof(fp))
1743161748Scperciva		return 0;
1744161748Scperciva	s = getenv("YYDEBUG");
1745161748Scperciva	if (s != NULL)
1746173441Scperciva		yydebug = atoi(s);
1747173441Scperciva	else
1748173441Scperciva		yydebug = 0;
1749173441Scperciva
1750173441Scperciva	yyin = fp;
1751173441Scperciva	yyparse();
1752161748Scperciva	return 1;
1753161748Scperciva}
1754161748Scperciva
1755161748Scperciva
1756161748Scpercivastatic void newrule()
1757161748Scperciva{
1758161748Scperciva	frentry_t *frn;
1759161748Scperciva
1760171784Scperciva	frn = (frentry_t *)calloc(1, sizeof(frentry_t));
1761171784Scperciva	for (fr = frtop; fr != NULL && fr->fr_next != NULL; fr = fr->fr_next)
1762171784Scperciva		;
1763171784Scperciva	if (fr != NULL)
1764171784Scperciva		fr->fr_next = frn;
1765171784Scperciva	if (frtop == NULL)
1766171784Scperciva		frtop = frn;
1767171784Scperciva	fr = frn;
1768171784Scperciva	frc = frn;
1769171784Scperciva	fr->fr_loglevel = 0xffff;
1770161748Scperciva	fr->fr_isc = (void *)-1;
1771171784Scperciva	fr->fr_logtag = FR_NOLOGTAG;
1772171784Scperciva	fr->fr_type = FR_T_NONE;
1773171784Scperciva	if (use_inet6 != 0)
1774171784Scperciva		fr->fr_v = 6;
1775171784Scperciva	else
1776171784Scperciva		fr->fr_v = 4;
1777171784Scperciva
1778171784Scperciva	nrules = 1;
1779161748Scperciva}
1780171784Scperciva
1781161748Scperciva
1782161748Scpercivastatic void setipftype()
1783161748Scperciva{
1784161748Scperciva	for (fr = frc; fr != NULL; fr = fr->fr_next) {
1785161748Scperciva		if (fr->fr_type == FR_T_NONE) {
1786161748Scperciva			fr->fr_type = FR_T_IPF;
1787161748Scperciva			fr->fr_data = (void *)calloc(sizeof(fripf_t), 1);
1788161748Scperciva			fr->fr_dsize = sizeof(fripf_t);
1789161748Scperciva			fr->fr_ip.fi_v = frc->fr_v;
1790161748Scperciva			fr->fr_mip.fi_v = 0xf;
1791161748Scperciva			fr->fr_ipf->fri_sifpidx = -1;
1792161748Scperciva			fr->fr_ipf->fri_difpidx = -1;
1793161748Scperciva		}
1794161748Scperciva		if (fr->fr_type != FR_T_IPF) {
1795161748Scperciva			fprintf(stderr, "IPF Type not set\n");
1796161748Scperciva		}
1797161748Scperciva	}
1798161748Scperciva}
1799161748Scperciva
1800161748Scperciva
1801161748Scpercivastatic frentry_t *addrule()
1802161748Scperciva{
1803161748Scperciva	frentry_t *f, *f1, *f2;
1804173564Scperciva	int count;
1805161748Scperciva
1806161748Scperciva	for (f2 = frc; f2->fr_next != NULL; f2 = f2->fr_next)
1807161748Scperciva		;
1808161748Scperciva
1809161748Scperciva	count = nrules;
1810161748Scperciva	f = f2;
1811161748Scperciva	for (f1 = frc; count > 0; count--, f1 = f1->fr_next) {
1812161748Scperciva		f->fr_next = (frentry_t *)calloc(sizeof(*f), 1);
1813161748Scperciva		added++;
1814161748Scperciva		f = f->fr_next;
1815161748Scperciva		bcopy(f1, f, sizeof(*f));
1816161748Scperciva		f->fr_next = NULL;
1817161748Scperciva		if (f->fr_caddr != NULL) {
1818161748Scperciva			f->fr_caddr = malloc(f->fr_dsize);
1819161748Scperciva			bcopy(f1->fr_caddr, f->fr_caddr, f->fr_dsize);
1820161748Scperciva		}
1821161748Scperciva	}
1822161748Scperciva
1823161748Scperciva	return f2->fr_next;
1824161748Scperciva}
1825161748Scperciva
1826161748Scperciva
1827161748Scpercivastatic u_32_t lookuphost(name)
1828161748Scpercivachar *name;
1829161748Scperciva{
1830161748Scperciva	u_32_t addr;
1831161748Scperciva	int i;
1832161748Scperciva
1833161748Scperciva	hashed = 0;
1834161748Scperciva	pooled = 0;
1835161748Scperciva	dynamic = -1;
1836161748Scperciva
1837161748Scperciva	for (i = 0; i < 4; i++) {
1838161748Scperciva		if (strncmp(name, frc->fr_ifnames[i],
1839161748Scperciva			    sizeof(frc->fr_ifnames[i])) == 0) {
1840161748Scperciva			ifpflag = FRI_DYNAMIC;
1841161748Scperciva			dynamic = i;
1842161748Scperciva			return 0;
1843161748Scperciva		}
1844161748Scperciva	}
1845161748Scperciva
1846161748Scperciva	if (gethost(name, &addr) == -1) {
1847161748Scperciva		fprintf(stderr, "unknown name \"%s\"\n", name);
1848161748Scperciva		return 0;
1849161748Scperciva	}
1850161748Scperciva	return addr;
1851161748Scperciva}
1852161748Scperciva
1853161748Scperciva
1854161748Scpercivastatic void dobpf(v, phrase)
1855161748Scpercivaint v;
1856161748Scpercivachar *phrase;
1857161748Scperciva{
1858161748Scperciva#ifdef IPFILTER_BPF
1859161748Scperciva	struct bpf_program bpf;
1860161748Scperciva	struct pcap *p;
1861161748Scperciva#endif
1862161748Scperciva	fakebpf_t *fb;
1863161748Scperciva	u_32_t l;
1864161748Scperciva	char *s;
1865161748Scperciva	int i;
1866161748Scperciva
1867161748Scperciva	for (fr = frc; fr != NULL; fr = fr->fr_next) {
1868161748Scperciva		if (fr->fr_type != FR_T_NONE) {
1869161748Scperciva			fprintf(stderr, "cannot mix IPF and BPF matching\n");
1870161748Scperciva			return;
1871161748Scperciva		}
1872161748Scperciva		fr->fr_v = v;
1873161748Scperciva		fr->fr_type = FR_T_BPFOPC;
1874161748Scperciva
1875161748Scperciva		if (!strncmp(phrase, "0x", 2)) {
1876161748Scperciva			fb = malloc(sizeof(fakebpf_t));
1877161748Scperciva
1878173564Scperciva			for (i = 0, s = strtok(phrase, " \r\n\t"); s != NULL;
1879161748Scperciva			     s = strtok(NULL, " \r\n\t"), i++) {
1880161748Scperciva				fb = realloc(fb, (i / 4 + 1) * sizeof(*fb));
1881161748Scperciva				l = (u_32_t)strtol(s, NULL, 0);
1882161748Scperciva				switch (i & 3)
1883161748Scperciva				{
1884161748Scperciva				case 0 :
1885161748Scperciva					fb[i / 4].fb_c = l & 0xffff;
1886161748Scperciva					break;
1887161748Scperciva				case 1 :
1888161748Scperciva					fb[i / 4].fb_t = l & 0xff;
1889161748Scperciva					break;
1890161748Scperciva				case 2 :
1891161748Scperciva					fb[i / 4].fb_f = l & 0xff;
1892161748Scperciva					break;
1893161748Scperciva				case 3 :
1894161748Scperciva					fb[i / 4].fb_k = l;
1895161748Scperciva					break;
1896161748Scperciva				}
1897161748Scperciva			}
1898161748Scperciva			if ((i & 3) != 0) {
1899161748Scperciva				fprintf(stderr,
1900161748Scperciva					"Odd number of bytes in BPF code\n");
1901161748Scperciva				exit(1);
1902161748Scperciva			}
1903161748Scperciva			i--;
1904161748Scperciva			fr->fr_dsize = (i / 4 + 1) * sizeof(*fb);
1905161748Scperciva			fr->fr_data = fb;
1906161748Scperciva			return;
1907161748Scperciva		}
1908173564Scperciva
1909161748Scperciva#ifdef IPFILTER_BPF
1910161748Scperciva		bzero((char *)&bpf, sizeof(bpf));
1911161748Scperciva		p = pcap_open_dead(DLT_RAW, 1);
1912161748Scperciva		if (!p) {
1913161748Scperciva			fprintf(stderr, "pcap_open_dead failed\n");
1914161748Scperciva			return;
1915161748Scperciva		}
1916161748Scperciva
1917173564Scperciva		if (pcap_compile(p, &bpf, phrase, 1, 0xffffffff)) {
1918161748Scperciva			pcap_perror(p, "ipf");
1919161748Scperciva			pcap_close(p);
1920161748Scperciva			fprintf(stderr, "pcap parsing failed (%s)\n", phrase);
1921161748Scperciva			return;
1922161748Scperciva		}
1923161748Scperciva		pcap_close(p);
1924161748Scperciva
1925161748Scperciva		fr->fr_dsize = bpf.bf_len * sizeof(struct bpf_insn);
1926161748Scperciva		fr->fr_data = malloc(fr->fr_dsize);
1927173564Scperciva		bcopy((char *)bpf.bf_insns, fr->fr_data, fr->fr_dsize);
1928161748Scperciva		if (!bpf_validate(fr->fr_data, bpf.bf_len)) {
1929161748Scperciva			fprintf(stderr, "BPF validation failed\n");
1930161748Scperciva			return;
1931161748Scperciva		}
1932161748Scperciva#endif
1933161748Scperciva	}
1934161748Scperciva
1935161748Scperciva#ifdef IPFILTER_BPF
1936161748Scperciva	if (opts & OPT_DEBUG)
1937161748Scperciva		bpf_dump(&bpf, 0);
1938161748Scperciva#else
1939161748Scperciva	fprintf(stderr, "BPF filter expressions not supported\n");
1940161748Scperciva	exit(1);
1941161748Scperciva#endif
1942161748Scperciva}
1943161748Scperciva
1944161748Scperciva
1945161748Scpercivastatic void resetaddr()
1946161748Scperciva{
1947161748Scperciva	hashed = 0;
1948161748Scperciva	pooled = 0;
1949161748Scperciva	dynamic = -1;
1950161748Scperciva}
1951161748Scperciva
1952161748Scperciva
1953161748Scpercivastatic alist_t *newalist(ptr)
1954161748Scpercivaalist_t *ptr;
1955161748Scperciva{
1956161748Scperciva	alist_t *al;
1957161869Scperciva
1958161748Scperciva	al = malloc(sizeof(*al));
1959161748Scperciva	if (al == NULL)
1960161748Scperciva		return NULL;
1961161748Scperciva	al->al_not = 0;
1962161748Scperciva	al->al_next = ptr;
1963161748Scperciva	return al;
1964161748Scperciva}
1965161748Scperciva
1966161748Scperciva
1967161748Scpercivastatic int makepool(list)
1968161748Scpercivaalist_t *list;
1969171838Scperciva{
1970171838Scperciva	ip_pool_node_t *n, *top;
1971161748Scperciva	ip_pool_t pool;
1972161748Scperciva	alist_t *a;
1973161748Scperciva	int num;
1974161748Scperciva
1975161748Scperciva	if (list == NULL)
1976161748Scperciva		return 0;
1977161748Scperciva	top = calloc(1, sizeof(*top));
1978161748Scperciva	if (top == NULL)
1979161748Scperciva		return 0;
1980161748Scperciva
1981161748Scperciva	for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) {
1982161748Scperciva		n->ipn_addr.adf_addr.in4.s_addr = a->al_1;
1983161748Scperciva		n->ipn_mask.adf_addr.in4.s_addr = a->al_2;
1984161748Scperciva		n->ipn_info = a->al_not;
1985161748Scperciva		if (a->al_next != NULL) {
1986161748Scperciva			n->ipn_next = calloc(1, sizeof(*n));
1987161748Scperciva			n = n->ipn_next;
1988161748Scperciva		}
1989161748Scperciva	}
1990161748Scperciva
1991161748Scperciva	bzero((char *)&pool, sizeof(pool));
1992161748Scperciva	pool.ipo_unit = IPL_LOGIPF;
1993161748Scperciva	pool.ipo_list = top;
1994161748Scperciva	num = load_pool(&pool, ipfioctl[IPL_LOGLOOKUP]);
1995161748Scperciva
1996161748Scperciva	while ((n = top) != NULL) {
1997161748Scperciva		top = n->ipn_next;
1998161748Scperciva		free(n);
1999161748Scperciva	}
2000161748Scperciva	return num;
2001161748Scperciva}
2002161748Scperciva
2003161748Scperciva
2004161748Scpercivastatic u_int makehash(list)
2005161748Scpercivaalist_t *list;
2006161748Scperciva{
2007161748Scperciva	iphtent_t *n, *top;
2008161748Scperciva	iphtable_t iph;
2009161748Scperciva	alist_t *a;
2010161748Scperciva	int num;
2011161748Scperciva
2012161748Scperciva	if (list == NULL)
2013161748Scperciva		return 0;
2014161748Scperciva	top = calloc(1, sizeof(*top));
2015161748Scperciva	if (top == NULL)
2016161748Scperciva		return 0;
2017161748Scperciva
2018161748Scperciva	for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) {
2019161748Scperciva		n->ipe_addr.in4_addr = a->al_1;
2020161748Scperciva		n->ipe_mask.in4_addr = a->al_2;
2021161748Scperciva		n->ipe_value = 0;
2022161748Scperciva		if (a->al_next != NULL) {
2023161748Scperciva			n->ipe_next = calloc(1, sizeof(*n));
2024161748Scperciva			n = n->ipe_next;
2025161748Scperciva		}
2026161748Scperciva	}
2027161748Scperciva
2028161748Scperciva	bzero((char *)&iph, sizeof(iph));
2029161748Scperciva	iph.iph_unit = IPL_LOGIPF;
2030161748Scperciva	iph.iph_type = IPHASH_LOOKUP;
2031161748Scperciva	*iph.iph_name = '\0';
2032161748Scperciva
2033161748Scperciva	if (load_hash(&iph, top, ipfioctl[IPL_LOGLOOKUP]) == 0)
2034161748Scperciva		sscanf(iph.iph_name, "%u", &num);
2035161748Scperciva	else
2036161748Scperciva		num = 0;
2037161748Scperciva
2038173564Scperciva	while ((n = top) != NULL) {
2039173564Scperciva		top = n->ipe_next;
2040173564Scperciva		free(n);
2041161748Scperciva	}
2042161748Scperciva	return num;
2043161748Scperciva}
2044161748Scperciva
2045161748Scperciva
2046161748Scpercivavoid ipf_addrule(fd, ioctlfunc, ptr)
2047161748Scpercivaint fd;
2048161748Scpercivaioctlfunc_t ioctlfunc;
2049161748Scpercivavoid *ptr;
2050161748Scperciva{
2051173564Scperciva	ioctlcmd_t add, del;
2052173564Scperciva	frentry_t *fr;
2053161748Scperciva	ipfobj_t obj;
2054161748Scperciva
2055161748Scperciva	if (ptr == NULL)
2056161748Scperciva		return;
2057161748Scperciva
2058161748Scperciva	fr = ptr;
2059161748Scperciva	add = 0;
2060161748Scperciva	del = 0;
2061161748Scperciva
2062161748Scperciva	bzero((char *)&obj, sizeof(obj));
2063161748Scperciva	obj.ipfo_rev = IPFILTER_VERSION;
2064161748Scperciva	obj.ipfo_size = sizeof(*fr);
2065161748Scperciva	obj.ipfo_type = IPFOBJ_FRENTRY;
2066161748Scperciva	obj.ipfo_ptr = ptr;
2067161748Scperciva
2068161748Scperciva	if ((opts & OPT_DONOTHING) != 0)
2069161748Scperciva		fd = -1;
2070161748Scperciva
2071161748Scperciva	if (opts & OPT_ZERORULEST) {
2072161748Scperciva		add = SIOCZRLST;
2073161748Scperciva	} else if (opts & OPT_INACTIVE) {
2074161748Scperciva		add = (u_int)fr->fr_hits ? SIOCINIFR :
2075161748Scperciva					   SIOCADIFR;
2076171784Scperciva		del = SIOCRMIFR;
2077161748Scperciva	} else {
2078161748Scperciva		add = (u_int)fr->fr_hits ? SIOCINAFR :
2079161748Scperciva					   SIOCADAFR;
2080161748Scperciva		del = SIOCRMAFR;
2081161748Scperciva	}
2082161748Scperciva
2083161748Scperciva	if ((opts & OPT_OUTQUE) != 0)
2084161748Scperciva		fr->fr_flags |= FR_OUTQUE;
2085161748Scperciva	if (fr->fr_hits)
2086161748Scperciva		fr->fr_hits--;
2087161748Scperciva	if ((opts & OPT_VERBOSE) != 0)
2088161748Scperciva		printfr(fr, ioctlfunc);
2089173564Scperciva
2090173564Scperciva	if ((opts & OPT_DEBUG) != 0) {
2091173564Scperciva		binprint(fr, sizeof(*fr));
2092173564Scperciva		if (fr->fr_data != NULL)
2093173564Scperciva			binprint(fr->fr_data, fr->fr_dsize);
2094173564Scperciva	}
2095173564Scperciva
2096173564Scperciva	if ((opts & OPT_ZERORULEST) != 0) {
2097173564Scperciva		if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
2098173564Scperciva			if ((opts & OPT_DONOTHING) == 0) {
2099173564Scperciva				fprintf(stderr, "%d:", yylineNum);
2100173564Scperciva				perror("ioctl(SIOCZRLST)");
2101173564Scperciva			}
2102173564Scperciva		} else {
2103173564Scperciva#ifdef	USE_QUAD_T
2104173564Scperciva			printf("hits %qd bytes %qd ",
2105173564Scperciva				(long long)fr->fr_hits,
2106173564Scperciva				(long long)fr->fr_bytes);
2107173564Scperciva#else
2108173564Scperciva			printf("hits %ld bytes %ld ",
2109173564Scperciva				fr->fr_hits, fr->fr_bytes);
2110173564Scperciva#endif
2111173564Scperciva			printfr(fr, ioctlfunc);
2112173564Scperciva		}
2113173564Scperciva	} else if ((opts & OPT_REMOVE) != 0) {
2114173564Scperciva		if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) {
2115173564Scperciva			if ((opts & OPT_DONOTHING) != 0) {
2116173564Scperciva				fprintf(stderr, "%d:", yylineNum);
2117173564Scperciva				perror("ioctl(delete rule)");
2118173564Scperciva			}
2119173564Scperciva		}
2120173564Scperciva	} else {
2121173564Scperciva		if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
2122173564Scperciva			if (!(opts & OPT_DONOTHING)) {
2123173564Scperciva				fprintf(stderr, "%d:", yylineNum);
2124173564Scperciva				perror("ioctl(add/insert rule)");
2125173564Scperciva			}
2126173564Scperciva		}
2127173564Scperciva	}
2128173564Scperciva}
2129173564Scperciva
2130173564Scpercivastatic void setsyslog()
2131173564Scperciva{
2132173564Scperciva	yysetdict(logwords);
2133173564Scperciva	yybreakondot = 1;
2134173564Scperciva}
2135173564Scperciva
2136173564Scperciva
2137173564Scpercivastatic void unsetsyslog()
2138173564Scperciva{
2139173564Scperciva	yyresetdict();
2140173564Scperciva	yybreakondot = 0;
2141173564Scperciva}
2142173564Scperciva
2143173564Scperciva
2144173564Scpercivastatic void fillgroup(fr)
2145173564Scpercivafrentry_t *fr;
2146173564Scperciva{
2147173564Scperciva	frentry_t *f;
2148173564Scperciva
2149173564Scperciva	for (f = frold; f != NULL; f = f->fr_next)
2150173564Scperciva		if (strncmp(f->fr_grhead, fr->fr_group, FR_GROUPLEN) == 0)
2151173564Scperciva			break;
2152173564Scperciva	if (f == NULL)
2153173564Scperciva		return;
2154173564Scperciva
2155173564Scperciva	/*
2156173564Scperciva	 * Only copy down matching fields if the rules are of the same type
2157173564Scperciva	 * and are of ipf type.   The only fields that are copied are those
2158173564Scperciva	 * that impact the rule parsing itself, eg. need for knowing what the
2159173564Scperciva	 * protocol should be for rules with port comparisons in them.
2160173564Scperciva	 */
2161173564Scperciva	if (f->fr_type != fr->fr_type || f->fr_type != FR_T_IPF)
2162173564Scperciva		return;
2163173564Scperciva
2164173564Scperciva	if (fr->fr_v == 0 && f->fr_v != 0)
2165173564Scperciva		fr->fr_v = f->fr_v;
2166173564Scperciva
2167173564Scperciva	if (fr->fr_mproto == 0 && f->fr_mproto != 0)
2168173564Scperciva		fr->fr_mproto = f->fr_mproto;
2169173564Scperciva	if (fr->fr_proto == 0 && f->fr_proto != 0)
2170173564Scperciva		fr->fr_proto = f->fr_proto;
2171173564Scperciva
2172173564Scperciva	if ((fr->fr_mproto == 0) && ((fr->fr_flx & FI_TCPUDP) == 0) &&
2173173564Scperciva	    ((f->fr_flx & FI_TCPUDP) != 0))
2174173564Scperciva		fr->fr_flx |= FI_TCPUDP;
2175173564Scperciva}
2176173564Scperciva