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