xref: /openbsd/sbin/pfctl/parse.y (revision 404b540a)
1 /*	$OpenBSD: parse.y,v 1.570 2009/10/04 16:08:37 michele Exp $	*/
2 
3 /*
4  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
5  * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
6  * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
7  * Copyright (c) 2002,2003 Henning Brauer. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 %{
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <sys/stat.h>
33 #include <net/if.h>
34 #include <netinet/in.h>
35 #include <netinet/in_systm.h>
36 #include <netinet/ip.h>
37 #include <netinet/ip_icmp.h>
38 #include <netinet/icmp6.h>
39 #include <net/pfvar.h>
40 #include <arpa/inet.h>
41 #include <altq/altq.h>
42 #include <altq/altq_cbq.h>
43 #include <altq/altq_priq.h>
44 #include <altq/altq_hfsc.h>
45 
46 #include <stdio.h>
47 #include <unistd.h>
48 #include <stdlib.h>
49 #include <netdb.h>
50 #include <stdarg.h>
51 #include <errno.h>
52 #include <string.h>
53 #include <ctype.h>
54 #include <math.h>
55 #include <err.h>
56 #include <limits.h>
57 #include <pwd.h>
58 #include <grp.h>
59 #include <md5.h>
60 
61 #include "pfctl_parser.h"
62 #include "pfctl.h"
63 
64 static struct pfctl	*pf = NULL;
65 static int		 debug = 0;
66 static int		 rulestate = 0;
67 static u_int16_t	 returnicmpdefault =
68 			    (ICMP_UNREACH << 8) | ICMP_UNREACH_PORT;
69 static u_int16_t	 returnicmp6default =
70 			    (ICMP6_DST_UNREACH << 8) | ICMP6_DST_UNREACH_NOPORT;
71 static int		 blockpolicy = PFRULE_DROP;
72 static int		 require_order = 0;
73 static int		 default_statelock;
74 
75 TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
76 static struct file {
77 	TAILQ_ENTRY(file)	 entry;
78 	FILE			*stream;
79 	char			*name;
80 	int			 lineno;
81 	int			 errors;
82 } *file;
83 struct file	*pushfile(const char *, int);
84 int		 popfile(void);
85 int		 check_file_secrecy(int, const char *);
86 int		 yyparse(void);
87 int		 yylex(void);
88 int		 yyerror(const char *, ...);
89 int		 kw_cmp(const void *, const void *);
90 int		 lookup(char *);
91 int		 lgetc(int);
92 int		 lungetc(int);
93 int		 findeol(void);
94 
95 TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
96 struct sym {
97 	TAILQ_ENTRY(sym)	 entry;
98 	int			 used;
99 	int			 persist;
100 	char			*nam;
101 	char			*val;
102 };
103 int		 symset(const char *, const char *, int);
104 char		*symget(const char *);
105 
106 int		 atoul(char *, u_long *);
107 
108 enum {
109 	PFCTL_STATE_NONE,
110 	PFCTL_STATE_OPTION,
111 	PFCTL_STATE_QUEUE,
112 	PFCTL_STATE_NAT,
113 	PFCTL_STATE_FILTER
114 };
115 
116 struct node_proto {
117 	u_int8_t		 proto;
118 	struct node_proto	*next;
119 	struct node_proto	*tail;
120 };
121 
122 struct node_port {
123 	u_int16_t		 port[2];
124 	u_int8_t		 op;
125 	struct node_port	*next;
126 	struct node_port	*tail;
127 };
128 
129 struct node_uid {
130 	uid_t			 uid[2];
131 	u_int8_t		 op;
132 	struct node_uid		*next;
133 	struct node_uid		*tail;
134 };
135 
136 struct node_gid {
137 	gid_t			 gid[2];
138 	u_int8_t		 op;
139 	struct node_gid		*next;
140 	struct node_gid		*tail;
141 };
142 
143 struct node_icmp {
144 	u_int8_t		 code;
145 	u_int8_t		 type;
146 	u_int8_t		 proto;
147 	struct node_icmp	*next;
148 	struct node_icmp	*tail;
149 };
150 
151 enum	{ PF_STATE_OPT_MAX, PF_STATE_OPT_NOSYNC, PF_STATE_OPT_SRCTRACK,
152 	    PF_STATE_OPT_MAX_SRC_STATES, PF_STATE_OPT_MAX_SRC_CONN,
153 	    PF_STATE_OPT_MAX_SRC_CONN_RATE, PF_STATE_OPT_MAX_SRC_NODES,
154 	    PF_STATE_OPT_OVERLOAD, PF_STATE_OPT_STATELOCK,
155 	    PF_STATE_OPT_TIMEOUT, PF_STATE_OPT_SLOPPY,
156 	    PF_STATE_OPT_PFLOW };
157 
158 enum	{ PF_SRCTRACK_NONE, PF_SRCTRACK, PF_SRCTRACK_GLOBAL, PF_SRCTRACK_RULE };
159 
160 struct node_state_opt {
161 	int			 type;
162 	union {
163 		u_int32_t	 max_states;
164 		u_int32_t	 max_src_states;
165 		u_int32_t	 max_src_conn;
166 		struct {
167 			u_int32_t	limit;
168 			u_int32_t	seconds;
169 		}		 max_src_conn_rate;
170 		struct {
171 			u_int8_t	flush;
172 			char		tblname[PF_TABLE_NAME_SIZE];
173 		}		 overload;
174 		u_int32_t	 max_src_nodes;
175 		u_int8_t	 src_track;
176 		u_int32_t	 statelock;
177 		struct {
178 			int		number;
179 			u_int32_t	seconds;
180 		}		 timeout;
181 	}			 data;
182 	struct node_state_opt	*next;
183 	struct node_state_opt	*tail;
184 };
185 
186 struct peer {
187 	struct node_host	*host;
188 	struct node_port	*port;
189 };
190 
191 struct node_queue {
192 	char			 queue[PF_QNAME_SIZE];
193 	char			 parent[PF_QNAME_SIZE];
194 	char			 ifname[IFNAMSIZ];
195 	int			 scheduler;
196 	struct node_queue	*next;
197 	struct node_queue	*tail;
198 }	*queues = NULL;
199 
200 struct node_qassign {
201 	char		*qname;
202 	char		*pqname;
203 };
204 
205 struct range {
206 	int		 a;
207 	int		 b;
208 	int		 t;
209 };
210 struct redirection {
211 	struct node_host	*host;
212 	struct range		 rport;
213 };
214 
215 struct pool_opts {
216 	int			 marker;
217 #define POM_TYPE		0x01
218 #define POM_STICKYADDRESS	0x02
219 	u_int8_t		 opts;
220 	int			 type;
221 	int			 staticport;
222 	struct pf_poolhashkey	*key;
223 
224 } pool_opts;
225 
226 struct redirspec {
227 	struct redirection      *rdr;
228 	struct pool_opts         pool_opts;
229 	int			 binat;
230 };
231 
232 struct filter_opts {
233 	int			 marker;
234 #define FOM_FLAGS	0x0001
235 #define FOM_ICMP	0x0002
236 #define FOM_TOS		0x0004
237 #define FOM_KEEP	0x0008
238 #define FOM_SRCTRACK	0x0010
239 #define FOM_MINTTL	0x0020
240 #define FOM_MAXMSS	0x0040
241 #define FOM_SETTOS	0x0100
242 #define FOM_SCRUB_TCP	0x0200
243 	struct node_uid		*uid;
244 	struct node_gid		*gid;
245 	struct {
246 		u_int8_t	 b1;
247 		u_int8_t	 b2;
248 		u_int16_t	 w;
249 		u_int16_t	 w2;
250 	} flags;
251 	struct node_icmp	*icmpspec;
252 	u_int32_t		 tos;
253 	u_int32_t		 prob;
254 	struct {
255 		int			 action;
256 		struct node_state_opt	*options;
257 	} keep;
258 	int			 fragment;
259 	int			 allowopts;
260 	char			*label;
261 	struct node_qassign	 queues;
262 	char			*tag;
263 	char			*match_tag;
264 	u_int8_t		 match_tag_not;
265 	u_int			 rtableid;
266 	struct {
267 		struct node_host	*addr;
268 		u_int16_t		port;
269 	}			 divert, divert_packet;
270 	struct redirspec	 nat;
271 	struct redirspec	 rdr;
272 
273 	/* scrub opts */
274 	int			 nodf;
275 	int			 minttl;
276 	int			 settos;
277 	int			 randomid;
278 	int			 max_mss;
279 
280 	/* route opts */
281 	struct {
282 		struct node_host	*host;
283 		u_int8_t		 rt;
284 		u_int8_t		 pool_opts;
285 		sa_family_t		 af;
286 		struct pf_poolhashkey	*key;
287 	}			 route;
288 } filter_opts;
289 
290 struct antispoof_opts {
291 	char			*label;
292 	u_int			 rtableid;
293 } antispoof_opts;
294 
295 struct scrub_opts {
296 	int			marker;
297 	int			nodf;
298 	int			minttl;
299 	int			maxmss;
300 	int			settos;
301 	int			randomid;
302 	int			reassemble_tcp;
303 } scrub_opts;
304 
305 struct queue_opts {
306 	int			marker;
307 #define QOM_BWSPEC	0x01
308 #define QOM_SCHEDULER	0x02
309 #define QOM_PRIORITY	0x04
310 #define QOM_TBRSIZE	0x08
311 #define QOM_QLIMIT	0x10
312 	struct node_queue_bw	queue_bwspec;
313 	struct node_queue_opt	scheduler;
314 	int			priority;
315 	int			tbrsize;
316 	int			qlimit;
317 } queue_opts;
318 
319 struct table_opts {
320 	int			flags;
321 	int			init_addr;
322 	struct node_tinithead	init_nodes;
323 } table_opts;
324 
325 struct node_hfsc_opts	 hfsc_opts;
326 struct node_state_opt	*keep_state_defaults = NULL;
327 
328 int		 disallow_table(struct node_host *, const char *);
329 int		 disallow_urpf_failed(struct node_host *, const char *);
330 int		 disallow_alias(struct node_host *, const char *);
331 int		 rule_consistent(struct pf_rule *, int);
332 int		 process_tabledef(char *, struct table_opts *);
333 void		 expand_label_str(char *, size_t, const char *, const char *);
334 void		 expand_label_if(const char *, char *, size_t, const char *);
335 void		 expand_label_addr(const char *, char *, size_t, u_int8_t,
336 		    struct node_host *);
337 void		 expand_label_port(const char *, char *, size_t,
338 		    struct node_port *);
339 void		 expand_label_proto(const char *, char *, size_t, u_int8_t);
340 void		 expand_label_nr(const char *, char *, size_t);
341 void		 expand_label(char *, size_t, const char *, u_int8_t,
342 		    struct node_host *, struct node_port *, struct node_host *,
343 		    struct node_port *, u_int8_t);
344 int		 apply_redirspec(struct pf_pool *, struct pf_rule *,
345 		    struct redirspec *, int, struct node_port *);
346 void		 expand_rule(struct pf_rule *, int, struct node_if *,
347 		    struct redirspec *, struct redirspec *, struct node_proto *,
348 		    struct node_os *, struct node_host *, struct node_port *,
349 		    struct node_host *, struct node_port *, struct node_uid *,
350 		    struct node_gid *, struct node_icmp *, const char *);
351 int		 expand_altq(struct pf_altq *, struct node_if *,
352 		    struct node_queue *, struct node_queue_bw bwspec,
353 		    struct node_queue_opt *);
354 int		 expand_queue(struct pf_altq *, struct node_if *,
355 		    struct node_queue *, struct node_queue_bw,
356 		    struct node_queue_opt *);
357 int		 expand_skip_interface(struct node_if *);
358 
359 int	 check_rulestate(int);
360 int	 getservice(char *);
361 int	 rule_label(struct pf_rule *, char *);
362 
363 void	 mv_rules(struct pf_ruleset *, struct pf_ruleset *);
364 void	 decide_address_family(struct node_host *, sa_family_t *);
365 void	 remove_invalid_hosts(struct node_host **, sa_family_t *);
366 int	 invalid_redirect(struct node_host *, sa_family_t);
367 u_int16_t parseicmpspec(char *, sa_family_t);
368 int	 kw_casecmp(const void *, const void *);
369 int	 map_tos(char *string, int *);
370 
371 TAILQ_HEAD(loadanchorshead, loadanchors)
372     loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead);
373 
374 struct loadanchors {
375 	TAILQ_ENTRY(loadanchors)	 entries;
376 	char				*anchorname;
377 	char				*filename;
378 };
379 
380 typedef struct {
381 	union {
382 		int64_t			 number;
383 		double			 probability;
384 		int			 i;
385 		char			*string;
386 		u_int			 rtableid;
387 		struct {
388 			u_int8_t	 b1;
389 			u_int8_t	 b2;
390 			u_int16_t	 w;
391 			u_int16_t	 w2;
392 		}			 b;
393 		struct range		 range;
394 		struct node_if		*interface;
395 		struct node_proto	*proto;
396 		struct node_icmp	*icmp;
397 		struct node_host	*host;
398 		struct node_os		*os;
399 		struct node_port	*port;
400 		struct node_uid		*uid;
401 		struct node_gid		*gid;
402 		struct node_state_opt	*state_opt;
403 		struct peer		 peer;
404 		struct {
405 			struct peer	 src, dst;
406 			struct node_os	*src_os;
407 		}			 fromto;
408 		struct redirection	*redirection;
409 		struct {
410 			int			 action;
411 			struct node_state_opt	*options;
412 		}			 keep_state;
413 		struct {
414 			u_int8_t	 log;
415 			u_int8_t	 logif;
416 			u_int8_t	 quick;
417 		}			 logquick;
418 		struct {
419 			int		 neg;
420 			char		*name;
421 		}			 tagged;
422 		struct pf_poolhashkey	*hashkey;
423 		struct node_queue	*queue;
424 		struct node_queue_opt	 queue_options;
425 		struct node_queue_bw	 queue_bwspec;
426 		struct node_qassign	 qassign;
427 		struct filter_opts	 filter_opts;
428 		struct antispoof_opts	 antispoof_opts;
429 		struct queue_opts	 queue_opts;
430 		struct scrub_opts	 scrub_opts;
431 		struct table_opts	 table_opts;
432 		struct pool_opts	 pool_opts;
433 		struct node_hfsc_opts	 hfsc_opts;
434 	} v;
435 	int lineno;
436 } YYSTYPE;
437 
438 #define PPORT_RANGE	1
439 #define PPORT_STAR	2
440 int	parseport(char *, struct range *r, int);
441 
442 #define DYNIF_MULTIADDR(addr) ((addr).type == PF_ADDR_DYNIFTL && \
443 	(!((addr).iflags & PFI_AFLAG_NOALIAS) ||		 \
444 	!isdigit((addr).v.ifname[strlen((addr).v.ifname)-1])))
445 
446 %}
447 
448 %token	PASS BLOCK MATCH SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS
449 %token	RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE
450 %token	ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINATTO NODF
451 %token	MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL
452 %token	NOROUTE URPFFAILED FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS DROP TABLE
453 %token	REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR
454 %token	SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY RANDOMID
455 %token	REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID
456 %token	ANTISPOOF FOR INCLUDE
457 %token	BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY
458 %token	ALTQ CBQ PRIQ HFSC BANDWIDTH TBRSIZE LINKSHARE REALTIME UPPERLIMIT
459 %token	QUEUE PRIORITY QLIMIT RTABLE
460 %token	LOAD RULESET_OPTIMIZATION
461 %token	STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
462 %token	MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW
463 %token	TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS
464 %token	DIVERTTO DIVERTREPLY DIVERTPACKET NATTO RDRTO
465 %token	<v.string>		STRING
466 %token	<v.number>		NUMBER
467 %token	<v.i>			PORTBINARY
468 %type	<v.interface>		interface if_list if_item_not if_item
469 %type	<v.number>		number icmptype icmp6type uid gid
470 %type	<v.number>		tos not yesno optnodf
471 %type	<v.probability>		probability
472 %type	<v.i>			dir af optimizer
473 %type	<v.i>			sourcetrack flush unaryop statelock
474 %type	<v.b>			action
475 %type	<v.b>			flags flag blockspec
476 %type	<v.range>		portplain portstar portrange
477 %type	<v.hashkey>		hashkey
478 %type	<v.proto>		proto proto_list proto_item
479 %type	<v.number>		protoval
480 %type	<v.icmp>		icmpspec
481 %type	<v.icmp>		icmp_list icmp_item
482 %type	<v.icmp>		icmp6_list icmp6_item
483 %type	<v.number>		reticmpspec reticmp6spec
484 %type	<v.fromto>		fromto
485 %type	<v.peer>		ipportspec from to
486 %type	<v.host>		ipspec xhost host dynaddr host_list
487 %type	<v.host>		redir_host_list redirspec
488 %type	<v.host>		route_host route_host_list routespec
489 %type	<v.os>			os xos os_list
490 %type	<v.port>		portspec port_list port_item
491 %type	<v.uid>			uids uid_list uid_item
492 %type	<v.gid>			gids gid_list gid_item
493 %type	<v.redirection>		redirpool
494 %type	<v.string>		label stringall anchorname
495 %type	<v.string>		string varstring numberstring
496 %type	<v.keep_state>		keep
497 %type	<v.state_opt>		state_opt_spec state_opt_list state_opt_item
498 %type	<v.logquick>		logquick quick log logopts logopt
499 %type	<v.interface>		antispoof_ifspc antispoof_iflst antispoof_if
500 %type	<v.qassign>		qname
501 %type	<v.queue>		qassign qassign_list qassign_item
502 %type	<v.queue_options>	scheduler
503 %type	<v.number>		cbqflags_list cbqflags_item
504 %type	<v.number>		priqflags_list priqflags_item
505 %type	<v.hfsc_opts>		hfscopts_list hfscopts_item hfsc_opts
506 %type	<v.queue_bwspec>	bandwidth
507 %type	<v.filter_opts>		filter_opts filter_opt filter_opts_l
508 %type	<v.antispoof_opts>	antispoof_opts antispoof_opt antispoof_opts_l
509 %type	<v.queue_opts>		queue_opts queue_opt queue_opts_l
510 %type	<v.scrub_opts>		scrub_opts scrub_opt scrub_opts_l
511 %type	<v.table_opts>		table_opts table_opt table_opts_l
512 %type	<v.pool_opts>		pool_opts pool_opt pool_opts_l
513 %%
514 
515 ruleset		: /* empty */
516 		| ruleset include '\n'
517 		| ruleset '\n'
518 		| ruleset option '\n'
519 		| ruleset pfrule '\n'
520 		| ruleset anchorrule '\n'
521 		| ruleset loadrule '\n'
522 		| ruleset altqif '\n'
523 		| ruleset queuespec '\n'
524 		| ruleset varset '\n'
525 		| ruleset antispoof '\n'
526 		| ruleset tabledef '\n'
527 		| '{' fakeanchor '}' '\n';
528 		| ruleset error '\n'		{ file->errors++; }
529 		;
530 
531 include		: INCLUDE STRING		{
532 			struct file	*nfile;
533 
534 			if ((nfile = pushfile($2, 0)) == NULL) {
535 				yyerror("failed to include file %s", $2);
536 				free($2);
537 				YYERROR;
538 			}
539 			free($2);
540 
541 			file = nfile;
542 			lungetc('\n');
543 		}
544 		;
545 
546 /*
547  * apply to previouslys specified rule: must be careful to note
548  * what that is: pf or nat or binat or rdr
549  */
550 fakeanchor	: fakeanchor '\n'
551 		| fakeanchor anchorrule '\n'
552 		| fakeanchor pfrule '\n'
553 		| fakeanchor error '\n'
554 		;
555 
556 optimizer	: string	{
557 			if (!strcmp($1, "none"))
558 				$$ = 0;
559 			else if (!strcmp($1, "basic"))
560 				$$ = PF_OPTIMIZE_BASIC;
561 			else if (!strcmp($1, "profile"))
562 				$$ = PF_OPTIMIZE_BASIC | PF_OPTIMIZE_PROFILE;
563 			else {
564 				yyerror("unknown ruleset-optimization %s", $1);
565 				YYERROR;
566 			}
567 		}
568 		;
569 
570 optnodf		: /* empty */	{ $$ = 0; }
571 		| NODF		{ $$ = 1; }
572 		;
573 
574 option		: SET REASSEMBLE yesno optnodf		{
575 			if (check_rulestate(PFCTL_STATE_OPTION))
576 				YYERROR;
577 			pfctl_set_reassembly(pf, $3, $4);
578 		}
579 		| SET OPTIMIZATION STRING		{
580 			if (check_rulestate(PFCTL_STATE_OPTION)) {
581 				free($3);
582 				YYERROR;
583 			}
584 			if (pfctl_set_optimization(pf, $3) != 0) {
585 				yyerror("unknown optimization %s", $3);
586 				free($3);
587 				YYERROR;
588 			}
589 			free($3);
590 		}
591 		| SET RULESET_OPTIMIZATION optimizer {
592 			if (!(pf->opts & PF_OPT_OPTIMIZE)) {
593 				pf->opts |= PF_OPT_OPTIMIZE;
594 				pf->optimize = $3;
595 			}
596 		}
597 		| SET TIMEOUT timeout_spec
598 		| SET TIMEOUT '{' optnl timeout_list '}'
599 		| SET LIMIT limit_spec
600 		| SET LIMIT '{' optnl limit_list '}'
601 		| SET LOGINTERFACE stringall		{
602 			if (check_rulestate(PFCTL_STATE_OPTION)) {
603 				free($3);
604 				YYERROR;
605 			}
606 			if (pfctl_set_logif(pf, $3) != 0) {
607 				yyerror("error setting loginterface %s", $3);
608 				free($3);
609 				YYERROR;
610 			}
611 			free($3);
612 		}
613 		| SET HOSTID number {
614 			if ($3 == 0 || $3 > UINT_MAX) {
615 				yyerror("hostid must be non-zero");
616 				YYERROR;
617 			}
618 			if (pfctl_set_hostid(pf, $3) != 0) {
619 				yyerror("error setting hostid %08x", $3);
620 				YYERROR;
621 			}
622 		}
623 		| SET BLOCKPOLICY DROP	{
624 			if (pf->opts & PF_OPT_VERBOSE)
625 				printf("set block-policy drop\n");
626 			if (check_rulestate(PFCTL_STATE_OPTION))
627 				YYERROR;
628 			blockpolicy = PFRULE_DROP;
629 		}
630 		| SET BLOCKPOLICY RETURN {
631 			if (pf->opts & PF_OPT_VERBOSE)
632 				printf("set block-policy return\n");
633 			if (check_rulestate(PFCTL_STATE_OPTION))
634 				YYERROR;
635 			blockpolicy = PFRULE_RETURN;
636 		}
637 		| SET REQUIREORDER yesno {
638 			if (pf->opts & PF_OPT_VERBOSE)
639 				printf("set require-order %s\n",
640 				    $3 == 1 ? "yes" : "no");
641 			require_order = $3;
642 		}
643 		| SET FINGERPRINTS STRING {
644 			if (pf->opts & PF_OPT_VERBOSE)
645 				printf("set fingerprints \"%s\"\n", $3);
646 			if (check_rulestate(PFCTL_STATE_OPTION)) {
647 				free($3);
648 				YYERROR;
649 			}
650 			if (!pf->anchor->name[0]) {
651 				if (pfctl_file_fingerprints(pf->dev,
652 				    pf->opts, $3)) {
653 					yyerror("error loading "
654 					    "fingerprints %s", $3);
655 					free($3);
656 					YYERROR;
657 				}
658 			}
659 			free($3);
660 		}
661 		| SET STATEPOLICY statelock {
662 			if (pf->opts & PF_OPT_VERBOSE)
663 				switch ($3) {
664 				case 0:
665 					printf("set state-policy floating\n");
666 					break;
667 				case PFRULE_IFBOUND:
668 					printf("set state-policy if-bound\n");
669 					break;
670 				}
671 			default_statelock = $3;
672 		}
673 		| SET DEBUG STRING {
674 			if (check_rulestate(PFCTL_STATE_OPTION)) {
675 				free($3);
676 				YYERROR;
677 			}
678 			if (pfctl_set_debug(pf, $3) != 0) {
679 				yyerror("error setting debuglevel %s", $3);
680 				free($3);
681 				YYERROR;
682 			}
683 			free($3);
684 		}
685 		| SET SKIP interface {
686 			if (expand_skip_interface($3) != 0) {
687 				yyerror("error setting skip interface(s)");
688 				YYERROR;
689 			}
690 		}
691 		| SET STATEDEFAULTS state_opt_list {
692 			if (keep_state_defaults != NULL) {
693 				yyerror("cannot redefine state-defaults");
694 				YYERROR;
695 			}
696 			keep_state_defaults = $3;
697 		}
698 		;
699 
700 stringall	: STRING	{ $$ = $1; }
701 		| ALL		{
702 			if (($$ = strdup("all")) == NULL) {
703 				err(1, "stringall: strdup");
704 			}
705 		}
706 		;
707 
708 string		: STRING string				{
709 			if (asprintf(&$$, "%s %s", $1, $2) == -1)
710 				err(1, "string: asprintf");
711 			free($1);
712 			free($2);
713 		}
714 		| STRING
715 		;
716 
717 varstring	: numberstring varstring 		{
718 			if (asprintf(&$$, "%s %s", $1, $2) == -1)
719 				err(1, "string: asprintf");
720 			free($1);
721 			free($2);
722 		}
723 		| numberstring
724 		;
725 
726 numberstring	: NUMBER				{
727 			char	*s;
728 			if (asprintf(&s, "%lld", $1) == -1) {
729 				yyerror("string: asprintf");
730 				YYERROR;
731 			}
732 			$$ = s;
733 		}
734 		| STRING
735 		;
736 
737 varset		: STRING '=' varstring	{
738 			if (pf->opts & PF_OPT_VERBOSE)
739 				printf("%s = \"%s\"\n", $1, $3);
740 			if (symset($1, $3, 0) == -1)
741 				err(1, "cannot store variable %s", $1);
742 			free($1);
743 			free($3);
744 		}
745 		;
746 
747 anchorname	: STRING			{ $$ = $1; }
748 		| /* empty */			{ $$ = NULL; }
749 		;
750 
751 pfa_anchorlist	: /* empty */
752 		| pfa_anchorlist '\n'
753 		| pfa_anchorlist pfrule '\n'
754 		| pfa_anchorlist anchorrule '\n'
755 		;
756 
757 pfa_anchor	: '{'
758 		{
759 			char ta[PF_ANCHOR_NAME_SIZE];
760 			struct pf_ruleset *rs;
761 
762 			/* steping into a brace anchor */
763 			pf->asd++;
764 			pf->bn++;
765 			pf->brace = 1;
766 
767 			/* create a holding ruleset in the root */
768 			snprintf(ta, PF_ANCHOR_NAME_SIZE, "_%d", pf->bn);
769 			rs = pf_find_or_create_ruleset(ta);
770 			if (rs == NULL)
771 				err(1, "pfa_anchor: pf_find_or_create_ruleset");
772 			pf->astack[pf->asd] = rs->anchor;
773 			pf->anchor = rs->anchor;
774 		} '\n' pfa_anchorlist '}'
775 		{
776 			pf->alast = pf->anchor;
777 			pf->asd--;
778 			pf->anchor = pf->astack[pf->asd];
779 		}
780 		| /* empty */
781 		;
782 
783 anchorrule	: ANCHOR anchorname dir quick interface af proto fromto
784 		    filter_opts pfa_anchor
785 		{
786 			struct pf_rule	r;
787 			struct node_proto	*proto;
788 
789 			if (check_rulestate(PFCTL_STATE_FILTER)) {
790 				if ($2)
791 					free($2);
792 				YYERROR;
793 			}
794 
795 			if ($2 && ($2[0] == '_' || strstr($2, "/_") != NULL)) {
796 				free($2);
797 				yyerror("anchor names beginning with '_' "
798 				    "are reserved for internal use");
799 				YYERROR;
800 			}
801 
802 			memset(&r, 0, sizeof(r));
803 			if (pf->astack[pf->asd + 1]) {
804 				/* move inline rules into relative location */
805 				pf_anchor_setup(&r,
806 				    &pf->astack[pf->asd]->ruleset,
807 				    $2 ? $2 : pf->alast->name);
808 
809 				if (r.anchor == NULL)
810 					err(1, "anchorrule: unable to "
811 					    "create ruleset");
812 
813 				if (pf->alast != r.anchor) {
814 					if (r.anchor->match) {
815 						yyerror("inline anchor '%s' "
816 						    "already exists",
817 						    r.anchor->name);
818 						YYERROR;
819 					}
820 					mv_rules(&pf->alast->ruleset,
821 					    &r.anchor->ruleset);
822 				}
823 				pf_remove_if_empty_ruleset(&pf->alast->ruleset);
824 				pf->alast = r.anchor;
825 			} else {
826 				if (!$2) {
827 					yyerror("anchors without explicit "
828 					    "rules must specify a name");
829 					YYERROR;
830 				}
831 			}
832 			r.direction = $3;
833 			r.quick = $4.quick;
834 			r.af = $6;
835 			r.prob = $9.prob;
836 			r.rtableid = $9.rtableid;
837 
838 			if ($9.tag)
839 				if (strlcpy(r.tagname, $9.tag,
840 				    PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
841 					yyerror("tag too long, max %u chars",
842 					    PF_TAG_NAME_SIZE - 1);
843 					YYERROR;
844 				}
845 			if ($9.match_tag)
846 				if (strlcpy(r.match_tagname, $9.match_tag,
847 				    PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
848 					yyerror("tag too long, max %u chars",
849 					    PF_TAG_NAME_SIZE - 1);
850 					YYERROR;
851 				}
852 			r.match_tag_not = $9.match_tag_not;
853 			if (rule_label(&r, $9.label))
854 				YYERROR;
855 			free($9.label);
856 			r.flags = $9.flags.b1;
857 			r.flagset = $9.flags.b2;
858 			if (($9.flags.b1 & $9.flags.b2) != $9.flags.b1) {
859 				yyerror("flags always false");
860 				YYERROR;
861 			}
862 			if ($9.flags.b1 || $9.flags.b2 || $8.src_os) {
863 				for (proto = $7; proto != NULL &&
864 				    proto->proto != IPPROTO_TCP;
865 				    proto = proto->next)
866 					;	/* nothing */
867 				if (proto == NULL && $7 != NULL) {
868 					if ($9.flags.b1 || $9.flags.b2)
869 						yyerror(
870 						    "flags only apply to tcp");
871 					if ($8.src_os)
872 						yyerror(
873 						    "OS fingerprinting only "
874 						    "applies to tcp");
875 					YYERROR;
876 				}
877 			}
878 
879 			r.tos = $9.tos;
880 
881 			if ($9.keep.action) {
882 				yyerror("cannot specify state handling "
883 				    "on anchors");
884 				YYERROR;
885 			}
886 
887 			if ($9.route.rt) {
888 				yyerror("cannot specify route handling "
889 				    "on anchors");
890 				YYERROR;
891 			}
892 
893 			if ($9.match_tag)
894 				if (strlcpy(r.match_tagname, $9.match_tag,
895 				    PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
896 					yyerror("tag too long, max %u chars",
897 					    PF_TAG_NAME_SIZE - 1);
898 					YYERROR;
899 				}
900 			r.match_tag_not = $9.match_tag_not;
901 
902 			decide_address_family($8.src.host, &r.af);
903 			decide_address_family($8.dst.host, &r.af);
904 
905 			expand_rule(&r, 0, $5, NULL, NULL, $7, $8.src_os,
906 			    $8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
907 			    $9.uid, $9.gid, $9.icmpspec,
908 			    pf->astack[pf->asd + 1] ? pf->alast->name : $2);
909 			free($2);
910 			pf->astack[pf->asd + 1] = NULL;
911 		}
912 		;
913 
914 loadrule	: LOAD ANCHOR string FROM string	{
915 			struct loadanchors	*loadanchor;
916 
917 			if (strlen(pf->anchor->name) + 1 +
918 			    strlen($3) >= MAXPATHLEN) {
919 				yyerror("anchorname %s too long, max %u\n",
920 				    $3, MAXPATHLEN - 1);
921 				free($3);
922 				YYERROR;
923 			}
924 			loadanchor = calloc(1, sizeof(struct loadanchors));
925 			if (loadanchor == NULL)
926 				err(1, "loadrule: calloc");
927 			if ((loadanchor->anchorname = malloc(MAXPATHLEN)) ==
928 			    NULL)
929 				err(1, "loadrule: malloc");
930 			if (pf->anchor->name[0])
931 				snprintf(loadanchor->anchorname, MAXPATHLEN,
932 				    "%s/%s", pf->anchor->name, $3);
933 			else
934 				strlcpy(loadanchor->anchorname, $3, MAXPATHLEN);
935 			if ((loadanchor->filename = strdup($5)) == NULL)
936 				err(1, "loadrule: strdup");
937 
938 			TAILQ_INSERT_TAIL(&loadanchorshead, loadanchor,
939 			    entries);
940 
941 			free($3);
942 			free($5);
943 		};
944 
945 scrub_opts	:	{
946 				bzero(&scrub_opts, sizeof scrub_opts);
947 			}
948 		    scrub_opts_l
949 			{ $$ = scrub_opts; }
950 		;
951 
952 scrub_opts_l	: scrub_opts_l comma scrub_opt
953 		| scrub_opt
954 		;
955 
956 scrub_opt	: NODF	{
957 			if (scrub_opts.nodf) {
958 				yyerror("no-df cannot be respecified");
959 				YYERROR;
960 			}
961 			scrub_opts.nodf = 1;
962 		}
963 		| MINTTL NUMBER {
964 			if (scrub_opts.marker & FOM_MINTTL) {
965 				yyerror("min-ttl cannot be respecified");
966 				YYERROR;
967 			}
968 			if ($2 < 0 || $2 > 255) {
969 				yyerror("illegal min-ttl value %d", $2);
970 				YYERROR;
971 			}
972 			scrub_opts.marker |= FOM_MINTTL;
973 			scrub_opts.minttl = $2;
974 		}
975 		| MAXMSS NUMBER {
976 			if (scrub_opts.marker & FOM_MAXMSS) {
977 				yyerror("max-mss cannot be respecified");
978 				YYERROR;
979 			}
980 			if ($2 < 0 || $2 > 65535) {
981 				yyerror("illegal max-mss value %d", $2);
982 				YYERROR;
983 			}
984 			scrub_opts.marker |= FOM_MAXMSS;
985 			scrub_opts.maxmss = $2;
986 		}
987 		| SETTOS tos {
988 			if (scrub_opts.marker & FOM_SETTOS) {
989 				yyerror("set-tos cannot be respecified");
990 				YYERROR;
991 			}
992 			scrub_opts.marker |= FOM_SETTOS;
993 			scrub_opts.settos = $2;
994 		}
995 		| REASSEMBLE STRING {
996 			if (strcasecmp($2, "tcp") != 0) {
997 				yyerror("scrub reassemble supports only tcp, "
998 				    "not '%s'", $2);
999 				free($2);
1000 				YYERROR;
1001 			}
1002 			free($2);
1003 			if (scrub_opts.reassemble_tcp) {
1004 				yyerror("reassemble tcp cannot be respecified");
1005 				YYERROR;
1006 			}
1007 			scrub_opts.reassemble_tcp = 1;
1008 		}
1009 		| RANDOMID {
1010 			if (scrub_opts.randomid) {
1011 				yyerror("random-id cannot be respecified");
1012 				YYERROR;
1013 			}
1014 			scrub_opts.randomid = 1;
1015 		}
1016 		;
1017 
1018 antispoof	: ANTISPOOF logquick antispoof_ifspc af antispoof_opts {
1019 			struct pf_rule		 r;
1020 			struct node_host	*h = NULL, *hh;
1021 			struct node_if		*i, *j;
1022 
1023 			if (check_rulestate(PFCTL_STATE_FILTER))
1024 				YYERROR;
1025 
1026 			for (i = $3; i; i = i->next) {
1027 				bzero(&r, sizeof(r));
1028 
1029 				r.action = PF_DROP;
1030 				r.direction = PF_IN;
1031 				r.log = $2.log;
1032 				r.logif = $2.logif;
1033 				r.quick = $2.quick;
1034 				r.af = $4;
1035 				if (rule_label(&r, $5.label))
1036 					YYERROR;
1037 				r.rtableid = $5.rtableid;
1038 				j = calloc(1, sizeof(struct node_if));
1039 				if (j == NULL)
1040 					err(1, "antispoof: calloc");
1041 				if (strlcpy(j->ifname, i->ifname,
1042 				    sizeof(j->ifname)) >= sizeof(j->ifname)) {
1043 					free(j);
1044 					yyerror("interface name too long");
1045 					YYERROR;
1046 				}
1047 				j->not = 1;
1048 				if (i->dynamic) {
1049 					h = calloc(1, sizeof(*h));
1050 					if (h == NULL)
1051 						err(1, "address: calloc");
1052 					h->addr.type = PF_ADDR_DYNIFTL;
1053 					set_ipmask(h, 128);
1054 					if (strlcpy(h->addr.v.ifname, i->ifname,
1055 					    sizeof(h->addr.v.ifname)) >=
1056 					    sizeof(h->addr.v.ifname)) {
1057 						free(h);
1058 						yyerror(
1059 						    "interface name too long");
1060 						YYERROR;
1061 					}
1062 					hh = malloc(sizeof(*hh));
1063 					if (hh == NULL)
1064 						 err(1, "address: malloc");
1065 					bcopy(h, hh, sizeof(*hh));
1066 					h->addr.iflags = PFI_AFLAG_NETWORK;
1067 				} else {
1068 					h = ifa_lookup(j->ifname,
1069 					    PFI_AFLAG_NETWORK);
1070 					hh = NULL;
1071 				}
1072 
1073 				if (h != NULL)
1074 					expand_rule(&r, 0, j, NULL, NULL, NULL,
1075 					    NULL, h, NULL, NULL, NULL, NULL,
1076 					    NULL, NULL, "");
1077 
1078 				if ((i->ifa_flags & IFF_LOOPBACK) == 0) {
1079 					bzero(&r, sizeof(r));
1080 
1081 					r.action = PF_DROP;
1082 					r.direction = PF_IN;
1083 					r.log = $2.log;
1084 					r.logif = $2.logif;
1085 					r.quick = $2.quick;
1086 					r.af = $4;
1087 					if (rule_label(&r, $5.label))
1088 						YYERROR;
1089 					r.rtableid = $5.rtableid;
1090 					if (hh != NULL)
1091 						h = hh;
1092 					else
1093 						h = ifa_lookup(i->ifname, 0);
1094 					if (h != NULL)
1095 						expand_rule(&r, 0, NULL, NULL,
1096 						    NULL, NULL, NULL, h, NULL,
1097 						    NULL, NULL, NULL, NULL,
1098 						    NULL, "");
1099 				} else
1100 					free(hh);
1101 			}
1102 			free($5.label);
1103 		}
1104 		;
1105 
1106 antispoof_ifspc	: FOR antispoof_if			{ $$ = $2; }
1107 		| FOR '{' optnl antispoof_iflst '}'	{ $$ = $4; }
1108 		;
1109 
1110 antispoof_iflst	: antispoof_if optnl			{ $$ = $1; }
1111 		| antispoof_iflst comma antispoof_if optnl {
1112 			$1->tail->next = $3;
1113 			$1->tail = $3;
1114 			$$ = $1;
1115 		}
1116 		;
1117 
1118 antispoof_if	: if_item				{ $$ = $1; }
1119 		| '(' if_item ')'			{
1120 			$2->dynamic = 1;
1121 			$$ = $2;
1122 		}
1123 		;
1124 
1125 antispoof_opts	:	{
1126 				bzero(&antispoof_opts, sizeof antispoof_opts);
1127 				antispoof_opts.rtableid = -1;
1128 			}
1129 		    antispoof_opts_l
1130 			{ $$ = antispoof_opts; }
1131 		| /* empty */	{
1132 			bzero(&antispoof_opts, sizeof antispoof_opts);
1133 			antispoof_opts.rtableid = -1;
1134 			$$ = antispoof_opts;
1135 		}
1136 		;
1137 
1138 antispoof_opts_l	: antispoof_opts_l antispoof_opt
1139 			| antispoof_opt
1140 			;
1141 
1142 antispoof_opt	: label	{
1143 			if (antispoof_opts.label) {
1144 				yyerror("label cannot be redefined");
1145 				YYERROR;
1146 			}
1147 			antispoof_opts.label = $1;
1148 		}
1149 		| RTABLE NUMBER				{
1150 			if ($2 < 0 || $2 > RT_TABLEID_MAX) {
1151 				yyerror("invalid rtable id");
1152 				YYERROR;
1153 			}
1154 			antispoof_opts.rtableid = $2;
1155 		}
1156 		;
1157 
1158 not		: '!'		{ $$ = 1; }
1159 		| /* empty */	{ $$ = 0; }
1160 		;
1161 
1162 tabledef	: TABLE '<' STRING '>' table_opts {
1163 			struct node_host	 *h, *nh;
1164 			struct node_tinit	 *ti, *nti;
1165 
1166 			if (strlen($3) >= PF_TABLE_NAME_SIZE) {
1167 				yyerror("table name too long, max %d chars",
1168 				    PF_TABLE_NAME_SIZE - 1);
1169 				free($3);
1170 				YYERROR;
1171 			}
1172 			if (pf->loadopt & PFCTL_FLAG_TABLE)
1173 				if (process_tabledef($3, &$5)) {
1174 					free($3);
1175 					YYERROR;
1176 				}
1177 			free($3);
1178 			for (ti = SIMPLEQ_FIRST(&$5.init_nodes);
1179 			    ti != SIMPLEQ_END(&$5.init_nodes); ti = nti) {
1180 				if (ti->file)
1181 					free(ti->file);
1182 				for (h = ti->host; h != NULL; h = nh) {
1183 					nh = h->next;
1184 					free(h);
1185 				}
1186 				nti = SIMPLEQ_NEXT(ti, entries);
1187 				free(ti);
1188 			}
1189 		}
1190 		;
1191 
1192 table_opts	:	{
1193 			bzero(&table_opts, sizeof table_opts);
1194 			SIMPLEQ_INIT(&table_opts.init_nodes);
1195 		}
1196 		    table_opts_l
1197 			{ $$ = table_opts; }
1198 		| /* empty */
1199 			{
1200 			bzero(&table_opts, sizeof table_opts);
1201 			SIMPLEQ_INIT(&table_opts.init_nodes);
1202 			$$ = table_opts;
1203 		}
1204 		;
1205 
1206 table_opts_l	: table_opts_l table_opt
1207 		| table_opt
1208 		;
1209 
1210 table_opt	: STRING		{
1211 			if (!strcmp($1, "const"))
1212 				table_opts.flags |= PFR_TFLAG_CONST;
1213 			else if (!strcmp($1, "persist"))
1214 				table_opts.flags |= PFR_TFLAG_PERSIST;
1215 			else if (!strcmp($1, "counters"))
1216 				table_opts.flags |= PFR_TFLAG_COUNTERS;
1217 			else {
1218 				yyerror("invalid table option '%s'", $1);
1219 				free($1);
1220 				YYERROR;
1221 			}
1222 			free($1);
1223 		}
1224 		| '{' optnl '}'		{ table_opts.init_addr = 1; }
1225 		| '{' optnl host_list '}'	{
1226 			struct node_host	*n;
1227 			struct node_tinit	*ti;
1228 
1229 			for (n = $3; n != NULL; n = n->next) {
1230 				switch (n->addr.type) {
1231 				case PF_ADDR_ADDRMASK:
1232 					continue; /* ok */
1233 				case PF_ADDR_RANGE:
1234 					yyerror("address ranges are not "
1235 					    "permitted inside tables");
1236 					break;
1237 				case PF_ADDR_DYNIFTL:
1238 					yyerror("dynamic addresses are not "
1239 					    "permitted inside tables");
1240 					break;
1241 				case PF_ADDR_TABLE:
1242 					yyerror("tables cannot contain tables");
1243 					break;
1244 				case PF_ADDR_NOROUTE:
1245 					yyerror("\"no-route\" is not permitted "
1246 					    "inside tables");
1247 					break;
1248 				case PF_ADDR_URPFFAILED:
1249 					yyerror("\"urpf-failed\" is not "
1250 					    "permitted inside tables");
1251 					break;
1252 				default:
1253 					yyerror("unknown address type %d",
1254 					    n->addr.type);
1255 				}
1256 				YYERROR;
1257 			}
1258 			if (!(ti = calloc(1, sizeof(*ti))))
1259 				err(1, "table_opt: calloc");
1260 			ti->host = $3;
1261 			SIMPLEQ_INSERT_TAIL(&table_opts.init_nodes, ti,
1262 			    entries);
1263 			table_opts.init_addr = 1;
1264 		}
1265 		| FILENAME STRING	{
1266 			struct node_tinit	*ti;
1267 
1268 			if (!(ti = calloc(1, sizeof(*ti))))
1269 				err(1, "table_opt: calloc");
1270 			ti->file = $2;
1271 			SIMPLEQ_INSERT_TAIL(&table_opts.init_nodes, ti,
1272 			    entries);
1273 			table_opts.init_addr = 1;
1274 		}
1275 		;
1276 
1277 altqif		: ALTQ interface queue_opts QUEUE qassign {
1278 			struct pf_altq	a;
1279 
1280 			if (check_rulestate(PFCTL_STATE_QUEUE))
1281 				YYERROR;
1282 
1283 			memset(&a, 0, sizeof(a));
1284 			if ($3.scheduler.qtype == ALTQT_NONE) {
1285 				yyerror("no scheduler specified!");
1286 				YYERROR;
1287 			}
1288 			a.scheduler = $3.scheduler.qtype;
1289 			a.qlimit = $3.qlimit;
1290 			a.tbrsize = $3.tbrsize;
1291 			if ($5 == NULL) {
1292 				yyerror("no child queues specified");
1293 				YYERROR;
1294 			}
1295 			if (expand_altq(&a, $2, $5, $3.queue_bwspec,
1296 			    &$3.scheduler))
1297 				YYERROR;
1298 		}
1299 		;
1300 
1301 queuespec	: QUEUE STRING interface queue_opts qassign {
1302 			struct pf_altq	a;
1303 
1304 			if (check_rulestate(PFCTL_STATE_QUEUE)) {
1305 				free($2);
1306 				YYERROR;
1307 			}
1308 
1309 			memset(&a, 0, sizeof(a));
1310 
1311 			if (strlcpy(a.qname, $2, sizeof(a.qname)) >=
1312 			    sizeof(a.qname)) {
1313 				yyerror("queue name too long (max "
1314 				    "%d chars)", PF_QNAME_SIZE-1);
1315 				free($2);
1316 				YYERROR;
1317 			}
1318 			free($2);
1319 			if ($4.tbrsize) {
1320 				yyerror("cannot specify tbrsize for queue");
1321 				YYERROR;
1322 			}
1323 			if ($4.priority > 255) {
1324 				yyerror("priority out of range: max 255");
1325 				YYERROR;
1326 			}
1327 			a.priority = $4.priority;
1328 			a.qlimit = $4.qlimit;
1329 			a.scheduler = $4.scheduler.qtype;
1330 			if (expand_queue(&a, $3, $5, $4.queue_bwspec,
1331 			    &$4.scheduler)) {
1332 				yyerror("errors in queue definition");
1333 				YYERROR;
1334 			}
1335 		}
1336 		;
1337 
1338 queue_opts	:	{
1339 			bzero(&queue_opts, sizeof queue_opts);
1340 			queue_opts.priority = DEFAULT_PRIORITY;
1341 			queue_opts.qlimit = DEFAULT_QLIMIT;
1342 			queue_opts.scheduler.qtype = ALTQT_NONE;
1343 			queue_opts.queue_bwspec.bw_percent = 100;
1344 		}
1345 		    queue_opts_l
1346 			{ $$ = queue_opts; }
1347 		| /* empty */ {
1348 			bzero(&queue_opts, sizeof queue_opts);
1349 			queue_opts.priority = DEFAULT_PRIORITY;
1350 			queue_opts.qlimit = DEFAULT_QLIMIT;
1351 			queue_opts.scheduler.qtype = ALTQT_NONE;
1352 			queue_opts.queue_bwspec.bw_percent = 100;
1353 			$$ = queue_opts;
1354 		}
1355 		;
1356 
1357 queue_opts_l	: queue_opts_l queue_opt
1358 		| queue_opt
1359 		;
1360 
1361 queue_opt	: BANDWIDTH bandwidth	{
1362 			if (queue_opts.marker & QOM_BWSPEC) {
1363 				yyerror("bandwidth cannot be respecified");
1364 				YYERROR;
1365 			}
1366 			queue_opts.marker |= QOM_BWSPEC;
1367 			queue_opts.queue_bwspec = $2;
1368 		}
1369 		| PRIORITY NUMBER	{
1370 			if (queue_opts.marker & QOM_PRIORITY) {
1371 				yyerror("priority cannot be respecified");
1372 				YYERROR;
1373 			}
1374 			if ($2 < 0 || $2 > 255) {
1375 				yyerror("priority out of range: max 255");
1376 				YYERROR;
1377 			}
1378 			queue_opts.marker |= QOM_PRIORITY;
1379 			queue_opts.priority = $2;
1380 		}
1381 		| QLIMIT NUMBER	{
1382 			if (queue_opts.marker & QOM_QLIMIT) {
1383 				yyerror("qlimit cannot be respecified");
1384 				YYERROR;
1385 			}
1386 			if ($2 < 0 || $2 > 65535) {
1387 				yyerror("qlimit out of range: max 65535");
1388 				YYERROR;
1389 			}
1390 			queue_opts.marker |= QOM_QLIMIT;
1391 			queue_opts.qlimit = $2;
1392 		}
1393 		| scheduler	{
1394 			if (queue_opts.marker & QOM_SCHEDULER) {
1395 				yyerror("scheduler cannot be respecified");
1396 				YYERROR;
1397 			}
1398 			queue_opts.marker |= QOM_SCHEDULER;
1399 			queue_opts.scheduler = $1;
1400 		}
1401 		| TBRSIZE NUMBER	{
1402 			if (queue_opts.marker & QOM_TBRSIZE) {
1403 				yyerror("tbrsize cannot be respecified");
1404 				YYERROR;
1405 			}
1406 			if ($2 < 0 || $2 > 65535) {
1407 				yyerror("tbrsize too big: max 65535");
1408 				YYERROR;
1409 			}
1410 			queue_opts.marker |= QOM_TBRSIZE;
1411 			queue_opts.tbrsize = $2;
1412 		}
1413 		;
1414 
1415 bandwidth	: STRING {
1416 			double	 bps;
1417 			char	*cp;
1418 
1419 			$$.bw_percent = 0;
1420 
1421 			bps = strtod($1, &cp);
1422 			if (cp != NULL) {
1423 				if (!strcmp(cp, "b"))
1424 					; /* nothing */
1425 				else if (!strcmp(cp, "Kb"))
1426 					bps *= 1000;
1427 				else if (!strcmp(cp, "Mb"))
1428 					bps *= 1000 * 1000;
1429 				else if (!strcmp(cp, "Gb"))
1430 					bps *= 1000 * 1000 * 1000;
1431 				else if (!strcmp(cp, "%")) {
1432 					if (bps < 0 || bps > 100) {
1433 						yyerror("bandwidth spec "
1434 						    "out of range");
1435 						free($1);
1436 						YYERROR;
1437 					}
1438 					$$.bw_percent = bps;
1439 					bps = 0;
1440 				} else {
1441 					yyerror("unknown unit %s", cp);
1442 					free($1);
1443 					YYERROR;
1444 				}
1445 			}
1446 			free($1);
1447 			$$.bw_absolute = (u_int32_t)bps;
1448 		}
1449 		| NUMBER {
1450 			if ($1 < 0 || $1 > UINT_MAX) {
1451 				yyerror("bandwidth number too big");
1452 				YYERROR;
1453 			}
1454 			$$.bw_percent = 0;
1455 			$$.bw_absolute = $1;
1456 		}
1457 		;
1458 
1459 scheduler	: CBQ				{
1460 			$$.qtype = ALTQT_CBQ;
1461 			$$.data.cbq_opts.flags = 0;
1462 		}
1463 		| CBQ '(' cbqflags_list ')'	{
1464 			$$.qtype = ALTQT_CBQ;
1465 			$$.data.cbq_opts.flags = $3;
1466 		}
1467 		| PRIQ				{
1468 			$$.qtype = ALTQT_PRIQ;
1469 			$$.data.priq_opts.flags = 0;
1470 		}
1471 		| PRIQ '(' priqflags_list ')'	{
1472 			$$.qtype = ALTQT_PRIQ;
1473 			$$.data.priq_opts.flags = $3;
1474 		}
1475 		| HFSC				{
1476 			$$.qtype = ALTQT_HFSC;
1477 			bzero(&$$.data.hfsc_opts,
1478 			    sizeof(struct node_hfsc_opts));
1479 		}
1480 		| HFSC '(' hfsc_opts ')'	{
1481 			$$.qtype = ALTQT_HFSC;
1482 			$$.data.hfsc_opts = $3;
1483 		}
1484 		;
1485 
1486 cbqflags_list	: cbqflags_item				{ $$ |= $1; }
1487 		| cbqflags_list comma cbqflags_item	{ $$ |= $3; }
1488 		;
1489 
1490 cbqflags_item	: STRING	{
1491 			if (!strcmp($1, "default"))
1492 				$$ = CBQCLF_DEFCLASS;
1493 			else if (!strcmp($1, "borrow"))
1494 				$$ = CBQCLF_BORROW;
1495 			else if (!strcmp($1, "red"))
1496 				$$ = CBQCLF_RED;
1497 			else if (!strcmp($1, "ecn"))
1498 				$$ = CBQCLF_RED|CBQCLF_ECN;
1499 			else if (!strcmp($1, "rio"))
1500 				$$ = CBQCLF_RIO;
1501 			else {
1502 				yyerror("unknown cbq flag \"%s\"", $1);
1503 				free($1);
1504 				YYERROR;
1505 			}
1506 			free($1);
1507 		}
1508 		;
1509 
1510 priqflags_list	: priqflags_item			{ $$ |= $1; }
1511 		| priqflags_list comma priqflags_item	{ $$ |= $3; }
1512 		;
1513 
1514 priqflags_item	: STRING	{
1515 			if (!strcmp($1, "default"))
1516 				$$ = PRCF_DEFAULTCLASS;
1517 			else if (!strcmp($1, "red"))
1518 				$$ = PRCF_RED;
1519 			else if (!strcmp($1, "ecn"))
1520 				$$ = PRCF_RED|PRCF_ECN;
1521 			else if (!strcmp($1, "rio"))
1522 				$$ = PRCF_RIO;
1523 			else {
1524 				yyerror("unknown priq flag \"%s\"", $1);
1525 				free($1);
1526 				YYERROR;
1527 			}
1528 			free($1);
1529 		}
1530 		;
1531 
1532 hfsc_opts	:	{
1533 				bzero(&hfsc_opts,
1534 				    sizeof(struct node_hfsc_opts));
1535 			}
1536 		    hfscopts_list				{
1537 			$$ = hfsc_opts;
1538 		}
1539 		;
1540 
1541 hfscopts_list	: hfscopts_item
1542 		| hfscopts_list comma hfscopts_item
1543 		;
1544 
1545 hfscopts_item	: LINKSHARE bandwidth				{
1546 			if (hfsc_opts.linkshare.used) {
1547 				yyerror("linkshare already specified");
1548 				YYERROR;
1549 			}
1550 			hfsc_opts.linkshare.m2 = $2;
1551 			hfsc_opts.linkshare.used = 1;
1552 		}
1553 		| LINKSHARE '(' bandwidth comma NUMBER comma bandwidth ')'
1554 		    {
1555 			if ($5 < 0 || $5 > INT_MAX) {
1556 				yyerror("timing in curve out of range");
1557 				YYERROR;
1558 			}
1559 			if (hfsc_opts.linkshare.used) {
1560 				yyerror("linkshare already specified");
1561 				YYERROR;
1562 			}
1563 			hfsc_opts.linkshare.m1 = $3;
1564 			hfsc_opts.linkshare.d = $5;
1565 			hfsc_opts.linkshare.m2 = $7;
1566 			hfsc_opts.linkshare.used = 1;
1567 		}
1568 		| REALTIME bandwidth				{
1569 			if (hfsc_opts.realtime.used) {
1570 				yyerror("realtime already specified");
1571 				YYERROR;
1572 			}
1573 			hfsc_opts.realtime.m2 = $2;
1574 			hfsc_opts.realtime.used = 1;
1575 		}
1576 		| REALTIME '(' bandwidth comma NUMBER comma bandwidth ')'
1577 		    {
1578 			if ($5 < 0 || $5 > INT_MAX) {
1579 				yyerror("timing in curve out of range");
1580 				YYERROR;
1581 			}
1582 			if (hfsc_opts.realtime.used) {
1583 				yyerror("realtime already specified");
1584 				YYERROR;
1585 			}
1586 			hfsc_opts.realtime.m1 = $3;
1587 			hfsc_opts.realtime.d = $5;
1588 			hfsc_opts.realtime.m2 = $7;
1589 			hfsc_opts.realtime.used = 1;
1590 		}
1591 		| UPPERLIMIT bandwidth				{
1592 			if (hfsc_opts.upperlimit.used) {
1593 				yyerror("upperlimit already specified");
1594 				YYERROR;
1595 			}
1596 			hfsc_opts.upperlimit.m2 = $2;
1597 			hfsc_opts.upperlimit.used = 1;
1598 		}
1599 		| UPPERLIMIT '(' bandwidth comma NUMBER comma bandwidth ')'
1600 		    {
1601 			if ($5 < 0 || $5 > INT_MAX) {
1602 				yyerror("timing in curve out of range");
1603 				YYERROR;
1604 			}
1605 			if (hfsc_opts.upperlimit.used) {
1606 				yyerror("upperlimit already specified");
1607 				YYERROR;
1608 			}
1609 			hfsc_opts.upperlimit.m1 = $3;
1610 			hfsc_opts.upperlimit.d = $5;
1611 			hfsc_opts.upperlimit.m2 = $7;
1612 			hfsc_opts.upperlimit.used = 1;
1613 		}
1614 		| STRING	{
1615 			if (!strcmp($1, "default"))
1616 				hfsc_opts.flags |= HFCF_DEFAULTCLASS;
1617 			else if (!strcmp($1, "red"))
1618 				hfsc_opts.flags |= HFCF_RED;
1619 			else if (!strcmp($1, "ecn"))
1620 				hfsc_opts.flags |= HFCF_RED|HFCF_ECN;
1621 			else if (!strcmp($1, "rio"))
1622 				hfsc_opts.flags |= HFCF_RIO;
1623 			else {
1624 				yyerror("unknown hfsc flag \"%s\"", $1);
1625 				free($1);
1626 				YYERROR;
1627 			}
1628 			free($1);
1629 		}
1630 		;
1631 
1632 qassign		: /* empty */		{ $$ = NULL; }
1633 		| qassign_item		{ $$ = $1; }
1634 		| '{' optnl qassign_list '}'	{ $$ = $3; }
1635 		;
1636 
1637 qassign_list	: qassign_item optnl		{ $$ = $1; }
1638 		| qassign_list comma qassign_item optnl	{
1639 			$1->tail->next = $3;
1640 			$1->tail = $3;
1641 			$$ = $1;
1642 		}
1643 		;
1644 
1645 qassign_item	: STRING			{
1646 			$$ = calloc(1, sizeof(struct node_queue));
1647 			if ($$ == NULL)
1648 				err(1, "qassign_item: calloc");
1649 			if (strlcpy($$->queue, $1, sizeof($$->queue)) >=
1650 			    sizeof($$->queue)) {
1651 				yyerror("queue name '%s' too long (max "
1652 				    "%d chars)", $1, sizeof($$->queue)-1);
1653 				free($1);
1654 				free($$);
1655 				YYERROR;
1656 			}
1657 			free($1);
1658 			$$->next = NULL;
1659 			$$->tail = $$;
1660 		}
1661 		;
1662 
1663 pfrule		: action dir logquick interface af proto fromto
1664 		    filter_opts
1665 		{
1666 			struct pf_rule		 r;
1667 			struct node_state_opt	*o;
1668 			struct node_proto	*proto;
1669 			int			 srctrack = 0;
1670 			int			 statelock = 0;
1671 			int			 adaptive = 0;
1672 			int			 defaults = 0;
1673 
1674 			if (check_rulestate(PFCTL_STATE_FILTER))
1675 				YYERROR;
1676 
1677 			memset(&r, 0, sizeof(r));
1678 
1679 			r.action = $1.b1;
1680 			switch ($1.b2) {
1681 			case PFRULE_RETURNRST:
1682 				r.rule_flag |= PFRULE_RETURNRST;
1683 				r.return_ttl = $1.w;
1684 				break;
1685 			case PFRULE_RETURNICMP:
1686 				r.rule_flag |= PFRULE_RETURNICMP;
1687 				r.return_icmp = $1.w;
1688 				r.return_icmp6 = $1.w2;
1689 				break;
1690 			case PFRULE_RETURN:
1691 				r.rule_flag |= PFRULE_RETURN;
1692 				r.return_icmp = $1.w;
1693 				r.return_icmp6 = $1.w2;
1694 				break;
1695 			}
1696 			r.direction = $2;
1697 			r.log = $3.log;
1698 			r.logif = $3.logif;
1699 			r.quick = $3.quick;
1700 			r.prob = $8.prob;
1701 			r.rtableid = $8.rtableid;
1702 
1703 			if ($8.nodf)
1704 				r.scrub_flags |= PFSTATE_NODF;
1705 			if ($8.randomid)
1706 				r.scrub_flags |= PFSTATE_RANDOMID;
1707 			if ($8.minttl)
1708 				r.min_ttl = $8.minttl;
1709 			if ($8.max_mss)
1710 				r.max_mss = $8.max_mss;
1711 			if ($8.marker & FOM_SETTOS) {
1712 				r.scrub_flags |= PFSTATE_SETTOS;
1713 				r.set_tos = $8.settos;
1714 			}
1715 			if ($8.marker & FOM_SCRUB_TCP)
1716 				r.scrub_flags |= PFSTATE_SCRUB_TCP;
1717 
1718 			r.af = $5;
1719 			if ($8.tag)
1720 				if (strlcpy(r.tagname, $8.tag,
1721 				    PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
1722 					yyerror("tag too long, max %u chars",
1723 					    PF_TAG_NAME_SIZE - 1);
1724 					YYERROR;
1725 				}
1726 			if ($8.match_tag)
1727 				if (strlcpy(r.match_tagname, $8.match_tag,
1728 				    PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
1729 					yyerror("tag too long, max %u chars",
1730 					    PF_TAG_NAME_SIZE - 1);
1731 					YYERROR;
1732 				}
1733 			r.match_tag_not = $8.match_tag_not;
1734 			if (rule_label(&r, $8.label))
1735 				YYERROR;
1736 			free($8.label);
1737 			r.flags = $8.flags.b1;
1738 			r.flagset = $8.flags.b2;
1739 			if (($8.flags.b1 & $8.flags.b2) != $8.flags.b1) {
1740 				yyerror("flags always false");
1741 				YYERROR;
1742 			}
1743 			if ($8.flags.b1 || $8.flags.b2 || $7.src_os) {
1744 				for (proto = $6; proto != NULL &&
1745 				    proto->proto != IPPROTO_TCP;
1746 				    proto = proto->next)
1747 					;	/* nothing */
1748 				if (proto == NULL && $6 != NULL) {
1749 					if ($8.flags.b1 || $8.flags.b2)
1750 						yyerror(
1751 						    "flags only apply to tcp");
1752 					if ($7.src_os)
1753 						yyerror(
1754 						    "OS fingerprinting only "
1755 						    "apply to tcp");
1756 					YYERROR;
1757 				}
1758 #if 0
1759 				if (($8.flags.b1 & parse_flags("S")) == 0 &&
1760 				    $7.src_os) {
1761 					yyerror("OS fingerprinting requires "
1762 					    "the SYN TCP flag (flags S/SA)");
1763 					YYERROR;
1764 				}
1765 #endif
1766 			}
1767 
1768 			r.tos = $8.tos;
1769 			r.keep_state = $8.keep.action;
1770 			o = $8.keep.options;
1771 
1772 			/* 'keep state' by default on pass rules. */
1773 			if (!r.keep_state && !r.action &&
1774 			    !($8.marker & FOM_KEEP)) {
1775 				r.keep_state = PF_STATE_NORMAL;
1776 				o = keep_state_defaults;
1777 				defaults = 1;
1778 			}
1779 
1780 			while (o) {
1781 				struct node_state_opt	*p = o;
1782 
1783 				switch (o->type) {
1784 				case PF_STATE_OPT_MAX:
1785 					if (r.max_states) {
1786 						yyerror("state option 'max' "
1787 						    "multiple definitions");
1788 						YYERROR;
1789 					}
1790 					r.max_states = o->data.max_states;
1791 					break;
1792 				case PF_STATE_OPT_NOSYNC:
1793 					if (r.rule_flag & PFRULE_NOSYNC) {
1794 						yyerror("state option 'sync' "
1795 						    "multiple definitions");
1796 						YYERROR;
1797 					}
1798 					r.rule_flag |= PFRULE_NOSYNC;
1799 					break;
1800 				case PF_STATE_OPT_SRCTRACK:
1801 					if (srctrack) {
1802 						yyerror("state option "
1803 						    "'source-track' "
1804 						    "multiple definitions");
1805 						YYERROR;
1806 					}
1807 					srctrack =  o->data.src_track;
1808 					r.rule_flag |= PFRULE_SRCTRACK;
1809 					break;
1810 				case PF_STATE_OPT_MAX_SRC_STATES:
1811 					if (r.max_src_states) {
1812 						yyerror("state option "
1813 						    "'max-src-states' "
1814 						    "multiple definitions");
1815 						YYERROR;
1816 					}
1817 					if (o->data.max_src_states == 0) {
1818 						yyerror("'max-src-states' must "
1819 						    "be > 0");
1820 						YYERROR;
1821 					}
1822 					r.max_src_states =
1823 					    o->data.max_src_states;
1824 					r.rule_flag |= PFRULE_SRCTRACK;
1825 					break;
1826 				case PF_STATE_OPT_OVERLOAD:
1827 					if (r.overload_tblname[0]) {
1828 						yyerror("multiple 'overload' "
1829 						    "table definitions");
1830 						YYERROR;
1831 					}
1832 					if (strlcpy(r.overload_tblname,
1833 					    o->data.overload.tblname,
1834 					    PF_TABLE_NAME_SIZE) >=
1835 					    PF_TABLE_NAME_SIZE) {
1836 						yyerror("state option: "
1837 						    "strlcpy");
1838 						YYERROR;
1839 					}
1840 					r.flush = o->data.overload.flush;
1841 					break;
1842 				case PF_STATE_OPT_MAX_SRC_CONN:
1843 					if (r.max_src_conn) {
1844 						yyerror("state option "
1845 						    "'max-src-conn' "
1846 						    "multiple definitions");
1847 						YYERROR;
1848 					}
1849 					if (o->data.max_src_conn == 0) {
1850 						yyerror("'max-src-conn' "
1851 						    "must be > 0");
1852 						YYERROR;
1853 					}
1854 					r.max_src_conn =
1855 					    o->data.max_src_conn;
1856 					r.rule_flag |= PFRULE_SRCTRACK |
1857 					    PFRULE_RULESRCTRACK;
1858 					break;
1859 				case PF_STATE_OPT_MAX_SRC_CONN_RATE:
1860 					if (r.max_src_conn_rate.limit) {
1861 						yyerror("state option "
1862 						    "'max-src-conn-rate' "
1863 						    "multiple definitions");
1864 						YYERROR;
1865 					}
1866 					if (!o->data.max_src_conn_rate.limit ||
1867 					    !o->data.max_src_conn_rate.seconds) {
1868 						yyerror("'max-src-conn-rate' "
1869 						    "values must be > 0");
1870 						YYERROR;
1871 					}
1872 					if (o->data.max_src_conn_rate.limit >
1873 					    PF_THRESHOLD_MAX) {
1874 						yyerror("'max-src-conn-rate' "
1875 						    "maximum rate must be < %u",
1876 						    PF_THRESHOLD_MAX);
1877 						YYERROR;
1878 					}
1879 					r.max_src_conn_rate.limit =
1880 					    o->data.max_src_conn_rate.limit;
1881 					r.max_src_conn_rate.seconds =
1882 					    o->data.max_src_conn_rate.seconds;
1883 					r.rule_flag |= PFRULE_SRCTRACK |
1884 					    PFRULE_RULESRCTRACK;
1885 					break;
1886 				case PF_STATE_OPT_MAX_SRC_NODES:
1887 					if (r.max_src_nodes) {
1888 						yyerror("state option "
1889 						    "'max-src-nodes' "
1890 						    "multiple definitions");
1891 						YYERROR;
1892 					}
1893 					if (o->data.max_src_nodes == 0) {
1894 						yyerror("'max-src-nodes' must "
1895 						    "be > 0");
1896 						YYERROR;
1897 					}
1898 					r.max_src_nodes =
1899 					    o->data.max_src_nodes;
1900 					r.rule_flag |= PFRULE_SRCTRACK |
1901 					    PFRULE_RULESRCTRACK;
1902 					break;
1903 				case PF_STATE_OPT_STATELOCK:
1904 					if (statelock) {
1905 						yyerror("state locking option: "
1906 						    "multiple definitions");
1907 						YYERROR;
1908 					}
1909 					statelock = 1;
1910 					r.rule_flag |= o->data.statelock;
1911 					break;
1912 				case PF_STATE_OPT_SLOPPY:
1913 					if (r.rule_flag & PFRULE_STATESLOPPY) {
1914 						yyerror("state sloppy option: "
1915 						    "multiple definitions");
1916 						YYERROR;
1917 					}
1918 					r.rule_flag |= PFRULE_STATESLOPPY;
1919 					break;
1920 				case PF_STATE_OPT_PFLOW:
1921 					if (r.rule_flag & PFRULE_PFLOW) {
1922 						yyerror("state pflow "
1923 						    "option: multiple "
1924 						    "definitions");
1925 						YYERROR;
1926 					}
1927 					r.rule_flag |= PFRULE_PFLOW;
1928 					break;
1929 				case PF_STATE_OPT_TIMEOUT:
1930 					if (o->data.timeout.number ==
1931 					    PFTM_ADAPTIVE_START ||
1932 					    o->data.timeout.number ==
1933 					    PFTM_ADAPTIVE_END)
1934 						adaptive = 1;
1935 					if (r.timeout[o->data.timeout.number]) {
1936 						yyerror("state timeout %s "
1937 						    "multiple definitions",
1938 						    pf_timeouts[o->data.
1939 						    timeout.number].name);
1940 						YYERROR;
1941 					}
1942 					r.timeout[o->data.timeout.number] =
1943 					    o->data.timeout.seconds;
1944 				}
1945 				o = o->next;
1946 				if (!defaults)
1947 					free(p);
1948 			}
1949 
1950 			/* 'flags S/SA' by default on stateful rules */
1951 			if (!r.action && !r.flags && !r.flagset &&
1952 			    !$8.fragment && !($8.marker & FOM_FLAGS) &&
1953 			    r.keep_state) {
1954 				r.flags = parse_flags("S");
1955 				r.flagset =  parse_flags("SA");
1956 			}
1957 			if (!adaptive && r.max_states) {
1958 				r.timeout[PFTM_ADAPTIVE_START] =
1959 				    (r.max_states / 10) * 6;
1960 				r.timeout[PFTM_ADAPTIVE_END] =
1961 				    (r.max_states / 10) * 12;
1962 			}
1963 			if (r.rule_flag & PFRULE_SRCTRACK) {
1964 				if (srctrack == PF_SRCTRACK_GLOBAL &&
1965 				    r.max_src_nodes) {
1966 					yyerror("'max-src-nodes' is "
1967 					    "incompatible with "
1968 					    "'source-track global'");
1969 					YYERROR;
1970 				}
1971 				if (srctrack == PF_SRCTRACK_GLOBAL &&
1972 				    r.max_src_conn) {
1973 					yyerror("'max-src-conn' is "
1974 					    "incompatible with "
1975 					    "'source-track global'");
1976 					YYERROR;
1977 				}
1978 				if (srctrack == PF_SRCTRACK_GLOBAL &&
1979 				    r.max_src_conn_rate.seconds) {
1980 					yyerror("'max-src-conn-rate' is "
1981 					    "incompatible with "
1982 					    "'source-track global'");
1983 					YYERROR;
1984 				}
1985 				if (r.timeout[PFTM_SRC_NODE] <
1986 				    r.max_src_conn_rate.seconds)
1987 					r.timeout[PFTM_SRC_NODE] =
1988 					    r.max_src_conn_rate.seconds;
1989 				r.rule_flag |= PFRULE_SRCTRACK;
1990 				if (srctrack == PF_SRCTRACK_RULE)
1991 					r.rule_flag |= PFRULE_RULESRCTRACK;
1992 			}
1993 			if (r.keep_state && !statelock)
1994 				r.rule_flag |= default_statelock;
1995 
1996 			if ($8.fragment)
1997 				r.rule_flag |= PFRULE_FRAGMENT;
1998 			r.allow_opts = $8.allowopts;
1999 
2000 			decide_address_family($7.src.host, &r.af);
2001 			decide_address_family($7.dst.host, &r.af);
2002 
2003 			if ($8.route.rt) {
2004 				if (!r.direction) {
2005 					yyerror("direction must be explicit "
2006 					    "with rules that specify routing");
2007 					YYERROR;
2008 				}
2009 				r.rt = $8.route.rt;
2010 				r.rdr.opts = $8.route.pool_opts;
2011 				if ($8.route.key != NULL)
2012 					memcpy(&r.rdr.key, $8.route.key,
2013 					    sizeof(struct pf_poolhashkey));
2014 			}
2015 			if (r.rt && r.rt != PF_FASTROUTE) {
2016 				decide_address_family($8.route.host, &r.af);
2017 				remove_invalid_hosts(&$8.route.host, &r.af);
2018 				if ($8.route.host == NULL) {
2019 					yyerror("no routing address with "
2020 					    "matching address family found.");
2021 					YYERROR;
2022 				}
2023 				if ((r.rdr.opts & PF_POOL_TYPEMASK) ==
2024 				    PF_POOL_NONE && ($8.route.host->next != NULL ||
2025 				    $8.route.host->addr.type == PF_ADDR_TABLE ||
2026 				    DYNIF_MULTIADDR($8.route.host->addr)))
2027 					r.rdr.opts |= PF_POOL_ROUNDROBIN;
2028 				if ((r.rdr.opts & PF_POOL_TYPEMASK) !=
2029 				    PF_POOL_ROUNDROBIN &&
2030 				    disallow_table($8.route.host,
2031 				    "tables are only "
2032 				    "supported in round-robin routing pools"))
2033 					YYERROR;
2034 				if ((r.rdr.opts & PF_POOL_TYPEMASK) !=
2035 				    PF_POOL_ROUNDROBIN &&
2036 				    disallow_alias($8.route.host,
2037 				    "interface (%s) "
2038 				    "is only supported in round-robin "
2039 				    "routing pools"))
2040 					YYERROR;
2041 				if ($8.route.host->next != NULL) {
2042 					if ((r.rdr.opts & PF_POOL_TYPEMASK) !=
2043 					    PF_POOL_ROUNDROBIN) {
2044 						yyerror("r.rpool.opts must "
2045 						    "be PF_POOL_ROUNDROBIN");
2046 						YYERROR;
2047 					}
2048 				}
2049 				/* fake redirspec */
2050 				if (($8.rdr.rdr = calloc(1,
2051 				    sizeof(*$8.rdr.rdr))) == NULL)
2052 					err(1, "$8.rdr.rdr");
2053 				$8.rdr.rdr->host = $8.route.host;
2054 			}
2055 			if ($8.queues.qname != NULL) {
2056 				if (strlcpy(r.qname, $8.queues.qname,
2057 				    sizeof(r.qname)) >= sizeof(r.qname)) {
2058 					yyerror("rule qname too long (max "
2059 					    "%d chars)", sizeof(r.qname)-1);
2060 					YYERROR;
2061 				}
2062 				free($8.queues.qname);
2063 			}
2064 			if ($8.queues.pqname != NULL) {
2065 				if (strlcpy(r.pqname, $8.queues.pqname,
2066 				    sizeof(r.pqname)) >= sizeof(r.pqname)) {
2067 					yyerror("rule pqname too long (max "
2068 					    "%d chars)", sizeof(r.pqname)-1);
2069 					YYERROR;
2070 				}
2071 				free($8.queues.pqname);
2072 			}
2073 			if ((r.divert.port = $8.divert.port)) {
2074 				if (r.direction == PF_OUT) {
2075 					if ($8.divert.addr) {
2076 						yyerror("address specified "
2077 						    "for outgoing divert");
2078 						YYERROR;
2079 					}
2080 					bzero(&r.divert.addr,
2081 					    sizeof(r.divert.addr));
2082 				} else {
2083 					if (!$8.divert.addr) {
2084 						yyerror("no address specified "
2085 						    "for incoming divert");
2086 						YYERROR;
2087 					}
2088 					if ($8.divert.addr->af != r.af) {
2089 						yyerror("address family "
2090 						    "mismatch for divert");
2091 						YYERROR;
2092 					}
2093 					r.divert.addr =
2094 					    $8.divert.addr->addr.v.a.addr;
2095 				}
2096 			}
2097 			r.divert_packet.port = $8.divert_packet.port;
2098 
2099 			expand_rule(&r, 0, $4, &$8.nat, &$8.rdr, $6, $7.src_os,
2100 			    $7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
2101 			    $8.uid, $8.gid, $8.icmpspec, "");
2102 		}
2103 		;
2104 
2105 filter_opts	:	{
2106 				bzero(&filter_opts, sizeof filter_opts);
2107 				filter_opts.rtableid = -1;
2108 			}
2109 		    filter_opts_l
2110 			{ $$ = filter_opts; }
2111 		| /* empty */	{
2112 			bzero(&filter_opts, sizeof filter_opts);
2113 			filter_opts.rtableid = -1;
2114 			$$ = filter_opts;
2115 		}
2116 		;
2117 
2118 filter_opts_l	: filter_opts_l filter_opt
2119 		| filter_opt
2120 		;
2121 
2122 filter_opt	: USER uids {
2123 			if (filter_opts.uid)
2124 				$2->tail->next = filter_opts.uid;
2125 			filter_opts.uid = $2;
2126 		}
2127 		| GROUP gids {
2128 			if (filter_opts.gid)
2129 				$2->tail->next = filter_opts.gid;
2130 			filter_opts.gid = $2;
2131 		}
2132 		| flags {
2133 			if (filter_opts.marker & FOM_FLAGS) {
2134 				yyerror("flags cannot be redefined");
2135 				YYERROR;
2136 			}
2137 			filter_opts.marker |= FOM_FLAGS;
2138 			filter_opts.flags.b1 |= $1.b1;
2139 			filter_opts.flags.b2 |= $1.b2;
2140 			filter_opts.flags.w |= $1.w;
2141 			filter_opts.flags.w2 |= $1.w2;
2142 		}
2143 		| icmpspec {
2144 			if (filter_opts.marker & FOM_ICMP) {
2145 				yyerror("icmp-type cannot be redefined");
2146 				YYERROR;
2147 			}
2148 			filter_opts.marker |= FOM_ICMP;
2149 			filter_opts.icmpspec = $1;
2150 		}
2151 		| TOS tos {
2152 			if (filter_opts.marker & FOM_TOS) {
2153 				yyerror("tos cannot be redefined");
2154 				YYERROR;
2155 			}
2156 			filter_opts.marker |= FOM_TOS;
2157 			filter_opts.tos = $2;
2158 		}
2159 		| keep {
2160 			if (filter_opts.marker & FOM_KEEP) {
2161 				yyerror("modulate or keep cannot be redefined");
2162 				YYERROR;
2163 			}
2164 			filter_opts.marker |= FOM_KEEP;
2165 			filter_opts.keep.action = $1.action;
2166 			filter_opts.keep.options = $1.options;
2167 		}
2168 		| FRAGMENT {
2169 			filter_opts.fragment = 1;
2170 		}
2171 		| ALLOWOPTS {
2172 			filter_opts.allowopts = 1;
2173 		}
2174 		| label	{
2175 			if (filter_opts.label) {
2176 				yyerror("label cannot be redefined");
2177 				YYERROR;
2178 			}
2179 			filter_opts.label = $1;
2180 		}
2181 		| qname	{
2182 			if (filter_opts.queues.qname) {
2183 				yyerror("queue cannot be redefined");
2184 				YYERROR;
2185 			}
2186 			filter_opts.queues = $1;
2187 		}
2188 		| TAG string				{
2189 			filter_opts.tag = $2;
2190 		}
2191 		| not TAGGED string			{
2192 			filter_opts.match_tag = $3;
2193 			filter_opts.match_tag_not = $1;
2194 		}
2195 		| PROBABILITY probability		{
2196 			double	p;
2197 
2198 			p = floor($2 * UINT_MAX + 0.5);
2199 			if (p < 0.0 || p > UINT_MAX) {
2200 				yyerror("invalid probability: %lf", p);
2201 				YYERROR;
2202 			}
2203 			filter_opts.prob = (u_int32_t)p;
2204 			if (filter_opts.prob == 0)
2205 				filter_opts.prob = 1;
2206 		}
2207 		| RTABLE NUMBER				{
2208 			if ($2 < 0 || $2 > RT_TABLEID_MAX) {
2209 				yyerror("invalid rtable id");
2210 				YYERROR;
2211 			}
2212 			filter_opts.rtableid = $2;
2213 		}
2214 		| DIVERTTO STRING PORT portplain {
2215 			if ((filter_opts.divert.addr = host($2)) == NULL) {
2216 				yyerror("could not parse divert address: %s",
2217 				    $2);
2218 				free($2);
2219 				YYERROR;
2220 			}
2221 			free($2);
2222 			filter_opts.divert.port = $4.a;
2223 			if (!filter_opts.divert.port) {
2224 				yyerror("invalid divert port: %u", ntohs($4.a));
2225 				YYERROR;
2226 			}
2227 		}
2228 		| DIVERTREPLY {
2229 			filter_opts.divert.port = 1;	/* some random value */
2230 		}
2231 		| DIVERTPACKET PORT number {
2232 			/*
2233 			 * If IP reassembly was not turned off, also
2234 			 * forcibly enable TCP reassembly by default.
2235 			 */
2236 			if (pf->reassemble & PF_REASS_ENABLED)
2237 				filter_opts.marker |= FOM_SCRUB_TCP;
2238 
2239 			if ($3 < 1 || $3 > 65535) {
2240 				yyerror("invalid divert port");
2241 				YYERROR;
2242 			}
2243 
2244 			filter_opts.divert_packet.port = htons($3);
2245 		}
2246 		| SCRUB '(' scrub_opts ')' {
2247 			filter_opts.nodf = $3.nodf;
2248 			filter_opts.minttl = $3.minttl;
2249 			filter_opts.settos = $3.settos;
2250 			filter_opts.randomid = $3.randomid;
2251 			filter_opts.max_mss = $3.maxmss;
2252 			if ($3.reassemble_tcp)
2253 				filter_opts.marker |= FOM_SCRUB_TCP;
2254 			filter_opts.marker |= $3.marker;
2255 		}
2256 		| NATTO redirpool pool_opts {
2257 			if (filter_opts.nat.rdr) {
2258 				yyerror("cannot respecify nat-to/binat-to");
2259 				YYERROR;
2260 			}
2261 			filter_opts.nat.rdr = $2;
2262 			memcpy(&filter_opts.nat.pool_opts, &$3,
2263 			    sizeof(filter_opts.nat.pool_opts));
2264 		}
2265 		| RDRTO redirpool pool_opts {
2266 			if (filter_opts.rdr.rdr) {
2267 				yyerror("cannot respecify rdr-to");
2268 				YYERROR;
2269 			}
2270 			filter_opts.rdr.rdr = $2;
2271 			memcpy(&filter_opts.rdr.pool_opts, &$3,
2272 			    sizeof(filter_opts.rdr.pool_opts));
2273 		}
2274 		| BINATTO redirpool pool_opts {
2275 			if (filter_opts.nat.rdr) {
2276 				yyerror("cannot respecify nat-to/binat-to");
2277 				YYERROR;
2278 			}
2279 			filter_opts.nat.rdr = $2;
2280 			filter_opts.nat.binat = 1;
2281 			memcpy(&filter_opts.nat.pool_opts, &$3,
2282 			    sizeof(filter_opts.nat.pool_opts));
2283 			filter_opts.nat.pool_opts.staticport = 1;
2284 		}
2285 		| FASTROUTE {
2286 			filter_opts.route.host = NULL;
2287 			filter_opts.route.rt = PF_FASTROUTE;
2288 			filter_opts.route.pool_opts = 0;
2289 		}
2290 		| ROUTETO routespec pool_opts {
2291 			filter_opts.route.host = $2;
2292 			filter_opts.route.rt = PF_ROUTETO;
2293 			filter_opts.route.pool_opts = $3.type | $3.opts;
2294 			if ($3.key != NULL)
2295 				filter_opts.route.key = $3.key;
2296 		}
2297 		| REPLYTO routespec pool_opts {
2298 			filter_opts.route.host = $2;
2299 			filter_opts.route.rt = PF_REPLYTO;
2300 			filter_opts.route.pool_opts = $3.type | $3.opts;
2301 			if ($3.key != NULL)
2302 				filter_opts.route.key = $3.key;
2303 		}
2304 		| DUPTO routespec pool_opts {
2305 			filter_opts.route.host = $2;
2306 			filter_opts.route.rt = PF_DUPTO;
2307 			filter_opts.route.pool_opts = $3.type | $3.opts;
2308 			if ($3.key != NULL)
2309 				filter_opts.route.key = $3.key;
2310 		}
2311 		;
2312 
2313 probability	: STRING				{
2314 			char	*e;
2315 			double	 p = strtod($1, &e);
2316 
2317 			if (*e == '%') {
2318 				p *= 0.01;
2319 				e++;
2320 			}
2321 			if (*e) {
2322 				yyerror("invalid probability: %s", $1);
2323 				free($1);
2324 				YYERROR;
2325 			}
2326 			free($1);
2327 			$$ = p;
2328 		}
2329 		| NUMBER				{
2330 			$$ = (double)$1;
2331 		}
2332 		;
2333 
2334 
2335 action		: PASS			{ $$.b1 = PF_PASS; $$.b2 = $$.w = 0; }
2336 		| MATCH			{ $$.b1 = PF_MATCH; $$.b2 = $$.w = 0; }
2337 		| BLOCK blockspec	{ $$ = $2; $$.b1 = PF_DROP; }
2338 		;
2339 
2340 blockspec	: /* empty */		{
2341 			$$.b2 = blockpolicy;
2342 			$$.w = returnicmpdefault;
2343 			$$.w2 = returnicmp6default;
2344 		}
2345 		| DROP			{
2346 			$$.b2 = PFRULE_DROP;
2347 			$$.w = 0;
2348 			$$.w2 = 0;
2349 		}
2350 		| RETURNRST		{
2351 			$$.b2 = PFRULE_RETURNRST;
2352 			$$.w = 0;
2353 			$$.w2 = 0;
2354 		}
2355 		| RETURNRST '(' TTL NUMBER ')'	{
2356 			if ($4 < 0 || $4 > 255) {
2357 				yyerror("illegal ttl value %d", $4);
2358 				YYERROR;
2359 			}
2360 			$$.b2 = PFRULE_RETURNRST;
2361 			$$.w = $4;
2362 			$$.w2 = 0;
2363 		}
2364 		| RETURNICMP		{
2365 			$$.b2 = PFRULE_RETURNICMP;
2366 			$$.w = returnicmpdefault;
2367 			$$.w2 = returnicmp6default;
2368 		}
2369 		| RETURNICMP6		{
2370 			$$.b2 = PFRULE_RETURNICMP;
2371 			$$.w = returnicmpdefault;
2372 			$$.w2 = returnicmp6default;
2373 		}
2374 		| RETURNICMP '(' reticmpspec ')'	{
2375 			$$.b2 = PFRULE_RETURNICMP;
2376 			$$.w = $3;
2377 			$$.w2 = returnicmpdefault;
2378 		}
2379 		| RETURNICMP6 '(' reticmp6spec ')'	{
2380 			$$.b2 = PFRULE_RETURNICMP;
2381 			$$.w = returnicmpdefault;
2382 			$$.w2 = $3;
2383 		}
2384 		| RETURNICMP '(' reticmpspec comma reticmp6spec ')' {
2385 			$$.b2 = PFRULE_RETURNICMP;
2386 			$$.w = $3;
2387 			$$.w2 = $5;
2388 		}
2389 		| RETURN {
2390 			$$.b2 = PFRULE_RETURN;
2391 			$$.w = returnicmpdefault;
2392 			$$.w2 = returnicmp6default;
2393 		}
2394 		;
2395 
2396 reticmpspec	: STRING			{
2397 			if (!($$ = parseicmpspec($1, AF_INET))) {
2398 				free($1);
2399 				YYERROR;
2400 			}
2401 			free($1);
2402 		}
2403 		| NUMBER			{
2404 			u_int8_t		icmptype;
2405 
2406 			if ($1 < 0 || $1 > 255) {
2407 				yyerror("invalid icmp code %lu", $1);
2408 				YYERROR;
2409 			}
2410 			icmptype = returnicmpdefault >> 8;
2411 			$$ = (icmptype << 8 | $1);
2412 		}
2413 		;
2414 
2415 reticmp6spec	: STRING			{
2416 			if (!($$ = parseicmpspec($1, AF_INET6))) {
2417 				free($1);
2418 				YYERROR;
2419 			}
2420 			free($1);
2421 		}
2422 		| NUMBER			{
2423 			u_int8_t		icmptype;
2424 
2425 			if ($1 < 0 || $1 > 255) {
2426 				yyerror("invalid icmp code %lu", $1);
2427 				YYERROR;
2428 			}
2429 			icmptype = returnicmp6default >> 8;
2430 			$$ = (icmptype << 8 | $1);
2431 		}
2432 		;
2433 
2434 dir		: /* empty */			{ $$ = PF_INOUT; }
2435 		| IN				{ $$ = PF_IN; }
2436 		| OUT				{ $$ = PF_OUT; }
2437 		;
2438 
2439 quick		: /* empty */			{ $$.quick = 0; }
2440 		| QUICK				{ $$.quick = 1; }
2441 		;
2442 
2443 logquick	: /* empty */	{ $$.log = 0; $$.quick = 0; $$.logif = 0; }
2444 		| log		{ $$ = $1; $$.quick = 0; }
2445 		| QUICK		{ $$.quick = 1; $$.log = 0; $$.logif = 0; }
2446 		| log QUICK	{ $$ = $1; $$.quick = 1; }
2447 		| QUICK log	{ $$ = $2; $$.quick = 1; }
2448 		;
2449 
2450 log		: LOG			{ $$.log = PF_LOG; $$.logif = 0; }
2451 		| LOG '(' logopts ')'	{
2452 			$$.log = PF_LOG | $3.log;
2453 			$$.logif = $3.logif;
2454 		}
2455 		;
2456 
2457 logopts		: logopt			{ $$ = $1; }
2458 		| logopts comma logopt		{
2459 			$$.log = $1.log | $3.log;
2460 			$$.logif = $3.logif;
2461 			if ($$.logif == 0)
2462 				$$.logif = $1.logif;
2463 		}
2464 		;
2465 
2466 logopt		: ALL		{ $$.log = PF_LOG_ALL; $$.logif = 0; }
2467 		| USER		{ $$.log = PF_LOG_SOCKET_LOOKUP; $$.logif = 0; }
2468 		| GROUP		{ $$.log = PF_LOG_SOCKET_LOOKUP; $$.logif = 0; }
2469 		| TO string	{
2470 			const char	*errstr;
2471 			u_int		 i;
2472 
2473 			$$.log = 0;
2474 			if (strncmp($2, "pflog", 5)) {
2475 				yyerror("%s: should be a pflog interface", $2);
2476 				free($2);
2477 				YYERROR;
2478 			}
2479 			i = strtonum($2 + 5, 0, 255, &errstr);
2480 			if (errstr) {
2481 				yyerror("%s: %s", $2, errstr);
2482 				free($2);
2483 				YYERROR;
2484 			}
2485 			free($2);
2486 			$$.logif = i;
2487 		}
2488 		;
2489 
2490 interface	: /* empty */			{ $$ = NULL; }
2491 		| ON if_item_not		{ $$ = $2; }
2492 		| ON '{' optnl if_list '}'	{ $$ = $4; }
2493 		;
2494 
2495 if_list		: if_item_not optnl		{ $$ = $1; }
2496 		| if_list comma if_item_not optnl	{
2497 			$1->tail->next = $3;
2498 			$1->tail = $3;
2499 			$$ = $1;
2500 		}
2501 		;
2502 
2503 if_item_not	: not if_item			{ $$ = $2; $$->not = $1; }
2504 		;
2505 
2506 if_item		: STRING			{
2507 			struct node_host	*n;
2508 
2509 			$$ = calloc(1, sizeof(struct node_if));
2510 			if ($$ == NULL)
2511 				err(1, "if_item: calloc");
2512 			if (strlcpy($$->ifname, $1, sizeof($$->ifname)) >=
2513 			    sizeof($$->ifname)) {
2514 				free($1);
2515 				free($$);
2516 				yyerror("interface name too long");
2517 				YYERROR;
2518 			}
2519 
2520 			if ((n = ifa_exists($1)) != NULL)
2521 				$$->ifa_flags = n->ifa_flags;
2522 
2523 			free($1);
2524 			$$->not = 0;
2525 			$$->next = NULL;
2526 			$$->tail = $$;
2527 		}
2528 		;
2529 
2530 af		: /* empty */			{ $$ = 0; }
2531 		| INET				{ $$ = AF_INET; }
2532 		| INET6				{ $$ = AF_INET6; }
2533 		;
2534 
2535 proto		: /* empty */				{ $$ = NULL; }
2536 		| PROTO proto_item			{ $$ = $2; }
2537 		| PROTO '{' optnl proto_list '}'	{ $$ = $4; }
2538 		;
2539 
2540 proto_list	: proto_item optnl		{ $$ = $1; }
2541 		| proto_list comma proto_item optnl	{
2542 			$1->tail->next = $3;
2543 			$1->tail = $3;
2544 			$$ = $1;
2545 		}
2546 		;
2547 
2548 proto_item	: protoval			{
2549 			u_int8_t	pr;
2550 
2551 			pr = (u_int8_t)$1;
2552 			if (pr == 0) {
2553 				yyerror("proto 0 cannot be used");
2554 				YYERROR;
2555 			}
2556 			$$ = calloc(1, sizeof(struct node_proto));
2557 			if ($$ == NULL)
2558 				err(1, "proto_item: calloc");
2559 			$$->proto = pr;
2560 			$$->next = NULL;
2561 			$$->tail = $$;
2562 		}
2563 		;
2564 
2565 protoval	: STRING			{
2566 			struct protoent	*p;
2567 
2568 			p = getprotobyname($1);
2569 			if (p == NULL) {
2570 				yyerror("unknown protocol %s", $1);
2571 				free($1);
2572 				YYERROR;
2573 			}
2574 			$$ = p->p_proto;
2575 			free($1);
2576 		}
2577 		| NUMBER			{
2578 			if ($1 < 0 || $1 > 255) {
2579 				yyerror("protocol outside range");
2580 				YYERROR;
2581 			}
2582 		}
2583 		;
2584 
2585 fromto		: ALL				{
2586 			$$.src.host = NULL;
2587 			$$.src.port = NULL;
2588 			$$.dst.host = NULL;
2589 			$$.dst.port = NULL;
2590 			$$.src_os = NULL;
2591 		}
2592 		| from os to			{
2593 			$$.src = $1;
2594 			$$.src_os = $2;
2595 			$$.dst = $3;
2596 		}
2597 		;
2598 
2599 os		: /* empty */			{ $$ = NULL; }
2600 		| OS xos			{ $$ = $2; }
2601 		| OS '{' optnl os_list '}'	{ $$ = $4; }
2602 		;
2603 
2604 xos		: STRING {
2605 			$$ = calloc(1, sizeof(struct node_os));
2606 			if ($$ == NULL)
2607 				err(1, "os: calloc");
2608 			$$->os = $1;
2609 			$$->tail = $$;
2610 		}
2611 		;
2612 
2613 os_list		: xos optnl 			{ $$ = $1; }
2614 		| os_list comma xos optnl	{
2615 			$1->tail->next = $3;
2616 			$1->tail = $3;
2617 			$$ = $1;
2618 		}
2619 		;
2620 
2621 from		: /* empty */			{
2622 			$$.host = NULL;
2623 			$$.port = NULL;
2624 		}
2625 		| FROM ipportspec		{
2626 			$$ = $2;
2627 		}
2628 		;
2629 
2630 to		: /* empty */			{
2631 			$$.host = NULL;
2632 			$$.port = NULL;
2633 		}
2634 		| TO ipportspec		{
2635 			if (disallow_urpf_failed($2.host, "\"urpf-failed\" is "
2636 			    "not permitted in a destination address"))
2637 				YYERROR;
2638 			$$ = $2;
2639 		}
2640 		;
2641 
2642 ipportspec	: ipspec			{
2643 			$$.host = $1;
2644 			$$.port = NULL;
2645 		}
2646 		| ipspec PORT portspec		{
2647 			$$.host = $1;
2648 			$$.port = $3;
2649 		}
2650 		| PORT portspec			{
2651 			$$.host = NULL;
2652 			$$.port = $2;
2653 		}
2654 		;
2655 
2656 optnl		: '\n' optnl
2657 		|
2658 		;
2659 
2660 ipspec		: ANY				{ $$ = NULL; }
2661 		| xhost				{ $$ = $1; }
2662 		| '{' optnl host_list '}'	{ $$ = $3; }
2663 		;
2664 
2665 host_list	: ipspec optnl			{ $$ = $1; }
2666 		| host_list comma ipspec optnl	{
2667 			if ($3 == NULL)
2668 				$$ = $1;
2669 			else if ($1 == NULL)
2670 				$$ = $3;
2671 			else {
2672 				$1->tail->next = $3;
2673 				$1->tail = $3->tail;
2674 				$$ = $1;
2675 			}
2676 		}
2677 		;
2678 
2679 xhost		: not host			{
2680 			struct node_host	*n;
2681 
2682 			for (n = $2; n != NULL; n = n->next)
2683 				n->not = $1;
2684 			$$ = $2;
2685 		}
2686 		| not NOROUTE			{
2687 			$$ = calloc(1, sizeof(struct node_host));
2688 			if ($$ == NULL)
2689 				err(1, "xhost: calloc");
2690 			$$->addr.type = PF_ADDR_NOROUTE;
2691 			$$->next = NULL;
2692 			$$->not = $1;
2693 			$$->tail = $$;
2694 		}
2695 		| not URPFFAILED		{
2696 			$$ = calloc(1, sizeof(struct node_host));
2697 			if ($$ == NULL)
2698 				err(1, "xhost: calloc");
2699 			$$->addr.type = PF_ADDR_URPFFAILED;
2700 			$$->next = NULL;
2701 			$$->not = $1;
2702 			$$->tail = $$;
2703 		}
2704 		;
2705 
2706 host		: STRING			{
2707 			if (($$ = host($1)) == NULL)	{
2708 				/* error. "any" is handled elsewhere */
2709 				free($1);
2710 				yyerror("could not parse host specification");
2711 				YYERROR;
2712 			}
2713 			free($1);
2714 
2715 		}
2716 		| STRING '-' STRING		{
2717 			struct node_host *b, *e;
2718 
2719 			if ((b = host($1)) == NULL || (e = host($3)) == NULL) {
2720 				free($1);
2721 				free($3);
2722 				yyerror("could not parse host specification");
2723 				YYERROR;
2724 			}
2725 			if (b->af != e->af ||
2726 			    b->addr.type != PF_ADDR_ADDRMASK ||
2727 			    e->addr.type != PF_ADDR_ADDRMASK ||
2728 			    unmask(&b->addr.v.a.mask, b->af) !=
2729 			    (b->af == AF_INET ? 32 : 128) ||
2730 			    unmask(&e->addr.v.a.mask, e->af) !=
2731 			    (e->af == AF_INET ? 32 : 128) ||
2732 			    b->next != NULL || b->not ||
2733 			    e->next != NULL || e->not) {
2734 				free(b);
2735 				free(e);
2736 				free($1);
2737 				free($3);
2738 				yyerror("invalid address range");
2739 				YYERROR;
2740 			}
2741 			memcpy(&b->addr.v.a.mask, &e->addr.v.a.addr,
2742 			    sizeof(b->addr.v.a.mask));
2743 			b->addr.type = PF_ADDR_RANGE;
2744 			$$ = b;
2745 			free(e);
2746 			free($1);
2747 			free($3);
2748 		}
2749 		| STRING '/' NUMBER		{
2750 			char	*buf;
2751 
2752 			if (asprintf(&buf, "%s/%lld", $1, $3) == -1)
2753 				err(1, "host: asprintf");
2754 			free($1);
2755 			if (($$ = host(buf)) == NULL)	{
2756 				/* error. "any" is handled elsewhere */
2757 				free(buf);
2758 				yyerror("could not parse host specification");
2759 				YYERROR;
2760 			}
2761 			free(buf);
2762 		}
2763 		| NUMBER '/' NUMBER		{
2764 			char	*buf;
2765 
2766 			/* ie. for 10/8 parsing */
2767 			if (asprintf(&buf, "%lld/%lld", $1, $3) == -1)
2768 				err(1, "host: asprintf");
2769 			if (($$ = host(buf)) == NULL)	{
2770 				/* error. "any" is handled elsewhere */
2771 				free(buf);
2772 				yyerror("could not parse host specification");
2773 				YYERROR;
2774 			}
2775 			free(buf);
2776 		}
2777 		| dynaddr
2778 		| dynaddr '/' NUMBER		{
2779 			struct node_host	*n;
2780 
2781 			if ($3 < 0 || $3 > 128) {
2782 				yyerror("bit number too big");
2783 				YYERROR;
2784 			}
2785 			$$ = $1;
2786 			for (n = $1; n != NULL; n = n->next)
2787 				set_ipmask(n, $3);
2788 		}
2789 		| '<' STRING '>'	{
2790 			if (strlen($2) >= PF_TABLE_NAME_SIZE) {
2791 				yyerror("table name '%s' too long", $2);
2792 				free($2);
2793 				YYERROR;
2794 			}
2795 			$$ = calloc(1, sizeof(struct node_host));
2796 			if ($$ == NULL)
2797 				err(1, "host: calloc");
2798 			$$->addr.type = PF_ADDR_TABLE;
2799 			if (strlcpy($$->addr.v.tblname, $2,
2800 			    sizeof($$->addr.v.tblname)) >=
2801 			    sizeof($$->addr.v.tblname))
2802 				errx(1, "host: strlcpy");
2803 			free($2);
2804 			$$->next = NULL;
2805 			$$->tail = $$;
2806 		}
2807 		| ROUTE	STRING		{
2808 			$$ = calloc(1, sizeof(struct node_host));
2809 			if ($$ == NULL) {
2810 				free($2);
2811 				err(1, "host: calloc");
2812 			}
2813 			$$->addr.type = PF_ADDR_RTLABEL;
2814 			if (strlcpy($$->addr.v.rtlabelname, $2,
2815 			    sizeof($$->addr.v.rtlabelname)) >=
2816 			    sizeof($$->addr.v.rtlabelname)) {
2817 				yyerror("route label too long, max %u chars",
2818 				    sizeof($$->addr.v.rtlabelname) - 1);
2819 				free($2);
2820 				free($$);
2821 				YYERROR;
2822 			}
2823 			$$->next = NULL;
2824 			$$->tail = $$;
2825 			free($2);
2826 		}
2827 		;
2828 
2829 number		: NUMBER
2830 		| STRING		{
2831 			u_long	ulval;
2832 
2833 			if (atoul($1, &ulval) == -1) {
2834 				yyerror("%s is not a number", $1);
2835 				free($1);
2836 				YYERROR;
2837 			} else
2838 				$$ = ulval;
2839 			free($1);
2840 		}
2841 		;
2842 
2843 dynaddr		: '(' STRING ')'		{
2844 			int	 flags = 0;
2845 			char	*p, *op;
2846 
2847 			op = $2;
2848 			if (!isalpha(op[0])) {
2849 				yyerror("invalid interface name '%s'", op);
2850 				free(op);
2851 				YYERROR;
2852 			}
2853 			while ((p = strrchr($2, ':')) != NULL) {
2854 				if (!strcmp(p+1, "network"))
2855 					flags |= PFI_AFLAG_NETWORK;
2856 				else if (!strcmp(p+1, "broadcast"))
2857 					flags |= PFI_AFLAG_BROADCAST;
2858 				else if (!strcmp(p+1, "peer"))
2859 					flags |= PFI_AFLAG_PEER;
2860 				else if (!strcmp(p+1, "0"))
2861 					flags |= PFI_AFLAG_NOALIAS;
2862 				else {
2863 					yyerror("interface %s has bad modifier",
2864 					    $2);
2865 					free(op);
2866 					YYERROR;
2867 				}
2868 				*p = '\0';
2869 			}
2870 			if (flags & (flags - 1) & PFI_AFLAG_MODEMASK) {
2871 				free(op);
2872 				yyerror("illegal combination of "
2873 				    "interface modifiers");
2874 				YYERROR;
2875 			}
2876 			$$ = calloc(1, sizeof(struct node_host));
2877 			if ($$ == NULL)
2878 				err(1, "address: calloc");
2879 			$$->af = 0;
2880 			set_ipmask($$, 128);
2881 			$$->addr.type = PF_ADDR_DYNIFTL;
2882 			$$->addr.iflags = flags;
2883 			if (strlcpy($$->addr.v.ifname, $2,
2884 			    sizeof($$->addr.v.ifname)) >=
2885 			    sizeof($$->addr.v.ifname)) {
2886 				free(op);
2887 				free($$);
2888 				yyerror("interface name too long");
2889 				YYERROR;
2890 			}
2891 			free(op);
2892 			$$->next = NULL;
2893 			$$->tail = $$;
2894 		}
2895 		;
2896 
2897 portspec	: port_item			{ $$ = $1; }
2898 		| '{' optnl port_list '}'	{ $$ = $3; }
2899 		;
2900 
2901 port_list	: port_item optnl		{ $$ = $1; }
2902 		| port_list comma port_item optnl	{
2903 			$1->tail->next = $3;
2904 			$1->tail = $3;
2905 			$$ = $1;
2906 		}
2907 		;
2908 
2909 port_item	: portrange			{
2910 			$$ = calloc(1, sizeof(struct node_port));
2911 			if ($$ == NULL)
2912 				err(1, "port_item: calloc");
2913 			$$->port[0] = $1.a;
2914 			$$->port[1] = $1.b;
2915 			if ($1.t)
2916 				$$->op = PF_OP_RRG;
2917 			else
2918 				$$->op = PF_OP_EQ;
2919 			$$->next = NULL;
2920 			$$->tail = $$;
2921 		}
2922 		| unaryop portrange	{
2923 			if ($2.t) {
2924 				yyerror("':' cannot be used with an other "
2925 				    "port operator");
2926 				YYERROR;
2927 			}
2928 			$$ = calloc(1, sizeof(struct node_port));
2929 			if ($$ == NULL)
2930 				err(1, "port_item: calloc");
2931 			$$->port[0] = $2.a;
2932 			$$->port[1] = $2.b;
2933 			$$->op = $1;
2934 			$$->next = NULL;
2935 			$$->tail = $$;
2936 		}
2937 		| portrange PORTBINARY portrange	{
2938 			if ($1.t || $3.t) {
2939 				yyerror("':' cannot be used with an other "
2940 				    "port operator");
2941 				YYERROR;
2942 			}
2943 			$$ = calloc(1, sizeof(struct node_port));
2944 			if ($$ == NULL)
2945 				err(1, "port_item: calloc");
2946 			$$->port[0] = $1.a;
2947 			$$->port[1] = $3.a;
2948 			$$->op = $2;
2949 			$$->next = NULL;
2950 			$$->tail = $$;
2951 		}
2952 		;
2953 
2954 portplain	: numberstring			{
2955 			if (parseport($1, &$$, 0) == -1) {
2956 				free($1);
2957 				YYERROR;
2958 			}
2959 			free($1);
2960 		}
2961 		;
2962 
2963 portrange	: numberstring			{
2964 			if (parseport($1, &$$, PPORT_RANGE) == -1) {
2965 				free($1);
2966 				YYERROR;
2967 			}
2968 			free($1);
2969 		}
2970 		;
2971 
2972 uids		: uid_item			{ $$ = $1; }
2973 		| '{' optnl uid_list '}'	{ $$ = $3; }
2974 		;
2975 
2976 uid_list	: uid_item optnl		{ $$ = $1; }
2977 		| uid_list comma uid_item optnl	{
2978 			$1->tail->next = $3;
2979 			$1->tail = $3;
2980 			$$ = $1;
2981 		}
2982 		;
2983 
2984 uid_item	: uid				{
2985 			$$ = calloc(1, sizeof(struct node_uid));
2986 			if ($$ == NULL)
2987 				err(1, "uid_item: calloc");
2988 			$$->uid[0] = $1;
2989 			$$->uid[1] = $1;
2990 			$$->op = PF_OP_EQ;
2991 			$$->next = NULL;
2992 			$$->tail = $$;
2993 		}
2994 		| unaryop uid			{
2995 			if ($2 == UID_MAX && $1 != PF_OP_EQ && $1 != PF_OP_NE) {
2996 				yyerror("user unknown requires operator = or "
2997 				    "!=");
2998 				YYERROR;
2999 			}
3000 			$$ = calloc(1, sizeof(struct node_uid));
3001 			if ($$ == NULL)
3002 				err(1, "uid_item: calloc");
3003 			$$->uid[0] = $2;
3004 			$$->uid[1] = $2;
3005 			$$->op = $1;
3006 			$$->next = NULL;
3007 			$$->tail = $$;
3008 		}
3009 		| uid PORTBINARY uid		{
3010 			if ($1 == UID_MAX || $3 == UID_MAX) {
3011 				yyerror("user unknown requires operator = or "
3012 				    "!=");
3013 				YYERROR;
3014 			}
3015 			$$ = calloc(1, sizeof(struct node_uid));
3016 			if ($$ == NULL)
3017 				err(1, "uid_item: calloc");
3018 			$$->uid[0] = $1;
3019 			$$->uid[1] = $3;
3020 			$$->op = $2;
3021 			$$->next = NULL;
3022 			$$->tail = $$;
3023 		}
3024 		;
3025 
3026 uid		: STRING			{
3027 			if (!strcmp($1, "unknown"))
3028 				$$ = UID_MAX;
3029 			else {
3030 				struct passwd	*pw;
3031 
3032 				if ((pw = getpwnam($1)) == NULL) {
3033 					yyerror("unknown user %s", $1);
3034 					free($1);
3035 					YYERROR;
3036 				}
3037 				$$ = pw->pw_uid;
3038 			}
3039 			free($1);
3040 		}
3041 		| NUMBER			{
3042 			if ($1 < 0 || $1 >= UID_MAX) {
3043 				yyerror("illegal uid value %lu", $1);
3044 				YYERROR;
3045 			}
3046 			$$ = $1;
3047 		}
3048 		;
3049 
3050 gids		: gid_item			{ $$ = $1; }
3051 		| '{' optnl gid_list '}'	{ $$ = $3; }
3052 		;
3053 
3054 gid_list	: gid_item optnl		{ $$ = $1; }
3055 		| gid_list comma gid_item optnl	{
3056 			$1->tail->next = $3;
3057 			$1->tail = $3;
3058 			$$ = $1;
3059 		}
3060 		;
3061 
3062 gid_item	: gid				{
3063 			$$ = calloc(1, sizeof(struct node_gid));
3064 			if ($$ == NULL)
3065 				err(1, "gid_item: calloc");
3066 			$$->gid[0] = $1;
3067 			$$->gid[1] = $1;
3068 			$$->op = PF_OP_EQ;
3069 			$$->next = NULL;
3070 			$$->tail = $$;
3071 		}
3072 		| unaryop gid			{
3073 			if ($2 == GID_MAX && $1 != PF_OP_EQ && $1 != PF_OP_NE) {
3074 				yyerror("group unknown requires operator = or "
3075 				    "!=");
3076 				YYERROR;
3077 			}
3078 			$$ = calloc(1, sizeof(struct node_gid));
3079 			if ($$ == NULL)
3080 				err(1, "gid_item: calloc");
3081 			$$->gid[0] = $2;
3082 			$$->gid[1] = $2;
3083 			$$->op = $1;
3084 			$$->next = NULL;
3085 			$$->tail = $$;
3086 		}
3087 		| gid PORTBINARY gid		{
3088 			if ($1 == GID_MAX || $3 == GID_MAX) {
3089 				yyerror("group unknown requires operator = or "
3090 				    "!=");
3091 				YYERROR;
3092 			}
3093 			$$ = calloc(1, sizeof(struct node_gid));
3094 			if ($$ == NULL)
3095 				err(1, "gid_item: calloc");
3096 			$$->gid[0] = $1;
3097 			$$->gid[1] = $3;
3098 			$$->op = $2;
3099 			$$->next = NULL;
3100 			$$->tail = $$;
3101 		}
3102 		;
3103 
3104 gid		: STRING			{
3105 			if (!strcmp($1, "unknown"))
3106 				$$ = GID_MAX;
3107 			else {
3108 				struct group	*grp;
3109 
3110 				if ((grp = getgrnam($1)) == NULL) {
3111 					yyerror("unknown group %s", $1);
3112 					free($1);
3113 					YYERROR;
3114 				}
3115 				$$ = grp->gr_gid;
3116 			}
3117 			free($1);
3118 		}
3119 		| NUMBER			{
3120 			if ($1 < 0 || $1 >= GID_MAX) {
3121 				yyerror("illegal gid value %lu", $1);
3122 				YYERROR;
3123 			}
3124 			$$ = $1;
3125 		}
3126 		;
3127 
3128 flag		: STRING			{
3129 			int	f;
3130 
3131 			if ((f = parse_flags($1)) < 0) {
3132 				yyerror("bad flags %s", $1);
3133 				free($1);
3134 				YYERROR;
3135 			}
3136 			free($1);
3137 			$$.b1 = f;
3138 		}
3139 		;
3140 
3141 flags		: FLAGS flag '/' flag	{ $$.b1 = $2.b1; $$.b2 = $4.b1; }
3142 		| FLAGS '/' flag	{ $$.b1 = 0; $$.b2 = $3.b1; }
3143 		| FLAGS ANY		{ $$.b1 = 0; $$.b2 = 0; }
3144 		;
3145 
3146 icmpspec	: ICMPTYPE icmp_item			{ $$ = $2; }
3147 		| ICMPTYPE '{' optnl icmp_list '}'	{ $$ = $4; }
3148 		| ICMP6TYPE icmp6_item			{ $$ = $2; }
3149 		| ICMP6TYPE '{' optnl icmp6_list '}'	{ $$ = $4; }
3150 		;
3151 
3152 icmp_list	: icmp_item optnl		{ $$ = $1; }
3153 		| icmp_list comma icmp_item optnl {
3154 			$1->tail->next = $3;
3155 			$1->tail = $3;
3156 			$$ = $1;
3157 		}
3158 		;
3159 
3160 icmp6_list	: icmp6_item optnl		{ $$ = $1; }
3161 		| icmp6_list comma icmp6_item optnl {
3162 			$1->tail->next = $3;
3163 			$1->tail = $3;
3164 			$$ = $1;
3165 		}
3166 		;
3167 
3168 icmp_item	: icmptype		{
3169 			$$ = calloc(1, sizeof(struct node_icmp));
3170 			if ($$ == NULL)
3171 				err(1, "icmp_item: calloc");
3172 			$$->type = $1;
3173 			$$->code = 0;
3174 			$$->proto = IPPROTO_ICMP;
3175 			$$->next = NULL;
3176 			$$->tail = $$;
3177 		}
3178 		| icmptype CODE STRING	{
3179 			const struct icmpcodeent	*p;
3180 
3181 			if ((p = geticmpcodebyname($1-1, $3, AF_INET)) == NULL) {
3182 				yyerror("unknown icmp-code %s", $3);
3183 				free($3);
3184 				YYERROR;
3185 			}
3186 
3187 			free($3);
3188 			$$ = calloc(1, sizeof(struct node_icmp));
3189 			if ($$ == NULL)
3190 				err(1, "icmp_item: calloc");
3191 			$$->type = $1;
3192 			$$->code = p->code + 1;
3193 			$$->proto = IPPROTO_ICMP;
3194 			$$->next = NULL;
3195 			$$->tail = $$;
3196 		}
3197 		| icmptype CODE NUMBER	{
3198 			if ($3 < 0 || $3 > 255) {
3199 				yyerror("illegal icmp-code %lu", $3);
3200 				YYERROR;
3201 			}
3202 			$$ = calloc(1, sizeof(struct node_icmp));
3203 			if ($$ == NULL)
3204 				err(1, "icmp_item: calloc");
3205 			$$->type = $1;
3206 			$$->code = $3 + 1;
3207 			$$->proto = IPPROTO_ICMP;
3208 			$$->next = NULL;
3209 			$$->tail = $$;
3210 		}
3211 		;
3212 
3213 icmp6_item	: icmp6type		{
3214 			$$ = calloc(1, sizeof(struct node_icmp));
3215 			if ($$ == NULL)
3216 				err(1, "icmp_item: calloc");
3217 			$$->type = $1;
3218 			$$->code = 0;
3219 			$$->proto = IPPROTO_ICMPV6;
3220 			$$->next = NULL;
3221 			$$->tail = $$;
3222 		}
3223 		| icmp6type CODE STRING	{
3224 			const struct icmpcodeent	*p;
3225 
3226 			if ((p = geticmpcodebyname($1-1, $3, AF_INET6)) == NULL) {
3227 				yyerror("unknown icmp6-code %s", $3);
3228 				free($3);
3229 				YYERROR;
3230 			}
3231 			free($3);
3232 
3233 			$$ = calloc(1, sizeof(struct node_icmp));
3234 			if ($$ == NULL)
3235 				err(1, "icmp_item: calloc");
3236 			$$->type = $1;
3237 			$$->code = p->code + 1;
3238 			$$->proto = IPPROTO_ICMPV6;
3239 			$$->next = NULL;
3240 			$$->tail = $$;
3241 		}
3242 		| icmp6type CODE NUMBER	{
3243 			if ($3 < 0 || $3 > 255) {
3244 				yyerror("illegal icmp-code %lu", $3);
3245 				YYERROR;
3246 			}
3247 			$$ = calloc(1, sizeof(struct node_icmp));
3248 			if ($$ == NULL)
3249 				err(1, "icmp_item: calloc");
3250 			$$->type = $1;
3251 			$$->code = $3 + 1;
3252 			$$->proto = IPPROTO_ICMPV6;
3253 			$$->next = NULL;
3254 			$$->tail = $$;
3255 		}
3256 		;
3257 
3258 icmptype	: STRING			{
3259 			const struct icmptypeent	*p;
3260 
3261 			if ((p = geticmptypebyname($1, AF_INET)) == NULL) {
3262 				yyerror("unknown icmp-type %s", $1);
3263 				free($1);
3264 				YYERROR;
3265 			}
3266 			$$ = p->type + 1;
3267 			free($1);
3268 		}
3269 		| NUMBER			{
3270 			if ($1 < 0 || $1 > 255) {
3271 				yyerror("illegal icmp-type %lu", $1);
3272 				YYERROR;
3273 			}
3274 			$$ = $1 + 1;
3275 		}
3276 		;
3277 
3278 icmp6type	: STRING			{
3279 			const struct icmptypeent	*p;
3280 
3281 			if ((p = geticmptypebyname($1, AF_INET6)) ==
3282 			    NULL) {
3283 				yyerror("unknown icmp6-type %s", $1);
3284 				free($1);
3285 				YYERROR;
3286 			}
3287 			$$ = p->type + 1;
3288 			free($1);
3289 		}
3290 		| NUMBER			{
3291 			if ($1 < 0 || $1 > 255) {
3292 				yyerror("illegal icmp6-type %lu", $1);
3293 				YYERROR;
3294 			}
3295 			$$ = $1 + 1;
3296 		}
3297 		;
3298 
3299 tos	: STRING			{
3300 			int val;
3301 			if (map_tos($1, &val))
3302 				$$ = val;
3303 			else if ($1[0] == '0' && $1[1] == 'x')
3304 				$$ = strtoul($1, NULL, 16);
3305 			else
3306 				$$ = 256;		/* flag bad argument */
3307 			if ($$ > 255) {
3308 				yyerror("illegal tos value %s", $1);
3309 				free($1);
3310 				YYERROR;
3311 			}
3312 			free($1);
3313 		}
3314 		| NUMBER			{
3315 			$$ = $1;
3316 			if ($$ > 255) {
3317 				yyerror("illegal tos value %s", $1);
3318 				YYERROR;
3319 			}
3320 		}
3321 		;
3322 
3323 sourcetrack	: SOURCETRACK		{ $$ = PF_SRCTRACK; }
3324 		| SOURCETRACK GLOBAL	{ $$ = PF_SRCTRACK_GLOBAL; }
3325 		| SOURCETRACK RULE	{ $$ = PF_SRCTRACK_RULE; }
3326 		;
3327 
3328 statelock	: IFBOUND {
3329 			$$ = PFRULE_IFBOUND;
3330 		}
3331 		| FLOATING {
3332 			$$ = 0;
3333 		}
3334 		;
3335 
3336 keep		: NO STATE			{
3337 			$$.action = 0;
3338 			$$.options = NULL;
3339 		}
3340 		| KEEP STATE state_opt_spec	{
3341 			$$.action = PF_STATE_NORMAL;
3342 			$$.options = $3;
3343 		}
3344 		| MODULATE STATE state_opt_spec {
3345 			$$.action = PF_STATE_MODULATE;
3346 			$$.options = $3;
3347 		}
3348 		| SYNPROXY STATE state_opt_spec {
3349 			$$.action = PF_STATE_SYNPROXY;
3350 			$$.options = $3;
3351 		}
3352 		;
3353 
3354 flush		: /* empty */			{ $$ = 0; }
3355 		| FLUSH				{ $$ = PF_FLUSH; }
3356 		| FLUSH GLOBAL			{
3357 			$$ = PF_FLUSH | PF_FLUSH_GLOBAL;
3358 		}
3359 		;
3360 
3361 state_opt_spec	: '(' state_opt_list ')'	{ $$ = $2; }
3362 		| /* empty */			{ $$ = NULL; }
3363 		;
3364 
3365 state_opt_list	: state_opt_item		{ $$ = $1; }
3366 		| state_opt_list comma state_opt_item {
3367 			$1->tail->next = $3;
3368 			$1->tail = $3;
3369 			$$ = $1;
3370 		}
3371 		;
3372 
3373 state_opt_item	: MAXIMUM NUMBER		{
3374 			if ($2 < 0 || $2 > UINT_MAX) {
3375 				yyerror("only positive values permitted");
3376 				YYERROR;
3377 			}
3378 			$$ = calloc(1, sizeof(struct node_state_opt));
3379 			if ($$ == NULL)
3380 				err(1, "state_opt_item: calloc");
3381 			$$->type = PF_STATE_OPT_MAX;
3382 			$$->data.max_states = $2;
3383 			$$->next = NULL;
3384 			$$->tail = $$;
3385 		}
3386 		| NOSYNC				{
3387 			$$ = calloc(1, sizeof(struct node_state_opt));
3388 			if ($$ == NULL)
3389 				err(1, "state_opt_item: calloc");
3390 			$$->type = PF_STATE_OPT_NOSYNC;
3391 			$$->next = NULL;
3392 			$$->tail = $$;
3393 		}
3394 		| MAXSRCSTATES NUMBER			{
3395 			if ($2 < 0 || $2 > UINT_MAX) {
3396 				yyerror("only positive values permitted");
3397 				YYERROR;
3398 			}
3399 			$$ = calloc(1, sizeof(struct node_state_opt));
3400 			if ($$ == NULL)
3401 				err(1, "state_opt_item: calloc");
3402 			$$->type = PF_STATE_OPT_MAX_SRC_STATES;
3403 			$$->data.max_src_states = $2;
3404 			$$->next = NULL;
3405 			$$->tail = $$;
3406 		}
3407 		| MAXSRCCONN NUMBER			{
3408 			if ($2 < 0 || $2 > UINT_MAX) {
3409 				yyerror("only positive values permitted");
3410 				YYERROR;
3411 			}
3412 			$$ = calloc(1, sizeof(struct node_state_opt));
3413 			if ($$ == NULL)
3414 				err(1, "state_opt_item: calloc");
3415 			$$->type = PF_STATE_OPT_MAX_SRC_CONN;
3416 			$$->data.max_src_conn = $2;
3417 			$$->next = NULL;
3418 			$$->tail = $$;
3419 		}
3420 		| MAXSRCCONNRATE NUMBER '/' NUMBER	{
3421 			if ($2 < 0 || $2 > UINT_MAX ||
3422 			    $4 < 0 || $4 > UINT_MAX) {
3423 				yyerror("only positive values permitted");
3424 				YYERROR;
3425 			}
3426 			$$ = calloc(1, sizeof(struct node_state_opt));
3427 			if ($$ == NULL)
3428 				err(1, "state_opt_item: calloc");
3429 			$$->type = PF_STATE_OPT_MAX_SRC_CONN_RATE;
3430 			$$->data.max_src_conn_rate.limit = $2;
3431 			$$->data.max_src_conn_rate.seconds = $4;
3432 			$$->next = NULL;
3433 			$$->tail = $$;
3434 		}
3435 		| OVERLOAD '<' STRING '>' flush		{
3436 			if (strlen($3) >= PF_TABLE_NAME_SIZE) {
3437 				yyerror("table name '%s' too long", $3);
3438 				free($3);
3439 				YYERROR;
3440 			}
3441 			$$ = calloc(1, sizeof(struct node_state_opt));
3442 			if ($$ == NULL)
3443 				err(1, "state_opt_item: calloc");
3444 			if (strlcpy($$->data.overload.tblname, $3,
3445 			    PF_TABLE_NAME_SIZE) >= PF_TABLE_NAME_SIZE)
3446 				errx(1, "state_opt_item: strlcpy");
3447 			free($3);
3448 			$$->type = PF_STATE_OPT_OVERLOAD;
3449 			$$->data.overload.flush = $5;
3450 			$$->next = NULL;
3451 			$$->tail = $$;
3452 		}
3453 		| MAXSRCNODES NUMBER			{
3454 			if ($2 < 0 || $2 > UINT_MAX) {
3455 				yyerror("only positive values permitted");
3456 				YYERROR;
3457 			}
3458 			$$ = calloc(1, sizeof(struct node_state_opt));
3459 			if ($$ == NULL)
3460 				err(1, "state_opt_item: calloc");
3461 			$$->type = PF_STATE_OPT_MAX_SRC_NODES;
3462 			$$->data.max_src_nodes = $2;
3463 			$$->next = NULL;
3464 			$$->tail = $$;
3465 		}
3466 		| sourcetrack {
3467 			$$ = calloc(1, sizeof(struct node_state_opt));
3468 			if ($$ == NULL)
3469 				err(1, "state_opt_item: calloc");
3470 			$$->type = PF_STATE_OPT_SRCTRACK;
3471 			$$->data.src_track = $1;
3472 			$$->next = NULL;
3473 			$$->tail = $$;
3474 		}
3475 		| statelock {
3476 			$$ = calloc(1, sizeof(struct node_state_opt));
3477 			if ($$ == NULL)
3478 				err(1, "state_opt_item: calloc");
3479 			$$->type = PF_STATE_OPT_STATELOCK;
3480 			$$->data.statelock = $1;
3481 			$$->next = NULL;
3482 			$$->tail = $$;
3483 		}
3484 		| SLOPPY {
3485 			$$ = calloc(1, sizeof(struct node_state_opt));
3486 			if ($$ == NULL)
3487 				err(1, "state_opt_item: calloc");
3488 			$$->type = PF_STATE_OPT_SLOPPY;
3489 			$$->next = NULL;
3490 			$$->tail = $$;
3491 		}
3492 		| PFLOW {
3493 			$$ = calloc(1, sizeof(struct node_state_opt));
3494 			if ($$ == NULL)
3495 				err(1, "state_opt_item: calloc");
3496 			$$->type = PF_STATE_OPT_PFLOW;
3497 			$$->next = NULL;
3498 			$$->tail = $$;
3499 		}
3500 		| STRING NUMBER			{
3501 			int	i;
3502 
3503 			if ($2 < 0 || $2 > UINT_MAX) {
3504 				yyerror("only positive values permitted");
3505 				YYERROR;
3506 			}
3507 			for (i = 0; pf_timeouts[i].name &&
3508 			    strcmp(pf_timeouts[i].name, $1); ++i)
3509 				;	/* nothing */
3510 			if (!pf_timeouts[i].name) {
3511 				yyerror("illegal timeout name %s", $1);
3512 				free($1);
3513 				YYERROR;
3514 			}
3515 			if (strchr(pf_timeouts[i].name, '.') == NULL) {
3516 				yyerror("illegal state timeout %s", $1);
3517 				free($1);
3518 				YYERROR;
3519 			}
3520 			free($1);
3521 			$$ = calloc(1, sizeof(struct node_state_opt));
3522 			if ($$ == NULL)
3523 				err(1, "state_opt_item: calloc");
3524 			$$->type = PF_STATE_OPT_TIMEOUT;
3525 			$$->data.timeout.number = pf_timeouts[i].timeout;
3526 			$$->data.timeout.seconds = $2;
3527 			$$->next = NULL;
3528 			$$->tail = $$;
3529 		}
3530 		;
3531 
3532 label		: LABEL STRING			{
3533 			$$ = $2;
3534 		}
3535 		;
3536 
3537 qname		: QUEUE STRING				{
3538 			$$.qname = $2;
3539 			$$.pqname = NULL;
3540 		}
3541 		| QUEUE '(' STRING ')'			{
3542 			$$.qname = $3;
3543 			$$.pqname = NULL;
3544 		}
3545 		| QUEUE '(' STRING comma STRING ')'	{
3546 			$$.qname = $3;
3547 			$$.pqname = $5;
3548 		}
3549 		;
3550 
3551 portstar	: numberstring			{
3552 			if (parseport($1, &$$, PPORT_RANGE|PPORT_STAR) == -1) {
3553 				free($1);
3554 				YYERROR;
3555 			}
3556 			free($1);
3557 		}
3558 		;
3559 
3560 redirspec	: host				{ $$ = $1; }
3561 		| '{' optnl redir_host_list '}'	{ $$ = $3; }
3562 		;
3563 
3564 redir_host_list	: host optnl			{ $$ = $1; }
3565 		| redir_host_list comma host optnl {
3566 			$1->tail->next = $3;
3567 			$1->tail = $3->tail;
3568 			$$ = $1;
3569 		}
3570 		;
3571 
3572 redirpool	: redirspec		{
3573 			$$ = calloc(1, sizeof(struct redirection));
3574 			if ($$ == NULL)
3575 				err(1, "redirection: calloc");
3576 			$$->host = $1;
3577 			$$->rport.a = $$->rport.b = $$->rport.t = 0;
3578 		}
3579 		| redirspec PORT portstar	{
3580 			$$ = calloc(1, sizeof(struct redirection));
3581 			if ($$ == NULL)
3582 				err(1, "redirection: calloc");
3583 			$$->host = $1;
3584 			$$->rport = $3;
3585 		}
3586 		;
3587 
3588 hashkey		: /* empty */
3589 		{
3590 			$$ = calloc(1, sizeof(struct pf_poolhashkey));
3591 			if ($$ == NULL)
3592 				err(1, "hashkey: calloc");
3593 			$$->key32[0] = arc4random();
3594 			$$->key32[1] = arc4random();
3595 			$$->key32[2] = arc4random();
3596 			$$->key32[3] = arc4random();
3597 		}
3598 		| string
3599 		{
3600 			if (!strncmp($1, "0x", 2)) {
3601 				if (strlen($1) != 34) {
3602 					free($1);
3603 					yyerror("hex key must be 128 bits "
3604 						"(32 hex digits) long");
3605 					YYERROR;
3606 				}
3607 				$$ = calloc(1, sizeof(struct pf_poolhashkey));
3608 				if ($$ == NULL)
3609 					err(1, "hashkey: calloc");
3610 
3611 				if (sscanf($1, "0x%8x%8x%8x%8x",
3612 				    &$$->key32[0], &$$->key32[1],
3613 				    &$$->key32[2], &$$->key32[3]) != 4) {
3614 					free($$);
3615 					free($1);
3616 					yyerror("invalid hex key");
3617 					YYERROR;
3618 				}
3619 			} else {
3620 				MD5_CTX	context;
3621 
3622 				$$ = calloc(1, sizeof(struct pf_poolhashkey));
3623 				if ($$ == NULL)
3624 					err(1, "hashkey: calloc");
3625 				MD5Init(&context);
3626 				MD5Update(&context, (unsigned char *)$1,
3627 				    strlen($1));
3628 				MD5Final((unsigned char *)$$, &context);
3629 				HTONL($$->key32[0]);
3630 				HTONL($$->key32[1]);
3631 				HTONL($$->key32[2]);
3632 				HTONL($$->key32[3]);
3633 			}
3634 			free($1);
3635 		}
3636 		;
3637 
3638 pool_opts	:	{ bzero(&pool_opts, sizeof pool_opts); }
3639 		    pool_opts_l
3640 			{ $$ = pool_opts; }
3641 		| /* empty */	{
3642 			bzero(&pool_opts, sizeof pool_opts);
3643 			$$ = pool_opts;
3644 		}
3645 		;
3646 
3647 pool_opts_l	: pool_opts_l pool_opt
3648 		| pool_opt
3649 		;
3650 
3651 pool_opt	: BITMASK	{
3652 			if (pool_opts.type) {
3653 				yyerror("pool type cannot be redefined");
3654 				YYERROR;
3655 			}
3656 			pool_opts.type =  PF_POOL_BITMASK;
3657 		}
3658 		| RANDOM	{
3659 			if (pool_opts.type) {
3660 				yyerror("pool type cannot be redefined");
3661 				YYERROR;
3662 			}
3663 			pool_opts.type = PF_POOL_RANDOM;
3664 		}
3665 		| SOURCEHASH hashkey {
3666 			if (pool_opts.type) {
3667 				yyerror("pool type cannot be redefined");
3668 				YYERROR;
3669 			}
3670 			pool_opts.type = PF_POOL_SRCHASH;
3671 			pool_opts.key = $2;
3672 		}
3673 		| ROUNDROBIN	{
3674 			if (pool_opts.type) {
3675 				yyerror("pool type cannot be redefined");
3676 				YYERROR;
3677 			}
3678 			pool_opts.type = PF_POOL_ROUNDROBIN;
3679 		}
3680 		| STATICPORT	{
3681 			if (pool_opts.staticport) {
3682 				yyerror("static-port cannot be redefined");
3683 				YYERROR;
3684 			}
3685 			pool_opts.staticport = 1;
3686 		}
3687 		| STICKYADDRESS	{
3688 			if (filter_opts.marker & POM_STICKYADDRESS) {
3689 				yyerror("sticky-address cannot be redefined");
3690 				YYERROR;
3691 			}
3692 			pool_opts.marker |= POM_STICKYADDRESS;
3693 			pool_opts.opts |= PF_POOL_STICKYADDR;
3694 		}
3695 		;
3696 
3697 route_host	: STRING			{
3698 			$$ = calloc(1, sizeof(struct node_host));
3699 			if ($$ == NULL)
3700 				err(1, "route_host: calloc");
3701 			$$->ifname = $1;
3702 			set_ipmask($$, 128);
3703 			$$->next = NULL;
3704 			$$->tail = $$;
3705 		}
3706 		| '(' STRING host ')'		{
3707 			$$ = $3;
3708 			$$->ifname = $2;
3709 		}
3710 		;
3711 
3712 route_host_list	: route_host optnl			{ $$ = $1; }
3713 		| route_host_list comma route_host optnl {
3714 			if ($1->af == 0)
3715 				$1->af = $3->af;
3716 			if ($1->af != $3->af) {
3717 				yyerror("all pool addresses must be in the "
3718 				    "same address family");
3719 				YYERROR;
3720 			}
3721 			$1->tail->next = $3;
3722 			$1->tail = $3->tail;
3723 			$$ = $1;
3724 		}
3725 		;
3726 
3727 routespec	: route_host			{ $$ = $1; }
3728 		| '{' optnl route_host_list '}'	{ $$ = $3; }
3729 		;
3730 
3731 timeout_spec	: STRING NUMBER
3732 		{
3733 			if (check_rulestate(PFCTL_STATE_OPTION)) {
3734 				free($1);
3735 				YYERROR;
3736 			}
3737 			if ($2 < 0 || $2 > UINT_MAX) {
3738 				yyerror("only positive values permitted");
3739 				YYERROR;
3740 			}
3741 			if (pfctl_set_timeout(pf, $1, $2, 0) != 0) {
3742 				yyerror("unknown timeout %s", $1);
3743 				free($1);
3744 				YYERROR;
3745 			}
3746 			free($1);
3747 		}
3748 		;
3749 
3750 timeout_list	: timeout_list comma timeout_spec optnl
3751 		| timeout_spec optnl
3752 		;
3753 
3754 limit_spec	: STRING NUMBER
3755 		{
3756 			if (check_rulestate(PFCTL_STATE_OPTION)) {
3757 				free($1);
3758 				YYERROR;
3759 			}
3760 			if ($2 < 0 || $2 > UINT_MAX) {
3761 				yyerror("only positive values permitted");
3762 				YYERROR;
3763 			}
3764 			if (pfctl_set_limit(pf, $1, $2) != 0) {
3765 				yyerror("unable to set limit %s %u", $1, $2);
3766 				free($1);
3767 				YYERROR;
3768 			}
3769 			free($1);
3770 		}
3771 		;
3772 
3773 limit_list	: limit_list comma limit_spec optnl
3774 		| limit_spec optnl
3775 		;
3776 
3777 comma		: ','
3778 		| /* empty */
3779 		;
3780 
3781 yesno		: NO			{ $$ = 0; }
3782 		| STRING		{
3783 			if (!strcmp($1, "yes"))
3784 				$$ = 1;
3785 			else {
3786 				yyerror("invalid value '%s', expected 'yes' "
3787 				    "or 'no'", $1);
3788 				free($1);
3789 				YYERROR;
3790 			}
3791 			free($1);
3792 		}
3793 		;
3794 
3795 unaryop		: '='		{ $$ = PF_OP_EQ; }
3796 		| '!' '='	{ $$ = PF_OP_NE; }
3797 		| '<' '='	{ $$ = PF_OP_LE; }
3798 		| '<'		{ $$ = PF_OP_LT; }
3799 		| '>' '='	{ $$ = PF_OP_GE; }
3800 		| '>'		{ $$ = PF_OP_GT; }
3801 		;
3802 
3803 %%
3804 
3805 int
3806 yyerror(const char *fmt, ...)
3807 {
3808 	va_list		 ap;
3809 
3810 	file->errors++;
3811 	va_start(ap, fmt);
3812 	fprintf(stderr, "%s:%d: ", file->name, yylval.lineno);
3813 	vfprintf(stderr, fmt, ap);
3814 	fprintf(stderr, "\n");
3815 	va_end(ap);
3816 	return (0);
3817 }
3818 
3819 int
3820 disallow_table(struct node_host *h, const char *fmt)
3821 {
3822 	for (; h != NULL; h = h->next)
3823 		if (h->addr.type == PF_ADDR_TABLE) {
3824 			yyerror(fmt, h->addr.v.tblname);
3825 			return (1);
3826 		}
3827 	return (0);
3828 }
3829 
3830 int
3831 disallow_urpf_failed(struct node_host *h, const char *fmt)
3832 {
3833 	for (; h != NULL; h = h->next)
3834 		if (h->addr.type == PF_ADDR_URPFFAILED) {
3835 			yyerror(fmt);
3836 			return (1);
3837 		}
3838 	return (0);
3839 }
3840 
3841 int
3842 disallow_alias(struct node_host *h, const char *fmt)
3843 {
3844 	for (; h != NULL; h = h->next)
3845 		if (DYNIF_MULTIADDR(h->addr)) {
3846 			yyerror(fmt, h->addr.v.tblname);
3847 			return (1);
3848 		}
3849 	return (0);
3850 }
3851 
3852 int
3853 rule_consistent(struct pf_rule *r, int anchor_call)
3854 {
3855 	int	problems = 0;
3856 
3857 	if (r->proto != IPPROTO_TCP && r->proto != IPPROTO_UDP &&
3858 	    (r->src.port_op || r->dst.port_op)) {
3859 		yyerror("port only applies to tcp/udp");
3860 		problems++;
3861 	}
3862 	if (r->proto != IPPROTO_ICMP && r->proto != IPPROTO_ICMPV6 &&
3863 	    (r->type || r->code)) {
3864 		yyerror("icmp-type/code only applies to icmp");
3865 		problems++;
3866 	}
3867 	if (!r->af && (r->type || r->code)) {
3868 		yyerror("must indicate address family with icmp-type/code");
3869 		problems++;
3870 	}
3871 	if (r->overload_tblname[0] &&
3872 	    r->max_src_conn == 0 && r->max_src_conn_rate.seconds == 0) {
3873 		yyerror("'overload' requires 'max-src-conn' "
3874 		    "or 'max-src-conn-rate'");
3875 		problems++;
3876 	}
3877 	if ((r->proto == IPPROTO_ICMP && r->af == AF_INET6) ||
3878 	    (r->proto == IPPROTO_ICMPV6 && r->af == AF_INET)) {
3879 		yyerror("proto %s doesn't match address family %s",
3880 		    r->proto == IPPROTO_ICMP ? "icmp" : "icmp6",
3881 		    r->af == AF_INET ? "inet" : "inet6");
3882 		problems++;
3883 	}
3884 	if (r->allow_opts && r->action != PF_PASS) {
3885 		yyerror("allow-opts can only be specified for pass rules");
3886 		problems++;
3887 	}
3888 	if (r->rule_flag & PFRULE_FRAGMENT && (r->src.port_op ||
3889 	    r->dst.port_op || r->flagset || r->type || r->code)) {
3890 		yyerror("fragments can be filtered only on IP header fields");
3891 		problems++;
3892 	}
3893 	if (r->rule_flag & PFRULE_RETURNRST && r->proto != IPPROTO_TCP) {
3894 		yyerror("return-rst can only be applied to TCP rules");
3895 		problems++;
3896 	}
3897 	if (r->max_src_nodes && !(r->rule_flag & PFRULE_RULESRCTRACK)) {
3898 		yyerror("max-src-nodes requires 'source-track rule'");
3899 		problems++;
3900 	}
3901 	if (r->action != PF_PASS && r->keep_state) {
3902 		yyerror("keep state is great, but only for pass rules");
3903 		problems++;
3904 	}
3905 	if (r->rule_flag & PFRULE_STATESLOPPY &&
3906 	    (r->keep_state == PF_STATE_MODULATE ||
3907 	    r->keep_state == PF_STATE_SYNPROXY)) {
3908 		yyerror("sloppy state matching cannot be used with "
3909 		    "synproxy state or modulate state");
3910 		problems++;
3911 	}
3912 	if ((!TAILQ_EMPTY(&r->nat.list) ||
3913 	    (!r->rt && !TAILQ_EMPTY(&r->rdr.list)))  &&
3914 	    r->action != PF_MATCH && !r->keep_state) {
3915 		yyerror("nat-to and rdr-to require keep state");
3916 		problems++;
3917 	}
3918 	if (!TAILQ_EMPTY(&r->nat.list) && r->direction != PF_OUT) {
3919 		yyerror("nat-to can only be used outbound");
3920 		problems++;
3921 	}
3922 	if (!r->rt && !TAILQ_EMPTY(&r->rdr.list) && r->direction != PF_IN) {
3923 		yyerror("rdr-to can only be used inbound");
3924 		problems++;
3925 	}
3926 
3927 	/* match rules rules */
3928 	if (r->action == PF_MATCH) {
3929 		if (r->divert.port) {
3930 			yyerror("divert is not supported on match rules");
3931 			problems++;
3932 		}
3933 		if (r->divert_packet.port) {
3934 			yyerror("divert is not supported on match rules");
3935 			problems++;
3936 		}
3937 		if (r->rt) {
3938 			yyerror("route-to, reply-to, dup-to and fastroute "
3939 			   "must not be used on match rules");
3940 			problems++;
3941 		}
3942 	}
3943 	return (-problems);
3944 }
3945 
3946 int
3947 process_tabledef(char *name, struct table_opts *opts)
3948 {
3949 	struct pfr_buffer	 ab;
3950 	struct node_tinit	*ti;
3951 
3952 	bzero(&ab, sizeof(ab));
3953 	ab.pfrb_type = PFRB_ADDRS;
3954 	SIMPLEQ_FOREACH(ti, &opts->init_nodes, entries) {
3955 		if (ti->file)
3956 			if (pfr_buf_load(&ab, ti->file, 0, append_addr)) {
3957 				if (errno)
3958 					yyerror("cannot load \"%s\": %s",
3959 					    ti->file, strerror(errno));
3960 				else
3961 					yyerror("file \"%s\" contains bad data",
3962 					    ti->file);
3963 				goto _error;
3964 			}
3965 		if (ti->host)
3966 			if (append_addr_host(&ab, ti->host, 0, 0)) {
3967 				yyerror("cannot create address buffer: %s",
3968 				    strerror(errno));
3969 				goto _error;
3970 			}
3971 	}
3972 	if (pf->opts & PF_OPT_VERBOSE)
3973 		print_tabledef(name, opts->flags, opts->init_addr,
3974 		    &opts->init_nodes);
3975 	if (!(pf->opts & PF_OPT_NOACTION) &&
3976 	    pfctl_define_table(name, opts->flags, opts->init_addr,
3977 	    pf->anchor->name, &ab, pf->anchor->ruleset.tticket)) {
3978 		yyerror("cannot define table %s: %s", name,
3979 		    pfr_strerror(errno));
3980 		goto _error;
3981 	}
3982 	pf->tdirty = 1;
3983 	pfr_buf_clear(&ab);
3984 	return (0);
3985 _error:
3986 	pfr_buf_clear(&ab);
3987 	return (-1);
3988 }
3989 
3990 struct keywords {
3991 	const char	*k_name;
3992 	int		 k_val;
3993 };
3994 
3995 /* macro gore, but you should've seen the prior indentation nightmare... */
3996 
3997 #define FREE_LIST(T,r) \
3998 	do { \
3999 		T *p, *node = r; \
4000 		while (node != NULL) { \
4001 			p = node; \
4002 			node = node->next; \
4003 			free(p); \
4004 		} \
4005 	} while (0)
4006 
4007 #define LOOP_THROUGH(T,n,r,C) \
4008 	do { \
4009 		T *n; \
4010 		if (r == NULL) { \
4011 			r = calloc(1, sizeof(T)); \
4012 			if (r == NULL) \
4013 				err(1, "LOOP: calloc"); \
4014 			r->next = NULL; \
4015 		} \
4016 		n = r; \
4017 		while (n != NULL) { \
4018 			do { \
4019 				C; \
4020 			} while (0); \
4021 			n = n->next; \
4022 		} \
4023 	} while (0)
4024 
4025 void
4026 expand_label_str(char *label, size_t len, const char *srch, const char *repl)
4027 {
4028 	char *tmp;
4029 	char *p, *q;
4030 
4031 	if ((tmp = calloc(1, len)) == NULL)
4032 		err(1, "expand_label_str: calloc");
4033 	p = q = label;
4034 	while ((q = strstr(p, srch)) != NULL) {
4035 		*q = '\0';
4036 		if ((strlcat(tmp, p, len) >= len) ||
4037 		    (strlcat(tmp, repl, len) >= len))
4038 			errx(1, "expand_label: label too long");
4039 		q += strlen(srch);
4040 		p = q;
4041 	}
4042 	if (strlcat(tmp, p, len) >= len)
4043 		errx(1, "expand_label: label too long");
4044 	strlcpy(label, tmp, len);	/* always fits */
4045 	free(tmp);
4046 }
4047 
4048 void
4049 expand_label_if(const char *name, char *label, size_t len, const char *ifname)
4050 {
4051 	if (strstr(label, name) != NULL) {
4052 		if (!*ifname)
4053 			expand_label_str(label, len, name, "any");
4054 		else
4055 			expand_label_str(label, len, name, ifname);
4056 	}
4057 }
4058 
4059 void
4060 expand_label_addr(const char *name, char *label, size_t len, sa_family_t af,
4061     struct node_host *h)
4062 {
4063 	char tmp[64], tmp_not[66];
4064 
4065 	if (strstr(label, name) != NULL) {
4066 		switch (h->addr.type) {
4067 		case PF_ADDR_DYNIFTL:
4068 			snprintf(tmp, sizeof(tmp), "(%s)", h->addr.v.ifname);
4069 			break;
4070 		case PF_ADDR_TABLE:
4071 			snprintf(tmp, sizeof(tmp), "<%s>", h->addr.v.tblname);
4072 			break;
4073 		case PF_ADDR_NOROUTE:
4074 			snprintf(tmp, sizeof(tmp), "no-route");
4075 			break;
4076 		case PF_ADDR_URPFFAILED:
4077 			snprintf(tmp, sizeof(tmp), "urpf-failed");
4078 			break;
4079 		case PF_ADDR_ADDRMASK:
4080 			if (!af || (PF_AZERO(&h->addr.v.a.addr, af) &&
4081 			    PF_AZERO(&h->addr.v.a.mask, af)))
4082 				snprintf(tmp, sizeof(tmp), "any");
4083 			else {
4084 				char	a[48];
4085 				int	bits;
4086 
4087 				if (inet_ntop(af, &h->addr.v.a.addr, a,
4088 				    sizeof(a)) == NULL)
4089 					snprintf(tmp, sizeof(tmp), "?");
4090 				else {
4091 					bits = unmask(&h->addr.v.a.mask, af);
4092 					if ((af == AF_INET && bits < 32) ||
4093 					    (af == AF_INET6 && bits < 128))
4094 						snprintf(tmp, sizeof(tmp),
4095 						    "%s/%d", a, bits);
4096 					else
4097 						snprintf(tmp, sizeof(tmp),
4098 						    "%s", a);
4099 				}
4100 			}
4101 			break;
4102 		default:
4103 			snprintf(tmp, sizeof(tmp), "?");
4104 			break;
4105 		}
4106 
4107 		if (h->not) {
4108 			snprintf(tmp_not, sizeof(tmp_not), "! %s", tmp);
4109 			expand_label_str(label, len, name, tmp_not);
4110 		} else
4111 			expand_label_str(label, len, name, tmp);
4112 	}
4113 }
4114 
4115 void
4116 expand_label_port(const char *name, char *label, size_t len,
4117     struct node_port *port)
4118 {
4119 	char	 a1[6], a2[6], op[13] = "";
4120 
4121 	if (strstr(label, name) != NULL) {
4122 		snprintf(a1, sizeof(a1), "%u", ntohs(port->port[0]));
4123 		snprintf(a2, sizeof(a2), "%u", ntohs(port->port[1]));
4124 		if (!port->op)
4125 			;
4126 		else if (port->op == PF_OP_IRG)
4127 			snprintf(op, sizeof(op), "%s><%s", a1, a2);
4128 		else if (port->op == PF_OP_XRG)
4129 			snprintf(op, sizeof(op), "%s<>%s", a1, a2);
4130 		else if (port->op == PF_OP_EQ)
4131 			snprintf(op, sizeof(op), "%s", a1);
4132 		else if (port->op == PF_OP_NE)
4133 			snprintf(op, sizeof(op), "!=%s", a1);
4134 		else if (port->op == PF_OP_LT)
4135 			snprintf(op, sizeof(op), "<%s", a1);
4136 		else if (port->op == PF_OP_LE)
4137 			snprintf(op, sizeof(op), "<=%s", a1);
4138 		else if (port->op == PF_OP_GT)
4139 			snprintf(op, sizeof(op), ">%s", a1);
4140 		else if (port->op == PF_OP_GE)
4141 			snprintf(op, sizeof(op), ">=%s", a1);
4142 		expand_label_str(label, len, name, op);
4143 	}
4144 }
4145 
4146 void
4147 expand_label_proto(const char *name, char *label, size_t len, u_int8_t proto)
4148 {
4149 	struct protoent *pe;
4150 	char n[4];
4151 
4152 	if (strstr(label, name) != NULL) {
4153 		pe = getprotobynumber(proto);
4154 		if (pe != NULL)
4155 			expand_label_str(label, len, name, pe->p_name);
4156 		else {
4157 			snprintf(n, sizeof(n), "%u", proto);
4158 			expand_label_str(label, len, name, n);
4159 		}
4160 	}
4161 }
4162 
4163 void
4164 expand_label_nr(const char *name, char *label, size_t len)
4165 {
4166 	char n[11];
4167 
4168 	if (strstr(label, name) != NULL) {
4169 		snprintf(n, sizeof(n), "%u", pf->anchor->match);
4170 		expand_label_str(label, len, name, n);
4171 	}
4172 }
4173 
4174 void
4175 expand_label(char *label, size_t len, const char *ifname, sa_family_t af,
4176     struct node_host *src_host, struct node_port *src_port,
4177     struct node_host *dst_host, struct node_port *dst_port,
4178     u_int8_t proto)
4179 {
4180 	expand_label_if("$if", label, len, ifname);
4181 	expand_label_addr("$srcaddr", label, len, af, src_host);
4182 	expand_label_addr("$dstaddr", label, len, af, dst_host);
4183 	expand_label_port("$srcport", label, len, src_port);
4184 	expand_label_port("$dstport", label, len, dst_port);
4185 	expand_label_proto("$proto", label, len, proto);
4186 	expand_label_nr("$nr", label, len);
4187 }
4188 
4189 int
4190 expand_altq(struct pf_altq *a, struct node_if *interfaces,
4191     struct node_queue *nqueues, struct node_queue_bw bwspec,
4192     struct node_queue_opt *opts)
4193 {
4194 	struct pf_altq		 pa, pb;
4195 	char			 qname[PF_QNAME_SIZE];
4196 	struct node_queue	*n;
4197 	struct node_queue_bw	 bw;
4198 	int			 errs = 0;
4199 
4200 	if ((pf->loadopt & PFCTL_FLAG_ALTQ) == 0) {
4201 		FREE_LIST(struct node_if, interfaces);
4202 		FREE_LIST(struct node_queue, nqueues);
4203 		return (0);
4204 	}
4205 
4206 	LOOP_THROUGH(struct node_if, interface, interfaces,
4207 		memcpy(&pa, a, sizeof(struct pf_altq));
4208 		if (strlcpy(pa.ifname, interface->ifname,
4209 		    sizeof(pa.ifname)) >= sizeof(pa.ifname))
4210 			errx(1, "expand_altq: strlcpy");
4211 
4212 		if (interface->not) {
4213 			yyerror("altq on ! <interface> is not supported");
4214 			errs++;
4215 		} else {
4216 			if (eval_pfaltq(pf, &pa, &bwspec, opts))
4217 				errs++;
4218 			else
4219 				if (pfctl_add_altq(pf, &pa))
4220 					errs++;
4221 
4222 			if (pf->opts & PF_OPT_VERBOSE) {
4223 				print_altq(&pf->paltq->altq, 0,
4224 				    &bwspec, opts);
4225 				if (nqueues && nqueues->tail) {
4226 					printf("queue { ");
4227 					LOOP_THROUGH(struct node_queue, queue,
4228 					    nqueues,
4229 						printf("%s ",
4230 						    queue->queue);
4231 					);
4232 					printf("}");
4233 				}
4234 				printf("\n");
4235 			}
4236 
4237 			if (pa.scheduler == ALTQT_CBQ ||
4238 			    pa.scheduler == ALTQT_HFSC) {
4239 				/* now create a root queue */
4240 				memset(&pb, 0, sizeof(struct pf_altq));
4241 				if (strlcpy(qname, "root_", sizeof(qname)) >=
4242 				    sizeof(qname))
4243 					errx(1, "expand_altq: strlcpy");
4244 				if (strlcat(qname, interface->ifname,
4245 				    sizeof(qname)) >= sizeof(qname))
4246 					errx(1, "expand_altq: strlcat");
4247 				if (strlcpy(pb.qname, qname,
4248 				    sizeof(pb.qname)) >= sizeof(pb.qname))
4249 					errx(1, "expand_altq: strlcpy");
4250 				if (strlcpy(pb.ifname, interface->ifname,
4251 				    sizeof(pb.ifname)) >= sizeof(pb.ifname))
4252 					errx(1, "expand_altq: strlcpy");
4253 				pb.qlimit = pa.qlimit;
4254 				pb.scheduler = pa.scheduler;
4255 				bw.bw_absolute = pa.ifbandwidth;
4256 				bw.bw_percent = 0;
4257 				if (eval_pfqueue(pf, &pb, &bw, opts))
4258 					errs++;
4259 				else
4260 					if (pfctl_add_altq(pf, &pb))
4261 						errs++;
4262 			}
4263 
4264 			LOOP_THROUGH(struct node_queue, queue, nqueues,
4265 				n = calloc(1, sizeof(struct node_queue));
4266 				if (n == NULL)
4267 					err(1, "expand_altq: calloc");
4268 				if (pa.scheduler == ALTQT_CBQ ||
4269 				    pa.scheduler == ALTQT_HFSC)
4270 					if (strlcpy(n->parent, qname,
4271 					    sizeof(n->parent)) >=
4272 					    sizeof(n->parent))
4273 						errx(1, "expand_altq: strlcpy");
4274 				if (strlcpy(n->queue, queue->queue,
4275 				    sizeof(n->queue)) >= sizeof(n->queue))
4276 					errx(1, "expand_altq: strlcpy");
4277 				if (strlcpy(n->ifname, interface->ifname,
4278 				    sizeof(n->ifname)) >= sizeof(n->ifname))
4279 					errx(1, "expand_altq: strlcpy");
4280 				n->scheduler = pa.scheduler;
4281 				n->next = NULL;
4282 				n->tail = n;
4283 				if (queues == NULL)
4284 					queues = n;
4285 				else {
4286 					queues->tail->next = n;
4287 					queues->tail = n;
4288 				}
4289 			);
4290 		}
4291 	);
4292 	FREE_LIST(struct node_if, interfaces);
4293 	FREE_LIST(struct node_queue, nqueues);
4294 
4295 	return (errs);
4296 }
4297 
4298 int
4299 expand_queue(struct pf_altq *a, struct node_if *interfaces,
4300     struct node_queue *nqueues, struct node_queue_bw bwspec,
4301     struct node_queue_opt *opts)
4302 {
4303 	struct node_queue	*n, *nq;
4304 	struct pf_altq		 pa;
4305 	u_int8_t		 found = 0;
4306 	u_int8_t		 errs = 0;
4307 
4308 	if ((pf->loadopt & PFCTL_FLAG_ALTQ) == 0) {
4309 		FREE_LIST(struct node_queue, nqueues);
4310 		return (0);
4311 	}
4312 
4313 	if (queues == NULL) {
4314 		yyerror("queue %s has no parent", a->qname);
4315 		FREE_LIST(struct node_queue, nqueues);
4316 		return (1);
4317 	}
4318 
4319 	LOOP_THROUGH(struct node_if, interface, interfaces,
4320 		LOOP_THROUGH(struct node_queue, tqueue, queues,
4321 			if (!strncmp(a->qname, tqueue->queue, PF_QNAME_SIZE) &&
4322 			    (interface->ifname[0] == 0 ||
4323 			    (!interface->not && !strncmp(interface->ifname,
4324 			    tqueue->ifname, IFNAMSIZ)) ||
4325 			    (interface->not && strncmp(interface->ifname,
4326 			    tqueue->ifname, IFNAMSIZ)))) {
4327 				/* found ourself in queues */
4328 				found++;
4329 
4330 				memcpy(&pa, a, sizeof(struct pf_altq));
4331 
4332 				if (pa.scheduler != ALTQT_NONE &&
4333 				    pa.scheduler != tqueue->scheduler) {
4334 					yyerror("exactly one scheduler type "
4335 					    "per interface allowed");
4336 					return (1);
4337 				}
4338 				pa.scheduler = tqueue->scheduler;
4339 
4340 				/* scheduler dependent error checking */
4341 				switch (pa.scheduler) {
4342 				case ALTQT_PRIQ:
4343 					if (nqueues != NULL) {
4344 						yyerror("priq queues cannot "
4345 						    "have child queues");
4346 						return (1);
4347 					}
4348 					if (bwspec.bw_absolute > 0 ||
4349 					    bwspec.bw_percent < 100) {
4350 						yyerror("priq doesn't take "
4351 						    "bandwidth");
4352 						return (1);
4353 					}
4354 					break;
4355 				default:
4356 					break;
4357 				}
4358 
4359 				if (strlcpy(pa.ifname, tqueue->ifname,
4360 				    sizeof(pa.ifname)) >= sizeof(pa.ifname))
4361 					errx(1, "expand_queue: strlcpy");
4362 				if (strlcpy(pa.parent, tqueue->parent,
4363 				    sizeof(pa.parent)) >= sizeof(pa.parent))
4364 					errx(1, "expand_queue: strlcpy");
4365 
4366 				if (eval_pfqueue(pf, &pa, &bwspec, opts))
4367 					errs++;
4368 				else
4369 					if (pfctl_add_altq(pf, &pa))
4370 						errs++;
4371 
4372 				for (nq = nqueues; nq != NULL; nq = nq->next) {
4373 					if (!strcmp(a->qname, nq->queue)) {
4374 						yyerror("queue cannot have "
4375 						    "itself as child");
4376 						errs++;
4377 						continue;
4378 					}
4379 					n = calloc(1,
4380 					    sizeof(struct node_queue));
4381 					if (n == NULL)
4382 						err(1, "expand_queue: calloc");
4383 					if (strlcpy(n->parent, a->qname,
4384 					    sizeof(n->parent)) >=
4385 					    sizeof(n->parent))
4386 						errx(1, "expand_queue strlcpy");
4387 					if (strlcpy(n->queue, nq->queue,
4388 					    sizeof(n->queue)) >=
4389 					    sizeof(n->queue))
4390 						errx(1, "expand_queue strlcpy");
4391 					if (strlcpy(n->ifname, tqueue->ifname,
4392 					    sizeof(n->ifname)) >=
4393 					    sizeof(n->ifname))
4394 						errx(1, "expand_queue strlcpy");
4395 					n->scheduler = tqueue->scheduler;
4396 					n->next = NULL;
4397 					n->tail = n;
4398 					if (queues == NULL)
4399 						queues = n;
4400 					else {
4401 						queues->tail->next = n;
4402 						queues->tail = n;
4403 					}
4404 				}
4405 				if ((pf->opts & PF_OPT_VERBOSE) && (
4406 				    (found == 1 && interface->ifname[0] == 0) ||
4407 				    (found > 0 && interface->ifname[0] != 0))) {
4408 					print_queue(&pf->paltq->altq, 0,
4409 					    &bwspec, interface->ifname[0] != 0,
4410 					    opts);
4411 					if (nqueues && nqueues->tail) {
4412 						printf("{ ");
4413 						LOOP_THROUGH(struct node_queue,
4414 						    queue, nqueues,
4415 							printf("%s ",
4416 							    queue->queue);
4417 						);
4418 						printf("}");
4419 					}
4420 					printf("\n");
4421 				}
4422 			}
4423 		);
4424 	);
4425 
4426 	FREE_LIST(struct node_queue, nqueues);
4427 	FREE_LIST(struct node_if, interfaces);
4428 
4429 	if (!found) {
4430 		yyerror("queue %s has no parent", a->qname);
4431 		errs++;
4432 	}
4433 
4434 	if (errs)
4435 		return (1);
4436 	else
4437 		return (0);
4438 }
4439 
4440 int
4441 apply_redirspec(struct pf_pool *rpool, struct pf_rule *r, struct redirspec *rs,
4442     int isrdr, struct node_port *np)
4443 {
4444 	struct node_host	*h;
4445 	struct pf_pooladdr	*pa;
4446 
4447 	if (!rs || !rs->rdr)
4448 		return (0);
4449 
4450 	if (!r->af && ! rs->rdr->host->ifindex)
4451 		r->af = rs->rdr->host->af;
4452 
4453 	remove_invalid_hosts(&rs->rdr->host, &r->af);
4454 	if (invalid_redirect(rs->rdr->host, r->af))
4455 		return (1);
4456 	if (check_netmask(rs->rdr->host, r->af))
4457 		return (1);
4458 
4459 	rpool->proxy_port[0] = ntohs(rs->rdr->rport.a);
4460 
4461 	if (isrdr) {
4462 		if (!rs->rdr->rport.b && rs->rdr->rport.t && np->port != NULL) {
4463 			rpool->proxy_port[1] = ntohs(rs->rdr->rport.a) +
4464 			    (ntohs(np->port[1]) - ntohs(np->port[0]));
4465 		} else
4466 			rpool->proxy_port[1] = ntohs(rs->rdr->rport.b);
4467 	} else {
4468 		rpool->proxy_port[1] = ntohs(rs->rdr->rport.b);
4469 		if (!rpool->proxy_port[0] && !rpool->proxy_port[1]) {
4470 			rpool->proxy_port[0] = PF_NAT_PROXY_PORT_LOW;
4471 			rpool->proxy_port[1] = PF_NAT_PROXY_PORT_HIGH;
4472 		} else if (!rpool->proxy_port[1])
4473 			rpool->proxy_port[1] = rpool->proxy_port[0];
4474 	}
4475 
4476 	rpool->opts = rs->pool_opts.type;
4477 	if ((rpool->opts & PF_POOL_TYPEMASK) == PF_POOL_NONE &&
4478 	    (rs->rdr->host->next != NULL ||
4479 	    rs->rdr->host->addr.type == PF_ADDR_TABLE ||
4480 	    DYNIF_MULTIADDR(rs->rdr->host->addr)))
4481 		rpool->opts = PF_POOL_ROUNDROBIN;
4482 	if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN &&
4483 	    disallow_table(rs->rdr->host, "tables are only supported in "
4484 	    "round-robin redirection pools"))
4485 		return (1);
4486 	if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN &&
4487 	    disallow_alias(rs->rdr->host, "interface (%s) is only supported in "
4488 	    "round-robin redirection pools"))
4489 		return (1);
4490 	if (rs->rdr->host->next != NULL) {
4491 		if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN) {
4492 			yyerror("only round-robin valid for multiple "
4493 			    "redirection addresses");
4494 			return (1);
4495 		}
4496 	}
4497 
4498 	if (rs->pool_opts.key != NULL)
4499 		memcpy(&rpool->key, rs->pool_opts.key,
4500 		    sizeof(struct pf_poolhashkey));
4501 
4502 	if (rs->pool_opts.opts)
4503 		rpool->opts |= rs->pool_opts.opts;
4504 
4505 	if (rs->pool_opts.staticport) {
4506 		if (isrdr) {
4507 			yyerror("the 'static-port' option is only valid with "
4508 			    "nat rules");
4509 			return (1);
4510 		}
4511 		if (rpool->proxy_port[0] != PF_NAT_PROXY_PORT_LOW &&
4512 		    rpool->proxy_port[1] != PF_NAT_PROXY_PORT_HIGH) {
4513 			yyerror("the 'static-port' option can't be used when "
4514 			    "specifying a port range");
4515 			return (1);
4516 		}
4517 		rpool->proxy_port[0] = 0;
4518 		rpool->proxy_port[1] = 0;
4519 	}
4520 
4521 	TAILQ_INIT(&rpool->list);
4522 	for (h = rs->rdr->host; h != NULL; h = h->next) {
4523 		if ((pa = calloc(1, sizeof(struct pf_pooladdr))) == NULL)
4524 			err(1, "expand_rule: calloc");
4525 		pa->addr = h->addr;
4526 		if (h->ifname != NULL) {
4527 			if (strlcpy(pa->ifname, h->ifname, sizeof pa->ifname) >=
4528 			    sizeof(pa->ifname))
4529 				errx(1, "expand_rule: strlcpy");
4530 		} else
4531 			pa->ifname[0] = 0;
4532 		TAILQ_INSERT_TAIL(&rpool->list, pa, entries);
4533 	}
4534 
4535 	return (0);
4536 }
4537 
4538 
4539 void
4540 expand_rule(struct pf_rule *r, int keeprule, struct node_if *interfaces,
4541     struct redirspec *nat, struct redirspec *rdr,
4542     struct node_proto *protos, struct node_os *src_oses,
4543     struct node_host *src_hosts, struct node_port *src_ports,
4544     struct node_host *dst_hosts, struct node_port *dst_ports,
4545     struct node_uid *uids, struct node_gid *gids, struct node_icmp *icmp_types,
4546     const char *anchor_call)
4547 {
4548 	sa_family_t		 af = r->af;
4549 	int			 added = 0, error = 0;
4550 	char			 ifname[IF_NAMESIZE];
4551 	char			 label[PF_RULE_LABEL_SIZE];
4552 	char			 tagname[PF_TAG_NAME_SIZE];
4553 	char			 match_tagname[PF_TAG_NAME_SIZE];
4554 	u_int8_t		 flags, flagset, keep_state;
4555 	struct node_host	*srch, *dsth;
4556 	struct redirspec	 binat;
4557 	struct pf_rule		 rb;
4558 	int			 dir = r->direction;
4559 
4560 	if (strlcpy(label, r->label, sizeof(label)) >= sizeof(label))
4561 		errx(1, "expand_rule: strlcpy");
4562 	if (strlcpy(tagname, r->tagname, sizeof(tagname)) >= sizeof(tagname))
4563 		errx(1, "expand_rule: strlcpy");
4564 	if (strlcpy(match_tagname, r->match_tagname, sizeof(match_tagname)) >=
4565 	    sizeof(match_tagname))
4566 		errx(1, "expand_rule: strlcpy");
4567 	flags = r->flags;
4568 	flagset = r->flagset;
4569 	keep_state = r->keep_state;
4570 
4571 	LOOP_THROUGH(struct node_if, interface, interfaces,
4572 	LOOP_THROUGH(struct node_proto, proto, protos,
4573 	LOOP_THROUGH(struct node_icmp, icmp_type, icmp_types,
4574 	LOOP_THROUGH(struct node_host, src_host, src_hosts,
4575 	LOOP_THROUGH(struct node_port, src_port, src_ports,
4576 	LOOP_THROUGH(struct node_os, src_os, src_oses,
4577 	LOOP_THROUGH(struct node_host, dst_host, dst_hosts,
4578 	LOOP_THROUGH(struct node_port, dst_port, dst_ports,
4579 	LOOP_THROUGH(struct node_uid, uid, uids,
4580 	LOOP_THROUGH(struct node_gid, gid, gids,
4581 
4582 		r->af = af;
4583 		/* for link-local IPv6 address, interface must match up */
4584 		if ((r->af && src_host->af && r->af != src_host->af) ||
4585 		    (r->af && dst_host->af && r->af != dst_host->af) ||
4586 		    (src_host->af && dst_host->af &&
4587 		    src_host->af != dst_host->af) ||
4588 		    (src_host->ifindex && dst_host->ifindex &&
4589 		    src_host->ifindex != dst_host->ifindex) ||
4590 		    (src_host->ifindex && *interface->ifname &&
4591 		    src_host->ifindex != if_nametoindex(interface->ifname)) ||
4592 		    (dst_host->ifindex && *interface->ifname &&
4593 		    dst_host->ifindex != if_nametoindex(interface->ifname)))
4594 			continue;
4595 		if (!r->af && src_host->af)
4596 			r->af = src_host->af;
4597 		else if (!r->af && dst_host->af)
4598 			r->af = dst_host->af;
4599 
4600 		if (*interface->ifname)
4601 			strlcpy(r->ifname, interface->ifname,
4602 			    sizeof(r->ifname));
4603 		else if (if_indextoname(src_host->ifindex, ifname))
4604 			strlcpy(r->ifname, ifname, sizeof(r->ifname));
4605 		else if (if_indextoname(dst_host->ifindex, ifname))
4606 			strlcpy(r->ifname, ifname, sizeof(r->ifname));
4607 		else
4608 			memset(r->ifname, '\0', sizeof(r->ifname));
4609 
4610 		if (strlcpy(r->label, label, sizeof(r->label)) >=
4611 		    sizeof(r->label))
4612 			errx(1, "expand_rule: strlcpy");
4613 		if (strlcpy(r->tagname, tagname, sizeof(r->tagname)) >=
4614 		    sizeof(r->tagname))
4615 			errx(1, "expand_rule: strlcpy");
4616 		if (strlcpy(r->match_tagname, match_tagname,
4617 		    sizeof(r->match_tagname)) >= sizeof(r->match_tagname))
4618 			errx(1, "expand_rule: strlcpy");
4619 		expand_label(r->label, PF_RULE_LABEL_SIZE, r->ifname, r->af,
4620 		    src_host, src_port, dst_host, dst_port, proto->proto);
4621 		expand_label(r->tagname, PF_TAG_NAME_SIZE, r->ifname, r->af,
4622 		    src_host, src_port, dst_host, dst_port, proto->proto);
4623 		expand_label(r->match_tagname, PF_TAG_NAME_SIZE, r->ifname,
4624 		    r->af, src_host, src_port, dst_host, dst_port,
4625 		    proto->proto);
4626 
4627 		error += check_netmask(src_host, r->af);
4628 		error += check_netmask(dst_host, r->af);
4629 
4630 		r->ifnot = interface->not;
4631 		r->proto = proto->proto;
4632 		r->src.addr = src_host->addr;
4633 		r->src.neg = src_host->not;
4634 		r->src.port[0] = src_port->port[0];
4635 		r->src.port[1] = src_port->port[1];
4636 		r->src.port_op = src_port->op;
4637 		r->dst.addr = dst_host->addr;
4638 		r->dst.neg = dst_host->not;
4639 		r->dst.port[0] = dst_port->port[0];
4640 		r->dst.port[1] = dst_port->port[1];
4641 		r->dst.port_op = dst_port->op;
4642 		r->uid.op = uid->op;
4643 		r->uid.uid[0] = uid->uid[0];
4644 		r->uid.uid[1] = uid->uid[1];
4645 		r->gid.op = gid->op;
4646 		r->gid.gid[0] = gid->gid[0];
4647 		r->gid.gid[1] = gid->gid[1];
4648 		r->type = icmp_type->type;
4649 		r->code = icmp_type->code;
4650 
4651 		if ((keep_state == PF_STATE_MODULATE ||
4652 		    keep_state == PF_STATE_SYNPROXY) &&
4653 		    r->proto && r->proto != IPPROTO_TCP)
4654 			r->keep_state = PF_STATE_NORMAL;
4655 		else
4656 			r->keep_state = keep_state;
4657 
4658 		if (r->proto && r->proto != IPPROTO_TCP) {
4659 			r->flags = 0;
4660 			r->flagset = 0;
4661 		} else {
4662 			r->flags = flags;
4663 			r->flagset = flagset;
4664 		}
4665 		if (icmp_type->proto && r->proto != icmp_type->proto) {
4666 			yyerror("icmp-type mismatch");
4667 			error++;
4668 		}
4669 
4670 		if (src_os && src_os->os) {
4671 			r->os_fingerprint = pfctl_get_fingerprint(src_os->os);
4672 			if ((pf->opts & PF_OPT_VERBOSE2) &&
4673 			    r->os_fingerprint == PF_OSFP_NOMATCH)
4674 				fprintf(stderr,
4675 				    "warning: unknown '%s' OS fingerprint\n",
4676 				    src_os->os);
4677 		} else {
4678 			r->os_fingerprint = PF_OSFP_ANY;
4679 		}
4680 
4681 		if (nat && nat->rdr && nat->binat) {
4682 			if (disallow_table(src_host, "invalid use of table "
4683 			    "<%s> as the source address of a binat-to rule") ||
4684 			    disallow_alias(src_host, "invalid use of interface "
4685 			    "(%s) as the source address of a binat-to rule")) {
4686 				error++;
4687 			} else if (src_host->af == AF_UNSPEC) {
4688 				yyerror("binat-to requires a specified "
4689 				    "source and redirect address");
4690 				error++;
4691 			}
4692 			if (disallow_table(src_host, "invalid use of table "
4693 			    "<%s> as the redirect address of a "
4694 			    "binat-to rule") ||
4695 			    disallow_alias(dst_host, "invalid use of interface "
4696 			    "(%s) as the redirect address of a "
4697 			    "binat-to rule") ||
4698 			    disallow_urpf_failed(dst_host, "\"urpf-failed\" "
4699 			    "is not permitted as a binat-to destination")) {
4700 				error++;
4701 			}
4702 			if (r->direction != PF_INOUT) {
4703 				yyerror("binat-to cannot be specified "
4704 				    "with a direction");
4705 				error++;
4706 			}
4707 
4708 			/* first specify outbound NAT rule */
4709 			r->direction = PF_OUT;
4710 		}
4711 
4712 		error += apply_redirspec(&r->nat, r, nat, 0, dst_port);
4713 		error += apply_redirspec(&r->rdr, r, rdr, 1, dst_port);
4714 
4715 		if (rule_consistent(r, anchor_call[0]) < 0 || error)
4716 			yyerror("skipping rule due to errors");
4717 		else {
4718 			r->nr = pf->astack[pf->asd]->match++;
4719 			pfctl_add_rule(pf, r, anchor_call);
4720 			added++;
4721 		}
4722 		r->direction = dir;
4723 
4724 		/* Generate binat's matching inbound rule */
4725 		if (!error && nat && nat->rdr && nat->binat) {
4726 			bcopy(r, &rb, sizeof(rb));
4727 
4728 			/* now specify inbound rdr rule */
4729 			rb.direction = PF_IN;
4730 
4731 			if ((srch = calloc(1, sizeof(*srch))) == NULL)
4732 				err(1, "expand_rule: calloc");
4733 			bcopy(src_host, srch, sizeof(*srch));
4734 			srch->ifname = NULL;
4735 			srch->next = NULL;
4736 			srch->tail = NULL;
4737 
4738 			if ((dsth = calloc(1, sizeof(*dsth))) == NULL)
4739 				err(1, "expand_rule: calloc");
4740 			bcopy(nat->rdr->host, dsth, sizeof(*dsth));
4741 			dsth->ifname = NULL;
4742 			dsth->next = NULL;
4743 			dsth->tail = NULL;
4744 
4745 			if ((binat.rdr =
4746 			    calloc(1, sizeof(*binat.rdr))) == NULL)
4747 				err(1, "expand_rule: calloc");
4748 			bcopy(nat->rdr, binat.rdr, sizeof(*binat.rdr));
4749 			bcopy(&nat->pool_opts, &binat.pool_opts,
4750 			    sizeof(binat.pool_opts));
4751 			binat.pool_opts.staticport = 0;
4752 			binat.rdr->host = srch;
4753 
4754 			expand_rule(&rb, 1, interface, NULL, &binat, proto,
4755 			    src_os, dst_host, dst_port, dsth, src_port,
4756 			    uid, gid, icmp_type, anchor_call);
4757 		}
4758 
4759 	))))))))));
4760 
4761 	if (!keeprule) {
4762 		FREE_LIST(struct node_if, interfaces);
4763 		FREE_LIST(struct node_proto, protos);
4764 		FREE_LIST(struct node_host, src_hosts);
4765 		FREE_LIST(struct node_port, src_ports);
4766 		FREE_LIST(struct node_os, src_oses);
4767 		FREE_LIST(struct node_host, dst_hosts);
4768 		FREE_LIST(struct node_port, dst_ports);
4769 		FREE_LIST(struct node_uid, uids);
4770 		FREE_LIST(struct node_gid, gids);
4771 		FREE_LIST(struct node_icmp, icmp_types);
4772 		if (nat && nat->rdr)
4773 			FREE_LIST(struct node_host, nat->rdr->host);
4774 		if (rdr && rdr->rdr)
4775 			FREE_LIST(struct node_host, rdr->rdr->host);
4776 	}
4777 
4778 	if (!added)
4779 		yyerror("rule expands to no valid combination");
4780 }
4781 
4782 int
4783 expand_skip_interface(struct node_if *interfaces)
4784 {
4785 	int	errs = 0;
4786 
4787 	if (!interfaces || (!interfaces->next && !interfaces->not &&
4788 	    !strcmp(interfaces->ifname, "none"))) {
4789 		if (pf->opts & PF_OPT_VERBOSE)
4790 			printf("set skip on none\n");
4791 		errs = pfctl_set_interface_flags(pf, "", PFI_IFLAG_SKIP, 0);
4792 		return (errs);
4793 	}
4794 
4795 	if (pf->opts & PF_OPT_VERBOSE)
4796 		printf("set skip on {");
4797 	LOOP_THROUGH(struct node_if, interface, interfaces,
4798 		if (pf->opts & PF_OPT_VERBOSE)
4799 			printf(" %s", interface->ifname);
4800 		if (interface->not) {
4801 			yyerror("skip on ! <interface> is not supported");
4802 			errs++;
4803 		} else
4804 			errs += pfctl_set_interface_flags(pf,
4805 			    interface->ifname, PFI_IFLAG_SKIP, 1);
4806 	);
4807 	if (pf->opts & PF_OPT_VERBOSE)
4808 		printf(" }\n");
4809 
4810 	FREE_LIST(struct node_if, interfaces);
4811 
4812 	if (errs)
4813 		return (1);
4814 	else
4815 		return (0);
4816 }
4817 
4818 #undef FREE_LIST
4819 #undef LOOP_THROUGH
4820 
4821 int
4822 check_rulestate(int desired_state)
4823 {
4824 	if (require_order && (rulestate > desired_state)) {
4825 		yyerror("Rules must be in order: options, normalization, "
4826 		    "queueing, translation, filtering");
4827 		return (1);
4828 	}
4829 	rulestate = desired_state;
4830 	return (0);
4831 }
4832 
4833 int
4834 kw_cmp(const void *k, const void *e)
4835 {
4836 	return (strcmp(k, ((const struct keywords *)e)->k_name));
4837 }
4838 
4839 int
4840 lookup(char *s)
4841 {
4842 	/* this has to be sorted always */
4843 	static const struct keywords keywords[] = {
4844 		{ "all",		ALL},
4845 		{ "allow-opts",		ALLOWOPTS},
4846 		{ "altq",		ALTQ},
4847 		{ "anchor",		ANCHOR},
4848 		{ "antispoof",		ANTISPOOF},
4849 		{ "any",		ANY},
4850 		{ "bandwidth",		BANDWIDTH},
4851 		{ "binat-to",		BINATTO},
4852 		{ "bitmask",		BITMASK},
4853 		{ "block",		BLOCK},
4854 		{ "block-policy",	BLOCKPOLICY},
4855 		{ "cbq",		CBQ},
4856 		{ "code",		CODE},
4857 		{ "crop",		FRAGCROP},
4858 		{ "debug",		DEBUG},
4859 		{ "divert-packet",	DIVERTPACKET},
4860 		{ "divert-reply",	DIVERTREPLY},
4861 		{ "divert-to",		DIVERTTO},
4862 		{ "drop",		DROP},
4863 		{ "drop-ovl",		FRAGDROP},
4864 		{ "dup-to",		DUPTO},
4865 		{ "fastroute",		FASTROUTE},
4866 		{ "file",		FILENAME},
4867 		{ "fingerprints",	FINGERPRINTS},
4868 		{ "flags",		FLAGS},
4869 		{ "floating",		FLOATING},
4870 		{ "flush",		FLUSH},
4871 		{ "for",		FOR},
4872 		{ "fragment",		FRAGMENT},
4873 		{ "from",		FROM},
4874 		{ "global",		GLOBAL},
4875 		{ "group",		GROUP},
4876 		{ "hfsc",		HFSC},
4877 		{ "hostid",		HOSTID},
4878 		{ "icmp-type",		ICMPTYPE},
4879 		{ "icmp6-type",		ICMP6TYPE},
4880 		{ "if-bound",		IFBOUND},
4881 		{ "in",			IN},
4882 		{ "include",		INCLUDE},
4883 		{ "inet",		INET},
4884 		{ "inet6",		INET6},
4885 		{ "keep",		KEEP},
4886 		{ "label",		LABEL},
4887 		{ "limit",		LIMIT},
4888 		{ "linkshare",		LINKSHARE},
4889 		{ "load",		LOAD},
4890 		{ "log",		LOG},
4891 		{ "loginterface",	LOGINTERFACE},
4892 		{ "match",		MATCH},
4893 		{ "max",		MAXIMUM},
4894 		{ "max-mss",		MAXMSS},
4895 		{ "max-src-conn",	MAXSRCCONN},
4896 		{ "max-src-conn-rate",	MAXSRCCONNRATE},
4897 		{ "max-src-nodes",	MAXSRCNODES},
4898 		{ "max-src-states",	MAXSRCSTATES},
4899 		{ "min-ttl",		MINTTL},
4900 		{ "modulate",		MODULATE},
4901 		{ "nat",		NAT},
4902 		{ "nat-anchor",		NATANCHOR},
4903 		{ "nat-to",		NATTO},
4904 		{ "no",			NO},
4905 		{ "no-df",		NODF},
4906 		{ "no-route",		NOROUTE},
4907 		{ "no-sync",		NOSYNC},
4908 		{ "on",			ON},
4909 		{ "optimization",	OPTIMIZATION},
4910 		{ "os",			OS},
4911 		{ "out",		OUT},
4912 		{ "overload",		OVERLOAD},
4913 		{ "pass",		PASS},
4914 		{ "pflow",		PFLOW},
4915 		{ "port",		PORT},
4916 		{ "priority",		PRIORITY},
4917 		{ "priq",		PRIQ},
4918 		{ "probability",	PROBABILITY},
4919 		{ "proto",		PROTO},
4920 		{ "qlimit",		QLIMIT},
4921 		{ "queue",		QUEUE},
4922 		{ "quick",		QUICK},
4923 		{ "random",		RANDOM},
4924 		{ "random-id",		RANDOMID},
4925 		{ "rdr",		RDR},
4926 		{ "rdr-anchor",		RDRANCHOR},
4927 		{ "rdr-to",		RDRTO},
4928 		{ "realtime",		REALTIME},
4929 		{ "reassemble",		REASSEMBLE},
4930 		{ "reply-to",		REPLYTO},
4931 		{ "require-order",	REQUIREORDER},
4932 		{ "return",		RETURN},
4933 		{ "return-icmp",	RETURNICMP},
4934 		{ "return-icmp6",	RETURNICMP6},
4935 		{ "return-rst",		RETURNRST},
4936 		{ "round-robin",	ROUNDROBIN},
4937 		{ "route",		ROUTE},
4938 		{ "route-to",		ROUTETO},
4939 		{ "rtable",		RTABLE},
4940 		{ "rule",		RULE},
4941 		{ "ruleset-optimization",	RULESET_OPTIMIZATION},
4942 		{ "scrub",		SCRUB},
4943 		{ "set",		SET},
4944 		{ "set-tos",		SETTOS},
4945 		{ "skip",		SKIP},
4946 		{ "sloppy",		SLOPPY},
4947 		{ "source-hash",	SOURCEHASH},
4948 		{ "source-track",	SOURCETRACK},
4949 		{ "state",		STATE},
4950 		{ "state-defaults",	STATEDEFAULTS},
4951 		{ "state-policy",	STATEPOLICY},
4952 		{ "static-port",	STATICPORT},
4953 		{ "sticky-address",	STICKYADDRESS},
4954 		{ "synproxy",		SYNPROXY},
4955 		{ "table",		TABLE},
4956 		{ "tag",		TAG},
4957 		{ "tagged",		TAGGED},
4958 		{ "tbrsize",		TBRSIZE},
4959 		{ "timeout",		TIMEOUT},
4960 		{ "to",			TO},
4961 		{ "tos",		TOS},
4962 		{ "ttl",		TTL},
4963 		{ "upperlimit",		UPPERLIMIT},
4964 		{ "urpf-failed",	URPFFAILED},
4965 		{ "user",		USER},
4966 	};
4967 	const struct keywords	*p;
4968 
4969 	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
4970 	    sizeof(keywords[0]), kw_cmp);
4971 
4972 	if (p) {
4973 		if (debug > 1)
4974 			fprintf(stderr, "%s: %d\n", s, p->k_val);
4975 		return (p->k_val);
4976 	} else {
4977 		if (debug > 1)
4978 			fprintf(stderr, "string: %s\n", s);
4979 		return (STRING);
4980 	}
4981 }
4982 
4983 #define MAXPUSHBACK	128
4984 
4985 char	*parsebuf;
4986 int	 parseindex;
4987 char	 pushback_buffer[MAXPUSHBACK];
4988 int	 pushback_index = 0;
4989 
4990 int
4991 lgetc(int quotec)
4992 {
4993 	int		c, next;
4994 
4995 	if (parsebuf) {
4996 		/* Read character from the parsebuffer instead of input. */
4997 		if (parseindex >= 0) {
4998 			c = parsebuf[parseindex++];
4999 			if (c != '\0')
5000 				return (c);
5001 			parsebuf = NULL;
5002 		} else
5003 			parseindex++;
5004 	}
5005 
5006 	if (pushback_index)
5007 		return (pushback_buffer[--pushback_index]);
5008 
5009 	if (quotec) {
5010 		if ((c = getc(file->stream)) == EOF) {
5011 			yyerror("reached end of file while parsing quoted string");
5012 			if (popfile() == EOF)
5013 				return (EOF);
5014 			return (quotec);
5015 		}
5016 		return (c);
5017 	}
5018 
5019 	while ((c = getc(file->stream)) == '\\') {
5020 		next = getc(file->stream);
5021 		if (next != '\n') {
5022 			c = next;
5023 			break;
5024 		}
5025 		yylval.lineno = file->lineno;
5026 		file->lineno++;
5027 	}
5028 
5029 	while (c == EOF) {
5030 		if (popfile() == EOF)
5031 			return (EOF);
5032 		c = getc(file->stream);
5033 	}
5034 	return (c);
5035 }
5036 
5037 int
5038 lungetc(int c)
5039 {
5040 	if (c == EOF)
5041 		return (EOF);
5042 	if (parsebuf) {
5043 		parseindex--;
5044 		if (parseindex >= 0)
5045 			return (c);
5046 	}
5047 	if (pushback_index < MAXPUSHBACK-1)
5048 		return (pushback_buffer[pushback_index++] = c);
5049 	else
5050 		return (EOF);
5051 }
5052 
5053 int
5054 findeol(void)
5055 {
5056 	int	c;
5057 
5058 	parsebuf = NULL;
5059 
5060 	/* skip to either EOF or the first real EOL */
5061 	while (1) {
5062 		if (pushback_index)
5063 			c = pushback_buffer[--pushback_index];
5064 		else
5065 			c = lgetc(0);
5066 		if (c == '\n') {
5067 			file->lineno++;
5068 			break;
5069 		}
5070 		if (c == EOF)
5071 			break;
5072 	}
5073 	return (ERROR);
5074 }
5075 
5076 int
5077 yylex(void)
5078 {
5079 	char	 buf[8096];
5080 	char	*p, *val;
5081 	int	 quotec, next, c;
5082 	int	 token;
5083 
5084 top:
5085 	p = buf;
5086 	while ((c = lgetc(0)) == ' ' || c == '\t')
5087 		; /* nothing */
5088 
5089 	yylval.lineno = file->lineno;
5090 	if (c == '#')
5091 		while ((c = lgetc(0)) != '\n' && c != EOF)
5092 			; /* nothing */
5093 	if (c == '$' && parsebuf == NULL) {
5094 		while (1) {
5095 			if ((c = lgetc(0)) == EOF)
5096 				return (0);
5097 
5098 			if (p + 1 >= buf + sizeof(buf) - 1) {
5099 				yyerror("string too long");
5100 				return (findeol());
5101 			}
5102 			if (isalnum(c) || c == '_') {
5103 				*p++ = (char)c;
5104 				continue;
5105 			}
5106 			*p = '\0';
5107 			lungetc(c);
5108 			break;
5109 		}
5110 		val = symget(buf);
5111 		if (val == NULL) {
5112 			yyerror("macro '%s' not defined", buf);
5113 			return (findeol());
5114 		}
5115 		parsebuf = val;
5116 		parseindex = 0;
5117 		goto top;
5118 	}
5119 
5120 	switch (c) {
5121 	case '\'':
5122 	case '"':
5123 		quotec = c;
5124 		while (1) {
5125 			if ((c = lgetc(quotec)) == EOF)
5126 				return (0);
5127 			if (c == '\n') {
5128 				file->lineno++;
5129 				continue;
5130 			} else if (c == '\\') {
5131 				if ((next = lgetc(quotec)) == EOF)
5132 					return (0);
5133 				if (next == quotec || c == ' ' || c == '\t')
5134 					c = next;
5135 				else if (next == '\n')
5136 					continue;
5137 				else
5138 					lungetc(next);
5139 			} else if (c == quotec) {
5140 				*p = '\0';
5141 				break;
5142 			}
5143 			if (p + 1 >= buf + sizeof(buf) - 1) {
5144 				yyerror("string too long");
5145 				return (findeol());
5146 			}
5147 			*p++ = (char)c;
5148 		}
5149 		yylval.v.string = strdup(buf);
5150 		if (yylval.v.string == NULL)
5151 			err(1, "yylex: strdup");
5152 		return (STRING);
5153 	case '<':
5154 		next = lgetc(0);
5155 		if (next == '>') {
5156 			yylval.v.i = PF_OP_XRG;
5157 			return (PORTBINARY);
5158 		}
5159 		lungetc(next);
5160 		break;
5161 	case '>':
5162 		next = lgetc(0);
5163 		if (next == '<') {
5164 			yylval.v.i = PF_OP_IRG;
5165 			return (PORTBINARY);
5166 		}
5167 		lungetc(next);
5168 		break;
5169 	}
5170 
5171 #define allowed_to_end_number(x) \
5172 	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
5173 
5174 	if (c == '-' || isdigit(c)) {
5175 		do {
5176 			*p++ = c;
5177 			if ((unsigned)(p-buf) >= sizeof(buf)) {
5178 				yyerror("string too long");
5179 				return (findeol());
5180 			}
5181 		} while ((c = lgetc(0)) != EOF && isdigit(c));
5182 		lungetc(c);
5183 		if (p == buf + 1 && buf[0] == '-')
5184 			goto nodigits;
5185 		if (c == EOF || allowed_to_end_number(c)) {
5186 			const char *errstr = NULL;
5187 
5188 			*p = '\0';
5189 			yylval.v.number = strtonum(buf, LLONG_MIN,
5190 			    LLONG_MAX, &errstr);
5191 			if (errstr) {
5192 				yyerror("\"%s\" invalid number: %s",
5193 				    buf, errstr);
5194 				return (findeol());
5195 			}
5196 			return (NUMBER);
5197 		} else {
5198 nodigits:
5199 			while (p > buf + 1)
5200 				lungetc(*--p);
5201 			c = *--p;
5202 			if (c == '-')
5203 				return (c);
5204 		}
5205 	}
5206 
5207 #define allowed_in_string(x) \
5208 	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
5209 	x != '{' && x != '}' && x != '<' && x != '>' && \
5210 	x != '!' && x != '=' && x != '/' && x != '#' && \
5211 	x != ','))
5212 
5213 	if (isalnum(c) || c == ':' || c == '_') {
5214 		do {
5215 			*p++ = c;
5216 			if ((unsigned)(p-buf) >= sizeof(buf)) {
5217 				yyerror("string too long");
5218 				return (findeol());
5219 			}
5220 		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
5221 		lungetc(c);
5222 		*p = '\0';
5223 		if ((token = lookup(buf)) == STRING)
5224 			if ((yylval.v.string = strdup(buf)) == NULL)
5225 				err(1, "yylex: strdup");
5226 		return (token);
5227 	}
5228 	if (c == '\n') {
5229 		yylval.lineno = file->lineno;
5230 		file->lineno++;
5231 	}
5232 	if (c == EOF)
5233 		return (0);
5234 	return (c);
5235 }
5236 
5237 int
5238 check_file_secrecy(int fd, const char *fname)
5239 {
5240 	struct stat	st;
5241 
5242 	if (fstat(fd, &st)) {
5243 		warn("cannot stat %s", fname);
5244 		return (-1);
5245 	}
5246 	if (st.st_uid != 0 && st.st_uid != getuid()) {
5247 		warnx("%s: owner not root or current user", fname);
5248 		return (-1);
5249 	}
5250 	if (st.st_mode & (S_IRWXG | S_IRWXO)) {
5251 		warnx("%s: group/world readable/writeable", fname);
5252 		return (-1);
5253 	}
5254 	return (0);
5255 }
5256 
5257 struct file *
5258 pushfile(const char *name, int secret)
5259 {
5260 	struct file	*nfile;
5261 
5262 	if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
5263 	    (nfile->name = strdup(name)) == NULL) {
5264 		warn("malloc");
5265 		return (NULL);
5266 	}
5267 	if (TAILQ_FIRST(&files) == NULL && strcmp(nfile->name, "-") == 0) {
5268 		nfile->stream = stdin;
5269 		free(nfile->name);
5270 		if ((nfile->name = strdup("stdin")) == NULL) {
5271 			warn("strdup");
5272 			free(nfile);
5273 			return (NULL);
5274 		}
5275 	} else if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
5276 		warn("%s", nfile->name);
5277 		free(nfile->name);
5278 		free(nfile);
5279 		return (NULL);
5280 	} else if (secret &&
5281 	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
5282 		fclose(nfile->stream);
5283 		free(nfile->name);
5284 		free(nfile);
5285 		return (NULL);
5286 	}
5287 	nfile->lineno = 1;
5288 	TAILQ_INSERT_TAIL(&files, nfile, entry);
5289 	return (nfile);
5290 }
5291 
5292 int
5293 popfile(void)
5294 {
5295 	struct file	*prev;
5296 
5297 	if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
5298 		prev->errors += file->errors;
5299 		TAILQ_REMOVE(&files, file, entry);
5300 		fclose(file->stream);
5301 		free(file->name);
5302 		free(file);
5303 		file = prev;
5304 		return (0);
5305 	}
5306 	return (EOF);
5307 }
5308 
5309 int
5310 parse_config(char *filename, struct pfctl *xpf)
5311 {
5312 	int		 errors = 0;
5313 	struct sym	*sym;
5314 
5315 	pf = xpf;
5316 	errors = 0;
5317 	rulestate = PFCTL_STATE_NONE;
5318 	returnicmpdefault = (ICMP_UNREACH << 8) | ICMP_UNREACH_PORT;
5319 	returnicmp6default =
5320 	    (ICMP6_DST_UNREACH << 8) | ICMP6_DST_UNREACH_NOPORT;
5321 	blockpolicy = PFRULE_DROP;
5322 	require_order = 0;
5323 
5324 	if ((file = pushfile(filename, 0)) == NULL) {
5325 		warn("cannot open the main config file!");
5326 		return (-1);
5327 	}
5328 
5329 	yyparse();
5330 	errors = file->errors;
5331 	popfile();
5332 
5333 	/* Free macros and check which have not been used. */
5334 	while ((sym = TAILQ_FIRST(&symhead))) {
5335 		if ((pf->opts & PF_OPT_VERBOSE2) && !sym->used)
5336 			fprintf(stderr, "warning: macro '%s' not "
5337 			    "used\n", sym->nam);
5338 		free(sym->nam);
5339 		free(sym->val);
5340 		TAILQ_REMOVE(&symhead, sym, entry);
5341 		free(sym);
5342 	}
5343 
5344 	return (errors ? -1 : 0);
5345 }
5346 
5347 int
5348 symset(const char *nam, const char *val, int persist)
5349 {
5350 	struct sym	*sym;
5351 
5352 	for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
5353 	    sym = TAILQ_NEXT(sym, entry))
5354 		;	/* nothing */
5355 
5356 	if (sym != NULL) {
5357 		if (sym->persist == 1)
5358 			return (0);
5359 		else {
5360 			free(sym->nam);
5361 			free(sym->val);
5362 			TAILQ_REMOVE(&symhead, sym, entry);
5363 			free(sym);
5364 		}
5365 	}
5366 	if ((sym = calloc(1, sizeof(*sym))) == NULL)
5367 		return (-1);
5368 
5369 	sym->nam = strdup(nam);
5370 	if (sym->nam == NULL) {
5371 		free(sym);
5372 		return (-1);
5373 	}
5374 	sym->val = strdup(val);
5375 	if (sym->val == NULL) {
5376 		free(sym->nam);
5377 		free(sym);
5378 		return (-1);
5379 	}
5380 	sym->used = 0;
5381 	sym->persist = persist;
5382 	TAILQ_INSERT_TAIL(&symhead, sym, entry);
5383 	return (0);
5384 }
5385 
5386 int
5387 pfctl_cmdline_symset(char *s)
5388 {
5389 	char	*sym, *val;
5390 	int	 ret;
5391 
5392 	if ((val = strrchr(s, '=')) == NULL)
5393 		return (-1);
5394 
5395 	if ((sym = malloc(strlen(s) - strlen(val) + 1)) == NULL)
5396 		err(1, "pfctl_cmdline_symset: malloc");
5397 
5398 	strlcpy(sym, s, strlen(s) - strlen(val) + 1);
5399 
5400 	ret = symset(sym, val + 1, 1);
5401 	free(sym);
5402 
5403 	return (ret);
5404 }
5405 
5406 char *
5407 symget(const char *nam)
5408 {
5409 	struct sym	*sym;
5410 
5411 	TAILQ_FOREACH(sym, &symhead, entry)
5412 		if (strcmp(nam, sym->nam) == 0) {
5413 			sym->used = 1;
5414 			return (sym->val);
5415 		}
5416 	return (NULL);
5417 }
5418 
5419 void
5420 mv_rules(struct pf_ruleset *src, struct pf_ruleset *dst)
5421 {
5422 	int i;
5423 	struct pf_rule *r;
5424 
5425 	for (i = 0; i < PF_RULESET_MAX; ++i) {
5426 		while ((r = TAILQ_FIRST(src->rules[i].active.ptr))
5427 		    != NULL) {
5428 			TAILQ_REMOVE(src->rules[i].active.ptr, r, entries);
5429 			TAILQ_INSERT_TAIL(dst->rules[i].active.ptr, r, entries);
5430 			dst->anchor->match++;
5431 		}
5432 		src->anchor->match = 0;
5433 		while ((r = TAILQ_FIRST(src->rules[i].inactive.ptr))
5434 		    != NULL) {
5435 			TAILQ_REMOVE(src->rules[i].inactive.ptr, r, entries);
5436 			TAILQ_INSERT_TAIL(dst->rules[i].inactive.ptr,
5437 				r, entries);
5438 		}
5439 	}
5440 }
5441 
5442 void
5443 decide_address_family(struct node_host *n, sa_family_t *af)
5444 {
5445 	if (*af != 0 || n == NULL)
5446 		return;
5447 	*af = n->af;
5448 	while ((n = n->next) != NULL) {
5449 		if (n->af != *af) {
5450 			*af = 0;
5451 			return;
5452 		}
5453 	}
5454 }
5455 
5456 void
5457 remove_invalid_hosts(struct node_host **nh, sa_family_t *af)
5458 {
5459 	struct node_host	*n = *nh, *prev = NULL;
5460 
5461 	while (n != NULL) {
5462 		if (*af && n->af && n->af != *af) {
5463 			/* unlink and free n */
5464 			struct node_host *next = n->next;
5465 
5466 			/* adjust tail pointer */
5467 			if (n == (*nh)->tail)
5468 				(*nh)->tail = prev;
5469 			/* adjust previous node's next pointer */
5470 			if (prev == NULL)
5471 				*nh = next;
5472 			else
5473 				prev->next = next;
5474 			/* free node */
5475 			if (n->ifname != NULL)
5476 				free(n->ifname);
5477 			free(n);
5478 			n = next;
5479 		} else {
5480 			if (n->af && !*af)
5481 				*af = n->af;
5482 			prev = n;
5483 			n = n->next;
5484 		}
5485 	}
5486 }
5487 
5488 int
5489 invalid_redirect(struct node_host *nh, sa_family_t af)
5490 {
5491 	if (!af) {
5492 		struct node_host *n;
5493 
5494 		/* tables and dyniftl are ok without an address family */
5495 		for (n = nh; n != NULL; n = n->next) {
5496 			if (n->addr.type != PF_ADDR_TABLE &&
5497 			    n->addr.type != PF_ADDR_DYNIFTL) {
5498 				yyerror("address family not given and "
5499 				    "translation address expands to multiple "
5500 				    "address families");
5501 				return (1);
5502 			}
5503 		}
5504 	}
5505 	if (nh == NULL) {
5506 		yyerror("no translation address with matching address family "
5507 		    "found.");
5508 		return (1);
5509 	}
5510 	return (0);
5511 }
5512 
5513 int
5514 atoul(char *s, u_long *ulvalp)
5515 {
5516 	u_long	 ulval;
5517 	char	*ep;
5518 
5519 	errno = 0;
5520 	ulval = strtoul(s, &ep, 0);
5521 	if (s[0] == '\0' || *ep != '\0')
5522 		return (-1);
5523 	if (errno == ERANGE && ulval == ULONG_MAX)
5524 		return (-1);
5525 	*ulvalp = ulval;
5526 	return (0);
5527 }
5528 
5529 int
5530 getservice(char *n)
5531 {
5532 	struct servent	*s;
5533 	u_long		 ulval;
5534 
5535 	if (atoul(n, &ulval) == 0) {
5536 		if (ulval > 65535) {
5537 			yyerror("illegal port value %lu", ulval);
5538 			return (-1);
5539 		}
5540 		return (htons(ulval));
5541 	} else {
5542 		s = getservbyname(n, "tcp");
5543 		if (s == NULL)
5544 			s = getservbyname(n, "udp");
5545 		if (s == NULL) {
5546 			yyerror("unknown port %s", n);
5547 			return (-1);
5548 		}
5549 		return (s->s_port);
5550 	}
5551 }
5552 
5553 int
5554 rule_label(struct pf_rule *r, char *s)
5555 {
5556 	if (s) {
5557 		if (strlcpy(r->label, s, sizeof(r->label)) >=
5558 		    sizeof(r->label)) {
5559 			yyerror("rule label too long (max %d chars)",
5560 			    sizeof(r->label)-1);
5561 			return (-1);
5562 		}
5563 	}
5564 	return (0);
5565 }
5566 
5567 u_int16_t
5568 parseicmpspec(char *w, sa_family_t af)
5569 {
5570 	const struct icmpcodeent	*p;
5571 	u_long				 ulval;
5572 	u_int8_t			 icmptype;
5573 
5574 	if (af == AF_INET)
5575 		icmptype = returnicmpdefault >> 8;
5576 	else
5577 		icmptype = returnicmp6default >> 8;
5578 
5579 	if (atoul(w, &ulval) == -1) {
5580 		if ((p = geticmpcodebyname(icmptype, w, af)) == NULL) {
5581 			yyerror("unknown icmp code %s", w);
5582 			return (0);
5583 		}
5584 		ulval = p->code;
5585 	}
5586 	if (ulval > 255) {
5587 		yyerror("invalid icmp code %lu", ulval);
5588 		return (0);
5589 	}
5590 	return (icmptype << 8 | ulval);
5591 }
5592 
5593 int
5594 parseport(char *port, struct range *r, int extensions)
5595 {
5596 	char	*p = strchr(port, ':');
5597 
5598 	if (p == NULL) {
5599 		if ((r->a = getservice(port)) == -1)
5600 			return (-1);
5601 		r->b = 0;
5602 		r->t = PF_OP_NONE;
5603 		return (0);
5604 	}
5605 	if ((extensions & PPORT_STAR) && !strcmp(p+1, "*")) {
5606 		*p = 0;
5607 		if ((r->a = getservice(port)) == -1)
5608 			return (-1);
5609 		r->b = 0;
5610 		r->t = PF_OP_IRG;
5611 		return (0);
5612 	}
5613 	if ((extensions & PPORT_RANGE)) {
5614 		*p++ = 0;
5615 		if ((r->a = getservice(port)) == -1 ||
5616 		    (r->b = getservice(p)) == -1)
5617 			return (-1);
5618 		if (r->a == r->b) {
5619 			r->b = 0;
5620 			r->t = PF_OP_NONE;
5621 		} else
5622 			r->t = PF_OP_RRG;
5623 		return (0);
5624 	}
5625 	return (-1);
5626 }
5627 
5628 int
5629 pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
5630 {
5631 	struct loadanchors	*la;
5632 
5633 	TAILQ_FOREACH(la, &loadanchorshead, entries) {
5634 		if (pf->opts & PF_OPT_VERBOSE)
5635 			fprintf(stderr, "\nLoading anchor %s from %s\n",
5636 			    la->anchorname, la->filename);
5637 		if (pfctl_rules(dev, la->filename, pf->opts, pf->optimize,
5638 		    la->anchorname, trans) == -1)
5639 			return (-1);
5640 	}
5641 
5642 	return (0);
5643 }
5644 
5645 int
5646 kw_casecmp(const void *k, const void *e)
5647 {
5648 	return (strcasecmp(k, ((const struct keywords *)e)->k_name));
5649 }
5650 
5651 int
5652 map_tos(char *s, int *val)
5653 {
5654 	/* DiffServ Codepoints and other TOS mappings */
5655 	const struct keywords	 toswords[] = {
5656 		{ "af11",		IPTOS_DSCP_AF11 },
5657 		{ "af12",		IPTOS_DSCP_AF12 },
5658 		{ "af13",		IPTOS_DSCP_AF13 },
5659 		{ "af21",		IPTOS_DSCP_AF21 },
5660 		{ "af22",		IPTOS_DSCP_AF22 },
5661 		{ "af23",		IPTOS_DSCP_AF23 },
5662 		{ "af31",		IPTOS_DSCP_AF31 },
5663 		{ "af32",		IPTOS_DSCP_AF32 },
5664 		{ "af33",		IPTOS_DSCP_AF33 },
5665 		{ "af41",		IPTOS_DSCP_AF41 },
5666 		{ "af42",		IPTOS_DSCP_AF42 },
5667 		{ "af43",		IPTOS_DSCP_AF43 },
5668 		{ "critical",		IPTOS_PREC_CRITIC_ECP },
5669 		{ "cs0",		IPTOS_DSCP_CS0 },
5670 		{ "cs1",		IPTOS_DSCP_CS1 },
5671 		{ "cs2",		IPTOS_DSCP_CS2 },
5672 		{ "cs3",		IPTOS_DSCP_CS3 },
5673 		{ "cs4",		IPTOS_DSCP_CS4 },
5674 		{ "cs5",		IPTOS_DSCP_CS5 },
5675 		{ "cs6",		IPTOS_DSCP_CS6 },
5676 		{ "cs7",		IPTOS_DSCP_CS7 },
5677 		{ "ef",			IPTOS_DSCP_EF },
5678 		{ "inetcontrol",	IPTOS_PREC_INTERNETCONTROL },
5679 		{ "lowdelay",		IPTOS_LOWDELAY },
5680 		{ "netcontrol",		IPTOS_PREC_NETCONTROL },
5681 		{ "reliability",	IPTOS_RELIABILITY },
5682 		{ "throughput",		IPTOS_THROUGHPUT }
5683 	};
5684 	const struct keywords	*p;
5685 
5686 	p = bsearch(s, toswords, sizeof(toswords)/sizeof(toswords[0]),
5687 	    sizeof(toswords[0]), kw_casecmp);
5688 
5689 	if (p) {
5690 		*val = p->k_val;
5691 		return (1);
5692 	}
5693 	return (0);
5694 }
5695