xref: /freebsd/sbin/ipf/common/ipf_y.y (revision 2a63c3be158216222d89a073dcbd6a72ee4aab5a)
141edb306SCy Schubert 
241edb306SCy Schubert /*
341edb306SCy Schubert  * Copyright (C) 2012 by Darren Reed.
441edb306SCy Schubert  *
541edb306SCy Schubert  * See the IPFILTER.LICENCE file for details on licencing.
641edb306SCy Schubert  */
741edb306SCy Schubert %{
841edb306SCy Schubert #include "ipf.h"
941edb306SCy Schubert #include <sys/ioctl.h>
1041edb306SCy Schubert #include <syslog.h>
1141edb306SCy Schubert #include <err.h>
1241edb306SCy Schubert #ifdef IPFILTER_BPF
1341edb306SCy Schubert # include <pcap.h>
1441edb306SCy Schubert #endif
1541edb306SCy Schubert #include "netinet/ip_pool.h"
1641edb306SCy Schubert #include "netinet/ip_htable.h"
1741edb306SCy Schubert #include "netinet/ipl.h"
1841edb306SCy Schubert #include "ipf_l.h"
1941edb306SCy Schubert 
2041edb306SCy Schubert #define	YYDEBUG	1
2141edb306SCy Schubert #define	DOALL(x)	for (fr = frc; fr != NULL; fr = fr->fr_next) { x }
2241edb306SCy Schubert #define	DOREM(x)	for (; fr != NULL; fr = fr->fr_next) { x }
2341edb306SCy Schubert 
2441edb306SCy Schubert extern	void	yyerror(char *);
2541edb306SCy Schubert extern	int	yyparse(void);
2641edb306SCy Schubert extern	int	yylex(void);
2741edb306SCy Schubert extern	int	yydebug;
2841edb306SCy Schubert extern	FILE	*yyin;
2941edb306SCy Schubert extern	int	yylineNum;
3041edb306SCy Schubert 
3141edb306SCy Schubert static	int	addname(frentry_t **, char *);
3241edb306SCy Schubert static	frentry_t *addrule(void);
3341edb306SCy Schubert static frentry_t *allocfr(void);
3441edb306SCy Schubert static	void	build_dstaddr_af(frentry_t *, void *);
3541edb306SCy Schubert static	void	build_srcaddr_af(frentry_t *, void *);
3641edb306SCy Schubert static	void	dobpf(int, char *);
3741edb306SCy Schubert static	void	doipfexpr(char *);
3841edb306SCy Schubert static	void	do_tuneint(char *, int);
3941edb306SCy Schubert static	void	do_tunestr(char *, char *);
4041edb306SCy Schubert static	void	fillgroup(frentry_t *);
4141edb306SCy Schubert static	int	lookuphost(char *, i6addr_t *);
4241edb306SCy Schubert static	u_int	makehash(struct alist_s *);
4341edb306SCy Schubert static	int	makepool(struct alist_s *);
4441edb306SCy Schubert static	struct	alist_s	*newalist(struct alist_s *);
4541edb306SCy Schubert static	void	newrule(void);
4641edb306SCy Schubert static	void	resetaddr(void);
4741edb306SCy Schubert static	void	setgroup(frentry_t **, char *);
4841edb306SCy Schubert static	void	setgrhead(frentry_t **, char *);
4941edb306SCy Schubert static	void	seticmphead(frentry_t **, char *);
5041edb306SCy Schubert static	void	setifname(frentry_t **, int, char *);
5141edb306SCy Schubert static	void	setipftype(void);
5241edb306SCy Schubert static	void	setsyslog(void);
5341edb306SCy Schubert static	void	unsetsyslog(void);
5441edb306SCy Schubert 
5541edb306SCy Schubert frentry_t	*fr = NULL, *frc = NULL, *frtop = NULL, *frold = NULL;
5641edb306SCy Schubert 
5741edb306SCy Schubert static	int		ifpflag = 0;
5841edb306SCy Schubert static	int		nowith = 0;
5941edb306SCy Schubert static	int		dynamic = -1;
6041edb306SCy Schubert static	int		pooled = 0;
6141edb306SCy Schubert static	int		hashed = 0;
6241edb306SCy Schubert static	int		nrules = 0;
6341edb306SCy Schubert static	int		newlist = 0;
6441edb306SCy Schubert static	int		added = 0;
6541edb306SCy Schubert static	int		ipffd = -1;
6641edb306SCy Schubert static	int		*yycont = NULL;
6741edb306SCy Schubert static	ioctlfunc_t	ipfioctls[IPL_LOGSIZE];
6841edb306SCy Schubert static	addfunc_t	ipfaddfunc = NULL;
6941edb306SCy Schubert 
7041edb306SCy Schubert %}
7141edb306SCy Schubert %union	{
7241edb306SCy Schubert 	char	*str;
7341edb306SCy Schubert 	u_32_t	num;
7441edb306SCy Schubert 	frentry_t	fr;
7541edb306SCy Schubert 	frtuc_t	*frt;
7641edb306SCy Schubert 	struct	alist_s	*alist;
7741edb306SCy Schubert 	u_short	port;
7841edb306SCy Schubert 	struct	in_addr	ip4;
7941edb306SCy Schubert 	struct	{
8041edb306SCy Schubert 		u_short	p1;
8141edb306SCy Schubert 		u_short	p2;
8241edb306SCy Schubert 		int	pc;
8341edb306SCy Schubert 	} pc;
8441edb306SCy Schubert 	struct ipp_s {
8541edb306SCy Schubert 		int		type;
8641edb306SCy Schubert 		int		ifpos;
8741edb306SCy Schubert 		int		f;
8841edb306SCy Schubert 		int		v;
8941edb306SCy Schubert 		int		lif;
9041edb306SCy Schubert 		union	i6addr	a;
9141edb306SCy Schubert 		union	i6addr	m;
9241edb306SCy Schubert 		char		*name;
9341edb306SCy Schubert 	} ipp;
9441edb306SCy Schubert 	struct	{
9541edb306SCy Schubert 		i6addr_t	adr;
9641edb306SCy Schubert 		int		f;
9741edb306SCy Schubert 	} adr;
9841edb306SCy Schubert 	i6addr_t	ip6;
9941edb306SCy Schubert 	struct	{
10041edb306SCy Schubert 		char	*if1;
10141edb306SCy Schubert 		char	*if2;
10241edb306SCy Schubert 	} ifs;
10341edb306SCy Schubert 	char	gname[FR_GROUPLEN];
10441edb306SCy Schubert };
10541edb306SCy Schubert 
10641edb306SCy Schubert %type	<port>	portnum
10741edb306SCy Schubert %type	<num>	facility priority icmpcode seclevel secname icmptype
10841edb306SCy Schubert %type	<num>	opt compare range opttype flagset optlist ipv6hdrlist ipv6hdr
10941edb306SCy Schubert %type	<num>	portc porteq ipmask maskopts
11041edb306SCy Schubert %type	<ip4>	ipv4 ipv4_16 ipv4_24
11141edb306SCy Schubert %type	<adr>	hostname
11241edb306SCy Schubert %type	<ipp>	addr ipaddr
11341edb306SCy Schubert %type	<str>	servicename name interfacename groupname
11441edb306SCy Schubert %type	<pc>	portrange portcomp
11541edb306SCy Schubert %type	<alist>	addrlist poollist
11641edb306SCy Schubert %type	<ifs>	onname
11741edb306SCy Schubert 
11841edb306SCy Schubert %token	<num>	YY_NUMBER YY_HEX
11941edb306SCy Schubert %token	<str>	YY_STR
12041edb306SCy Schubert %token		YY_COMMENT
12141edb306SCy Schubert %token		YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
12241edb306SCy Schubert %token		YY_RANGE_OUT YY_RANGE_IN
12341edb306SCy Schubert %token	<ip6>	YY_IPV6
12441edb306SCy Schubert 
12541edb306SCy Schubert %token	IPFY_SET
12641edb306SCy Schubert %token	IPFY_PASS IPFY_BLOCK IPFY_COUNT IPFY_CALL IPFY_NOMATCH
12741edb306SCy Schubert %token	IPFY_RETICMP IPFY_RETRST IPFY_RETICMPASDST
12841edb306SCy Schubert %token	IPFY_IN IPFY_OUT
12941edb306SCy Schubert %token	IPFY_QUICK IPFY_ON IPFY_OUTVIA IPFY_INVIA
13041edb306SCy Schubert %token	IPFY_DUPTO IPFY_TO IPFY_FROUTE IPFY_REPLY_TO IPFY_ROUTETO
13141edb306SCy Schubert %token	IPFY_TOS IPFY_TTL IPFY_PROTO IPFY_INET IPFY_INET6
13241edb306SCy Schubert %token	IPFY_HEAD IPFY_GROUP
13341edb306SCy Schubert %token	IPFY_AUTH IPFY_PREAUTH
13441edb306SCy Schubert %token	IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK IPFY_L5AS
13541edb306SCy Schubert %token	IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP IPFY_DECAPS
13641edb306SCy Schubert %token	IPFY_FROM IPFY_ALL IPFY_ANY IPFY_BPFV4 IPFY_BPFV6 IPFY_POOL IPFY_HASH
13741edb306SCy Schubert %token	IPFY_IPFEXPR IPFY_PPS IPFY_FAMILY IPFY_DSTLIST
13841edb306SCy Schubert %token	IPFY_ESP IPFY_AH
13941edb306SCy Schubert %token	IPFY_WITH IPFY_AND IPFY_NOT IPFY_NO IPFY_OPT
14041edb306SCy Schubert %token	IPFY_TCPUDP IPFY_TCP IPFY_UDP
14141edb306SCy Schubert %token	IPFY_FLAGS IPFY_MULTICAST
14241edb306SCy Schubert %token	IPFY_MASK IPFY_BROADCAST IPFY_NETWORK IPFY_NETMASKED IPFY_PEER
14341edb306SCy Schubert %token	IPFY_RPC IPFY_PORT
14441edb306SCy Schubert %token	IPFY_NOW IPFY_COMMENT IPFY_RULETTL
14541edb306SCy Schubert %token	IPFY_ICMP IPFY_ICMPTYPE IPFY_ICMPCODE
14641edb306SCy Schubert %token	IPFY_IPOPTS IPFY_SHORT IPFY_NAT IPFY_BADSRC IPFY_LOWTTL IPFY_FRAG
14741edb306SCy Schubert %token	IPFY_MBCAST IPFY_BAD IPFY_BADNAT IPFY_OOW IPFY_NEWISN IPFY_NOICMPERR
14841edb306SCy Schubert %token	IPFY_KEEP IPFY_STATE IPFY_FRAGS IPFY_LIMIT IPFY_STRICT IPFY_AGE
14941edb306SCy Schubert %token	IPFY_SYNC IPFY_FRAGBODY IPFY_ICMPHEAD IPFY_NOLOG IPFY_LOOSE
15041edb306SCy Schubert %token	IPFY_MAX_SRCS IPFY_MAX_PER_SRC
15141edb306SCy Schubert %token	IPFY_IPOPT_NOP IPFY_IPOPT_RR IPFY_IPOPT_ZSU IPFY_IPOPT_MTUP
15241edb306SCy Schubert %token	IPFY_IPOPT_MTUR IPFY_IPOPT_ENCODE IPFY_IPOPT_TS IPFY_IPOPT_TR
15341edb306SCy Schubert %token	IPFY_IPOPT_SEC IPFY_IPOPT_LSRR IPFY_IPOPT_ESEC IPFY_IPOPT_CIPSO
15441edb306SCy Schubert %token	IPFY_IPOPT_SATID IPFY_IPOPT_SSRR IPFY_IPOPT_ADDEXT IPFY_IPOPT_VISA
15541edb306SCy Schubert %token	IPFY_IPOPT_IMITD IPFY_IPOPT_EIP IPFY_IPOPT_FINN IPFY_IPOPT_DPS
15641edb306SCy Schubert %token	IPFY_IPOPT_SDB IPFY_IPOPT_NSAPA IPFY_IPOPT_RTRALRT IPFY_IPOPT_UMP
15741edb306SCy Schubert %token	IPFY_SECCLASS IPFY_SEC_UNC IPFY_SEC_CONF IPFY_SEC_RSV1 IPFY_SEC_RSV2
15841edb306SCy Schubert %token	IPFY_SEC_RSV4 IPFY_SEC_SEC IPFY_SEC_TS IPFY_SEC_RSV3 IPFY_DOI
15941edb306SCy Schubert 
16041edb306SCy Schubert %token	IPFY_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS
16141edb306SCy Schubert %token	IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING IPFY_V6HDR
16241edb306SCy Schubert %token	IPFY_IPV6OPT_MOBILITY IPFY_IPV6OPT_ESP IPFY_IPV6OPT_FRAG
16341edb306SCy Schubert 
16441edb306SCy Schubert %token	IPFY_ICMPT_UNR IPFY_ICMPT_ECHO IPFY_ICMPT_ECHOR IPFY_ICMPT_SQUENCH
16541edb306SCy Schubert %token	IPFY_ICMPT_REDIR IPFY_ICMPT_TIMEX IPFY_ICMPT_PARAMP IPFY_ICMPT_TIMEST
16641edb306SCy Schubert %token	IPFY_ICMPT_TIMESTREP IPFY_ICMPT_INFOREQ IPFY_ICMPT_INFOREP
16741edb306SCy Schubert %token	IPFY_ICMPT_MASKREQ IPFY_ICMPT_MASKREP IPFY_ICMPT_ROUTERAD
16841edb306SCy Schubert %token	IPFY_ICMPT_ROUTERSOL
16941edb306SCy Schubert 
17041edb306SCy Schubert %token	IPFY_ICMPC_NETUNR IPFY_ICMPC_HSTUNR IPFY_ICMPC_PROUNR IPFY_ICMPC_PORUNR
17141edb306SCy Schubert %token	IPFY_ICMPC_NEEDF IPFY_ICMPC_SRCFAIL IPFY_ICMPC_NETUNK IPFY_ICMPC_HSTUNK
17241edb306SCy Schubert %token	IPFY_ICMPC_ISOLATE IPFY_ICMPC_NETPRO IPFY_ICMPC_HSTPRO
17341edb306SCy Schubert %token	IPFY_ICMPC_NETTOS IPFY_ICMPC_HSTTOS IPFY_ICMPC_FLTPRO IPFY_ICMPC_HSTPRE
17441edb306SCy Schubert %token	IPFY_ICMPC_CUTPRE
17541edb306SCy Schubert 
17641edb306SCy Schubert %token	IPFY_FAC_KERN IPFY_FAC_USER IPFY_FAC_MAIL IPFY_FAC_DAEMON IPFY_FAC_AUTH
17741edb306SCy Schubert %token	IPFY_FAC_SYSLOG IPFY_FAC_LPR IPFY_FAC_NEWS IPFY_FAC_UUCP IPFY_FAC_CRON
17841edb306SCy Schubert %token	IPFY_FAC_LOCAL0 IPFY_FAC_LOCAL1 IPFY_FAC_LOCAL2 IPFY_FAC_LOCAL3
17941edb306SCy Schubert %token	IPFY_FAC_LOCAL4 IPFY_FAC_LOCAL5 IPFY_FAC_LOCAL6 IPFY_FAC_LOCAL7
18041edb306SCy Schubert %token	IPFY_FAC_SECURITY IPFY_FAC_FTP IPFY_FAC_AUTHPRIV IPFY_FAC_AUDIT
18141edb306SCy Schubert %token	IPFY_FAC_LFMT IPFY_FAC_CONSOLE
18241edb306SCy Schubert 
18341edb306SCy Schubert %token	IPFY_PRI_EMERG IPFY_PRI_ALERT IPFY_PRI_CRIT IPFY_PRI_ERR IPFY_PRI_WARN
18441edb306SCy Schubert %token	IPFY_PRI_NOTICE IPFY_PRI_INFO IPFY_PRI_DEBUG
18541edb306SCy Schubert %%
18641edb306SCy Schubert file:	settings rules
18741edb306SCy Schubert 	| rules
18841edb306SCy Schubert 	;
18941edb306SCy Schubert 
19041edb306SCy Schubert settings:
19141edb306SCy Schubert 	YY_COMMENT
19241edb306SCy Schubert 	| setting
19341edb306SCy Schubert 	| settings setting
19441edb306SCy Schubert 	;
19541edb306SCy Schubert 
19641edb306SCy Schubert rules:	line
19741edb306SCy Schubert 	| assign
19841edb306SCy Schubert 	| rules line
19941edb306SCy Schubert 	| rules assign
20041edb306SCy Schubert 	;
20141edb306SCy Schubert 
20241edb306SCy Schubert setting:
20341edb306SCy Schubert 	IPFY_SET YY_STR YY_NUMBER ';'	{ do_tuneint($2, $3); }
20441edb306SCy Schubert 	| IPFY_SET YY_STR YY_HEX ';'	{ do_tuneint($2, $3); }
20541edb306SCy Schubert 	| IPFY_SET YY_STR YY_STR ';'	{ do_tunestr($2, $3); }
20641edb306SCy Schubert 	;
20741edb306SCy Schubert 
20841edb306SCy Schubert line:	rule		{ while ((fr = frtop) != NULL) {
20941edb306SCy Schubert 				frtop = fr->fr_next;
21041edb306SCy Schubert 				fr->fr_next = NULL;
21141edb306SCy Schubert 				if ((fr->fr_type == FR_T_IPF) &&
21241edb306SCy Schubert 				    (fr->fr_ip.fi_v == 0))
21341edb306SCy Schubert 					fr->fr_mip.fi_v = 0;
21441edb306SCy Schubert 				/* XXX validate ? */
21541edb306SCy Schubert 				(*ipfaddfunc)(ipffd, ipfioctls[IPL_LOGIPF], fr);
21641edb306SCy Schubert 				fr->fr_next = frold;
21741edb306SCy Schubert 				frold = fr;
21841edb306SCy Schubert 			  }
21941edb306SCy Schubert 			  resetlexer();
22041edb306SCy Schubert 			}
22141edb306SCy Schubert 	| YY_COMMENT
22241edb306SCy Schubert 	;
22341edb306SCy Schubert 
22441edb306SCy Schubert xx:					{ newrule(); }
22541edb306SCy Schubert 	;
22641edb306SCy Schubert 
22741edb306SCy Schubert assign:	YY_STR assigning YY_STR ';'	{ set_variable($1, $3);
22841edb306SCy Schubert 					  resetlexer();
22941edb306SCy Schubert 					  free($1);
23041edb306SCy Schubert 					  free($3);
23141edb306SCy Schubert 					  yyvarnext = 0;
23241edb306SCy Schubert 					}
23341edb306SCy Schubert 	;
23441edb306SCy Schubert 
23541edb306SCy Schubert assigning:
23641edb306SCy Schubert 	'='				{ yyvarnext = 1; }
23741edb306SCy Schubert 	;
23841edb306SCy Schubert 
23941edb306SCy Schubert rule:	inrule eol
24041edb306SCy Schubert 	| outrule eol
24141edb306SCy Schubert 	;
24241edb306SCy Schubert 
24341edb306SCy Schubert eol:	| ';'
24441edb306SCy Schubert 	;
24541edb306SCy Schubert 
24641edb306SCy Schubert inrule:
24741edb306SCy Schubert 	rulehead markin inopts rulemain ruletail intag ruletail2
24841edb306SCy Schubert 	;
24941edb306SCy Schubert 
25041edb306SCy Schubert outrule:
25141edb306SCy Schubert 	rulehead markout outopts rulemain ruletail outtag ruletail2
25241edb306SCy Schubert 	;
25341edb306SCy Schubert 
25441edb306SCy Schubert rulehead:
25541edb306SCy Schubert 	xx collection action
25641edb306SCy Schubert 	| xx insert collection action
25741edb306SCy Schubert 	;
25841edb306SCy Schubert 
25941edb306SCy Schubert markin:	IPFY_IN				{ fr->fr_flags |= FR_INQUE; }
26041edb306SCy Schubert 	;
26141edb306SCy Schubert 
26241edb306SCy Schubert markout:
26341edb306SCy Schubert 	IPFY_OUT			{ fr->fr_flags |= FR_OUTQUE; }
26441edb306SCy Schubert 	;
26541edb306SCy Schubert 
26641edb306SCy Schubert rulemain:
26741edb306SCy Schubert 	ipfrule
26841edb306SCy Schubert 	| bpfrule
26941edb306SCy Schubert 	| exprrule
27041edb306SCy Schubert 	;
27141edb306SCy Schubert 
27241edb306SCy Schubert ipfrule:
27341edb306SCy Schubert 	family tos ttl proto ip
27441edb306SCy Schubert 	;
27541edb306SCy Schubert 
27641edb306SCy Schubert family:	| IPFY_FAMILY IPFY_INET		{ if (use_inet6 == 1) {
27741edb306SCy Schubert 						YYERROR;
27841edb306SCy Schubert 					  } else {
27941edb306SCy Schubert 						frc->fr_family = AF_INET;
28041edb306SCy Schubert 					  }
28141edb306SCy Schubert 					}
28241edb306SCy Schubert 	| IPFY_INET			{ if (use_inet6 == 1) {
28341edb306SCy Schubert 						YYERROR;
28441edb306SCy Schubert 					  } else {
28541edb306SCy Schubert 						frc->fr_family = AF_INET;
28641edb306SCy Schubert 					  }
28741edb306SCy Schubert 					}
28841edb306SCy Schubert 	| IPFY_FAMILY IPFY_INET6	{ if (use_inet6 == -1) {
28941edb306SCy Schubert 						YYERROR;
29041edb306SCy Schubert 					  } else {
29141edb306SCy Schubert 						frc->fr_family = AF_INET6;
29241edb306SCy Schubert 					  }
29341edb306SCy Schubert 					}
29441edb306SCy Schubert 	| IPFY_INET6			{ if (use_inet6 == -1) {
29541edb306SCy Schubert 						YYERROR;
29641edb306SCy Schubert 					  } else {
29741edb306SCy Schubert 						frc->fr_family = AF_INET6;
29841edb306SCy Schubert 					  }
29941edb306SCy Schubert 					}
30041edb306SCy Schubert 	;
30141edb306SCy Schubert 
30241edb306SCy Schubert bpfrule:
30341edb306SCy Schubert 	IPFY_BPFV4 '{' YY_STR '}' 	{ dobpf(4, $3); free($3); }
30441edb306SCy Schubert 	| IPFY_BPFV6 '{' YY_STR '}' 	{ dobpf(6, $3); free($3); }
30541edb306SCy Schubert 	;
30641edb306SCy Schubert 
30741edb306SCy Schubert exprrule:
30841edb306SCy Schubert 	IPFY_IPFEXPR '{' YY_STR '}'	{ doipfexpr($3); }
30941edb306SCy Schubert 	;
31041edb306SCy Schubert 
31141edb306SCy Schubert ruletail:
31241edb306SCy Schubert 	with keep head group
31341edb306SCy Schubert 	;
31441edb306SCy Schubert 
31541edb306SCy Schubert ruletail2:
31641edb306SCy Schubert 	pps age new rulettl comment
31741edb306SCy Schubert 	;
31841edb306SCy Schubert 
31941edb306SCy Schubert intag:	settagin matchtagin
32041edb306SCy Schubert 	;
32141edb306SCy Schubert 
32241edb306SCy Schubert outtag:	settagout matchtagout
32341edb306SCy Schubert 	;
32441edb306SCy Schubert 
32541edb306SCy Schubert insert:
32641edb306SCy Schubert 	'@' YY_NUMBER			{ fr->fr_hits = (U_QUAD_T)$2 + 1; }
32741edb306SCy Schubert 	;
32841edb306SCy Schubert 
32941edb306SCy Schubert collection:
33041edb306SCy Schubert 	| YY_NUMBER			{ fr->fr_collect = $1; }
33141edb306SCy Schubert 	;
33241edb306SCy Schubert 
33341edb306SCy Schubert action:	block
33441edb306SCy Schubert 	| IPFY_PASS			{ fr->fr_flags |= FR_PASS; }
33541edb306SCy Schubert 	| IPFY_NOMATCH			{ fr->fr_flags |= FR_NOMATCH; }
33641edb306SCy Schubert 	| log
33741edb306SCy Schubert 	| IPFY_COUNT			{ fr->fr_flags |= FR_ACCOUNT; }
33841edb306SCy Schubert 	| decaps			{ fr->fr_flags |= FR_DECAPSULATE; }
33941edb306SCy Schubert 	| auth
34041edb306SCy Schubert 	| IPFY_SKIP YY_NUMBER		{ fr->fr_flags |= FR_SKIP;
34141edb306SCy Schubert 					  fr->fr_arg = $2; }
34241edb306SCy Schubert 	| IPFY_CALL func
34341edb306SCy Schubert 	| IPFY_CALL IPFY_NOW func	{ fr->fr_flags |= FR_CALLNOW; }
34441edb306SCy Schubert 	;
34541edb306SCy Schubert 
34641edb306SCy Schubert block:	blocked
34741edb306SCy Schubert 	| blocked blockreturn
34841edb306SCy Schubert 	;
34941edb306SCy Schubert 
35041edb306SCy Schubert blocked:
35141edb306SCy Schubert 	IPFY_BLOCK			{ fr->fr_flags = FR_BLOCK; }
35241edb306SCy Schubert 	;
35341edb306SCy Schubert blockreturn:
35441edb306SCy Schubert 	IPFY_RETICMP			{ fr->fr_flags |= FR_RETICMP; }
35541edb306SCy Schubert 	| IPFY_RETICMP returncode	{ fr->fr_flags |= FR_RETICMP; }
35641edb306SCy Schubert 	| IPFY_RETICMPASDST		{ fr->fr_flags |= FR_FAKEICMP; }
35741edb306SCy Schubert 	| IPFY_RETICMPASDST returncode	{ fr->fr_flags |= FR_FAKEICMP; }
35841edb306SCy Schubert 	| IPFY_RETRST			{ fr->fr_flags |= FR_RETRST; }
35941edb306SCy Schubert 	;
36041edb306SCy Schubert 
36141edb306SCy Schubert decaps:	IPFY_DECAPS
36241edb306SCy Schubert 	| IPFY_DECAPS IPFY_L5AS '(' YY_STR ')'
36341edb306SCy Schubert 					{ fr->fr_icode = atoi($4); }
36441edb306SCy Schubert 	;
36541edb306SCy Schubert 
36641edb306SCy Schubert log:	IPFY_LOG			{ fr->fr_flags |= FR_LOG; }
36741edb306SCy Schubert 	| IPFY_LOG logoptions		{ fr->fr_flags |= FR_LOG; }
36841edb306SCy Schubert 	;
36941edb306SCy Schubert 
37041edb306SCy Schubert auth:	IPFY_AUTH			{ fr->fr_flags |= FR_AUTH; }
37141edb306SCy Schubert 	| IPFY_AUTH blockreturn		{ fr->fr_flags |= FR_AUTH;}
37241edb306SCy Schubert 	| IPFY_PREAUTH			{ fr->fr_flags |= FR_PREAUTH; }
37341edb306SCy Schubert 	;
37441edb306SCy Schubert 
37541edb306SCy Schubert func:	YY_STR '/' YY_NUMBER
37641edb306SCy Schubert 			{ fr->fr_func = nametokva($1, ipfioctls[IPL_LOGIPF]);
37741edb306SCy Schubert 			  fr->fr_arg = $3;
37841edb306SCy Schubert 			  free($1);
37941edb306SCy Schubert 			}
38041edb306SCy Schubert 	;
38141edb306SCy Schubert 
38241edb306SCy Schubert inopts:
38341edb306SCy Schubert 	| inopts inopt
38441edb306SCy Schubert 	;
38541edb306SCy Schubert 
38641edb306SCy Schubert inopt:
38741edb306SCy Schubert 	logopt
38841edb306SCy Schubert 	| quick
38941edb306SCy Schubert 	| on
39041edb306SCy Schubert 	| dup
39141edb306SCy Schubert 	| froute
39241edb306SCy Schubert 	| proute
39341edb306SCy Schubert 	| replyto
39441edb306SCy Schubert 	;
39541edb306SCy Schubert 
39641edb306SCy Schubert outopts:
39741edb306SCy Schubert 	| outopts outopt
39841edb306SCy Schubert 	;
39941edb306SCy Schubert 
40041edb306SCy Schubert outopt:
40141edb306SCy Schubert 	logopt
40241edb306SCy Schubert 	| quick
40341edb306SCy Schubert 	| on
40441edb306SCy Schubert 	| dup
40541edb306SCy Schubert 	| proute
40641edb306SCy Schubert 	| froute
40741edb306SCy Schubert 	| replyto
40841edb306SCy Schubert 	;
40941edb306SCy Schubert 
41041edb306SCy Schubert tos:	| settos YY_NUMBER	{ DOALL(fr->fr_tos = $2; fr->fr_mtos = 0xff;) }
41141edb306SCy Schubert 	| settos YY_HEX	{ DOALL(fr->fr_tos = $2; fr->fr_mtos = 0xff;) }
41241edb306SCy Schubert 	| settos lstart toslist lend
41341edb306SCy Schubert 	;
41441edb306SCy Schubert 
41541edb306SCy Schubert settos:	IPFY_TOS			{ setipftype(); }
41641edb306SCy Schubert 	;
41741edb306SCy Schubert 
41841edb306SCy Schubert toslist:
41941edb306SCy Schubert 	YY_NUMBER	{ DOALL(fr->fr_tos = $1; fr->fr_mtos = 0xff;) }
42041edb306SCy Schubert 	| YY_HEX	{ DOREM(fr->fr_tos = $1; fr->fr_mtos = 0xff;) }
42141edb306SCy Schubert 	| toslist lmore YY_NUMBER
42241edb306SCy Schubert 			{ DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) }
42341edb306SCy Schubert 	| toslist lmore YY_HEX
42441edb306SCy Schubert 			{ DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) }
42541edb306SCy Schubert 	;
42641edb306SCy Schubert 
42741edb306SCy Schubert ttl:	| setttl YY_NUMBER
42841edb306SCy Schubert 			{ DOALL(fr->fr_ttl = $2; fr->fr_mttl = 0xff;) }
42941edb306SCy Schubert 	| setttl lstart ttllist lend
43041edb306SCy Schubert 	;
43141edb306SCy Schubert 
43241edb306SCy Schubert lstart:	'{'				{ newlist = 1; fr = frc; added = 0; }
43341edb306SCy Schubert 	;
43441edb306SCy Schubert 
43541edb306SCy Schubert lend:	'}'				{ nrules += added; }
43641edb306SCy Schubert 	;
43741edb306SCy Schubert 
43841edb306SCy Schubert lmore:	lanother			{ if (newlist == 1) {
43941edb306SCy Schubert 						newlist = 0;
44041edb306SCy Schubert 					  }
44141edb306SCy Schubert 					  fr = addrule();
44241edb306SCy Schubert 					  if (yycont != NULL)
44341edb306SCy Schubert 						*yycont = 1;
44441edb306SCy Schubert 					}
44541edb306SCy Schubert 	;
44641edb306SCy Schubert 
44741edb306SCy Schubert lanother:
44841edb306SCy Schubert 	| ','
44941edb306SCy Schubert 	;
45041edb306SCy Schubert 
45141edb306SCy Schubert setttl:	IPFY_TTL			{ setipftype(); }
45241edb306SCy Schubert 	;
45341edb306SCy Schubert 
45441edb306SCy Schubert ttllist:
45541edb306SCy Schubert 	YY_NUMBER	{ DOREM(fr->fr_ttl = $1; fr->fr_mttl = 0xff;) }
45641edb306SCy Schubert 	| ttllist lmore YY_NUMBER
45741edb306SCy Schubert 			{ DOREM(fr->fr_ttl = $3; fr->fr_mttl = 0xff;) }
45841edb306SCy Schubert 	;
45941edb306SCy Schubert 
46041edb306SCy Schubert proto:	| protox protocol		{ yyresetdict(); }
46141edb306SCy Schubert 	;
46241edb306SCy Schubert 
46341edb306SCy Schubert protox:	IPFY_PROTO			{ setipftype();
46441edb306SCy Schubert 					  fr = frc;
46541edb306SCy Schubert 					  yysetdict(NULL); }
46641edb306SCy Schubert 	;
46741edb306SCy Schubert 
46841edb306SCy Schubert ip:	srcdst flags icmp
46941edb306SCy Schubert 	;
47041edb306SCy Schubert 
47141edb306SCy Schubert group:	| IPFY_GROUP groupname		{ DOALL(setgroup(&fr, $2); \
47241edb306SCy Schubert 						fillgroup(fr););
47341edb306SCy Schubert 					  free($2);
47441edb306SCy Schubert 					}
47541edb306SCy Schubert 	;
47641edb306SCy Schubert 
47741edb306SCy Schubert head:	| IPFY_HEAD groupname		{ DOALL(setgrhead(&fr, $2););
47841edb306SCy Schubert 					  free($2);
47941edb306SCy Schubert 					}
48041edb306SCy Schubert 	;
48141edb306SCy Schubert 
48241edb306SCy Schubert groupname:
48341edb306SCy Schubert 	YY_STR				{ $$ = $1;
48441edb306SCy Schubert 					  if (strlen($$) >= FR_GROUPLEN)
48541edb306SCy Schubert 						$$[FR_GROUPLEN - 1] = '\0';
48641edb306SCy Schubert 					}
48741edb306SCy Schubert 	| YY_NUMBER			{ $$ = malloc(16);
48841edb306SCy Schubert 					  sprintf($$, "%d", $1);
48941edb306SCy Schubert 					}
49041edb306SCy Schubert 	;
49141edb306SCy Schubert 
49241edb306SCy Schubert settagin:
49341edb306SCy Schubert 	| IPFY_SETTAG '(' taginlist ')'
49441edb306SCy Schubert 	;
49541edb306SCy Schubert 
49641edb306SCy Schubert taginlist:
49741edb306SCy Schubert 	taginspec
49841edb306SCy Schubert 	| taginlist ',' taginspec
49941edb306SCy Schubert 	;
50041edb306SCy Schubert 
50141edb306SCy Schubert taginspec:
50241edb306SCy Schubert 	logtag
50341edb306SCy Schubert 	;
50441edb306SCy Schubert 
50541edb306SCy Schubert nattag:	IPFY_NAT '=' YY_STR		{ DOALL(strncpy(fr->fr_nattag.ipt_tag,\
50641edb306SCy Schubert 						$3, IPFTAG_LEN););
50741edb306SCy Schubert 					  free($3); }
50841edb306SCy Schubert 	| IPFY_NAT '=' YY_NUMBER	{ DOALL(sprintf(fr->fr_nattag.ipt_tag,\
50941edb306SCy Schubert 						"%d", $3 & 0xffffffff);) }
51041edb306SCy Schubert 	;
51141edb306SCy Schubert 
51241edb306SCy Schubert logtag:	IPFY_LOG '=' YY_NUMBER		{ DOALL(fr->fr_logtag = $3;) }
51341edb306SCy Schubert 	;
51441edb306SCy Schubert 
51541edb306SCy Schubert settagout:
51641edb306SCy Schubert 	| IPFY_SETTAG '(' tagoutlist ')'
51741edb306SCy Schubert 	;
51841edb306SCy Schubert 
51941edb306SCy Schubert tagoutlist:
52041edb306SCy Schubert 	tagoutspec
52141edb306SCy Schubert 	| tagoutlist ',' tagoutspec
52241edb306SCy Schubert 	;
52341edb306SCy Schubert 
52441edb306SCy Schubert tagoutspec:
52541edb306SCy Schubert 	logtag
52641edb306SCy Schubert 	| nattag
52741edb306SCy Schubert 	;
52841edb306SCy Schubert 
52941edb306SCy Schubert matchtagin:
53041edb306SCy Schubert 	| IPFY_MATCHTAG '(' tagoutlist ')'
53141edb306SCy Schubert 	;
53241edb306SCy Schubert 
53341edb306SCy Schubert matchtagout:
53441edb306SCy Schubert 	| IPFY_MATCHTAG '(' taginlist ')'
53541edb306SCy Schubert 	;
53641edb306SCy Schubert 
53741edb306SCy Schubert pps:	| IPFY_PPS YY_NUMBER		{ DOALL(fr->fr_pps = $2;) }
53841edb306SCy Schubert 	;
53941edb306SCy Schubert 
54041edb306SCy Schubert new:	| savegroup file restoregroup
54141edb306SCy Schubert 	;
54241edb306SCy Schubert 
54341edb306SCy Schubert rulettl:
54441edb306SCy Schubert 	| IPFY_RULETTL YY_NUMBER	{ DOALL(fr->fr_die = $2;) }
54541edb306SCy Schubert 	;
54641edb306SCy Schubert 
54741edb306SCy Schubert comment:
54841edb306SCy Schubert 	| IPFY_COMMENT YY_STR		{ DOALL(fr->fr_comment = addname(&fr, \
54941edb306SCy Schubert 						$2);) }
55041edb306SCy Schubert 	;
55141edb306SCy Schubert 
55241edb306SCy Schubert savegroup:
55341edb306SCy Schubert 	'{'
55441edb306SCy Schubert 	;
55541edb306SCy Schubert 
55641edb306SCy Schubert restoregroup:
55741edb306SCy Schubert 	'}'
55841edb306SCy Schubert 	;
55941edb306SCy Schubert 
56041edb306SCy Schubert logopt:	log
56141edb306SCy Schubert 	;
56241edb306SCy Schubert 
56341edb306SCy Schubert quick:	IPFY_QUICK				{ fr->fr_flags |= FR_QUICK; }
56441edb306SCy Schubert 	;
56541edb306SCy Schubert 
56641edb306SCy Schubert on:	IPFY_ON onname				{ setifname(&fr, 0, $2.if1);
56741edb306SCy Schubert 						  free($2.if1);
56841edb306SCy Schubert 						  if ($2.if2 != NULL) {
56941edb306SCy Schubert 							setifname(&fr, 1,
57041edb306SCy Schubert 								  $2.if2);
57141edb306SCy Schubert 							free($2.if2);
57241edb306SCy Schubert 						  }
57341edb306SCy Schubert 						}
57441edb306SCy Schubert 	| IPFY_ON lstart onlist lend
57541edb306SCy Schubert 	| IPFY_ON onname IPFY_INVIA vianame	{ setifname(&fr, 0, $2.if1);
57641edb306SCy Schubert 						  free($2.if1);
57741edb306SCy Schubert 						  if ($2.if2 != NULL) {
57841edb306SCy Schubert 							setifname(&fr, 1,
57941edb306SCy Schubert 								  $2.if2);
58041edb306SCy Schubert 							free($2.if2);
58141edb306SCy Schubert 						  }
58241edb306SCy Schubert 						}
58341edb306SCy Schubert 	| IPFY_ON onname IPFY_OUTVIA vianame	{ setifname(&fr, 0, $2.if1);
58441edb306SCy Schubert 						  free($2.if1);
58541edb306SCy Schubert 						  if ($2.if2 != NULL) {
58641edb306SCy Schubert 							setifname(&fr, 1,
58741edb306SCy Schubert 								  $2.if2);
58841edb306SCy Schubert 							free($2.if2);
58941edb306SCy Schubert 						  }
59041edb306SCy Schubert 						}
59141edb306SCy Schubert 	;
59241edb306SCy Schubert 
59341edb306SCy Schubert onlist:	onname			{ DOREM(setifname(&fr, 0, $1.if1);	   \
59441edb306SCy Schubert 					if ($1.if2 != NULL)		   \
59541edb306SCy Schubert 						setifname(&fr, 1, $1.if2); \
59641edb306SCy Schubert 					)
59741edb306SCy Schubert 				  free($1.if1);
59841edb306SCy Schubert 				  if ($1.if2 != NULL)
59941edb306SCy Schubert 					free($1.if2);
60041edb306SCy Schubert 				}
60141edb306SCy Schubert 	| onlist lmore onname	{ DOREM(setifname(&fr, 0, $3.if1);	   \
60241edb306SCy Schubert 					if ($3.if2 != NULL)		   \
60341edb306SCy Schubert 						setifname(&fr, 1, $3.if2); \
60441edb306SCy Schubert 					)
60541edb306SCy Schubert 				  free($3.if1);
60641edb306SCy Schubert 				  if ($3.if2 != NULL)
60741edb306SCy Schubert 					free($3.if2);
60841edb306SCy Schubert 				}
60941edb306SCy Schubert 	;
61041edb306SCy Schubert 
61141edb306SCy Schubert onname:	interfacename		{ $$.if1 = $1;
61241edb306SCy Schubert 				  $$.if2 = NULL;
61341edb306SCy Schubert 				}
61441edb306SCy Schubert 	| interfacename ',' interfacename
61541edb306SCy Schubert 				{ $$.if1 = $1;
61641edb306SCy Schubert 				  $$.if2 = $3;
61741edb306SCy Schubert 				}
61841edb306SCy Schubert 	;
61941edb306SCy Schubert 
62041edb306SCy Schubert vianame:
62141edb306SCy Schubert 	name			{ setifname(&fr, 2, $1);
62241edb306SCy Schubert 				  free($1);
62341edb306SCy Schubert 				}
62441edb306SCy Schubert 	| name ',' name		{ setifname(&fr, 2, $1);
62541edb306SCy Schubert 				  free($1);
62641edb306SCy Schubert 				  setifname(&fr, 3, $3);
62741edb306SCy Schubert 				  free($3);
62841edb306SCy Schubert 				}
62941edb306SCy Schubert 	;
63041edb306SCy Schubert 
63141edb306SCy Schubert dup:	IPFY_DUPTO name
63241edb306SCy Schubert 	{ int idx = addname(&fr, $2);
63341edb306SCy Schubert 	  fr->fr_dif.fd_name = idx;
63441edb306SCy Schubert 	  free($2);
63541edb306SCy Schubert 	}
63641edb306SCy Schubert 	| IPFY_DUPTO IPFY_DSTLIST '/' name
63741edb306SCy Schubert 	{ int idx = addname(&fr, $4);
63841edb306SCy Schubert 	  fr->fr_dif.fd_name = idx;
63941edb306SCy Schubert 	  fr->fr_dif.fd_type = FRD_DSTLIST;
64041edb306SCy Schubert 	  free($4);
64141edb306SCy Schubert 	}
64241edb306SCy Schubert 	| IPFY_DUPTO name duptoseparator hostname
64341edb306SCy Schubert 	{ int idx = addname(&fr, $2);
64441edb306SCy Schubert 	  fr->fr_dif.fd_name = idx;
64541edb306SCy Schubert 	  fr->fr_dif.fd_ptr = (void *)-1;
64641edb306SCy Schubert 	  fr->fr_dif.fd_ip6 = $4.adr;
64741edb306SCy Schubert 	  if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC)
64841edb306SCy Schubert 		fr->fr_family = $4.f;
64941edb306SCy Schubert 	  yyexpectaddr = 0;
65041edb306SCy Schubert 	  free($2);
65141edb306SCy Schubert 	}
65241edb306SCy Schubert 	;
65341edb306SCy Schubert 
65441edb306SCy Schubert duptoseparator:
65541edb306SCy Schubert 	':'	{ yyexpectaddr = 1; yycont = &yyexpectaddr; resetaddr(); }
65641edb306SCy Schubert 	;
65741edb306SCy Schubert 
65841edb306SCy Schubert froute:	IPFY_FROUTE			{ fr->fr_flags |= FR_FASTROUTE; }
65941edb306SCy Schubert 	;
66041edb306SCy Schubert 
66141edb306SCy Schubert proute:	routeto name
66241edb306SCy Schubert 	{ int idx = addname(&fr, $2);
66341edb306SCy Schubert 	  fr->fr_tif.fd_name = idx;
66441edb306SCy Schubert 	  free($2);
66541edb306SCy Schubert 	}
66641edb306SCy Schubert 	| routeto IPFY_DSTLIST '/' name
66741edb306SCy Schubert 	{ int idx = addname(&fr, $4);
66841edb306SCy Schubert 	  fr->fr_tif.fd_name = idx;
66941edb306SCy Schubert 	  fr->fr_tif.fd_type = FRD_DSTLIST;
67041edb306SCy Schubert 	  free($4);
67141edb306SCy Schubert 	}
67241edb306SCy Schubert 	| routeto name duptoseparator hostname
67341edb306SCy Schubert 	{ int idx = addname(&fr, $2);
67441edb306SCy Schubert 	  fr->fr_tif.fd_name = idx;
67541edb306SCy Schubert 	  fr->fr_tif.fd_ptr = (void *)-1;
67641edb306SCy Schubert 	  fr->fr_tif.fd_ip6 = $4.adr;
67741edb306SCy Schubert 	  if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC)
67841edb306SCy Schubert 		fr->fr_family = $4.f;
67941edb306SCy Schubert 	  yyexpectaddr = 0;
68041edb306SCy Schubert 	  free($2);
68141edb306SCy Schubert 	}
68241edb306SCy Schubert 	;
68341edb306SCy Schubert 
68441edb306SCy Schubert routeto:
68541edb306SCy Schubert 	IPFY_TO
68641edb306SCy Schubert 	| IPFY_ROUTETO
68741edb306SCy Schubert 	;
68841edb306SCy Schubert 
68941edb306SCy Schubert replyto:
69041edb306SCy Schubert 	IPFY_REPLY_TO name
69141edb306SCy Schubert 	{ int idx = addname(&fr, $2);
69241edb306SCy Schubert 	  fr->fr_rif.fd_name = idx;
69341edb306SCy Schubert 	  free($2);
69441edb306SCy Schubert 	}
69541edb306SCy Schubert 	| IPFY_REPLY_TO IPFY_DSTLIST '/' name
69641edb306SCy Schubert 	{ fr->fr_rif.fd_name = addname(&fr, $4);
69741edb306SCy Schubert 	  fr->fr_rif.fd_type = FRD_DSTLIST;
69841edb306SCy Schubert 	  free($4);
69941edb306SCy Schubert 	}
70041edb306SCy Schubert 	| IPFY_REPLY_TO name duptoseparator hostname
70141edb306SCy Schubert 	{ int idx = addname(&fr, $2);
70241edb306SCy Schubert 	  fr->fr_rif.fd_name = idx;
70341edb306SCy Schubert 	  fr->fr_rif.fd_ptr = (void *)-1;
70441edb306SCy Schubert 	  fr->fr_rif.fd_ip6 = $4.adr;
70541edb306SCy Schubert 	  if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC)
70641edb306SCy Schubert 		fr->fr_family = $4.f;
70741edb306SCy Schubert 	  free($2);
70841edb306SCy Schubert 	}
70941edb306SCy Schubert 	;
71041edb306SCy Schubert 
71141edb306SCy Schubert logoptions:
71241edb306SCy Schubert 	logoption
71341edb306SCy Schubert 	| logoptions logoption
71441edb306SCy Schubert 	;
71541edb306SCy Schubert 
71641edb306SCy Schubert logoption:
71741edb306SCy Schubert 	IPFY_BODY			{ fr->fr_flags |= FR_LOGBODY; }
71841edb306SCy Schubert 	| IPFY_FIRST			{ fr->fr_flags |= FR_LOGFIRST; }
71941edb306SCy Schubert 	| IPFY_ORBLOCK			{ fr->fr_flags |= FR_LOGORBLOCK; }
72041edb306SCy Schubert 	| level loglevel		{ unsetsyslog(); }
72141edb306SCy Schubert 	;
72241edb306SCy Schubert 
72341edb306SCy Schubert returncode:
72441edb306SCy Schubert 	starticmpcode icmpcode ')'	{ fr->fr_icode = $2; yyresetdict(); }
72541edb306SCy Schubert 	;
72641edb306SCy Schubert 
72741edb306SCy Schubert starticmpcode:
72841edb306SCy Schubert 	'('				{ yysetdict(icmpcodewords); }
72941edb306SCy Schubert 	;
73041edb306SCy Schubert 
73141edb306SCy Schubert srcdst:	| IPFY_ALL
73241edb306SCy Schubert 	| fromto
73341edb306SCy Schubert 	;
73441edb306SCy Schubert 
73541edb306SCy Schubert protocol:
73641edb306SCy Schubert 	YY_NUMBER		{ DOALL(fr->fr_proto = $1; \
73741edb306SCy Schubert 					fr->fr_mproto = 0xff;)
73841edb306SCy Schubert 				}
73941edb306SCy Schubert 	| YY_STR		{ if (!strcmp($1, "tcp-udp")) {
74041edb306SCy Schubert 					DOALL(fr->fr_flx |= FI_TCPUDP; \
74141edb306SCy Schubert 					      fr->fr_mflx |= FI_TCPUDP;)
74241edb306SCy Schubert 				  } else {
74341edb306SCy Schubert 					int p = getproto($1);
74441edb306SCy Schubert 					if (p == -1)
74541edb306SCy Schubert 						yyerror("protocol unknown");
74641edb306SCy Schubert 					DOALL(fr->fr_proto = p; \
74741edb306SCy Schubert 						fr->fr_mproto = 0xff;)
74841edb306SCy Schubert 				  }
74941edb306SCy Schubert 				  free($1);
75041edb306SCy Schubert 				}
75141edb306SCy Schubert 	| YY_STR nextstring YY_STR
75241edb306SCy Schubert 				{ if (!strcmp($1, "tcp") &&
75341edb306SCy Schubert 				      !strcmp($3, "udp")) {
75441edb306SCy Schubert 					DOREM(fr->fr_flx |= FI_TCPUDP; \
75541edb306SCy Schubert 					      fr->fr_mflx |= FI_TCPUDP;)
75641edb306SCy Schubert 				  } else {
75741edb306SCy Schubert 					YYERROR;
75841edb306SCy Schubert 				  }
75941edb306SCy Schubert 				  free($1);
76041edb306SCy Schubert 				  free($3);
76141edb306SCy Schubert 				}
76241edb306SCy Schubert 	;
76341edb306SCy Schubert 
76441edb306SCy Schubert nextstring:
76541edb306SCy Schubert 	'/'			{ yysetdict(NULL); }
76641edb306SCy Schubert 	;
76741edb306SCy Schubert 
76841edb306SCy Schubert fromto:	from srcobject to dstobject	{ yyexpectaddr = 0; yycont = NULL; }
76941edb306SCy Schubert 	| to dstobject			{ yyexpectaddr = 0; yycont = NULL; }
77041edb306SCy Schubert 	| from srcobject		{ yyexpectaddr = 0; yycont = NULL; }
77141edb306SCy Schubert 	;
77241edb306SCy Schubert 
77341edb306SCy Schubert from:	IPFY_FROM			{ setipftype();
77441edb306SCy Schubert 					  if (fr == NULL)
77541edb306SCy Schubert 						fr = frc;
77641edb306SCy Schubert 					  yyexpectaddr = 1;
77741edb306SCy Schubert 					  if (yydebug)
77841edb306SCy Schubert 						printf("set yyexpectaddr\n");
77941edb306SCy Schubert 					  yycont = &yyexpectaddr;
78041edb306SCy Schubert 					  yysetdict(addrwords);
78141edb306SCy Schubert 					  resetaddr(); }
78241edb306SCy Schubert 	;
78341edb306SCy Schubert 
78441edb306SCy Schubert to:	IPFY_TO				{ if (fr == NULL)
78541edb306SCy Schubert 						fr = frc;
78641edb306SCy Schubert 					  yyexpectaddr = 1;
78741edb306SCy Schubert 					  if (yydebug)
78841edb306SCy Schubert 						printf("set yyexpectaddr\n");
78941edb306SCy Schubert 					  yycont = &yyexpectaddr;
79041edb306SCy Schubert 					  yysetdict(addrwords);
79141edb306SCy Schubert 					  resetaddr();
79241edb306SCy Schubert 					}
79341edb306SCy Schubert 	;
79441edb306SCy Schubert 
79541edb306SCy Schubert with:	| andwith withlist
79641edb306SCy Schubert 	;
79741edb306SCy Schubert 
79841edb306SCy Schubert andwith:
79941edb306SCy Schubert 	IPFY_WITH			{ nowith = 0; setipftype(); }
80041edb306SCy Schubert 	| IPFY_AND			{ nowith = 0; setipftype(); }
80141edb306SCy Schubert 	;
80241edb306SCy Schubert 
80341edb306SCy Schubert flags:	| startflags flagset
80441edb306SCy Schubert 		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) }
80541edb306SCy Schubert 	| startflags flagset '/' flagset
80641edb306SCy Schubert 		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
80741edb306SCy Schubert 	| startflags '/' flagset
80841edb306SCy Schubert 		{ DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) }
80941edb306SCy Schubert 	| startflags YY_NUMBER
81041edb306SCy Schubert 		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) }
81141edb306SCy Schubert 	| startflags '/' YY_NUMBER
81241edb306SCy Schubert 		{ DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) }
81341edb306SCy Schubert 	| startflags YY_NUMBER '/' YY_NUMBER
81441edb306SCy Schubert 		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
81541edb306SCy Schubert 	| startflags flagset '/' YY_NUMBER
81641edb306SCy Schubert 		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
81741edb306SCy Schubert 	| startflags YY_NUMBER '/' flagset
81841edb306SCy Schubert 		{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
81941edb306SCy Schubert 	;
82041edb306SCy Schubert 
82141edb306SCy Schubert startflags:
82241edb306SCy Schubert 	IPFY_FLAGS	{ if (frc->fr_type != FR_T_IPF)
82341edb306SCy Schubert 				yyerror("flags with non-ipf type rule");
82441edb306SCy Schubert 			  if (frc->fr_proto != IPPROTO_TCP)
82541edb306SCy Schubert 				yyerror("flags with non-TCP rule");
82641edb306SCy Schubert 			}
82741edb306SCy Schubert 	;
82841edb306SCy Schubert 
82941edb306SCy Schubert flagset:
83041edb306SCy Schubert 	YY_STR				{ $$ = tcpflags($1); free($1); }
83141edb306SCy Schubert 	| YY_HEX			{ $$ = $1; }
83241edb306SCy Schubert 	;
83341edb306SCy Schubert 
83441edb306SCy Schubert srcobject:
83541edb306SCy Schubert 	{ yyresetdict(); } fromport
83641edb306SCy Schubert 	| srcaddr srcport
83741edb306SCy Schubert 	| '!' srcaddr srcport
83841edb306SCy Schubert 		{ DOALL(fr->fr_flags |= FR_NOTSRCIP;) }
83941edb306SCy Schubert 	;
84041edb306SCy Schubert 
84141edb306SCy Schubert srcaddr:
84241edb306SCy Schubert 	addr	{ build_srcaddr_af(fr, &$1); }
84341edb306SCy Schubert 	| lstart srcaddrlist lend
84441edb306SCy Schubert 	;
84541edb306SCy Schubert 
84641edb306SCy Schubert srcaddrlist:
84741edb306SCy Schubert 	addr	{ build_srcaddr_af(fr, &$1); }
84841edb306SCy Schubert 	| srcaddrlist lmore addr
84941edb306SCy Schubert 		{ build_srcaddr_af(fr, &$3); }
85041edb306SCy Schubert 	;
85141edb306SCy Schubert 
85241edb306SCy Schubert srcport:
85341edb306SCy Schubert 	| portcomp
85441edb306SCy Schubert 		{ DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1;) }
85541edb306SCy Schubert 	| portrange
85641edb306SCy Schubert 		{ DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1; \
85741edb306SCy Schubert 			fr->fr_stop = $1.p2;) }
85841edb306SCy Schubert 	| porteq lstart srcportlist lend
85941edb306SCy Schubert 		{ yyresetdict(); }
86041edb306SCy Schubert 	;
86141edb306SCy Schubert 
86241edb306SCy Schubert fromport:
86341edb306SCy Schubert 	portcomp
86441edb306SCy Schubert 		{ DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1;) }
86541edb306SCy Schubert 	| portrange
86641edb306SCy Schubert 		{ DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1; \
86741edb306SCy Schubert 			fr->fr_stop = $1.p2;) }
86841edb306SCy Schubert 	| porteq lstart srcportlist lend
86941edb306SCy Schubert 		{ yyresetdict(); }
87041edb306SCy Schubert 	;
87141edb306SCy Schubert 
87241edb306SCy Schubert srcportlist:
87341edb306SCy Schubert 	portnum		{ DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $1;) }
87441edb306SCy Schubert 	| portnum ':' portnum
87541edb306SCy Schubert 			{ DOREM(fr->fr_scmp = FR_INCRANGE; fr->fr_sport = $1; \
87641edb306SCy Schubert 				fr->fr_stop = $3;) }
87741edb306SCy Schubert 	| portnum YY_RANGE_IN portnum
87841edb306SCy Schubert 			{ DOREM(fr->fr_scmp = FR_INRANGE; fr->fr_sport = $1; \
87941edb306SCy Schubert 				fr->fr_stop = $3;) }
88041edb306SCy Schubert 	| srcportlist lmore portnum
88141edb306SCy Schubert 			{ DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $3;) }
88241edb306SCy Schubert 	| srcportlist lmore portnum ':' portnum
88341edb306SCy Schubert 			{ DOREM(fr->fr_scmp = FR_INCRANGE; fr->fr_sport = $3; \
88441edb306SCy Schubert 				fr->fr_stop = $5;) }
88541edb306SCy Schubert 	| srcportlist lmore portnum YY_RANGE_IN portnum
88641edb306SCy Schubert 			{ DOREM(fr->fr_scmp = FR_INRANGE; fr->fr_sport = $3; \
88741edb306SCy Schubert 				fr->fr_stop = $5;) }
88841edb306SCy Schubert 	;
88941edb306SCy Schubert 
89041edb306SCy Schubert dstobject:
89141edb306SCy Schubert 	{ yyresetdict(); } toport
89241edb306SCy Schubert 	| dstaddr dstport
89341edb306SCy Schubert 	| '!' dstaddr dstport
89441edb306SCy Schubert 			{ DOALL(fr->fr_flags |= FR_NOTDSTIP;) }
89541edb306SCy Schubert 	;
89641edb306SCy Schubert 
89741edb306SCy Schubert dstaddr:
89841edb306SCy Schubert 	addr	{ if (($1.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) &&
89941edb306SCy Schubert 		      ($1.f != frc->fr_family))
90041edb306SCy Schubert 			yyerror("1.src/dst address family mismatch");
90141edb306SCy Schubert 		  build_dstaddr_af(fr, &$1);
90241edb306SCy Schubert 		}
90341edb306SCy Schubert 	| lstart dstaddrlist lend
90441edb306SCy Schubert 	;
90541edb306SCy Schubert 
90641edb306SCy Schubert dstaddrlist:
90741edb306SCy Schubert 	addr	{ if (($1.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) &&
90841edb306SCy Schubert 		      ($1.f != frc->fr_family))
90941edb306SCy Schubert 			yyerror("2.src/dst address family mismatch");
91041edb306SCy Schubert 		  build_dstaddr_af(fr, &$1);
91141edb306SCy Schubert 		}
91241edb306SCy Schubert 	| dstaddrlist lmore addr
91341edb306SCy Schubert 		{ if (($3.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) &&
91441edb306SCy Schubert 		      ($3.f != frc->fr_family))
91541edb306SCy Schubert 			yyerror("3.src/dst address family mismatch");
91641edb306SCy Schubert 		  build_dstaddr_af(fr, &$3);
91741edb306SCy Schubert 		}
91841edb306SCy Schubert 	;
91941edb306SCy Schubert 
92041edb306SCy Schubert 
92141edb306SCy Schubert dstport:
92241edb306SCy Schubert 	| portcomp
92341edb306SCy Schubert 		{ DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1;) }
92441edb306SCy Schubert 	| portrange
92541edb306SCy Schubert 		{ DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1; \
92641edb306SCy Schubert 			fr->fr_dtop = $1.p2;) }
92741edb306SCy Schubert 	| porteq lstart dstportlist lend
92841edb306SCy Schubert 		{ yyresetdict(); }
92941edb306SCy Schubert 	;
93041edb306SCy Schubert 
93141edb306SCy Schubert toport:
93241edb306SCy Schubert 	portcomp
93341edb306SCy Schubert 		{ DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1;) }
93441edb306SCy Schubert 	| portrange
93541edb306SCy Schubert 		{ DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1; \
93641edb306SCy Schubert 			fr->fr_dtop = $1.p2;) }
93741edb306SCy Schubert 	| porteq lstart dstportlist lend
93841edb306SCy Schubert 		{ yyresetdict(); }
93941edb306SCy Schubert 	;
94041edb306SCy Schubert 
94141edb306SCy Schubert dstportlist:
94241edb306SCy Schubert 	portnum		{ DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $1;) }
94341edb306SCy Schubert 	| portnum ':' portnum
94441edb306SCy Schubert 			{ DOREM(fr->fr_dcmp = FR_INCRANGE; fr->fr_dport = $1; \
94541edb306SCy Schubert 				fr->fr_dtop = $3;) }
94641edb306SCy Schubert 	| portnum YY_RANGE_IN portnum
94741edb306SCy Schubert 			{ DOREM(fr->fr_dcmp = FR_INRANGE; fr->fr_dport = $1; \
94841edb306SCy Schubert 				fr->fr_dtop = $3;) }
94941edb306SCy Schubert 	| dstportlist lmore portnum
95041edb306SCy Schubert 			{ DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $3;) }
95141edb306SCy Schubert 	| dstportlist lmore portnum ':' portnum
95241edb306SCy Schubert 			{ DOREM(fr->fr_dcmp = FR_INCRANGE; fr->fr_dport = $3; \
95341edb306SCy Schubert 				fr->fr_dtop = $5;) }
95441edb306SCy Schubert 	| dstportlist lmore portnum YY_RANGE_IN portnum
95541edb306SCy Schubert 			{ DOREM(fr->fr_dcmp = FR_INRANGE; fr->fr_dport = $3; \
95641edb306SCy Schubert 				fr->fr_dtop = $5;) }
95741edb306SCy Schubert 	;
95841edb306SCy Schubert 
95941edb306SCy Schubert addr:	pool '/' YY_NUMBER		{ pooled = 1;
96041edb306SCy Schubert 					  yyexpectaddr = 0;
96141edb306SCy Schubert 					  $$.type = FRI_LOOKUP;
96241edb306SCy Schubert 					  $$.v = 0;
96341edb306SCy Schubert 					  $$.ifpos = -1;
96441edb306SCy Schubert 					  $$.f = AF_UNSPEC;
96541edb306SCy Schubert 					  $$.a.iplookuptype = IPLT_POOL;
96641edb306SCy Schubert 					  $$.a.iplookupsubtype = 0;
96741edb306SCy Schubert 					  $$.a.iplookupnum = $3; }
96841edb306SCy Schubert 	| pool '/' YY_STR		{ pooled = 1;
96941edb306SCy Schubert 					  $$.ifpos = -1;
97041edb306SCy Schubert 					  $$.f = AF_UNSPEC;
97141edb306SCy Schubert 					  $$.type = FRI_LOOKUP;
97241edb306SCy Schubert 					  $$.a.iplookuptype = IPLT_POOL;
97341edb306SCy Schubert 					  $$.a.iplookupsubtype = 1;
97441edb306SCy Schubert 					  $$.a.iplookupname = addname(&fr, $3);
97541edb306SCy Schubert 					}
97641edb306SCy Schubert 	| pool '=' '('			{ yyexpectaddr = 1;
97741edb306SCy Schubert 					  pooled = 1;
97841edb306SCy Schubert 					}
97941edb306SCy Schubert 			poollist ')'	{ yyexpectaddr = 0;
98041edb306SCy Schubert 					  $$.v = 0;
98141edb306SCy Schubert 					  $$.ifpos = -1;
98241edb306SCy Schubert 					  $$.f = AF_UNSPEC;
98341edb306SCy Schubert 					  $$.type = FRI_LOOKUP;
98441edb306SCy Schubert 					  $$.a.iplookuptype = IPLT_POOL;
98541edb306SCy Schubert 					  $$.a.iplookupsubtype = 0;
98641edb306SCy Schubert 					  $$.a.iplookupnum = makepool($5);
98741edb306SCy Schubert 					}
98841edb306SCy Schubert 	| hash '/' YY_NUMBER		{ hashed = 1;
98941edb306SCy Schubert 					  yyexpectaddr = 0;
99041edb306SCy Schubert 					  $$.v = 0;
99141edb306SCy Schubert 					  $$.ifpos = -1;
99241edb306SCy Schubert 					  $$.f = AF_UNSPEC;
99341edb306SCy Schubert 					  $$.type = FRI_LOOKUP;
99441edb306SCy Schubert 					  $$.a.iplookuptype = IPLT_HASH;
99541edb306SCy Schubert 					  $$.a.iplookupsubtype = 0;
99641edb306SCy Schubert 					  $$.a.iplookupnum = $3;
99741edb306SCy Schubert 					}
99841edb306SCy Schubert 	| hash '/' YY_STR		{ hashed = 1;
99941edb306SCy Schubert 					  $$.type = FRI_LOOKUP;
100041edb306SCy Schubert 					  $$.v = 0;
100141edb306SCy Schubert 					  $$.ifpos = -1;
100241edb306SCy Schubert 					  $$.f = AF_UNSPEC;
100341edb306SCy Schubert 					  $$.a.iplookuptype = IPLT_HASH;
100441edb306SCy Schubert 					  $$.a.iplookupsubtype = 1;
100541edb306SCy Schubert 					  $$.a.iplookupname = addname(&fr, $3);
100641edb306SCy Schubert 					}
100741edb306SCy Schubert 	| hash '=' '(' 			{ hashed = 1;
100841edb306SCy Schubert 					  yyexpectaddr = 1;
100941edb306SCy Schubert 					}
101041edb306SCy Schubert 			addrlist ')'	{ yyexpectaddr = 0;
101141edb306SCy Schubert 					  $$.v = 0;
101241edb306SCy Schubert 					  $$.ifpos = -1;
101341edb306SCy Schubert 					  $$.f = AF_UNSPEC;
101441edb306SCy Schubert 					  $$.type = FRI_LOOKUP;
101541edb306SCy Schubert 					  $$.a.iplookuptype = IPLT_HASH;
101641edb306SCy Schubert 					  $$.a.iplookupsubtype = 0;
101741edb306SCy Schubert 					  $$.a.iplookupnum = makehash($5);
101841edb306SCy Schubert 					}
101941edb306SCy Schubert 	| ipaddr			{ $$ = $1;
102041edb306SCy Schubert 					  yyexpectaddr = 0; }
102141edb306SCy Schubert 	;
102241edb306SCy Schubert 
102341edb306SCy Schubert ipaddr:	IPFY_ANY			{ memset(&($$), 0, sizeof($$));
102441edb306SCy Schubert 					  $$.type = FRI_NORMAL;
102541edb306SCy Schubert 					  $$.ifpos = -1;
102641edb306SCy Schubert 					  yyexpectaddr = 0;
102741edb306SCy Schubert 					}
102841edb306SCy Schubert 	| hostname			{ memset(&($$), 0, sizeof($$));
102941edb306SCy Schubert 					  $$.a = $1.adr;
103041edb306SCy Schubert 					  $$.f = $1.f;
103141edb306SCy Schubert 					  if ($1.f == AF_INET6)
103241edb306SCy Schubert 						  fill6bits(128, $$.m.i6);
103341edb306SCy Schubert 					  else if ($1.f == AF_INET)
103441edb306SCy Schubert 						  fill6bits(32, $$.m.i6);
103541edb306SCy Schubert 					  $$.v = ftov($1.f);
103641edb306SCy Schubert 					  $$.ifpos = dynamic;
103741edb306SCy Schubert 					  $$.type = FRI_NORMAL;
103841edb306SCy Schubert 					}
103941edb306SCy Schubert 	| hostname			{ yyresetdict(); }
104041edb306SCy Schubert 		maskspace		{ yysetdict(maskwords);
104141edb306SCy Schubert 					  yyexpectaddr = 2; }
104241edb306SCy Schubert 		ipmask			{ memset(&($$), 0, sizeof($$));
104341edb306SCy Schubert 					  ntomask($1.f, $5, $$.m.i6);
104441edb306SCy Schubert 					  $$.a = $1.adr;
104541edb306SCy Schubert 					  $$.a.i6[0] &= $$.m.i6[0];
104641edb306SCy Schubert 					  $$.a.i6[1] &= $$.m.i6[1];
104741edb306SCy Schubert 					  $$.a.i6[2] &= $$.m.i6[2];
104841edb306SCy Schubert 					  $$.a.i6[3] &= $$.m.i6[3];
104941edb306SCy Schubert 					  $$.f = $1.f;
105041edb306SCy Schubert 					  $$.v = ftov($1.f);
105141edb306SCy Schubert 					  $$.type = ifpflag;
105241edb306SCy Schubert 					  $$.ifpos = dynamic;
105341edb306SCy Schubert 					  if (ifpflag != 0 && $$.v == 0) {
105441edb306SCy Schubert 						if (frc->fr_family == AF_INET6){
105541edb306SCy Schubert 							$$.v = 6;
105641edb306SCy Schubert 							$$.f = AF_INET6;
105741edb306SCy Schubert 						} else {
105841edb306SCy Schubert 							$$.v = 4;
105941edb306SCy Schubert 							$$.f = AF_INET;
106041edb306SCy Schubert 						}
106141edb306SCy Schubert 					  }
106241edb306SCy Schubert 					  yyresetdict();
106341edb306SCy Schubert 					  yyexpectaddr = 0;
106441edb306SCy Schubert 					}
106541edb306SCy Schubert 	| '(' YY_STR ')'		{ memset(&($$), 0, sizeof($$));
106641edb306SCy Schubert 					  $$.type = FRI_DYNAMIC;
106741edb306SCy Schubert 					  ifpflag = FRI_DYNAMIC;
106841edb306SCy Schubert 					  $$.ifpos = addname(&fr, $2);
106941edb306SCy Schubert 					  $$.lif = 0;
107041edb306SCy Schubert 					}
107141edb306SCy Schubert 	| '(' YY_STR ')' '/'
107241edb306SCy Schubert 	  { ifpflag = FRI_DYNAMIC; yysetdict(maskwords); }
107341edb306SCy Schubert 	  maskopts
107441edb306SCy Schubert 					{ memset(&($$), 0, sizeof($$));
107541edb306SCy Schubert 					  $$.type = ifpflag;
107641edb306SCy Schubert 					  $$.ifpos = addname(&fr, $2);
107741edb306SCy Schubert 					  $$.lif = 0;
107841edb306SCy Schubert 					  if (frc->fr_family == AF_UNSPEC)
107941edb306SCy Schubert 						frc->fr_family = AF_INET;
108041edb306SCy Schubert 					  if (ifpflag == FRI_DYNAMIC) {
108141edb306SCy Schubert 						ntomask(frc->fr_family,
108241edb306SCy Schubert 							$6, $$.m.i6);
108341edb306SCy Schubert 					  }
108441edb306SCy Schubert 					  yyresetdict();
108541edb306SCy Schubert 					  yyexpectaddr = 0;
108641edb306SCy Schubert 					}
108741edb306SCy Schubert 	| '(' YY_STR ':' YY_NUMBER ')' '/'
108841edb306SCy Schubert 	  { ifpflag = FRI_DYNAMIC; yysetdict(maskwords); }
108941edb306SCy Schubert 	  maskopts
109041edb306SCy Schubert 					{ memset(&($$), 0, sizeof($$));
109141edb306SCy Schubert 					  $$.type = ifpflag;
109241edb306SCy Schubert 					  $$.ifpos = addname(&fr, $2);
109341edb306SCy Schubert 					  $$.lif = $4;
109441edb306SCy Schubert 					  if (frc->fr_family == AF_UNSPEC)
109541edb306SCy Schubert 						frc->fr_family = AF_INET;
109641edb306SCy Schubert 					  if (ifpflag == FRI_DYNAMIC) {
109741edb306SCy Schubert 						ntomask(frc->fr_family,
109841edb306SCy Schubert 							$8, $$.m.i6);
109941edb306SCy Schubert 					  }
110041edb306SCy Schubert 					  yyresetdict();
110141edb306SCy Schubert 					  yyexpectaddr = 0;
110241edb306SCy Schubert 					}
110341edb306SCy Schubert 	;
110441edb306SCy Schubert 
110541edb306SCy Schubert maskspace:
110641edb306SCy Schubert 	'/'
110741edb306SCy Schubert 	| IPFY_MASK
110841edb306SCy Schubert 	;
110941edb306SCy Schubert 
111041edb306SCy Schubert ipmask:	ipv4				{ $$ = count4bits($1.s_addr); }
111141edb306SCy Schubert 	| YY_HEX			{ $$ = count4bits(htonl($1)); }
111241edb306SCy Schubert 	| YY_NUMBER			{ $$ = $1; }
111341edb306SCy Schubert 	| YY_IPV6			{ $$ = count6bits($1.i6); }
111441edb306SCy Schubert 	| maskopts			{ $$ = $1; }
111541edb306SCy Schubert 	;
111641edb306SCy Schubert 
111741edb306SCy Schubert maskopts:
111841edb306SCy Schubert 	IPFY_BROADCAST			{ if (ifpflag == FRI_DYNAMIC) {
111941edb306SCy Schubert 						ifpflag = FRI_BROADCAST;
112041edb306SCy Schubert 					  } else {
112141edb306SCy Schubert 						YYERROR;
112241edb306SCy Schubert 					  }
112341edb306SCy Schubert 					  $$ = 0;
112441edb306SCy Schubert 					}
112541edb306SCy Schubert 	| IPFY_NETWORK			{ if (ifpflag == FRI_DYNAMIC) {
112641edb306SCy Schubert 						ifpflag = FRI_NETWORK;
112741edb306SCy Schubert 					  } else {
112841edb306SCy Schubert 						YYERROR;
112941edb306SCy Schubert 					  }
113041edb306SCy Schubert 					  $$ = 0;
113141edb306SCy Schubert 					}
113241edb306SCy Schubert 	| IPFY_NETMASKED		{ if (ifpflag == FRI_DYNAMIC) {
113341edb306SCy Schubert 						ifpflag = FRI_NETMASKED;
113441edb306SCy Schubert 					  } else {
113541edb306SCy Schubert 						YYERROR;
113641edb306SCy Schubert 					  }
113741edb306SCy Schubert 					  $$ = 0;
113841edb306SCy Schubert 					}
113941edb306SCy Schubert 	| IPFY_PEER			{ if (ifpflag == FRI_DYNAMIC) {
114041edb306SCy Schubert 						ifpflag = FRI_PEERADDR;
114141edb306SCy Schubert 					  } else {
114241edb306SCy Schubert 						YYERROR;
114341edb306SCy Schubert 					  }
114441edb306SCy Schubert 					  $$ = 0;
114541edb306SCy Schubert 					}
114641edb306SCy Schubert 	| YY_NUMBER			{ $$ = $1; }
114741edb306SCy Schubert 	;
114841edb306SCy Schubert 
114941edb306SCy Schubert hostname:
115041edb306SCy Schubert 	ipv4				{ memset(&($$), 0, sizeof($$));
115141edb306SCy Schubert 					  $$.adr.in4 = $1;
115241edb306SCy Schubert 					  if (frc->fr_family == AF_INET6)
115341edb306SCy Schubert 						YYERROR;
115441edb306SCy Schubert 					  $$.f = AF_INET;
115541edb306SCy Schubert 					  yyexpectaddr = 2;
115641edb306SCy Schubert 					}
115741edb306SCy Schubert 	| YY_NUMBER			{ memset(&($$), 0, sizeof($$));
115841edb306SCy Schubert 					  if (frc->fr_family == AF_INET6)
115941edb306SCy Schubert 						YYERROR;
116041edb306SCy Schubert 					  $$.adr.in4_addr = $1;
116141edb306SCy Schubert 					  $$.f = AF_INET;
116241edb306SCy Schubert 					  yyexpectaddr = 2;
116341edb306SCy Schubert 					}
116441edb306SCy Schubert 	| YY_HEX			{ memset(&($$), 0, sizeof($$));
116541edb306SCy Schubert 					  if (frc->fr_family == AF_INET6)
116641edb306SCy Schubert 						YYERROR;
116741edb306SCy Schubert 					  $$.adr.in4_addr = $1;
116841edb306SCy Schubert 					  $$.f = AF_INET;
116941edb306SCy Schubert 					  yyexpectaddr = 2;
117041edb306SCy Schubert 					}
117141edb306SCy Schubert 	| YY_STR			{ memset(&($$), 0, sizeof($$));
117241edb306SCy Schubert 					  if (lookuphost($1, &$$.adr) == 0)
117341edb306SCy Schubert 						  $$.f = AF_INET;
117441edb306SCy Schubert 					  free($1);
117541edb306SCy Schubert 					  yyexpectaddr = 2;
117641edb306SCy Schubert 					}
117741edb306SCy Schubert 	| YY_IPV6			{ memset(&($$), 0, sizeof($$));
117841edb306SCy Schubert 					  if (frc->fr_family == AF_INET)
117941edb306SCy Schubert 						YYERROR;
118041edb306SCy Schubert 					  $$.adr = $1;
118141edb306SCy Schubert 					  $$.f = AF_INET6;
118241edb306SCy Schubert 					  yyexpectaddr = 2;
118341edb306SCy Schubert 					}
118441edb306SCy Schubert 	;
118541edb306SCy Schubert 
118641edb306SCy Schubert addrlist:
118741edb306SCy Schubert 	ipaddr		{ $$ = newalist(NULL);
118841edb306SCy Schubert 			  $$->al_family = $1.f;
118941edb306SCy Schubert 			  $$->al_i6addr = $1.a;
119041edb306SCy Schubert 			  $$->al_i6mask = $1.m;
119141edb306SCy Schubert 			}
119241edb306SCy Schubert 	| ipaddr ',' { yyexpectaddr = 1; } addrlist
119341edb306SCy Schubert 			{ $$ = newalist($4);
119441edb306SCy Schubert 			  $$->al_family = $1.f;
119541edb306SCy Schubert 			  $$->al_i6addr = $1.a;
119641edb306SCy Schubert 			  $$->al_i6mask = $1.m;
119741edb306SCy Schubert 			}
119841edb306SCy Schubert 	;
119941edb306SCy Schubert 
120041edb306SCy Schubert pool:	IPFY_POOL	{ yyexpectaddr = 0; yycont = NULL; yyresetdict(); }
120141edb306SCy Schubert 	;
120241edb306SCy Schubert 
120341edb306SCy Schubert hash:	IPFY_HASH	{ yyexpectaddr = 0; yycont = NULL; yyresetdict(); }
120441edb306SCy Schubert 	;
120541edb306SCy Schubert 
120641edb306SCy Schubert poollist:
120741edb306SCy Schubert 	ipaddr		{ $$ = newalist(NULL);
120841edb306SCy Schubert 			  $$->al_family = $1.f;
120941edb306SCy Schubert 			  $$->al_i6addr = $1.a;
121041edb306SCy Schubert 			  $$->al_i6mask = $1.m;
121141edb306SCy Schubert 			}
121241edb306SCy Schubert 	| '!' ipaddr	{ $$ = newalist(NULL);
121341edb306SCy Schubert 			  $$->al_not = 1;
121441edb306SCy Schubert 			  $$->al_family = $2.f;
121541edb306SCy Schubert 			  $$->al_i6addr = $2.a;
121641edb306SCy Schubert 			  $$->al_i6mask = $2.m;
121741edb306SCy Schubert 			}
121841edb306SCy Schubert 	| poollist ',' ipaddr
121941edb306SCy Schubert 			{ $$ = newalist($1);
122041edb306SCy Schubert 			  $$->al_family = $3.f;
122141edb306SCy Schubert 			  $$->al_i6addr = $3.a;
122241edb306SCy Schubert 			  $$->al_i6mask = $3.m;
122341edb306SCy Schubert 			}
122441edb306SCy Schubert 	| poollist ',' '!' ipaddr
122541edb306SCy Schubert 			{ $$ = newalist($1);
122641edb306SCy Schubert 			  $$->al_not = 1;
122741edb306SCy Schubert 			  $$->al_family = $4.f;
122841edb306SCy Schubert 			  $$->al_i6addr = $4.a;
122941edb306SCy Schubert 			  $$->al_i6mask = $4.m;
123041edb306SCy Schubert 			}
123141edb306SCy Schubert 	;
123241edb306SCy Schubert 
123341edb306SCy Schubert port:	IPFY_PORT			{ yyexpectaddr = 0;
123441edb306SCy Schubert 					  yycont = NULL;
123541edb306SCy Schubert 					  if (frc->fr_proto != 0 &&
123641edb306SCy Schubert 					      frc->fr_proto != IPPROTO_UDP &&
123741edb306SCy Schubert 					      frc->fr_proto != IPPROTO_TCP)
123841edb306SCy Schubert 						yyerror("port use incorrect");
123941edb306SCy Schubert 					}
124041edb306SCy Schubert 	;
124141edb306SCy Schubert 
124241edb306SCy Schubert portc:	port compare			{ $$ = $2;
124341edb306SCy Schubert 					  yysetdict(NULL);
124441edb306SCy Schubert 					}
124541edb306SCy Schubert 	| porteq			{ $$ = $1; }
124641edb306SCy Schubert 	;
124741edb306SCy Schubert 
124841edb306SCy Schubert porteq:	port '='			{ $$ = FR_EQUAL;
124941edb306SCy Schubert 					  yysetdict(NULL);
125041edb306SCy Schubert 					}
125141edb306SCy Schubert 	;
125241edb306SCy Schubert 
125341edb306SCy Schubert portr:	IPFY_PORT			{ yyexpectaddr = 0;
125441edb306SCy Schubert 					  yycont = NULL;
125541edb306SCy Schubert 					  yysetdict(NULL);
125641edb306SCy Schubert 					}
125741edb306SCy Schubert 	;
125841edb306SCy Schubert 
125941edb306SCy Schubert portcomp:
126041edb306SCy Schubert 	portc portnum			{ $$.pc = $1;
126141edb306SCy Schubert 					  $$.p1 = $2;
126241edb306SCy Schubert 					  yyresetdict();
126341edb306SCy Schubert 					}
126441edb306SCy Schubert 	;
126541edb306SCy Schubert 
126641edb306SCy Schubert portrange:
126741edb306SCy Schubert 	portr portnum range portnum	{ $$.p1 = $2;
126841edb306SCy Schubert 					  $$.pc = $3;
126941edb306SCy Schubert 					  $$.p2 = $4;
127041edb306SCy Schubert 					  yyresetdict();
127141edb306SCy Schubert 					}
127241edb306SCy Schubert 	;
127341edb306SCy Schubert 
127441edb306SCy Schubert icmp:	| itype icode
127541edb306SCy Schubert 	;
127641edb306SCy Schubert 
127741edb306SCy Schubert itype:	seticmptype icmptype
127841edb306SCy Schubert 	{ DOALL(fr->fr_icmp = htons($2 << 8); fr->fr_icmpm = htons(0xff00););
127941edb306SCy Schubert 	  yyresetdict();
128041edb306SCy Schubert 	}
128141edb306SCy Schubert 	| seticmptype lstart typelist lend	{ yyresetdict(); }
128241edb306SCy Schubert 	;
128341edb306SCy Schubert 
128441edb306SCy Schubert seticmptype:
128541edb306SCy Schubert 	IPFY_ICMPTYPE		{ if (frc->fr_family == AF_UNSPEC)
128641edb306SCy Schubert 					frc->fr_family = AF_INET;
128741edb306SCy Schubert 				  if (frc->fr_family == AF_INET &&
128841edb306SCy Schubert 				      frc->fr_type == FR_T_IPF &&
128941edb306SCy Schubert 				      frc->fr_proto != IPPROTO_ICMP) {
129041edb306SCy Schubert 					yyerror("proto not icmp");
129141edb306SCy Schubert 				  }
129241edb306SCy Schubert 				  if (frc->fr_family == AF_INET6 &&
129341edb306SCy Schubert 				      frc->fr_type == FR_T_IPF &&
129441edb306SCy Schubert 				      frc->fr_proto != IPPROTO_ICMPV6) {
129541edb306SCy Schubert 					yyerror("proto not ipv6-icmp");
129641edb306SCy Schubert 				  }
129741edb306SCy Schubert 				  setipftype();
129841edb306SCy Schubert 				  DOALL(if (fr->fr_family == AF_INET) { \
129941edb306SCy Schubert 						fr->fr_ip.fi_v = 4; \
130041edb306SCy Schubert 						fr->fr_mip.fi_v = 0xf; \
130141edb306SCy Schubert 					}
130241edb306SCy Schubert 					if (fr->fr_family == AF_INET6) { \
130341edb306SCy Schubert 						fr->fr_ip.fi_v = 6; \
130441edb306SCy Schubert 						fr->fr_mip.fi_v = 0xf; \
130541edb306SCy Schubert 					}
130641edb306SCy Schubert 				  )
130741edb306SCy Schubert 				  yysetdict(NULL);
130841edb306SCy Schubert 				}
130941edb306SCy Schubert 	;
131041edb306SCy Schubert 
131141edb306SCy Schubert icode:	| seticmpcode icmpcode
131241edb306SCy Schubert 	{ DOALL(fr->fr_icmp |= htons($2); fr->fr_icmpm |= htons(0xff););
131341edb306SCy Schubert 	  yyresetdict();
131441edb306SCy Schubert 	}
131541edb306SCy Schubert 	| seticmpcode lstart codelist lend	{ yyresetdict(); }
131641edb306SCy Schubert 	;
131741edb306SCy Schubert 
131841edb306SCy Schubert seticmpcode:
131941edb306SCy Schubert 	IPFY_ICMPCODE				{ yysetdict(icmpcodewords); }
132041edb306SCy Schubert 	;
132141edb306SCy Schubert 
132241edb306SCy Schubert typelist:
132341edb306SCy Schubert 	icmptype
132441edb306SCy Schubert 	{ DOREM(fr->fr_icmp = htons($1 << 8); fr->fr_icmpm = htons(0xff00);) }
132541edb306SCy Schubert 	| typelist lmore icmptype
132641edb306SCy Schubert 	{ DOREM(fr->fr_icmp = htons($3 << 8); fr->fr_icmpm = htons(0xff00);) }
132741edb306SCy Schubert 	;
132841edb306SCy Schubert 
132941edb306SCy Schubert codelist:
133041edb306SCy Schubert 	icmpcode
133141edb306SCy Schubert 	{ DOREM(fr->fr_icmp |= htons($1); fr->fr_icmpm |= htons(0xff);) }
133241edb306SCy Schubert 	| codelist lmore icmpcode
133341edb306SCy Schubert 	{ DOREM(fr->fr_icmp &= htons(0xff00); fr->fr_icmp |= htons($3); \
133441edb306SCy Schubert 		fr->fr_icmpm |= htons(0xff);) }
133541edb306SCy Schubert 	;
133641edb306SCy Schubert 
133741edb306SCy Schubert age:	| IPFY_AGE YY_NUMBER		{ DOALL(fr->fr_age[0] = $2; \
133841edb306SCy Schubert 						fr->fr_age[1] = $2;) }
133941edb306SCy Schubert 	| IPFY_AGE YY_NUMBER '/' YY_NUMBER
134041edb306SCy Schubert 					{ DOALL(fr->fr_age[0] = $2; \
134141edb306SCy Schubert 						fr->fr_age[1] = $4;) }
134241edb306SCy Schubert 	;
134341edb306SCy Schubert 
134441edb306SCy Schubert keep:	| IPFY_KEEP keepstate keep
134541edb306SCy Schubert 	| IPFY_KEEP keepfrag keep
134641edb306SCy Schubert 	;
134741edb306SCy Schubert 
134841edb306SCy Schubert keepstate:
134941edb306SCy Schubert 	IPFY_STATE stateoptlist		{ DOALL(fr->fr_flags |= FR_KEEPSTATE;)}
135041edb306SCy Schubert 	;
135141edb306SCy Schubert 
135241edb306SCy Schubert keepfrag:
135341edb306SCy Schubert 	IPFY_FRAGS fragoptlist		{ DOALL(fr->fr_flags |= FR_KEEPFRAG;) }
135441edb306SCy Schubert 	| IPFY_FRAG fragoptlist		{ DOALL(fr->fr_flags |= FR_KEEPFRAG;) }
135541edb306SCy Schubert 	;
135641edb306SCy Schubert 
135741edb306SCy Schubert fragoptlist:
135841edb306SCy Schubert 	| '(' fragopts ')'
135941edb306SCy Schubert 	;
136041edb306SCy Schubert 
136141edb306SCy Schubert fragopts:
136241edb306SCy Schubert 	fragopt lanother fragopts
136341edb306SCy Schubert 	| fragopt
136441edb306SCy Schubert 	;
136541edb306SCy Schubert 
136641edb306SCy Schubert fragopt:
136741edb306SCy Schubert 	IPFY_STRICT			{ DOALL(fr->fr_flags |= FR_FRSTRICT;) }
136841edb306SCy Schubert 	;
136941edb306SCy Schubert 
137041edb306SCy Schubert stateoptlist:
137141edb306SCy Schubert 	| '(' stateopts ')'
137241edb306SCy Schubert 	;
137341edb306SCy Schubert 
137441edb306SCy Schubert stateopts:
137541edb306SCy Schubert 	stateopt lanother stateopts
137641edb306SCy Schubert 	| stateopt
137741edb306SCy Schubert 	;
137841edb306SCy Schubert 
137941edb306SCy Schubert stateopt:
138041edb306SCy Schubert 	IPFY_LIMIT YY_NUMBER	{ DOALL(fr->fr_statemax = $2;) }
138141edb306SCy Schubert 	| IPFY_STRICT		{ DOALL(if (fr->fr_proto != IPPROTO_TCP) { \
138241edb306SCy Schubert 						YYERROR; \
138341edb306SCy Schubert 					} else if (fr->fr_flags & FR_STLOOSE) {\
138441edb306SCy Schubert 						YYERROR; \
138541edb306SCy Schubert 					} else \
138641edb306SCy Schubert 						fr->fr_flags |= FR_STSTRICT;)
138741edb306SCy Schubert 				}
138841edb306SCy Schubert 	| IPFY_LOOSE		{ DOALL(if (fr->fr_proto != IPPROTO_TCP) { \
138941edb306SCy Schubert 						YYERROR; \
139041edb306SCy Schubert 					} else if (fr->fr_flags & FR_STSTRICT){\
139141edb306SCy Schubert 						YYERROR; \
139241edb306SCy Schubert 					} else \
139341edb306SCy Schubert 						fr->fr_flags |= FR_STLOOSE;)
139441edb306SCy Schubert 				}
139541edb306SCy Schubert 	| IPFY_NEWISN		{ DOALL(if (fr->fr_proto != IPPROTO_TCP) { \
139641edb306SCy Schubert 						YYERROR; \
139741edb306SCy Schubert 					  } else \
139841edb306SCy Schubert 						fr->fr_flags |= FR_NEWISN;)
139941edb306SCy Schubert 				}
140041edb306SCy Schubert 	| IPFY_NOICMPERR	{ DOALL(fr->fr_flags |= FR_NOICMPERR;) }
140141edb306SCy Schubert 
140241edb306SCy Schubert 	| IPFY_SYNC		{ DOALL(fr->fr_flags |= FR_STATESYNC;) }
140341edb306SCy Schubert 	| IPFY_AGE YY_NUMBER		{ DOALL(fr->fr_age[0] = $2; \
140441edb306SCy Schubert 						fr->fr_age[1] = $2;) }
140541edb306SCy Schubert 	| IPFY_AGE YY_NUMBER '/' YY_NUMBER
140641edb306SCy Schubert 					{ DOALL(fr->fr_age[0] = $2; \
140741edb306SCy Schubert 						fr->fr_age[1] = $4;) }
140841edb306SCy Schubert 	| IPFY_ICMPHEAD groupname
140941edb306SCy Schubert 				{ DOALL(seticmphead(&fr, $2);)
141041edb306SCy Schubert 				  free($2);
141141edb306SCy Schubert 				}
141241edb306SCy Schubert 	| IPFY_NOLOG
141341edb306SCy Schubert 				{ DOALL(fr->fr_nostatelog = 1;) }
141441edb306SCy Schubert 	| IPFY_RPC
141541edb306SCy Schubert 				{ DOALL(fr->fr_rpc = 1;) }
141641edb306SCy Schubert 	| IPFY_RPC IPFY_IN YY_STR
141741edb306SCy Schubert 				{ DOALL(fr->fr_rpc = 1;) }
141841edb306SCy Schubert 	| IPFY_MAX_SRCS YY_NUMBER
141941edb306SCy Schubert 				{ DOALL(fr->fr_srctrack.ht_max_nodes = $2;) }
142041edb306SCy Schubert 	| IPFY_MAX_PER_SRC YY_NUMBER
142141edb306SCy Schubert 				{ DOALL(fr->fr_srctrack.ht_max_per_node = $2; \
142241edb306SCy Schubert 					fr->fr_srctrack.ht_netmask = \
142341edb306SCy Schubert 					fr->fr_family == AF_INET ? 32: 128;)
142441edb306SCy Schubert 				}
142541edb306SCy Schubert 	| IPFY_MAX_PER_SRC YY_NUMBER '/' YY_NUMBER
142641edb306SCy Schubert 				{ DOALL(fr->fr_srctrack.ht_max_per_node = $2; \
142741edb306SCy Schubert 					fr->fr_srctrack.ht_netmask = $4;)
142841edb306SCy Schubert 				}
142941edb306SCy Schubert 	;
143041edb306SCy Schubert 
143141edb306SCy Schubert portnum:
143241edb306SCy Schubert 	servicename			{ if (getport(frc, $1,
143341edb306SCy Schubert 						      &($$), NULL) == -1)
143441edb306SCy Schubert 						yyerror("service unknown");
143541edb306SCy Schubert 					  $$ = ntohs($$);
143641edb306SCy Schubert 					  free($1);
143741edb306SCy Schubert 					}
143841edb306SCy Schubert 	| YY_NUMBER			{ if ($1 > 65535)	/* Unsigned */
143941edb306SCy Schubert 						yyerror("invalid port number");
144041edb306SCy Schubert 					  else
144141edb306SCy Schubert 						$$ = $1;
144241edb306SCy Schubert 					}
144341edb306SCy Schubert 	;
144441edb306SCy Schubert 
144541edb306SCy Schubert withlist:
144641edb306SCy Schubert 	withopt				{ nowith = 0; }
144741edb306SCy Schubert 	| withlist withopt		{ nowith = 0; }
144841edb306SCy Schubert 	| withlist ',' withopt		{ nowith = 0; }
144941edb306SCy Schubert 	;
145041edb306SCy Schubert 
145141edb306SCy Schubert withopt:
145241edb306SCy Schubert 	opttype		{ DOALL(fr->fr_flx |= $1; fr->fr_mflx |= $1;) }
145341edb306SCy Schubert 	| notwith opttype		{ DOALL(fr->fr_mflx |= $2;) }
145441edb306SCy Schubert 	| ipopt ipopts			{ yyresetdict(); }
145541edb306SCy Schubert 	| notwith ipopt ipopts		{ yyresetdict(); }
145641edb306SCy Schubert 	| startv6hdr ipv6hdrs		{ yyresetdict(); }
145741edb306SCy Schubert 	;
145841edb306SCy Schubert 
145941edb306SCy Schubert ipopt:	IPFY_OPT			{ yysetdict(ipv4optwords); }
146041edb306SCy Schubert 	;
146141edb306SCy Schubert 
146241edb306SCy Schubert startv6hdr:
146341edb306SCy Schubert 	IPFY_V6HDR	{ if (frc->fr_family != AF_INET6)
146441edb306SCy Schubert 				yyerror("only available with IPv6");
146541edb306SCy Schubert 			  yysetdict(ipv6optwords);
146641edb306SCy Schubert 			}
146741edb306SCy Schubert 	;
146841edb306SCy Schubert 
146941edb306SCy Schubert notwith:
147041edb306SCy Schubert 	IPFY_NOT			{ nowith = 1; }
147141edb306SCy Schubert 	| IPFY_NO			{ nowith = 1; }
147241edb306SCy Schubert 	;
147341edb306SCy Schubert 
147441edb306SCy Schubert opttype:
147541edb306SCy Schubert 	IPFY_IPOPTS			{ $$ = FI_OPTIONS; }
147641edb306SCy Schubert 	| IPFY_SHORT			{ $$ = FI_SHORT; }
147741edb306SCy Schubert 	| IPFY_NAT			{ $$ = FI_NATED; }
147841edb306SCy Schubert 	| IPFY_BAD			{ $$ = FI_BAD; }
147941edb306SCy Schubert 	| IPFY_BADNAT			{ $$ = FI_BADNAT; }
148041edb306SCy Schubert 	| IPFY_BADSRC			{ $$ = FI_BADSRC; }
148141edb306SCy Schubert 	| IPFY_LOWTTL			{ $$ = FI_LOWTTL; }
148241edb306SCy Schubert 	| IPFY_FRAG			{ $$ = FI_FRAG; }
148341edb306SCy Schubert 	| IPFY_FRAGBODY			{ $$ = FI_FRAGBODY; }
148441edb306SCy Schubert 	| IPFY_FRAGS			{ $$ = FI_FRAG; }
148541edb306SCy Schubert 	| IPFY_MBCAST			{ $$ = FI_MBCAST; }
148641edb306SCy Schubert 	| IPFY_MULTICAST		{ $$ = FI_MULTICAST; }
148741edb306SCy Schubert 	| IPFY_BROADCAST		{ $$ = FI_BROADCAST; }
148841edb306SCy Schubert 	| IPFY_STATE			{ $$ = FI_STATE; }
148941edb306SCy Schubert 	| IPFY_OOW			{ $$ = FI_OOW; }
149041edb306SCy Schubert 	| IPFY_AH			{ $$ = FI_AH; }
149141edb306SCy Schubert 	| IPFY_V6HDRS			{ $$ = FI_V6EXTHDR; }
149241edb306SCy Schubert 	;
149341edb306SCy Schubert 
149441edb306SCy Schubert ipopts:	optlist		{ DOALL(fr->fr_mip.fi_optmsk |= $1;
149541edb306SCy Schubert 				if (fr->fr_family == AF_UNSPEC) {
149641edb306SCy Schubert 					fr->fr_family = AF_INET;
149741edb306SCy Schubert 					fr->fr_ip.fi_v = 4;
149841edb306SCy Schubert 					fr->fr_mip.fi_v = 0xf;
149941edb306SCy Schubert 				} else if (fr->fr_family != AF_INET) {
150041edb306SCy Schubert 					YYERROR;
150141edb306SCy Schubert 				}
150241edb306SCy Schubert 				if (!nowith)
150341edb306SCy Schubert 					fr->fr_ip.fi_optmsk |= $1;)
150441edb306SCy Schubert 			}
150541edb306SCy Schubert 	;
150641edb306SCy Schubert 
150741edb306SCy Schubert optlist:
150841edb306SCy Schubert 	opt				{ $$ |= $1; }
150941edb306SCy Schubert 	| optlist ',' opt		{ $$ |= $1 | $3; }
151041edb306SCy Schubert 	;
151141edb306SCy Schubert 
151241edb306SCy Schubert ipv6hdrs:
151341edb306SCy Schubert 	ipv6hdrlist	{ DOALL(fr->fr_mip.fi_optmsk |= $1;
151441edb306SCy Schubert 				if (!nowith)
151541edb306SCy Schubert 					fr->fr_ip.fi_optmsk |= $1;)
151641edb306SCy Schubert 			}
151741edb306SCy Schubert 	;
151841edb306SCy Schubert 
151941edb306SCy Schubert ipv6hdrlist:
152041edb306SCy Schubert 	ipv6hdr				{ $$ |= $1; }
152141edb306SCy Schubert 	| ipv6hdrlist ',' ipv6hdr	{ $$ |= $1 | $3; }
152241edb306SCy Schubert 	;
152341edb306SCy Schubert 
152441edb306SCy Schubert secname:
152541edb306SCy Schubert 	seclevel			{ $$ |= $1; }
152641edb306SCy Schubert 	| secname ',' seclevel		{ $$ |= $1 | $3; }
152741edb306SCy Schubert 	;
152841edb306SCy Schubert 
152941edb306SCy Schubert seclevel:
153041edb306SCy Schubert 	IPFY_SEC_UNC			{ $$ = secbit(IPSO_CLASS_UNCL); }
153141edb306SCy Schubert 	| IPFY_SEC_CONF			{ $$ = secbit(IPSO_CLASS_CONF); }
153241edb306SCy Schubert 	| IPFY_SEC_RSV1			{ $$ = secbit(IPSO_CLASS_RES1); }
153341edb306SCy Schubert 	| IPFY_SEC_RSV2			{ $$ = secbit(IPSO_CLASS_RES2); }
153441edb306SCy Schubert 	| IPFY_SEC_RSV3			{ $$ = secbit(IPSO_CLASS_RES3); }
153541edb306SCy Schubert 	| IPFY_SEC_RSV4			{ $$ = secbit(IPSO_CLASS_RES4); }
153641edb306SCy Schubert 	| IPFY_SEC_SEC			{ $$ = secbit(IPSO_CLASS_SECR); }
153741edb306SCy Schubert 	| IPFY_SEC_TS			{ $$ = secbit(IPSO_CLASS_TOPS); }
153841edb306SCy Schubert 	;
153941edb306SCy Schubert 
154041edb306SCy Schubert icmptype:
154141edb306SCy Schubert 	YY_NUMBER		{ $$ = $1; }
154241edb306SCy Schubert 	| YY_STR		{ $$ = geticmptype(frc->fr_family, $1);
154341edb306SCy Schubert 				  if ($$ == -1)
154441edb306SCy Schubert 					yyerror("unrecognised icmp type");
154541edb306SCy Schubert 				}
154641edb306SCy Schubert 	;
154741edb306SCy Schubert 
154841edb306SCy Schubert icmpcode:
154941edb306SCy Schubert 	YY_NUMBER			{ $$ = $1; }
155041edb306SCy Schubert 	| IPFY_ICMPC_NETUNR		{ $$ = ICMP_UNREACH_NET; }
155141edb306SCy Schubert 	| IPFY_ICMPC_HSTUNR		{ $$ = ICMP_UNREACH_HOST; }
155241edb306SCy Schubert 	| IPFY_ICMPC_PROUNR		{ $$ = ICMP_UNREACH_PROTOCOL; }
155341edb306SCy Schubert 	| IPFY_ICMPC_PORUNR		{ $$ = ICMP_UNREACH_PORT; }
155441edb306SCy Schubert 	| IPFY_ICMPC_NEEDF		{ $$ = ICMP_UNREACH_NEEDFRAG; }
155541edb306SCy Schubert 	| IPFY_ICMPC_SRCFAIL		{ $$ = ICMP_UNREACH_SRCFAIL; }
155641edb306SCy Schubert 	| IPFY_ICMPC_NETUNK		{ $$ = ICMP_UNREACH_NET_UNKNOWN; }
155741edb306SCy Schubert 	| IPFY_ICMPC_HSTUNK		{ $$ = ICMP_UNREACH_HOST_UNKNOWN; }
155841edb306SCy Schubert 	| IPFY_ICMPC_ISOLATE		{ $$ = ICMP_UNREACH_ISOLATED; }
155941edb306SCy Schubert 	| IPFY_ICMPC_NETPRO		{ $$ = ICMP_UNREACH_NET_PROHIB; }
156041edb306SCy Schubert 	| IPFY_ICMPC_HSTPRO		{ $$ = ICMP_UNREACH_HOST_PROHIB; }
156141edb306SCy Schubert 	| IPFY_ICMPC_NETTOS		{ $$ = ICMP_UNREACH_TOSNET; }
156241edb306SCy Schubert 	| IPFY_ICMPC_HSTTOS		{ $$ = ICMP_UNREACH_TOSHOST; }
156341edb306SCy Schubert 	| IPFY_ICMPC_FLTPRO		{ $$ = ICMP_UNREACH_ADMIN_PROHIBIT; }
156441edb306SCy Schubert 	| IPFY_ICMPC_HSTPRE		{ $$ = 14; }
156541edb306SCy Schubert 	| IPFY_ICMPC_CUTPRE		{ $$ = 15; }
156641edb306SCy Schubert 	;
156741edb306SCy Schubert 
156841edb306SCy Schubert opt:
156941edb306SCy Schubert 	IPFY_IPOPT_NOP			{ $$ = getoptbyvalue(IPOPT_NOP); }
157041edb306SCy Schubert 	| IPFY_IPOPT_RR			{ $$ = getoptbyvalue(IPOPT_RR); }
157141edb306SCy Schubert 	| IPFY_IPOPT_ZSU		{ $$ = getoptbyvalue(IPOPT_ZSU); }
157241edb306SCy Schubert 	| IPFY_IPOPT_MTUP		{ $$ = getoptbyvalue(IPOPT_MTUP); }
157341edb306SCy Schubert 	| IPFY_IPOPT_MTUR		{ $$ = getoptbyvalue(IPOPT_MTUR); }
157441edb306SCy Schubert 	| IPFY_IPOPT_ENCODE		{ $$ = getoptbyvalue(IPOPT_ENCODE); }
157541edb306SCy Schubert 	| IPFY_IPOPT_TS			{ $$ = getoptbyvalue(IPOPT_TS); }
157641edb306SCy Schubert 	| IPFY_IPOPT_TR			{ $$ = getoptbyvalue(IPOPT_TR); }
157741edb306SCy Schubert 	| IPFY_IPOPT_SEC		{ $$ = getoptbyvalue(IPOPT_SECURITY); }
157841edb306SCy Schubert 	| IPFY_IPOPT_LSRR		{ $$ = getoptbyvalue(IPOPT_LSRR); }
157941edb306SCy Schubert 	| IPFY_IPOPT_ESEC		{ $$ = getoptbyvalue(IPOPT_E_SEC); }
158041edb306SCy Schubert 	| IPFY_IPOPT_CIPSO 		{ $$ = getoptbyvalue(IPOPT_CIPSO); }
158141edb306SCy Schubert 	| IPFY_IPOPT_CIPSO doi		{ $$ = getoptbyvalue(IPOPT_CIPSO); }
158241edb306SCy Schubert 	| IPFY_IPOPT_SATID		{ $$ = getoptbyvalue(IPOPT_SATID); }
158341edb306SCy Schubert 	| IPFY_IPOPT_SSRR		{ $$ = getoptbyvalue(IPOPT_SSRR); }
158441edb306SCy Schubert 	| IPFY_IPOPT_ADDEXT		{ $$ = getoptbyvalue(IPOPT_ADDEXT); }
158541edb306SCy Schubert 	| IPFY_IPOPT_VISA		{ $$ = getoptbyvalue(IPOPT_VISA); }
158641edb306SCy Schubert 	| IPFY_IPOPT_IMITD		{ $$ = getoptbyvalue(IPOPT_IMITD); }
158741edb306SCy Schubert 	| IPFY_IPOPT_EIP		{ $$ = getoptbyvalue(IPOPT_EIP); }
158841edb306SCy Schubert 	| IPFY_IPOPT_FINN		{ $$ = getoptbyvalue(IPOPT_FINN); }
158941edb306SCy Schubert 	| IPFY_IPOPT_DPS		{ $$ = getoptbyvalue(IPOPT_DPS); }
159041edb306SCy Schubert 	| IPFY_IPOPT_SDB		{ $$ = getoptbyvalue(IPOPT_SDB); }
159141edb306SCy Schubert 	| IPFY_IPOPT_NSAPA		{ $$ = getoptbyvalue(IPOPT_NSAPA); }
159241edb306SCy Schubert 	| IPFY_IPOPT_RTRALRT		{ $$ = getoptbyvalue(IPOPT_RTRALRT); }
159341edb306SCy Schubert 	| IPFY_IPOPT_UMP		{ $$ = getoptbyvalue(IPOPT_UMP); }
159441edb306SCy Schubert 	| setsecclass secname
159541edb306SCy Schubert 			{ DOALL(fr->fr_mip.fi_secmsk |= $2;
159641edb306SCy Schubert 				if (fr->fr_family == AF_UNSPEC) {
159741edb306SCy Schubert 					fr->fr_family = AF_INET;
159841edb306SCy Schubert 					fr->fr_ip.fi_v = 4;
159941edb306SCy Schubert 					fr->fr_mip.fi_v = 0xf;
160041edb306SCy Schubert 				} else if (fr->fr_family != AF_INET) {
160141edb306SCy Schubert 					YYERROR;
160241edb306SCy Schubert 				}
160341edb306SCy Schubert 				if (!nowith)
160441edb306SCy Schubert 					fr->fr_ip.fi_secmsk |= $2;)
160541edb306SCy Schubert 			  $$ = 0;
160641edb306SCy Schubert 			  yyresetdict();
160741edb306SCy Schubert 			}
160841edb306SCy Schubert 	;
160941edb306SCy Schubert 
161041edb306SCy Schubert setsecclass:
161141edb306SCy Schubert 	IPFY_SECCLASS			{ yysetdict(ipv4secwords); }
161241edb306SCy Schubert 	;
161341edb306SCy Schubert 
161441edb306SCy Schubert doi:	IPFY_DOI YY_NUMBER		{ DOALL(fr->fr_doimask = 0xffffffff; \
161541edb306SCy Schubert 						if (!nowith) \
161641edb306SCy Schubert 							fr->fr_doi = $2;) }
161741edb306SCy Schubert 	| IPFY_DOI YY_HEX		{ DOALL(fr->fr_doimask = 0xffffffff; \
161841edb306SCy Schubert 						if (!nowith) \
161941edb306SCy Schubert 							fr->fr_doi = $2;) }
162041edb306SCy Schubert 	;
162141edb306SCy Schubert 
162241edb306SCy Schubert ipv6hdr:
162341edb306SCy Schubert 	IPFY_AH			{ $$ = getv6optbyvalue(IPPROTO_AH); }
162441edb306SCy Schubert 	| IPFY_IPV6OPT_DSTOPTS	{ $$ = getv6optbyvalue(IPPROTO_DSTOPTS); }
162541edb306SCy Schubert 	| IPFY_IPV6OPT_ESP	{ $$ = getv6optbyvalue(IPPROTO_ESP); }
162641edb306SCy Schubert 	| IPFY_IPV6OPT_HOPOPTS	{ $$ = getv6optbyvalue(IPPROTO_HOPOPTS); }
162741edb306SCy Schubert 	| IPFY_IPV6OPT_IPV6	{ $$ = getv6optbyvalue(IPPROTO_IPV6); }
162841edb306SCy Schubert 	| IPFY_IPV6OPT_NONE	{ $$ = getv6optbyvalue(IPPROTO_NONE); }
162941edb306SCy Schubert 	| IPFY_IPV6OPT_ROUTING	{ $$ = getv6optbyvalue(IPPROTO_ROUTING); }
163041edb306SCy Schubert 	| IPFY_IPV6OPT_FRAG	{ $$ = getv6optbyvalue(IPPROTO_FRAGMENT); }
163141edb306SCy Schubert 	| IPFY_IPV6OPT_MOBILITY	{ $$ = getv6optbyvalue(IPPROTO_MOBILITY); }
163241edb306SCy Schubert 	;
163341edb306SCy Schubert 
163441edb306SCy Schubert level:	IPFY_LEVEL			{ setsyslog(); }
163541edb306SCy Schubert 	;
163641edb306SCy Schubert 
163741edb306SCy Schubert loglevel:
163841edb306SCy Schubert 	priority			{ fr->fr_loglevel = LOG_LOCAL0|$1; }
163941edb306SCy Schubert 	| facility '.' priority		{ fr->fr_loglevel = $1 | $3; }
164041edb306SCy Schubert 	;
164141edb306SCy Schubert 
164241edb306SCy Schubert facility:
164341edb306SCy Schubert 	IPFY_FAC_KERN			{ $$ = LOG_KERN; }
164441edb306SCy Schubert 	| IPFY_FAC_USER			{ $$ = LOG_USER; }
164541edb306SCy Schubert 	| IPFY_FAC_MAIL			{ $$ = LOG_MAIL; }
164641edb306SCy Schubert 	| IPFY_FAC_DAEMON		{ $$ = LOG_DAEMON; }
164741edb306SCy Schubert 	| IPFY_FAC_AUTH			{ $$ = LOG_AUTH; }
164841edb306SCy Schubert 	| IPFY_FAC_SYSLOG		{ $$ = LOG_SYSLOG; }
164941edb306SCy Schubert 	| IPFY_FAC_LPR			{ $$ = LOG_LPR; }
165041edb306SCy Schubert 	| IPFY_FAC_NEWS			{ $$ = LOG_NEWS; }
165141edb306SCy Schubert 	| IPFY_FAC_UUCP			{ $$ = LOG_UUCP; }
165241edb306SCy Schubert 	| IPFY_FAC_CRON			{ $$ = LOG_CRON; }
165341edb306SCy Schubert 	| IPFY_FAC_FTP			{ $$ = LOG_FTP; }
165441edb306SCy Schubert 	| IPFY_FAC_AUTHPRIV		{ $$ = LOG_AUTHPRIV; }
165541edb306SCy Schubert 	| IPFY_FAC_AUDIT		{ $$ = LOG_AUDIT; }
165641edb306SCy Schubert 	| IPFY_FAC_LFMT			{ $$ = LOG_LFMT; }
165741edb306SCy Schubert 	| IPFY_FAC_LOCAL0		{ $$ = LOG_LOCAL0; }
165841edb306SCy Schubert 	| IPFY_FAC_LOCAL1		{ $$ = LOG_LOCAL1; }
165941edb306SCy Schubert 	| IPFY_FAC_LOCAL2		{ $$ = LOG_LOCAL2; }
166041edb306SCy Schubert 	| IPFY_FAC_LOCAL3		{ $$ = LOG_LOCAL3; }
166141edb306SCy Schubert 	| IPFY_FAC_LOCAL4		{ $$ = LOG_LOCAL4; }
166241edb306SCy Schubert 	| IPFY_FAC_LOCAL5		{ $$ = LOG_LOCAL5; }
166341edb306SCy Schubert 	| IPFY_FAC_LOCAL6		{ $$ = LOG_LOCAL6; }
166441edb306SCy Schubert 	| IPFY_FAC_LOCAL7		{ $$ = LOG_LOCAL7; }
166541edb306SCy Schubert 	| IPFY_FAC_SECURITY		{ $$ = LOG_SECURITY; }
166641edb306SCy Schubert 	;
166741edb306SCy Schubert 
166841edb306SCy Schubert priority:
166941edb306SCy Schubert 	IPFY_PRI_EMERG			{ $$ = LOG_EMERG; }
167041edb306SCy Schubert 	| IPFY_PRI_ALERT		{ $$ = LOG_ALERT; }
167141edb306SCy Schubert 	| IPFY_PRI_CRIT			{ $$ = LOG_CRIT; }
167241edb306SCy Schubert 	| IPFY_PRI_ERR			{ $$ = LOG_ERR; }
167341edb306SCy Schubert 	| IPFY_PRI_WARN			{ $$ = LOG_WARNING; }
167441edb306SCy Schubert 	| IPFY_PRI_NOTICE		{ $$ = LOG_NOTICE; }
167541edb306SCy Schubert 	| IPFY_PRI_INFO			{ $$ = LOG_INFO; }
167641edb306SCy Schubert 	| IPFY_PRI_DEBUG		{ $$ = LOG_DEBUG; }
167741edb306SCy Schubert 	;
167841edb306SCy Schubert 
167941edb306SCy Schubert compare:
168041edb306SCy Schubert 	YY_CMP_EQ			{ $$ = FR_EQUAL; }
168141edb306SCy Schubert 	| YY_CMP_NE			{ $$ = FR_NEQUAL; }
168241edb306SCy Schubert 	| YY_CMP_LT			{ $$ = FR_LESST; }
168341edb306SCy Schubert 	| YY_CMP_LE			{ $$ = FR_LESSTE; }
168441edb306SCy Schubert 	| YY_CMP_GT			{ $$ = FR_GREATERT; }
168541edb306SCy Schubert 	| YY_CMP_GE			{ $$ = FR_GREATERTE; }
168641edb306SCy Schubert 	;
168741edb306SCy Schubert 
168841edb306SCy Schubert range:	YY_RANGE_IN			{ $$ = FR_INRANGE; }
168941edb306SCy Schubert 	| YY_RANGE_OUT			{ $$ = FR_OUTRANGE; }
169041edb306SCy Schubert 	| ':'				{ $$ = FR_INCRANGE; }
169141edb306SCy Schubert 	;
169241edb306SCy Schubert 
169341edb306SCy Schubert servicename:
169441edb306SCy Schubert 	YY_STR				{ $$ = $1; }
169541edb306SCy Schubert 	;
169641edb306SCy Schubert 
169741edb306SCy Schubert interfacename:	name				{ $$ = $1; }
169841edb306SCy Schubert 	| name ':' YY_NUMBER
169941edb306SCy Schubert 		{ $$ = $1;
170041edb306SCy Schubert 		  fprintf(stderr, "%d: Logical interface %s:%d unsupported, "
170141edb306SCy Schubert 			  "use the physical interface %s instead.\n",
170241edb306SCy Schubert 			  yylineNum, $1, $3, $1);
170341edb306SCy Schubert 		}
170441edb306SCy Schubert 	;
170541edb306SCy Schubert 
170641edb306SCy Schubert name:	YY_STR				{ $$ = $1; }
170741edb306SCy Schubert 	| '-'				{ $$ = strdup("-"); }
170841edb306SCy Schubert 	;
170941edb306SCy Schubert 
171041edb306SCy Schubert ipv4_16:
171141edb306SCy Schubert 	YY_NUMBER '.' YY_NUMBER
171241edb306SCy Schubert 		{ if ($1 > 255 || $3 > 255) {
171341edb306SCy Schubert 			yyerror("Invalid octet string for IP address");
1714*2582ae57SCy Schubert 			return(0);
171541edb306SCy Schubert 		  }
171641edb306SCy Schubert 		  $$.s_addr = ($1 << 24) | ($3 << 16);
171741edb306SCy Schubert 		  $$.s_addr = htonl($$.s_addr);
171841edb306SCy Schubert 		}
171941edb306SCy Schubert 	;
172041edb306SCy Schubert 
172141edb306SCy Schubert ipv4_24:
172241edb306SCy Schubert 	ipv4_16 '.' YY_NUMBER
172341edb306SCy Schubert 		{ if ($3 > 255) {
172441edb306SCy Schubert 			yyerror("Invalid octet string for IP address");
1725*2582ae57SCy Schubert 			return(0);
172641edb306SCy Schubert 		  }
172741edb306SCy Schubert 		  $$.s_addr |= htonl($3 << 8);
172841edb306SCy Schubert 		}
172941edb306SCy Schubert 	;
173041edb306SCy Schubert 
173141edb306SCy Schubert ipv4:	ipv4_24 '.' YY_NUMBER
173241edb306SCy Schubert 		{ if ($3 > 255) {
173341edb306SCy Schubert 			yyerror("Invalid octet string for IP address");
1734*2582ae57SCy Schubert 			return(0);
173541edb306SCy Schubert 		  }
173641edb306SCy Schubert 		  $$.s_addr |= htonl($3);
173741edb306SCy Schubert 		}
173841edb306SCy Schubert 	| ipv4_24
173941edb306SCy Schubert 	| ipv4_16
174041edb306SCy Schubert 	;
174141edb306SCy Schubert 
174241edb306SCy Schubert %%
174341edb306SCy Schubert 
174441edb306SCy Schubert 
174541edb306SCy Schubert static	struct	wordtab ipfwords[] = {
174641edb306SCy Schubert 	{ "age",			IPFY_AGE },
174741edb306SCy Schubert 	{ "ah",				IPFY_AH },
174841edb306SCy Schubert 	{ "all",			IPFY_ALL },
174941edb306SCy Schubert 	{ "and",			IPFY_AND },
175041edb306SCy Schubert 	{ "auth",			IPFY_AUTH },
175141edb306SCy Schubert 	{ "bad",			IPFY_BAD },
175241edb306SCy Schubert 	{ "bad-nat",			IPFY_BADNAT },
175341edb306SCy Schubert 	{ "bad-src",			IPFY_BADSRC },
175441edb306SCy Schubert 	{ "bcast",			IPFY_BROADCAST },
175541edb306SCy Schubert 	{ "block",			IPFY_BLOCK },
175641edb306SCy Schubert 	{ "body",			IPFY_BODY },
175741edb306SCy Schubert 	{ "bpf-v4",			IPFY_BPFV4 },
175841edb306SCy Schubert #ifdef USE_INET6
175941edb306SCy Schubert 	{ "bpf-v6",			IPFY_BPFV6 },
176041edb306SCy Schubert #endif
176141edb306SCy Schubert 	{ "call",			IPFY_CALL },
176241edb306SCy Schubert 	{ "code",			IPFY_ICMPCODE },
176341edb306SCy Schubert 	{ "comment",			IPFY_COMMENT },
176441edb306SCy Schubert 	{ "count",			IPFY_COUNT },
176541edb306SCy Schubert 	{ "decapsulate",		IPFY_DECAPS },
176641edb306SCy Schubert 	{ "dstlist",			IPFY_DSTLIST },
176741edb306SCy Schubert 	{ "doi",			IPFY_DOI },
176841edb306SCy Schubert 	{ "dup-to",			IPFY_DUPTO },
176941edb306SCy Schubert 	{ "eq",				YY_CMP_EQ },
177041edb306SCy Schubert 	{ "esp",			IPFY_ESP },
177141edb306SCy Schubert 	{ "exp",			IPFY_IPFEXPR },
177241edb306SCy Schubert 	{ "family",			IPFY_FAMILY },
177341edb306SCy Schubert 	{ "fastroute",			IPFY_FROUTE },
177441edb306SCy Schubert 	{ "first",			IPFY_FIRST },
177541edb306SCy Schubert 	{ "flags",			IPFY_FLAGS },
177641edb306SCy Schubert 	{ "frag",			IPFY_FRAG },
177741edb306SCy Schubert 	{ "frag-body",			IPFY_FRAGBODY },
177841edb306SCy Schubert 	{ "frags",			IPFY_FRAGS },
177941edb306SCy Schubert 	{ "from",			IPFY_FROM },
178041edb306SCy Schubert 	{ "ge",				YY_CMP_GE },
178141edb306SCy Schubert 	{ "group",			IPFY_GROUP },
178241edb306SCy Schubert 	{ "gt",				YY_CMP_GT },
178341edb306SCy Schubert 	{ "head",			IPFY_HEAD },
178441edb306SCy Schubert 	{ "icmp",			IPFY_ICMP },
178541edb306SCy Schubert 	{ "icmp-head",			IPFY_ICMPHEAD },
178641edb306SCy Schubert 	{ "icmp-type",			IPFY_ICMPTYPE },
178741edb306SCy Schubert 	{ "in",				IPFY_IN },
178841edb306SCy Schubert 	{ "in-via",			IPFY_INVIA },
178941edb306SCy Schubert 	{ "inet",			IPFY_INET },
179041edb306SCy Schubert 	{ "inet6",			IPFY_INET6 },
179141edb306SCy Schubert 	{ "ipopt",			IPFY_IPOPTS },
179241edb306SCy Schubert 	{ "ipopts",			IPFY_IPOPTS },
179341edb306SCy Schubert 	{ "keep",			IPFY_KEEP },
179441edb306SCy Schubert 	{ "l5-as",			IPFY_L5AS },
179541edb306SCy Schubert 	{ "le",				YY_CMP_LE },
179641edb306SCy Schubert 	{ "level",			IPFY_LEVEL },
179741edb306SCy Schubert 	{ "limit",			IPFY_LIMIT },
179841edb306SCy Schubert 	{ "log",			IPFY_LOG },
179941edb306SCy Schubert 	{ "loose",			IPFY_LOOSE },
180041edb306SCy Schubert 	{ "lowttl",			IPFY_LOWTTL },
180141edb306SCy Schubert 	{ "lt",				YY_CMP_LT },
180241edb306SCy Schubert 	{ "mask",			IPFY_MASK },
180341edb306SCy Schubert 	{ "match-tag",			IPFY_MATCHTAG },
180441edb306SCy Schubert 	{ "max-per-src",		IPFY_MAX_PER_SRC },
180541edb306SCy Schubert 	{ "max-srcs",			IPFY_MAX_SRCS },
180641edb306SCy Schubert 	{ "mbcast",			IPFY_MBCAST },
180741edb306SCy Schubert 	{ "mcast",			IPFY_MULTICAST },
180841edb306SCy Schubert 	{ "multicast",			IPFY_MULTICAST },
180941edb306SCy Schubert 	{ "nat",			IPFY_NAT },
181041edb306SCy Schubert 	{ "ne",				YY_CMP_NE },
181141edb306SCy Schubert 	{ "net",			IPFY_NETWORK },
181241edb306SCy Schubert 	{ "newisn",			IPFY_NEWISN },
181341edb306SCy Schubert 	{ "no",				IPFY_NO },
181441edb306SCy Schubert 	{ "no-icmp-err",		IPFY_NOICMPERR },
181541edb306SCy Schubert 	{ "nolog",			IPFY_NOLOG },
181641edb306SCy Schubert 	{ "nomatch",			IPFY_NOMATCH },
181741edb306SCy Schubert 	{ "now",			IPFY_NOW },
181841edb306SCy Schubert 	{ "not",			IPFY_NOT },
181941edb306SCy Schubert 	{ "oow",			IPFY_OOW },
182041edb306SCy Schubert 	{ "on",				IPFY_ON },
182141edb306SCy Schubert 	{ "opt",			IPFY_OPT },
182241edb306SCy Schubert 	{ "or-block",			IPFY_ORBLOCK },
182341edb306SCy Schubert 	{ "out",			IPFY_OUT },
182441edb306SCy Schubert 	{ "out-via",			IPFY_OUTVIA },
182541edb306SCy Schubert 	{ "pass",			IPFY_PASS },
182641edb306SCy Schubert 	{ "port",			IPFY_PORT },
182741edb306SCy Schubert 	{ "pps",			IPFY_PPS },
182841edb306SCy Schubert 	{ "preauth",			IPFY_PREAUTH },
182941edb306SCy Schubert 	{ "proto",			IPFY_PROTO },
183041edb306SCy Schubert 	{ "quick",			IPFY_QUICK },
183141edb306SCy Schubert 	{ "reply-to",			IPFY_REPLY_TO },
183241edb306SCy Schubert 	{ "return-icmp",		IPFY_RETICMP },
183341edb306SCy Schubert 	{ "return-icmp-as-dest",	IPFY_RETICMPASDST },
183441edb306SCy Schubert 	{ "return-rst",			IPFY_RETRST },
183541edb306SCy Schubert 	{ "route-to",			IPFY_ROUTETO },
183641edb306SCy Schubert 	{ "rule-ttl",			IPFY_RULETTL },
183741edb306SCy Schubert 	{ "rpc",			IPFY_RPC },
183841edb306SCy Schubert 	{ "sec-class",			IPFY_SECCLASS },
183941edb306SCy Schubert 	{ "set",			IPFY_SET },
184041edb306SCy Schubert 	{ "set-tag",			IPFY_SETTAG },
184141edb306SCy Schubert 	{ "skip",			IPFY_SKIP },
184241edb306SCy Schubert 	{ "short",			IPFY_SHORT },
184341edb306SCy Schubert 	{ "state",			IPFY_STATE },
184441edb306SCy Schubert 	{ "state-age",			IPFY_AGE },
184541edb306SCy Schubert 	{ "strict",			IPFY_STRICT },
184641edb306SCy Schubert 	{ "sync",			IPFY_SYNC },
184741edb306SCy Schubert 	{ "tcp",			IPFY_TCP },
184841edb306SCy Schubert 	{ "tcp-udp",			IPFY_TCPUDP },
184941edb306SCy Schubert 	{ "tos",			IPFY_TOS },
185041edb306SCy Schubert 	{ "to",				IPFY_TO },
185141edb306SCy Schubert 	{ "ttl",			IPFY_TTL },
185241edb306SCy Schubert 	{ "udp",			IPFY_UDP },
185341edb306SCy Schubert 	{ "v6hdr",			IPFY_V6HDR },
185441edb306SCy Schubert 	{ "v6hdrs",			IPFY_V6HDRS },
185541edb306SCy Schubert 	{ "with",			IPFY_WITH },
185641edb306SCy Schubert 	{ NULL,				0 }
185741edb306SCy Schubert };
185841edb306SCy Schubert 
185941edb306SCy Schubert static	struct	wordtab	addrwords[] = {
186041edb306SCy Schubert 	{ "any",			IPFY_ANY },
186141edb306SCy Schubert 	{ "hash",			IPFY_HASH },
186241edb306SCy Schubert 	{ "pool",			IPFY_POOL },
186341edb306SCy Schubert 	{ NULL,				0 }
186441edb306SCy Schubert };
186541edb306SCy Schubert 
186641edb306SCy Schubert static	struct	wordtab	maskwords[] = {
186741edb306SCy Schubert 	{ "broadcast",			IPFY_BROADCAST },
186841edb306SCy Schubert 	{ "netmasked",			IPFY_NETMASKED },
186941edb306SCy Schubert 	{ "network",			IPFY_NETWORK },
187041edb306SCy Schubert 	{ "peer",			IPFY_PEER },
187141edb306SCy Schubert 	{ NULL,				0 }
187241edb306SCy Schubert };
187341edb306SCy Schubert 
187441edb306SCy Schubert static	struct	wordtab icmpcodewords[] = {
187541edb306SCy Schubert 	{ "cutoff-preced",		IPFY_ICMPC_CUTPRE },
187641edb306SCy Schubert 	{ "filter-prohib",		IPFY_ICMPC_FLTPRO },
187741edb306SCy Schubert 	{ "isolate",			IPFY_ICMPC_ISOLATE },
187841edb306SCy Schubert 	{ "needfrag",			IPFY_ICMPC_NEEDF },
187941edb306SCy Schubert 	{ "net-prohib",			IPFY_ICMPC_NETPRO },
188041edb306SCy Schubert 	{ "net-tos",			IPFY_ICMPC_NETTOS },
188141edb306SCy Schubert 	{ "host-preced",		IPFY_ICMPC_HSTPRE },
188241edb306SCy Schubert 	{ "host-prohib",		IPFY_ICMPC_HSTPRO },
188341edb306SCy Schubert 	{ "host-tos",			IPFY_ICMPC_HSTTOS },
188441edb306SCy Schubert 	{ "host-unk",			IPFY_ICMPC_HSTUNK },
188541edb306SCy Schubert 	{ "host-unr",			IPFY_ICMPC_HSTUNR },
188641edb306SCy Schubert 	{ "net-unk",			IPFY_ICMPC_NETUNK },
188741edb306SCy Schubert 	{ "net-unr",			IPFY_ICMPC_NETUNR },
188841edb306SCy Schubert 	{ "port-unr",			IPFY_ICMPC_PORUNR },
188941edb306SCy Schubert 	{ "proto-unr",			IPFY_ICMPC_PROUNR },
189041edb306SCy Schubert 	{ "srcfail",			IPFY_ICMPC_SRCFAIL },
189141edb306SCy Schubert 	{ NULL,				0 },
189241edb306SCy Schubert };
189341edb306SCy Schubert 
189441edb306SCy Schubert static	struct	wordtab ipv4optwords[] = {
189541edb306SCy Schubert 	{ "addext",			IPFY_IPOPT_ADDEXT },
189641edb306SCy Schubert 	{ "cipso",			IPFY_IPOPT_CIPSO },
189741edb306SCy Schubert 	{ "dps",			IPFY_IPOPT_DPS },
189841edb306SCy Schubert 	{ "e-sec",			IPFY_IPOPT_ESEC },
189941edb306SCy Schubert 	{ "eip",			IPFY_IPOPT_EIP },
190041edb306SCy Schubert 	{ "encode",			IPFY_IPOPT_ENCODE },
190141edb306SCy Schubert 	{ "finn",			IPFY_IPOPT_FINN },
190241edb306SCy Schubert 	{ "imitd",			IPFY_IPOPT_IMITD },
190341edb306SCy Schubert 	{ "lsrr",			IPFY_IPOPT_LSRR },
190441edb306SCy Schubert 	{ "mtup",			IPFY_IPOPT_MTUP },
190541edb306SCy Schubert 	{ "mtur",			IPFY_IPOPT_MTUR },
190641edb306SCy Schubert 	{ "nop",			IPFY_IPOPT_NOP },
190741edb306SCy Schubert 	{ "nsapa",			IPFY_IPOPT_NSAPA },
190841edb306SCy Schubert 	{ "rr",				IPFY_IPOPT_RR },
190941edb306SCy Schubert 	{ "rtralrt",			IPFY_IPOPT_RTRALRT },
191041edb306SCy Schubert 	{ "satid",			IPFY_IPOPT_SATID },
191141edb306SCy Schubert 	{ "sdb",			IPFY_IPOPT_SDB },
191241edb306SCy Schubert 	{ "sec",			IPFY_IPOPT_SEC },
191341edb306SCy Schubert 	{ "ssrr",			IPFY_IPOPT_SSRR },
191441edb306SCy Schubert 	{ "tr",				IPFY_IPOPT_TR },
191541edb306SCy Schubert 	{ "ts",				IPFY_IPOPT_TS },
191641edb306SCy Schubert 	{ "ump",			IPFY_IPOPT_UMP },
191741edb306SCy Schubert 	{ "visa",			IPFY_IPOPT_VISA },
191841edb306SCy Schubert 	{ "zsu",			IPFY_IPOPT_ZSU },
191941edb306SCy Schubert 	{ NULL,				0 },
192041edb306SCy Schubert };
192141edb306SCy Schubert 
192241edb306SCy Schubert static	struct	wordtab ipv4secwords[] = {
192341edb306SCy Schubert 	{ "confid",			IPFY_SEC_CONF },
192441edb306SCy Schubert 	{ "reserv-1",			IPFY_SEC_RSV1 },
192541edb306SCy Schubert 	{ "reserv-2",			IPFY_SEC_RSV2 },
192641edb306SCy Schubert 	{ "reserv-3",			IPFY_SEC_RSV3 },
192741edb306SCy Schubert 	{ "reserv-4",			IPFY_SEC_RSV4 },
192841edb306SCy Schubert 	{ "secret",			IPFY_SEC_SEC },
192941edb306SCy Schubert 	{ "topsecret",			IPFY_SEC_TS },
193041edb306SCy Schubert 	{ "unclass",			IPFY_SEC_UNC },
193141edb306SCy Schubert 	{ NULL,				0 },
193241edb306SCy Schubert };
193341edb306SCy Schubert 
193441edb306SCy Schubert static	struct	wordtab ipv6optwords[] = {
193541edb306SCy Schubert 	{ "dstopts",			IPFY_IPV6OPT_DSTOPTS },
193641edb306SCy Schubert 	{ "esp",			IPFY_IPV6OPT_ESP },
193741edb306SCy Schubert 	{ "frag",			IPFY_IPV6OPT_FRAG },
193841edb306SCy Schubert 	{ "hopopts",			IPFY_IPV6OPT_HOPOPTS },
193941edb306SCy Schubert 	{ "ipv6",			IPFY_IPV6OPT_IPV6 },
194041edb306SCy Schubert 	{ "mobility",			IPFY_IPV6OPT_MOBILITY },
194141edb306SCy Schubert 	{ "none",			IPFY_IPV6OPT_NONE },
194241edb306SCy Schubert 	{ "routing",			IPFY_IPV6OPT_ROUTING },
194341edb306SCy Schubert 	{ NULL,				0 },
194441edb306SCy Schubert };
194541edb306SCy Schubert 
194641edb306SCy Schubert static	struct	wordtab logwords[] = {
194741edb306SCy Schubert 	{ "kern",			IPFY_FAC_KERN },
194841edb306SCy Schubert 	{ "user",			IPFY_FAC_USER },
194941edb306SCy Schubert 	{ "mail",			IPFY_FAC_MAIL },
195041edb306SCy Schubert 	{ "daemon",			IPFY_FAC_DAEMON },
195141edb306SCy Schubert 	{ "auth",			IPFY_FAC_AUTH },
195241edb306SCy Schubert 	{ "syslog",			IPFY_FAC_SYSLOG },
195341edb306SCy Schubert 	{ "lpr",			IPFY_FAC_LPR },
195441edb306SCy Schubert 	{ "news",			IPFY_FAC_NEWS },
195541edb306SCy Schubert 	{ "uucp",			IPFY_FAC_UUCP },
195641edb306SCy Schubert 	{ "cron",			IPFY_FAC_CRON },
195741edb306SCy Schubert 	{ "ftp",			IPFY_FAC_FTP },
195841edb306SCy Schubert 	{ "authpriv",			IPFY_FAC_AUTHPRIV },
195941edb306SCy Schubert 	{ "audit",			IPFY_FAC_AUDIT },
196041edb306SCy Schubert 	{ "logalert",			IPFY_FAC_LFMT },
196141edb306SCy Schubert 	{ "console",			IPFY_FAC_CONSOLE },
196241edb306SCy Schubert 	{ "security",			IPFY_FAC_SECURITY },
196341edb306SCy Schubert 	{ "local0",			IPFY_FAC_LOCAL0 },
196441edb306SCy Schubert 	{ "local1",			IPFY_FAC_LOCAL1 },
196541edb306SCy Schubert 	{ "local2",			IPFY_FAC_LOCAL2 },
196641edb306SCy Schubert 	{ "local3",			IPFY_FAC_LOCAL3 },
196741edb306SCy Schubert 	{ "local4",			IPFY_FAC_LOCAL4 },
196841edb306SCy Schubert 	{ "local5",			IPFY_FAC_LOCAL5 },
196941edb306SCy Schubert 	{ "local6",			IPFY_FAC_LOCAL6 },
197041edb306SCy Schubert 	{ "local7",			IPFY_FAC_LOCAL7 },
197141edb306SCy Schubert 	{ "emerg",			IPFY_PRI_EMERG },
197241edb306SCy Schubert 	{ "alert",			IPFY_PRI_ALERT },
197341edb306SCy Schubert 	{ "crit",			IPFY_PRI_CRIT },
197441edb306SCy Schubert 	{ "err",			IPFY_PRI_ERR },
197541edb306SCy Schubert 	{ "warn",			IPFY_PRI_WARN },
197641edb306SCy Schubert 	{ "notice",			IPFY_PRI_NOTICE },
197741edb306SCy Schubert 	{ "info",			IPFY_PRI_INFO },
197841edb306SCy Schubert 	{ "debug",			IPFY_PRI_DEBUG },
197941edb306SCy Schubert 	{ NULL,				0 },
198041edb306SCy Schubert };
198141edb306SCy Schubert 
198241edb306SCy Schubert 
198341edb306SCy Schubert 
198441edb306SCy Schubert 
1985efeb8bffSCy Schubert int
ipf_parsefile(int fd,addfunc_t addfunc,ioctlfunc_t * iocfuncs,char * filename)1986efeb8bffSCy Schubert ipf_parsefile(int fd, addfunc_t addfunc, ioctlfunc_t *iocfuncs, char *filename)
198741edb306SCy Schubert {
198841edb306SCy Schubert 	FILE *fp = NULL;
198941edb306SCy Schubert 	char *s;
199041edb306SCy Schubert 
199141edb306SCy Schubert 	yylineNum = 1;
199241edb306SCy Schubert 	yysettab(ipfwords);
199341edb306SCy Schubert 
199441edb306SCy Schubert 	s = getenv("YYDEBUG");
199541edb306SCy Schubert 	if (s != NULL)
199641edb306SCy Schubert 		yydebug = atoi(s);
199741edb306SCy Schubert 	else
199841edb306SCy Schubert 		yydebug = 0;
199941edb306SCy Schubert 
200041edb306SCy Schubert 	if (strcmp(filename, "-")) {
200141edb306SCy Schubert 		fp = fopen(filename, "r");
200241edb306SCy Schubert 		if (fp == NULL) {
200341edb306SCy Schubert 			fprintf(stderr, "fopen(%s) failed: %s\n", filename,
200441edb306SCy Schubert 				STRERROR(errno));
2005*2582ae57SCy Schubert 			return(-1);
200641edb306SCy Schubert 		}
200741edb306SCy Schubert 	} else
200841edb306SCy Schubert 		fp = stdin;
200941edb306SCy Schubert 
201041edb306SCy Schubert 	while (ipf_parsesome(fd, addfunc, iocfuncs, fp) == 1)
201141edb306SCy Schubert 		;
201241edb306SCy Schubert 	if (fp != NULL)
201341edb306SCy Schubert 		fclose(fp);
2014*2582ae57SCy Schubert 	return(0);
201541edb306SCy Schubert }
201641edb306SCy Schubert 
201741edb306SCy Schubert 
2018efeb8bffSCy Schubert int
ipf_parsesome(int fd,addfunc_t addfunc,ioctlfunc_t * iocfuncs,FILE * fp)2019efeb8bffSCy Schubert ipf_parsesome(int fd, addfunc_t addfunc, ioctlfunc_t *iocfuncs, FILE *fp)
202041edb306SCy Schubert {
202141edb306SCy Schubert 	char *s;
202241edb306SCy Schubert 	int i;
202341edb306SCy Schubert 
202441edb306SCy Schubert 	ipffd = fd;
202541edb306SCy Schubert 	for (i = 0; i <= IPL_LOGMAX; i++)
202641edb306SCy Schubert 		ipfioctls[i] = iocfuncs[i];
202741edb306SCy Schubert 	ipfaddfunc = addfunc;
202841edb306SCy Schubert 
202941edb306SCy Schubert 	if (feof(fp))
2030*2582ae57SCy Schubert 		return(0);
203141edb306SCy Schubert 	i = fgetc(fp);
203241edb306SCy Schubert 	if (i == EOF)
2033*2582ae57SCy Schubert 		return(0);
203441edb306SCy Schubert 	if (ungetc(i, fp) == 0)
2035*2582ae57SCy Schubert 		return(0);
203641edb306SCy Schubert 	if (feof(fp))
2037*2582ae57SCy Schubert 		return(0);
203841edb306SCy Schubert 	s = getenv("YYDEBUG");
203941edb306SCy Schubert 	if (s != NULL)
204041edb306SCy Schubert 		yydebug = atoi(s);
204141edb306SCy Schubert 	else
204241edb306SCy Schubert 		yydebug = 0;
204341edb306SCy Schubert 
204441edb306SCy Schubert 	yyin = fp;
204541edb306SCy Schubert 	yyparse();
2046*2582ae57SCy Schubert 	return(1);
204741edb306SCy Schubert }
204841edb306SCy Schubert 
204941edb306SCy Schubert 
2050efeb8bffSCy Schubert static void
newrule(void)2051efeb8bffSCy Schubert newrule(void)
205241edb306SCy Schubert {
205341edb306SCy Schubert 	frentry_t *frn;
205441edb306SCy Schubert 
205541edb306SCy Schubert 	frn = allocfr();
205641edb306SCy Schubert 	for (fr = frtop; fr != NULL && fr->fr_next != NULL; fr = fr->fr_next)
205741edb306SCy Schubert 		;
205841edb306SCy Schubert 	if (fr != NULL) {
205941edb306SCy Schubert 		fr->fr_next = frn;
206041edb306SCy Schubert 		frn->fr_pnext = &fr->fr_next;
206141edb306SCy Schubert 	}
206241edb306SCy Schubert 	if (frtop == NULL) {
206341edb306SCy Schubert 		frtop = frn;
206441edb306SCy Schubert 		frn->fr_pnext = &frtop;
206541edb306SCy Schubert 	}
206641edb306SCy Schubert 	fr = frn;
206741edb306SCy Schubert 	frc = frn;
206841edb306SCy Schubert 	fr->fr_loglevel = 0xffff;
206941edb306SCy Schubert 	fr->fr_isc = (void *)-1;
207041edb306SCy Schubert 	fr->fr_logtag = FR_NOLOGTAG;
207141edb306SCy Schubert 	fr->fr_type = FR_T_NONE;
207241edb306SCy Schubert 	fr->fr_flineno = yylineNum;
207341edb306SCy Schubert 
207441edb306SCy Schubert 	if (use_inet6 == 1)
207541edb306SCy Schubert 		fr->fr_family = AF_INET6;
207641edb306SCy Schubert 	else if (use_inet6 == -1)
207741edb306SCy Schubert 		fr->fr_family = AF_INET;
207841edb306SCy Schubert 
207941edb306SCy Schubert 	nrules = 1;
208041edb306SCy Schubert }
208141edb306SCy Schubert 
208241edb306SCy Schubert 
2083efeb8bffSCy Schubert static void
setipftype(void)2084efeb8bffSCy Schubert setipftype(void)
208541edb306SCy Schubert {
208641edb306SCy Schubert 	for (fr = frc; fr != NULL; fr = fr->fr_next) {
208741edb306SCy Schubert 		if (fr->fr_type == FR_T_NONE) {
208841edb306SCy Schubert 			fr->fr_type = FR_T_IPF;
208941edb306SCy Schubert 			fr->fr_data = (void *)calloc(sizeof(fripf_t), 1);
209041edb306SCy Schubert 			fr->fr_dsize = sizeof(fripf_t);
209141edb306SCy Schubert 			fr->fr_family = frc->fr_family;
209241edb306SCy Schubert 			if (fr->fr_family == AF_INET) {
209341edb306SCy Schubert 				fr->fr_ip.fi_v = 4;
209441edb306SCy Schubert 			}
209541edb306SCy Schubert 			else if (fr->fr_family == AF_INET6) {
209641edb306SCy Schubert 				fr->fr_ip.fi_v = 6;
209741edb306SCy Schubert 			}
209841edb306SCy Schubert 			fr->fr_mip.fi_v = 0xf;
209941edb306SCy Schubert 			fr->fr_ipf->fri_sifpidx = -1;
210041edb306SCy Schubert 			fr->fr_ipf->fri_difpidx = -1;
210141edb306SCy Schubert 		}
210241edb306SCy Schubert 		if (fr->fr_type != FR_T_IPF) {
210341edb306SCy Schubert 			fprintf(stderr, "IPF Type not set\n");
210441edb306SCy Schubert 		}
210541edb306SCy Schubert 	}
210641edb306SCy Schubert }
210741edb306SCy Schubert 
210841edb306SCy Schubert 
2109efeb8bffSCy Schubert static frentry_t *
addrule(void)2110efeb8bffSCy Schubert addrule(void)
211141edb306SCy Schubert {
211241edb306SCy Schubert 	frentry_t *f, *f1, *f2;
211341edb306SCy Schubert 	int count;
211441edb306SCy Schubert 
211541edb306SCy Schubert 	for (f2 = frc; f2->fr_next != NULL; f2 = f2->fr_next)
211641edb306SCy Schubert 		;
211741edb306SCy Schubert 
211841edb306SCy Schubert 	count = nrules;
211941edb306SCy Schubert 	f = f2;
212041edb306SCy Schubert 	for (f1 = frc; count > 0; count--, f1 = f1->fr_next) {
212141edb306SCy Schubert 		f->fr_next = allocfr();
212241edb306SCy Schubert 		if (f->fr_next == NULL)
2123*2582ae57SCy Schubert 			return(NULL);
212441edb306SCy Schubert 		f->fr_next->fr_pnext = &f->fr_next;
212541edb306SCy Schubert 		added++;
212641edb306SCy Schubert 		f = f->fr_next;
212741edb306SCy Schubert 		*f = *f1;
212841edb306SCy Schubert 		f->fr_next = NULL;
212941edb306SCy Schubert 		if (f->fr_caddr != NULL) {
213041edb306SCy Schubert 			f->fr_caddr = malloc(f->fr_dsize);
213141edb306SCy Schubert 			bcopy(f1->fr_caddr, f->fr_caddr, f->fr_dsize);
213241edb306SCy Schubert 		}
213341edb306SCy Schubert 	}
213441edb306SCy Schubert 
2135*2582ae57SCy Schubert 	return(f2->fr_next);
213641edb306SCy Schubert }
213741edb306SCy Schubert 
213841edb306SCy Schubert 
213941edb306SCy Schubert static int
lookuphost(char * name,i6addr_t * addrp)2140efeb8bffSCy Schubert lookuphost(char *name, i6addr_t *addrp)
214141edb306SCy Schubert {
214241edb306SCy Schubert 	int i;
214341edb306SCy Schubert 
214441edb306SCy Schubert 	hashed = 0;
214541edb306SCy Schubert 	pooled = 0;
214641edb306SCy Schubert 	dynamic = -1;
214741edb306SCy Schubert 
214841edb306SCy Schubert 	for (i = 0; i < 4; i++) {
214941edb306SCy Schubert 		if (fr->fr_ifnames[i] == -1)
215041edb306SCy Schubert 			continue;
215141edb306SCy Schubert 		if (strcmp(name, fr->fr_names + fr->fr_ifnames[i]) == 0) {
215241edb306SCy Schubert 			ifpflag = FRI_DYNAMIC;
215341edb306SCy Schubert 			dynamic = addname(&fr, name);
2154*2582ae57SCy Schubert 			return(1);
215541edb306SCy Schubert 		}
215641edb306SCy Schubert 	}
215741edb306SCy Schubert 
215841edb306SCy Schubert 	if (gethost(AF_INET, name, addrp) == -1) {
215941edb306SCy Schubert 		fprintf(stderr, "unknown name \"%s\"\n", name);
2160*2582ae57SCy Schubert 		return(-1);
216141edb306SCy Schubert 	}
2162*2582ae57SCy Schubert 	return(0);
216341edb306SCy Schubert }
216441edb306SCy Schubert 
216541edb306SCy Schubert 
2166efeb8bffSCy Schubert static void
dobpf(int v,char * phrase)2167efeb8bffSCy Schubert dobpf(int v, char *phrase)
216841edb306SCy Schubert {
216941edb306SCy Schubert #ifdef IPFILTER_BPF
217041edb306SCy Schubert 	struct bpf_program bpf;
217141edb306SCy Schubert 	struct pcap *p;
217241edb306SCy Schubert #endif
217341edb306SCy Schubert 	fakebpf_t *fb;
217441edb306SCy Schubert 	u_32_t l;
217541edb306SCy Schubert 	char *s;
217641edb306SCy Schubert 	int i;
217741edb306SCy Schubert 
217841edb306SCy Schubert 	for (fr = frc; fr != NULL; fr = fr->fr_next) {
217941edb306SCy Schubert 		if (fr->fr_type != FR_T_NONE) {
218041edb306SCy Schubert 			fprintf(stderr, "cannot mix IPF and BPF matching\n");
218141edb306SCy Schubert 			return;
218241edb306SCy Schubert 		}
218341edb306SCy Schubert 		fr->fr_family = vtof(v);
218441edb306SCy Schubert 		fr->fr_type = FR_T_BPFOPC;
218541edb306SCy Schubert 
218641edb306SCy Schubert 		if (!strncmp(phrase, "0x", 2)) {
218741edb306SCy Schubert 			fb = malloc(sizeof(fakebpf_t));
218841edb306SCy Schubert 
218941edb306SCy Schubert 			for (i = 0, s = strtok(phrase, " \r\n\t"); s != NULL;
219041edb306SCy Schubert 			     s = strtok(NULL, " \r\n\t"), i++) {
219141edb306SCy Schubert 				fb = reallocarray(fb, i / 4 + 1, sizeof(*fb));
219241edb306SCy Schubert 				if (fb == NULL) {
219341edb306SCy Schubert 					warnx("memory allocation error at %d in %s in %s", __LINE__, __FUNCTION__, __FILE__);
219441edb306SCy Schubert 					abort();
219541edb306SCy Schubert 				}
219641edb306SCy Schubert 				l = (u_32_t)strtol(s, NULL, 0);
219741edb306SCy Schubert 				switch (i & 3)
219841edb306SCy Schubert 				{
219941edb306SCy Schubert 				case 0 :
220041edb306SCy Schubert 					fb[i / 4].fb_c = l & 0xffff;
220141edb306SCy Schubert 					break;
220241edb306SCy Schubert 				case 1 :
220341edb306SCy Schubert 					fb[i / 4].fb_t = l & 0xff;
220441edb306SCy Schubert 					break;
220541edb306SCy Schubert 				case 2 :
220641edb306SCy Schubert 					fb[i / 4].fb_f = l & 0xff;
220741edb306SCy Schubert 					break;
220841edb306SCy Schubert 				case 3 :
220941edb306SCy Schubert 					fb[i / 4].fb_k = l;
221041edb306SCy Schubert 					break;
221141edb306SCy Schubert 				}
221241edb306SCy Schubert 			}
221341edb306SCy Schubert 			if ((i & 3) != 0) {
221441edb306SCy Schubert 				fprintf(stderr,
221541edb306SCy Schubert 					"Odd number of bytes in BPF code\n");
221641edb306SCy Schubert 				exit(1);
221741edb306SCy Schubert 			}
221841edb306SCy Schubert 			i--;
221941edb306SCy Schubert 			fr->fr_dsize = (i / 4 + 1) * sizeof(*fb);
222041edb306SCy Schubert 			fr->fr_data = fb;
222141edb306SCy Schubert 			return;
222241edb306SCy Schubert 		}
222341edb306SCy Schubert 
222441edb306SCy Schubert #ifdef IPFILTER_BPF
222541edb306SCy Schubert 		bzero((char *)&bpf, sizeof(bpf));
222641edb306SCy Schubert 		p = pcap_open_dead(DLT_RAW, 1);
222741edb306SCy Schubert 		if (!p) {
222841edb306SCy Schubert 			fprintf(stderr, "pcap_open_dead failed\n");
222941edb306SCy Schubert 			return;
223041edb306SCy Schubert 		}
223141edb306SCy Schubert 
223241edb306SCy Schubert 		if (pcap_compile(p, &bpf, phrase, 1, 0xffffffff)) {
223341edb306SCy Schubert 			pcap_perror(p, "ipf");
223441edb306SCy Schubert 			pcap_close(p);
223541edb306SCy Schubert 			fprintf(stderr, "pcap parsing failed (%s)\n", phrase);
223641edb306SCy Schubert 			return;
223741edb306SCy Schubert 		}
223841edb306SCy Schubert 		pcap_close(p);
223941edb306SCy Schubert 
224041edb306SCy Schubert 		fr->fr_dsize = bpf.bf_len * sizeof(struct bpf_insn);
224141edb306SCy Schubert 		fr->fr_data = malloc(fr->fr_dsize);
224241edb306SCy Schubert 		bcopy((char *)bpf.bf_insns, fr->fr_data, fr->fr_dsize);
224341edb306SCy Schubert 		if (!bpf_validate(fr->fr_data, bpf.bf_len)) {
224441edb306SCy Schubert 			fprintf(stderr, "BPF validation failed\n");
224541edb306SCy Schubert 			return;
224641edb306SCy Schubert 		}
224741edb306SCy Schubert #endif
224841edb306SCy Schubert 	}
224941edb306SCy Schubert 
225041edb306SCy Schubert #ifdef IPFILTER_BPF
225141edb306SCy Schubert 	if (opts & OPT_DEBUG)
225241edb306SCy Schubert 		bpf_dump(&bpf, 0);
225341edb306SCy Schubert #else
225441edb306SCy Schubert 	fprintf(stderr, "BPF filter expressions not supported\n");
225541edb306SCy Schubert 	exit(1);
225641edb306SCy Schubert #endif
225741edb306SCy Schubert }
225841edb306SCy Schubert 
225941edb306SCy Schubert 
2260efeb8bffSCy Schubert static void
resetaddr(void)2261efeb8bffSCy Schubert resetaddr(void)
226241edb306SCy Schubert {
226341edb306SCy Schubert 	hashed = 0;
226441edb306SCy Schubert 	pooled = 0;
226541edb306SCy Schubert 	dynamic = -1;
226641edb306SCy Schubert }
226741edb306SCy Schubert 
226841edb306SCy Schubert 
2269efeb8bffSCy Schubert static alist_t *
newalist(alist_t * ptr)2270efeb8bffSCy Schubert newalist(alist_t *ptr)
227141edb306SCy Schubert {
227241edb306SCy Schubert 	alist_t *al;
227341edb306SCy Schubert 
227441edb306SCy Schubert 	al = malloc(sizeof(*al));
227541edb306SCy Schubert 	if (al == NULL)
2276*2582ae57SCy Schubert 		return(NULL);
227741edb306SCy Schubert 	al->al_not = 0;
227841edb306SCy Schubert 	al->al_next = ptr;
2279*2582ae57SCy Schubert 	return(al);
228041edb306SCy Schubert }
228141edb306SCy Schubert 
228241edb306SCy Schubert 
228341edb306SCy Schubert static int
makepool(alist_t * list)2284efeb8bffSCy Schubert makepool(alist_t *list)
228541edb306SCy Schubert {
228641edb306SCy Schubert 	ip_pool_node_t *n, *top;
228741edb306SCy Schubert 	ip_pool_t pool;
228841edb306SCy Schubert 	alist_t *a;
228941edb306SCy Schubert 	int num;
229041edb306SCy Schubert 
229141edb306SCy Schubert 	if (list == NULL)
2292*2582ae57SCy Schubert 		return(0);
229341edb306SCy Schubert 	top = calloc(1, sizeof(*top));
229441edb306SCy Schubert 	if (top == NULL)
2295*2582ae57SCy Schubert 		return(0);
229641edb306SCy Schubert 
229741edb306SCy Schubert 	for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) {
229841edb306SCy Schubert 		if (use_inet6 == 1) {
229941edb306SCy Schubert #ifdef USE_INET6
230041edb306SCy Schubert 			n->ipn_addr.adf_family = AF_INET6;
230141edb306SCy Schubert 			n->ipn_addr.adf_addr = a->al_i6addr;
230241edb306SCy Schubert 			n->ipn_addr.adf_len = offsetof(addrfamily_t,
230341edb306SCy Schubert 						       adf_addr) + 16;
230441edb306SCy Schubert 			n->ipn_mask.adf_family = AF_INET6;
230541edb306SCy Schubert 			n->ipn_mask.adf_addr = a->al_i6mask;
230641edb306SCy Schubert 			n->ipn_mask.adf_len = offsetof(addrfamily_t,
230741edb306SCy Schubert 						       adf_addr) + 16;
230841edb306SCy Schubert 
230941edb306SCy Schubert #endif
231041edb306SCy Schubert 		} else {
231141edb306SCy Schubert 			n->ipn_addr.adf_family = AF_INET;
231241edb306SCy Schubert 			n->ipn_addr.adf_addr.in4.s_addr = a->al_1;
231341edb306SCy Schubert 			n->ipn_addr.adf_len = offsetof(addrfamily_t,
231441edb306SCy Schubert 						       adf_addr) + 4;
231541edb306SCy Schubert 			n->ipn_mask.adf_family = AF_INET;
231641edb306SCy Schubert 			n->ipn_mask.adf_addr.in4.s_addr = a->al_2;
231741edb306SCy Schubert 			n->ipn_mask.adf_len = offsetof(addrfamily_t,
231841edb306SCy Schubert 						       adf_addr) + 4;
231941edb306SCy Schubert 		}
232041edb306SCy Schubert 		n->ipn_info = a->al_not;
232141edb306SCy Schubert 		if (a->al_next != NULL) {
232241edb306SCy Schubert 			n->ipn_next = calloc(1, sizeof(*n));
232341edb306SCy Schubert 			n = n->ipn_next;
232441edb306SCy Schubert 		}
232541edb306SCy Schubert 	}
232641edb306SCy Schubert 
232741edb306SCy Schubert 	bzero((char *)&pool, sizeof(pool));
232841edb306SCy Schubert 	pool.ipo_unit = IPL_LOGIPF;
232941edb306SCy Schubert 	pool.ipo_list = top;
233041edb306SCy Schubert 	num = load_pool(&pool, ipfioctls[IPL_LOGLOOKUP]);
233141edb306SCy Schubert 
233241edb306SCy Schubert 	while ((n = top) != NULL) {
233341edb306SCy Schubert 		top = n->ipn_next;
233441edb306SCy Schubert 		free(n);
233541edb306SCy Schubert 	}
2336*2582ae57SCy Schubert 	return(num);
233741edb306SCy Schubert }
233841edb306SCy Schubert 
233941edb306SCy Schubert 
2340efeb8bffSCy Schubert static u_int
makehash(alist_t * list)2341efeb8bffSCy Schubert makehash(alist_t *list)
234241edb306SCy Schubert {
234341edb306SCy Schubert 	iphtent_t *n, *top;
234441edb306SCy Schubert 	iphtable_t iph;
234541edb306SCy Schubert 	alist_t *a;
234641edb306SCy Schubert 	int num;
234741edb306SCy Schubert 
234841edb306SCy Schubert 	if (list == NULL)
2349*2582ae57SCy Schubert 		return(0);
235041edb306SCy Schubert 	top = calloc(1, sizeof(*top));
235141edb306SCy Schubert 	if (top == NULL)
2352*2582ae57SCy Schubert 		return(0);
235341edb306SCy Schubert 
235441edb306SCy Schubert 	for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) {
235541edb306SCy Schubert 		if (a->al_family == AF_INET6) {
235641edb306SCy Schubert 			n->ipe_family = AF_INET6;
235741edb306SCy Schubert 			n->ipe_addr = a->al_i6addr;
235841edb306SCy Schubert 			n->ipe_mask = a->al_i6mask;
235941edb306SCy Schubert 		} else {
236041edb306SCy Schubert 			n->ipe_family = AF_INET;
236141edb306SCy Schubert 			n->ipe_addr.in4_addr = a->al_1;
236241edb306SCy Schubert 			n->ipe_mask.in4_addr = a->al_2;
236341edb306SCy Schubert 		}
236441edb306SCy Schubert 		n->ipe_value = 0;
236541edb306SCy Schubert 		if (a->al_next != NULL) {
236641edb306SCy Schubert 			n->ipe_next = calloc(1, sizeof(*n));
236741edb306SCy Schubert 			n = n->ipe_next;
236841edb306SCy Schubert 		}
236941edb306SCy Schubert 	}
237041edb306SCy Schubert 
237141edb306SCy Schubert 	bzero((char *)&iph, sizeof(iph));
237241edb306SCy Schubert 	iph.iph_unit = IPL_LOGIPF;
237341edb306SCy Schubert 	iph.iph_type = IPHASH_LOOKUP;
237441edb306SCy Schubert 	*iph.iph_name = '\0';
237541edb306SCy Schubert 
237641edb306SCy Schubert 	if (load_hash(&iph, top, ipfioctls[IPL_LOGLOOKUP]) == 0)
237741edb306SCy Schubert 		sscanf(iph.iph_name, "%u", &num);
237841edb306SCy Schubert 	else
237941edb306SCy Schubert 		num = 0;
238041edb306SCy Schubert 
238141edb306SCy Schubert 	while ((n = top) != NULL) {
238241edb306SCy Schubert 		top = n->ipe_next;
238341edb306SCy Schubert 		free(n);
238441edb306SCy Schubert 	}
2385*2582ae57SCy Schubert 	return(num);
238641edb306SCy Schubert }
238741edb306SCy Schubert 
238841edb306SCy Schubert 
2389efeb8bffSCy Schubert int
ipf_addrule(int fd,ioctlfunc_t ioctlfunc,void * ptr)2390efeb8bffSCy Schubert ipf_addrule(int fd, ioctlfunc_t ioctlfunc, void *ptr)
239141edb306SCy Schubert {
239241edb306SCy Schubert 	ioctlcmd_t add, del;
239341edb306SCy Schubert 	frentry_t *fr;
239441edb306SCy Schubert 	ipfobj_t obj;
239541edb306SCy Schubert 
239641edb306SCy Schubert 	if (ptr == NULL)
2397*2582ae57SCy Schubert 		return(0);
239841edb306SCy Schubert 
239941edb306SCy Schubert 	fr = ptr;
240041edb306SCy Schubert 	add = 0;
240141edb306SCy Schubert 	del = 0;
240241edb306SCy Schubert 
240341edb306SCy Schubert 	bzero((char *)&obj, sizeof(obj));
240441edb306SCy Schubert 	obj.ipfo_rev = IPFILTER_VERSION;
240541edb306SCy Schubert 	obj.ipfo_size = fr->fr_size;
240641edb306SCy Schubert 	obj.ipfo_type = IPFOBJ_FRENTRY;
240741edb306SCy Schubert 	obj.ipfo_ptr = ptr;
240841edb306SCy Schubert 
240941edb306SCy Schubert 	if ((opts & OPT_DONOTHING) != 0)
241041edb306SCy Schubert 		fd = -1;
241141edb306SCy Schubert 
241241edb306SCy Schubert 	if (opts & OPT_ZERORULEST) {
241341edb306SCy Schubert 		add = SIOCZRLST;
241441edb306SCy Schubert 	} else if (opts & OPT_INACTIVE) {
241541edb306SCy Schubert 		add = (u_int)fr->fr_hits ? SIOCINIFR :
241641edb306SCy Schubert 					   SIOCADIFR;
241741edb306SCy Schubert 		del = SIOCRMIFR;
241841edb306SCy Schubert 	} else {
241941edb306SCy Schubert 		add = (u_int)fr->fr_hits ? SIOCINAFR :
242041edb306SCy Schubert 					   SIOCADAFR;
242141edb306SCy Schubert 		del = SIOCRMAFR;
242241edb306SCy Schubert 	}
242341edb306SCy Schubert 
242441edb306SCy Schubert 	if ((opts & OPT_OUTQUE) != 0)
242541edb306SCy Schubert 		fr->fr_flags |= FR_OUTQUE;
242641edb306SCy Schubert 	if (fr->fr_hits)
242741edb306SCy Schubert 		fr->fr_hits--;
242841edb306SCy Schubert 	if ((opts & OPT_VERBOSE) != 0)
242941edb306SCy Schubert 		printfr(fr, ioctlfunc);
243041edb306SCy Schubert 
243141edb306SCy Schubert 	if ((opts & OPT_DEBUG) != 0) {
243241edb306SCy Schubert 		binprint(fr, sizeof(*fr));
243341edb306SCy Schubert 		if (fr->fr_data != NULL)
243441edb306SCy Schubert 			binprint(fr->fr_data, fr->fr_dsize);
243541edb306SCy Schubert 	}
243641edb306SCy Schubert 
243741edb306SCy Schubert 	if ((opts & OPT_ZERORULEST) != 0) {
243841edb306SCy Schubert 		if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
243941edb306SCy Schubert 			if ((opts & OPT_DONOTHING) == 0) {
244041edb306SCy Schubert 				char msg[80];
244141edb306SCy Schubert 
244241edb306SCy Schubert 				snprintf(msg, sizeof(msg), "%d:ioctl(zero rule)",
244341edb306SCy Schubert 					fr->fr_flineno);
2444*2582ae57SCy Schubert 				return(ipf_perror_fd(fd, ioctlfunc, msg));
244541edb306SCy Schubert 			}
244641edb306SCy Schubert 		} else {
244741edb306SCy Schubert #ifdef	USE_QUAD_T
244841edb306SCy Schubert 			printf("hits %qd bytes %qd ",
244941edb306SCy Schubert 				(long long)fr->fr_hits,
245041edb306SCy Schubert 				(long long)fr->fr_bytes);
245141edb306SCy Schubert #else
245241edb306SCy Schubert 			printf("hits %ld bytes %ld ",
245341edb306SCy Schubert 				fr->fr_hits, fr->fr_bytes);
245441edb306SCy Schubert #endif
245541edb306SCy Schubert 			printfr(fr, ioctlfunc);
245641edb306SCy Schubert 		}
245741edb306SCy Schubert 	} else if ((opts & OPT_REMOVE) != 0) {
245841edb306SCy Schubert 		if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) {
245941edb306SCy Schubert 			if ((opts & OPT_DONOTHING) == 0) {
246041edb306SCy Schubert 				char msg[80];
246141edb306SCy Schubert 
246241edb306SCy Schubert 				snprintf(msg, sizeof(msg), "%d:ioctl(delete rule)",
246341edb306SCy Schubert 					fr->fr_flineno);
2464*2582ae57SCy Schubert 				return(ipf_perror_fd(fd, ioctlfunc, msg));
246541edb306SCy Schubert 			}
246641edb306SCy Schubert 		}
246741edb306SCy Schubert 	} else {
246841edb306SCy Schubert 		if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
246941edb306SCy Schubert 			if ((opts & OPT_DONOTHING) == 0) {
247041edb306SCy Schubert 				char msg[80];
247141edb306SCy Schubert 
247241edb306SCy Schubert 				snprintf(msg, sizeof(msg), "%d:ioctl(add/insert rule)",
247341edb306SCy Schubert 					fr->fr_flineno);
2474*2582ae57SCy Schubert 				return(ipf_perror_fd(fd, ioctlfunc, msg));
247541edb306SCy Schubert 			}
247641edb306SCy Schubert 		}
247741edb306SCy Schubert 	}
2478*2582ae57SCy Schubert 	return(0);
247941edb306SCy Schubert }
248041edb306SCy Schubert 
2481efeb8bffSCy Schubert static void
setsyslog(void)2482efeb8bffSCy Schubert setsyslog(void)
248341edb306SCy Schubert {
248441edb306SCy Schubert 	yysetdict(logwords);
248541edb306SCy Schubert 	yybreakondot = 1;
248641edb306SCy Schubert }
248741edb306SCy Schubert 
248841edb306SCy Schubert 
2489efeb8bffSCy Schubert static void
unsetsyslog(void)2490efeb8bffSCy Schubert unsetsyslog(void)
249141edb306SCy Schubert {
249241edb306SCy Schubert 	yyresetdict();
249341edb306SCy Schubert 	yybreakondot = 0;
249441edb306SCy Schubert }
249541edb306SCy Schubert 
249641edb306SCy Schubert 
2497efeb8bffSCy Schubert static void
fillgroup(frentry_t * fr)2498efeb8bffSCy Schubert fillgroup(frentry_t *fr)
249941edb306SCy Schubert {
250041edb306SCy Schubert 	frentry_t *f;
250141edb306SCy Schubert 
250241edb306SCy Schubert 	for (f = frold; f != NULL; f = f->fr_next) {
250341edb306SCy Schubert 		if (f->fr_grhead == -1 && fr->fr_group == -1)
250441edb306SCy Schubert 			break;
250541edb306SCy Schubert 		if (f->fr_grhead == -1 || fr->fr_group == -1)
250641edb306SCy Schubert 			continue;
250741edb306SCy Schubert 		if (strcmp(f->fr_names + f->fr_grhead,
250841edb306SCy Schubert 			   fr->fr_names + fr->fr_group) == 0)
250941edb306SCy Schubert 			break;
251041edb306SCy Schubert 	}
251141edb306SCy Schubert 
251241edb306SCy Schubert 	if (f == NULL)
251341edb306SCy Schubert 		return;
251441edb306SCy Schubert 
251541edb306SCy Schubert 	/*
251641edb306SCy Schubert 	 * Only copy down matching fields if the rules are of the same type
251741edb306SCy Schubert 	 * and are of ipf type.   The only fields that are copied are those
251841edb306SCy Schubert 	 * that impact the rule parsing itself, eg. need for knowing what the
251941edb306SCy Schubert 	 * protocol should be for rules with port comparisons in them.
252041edb306SCy Schubert 	 */
252141edb306SCy Schubert 	if (f->fr_type != fr->fr_type || f->fr_type != FR_T_IPF)
252241edb306SCy Schubert 		return;
252341edb306SCy Schubert 
252441edb306SCy Schubert 	if (fr->fr_family == 0 && f->fr_family != 0)
252541edb306SCy Schubert 		fr->fr_family = f->fr_family;
252641edb306SCy Schubert 
252741edb306SCy Schubert 	if (fr->fr_mproto == 0 && f->fr_mproto != 0)
252841edb306SCy Schubert 		fr->fr_mproto = f->fr_mproto;
252941edb306SCy Schubert 	if (fr->fr_proto == 0 && f->fr_proto != 0)
253041edb306SCy Schubert 		fr->fr_proto = f->fr_proto;
253141edb306SCy Schubert 
253241edb306SCy Schubert 	if ((fr->fr_mproto == 0) && ((fr->fr_flx & FI_TCPUDP) == 0) &&
253341edb306SCy Schubert 	    ((f->fr_flx & FI_TCPUDP) != 0)) {
253441edb306SCy Schubert 		fr->fr_flx |= FI_TCPUDP;
253541edb306SCy Schubert 		fr->fr_mflx |= FI_TCPUDP;
253641edb306SCy Schubert 	}
253741edb306SCy Schubert }
253841edb306SCy Schubert 
253941edb306SCy Schubert 
2540efeb8bffSCy Schubert static void
doipfexpr(char * line)2541efeb8bffSCy Schubert doipfexpr(char *line)
254241edb306SCy Schubert {
254341edb306SCy Schubert 	int *array;
254441edb306SCy Schubert 	char *error;
254541edb306SCy Schubert 
254641edb306SCy Schubert 	array = parseipfexpr(line, &error);
254741edb306SCy Schubert 	if (array == NULL) {
254841edb306SCy Schubert 		fprintf(stderr, "%s:", error);
254941edb306SCy Schubert 		yyerror("error parsing ipf matching expression");
255041edb306SCy Schubert 		return;
255141edb306SCy Schubert 	}
255241edb306SCy Schubert 
255341edb306SCy Schubert 	fr->fr_type = FR_T_IPFEXPR;
255441edb306SCy Schubert 	fr->fr_data = array;
255541edb306SCy Schubert 	fr->fr_dsize = array[0] * sizeof(*array);
255641edb306SCy Schubert }
255741edb306SCy Schubert 
255841edb306SCy Schubert 
2559efeb8bffSCy Schubert static void
do_tuneint(char * varname,int value)2560efeb8bffSCy Schubert do_tuneint(char *varname, int value)
256141edb306SCy Schubert {
256241edb306SCy Schubert 	char buffer[80];
256341edb306SCy Schubert 
256441edb306SCy Schubert 	strncpy(buffer, varname, 60);
256541edb306SCy Schubert 	buffer[59] = '\0';
256641edb306SCy Schubert 	strcat(buffer, "=");
256741edb306SCy Schubert 	snprintf(buffer, sizeof(buffer), "%u", value);
256841edb306SCy Schubert 	ipf_dotuning(ipffd, buffer, ioctl);
256941edb306SCy Schubert }
257041edb306SCy Schubert 
257141edb306SCy Schubert 
2572efeb8bffSCy Schubert static void
do_tunestr(char * varname,char * value)2573efeb8bffSCy Schubert do_tunestr(char *varname, char *value)
257441edb306SCy Schubert {
257541edb306SCy Schubert 
257641edb306SCy Schubert 	if (!strcasecmp(value, "true")) {
257741edb306SCy Schubert 		do_tuneint(varname, 1);
257841edb306SCy Schubert 	} else if (!strcasecmp(value, "false")) {
257941edb306SCy Schubert 		do_tuneint(varname, 0);
258041edb306SCy Schubert 	} else {
258141edb306SCy Schubert 		yyerror("did not find true/false where expected");
258241edb306SCy Schubert 	}
258341edb306SCy Schubert }
258441edb306SCy Schubert 
258541edb306SCy Schubert 
2586efeb8bffSCy Schubert static void
setifname(frentry_t ** frp,int idx,char * name)2587efeb8bffSCy Schubert setifname(frentry_t **frp, int idx, char *name)
258841edb306SCy Schubert {
258941edb306SCy Schubert 	int pos;
259041edb306SCy Schubert 
259141edb306SCy Schubert 	pos = addname(frp, name);
259241edb306SCy Schubert 	if (pos == -1)
259341edb306SCy Schubert 		return;
259441edb306SCy Schubert 	(*frp)->fr_ifnames[idx] = pos;
259541edb306SCy Schubert }
259641edb306SCy Schubert 
259741edb306SCy Schubert 
2598efeb8bffSCy Schubert static int
addname(frentry_t ** frp,char * name)2599efeb8bffSCy Schubert addname(frentry_t **frp, char *name)
260041edb306SCy Schubert {
260141edb306SCy Schubert 	frentry_t *f;
260241edb306SCy Schubert 	int nlen;
260341edb306SCy Schubert 	int pos;
260441edb306SCy Schubert 
260541edb306SCy Schubert 	nlen = strlen(name) + 1;
260641edb306SCy Schubert 	f = realloc(*frp, (*frp)->fr_size + nlen);
260741edb306SCy Schubert 	if (*frp == frc)
260841edb306SCy Schubert 		frc = f;
260941edb306SCy Schubert 	*frp = f;
261041edb306SCy Schubert 	if (f == NULL)
2611*2582ae57SCy Schubert 		return(-1);
261241edb306SCy Schubert 	if (f->fr_pnext != NULL)
261341edb306SCy Schubert 		*f->fr_pnext = f;
261441edb306SCy Schubert 	f->fr_size += nlen;
261541edb306SCy Schubert 	pos = f->fr_namelen;
261641edb306SCy Schubert 	f->fr_namelen += nlen;
261741edb306SCy Schubert 	strcpy(f->fr_names + pos, name);
261841edb306SCy Schubert 	f->fr_names[f->fr_namelen] = '\0';
2619*2582ae57SCy Schubert 	return(pos);
262041edb306SCy Schubert }
262141edb306SCy Schubert 
262241edb306SCy Schubert 
2623efeb8bffSCy Schubert static frentry_t *
allocfr(void)2624efeb8bffSCy Schubert allocfr(void)
262541edb306SCy Schubert {
262641edb306SCy Schubert 	frentry_t *fr;
262741edb306SCy Schubert 
262841edb306SCy Schubert 	fr = calloc(1, sizeof(*fr));
262941edb306SCy Schubert 	if (fr != NULL) {
263041edb306SCy Schubert 		fr->fr_size = sizeof(*fr);
263141edb306SCy Schubert 		fr->fr_comment = -1;
263241edb306SCy Schubert 		fr->fr_group = -1;
263341edb306SCy Schubert 		fr->fr_grhead = -1;
263441edb306SCy Schubert 		fr->fr_icmphead = -1;
263541edb306SCy Schubert 		fr->fr_ifnames[0] = -1;
263641edb306SCy Schubert 		fr->fr_ifnames[1] = -1;
263741edb306SCy Schubert 		fr->fr_ifnames[2] = -1;
263841edb306SCy Schubert 		fr->fr_ifnames[3] = -1;
263941edb306SCy Schubert 		fr->fr_tif.fd_name = -1;
264041edb306SCy Schubert 		fr->fr_rif.fd_name = -1;
264141edb306SCy Schubert 		fr->fr_dif.fd_name = -1;
264241edb306SCy Schubert 	}
2643*2582ae57SCy Schubert 	return(fr);
264441edb306SCy Schubert }
264541edb306SCy Schubert 
264641edb306SCy Schubert 
2647efeb8bffSCy Schubert static void
setgroup(frentry_t ** frp,char * name)2648efeb8bffSCy Schubert setgroup(frentry_t **frp, char *name)
264941edb306SCy Schubert {
265041edb306SCy Schubert 	int pos;
265141edb306SCy Schubert 
265241edb306SCy Schubert 	pos = addname(frp, name);
265341edb306SCy Schubert 	if (pos == -1)
265441edb306SCy Schubert 		return;
265541edb306SCy Schubert 	(*frp)->fr_group = pos;
265641edb306SCy Schubert }
265741edb306SCy Schubert 
265841edb306SCy Schubert 
2659efeb8bffSCy Schubert static void
setgrhead(frentry_t ** frp,char * name)2660efeb8bffSCy Schubert setgrhead(frentry_t **frp, char *name)
266141edb306SCy Schubert {
266241edb306SCy Schubert 	int pos;
266341edb306SCy Schubert 
266441edb306SCy Schubert 	pos = addname(frp, name);
266541edb306SCy Schubert 	if (pos == -1)
266641edb306SCy Schubert 		return;
266741edb306SCy Schubert 	(*frp)->fr_grhead = pos;
266841edb306SCy Schubert }
266941edb306SCy Schubert 
267041edb306SCy Schubert 
2671efeb8bffSCy Schubert static void
seticmphead(frentry_t ** frp,char * name)2672efeb8bffSCy Schubert seticmphead(frentry_t **frp, char *name)
267341edb306SCy Schubert {
267441edb306SCy Schubert 	int pos;
267541edb306SCy Schubert 
267641edb306SCy Schubert 	pos = addname(frp, name);
267741edb306SCy Schubert 	if (pos == -1)
267841edb306SCy Schubert 		return;
267941edb306SCy Schubert 	(*frp)->fr_icmphead = pos;
268041edb306SCy Schubert }
268141edb306SCy Schubert 
268241edb306SCy Schubert 
268341edb306SCy Schubert static void
build_dstaddr_af(frentry_t * fp,void * ptr)2684efeb8bffSCy Schubert build_dstaddr_af(frentry_t *fp, void *ptr)
268541edb306SCy Schubert {
268641edb306SCy Schubert 	struct ipp_s *ipp = ptr;
268741edb306SCy Schubert 	frentry_t *f = fp;
268841edb306SCy Schubert 
268941edb306SCy Schubert 	if (f->fr_family != AF_UNSPEC && ipp->f == AF_UNSPEC) {
269041edb306SCy Schubert 		ipp->f = f->fr_family;
269141edb306SCy Schubert 		ipp->v = f->fr_ip.fi_v;
269241edb306SCy Schubert 	}
269341edb306SCy Schubert 	if (ipp->f == AF_INET)
269441edb306SCy Schubert 		ipp->v = 4;
269541edb306SCy Schubert 	else if (ipp->f == AF_INET6)
269641edb306SCy Schubert 		ipp->v = 6;
269741edb306SCy Schubert 
269841edb306SCy Schubert 	for (; f != NULL; f = f->fr_next) {
269941edb306SCy Schubert 		f->fr_ip.fi_dst = ipp->a;
270041edb306SCy Schubert 		f->fr_mip.fi_dst = ipp->m;
270141edb306SCy Schubert 		f->fr_family = ipp->f;
270241edb306SCy Schubert 		f->fr_ip.fi_v = ipp->v;
270341edb306SCy Schubert 		f->fr_mip.fi_v = 0xf;
270441edb306SCy Schubert 		f->fr_datype = ipp->type;
270541edb306SCy Schubert 		if (ipp->ifpos != -1)
270641edb306SCy Schubert 			f->fr_ipf->fri_difpidx = ipp->ifpos;
270741edb306SCy Schubert 	}
270841edb306SCy Schubert 	fr = NULL;
270941edb306SCy Schubert }
271041edb306SCy Schubert 
271141edb306SCy Schubert 
271241edb306SCy Schubert static void
build_srcaddr_af(frentry_t * fp,void * ptr)2713efeb8bffSCy Schubert build_srcaddr_af(frentry_t *fp, void *ptr)
271441edb306SCy Schubert {
271541edb306SCy Schubert 	struct ipp_s *ipp = ptr;
271641edb306SCy Schubert 	frentry_t *f = fp;
271741edb306SCy Schubert 
271841edb306SCy Schubert 	if (f->fr_family != AF_UNSPEC && ipp->f == AF_UNSPEC) {
271941edb306SCy Schubert 		ipp->f = f->fr_family;
272041edb306SCy Schubert 		ipp->v = f->fr_ip.fi_v;
272141edb306SCy Schubert 	}
272241edb306SCy Schubert 	if (ipp->f == AF_INET)
272341edb306SCy Schubert 		ipp->v = 4;
272441edb306SCy Schubert 	else if (ipp->f == AF_INET6)
272541edb306SCy Schubert 		ipp->v = 6;
272641edb306SCy Schubert 
272741edb306SCy Schubert 	for (; f != NULL; f = f->fr_next) {
272841edb306SCy Schubert 		f->fr_ip.fi_src = ipp->a;
272941edb306SCy Schubert 		f->fr_mip.fi_src = ipp->m;
273041edb306SCy Schubert 		f->fr_family = ipp->f;
273141edb306SCy Schubert 		f->fr_ip.fi_v = ipp->v;
273241edb306SCy Schubert 		f->fr_mip.fi_v = 0xf;
273341edb306SCy Schubert 		f->fr_satype = ipp->type;
273441edb306SCy Schubert 		f->fr_ipf->fri_sifpidx = ipp->ifpos;
273541edb306SCy Schubert 	}
273641edb306SCy Schubert 	fr = NULL;
273741edb306SCy Schubert }
2738