Deleted Added
full compact
parse.y (145840) parse.y (171172)
1/* $OpenBSD: parse.y,v 1.482 2005/03/07 13:20:03 henning Exp $ */
1/* $OpenBSD: parse.y,v 1.517 2007/02/03 23:26:40 dhartmei Exp $ */
2
3/*
4 * Copyright (c) 2001 Markus Friedl. All rights reserved.
5 * Copyright (c) 2001 Daniel Hartmeier. All rights reserved.
6 * Copyright (c) 2001 Theo de Raadt. All rights reserved.
7 * Copyright (c) 2002,2003 Henning Brauer. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without

--- 13 unchanged lines hidden (view full) ---

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/cdefs.h>
2
3/*
4 * Copyright (c) 2001 Markus Friedl. All rights reserved.
5 * Copyright (c) 2001 Daniel Hartmeier. All rights reserved.
6 * Copyright (c) 2001 Theo de Raadt. All rights reserved.
7 * Copyright (c) 2002,2003 Henning Brauer. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without

--- 13 unchanged lines hidden (view full) ---

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/cdefs.h>
31__FBSDID("$FreeBSD: head/contrib/pf/pfctl/parse.y 145840 2005-05-03 16:55:20Z mlaier $");
31__FBSDID("$FreeBSD: head/contrib/pf/pfctl/parse.y 171172 2007-07-03 12:30:03Z mlaier $");
32
33#include <sys/types.h>
34#include <sys/socket.h>
35#include <net/if.h>
36#include <netinet/in.h>
37#include <netinet/in_systm.h>
38#include <netinet/ip.h>
39#include <netinet/ip_icmp.h>

--- 161 unchanged lines hidden (view full) ---

201 } keep;
202 int fragment;
203 int allowopts;
204 char *label;
205 struct node_qassign queues;
206 char *tag;
207 char *match_tag;
208 u_int8_t match_tag_not;
32
33#include <sys/types.h>
34#include <sys/socket.h>
35#include <net/if.h>
36#include <netinet/in.h>
37#include <netinet/in_systm.h>
38#include <netinet/ip.h>
39#include <netinet/ip_icmp.h>

--- 161 unchanged lines hidden (view full) ---

201 } keep;
202 int fragment;
203 int allowopts;
204 char *label;
205 struct node_qassign queues;
206 char *tag;
207 char *match_tag;
208 u_int8_t match_tag_not;
209 int rtableid;
209} filter_opts;
210
211struct antispoof_opts {
212 char *label;
210} filter_opts;
211
212struct antispoof_opts {
213 char *label;
214 int rtableid;
213} antispoof_opts;
214
215struct scrub_opts {
216 int marker;
217#define SOM_MINTTL 0x01
218#define SOM_MAXMSS 0x02
219#define SOM_FRAGCACHE 0x04
220 int nodf;
221 int minttl;
222 int maxmss;
223 int fragcache;
224 int randomid;
225 int reassemble_tcp;
215} antispoof_opts;
216
217struct scrub_opts {
218 int marker;
219#define SOM_MINTTL 0x01
220#define SOM_MAXMSS 0x02
221#define SOM_FRAGCACHE 0x04
222 int nodf;
223 int minttl;
224 int maxmss;
225 int fragcache;
226 int randomid;
227 int reassemble_tcp;
228 int rtableid;
226} scrub_opts;
227
228struct queue_opts {
229 int marker;
230#define QOM_BWSPEC 0x01
231#define QOM_SCHEDULER 0x02
232#define QOM_PRIORITY 0x04
233#define QOM_TBRSIZE 0x08

--- 22 unchanged lines hidden (view full) ---

256
257} pool_opts;
258
259
260struct node_hfsc_opts hfsc_opts;
261
262int yyerror(const char *, ...);
263int disallow_table(struct node_host *, const char *);
229} scrub_opts;
230
231struct queue_opts {
232 int marker;
233#define QOM_BWSPEC 0x01
234#define QOM_SCHEDULER 0x02
235#define QOM_PRIORITY 0x04
236#define QOM_TBRSIZE 0x08

--- 22 unchanged lines hidden (view full) ---

259
260} pool_opts;
261
262
263struct node_hfsc_opts hfsc_opts;
264
265int yyerror(const char *, ...);
266int disallow_table(struct node_host *, const char *);
267int disallow_urpf_failed(struct node_host *, const char *);
264int disallow_alias(struct node_host *, const char *);
268int disallow_alias(struct node_host *, const char *);
265int rule_consistent(struct pf_rule *);
266int filter_consistent(struct pf_rule *);
269int rule_consistent(struct pf_rule *, int);
270int filter_consistent(struct pf_rule *, int);
267int nat_consistent(struct pf_rule *);
268int rdr_consistent(struct pf_rule *);
269int process_tabledef(char *, struct table_opts *);
270int yyparse(void);
271void expand_label_str(char *, size_t, const char *, const char *);
272void expand_label_if(const char *, char *, size_t, const char *);
273void expand_label_addr(const char *, char *, size_t, u_int8_t,
274 struct node_host *);

--- 33 unchanged lines hidden (view full) ---

308 char *nam;
309 char *val;
310};
311
312
313int symset(const char *, const char *, int);
314char *symget(const char *);
315
271int nat_consistent(struct pf_rule *);
272int rdr_consistent(struct pf_rule *);
273int process_tabledef(char *, struct table_opts *);
274int yyparse(void);
275void expand_label_str(char *, size_t, const char *, const char *);
276void expand_label_if(const char *, char *, size_t, const char *);
277void expand_label_addr(const char *, char *, size_t, u_int8_t,
278 struct node_host *);

--- 33 unchanged lines hidden (view full) ---

312 char *nam;
313 char *val;
314};
315
316
317int symset(const char *, const char *, int);
318char *symget(const char *);
319
320void mv_rules(struct pf_ruleset *, struct pf_ruleset *);
316void decide_address_family(struct node_host *, sa_family_t *);
317void remove_invalid_hosts(struct node_host **, sa_family_t *);
318int invalid_redirect(struct node_host *, sa_family_t);
319u_int16_t parseicmpspec(char *, sa_family_t);
320
321TAILQ_HEAD(loadanchorshead, loadanchors)
322 loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead);
323
324struct loadanchors {
325 TAILQ_ENTRY(loadanchors) entries;
326 char *anchorname;
327 char *filename;
328};
329
330typedef struct {
331 union {
332 u_int32_t number;
333 int i;
334 char *string;
321void decide_address_family(struct node_host *, sa_family_t *);
322void remove_invalid_hosts(struct node_host **, sa_family_t *);
323int invalid_redirect(struct node_host *, sa_family_t);
324u_int16_t parseicmpspec(char *, sa_family_t);
325
326TAILQ_HEAD(loadanchorshead, loadanchors)
327 loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead);
328
329struct loadanchors {
330 TAILQ_ENTRY(loadanchors) entries;
331 char *anchorname;
332 char *filename;
333};
334
335typedef struct {
336 union {
337 u_int32_t number;
338 int i;
339 char *string;
340 int rtableid;
335 struct {
336 u_int8_t b1;
337 u_int8_t b2;
338 u_int16_t w;
339 u_int16_t w2;
340 } b;
341 struct range {
342 int a;

--- 26 unchanged lines hidden (view full) ---

369 struct range rport;
370 } *redirection;
371 struct {
372 int action;
373 struct node_state_opt *options;
374 } keep_state;
375 struct {
376 u_int8_t log;
341 struct {
342 u_int8_t b1;
343 u_int8_t b2;
344 u_int16_t w;
345 u_int16_t w2;
346 } b;
347 struct range {
348 int a;

--- 26 unchanged lines hidden (view full) ---

375 struct range rport;
376 } *redirection;
377 struct {
378 int action;
379 struct node_state_opt *options;
380 } keep_state;
381 struct {
382 u_int8_t log;
383 u_int8_t logif;
377 u_int8_t quick;
378 } logquick;
379 struct {
380 int neg;
381 char *name;
382 } tagged;
383 struct pf_poolhashkey *hashkey;
384 struct node_queue *queue;

--- 12 unchanged lines hidden (view full) ---

397} YYSTYPE;
398
399#define DYNIF_MULTIADDR(addr) ((addr).type == PF_ADDR_DYNIFTL && \
400 (!((addr).iflags & PFI_AFLAG_NOALIAS) || \
401 !isdigit((addr).v.ifname[strlen((addr).v.ifname)-1])))
402
403%}
404
384 u_int8_t quick;
385 } logquick;
386 struct {
387 int neg;
388 char *name;
389 } tagged;
390 struct pf_poolhashkey *hashkey;
391 struct node_queue *queue;

--- 12 unchanged lines hidden (view full) ---

404} YYSTYPE;
405
406#define DYNIF_MULTIADDR(addr) ((addr).type == PF_ADDR_DYNIFTL && \
407 (!((addr).iflags & PFI_AFLAG_NOALIAS) || \
408 !isdigit((addr).v.ifname[strlen((addr).v.ifname)-1])))
409
410%}
411
405%token PASS BLOCK SCRUB RETURN IN OS OUT LOG LOGALL QUICK ON FROM TO FLAGS
412%token PASS BLOCK SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS
406%token RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE
407%token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF
408%token MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL
413%token RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE
414%token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF
415%token MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL
409%token NOROUTE FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS DROP TABLE
416%token NOROUTE URPFFAILED FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS DROP TABLE
410%token REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR
411%token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY RANDOMID
412%token REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID
413%token ANTISPOOF FOR
414%token BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY
415%token ALTQ CBQ PRIQ HFSC BANDWIDTH TBRSIZE LINKSHARE REALTIME UPPERLIMIT
417%token REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR
418%token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY RANDOMID
419%token REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID
420%token ANTISPOOF FOR
421%token BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY
422%token ALTQ CBQ PRIQ HFSC BANDWIDTH TBRSIZE LINKSHARE REALTIME UPPERLIMIT
416%token QUEUE PRIORITY QLIMIT
417%token LOAD
423%token QUEUE PRIORITY QLIMIT RTABLE
424%token LOAD RULESET_OPTIMIZATION
418%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
419%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH
425%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
426%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH
420%token TAGGED TAG IFBOUND GRBOUND FLOATING STATEPOLICY ROUTE
427%token TAGGED TAG IFBOUND FLOATING STATEPOLICY ROUTE
421%token <v.string> STRING
422%token <v.i> PORTBINARY
423%type <v.interface> interface if_list if_item_not if_item
424%type <v.number> number icmptype icmp6type uid gid
428%token <v.string> STRING
429%token <v.i> PORTBINARY
430%type <v.interface> interface if_list if_item_not if_item
431%type <v.number> number icmptype icmp6type uid gid
425%type <v.number> tos not yesno natpass
426%type <v.i> no dir log af fragcache sourcetrack flush
427%type unaryop statelock
428%type action nataction scrubaction
432%type tos not yesno
433%type <v.i> no dir af fragcache optimizer
434%type <v.i> sourcetrack flush unaryop statelock
435%type <v.b> action nataction natpass scrubaction
429%type <v.b> flags flag blockspec
430%type <v.range> port rport
431%type <v.hashkey> hashkey
432%type <v.proto> proto proto_list proto_item
433%type <v.icmp> icmpspec
434%type <v.icmp> icmp_list icmp_item
435%type <v.icmp> icmp6_list icmp6_item
436%type <v.fromto> fromto
437%type <v.peer> ipportspec from to
438%type <v.host> ipspec xhost host dynaddr host_list
439%type <v.host> redir_host_list redirspec
440%type <v.host> route_host route_host_list routespec
441%type <v.os> os xos os_list
442%type <v.port> portspec port_list port_item
443%type <v.uid> uids uid_list uid_item
444%type <v.gid> gids gid_list gid_item
445%type <v.route> route
446%type <v.redirection> redirection redirpool
436%type <v.b> flags flag blockspec
437%type <v.range> port rport
438%type <v.hashkey> hashkey
439%type <v.proto> proto proto_list proto_item
440%type <v.icmp> icmpspec
441%type <v.icmp> icmp_list icmp_item
442%type <v.icmp> icmp6_list icmp6_item
443%type <v.fromto> fromto
444%type <v.peer> ipportspec from to
445%type <v.host> ipspec xhost host dynaddr host_list
446%type <v.host> redir_host_list redirspec
447%type <v.host> route_host route_host_list routespec
448%type <v.os> os xos os_list
449%type <v.port> portspec port_list port_item
450%type <v.uid> uids uid_list uid_item
451%type <v.gid> gids gid_list gid_item
452%type <v.route> route
453%type <v.redirection> redirection redirpool
447%type label string tag
454%type <v.string> label string tag anchorname
448%type <v.keep_state> keep
449%type <v.state_opt> state_opt_spec state_opt_list state_opt_item
455%type <v.keep_state> keep
456%type <v.state_opt> state_opt_spec state_opt_list state_opt_item
450%type logquick
457%type <v.logquick> logquick quick log logopts logopt
451%type <v.interface> antispoof_ifspc antispoof_iflst antispoof_if
452%type <v.qassign> qname
453%type <v.queue> qassign qassign_list qassign_item
454%type <v.queue_options> scheduler
455%type <v.number> cbqflags_list cbqflags_item
456%type <v.number> priqflags_list priqflags_item
457%type <v.hfsc_opts> hfscopts_list hfscopts_item hfsc_opts
458%type <v.queue_bwspec> bandwidth
459%type <v.filter_opts> filter_opts filter_opt filter_opts_l
460%type <v.antispoof_opts> antispoof_opts antispoof_opt antispoof_opts_l
461%type <v.queue_opts> queue_opts queue_opt queue_opts_l
462%type <v.scrub_opts> scrub_opts scrub_opt scrub_opts_l
463%type <v.table_opts> table_opts table_opt table_opts_l
464%type <v.pool_opts> pool_opts pool_opt pool_opts_l
465%type <v.tagged> tagged
458%type <v.interface> antispoof_ifspc antispoof_iflst antispoof_if
459%type <v.qassign> qname
460%type <v.queue> qassign qassign_list qassign_item
461%type <v.queue_options> scheduler
462%type <v.number> cbqflags_list cbqflags_item
463%type <v.number> priqflags_list priqflags_item
464%type <v.hfsc_opts> hfscopts_list hfscopts_item hfsc_opts
465%type <v.queue_bwspec> bandwidth
466%type <v.filter_opts> filter_opts filter_opt filter_opts_l
467%type <v.antispoof_opts> antispoof_opts antispoof_opt antispoof_opts_l
468%type <v.queue_opts> queue_opts queue_opt queue_opts_l
469%type <v.scrub_opts> scrub_opts scrub_opt scrub_opts_l
470%type <v.table_opts> table_opts table_opt table_opts_l
471%type <v.pool_opts> pool_opts pool_opt pool_opts_l
472%type <v.tagged> tagged
473%type <v.rtableid> rtable
466%%
467
468ruleset : /* empty */
469 | ruleset '\n'
470 | ruleset option '\n'
471 | ruleset scrubrule '\n'
472 | ruleset natrule '\n'
473 | ruleset binatrule '\n'
474 | ruleset pfrule '\n'
475 | ruleset anchorrule '\n'
476 | ruleset loadrule '\n'
477 | ruleset altqif '\n'
478 | ruleset queuespec '\n'
479 | ruleset varset '\n'
480 | ruleset antispoof '\n'
481 | ruleset tabledef '\n'
474%%
475
476ruleset : /* empty */
477 | ruleset '\n'
478 | ruleset option '\n'
479 | ruleset scrubrule '\n'
480 | ruleset natrule '\n'
481 | ruleset binatrule '\n'
482 | ruleset pfrule '\n'
483 | ruleset anchorrule '\n'
484 | ruleset loadrule '\n'
485 | ruleset altqif '\n'
486 | ruleset queuespec '\n'
487 | ruleset varset '\n'
488 | ruleset antispoof '\n'
489 | ruleset tabledef '\n'
490 | '{' fakeanchor '}' '\n';
482 | ruleset error '\n' { errors++; }
483 ;
484
491 | ruleset error '\n' { errors++; }
492 ;
493
494/*
495 * apply to previouslys specified rule: must be careful to note
496 * what that is: pf or nat or binat or rdr
497 */
498fakeanchor : fakeanchor '\n'
499 | fakeanchor anchorrule '\n'
500 | fakeanchor binatrule '\n'
501 | fakeanchor natrule '\n'
502 | fakeanchor pfrule '\n'
503 | fakeanchor error '\n'
504 ;
505
506optimizer : string {
507 if (!strcmp($1, "none"))
508 $$ = 0;
509 else if (!strcmp($1, "basic"))
510 $$ = PF_OPTIMIZE_BASIC;
511 else if (!strcmp($1, "profile"))
512 $$ = PF_OPTIMIZE_BASIC | PF_OPTIMIZE_PROFILE;
513 else {
514 yyerror("unknown ruleset-optimization %s", $$);
515 YYERROR;
516 }
517 }
518 ;
519
485option : SET OPTIMIZATION STRING {
486 if (check_rulestate(PFCTL_STATE_OPTION)) {
487 free($3);
488 YYERROR;
489 }
490 if (pfctl_set_optimization(pf, $3) != 0) {
491 yyerror("unknown optimization %s", $3);
492 free($3);
493 YYERROR;
494 }
520option : SET OPTIMIZATION STRING {
521 if (check_rulestate(PFCTL_STATE_OPTION)) {
522 free($3);
523 YYERROR;
524 }
525 if (pfctl_set_optimization(pf, $3) != 0) {
526 yyerror("unknown optimization %s", $3);
527 free($3);
528 YYERROR;
529 }
495 free ($3);
530 free($3);
496 }
531 }
532 | SET RULESET_OPTIMIZATION optimizer {
533 if (!(pf->opts & PF_OPT_OPTIMIZE)) {
534 pf->opts |= PF_OPT_OPTIMIZE;
535 pf->optimize = $3;
536 }
537 }
497 | SET TIMEOUT timeout_spec
498 | SET TIMEOUT '{' timeout_list '}'
499 | SET LIMIT limit_spec
500 | SET LIMIT '{' limit_list '}'
501 | SET LOGINTERFACE STRING {
502 if (check_rulestate(PFCTL_STATE_OPTION)) {
503 free($3);
504 YYERROR;

--- 32 unchanged lines hidden (view full) ---

537 | SET REQUIREORDER yesno {
538 if (pf->opts & PF_OPT_VERBOSE)
539 printf("set require-order %s\n",
540 $3 == 1 ? "yes" : "no");
541 require_order = $3;
542 }
543 | SET FINGERPRINTS STRING {
544 if (pf->opts & PF_OPT_VERBOSE)
538 | SET TIMEOUT timeout_spec
539 | SET TIMEOUT '{' timeout_list '}'
540 | SET LIMIT limit_spec
541 | SET LIMIT '{' limit_list '}'
542 | SET LOGINTERFACE STRING {
543 if (check_rulestate(PFCTL_STATE_OPTION)) {
544 free($3);
545 YYERROR;

--- 32 unchanged lines hidden (view full) ---

578 | SET REQUIREORDER yesno {
579 if (pf->opts & PF_OPT_VERBOSE)
580 printf("set require-order %s\n",
581 $3 == 1 ? "yes" : "no");
582 require_order = $3;
583 }
584 | SET FINGERPRINTS STRING {
585 if (pf->opts & PF_OPT_VERBOSE)
545 printf("set fingerprints %s\n", $3);
586 printf("set fingerprints \"%s\"\n", $3);
546 if (check_rulestate(PFCTL_STATE_OPTION)) {
547 free($3);
548 YYERROR;
549 }
587 if (check_rulestate(PFCTL_STATE_OPTION)) {
588 free($3);
589 YYERROR;
590 }
550 if (!pf->anchor[0]) {
591 if (!pf->anchor->name[0]) {
551 if (pfctl_file_fingerprints(pf->dev,
552 pf->opts, $3)) {
553 yyerror("error loading "
554 "fingerprints %s", $3);
555 free($3);
556 YYERROR;
557 }
558 }
559 free($3);
560 }
561 | SET STATEPOLICY statelock {
562 if (pf->opts & PF_OPT_VERBOSE)
563 switch ($3) {
564 case 0:
565 printf("set state-policy floating\n");
566 break;
567 case PFRULE_IFBOUND:
568 printf("set state-policy if-bound\n");
569 break;
592 if (pfctl_file_fingerprints(pf->dev,
593 pf->opts, $3)) {
594 yyerror("error loading "
595 "fingerprints %s", $3);
596 free($3);
597 YYERROR;
598 }
599 }
600 free($3);
601 }
602 | SET STATEPOLICY statelock {
603 if (pf->opts & PF_OPT_VERBOSE)
604 switch ($3) {
605 case 0:
606 printf("set state-policy floating\n");
607 break;
608 case PFRULE_IFBOUND:
609 printf("set state-policy if-bound\n");
610 break;
570 case PFRULE_GRBOUND:
571 printf("set state-policy "
572 "group-bound\n");
573 break;
574 }
575 default_statelock = $3;
576 }
577 | SET DEBUG STRING {
578 if (check_rulestate(PFCTL_STATE_OPTION)) {
579 free($3);
580 YYERROR;
581 }

--- 26 unchanged lines hidden (view full) ---

608 printf("%s = \"%s\"\n", $1, $3);
609 if (symset($1, $3, 0) == -1)
610 err(1, "cannot store variable %s", $1);
611 free($1);
612 free($3);
613 }
614 ;
615
611 }
612 default_statelock = $3;
613 }
614 | SET DEBUG STRING {
615 if (check_rulestate(PFCTL_STATE_OPTION)) {
616 free($3);
617 YYERROR;
618 }

--- 26 unchanged lines hidden (view full) ---

645 printf("%s = \"%s\"\n", $1, $3);
646 if (symset($1, $3, 0) == -1)
647 err(1, "cannot store variable %s", $1);
648 free($1);
649 free($3);
650 }
651 ;
652
616anchorrule : ANCHOR string dir interface af proto fromto filter_opts {
653anchorname : STRING { $$ = $1; }
654 | /* empty */ { $$ = NULL; }
655 ;
656
657optnl : optnl '\n'
658 |
659 ;
660
661pfa_anchorlist : pfrule optnl
662 | anchorrule optnl
663 | pfa_anchorlist pfrule optnl
664 | pfa_anchorlist anchorrule optnl
665 ;
666
667pfa_anchor : '{'
668 {
669 char ta[PF_ANCHOR_NAME_SIZE];
670 struct pf_ruleset *rs;
671
672 /* steping into a brace anchor */
673 pf->asd++;
674 pf->bn++;
675 pf->brace = 1;
676
677 /* create a holding ruleset in the root */
678 snprintf(ta, PF_ANCHOR_NAME_SIZE, "_%d", pf->bn);
679 rs = pf_find_or_create_ruleset(ta);
680 if (rs == NULL)
681 err(1, "pfa_anchor: pf_find_or_create_ruleset");
682 pf->astack[pf->asd] = rs->anchor;
683 pf->anchor = rs->anchor;
684 } '\n' pfa_anchorlist '}'
685 {
686 pf->alast = pf->anchor;
687 pf->asd--;
688 pf->anchor = pf->astack[pf->asd];
689 }
690 | /* empty */
691 ;
692
693anchorrule : ANCHOR anchorname dir quick interface af proto fromto
694 filter_opts pfa_anchor
695 {
617 struct pf_rule r;
618
619 if (check_rulestate(PFCTL_STATE_FILTER)) {
696 struct pf_rule r;
697
698 if (check_rulestate(PFCTL_STATE_FILTER)) {
699 if ($2)
700 free($2);
701 YYERROR;
702 }
703
704 if ($2 && ($2[0] == '_' || strstr($2, "/_") != NULL)) {
620 free($2);
705 free($2);
706 yyerror("anchor names beginning with '_' "
707 "are reserved for internal use");
621 YYERROR;
622 }
623
624 memset(&r, 0, sizeof(r));
708 YYERROR;
709 }
710
711 memset(&r, 0, sizeof(r));
712 if (pf->astack[pf->asd + 1]) {
713 /* move inline rules into relative location */
714 pf_anchor_setup(&r,
715 &pf->astack[pf->asd]->ruleset,
716 $2 ? $2 : pf->alast->name);
717
718 if (r.anchor == NULL)
719 err(1, "anchorrule: unable to "
720 "create ruleset");
721
722 if (pf->alast != r.anchor) {
723 if (r.anchor->match) {
724 yyerror("inline anchor '%s' "
725 "already exists",
726 r.anchor->name);
727 YYERROR;
728 }
729 mv_rules(&pf->alast->ruleset,
730 &r.anchor->ruleset);
731 }
732 pf_remove_if_empty_ruleset(&pf->alast->ruleset);
733 pf->alast = r.anchor;
734 } else {
735 if (!$2) {
736 yyerror("anchors without explicit "
737 "rules must specify a name");
738 YYERROR;
739 }
740 }
625 r.direction = $3;
741 r.direction = $3;
626 r.af = $5;
627 r.prob = $8.prob;
742 r.quick = $4.quick;
743 r.af = $6;
744 r.prob = $9.prob;
745 r.rtableid = $9.rtableid;
628
746
629 if ($8.match_tag)
630 if (strlcpy(r.match_tagname, $8.match_tag,
747 if ($9.match_tag)
748 if (strlcpy(r.match_tagname, $9.match_tag,
631 PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
632 yyerror("tag too long, max %u chars",
633 PF_TAG_NAME_SIZE - 1);
634 YYERROR;
635 }
749 PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
750 yyerror("tag too long, max %u chars",
751 PF_TAG_NAME_SIZE - 1);
752 YYERROR;
753 }
636 r.match_tag_not = $8.match_tag_not;
754 r.match_tag_not = $9.match_tag_not;
637
755
638 decide_address_family($7.src.host, &r.af);
639 decide_address_family($7.dst.host, &r.af);
756 decide_address_family($8.src.host, &r.af);
757 decide_address_family($8.dst.host, &r.af);
640
758
641 expand_rule(&r, $4, NULL, $6, $7.src_os,
642 $7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
643 0, 0, 0, $2);
759 expand_rule(&r, $5, NULL, $7, $8.src_os,
760 $8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
761 0, 0, 0, pf->astack[pf->asd + 1] ?
762 pf->alast->name : $2);
644 free($2);
763 free($2);
764 pf->astack[pf->asd + 1] = NULL;
645 }
765 }
646 | NATANCHOR string interface af proto fromto {
766 | NATANCHOR string interface af proto fromto rtable {
647 struct pf_rule r;
648
649 if (check_rulestate(PFCTL_STATE_NAT)) {
650 free($2);
651 YYERROR;
652 }
653
654 memset(&r, 0, sizeof(r));
655 r.action = PF_NAT;
656 r.af = $4;
767 struct pf_rule r;
768
769 if (check_rulestate(PFCTL_STATE_NAT)) {
770 free($2);
771 YYERROR;
772 }
773
774 memset(&r, 0, sizeof(r));
775 r.action = PF_NAT;
776 r.af = $4;
777 r.rtableid = $7;
657
658 decide_address_family($6.src.host, &r.af);
659 decide_address_family($6.dst.host, &r.af);
660
661 expand_rule(&r, $3, NULL, $5, $6.src_os,
662 $6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
663 0, 0, 0, $2);
664 free($2);
665 }
778
779 decide_address_family($6.src.host, &r.af);
780 decide_address_family($6.dst.host, &r.af);
781
782 expand_rule(&r, $3, NULL, $5, $6.src_os,
783 $6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
784 0, 0, 0, $2);
785 free($2);
786 }
666 | RDRANCHOR string interface af proto fromto {
787 | RDRANCHOR string interface af proto fromto rtable {
667 struct pf_rule r;
668
669 if (check_rulestate(PFCTL_STATE_NAT)) {
670 free($2);
671 YYERROR;
672 }
673
674 memset(&r, 0, sizeof(r));
675 r.action = PF_RDR;
676 r.af = $4;
788 struct pf_rule r;
789
790 if (check_rulestate(PFCTL_STATE_NAT)) {
791 free($2);
792 YYERROR;
793 }
794
795 memset(&r, 0, sizeof(r));
796 r.action = PF_RDR;
797 r.af = $4;
798 r.rtableid = $7;
677
678 decide_address_family($6.src.host, &r.af);
679 decide_address_family($6.dst.host, &r.af);
680
681 if ($6.src.port != NULL) {
682 yyerror("source port parameter not supported"
683 " in rdr-anchor");
684 YYERROR;

--- 14 unchanged lines hidden (view full) ---

699 r.dst.port_op = $6.dst.port->op;
700 }
701
702 expand_rule(&r, $3, NULL, $5, $6.src_os,
703 $6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
704 0, 0, 0, $2);
705 free($2);
706 }
799
800 decide_address_family($6.src.host, &r.af);
801 decide_address_family($6.dst.host, &r.af);
802
803 if ($6.src.port != NULL) {
804 yyerror("source port parameter not supported"
805 " in rdr-anchor");
806 YYERROR;

--- 14 unchanged lines hidden (view full) ---

821 r.dst.port_op = $6.dst.port->op;
822 }
823
824 expand_rule(&r, $3, NULL, $5, $6.src_os,
825 $6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
826 0, 0, 0, $2);
827 free($2);
828 }
707 | BINATANCHOR string interface af proto fromto {
829 | BINATANCHOR string interface af proto fromto rtable {
708 struct pf_rule r;
709
710 if (check_rulestate(PFCTL_STATE_NAT)) {
711 free($2);
712 YYERROR;
713 }
714
715 memset(&r, 0, sizeof(r));
716 r.action = PF_BINAT;
717 r.af = $4;
830 struct pf_rule r;
831
832 if (check_rulestate(PFCTL_STATE_NAT)) {
833 free($2);
834 YYERROR;
835 }
836
837 memset(&r, 0, sizeof(r));
838 r.action = PF_BINAT;
839 r.af = $4;
840 r.rtableid = $7;
718 if ($5 != NULL) {
719 if ($5->next != NULL) {
720 yyerror("proto list expansion"
721 " not supported in binat-anchor");
722 YYERROR;
723 }
724 r.proto = $5->proto;
725 free($5);

--- 12 unchanged lines hidden (view full) ---

738 pfctl_add_rule(pf, &r, $2);
739 free($2);
740 }
741 ;
742
743loadrule : LOAD ANCHOR string FROM string {
744 struct loadanchors *loadanchor;
745
841 if ($5 != NULL) {
842 if ($5->next != NULL) {
843 yyerror("proto list expansion"
844 " not supported in binat-anchor");
845 YYERROR;
846 }
847 r.proto = $5->proto;
848 free($5);

--- 12 unchanged lines hidden (view full) ---

861 pfctl_add_rule(pf, &r, $2);
862 free($2);
863 }
864 ;
865
866loadrule : LOAD ANCHOR string FROM string {
867 struct loadanchors *loadanchor;
868
746 if (strlen($3) >= MAXPATHLEN) {
869 if (strlen(pf->anchor->name) + 1 +
870 strlen($3) >= MAXPATHLEN) {
747 yyerror("anchorname %s too long, max %u\n",
748 $3, MAXPATHLEN - 1);
749 free($3);
750 YYERROR;
751 }
752 loadanchor = calloc(1, sizeof(struct loadanchors));
753 if (loadanchor == NULL)
754 err(1, "loadrule: calloc");
871 yyerror("anchorname %s too long, max %u\n",
872 $3, MAXPATHLEN - 1);
873 free($3);
874 YYERROR;
875 }
876 loadanchor = calloc(1, sizeof(struct loadanchors));
877 if (loadanchor == NULL)
878 err(1, "loadrule: calloc");
755 if ((loadanchor->anchorname = strdup($3)) == NULL)
756 err(1, "loadrule: strdup");
879 if ((loadanchor->anchorname = malloc(MAXPATHLEN)) ==
880 NULL)
881 err(1, "loadrule: malloc");
882 if (pf->anchor->name[0])
883 snprintf(loadanchor->anchorname, MAXPATHLEN,
884 "%s/%s", pf->anchor->name, $3);
885 else
886 strlcpy(loadanchor->anchorname, $3, MAXPATHLEN);
757 if ((loadanchor->filename = strdup($5)) == NULL)
758 err(1, "loadrule: strdup");
759
760 TAILQ_INSERT_TAIL(&loadanchorshead, loadanchor,
761 entries);
762
763 free($3);
764 free($5);

--- 16 unchanged lines hidden (view full) ---

781 YYERROR;
782
783 memset(&r, 0, sizeof(r));
784
785 r.action = $1.b1;
786 r.direction = $2;
787
788 r.log = $3.log;
887 if ((loadanchor->filename = strdup($5)) == NULL)
888 err(1, "loadrule: strdup");
889
890 TAILQ_INSERT_TAIL(&loadanchorshead, loadanchor,
891 entries);
892
893 free($3);
894 free($5);

--- 16 unchanged lines hidden (view full) ---

911 YYERROR;
912
913 memset(&r, 0, sizeof(r));
914
915 r.action = $1.b1;
916 r.direction = $2;
917
918 r.log = $3.log;
919 r.logif = $3.logif;
789 if ($3.quick) {
790 yyerror("scrub rules do not support 'quick'");
791 YYERROR;
792 }
793
794 r.af = $5;
795 if ($8.nodf)
796 r.rule_flag |= PFRULE_NODF;

--- 8 unchanged lines hidden (view full) ---

805 r.rule_flag |= PFRULE_REASSEMBLE_TCP;
806 }
807 if ($8.minttl)
808 r.min_ttl = $8.minttl;
809 if ($8.maxmss)
810 r.max_mss = $8.maxmss;
811 if ($8.fragcache)
812 r.rule_flag |= $8.fragcache;
920 if ($3.quick) {
921 yyerror("scrub rules do not support 'quick'");
922 YYERROR;
923 }
924
925 r.af = $5;
926 if ($8.nodf)
927 r.rule_flag |= PFRULE_NODF;

--- 8 unchanged lines hidden (view full) ---

936 r.rule_flag |= PFRULE_REASSEMBLE_TCP;
937 }
938 if ($8.minttl)
939 r.min_ttl = $8.minttl;
940 if ($8.maxmss)
941 r.max_mss = $8.maxmss;
942 if ($8.fragcache)
943 r.rule_flag |= $8.fragcache;
944 r.rtableid = $8.rtableid;
813
814 expand_rule(&r, $4, NULL, $6, $7.src_os,
815 $7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
816 NULL, NULL, NULL, "");
817 }
818 ;
819
820scrub_opts : {
945
946 expand_rule(&r, $4, NULL, $6, $7.src_os,
947 $7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
948 NULL, NULL, NULL, "");
949 }
950 ;
951
952scrub_opts : {
821 bzero(&scrub_opts, sizeof scrub_opts);
822 }
953 bzero(&scrub_opts, sizeof scrub_opts);
954 scrub_opts.rtableid = -1;
955 }
823 scrub_opts_l
824 { $$ = scrub_opts; }
825 | /* empty */ {
826 bzero(&scrub_opts, sizeof scrub_opts);
956 scrub_opts_l
957 { $$ = scrub_opts; }
958 | /* empty */ {
959 bzero(&scrub_opts, sizeof scrub_opts);
960 scrub_opts.rtableid = -1;
827 $$ = scrub_opts;
828 }
829 ;
830
831scrub_opts_l : scrub_opts_l scrub_opt
832 | scrub_opt
833 ;
834

--- 52 unchanged lines hidden (view full) ---

887 }
888 | RANDOMID {
889 if (scrub_opts.randomid) {
890 yyerror("random-id cannot be respecified");
891 YYERROR;
892 }
893 scrub_opts.randomid = 1;
894 }
961 $$ = scrub_opts;
962 }
963 ;
964
965scrub_opts_l : scrub_opts_l scrub_opt
966 | scrub_opt
967 ;
968

--- 52 unchanged lines hidden (view full) ---

1021 }
1022 | RANDOMID {
1023 if (scrub_opts.randomid) {
1024 yyerror("random-id cannot be respecified");
1025 YYERROR;
1026 }
1027 scrub_opts.randomid = 1;
1028 }
1029 | RTABLE number {
1030#ifdef __FreeBSD__
1031 yyerror("rtable id not supported in FreeBSD, yet");
1032 YYERROR;
1033#else
1034 if ($2 > RT_TABLEID_MAX || $2 < 0) {
1035 yyerror("invalid rtable id");
1036 YYERROR;
1037 }
1038 scrub_opts.rtableid = $2;
1039#endif
1040 }
895 ;
896
897fragcache : FRAGMENT REASSEMBLE { $$ = 0; /* default */ }
898 | FRAGMENT FRAGCROP { $$ = PFRULE_FRAGCROP; }
899 | FRAGMENT FRAGDROP { $$ = PFRULE_FRAGDROP; }
900 ;
901
902antispoof : ANTISPOOF logquick antispoof_ifspc af antispoof_opts {

--- 5 unchanged lines hidden (view full) ---

908 YYERROR;
909
910 for (i = $3; i; i = i->next) {
911 bzero(&r, sizeof(r));
912
913 r.action = PF_DROP;
914 r.direction = PF_IN;
915 r.log = $2.log;
1041 ;
1042
1043fragcache : FRAGMENT REASSEMBLE { $$ = 0; /* default */ }
1044 | FRAGMENT FRAGCROP { $$ = PFRULE_FRAGCROP; }
1045 | FRAGMENT FRAGDROP { $$ = PFRULE_FRAGDROP; }
1046 ;
1047
1048antispoof : ANTISPOOF logquick antispoof_ifspc af antispoof_opts {

--- 5 unchanged lines hidden (view full) ---

1054 YYERROR;
1055
1056 for (i = $3; i; i = i->next) {
1057 bzero(&r, sizeof(r));
1058
1059 r.action = PF_DROP;
1060 r.direction = PF_IN;
1061 r.log = $2.log;
1062 r.logif = $2.logif;
916 r.quick = $2.quick;
917 r.af = $4;
918 if (rule_label(&r, $5.label))
919 YYERROR;
1063 r.quick = $2.quick;
1064 r.af = $4;
1065 if (rule_label(&r, $5.label))
1066 YYERROR;
1067 r.rtableid = $5.rtableid;
920 j = calloc(1, sizeof(struct node_if));
921 if (j == NULL)
922 err(1, "antispoof: calloc");
923 if (strlcpy(j->ifname, i->ifname,
924 sizeof(j->ifname)) >= sizeof(j->ifname)) {
925 free(j);
926 yyerror("interface name too long");
927 YYERROR;

--- 34 unchanged lines hidden (view full) ---

962
963 r.action = PF_DROP;
964 r.direction = PF_IN;
965 r.log = $2.log;
966 r.quick = $2.quick;
967 r.af = $4;
968 if (rule_label(&r, $5.label))
969 YYERROR;
1068 j = calloc(1, sizeof(struct node_if));
1069 if (j == NULL)
1070 err(1, "antispoof: calloc");
1071 if (strlcpy(j->ifname, i->ifname,
1072 sizeof(j->ifname)) >= sizeof(j->ifname)) {
1073 free(j);
1074 yyerror("interface name too long");
1075 YYERROR;

--- 34 unchanged lines hidden (view full) ---

1110
1111 r.action = PF_DROP;
1112 r.direction = PF_IN;
1113 r.log = $2.log;
1114 r.quick = $2.quick;
1115 r.af = $4;
1116 if (rule_label(&r, $5.label))
1117 YYERROR;
1118 r.rtableid = $5.rtableid;
970 if (hh != NULL)
971 h = hh;
972 else
973 h = ifa_lookup(i->ifname, 0);
974 if (h != NULL)
975 expand_rule(&r, NULL, NULL,
976 NULL, NULL, h, NULL, NULL,
977 NULL, NULL, NULL, NULL, "");

--- 18 unchanged lines hidden (view full) ---

996
997antispoof_if : if_item { $$ = $1; }
998 | '(' if_item ')' {
999 $2->dynamic = 1;
1000 $$ = $2;
1001 }
1002 ;
1003
1119 if (hh != NULL)
1120 h = hh;
1121 else
1122 h = ifa_lookup(i->ifname, 0);
1123 if (h != NULL)
1124 expand_rule(&r, NULL, NULL,
1125 NULL, NULL, h, NULL, NULL,
1126 NULL, NULL, NULL, NULL, "");

--- 18 unchanged lines hidden (view full) ---

1145
1146antispoof_if : if_item { $$ = $1; }
1147 | '(' if_item ')' {
1148 $2->dynamic = 1;
1149 $$ = $2;
1150 }
1151 ;
1152
1004antispoof_opts : { bzero(&antispoof_opts, sizeof antispoof_opts); }
1153antispoof_opts : {
1154 bzero(&antispoof_opts, sizeof antispoof_opts);
1155 antispoof_opts.rtableid = -1;
1156 }
1005 antispoof_opts_l
1006 { $$ = antispoof_opts; }
1007 | /* empty */ {
1008 bzero(&antispoof_opts, sizeof antispoof_opts);
1157 antispoof_opts_l
1158 { $$ = antispoof_opts; }
1159 | /* empty */ {
1160 bzero(&antispoof_opts, sizeof antispoof_opts);
1161 antispoof_opts.rtableid = -1;
1009 $$ = antispoof_opts;
1010 }
1011 ;
1012
1013antispoof_opts_l : antispoof_opts_l antispoof_opt
1014 | antispoof_opt
1015 ;
1016
1017antispoof_opt : label {
1018 if (antispoof_opts.label) {
1019 yyerror("label cannot be redefined");
1020 YYERROR;
1021 }
1022 antispoof_opts.label = $1;
1023 }
1162 $$ = antispoof_opts;
1163 }
1164 ;
1165
1166antispoof_opts_l : antispoof_opts_l antispoof_opt
1167 | antispoof_opt
1168 ;
1169
1170antispoof_opt : label {
1171 if (antispoof_opts.label) {
1172 yyerror("label cannot be redefined");
1173 YYERROR;
1174 }
1175 antispoof_opts.label = $1;
1176 }
1177 | RTABLE number {
1178#ifdef __FreeBSD__
1179 yyerror("rtable id not supported in FreeBSD, yet");
1180 YYERROR;
1181#else
1182 if ($2 > RT_TABLEID_MAX || $2 < 0) {
1183 yyerror("invalid rtable id");
1184 YYERROR;
1185 }
1186 antispoof_opts.rtableid = $2;
1187#endif
1188 }
1024 ;
1025
1026not : '!' { $$ = 1; }
1027 | /* empty */ { $$ = 0; }
1028 ;
1029
1030tabledef : TABLE '<' STRING '>' table_opts {
1031 struct node_host *h, *nh;

--- 70 unchanged lines hidden (view full) ---

1102 break;
1103 case PF_ADDR_TABLE:
1104 yyerror("tables cannot contain tables");
1105 break;
1106 case PF_ADDR_NOROUTE:
1107 yyerror("\"no-route\" is not permitted "
1108 "inside tables");
1109 break;
1189 ;
1190
1191not : '!' { $$ = 1; }
1192 | /* empty */ { $$ = 0; }
1193 ;
1194
1195tabledef : TABLE '<' STRING '>' table_opts {
1196 struct node_host *h, *nh;

--- 70 unchanged lines hidden (view full) ---

1267 break;
1268 case PF_ADDR_TABLE:
1269 yyerror("tables cannot contain tables");
1270 break;
1271 case PF_ADDR_NOROUTE:
1272 yyerror("\"no-route\" is not permitted "
1273 "inside tables");
1274 break;
1275 case PF_ADDR_URPFFAILED:
1276 yyerror("\"urpf-failed\" is not "
1277 "permitted inside tables");
1278 break;
1110 default:
1111 yyerror("unknown address type %d",
1112 n->addr.type);
1113 }
1114 YYERROR;
1115 }
1116 if (!(ti = calloc(1, sizeof(*ti))))
1117 err(1, "table_opt: calloc");

--- 383 unchanged lines hidden (view full) ---

1501pfrule : action dir logquick interface route af proto fromto
1502 filter_opts
1503 {
1504 struct pf_rule r;
1505 struct node_state_opt *o;
1506 struct node_proto *proto;
1507 int srctrack = 0;
1508 int statelock = 0;
1279 default:
1280 yyerror("unknown address type %d",
1281 n->addr.type);
1282 }
1283 YYERROR;
1284 }
1285 if (!(ti = calloc(1, sizeof(*ti))))
1286 err(1, "table_opt: calloc");

--- 383 unchanged lines hidden (view full) ---

1670pfrule : action dir logquick interface route af proto fromto
1671 filter_opts
1672 {
1673 struct pf_rule r;
1674 struct node_state_opt *o;
1675 struct node_proto *proto;
1676 int srctrack = 0;
1677 int statelock = 0;
1678 int adaptive = 0;
1509
1510 if (check_rulestate(PFCTL_STATE_FILTER))
1511 YYERROR;
1512
1513 memset(&r, 0, sizeof(r));
1514
1515 r.action = $1.b1;
1516 switch ($1.b2) {

--- 9 unchanged lines hidden (view full) ---

1526 case PFRULE_RETURN:
1527 r.rule_flag |= PFRULE_RETURN;
1528 r.return_icmp = $1.w;
1529 r.return_icmp6 = $1.w2;
1530 break;
1531 }
1532 r.direction = $2;
1533 r.log = $3.log;
1679
1680 if (check_rulestate(PFCTL_STATE_FILTER))
1681 YYERROR;
1682
1683 memset(&r, 0, sizeof(r));
1684
1685 r.action = $1.b1;
1686 switch ($1.b2) {

--- 9 unchanged lines hidden (view full) ---

1696 case PFRULE_RETURN:
1697 r.rule_flag |= PFRULE_RETURN;
1698 r.return_icmp = $1.w;
1699 r.return_icmp6 = $1.w2;
1700 break;
1701 }
1702 r.direction = $2;
1703 r.log = $3.log;
1704 r.logif = $3.logif;
1534 r.quick = $3.quick;
1535 r.prob = $9.prob;
1705 r.quick = $3.quick;
1706 r.prob = $9.prob;
1707 r.rtableid = $9.rtableid;
1536
1537 r.af = $6;
1538 if ($9.tag)
1539 if (strlcpy(r.tagname, $9.tag,
1540 PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
1541 yyerror("tag too long, max %u chars",
1542 PF_TAG_NAME_SIZE - 1);
1543 YYERROR;
1544 }
1545 if ($9.match_tag)
1546 if (strlcpy(r.match_tagname, $9.match_tag,
1547 PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
1548 yyerror("tag too long, max %u chars",
1549 PF_TAG_NAME_SIZE - 1);
1550 YYERROR;
1551 }
1552 r.match_tag_not = $9.match_tag_not;
1708
1709 r.af = $6;
1710 if ($9.tag)
1711 if (strlcpy(r.tagname, $9.tag,
1712 PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
1713 yyerror("tag too long, max %u chars",
1714 PF_TAG_NAME_SIZE - 1);
1715 YYERROR;
1716 }
1717 if ($9.match_tag)
1718 if (strlcpy(r.match_tagname, $9.match_tag,
1719 PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
1720 yyerror("tag too long, max %u chars",
1721 PF_TAG_NAME_SIZE - 1);
1722 YYERROR;
1723 }
1724 r.match_tag_not = $9.match_tag_not;
1553 r.flags = $9.flags.b1;
1554 r.flagset = $9.flags.b2;
1555 if (rule_label(&r, $9.label))
1556 YYERROR;
1557 free($9.label);
1725 if (rule_label(&r, $9.label))
1726 YYERROR;
1727 free($9.label);
1728 r.flags = $9.flags.b1;
1729 r.flagset = $9.flags.b2;
1730 if (($9.flags.b1 & $9.flags.b2) != $9.flags.b1) {
1731 yyerror("flags always false");
1732 YYERROR;
1733 }
1558 if ($9.flags.b1 || $9.flags.b2 || $8.src_os) {
1559 for (proto = $7; proto != NULL &&
1560 proto->proto != IPPROTO_TCP;
1561 proto = proto->next)
1562 ; /* nothing */
1563 if (proto == NULL && $7 != NULL) {
1564 if ($9.flags.b1 || $9.flags.b2)
1565 yyerror(

--- 11 unchanged lines hidden (view full) ---

1577 "the SYN TCP flag (flags S/SA)");
1578 YYERROR;
1579 }
1580#endif
1581 }
1582
1583 r.tos = $9.tos;
1584 r.keep_state = $9.keep.action;
1734 if ($9.flags.b1 || $9.flags.b2 || $8.src_os) {
1735 for (proto = $7; proto != NULL &&
1736 proto->proto != IPPROTO_TCP;
1737 proto = proto->next)
1738 ; /* nothing */
1739 if (proto == NULL && $7 != NULL) {
1740 if ($9.flags.b1 || $9.flags.b2)
1741 yyerror(

--- 11 unchanged lines hidden (view full) ---

1753 "the SYN TCP flag (flags S/SA)");
1754 YYERROR;
1755 }
1756#endif
1757 }
1758
1759 r.tos = $9.tos;
1760 r.keep_state = $9.keep.action;
1761
1762 /* 'keep state' by default on pass rules. */
1763 if (!r.keep_state && !r.action &&
1764 !($9.marker & FOM_KEEP))
1765 r.keep_state = PF_STATE_NORMAL;
1766
1585 o = $9.keep.options;
1586 while (o) {
1587 struct node_state_opt *p = o;
1588
1589 switch (o->type) {
1590 case PF_STATE_OPT_MAX:
1591 if (r.max_states) {
1592 yyerror("state option 'max' "

--- 80 unchanged lines hidden (view full) ---

1673 !o->data.max_src_conn_rate.seconds) {
1674 yyerror("'max-src-conn-rate' "
1675 "values must be > 0");
1676 YYERROR;
1677 }
1678 if (o->data.max_src_conn_rate.limit >
1679 PF_THRESHOLD_MAX) {
1680 yyerror("'max-src-conn-rate' "
1767 o = $9.keep.options;
1768 while (o) {
1769 struct node_state_opt *p = o;
1770
1771 switch (o->type) {
1772 case PF_STATE_OPT_MAX:
1773 if (r.max_states) {
1774 yyerror("state option 'max' "

--- 80 unchanged lines hidden (view full) ---

1855 !o->data.max_src_conn_rate.seconds) {
1856 yyerror("'max-src-conn-rate' "
1857 "values must be > 0");
1858 YYERROR;
1859 }
1860 if (o->data.max_src_conn_rate.limit >
1861 PF_THRESHOLD_MAX) {
1862 yyerror("'max-src-conn-rate' "
1681 "maximum rate must be < %u",
1682 PF_THRESHOLD_MAX);
1863 "maximum rate must be < %u",
1864 PF_THRESHOLD_MAX);
1683 YYERROR;
1684 }
1685 r.max_src_conn_rate.limit =
1686 o->data.max_src_conn_rate.limit;
1687 r.max_src_conn_rate.seconds =
1688 o->data.max_src_conn_rate.seconds;
1689 r.rule_flag |= PFRULE_SRCTRACK |
1690 PFRULE_RULESRCTRACK;

--- 20 unchanged lines hidden (view full) ---

1711 yyerror("state locking option: "
1712 "multiple definitions");
1713 YYERROR;
1714 }
1715 statelock = 1;
1716 r.rule_flag |= o->data.statelock;
1717 break;
1718 case PF_STATE_OPT_TIMEOUT:
1865 YYERROR;
1866 }
1867 r.max_src_conn_rate.limit =
1868 o->data.max_src_conn_rate.limit;
1869 r.max_src_conn_rate.seconds =
1870 o->data.max_src_conn_rate.seconds;
1871 r.rule_flag |= PFRULE_SRCTRACK |
1872 PFRULE_RULESRCTRACK;

--- 20 unchanged lines hidden (view full) ---

1893 yyerror("state locking option: "
1894 "multiple definitions");
1895 YYERROR;
1896 }
1897 statelock = 1;
1898 r.rule_flag |= o->data.statelock;
1899 break;
1900 case PF_STATE_OPT_TIMEOUT:
1901 if (o->data.timeout.number ==
1902 PFTM_ADAPTIVE_START ||
1903 o->data.timeout.number ==
1904 PFTM_ADAPTIVE_END)
1905 adaptive = 1;
1719 if (r.timeout[o->data.timeout.number]) {
1720 yyerror("state timeout %s "
1721 "multiple definitions",
1722 pf_timeouts[o->data.
1723 timeout.number].name);
1724 YYERROR;
1725 }
1726 r.timeout[o->data.timeout.number] =
1727 o->data.timeout.seconds;
1728 }
1729 o = o->next;
1730 free(p);
1731 }
1906 if (r.timeout[o->data.timeout.number]) {
1907 yyerror("state timeout %s "
1908 "multiple definitions",
1909 pf_timeouts[o->data.
1910 timeout.number].name);
1911 YYERROR;
1912 }
1913 r.timeout[o->data.timeout.number] =
1914 o->data.timeout.seconds;
1915 }
1916 o = o->next;
1917 free(p);
1918 }
1919
1920 /* 'flags S/SA' by default on stateful rules */
1921 if (!r.action && !r.flags && !r.flagset &&
1922 !$9.fragment && !($9.marker & FOM_FLAGS) &&
1923 r.keep_state) {
1924 r.flags = parse_flags("S");
1925 r.flagset = parse_flags("SA");
1926 }
1927 if (!adaptive && r.max_states) {
1928 r.timeout[PFTM_ADAPTIVE_START] =
1929 (r.max_states / 10) * 6;
1930 r.timeout[PFTM_ADAPTIVE_END] =
1931 (r.max_states / 10) * 12;
1932 }
1732 if (r.rule_flag & PFRULE_SRCTRACK) {
1733 if (srctrack == PF_SRCTRACK_GLOBAL &&
1734 r.max_src_nodes) {
1735 yyerror("'max-src-nodes' is "
1736 "incompatible with "
1737 "'source-track global'");
1738 YYERROR;
1739 }

--- 94 unchanged lines hidden (view full) ---

1834 }
1835
1836 expand_rule(&r, $4, $5.host, $7, $8.src_os,
1837 $8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
1838 $9.uid, $9.gid, $9.icmpspec, "");
1839 }
1840 ;
1841
1933 if (r.rule_flag & PFRULE_SRCTRACK) {
1934 if (srctrack == PF_SRCTRACK_GLOBAL &&
1935 r.max_src_nodes) {
1936 yyerror("'max-src-nodes' is "
1937 "incompatible with "
1938 "'source-track global'");
1939 YYERROR;
1940 }

--- 94 unchanged lines hidden (view full) ---

2035 }
2036
2037 expand_rule(&r, $4, $5.host, $7, $8.src_os,
2038 $8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
2039 $9.uid, $9.gid, $9.icmpspec, "");
2040 }
2041 ;
2042
1842filter_opts : { bzero(&filter_opts, sizeof filter_opts); }
2043filter_opts : {
2044 bzero(&filter_opts, sizeof filter_opts);
2045 filter_opts.rtableid = -1;
2046 }
1843 filter_opts_l
1844 { $$ = filter_opts; }
1845 | /* empty */ {
1846 bzero(&filter_opts, sizeof filter_opts);
2047 filter_opts_l
2048 { $$ = filter_opts; }
2049 | /* empty */ {
2050 bzero(&filter_opts, sizeof filter_opts);
2051 filter_opts.rtableid = -1;
1847 $$ = filter_opts;
1848 }
1849 ;
1850
1851filter_opts_l : filter_opts_l filter_opt
1852 | filter_opt
1853 ;
1854

--- 87 unchanged lines hidden (view full) ---

1942 if (p < 1.0 || p >= (UINT_MAX+1.0)) {
1943 yyerror("invalid probability: %s", $2);
1944 free($2);
1945 YYERROR;
1946 }
1947 filter_opts.prob = (u_int32_t)p;
1948 free($2);
1949 }
2052 $$ = filter_opts;
2053 }
2054 ;
2055
2056filter_opts_l : filter_opts_l filter_opt
2057 | filter_opt
2058 ;
2059

--- 87 unchanged lines hidden (view full) ---

2147 if (p < 1.0 || p >= (UINT_MAX+1.0)) {
2148 yyerror("invalid probability: %s", $2);
2149 free($2);
2150 YYERROR;
2151 }
2152 filter_opts.prob = (u_int32_t)p;
2153 free($2);
2154 }
2155 | RTABLE number {
2156#ifdef __FreeBSD__
2157 yyerror("rtable id not supported in FreeBSD, yet");
2158 YYERROR;
2159#else
2160 if ($2 > RT_TABLEID_MAX || $2 < 0) {
2161 yyerror("invalid rtable id");
2162 YYERROR;
2163 }
2164 filter_opts.rtableid = $2;
2165#endif
2166 }
1950 ;
1951
1952action : PASS { $$.b1 = PF_PASS; $$.b2 = $$.w = 0; }
1953 | BLOCK blockspec { $$ = $2; $$.b1 = PF_DROP; }
1954 ;
1955
1956blockspec : /* empty */ {
1957 $$.b2 = blockpolicy;

--- 65 unchanged lines hidden (view full) ---

2023 }
2024 ;
2025
2026dir : /* empty */ { $$ = 0; }
2027 | IN { $$ = PF_IN; }
2028 | OUT { $$ = PF_OUT; }
2029 ;
2030
2167 ;
2168
2169action : PASS { $$.b1 = PF_PASS; $$.b2 = $$.w = 0; }
2170 | BLOCK blockspec { $$ = $2; $$.b1 = PF_DROP; }
2171 ;
2172
2173blockspec : /* empty */ {
2174 $$.b2 = blockpolicy;

--- 65 unchanged lines hidden (view full) ---

2240 }
2241 ;
2242
2243dir : /* empty */ { $$ = 0; }
2244 | IN { $$ = PF_IN; }
2245 | OUT { $$ = PF_OUT; }
2246 ;
2247
2031logquick : /* empty */ { $$.log = 0; $$.quick = 0; }
2032 | log { $$.log = $1; $$.quick = 0; }
2033 | QUICK { $$.log = 0; $$.quick = 1; }
2034 | log QUICK { $$.log = $1; $$.quick = 1; }
2035 | QUICK log { $$.log = $2; $$.quick = 1; }
2248quick : /* empty */ { $$.quick = 0; }
2249 | QUICK { $$.quick = 1; }
2036 ;
2037
2250 ;
2251
2038log : LOG { $$ = 1; }
2039 | LOGALL { $$ = 2; }
2252logquick : /* empty */ { $$.log = 0; $$.quick = 0; $$.logif = 0; }
2253 | log { $$ = $1; $$.quick = 0; }
2254 | QUICK { $$.quick = 1; $$.log = 0; $$.logif = 0; }
2255 | log QUICK { $$ = $1; $$.quick = 1; }
2256 | QUICK log { $$ = $2; $$.quick = 1; }
2040 ;
2041
2257 ;
2258
2259log : LOG { $$.log = PF_LOG; $$.logif = 0; }
2260 | LOG '(' logopts ')' {
2261 $$.log = PF_LOG | $3.log;
2262 $$.logif = $3.logif;
2263 }
2264 ;
2265
2266logopts : logopt { $$ = $1; }
2267 | logopts comma logopt {
2268 $$.log = $1.log | $3.log;
2269 $$.logif = $3.logif;
2270 if ($$.logif == 0)
2271 $$.logif = $1.logif;
2272 }
2273 ;
2274
2275logopt : ALL { $$.log = PF_LOG_ALL; $$.logif = 0; }
2276 | USER { $$.log = PF_LOG_SOCKET_LOOKUP; $$.logif = 0; }
2277 | GROUP { $$.log = PF_LOG_SOCKET_LOOKUP; $$.logif = 0; }
2278 | TO string {
2279 const char *errstr;
2280 u_int i;
2281
2282 $$.log = 0;
2283 if (strncmp($2, "pflog", 5)) {
2284 yyerror("%s: should be a pflog interface", $2);
2285 free($2);
2286 YYERROR;
2287 }
2288 i = strtonum($2 + 5, 0, 255, &errstr);
2289 if (errstr) {
2290 yyerror("%s: %s", $2, errstr);
2291 free($2);
2292 YYERROR;
2293 }
2294 free($2);
2295 $$.logif = i;
2296 }
2297 ;
2298
2042interface : /* empty */ { $$ = NULL; }
2043 | ON if_item_not { $$ = $2; }
2044 | ON '{' if_list '}' { $$ = $3; }
2045 ;
2046
2047if_list : if_item_not { $$ = $1; }
2048 | if_list comma if_item_not {
2049 $1->tail->next = $3;

--- 14 unchanged lines hidden (view full) ---

2064 if (strlcpy($$->ifname, $1, sizeof($$->ifname)) >=
2065 sizeof($$->ifname)) {
2066 free($1);
2067 free($$);
2068 yyerror("interface name too long");
2069 YYERROR;
2070 }
2071
2299interface : /* empty */ { $$ = NULL; }
2300 | ON if_item_not { $$ = $2; }
2301 | ON '{' if_list '}' { $$ = $3; }
2302 ;
2303
2304if_list : if_item_not { $$ = $1; }
2305 | if_list comma if_item_not {
2306 $1->tail->next = $3;

--- 14 unchanged lines hidden (view full) ---

2321 if (strlcpy($$->ifname, $1, sizeof($$->ifname)) >=
2322 sizeof($$->ifname)) {
2323 free($1);
2324 free($$);
2325 yyerror("interface name too long");
2326 YYERROR;
2327 }
2328
2072 if ((n = ifa_exists($1, 1)) != NULL)
2329 if ((n = ifa_exists($1)) != NULL)
2073 $$->ifa_flags = n->ifa_flags;
2074
2075 free($1);
2076 $$->not = 0;
2077 $$->next = NULL;
2078 $$->tail = $$;
2079 }
2080 ;

--- 97 unchanged lines hidden (view full) ---

2178 }
2179 ;
2180
2181to : /* empty */ {
2182 $$.host = NULL;
2183 $$.port = NULL;
2184 }
2185 | TO ipportspec {
2330 $$->ifa_flags = n->ifa_flags;
2331
2332 free($1);
2333 $$->not = 0;
2334 $$->next = NULL;
2335 $$->tail = $$;
2336 }
2337 ;

--- 97 unchanged lines hidden (view full) ---

2435 }
2436 ;
2437
2438to : /* empty */ {
2439 $$.host = NULL;
2440 $$.port = NULL;
2441 }
2442 | TO ipportspec {
2443 if (disallow_urpf_failed($2.host, "\"urpf-failed\" is "
2444 "not permitted in a destination address"))
2445 YYERROR;
2186 $$ = $2;
2187 }
2188 ;
2189
2190ipportspec : ipspec {
2191 $$.host = $1;
2192 $$.port = NULL;
2193 }

--- 7 unchanged lines hidden (view full) ---

2201 }
2202 ;
2203
2204ipspec : ANY { $$ = NULL; }
2205 | xhost { $$ = $1; }
2206 | '{' host_list '}' { $$ = $2; }
2207 ;
2208
2446 $$ = $2;
2447 }
2448 ;
2449
2450ipportspec : ipspec {
2451 $$.host = $1;
2452 $$.port = NULL;
2453 }

--- 7 unchanged lines hidden (view full) ---

2461 }
2462 ;
2463
2464ipspec : ANY { $$ = NULL; }
2465 | xhost { $$ = $1; }
2466 | '{' host_list '}' { $$ = $2; }
2467 ;
2468
2209host_list : xhost { $$ = $1; }
2210 | host_list comma xhost {
2469host_list : ipspec { $$ = $1; }
2470 | host_list comma ipspec {
2211 if ($3 == NULL)
2212 $$ = $1;
2213 else if ($1 == NULL)
2214 $$ = $3;
2215 else {
2216 $1->tail->next = $3;
2217 $1->tail = $3->tail;
2218 $$ = $1;
2219 }
2220 }
2221 ;
2222
2223xhost : not host {
2224 struct node_host *n;
2225
2226 for (n = $2; n != NULL; n = n->next)
2227 n->not = $1;
2228 $$ = $2;
2229 }
2471 if ($3 == NULL)
2472 $$ = $1;
2473 else if ($1 == NULL)
2474 $$ = $3;
2475 else {
2476 $1->tail->next = $3;
2477 $1->tail = $3->tail;
2478 $$ = $1;
2479 }
2480 }
2481 ;
2482
2483xhost : not host {
2484 struct node_host *n;
2485
2486 for (n = $2; n != NULL; n = n->next)
2487 n->not = $1;
2488 $$ = $2;
2489 }
2230 | NOROUTE {
2490 | not NOROUTE {
2231 $$ = calloc(1, sizeof(struct node_host));
2232 if ($$ == NULL)
2233 err(1, "xhost: calloc");
2234 $$->addr.type = PF_ADDR_NOROUTE;
2235 $$->next = NULL;
2491 $$ = calloc(1, sizeof(struct node_host));
2492 if ($$ == NULL)
2493 err(1, "xhost: calloc");
2494 $$->addr.type = PF_ADDR_NOROUTE;
2495 $$->next = NULL;
2496 $$->not = $1;
2236 $$->tail = $$;
2237 }
2497 $$->tail = $$;
2498 }
2499 | not URPFFAILED {
2500 $$ = calloc(1, sizeof(struct node_host));
2501 if ($$ == NULL)
2502 err(1, "xhost: calloc");
2503 $$->addr.type = PF_ADDR_URPFFAILED;
2504 $$->next = NULL;
2505 $$->not = $1;
2506 $$->tail = $$;
2507 }
2238 ;
2239
2240host : STRING {
2241 if (($$ = host($1)) == NULL) {
2242 /* error. "any" is handled elsewhere */
2243 free($1);
2244 yyerror("could not parse host specification");
2245 YYERROR;

--- 184 unchanged lines hidden (view full) ---

2430 $$->op = $2;
2431 $$->next = NULL;
2432 $$->tail = $$;
2433 }
2434 ;
2435
2436port : STRING {
2437 char *p = strchr($1, ':');
2508 ;
2509
2510host : STRING {
2511 if (($$ = host($1)) == NULL) {
2512 /* error. "any" is handled elsewhere */
2513 free($1);
2514 yyerror("could not parse host specification");
2515 YYERROR;

--- 184 unchanged lines hidden (view full) ---

2700 $$->op = $2;
2701 $$->next = NULL;
2702 $$->tail = $$;
2703 }
2704 ;
2705
2706port : STRING {
2707 char *p = strchr($1, ':');
2438 struct servent *s = NULL;
2439 u_long ulval;
2440
2441 if (p == NULL) {
2708
2709 if (p == NULL) {
2442 if (atoul($1, &ulval) == 0) {
2443 if (ulval > 65535) {
2444 free($1);
2445 yyerror("illegal port value %lu",
2446 ulval);
2447 YYERROR;
2448 }
2449 $$.a = htons(ulval);
2450 } else {
2451 s = getservbyname($1, "tcp");
2452 if (s == NULL)
2453 s = getservbyname($1, "udp");
2454 if (s == NULL) {
2455 yyerror("unknown port %s", $1);
2456 free($1);
2457 YYERROR;
2458 }
2459 $$.a = s->s_port;
2710 if (($$.a = getservice($1)) == -1) {
2711 free($1);
2712 YYERROR;
2460 }
2713 }
2461 $$.b = 0;
2462 $$.t = 0;
2714 $$.b = $$.t = 0;
2463 } else {
2464 int port[2];
2465
2466 *p++ = 0;
2467 if ((port[0] = getservice($1)) == -1 ||
2468 (port[1] = getservice(p)) == -1) {
2469 free($1);
2470 YYERROR;

--- 180 unchanged lines hidden (view full) ---

2651 }
2652 free($1);
2653 $$.b1 = f;
2654 }
2655 ;
2656
2657flags : FLAGS flag '/' flag { $$.b1 = $2.b1; $$.b2 = $4.b1; }
2658 | FLAGS '/' flag { $$.b1 = 0; $$.b2 = $3.b1; }
2715 } else {
2716 int port[2];
2717
2718 *p++ = 0;
2719 if ((port[0] = getservice($1)) == -1 ||
2720 (port[1] = getservice(p)) == -1) {
2721 free($1);
2722 YYERROR;

--- 180 unchanged lines hidden (view full) ---

2903 }
2904 free($1);
2905 $$.b1 = f;
2906 }
2907 ;
2908
2909flags : FLAGS flag '/' flag { $$.b1 = $2.b1; $$.b2 = $4.b1; }
2910 | FLAGS '/' flag { $$.b1 = 0; $$.b2 = $3.b1; }
2911 | FLAGS ANY { $$.b1 = 0; $$.b2 = 0; }
2659 ;
2660
2661icmpspec : ICMPTYPE icmp_item { $$ = $2; }
2662 | ICMPTYPE '{' icmp_list '}' { $$ = $3; }
2663 | ICMP6TYPE icmp6_item { $$ = $2; }
2664 | ICMP6TYPE '{' icmp6_list '}' { $$ = $3; }
2665 ;
2666

--- 121 unchanged lines hidden (view full) ---

2788 ;
2789
2790icmp6type : STRING {
2791 const struct icmptypeent *p;
2792 u_long ulval;
2793
2794 if (atoul($1, &ulval) == 0) {
2795 if (ulval > 255) {
2912 ;
2913
2914icmpspec : ICMPTYPE icmp_item { $$ = $2; }
2915 | ICMPTYPE '{' icmp_list '}' { $$ = $3; }
2916 | ICMP6TYPE icmp6_item { $$ = $2; }
2917 | ICMP6TYPE '{' icmp6_list '}' { $$ = $3; }
2918 ;
2919

--- 121 unchanged lines hidden (view full) ---

3041 ;
3042
3043icmp6type : STRING {
3044 const struct icmptypeent *p;
3045 u_long ulval;
3046
3047 if (atoul($1, &ulval) == 0) {
3048 if (ulval > 255) {
2796 yyerror("illegal icmp6-type %lu", ulval);
3049 yyerror("illegal icmp6-type %lu",
3050 ulval);
2797 free($1);
2798 YYERROR;
2799 }
2800 $$ = ulval + 1;
2801 } else {
2802 if ((p = geticmptypebyname($1, AF_INET6)) ==
2803 NULL) {
2804 yyerror("unknown icmp6-type %s", $1);

--- 29 unchanged lines hidden (view full) ---

2834sourcetrack : SOURCETRACK { $$ = PF_SRCTRACK; }
2835 | SOURCETRACK GLOBAL { $$ = PF_SRCTRACK_GLOBAL; }
2836 | SOURCETRACK RULE { $$ = PF_SRCTRACK_RULE; }
2837 ;
2838
2839statelock : IFBOUND {
2840 $$ = PFRULE_IFBOUND;
2841 }
3051 free($1);
3052 YYERROR;
3053 }
3054 $$ = ulval + 1;
3055 } else {
3056 if ((p = geticmptypebyname($1, AF_INET6)) ==
3057 NULL) {
3058 yyerror("unknown icmp6-type %s", $1);

--- 29 unchanged lines hidden (view full) ---

3088sourcetrack : SOURCETRACK { $$ = PF_SRCTRACK; }
3089 | SOURCETRACK GLOBAL { $$ = PF_SRCTRACK_GLOBAL; }
3090 | SOURCETRACK RULE { $$ = PF_SRCTRACK_RULE; }
3091 ;
3092
3093statelock : IFBOUND {
3094 $$ = PFRULE_IFBOUND;
3095 }
2842 | GRBOUND {
2843 $$ = PFRULE_GRBOUND;
2844 }
2845 | FLOATING {
2846 $$ = 0;
2847 }
2848 ;
2849
3096 | FLOATING {
3097 $$ = 0;
3098 }
3099 ;
3100
2850keep : KEEP STATE state_opt_spec {
3101keep : NO STATE {
3102 $$.action = 0;
3103 $$.options = NULL;
3104 }
3105 | KEEP STATE state_opt_spec {
2851 $$.action = PF_STATE_NORMAL;
2852 $$.options = $3;
2853 }
2854 | MODULATE STATE state_opt_spec {
2855 $$.action = PF_STATE_MODULATE;
2856 $$.options = $3;
2857 }
2858 | SYNPROXY STATE state_opt_spec {

--- 342 unchanged lines hidden (view full) ---

3201 $$ = calloc(1, sizeof(struct redirection));
3202 if ($$ == NULL)
3203 err(1, "redirection: calloc");
3204 $$->host = $2;
3205 $$->rport = $4;
3206 }
3207 ;
3208
3106 $$.action = PF_STATE_NORMAL;
3107 $$.options = $3;
3108 }
3109 | MODULATE STATE state_opt_spec {
3110 $$.action = PF_STATE_MODULATE;
3111 $$.options = $3;
3112 }
3113 | SYNPROXY STATE state_opt_spec {

--- 342 unchanged lines hidden (view full) ---

3456 $$ = calloc(1, sizeof(struct redirection));
3457 if ($$ == NULL)
3458 err(1, "redirection: calloc");
3459 $$->host = $2;
3460 $$->rport = $4;
3461 }
3462 ;
3463
3209natpass : /* empty */ { $$ = 0; }
3210 | PASS { $$ = 1; }
3464/* ifdef __FreeBSD__ */
3465natpass : /* empty */ { $$.b1 = $$.b2 = 0; $$.w2 = 0; }
3466 | PASS { $$.b1 = 1; $$.b2 = 0; $$.w2 = 0; }
3467/* else
3468natpass : empty { $$.b1 = $$.b2 = 0; }
3469 | PASS { $$.b1 = 1; $$.b2 = 0; }
3470 * endif */
3471 | PASS log { $$.b1 = 1; $$.b2 = $2.log; $$.w2 = $2.logif; }
3211 ;
3212
3213nataction : no NAT natpass {
3472 ;
3473
3474nataction : no NAT natpass {
3214 $$.b2 = $$.w = 0;
3475 if ($1 && $3.b1) {
3476 yyerror("\"pass\" not valid with \"no\"");
3477 YYERROR;
3478 }
3215 if ($1)
3216 $$.b1 = PF_NONAT;
3217 else
3218 $$.b1 = PF_NAT;
3479 if ($1)
3480 $$.b1 = PF_NONAT;
3481 else
3482 $$.b1 = PF_NAT;
3219 $$.b2 = $3;
3483 $$.b2 = $3.b1;
3484 $$.w = $3.b2;
3485 $$.w2 = $3.w2;
3220 }
3221 | no RDR natpass {
3486 }
3487 | no RDR natpass {
3222 $$.b2 = $$.w = 0;
3488 if ($1 && $3.b1) {
3489 yyerror("\"pass\" not valid with \"no\"");
3490 YYERROR;
3491 }
3223 if ($1)
3224 $$.b1 = PF_NORDR;
3225 else
3226 $$.b1 = PF_RDR;
3492 if ($1)
3493 $$.b1 = PF_NORDR;
3494 else
3495 $$.b1 = PF_RDR;
3227 $$.b2 = $3;
3496 $$.b2 = $3.b1;
3497 $$.w = $3.b2;
3498 $$.w2 = $3.w2;
3228 }
3229 ;
3230
3499 }
3500 ;
3501
3231natrule : nataction interface af proto fromto tag tagged redirpool pool_opts
3502natrule : nataction interface af proto fromto tag tagged rtable
3503 redirpool pool_opts
3232 {
3233 struct pf_rule r;
3234
3235 if (check_rulestate(PFCTL_STATE_NAT))
3236 YYERROR;
3237
3238 memset(&r, 0, sizeof(r));
3239
3240 r.action = $1.b1;
3241 r.natpass = $1.b2;
3504 {
3505 struct pf_rule r;
3506
3507 if (check_rulestate(PFCTL_STATE_NAT))
3508 YYERROR;
3509
3510 memset(&r, 0, sizeof(r));
3511
3512 r.action = $1.b1;
3513 r.natpass = $1.b2;
3514 r.log = $1.w;
3515 r.logif = $1.w2;
3242 r.af = $3;
3243
3244 if (!r.af) {
3245 if ($5.src.host && $5.src.host->af &&
3246 !$5.src.host->ifindex)
3247 r.af = $5.src.host->af;
3248 else if ($5.dst.host && $5.dst.host->af &&
3249 !$5.dst.host->ifindex)

--- 11 unchanged lines hidden (view full) ---

3261 if ($7.name)
3262 if (strlcpy(r.match_tagname, $7.name,
3263 PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
3264 yyerror("tag too long, max %u chars",
3265 PF_TAG_NAME_SIZE - 1);
3266 YYERROR;
3267 }
3268 r.match_tag_not = $7.neg;
3516 r.af = $3;
3517
3518 if (!r.af) {
3519 if ($5.src.host && $5.src.host->af &&
3520 !$5.src.host->ifindex)
3521 r.af = $5.src.host->af;
3522 else if ($5.dst.host && $5.dst.host->af &&
3523 !$5.dst.host->ifindex)

--- 11 unchanged lines hidden (view full) ---

3535 if ($7.name)
3536 if (strlcpy(r.match_tagname, $7.name,
3537 PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
3538 yyerror("tag too long, max %u chars",
3539 PF_TAG_NAME_SIZE - 1);
3540 YYERROR;
3541 }
3542 r.match_tag_not = $7.neg;
3543 r.rtableid = $8;
3269
3270 if (r.action == PF_NONAT || r.action == PF_NORDR) {
3544
3545 if (r.action == PF_NONAT || r.action == PF_NORDR) {
3271 if ($8 != NULL) {
3546 if ($9 != NULL) {
3272 yyerror("translation rule with 'no' "
3273 "does not need '->'");
3274 YYERROR;
3275 }
3276 } else {
3547 yyerror("translation rule with 'no' "
3548 "does not need '->'");
3549 YYERROR;
3550 }
3551 } else {
3277 if ($8 == NULL || $8->host == NULL) {
3552 if ($9 == NULL || $9->host == NULL) {
3278 yyerror("translation rule requires '-> "
3279 "address'");
3280 YYERROR;
3281 }
3553 yyerror("translation rule requires '-> "
3554 "address'");
3555 YYERROR;
3556 }
3282 if (!r.af && ! $8->host->ifindex)
3283 r.af = $8->host->af;
3557 if (!r.af && ! $9->host->ifindex)
3558 r.af = $9->host->af;
3284
3559
3285 remove_invalid_hosts(&$8->host, &r.af);
3286 if (invalid_redirect($8->host, r.af))
3560 remove_invalid_hosts(&$9->host, &r.af);
3561 if (invalid_redirect($9->host, r.af))
3287 YYERROR;
3562 YYERROR;
3288 if (check_netmask($8->host, r.af))
3563 if (check_netmask($9->host, r.af))
3289 YYERROR;
3290
3564 YYERROR;
3565
3291 r.rpool.proxy_port[0] = ntohs($8->rport.a);
3566 r.rpool.proxy_port[0] = ntohs($9->rport.a);
3292
3293 switch (r.action) {
3294 case PF_RDR:
3567
3568 switch (r.action) {
3569 case PF_RDR:
3295 if (!$8->rport.b && $8->rport.t &&
3570 if (!$9->rport.b && $9->rport.t &&
3296 $5.dst.port != NULL) {
3297 r.rpool.proxy_port[1] =
3571 $5.dst.port != NULL) {
3572 r.rpool.proxy_port[1] =
3298 ntohs($8->rport.a) +
3573 ntohs($9->rport.a) +
3299 (ntohs(
3300 $5.dst.port->port[1]) -
3301 ntohs(
3302 $5.dst.port->port[0]));
3303 } else
3304 r.rpool.proxy_port[1] =
3574 (ntohs(
3575 $5.dst.port->port[1]) -
3576 ntohs(
3577 $5.dst.port->port[0]));
3578 } else
3579 r.rpool.proxy_port[1] =
3305 ntohs($8->rport.b);
3580 ntohs($9->rport.b);
3306 break;
3307 case PF_NAT:
3308 r.rpool.proxy_port[1] =
3581 break;
3582 case PF_NAT:
3583 r.rpool.proxy_port[1] =
3309 ntohs($8->rport.b);
3584 ntohs($9->rport.b);
3310 if (!r.rpool.proxy_port[0] &&
3311 !r.rpool.proxy_port[1]) {
3312 r.rpool.proxy_port[0] =
3313 PF_NAT_PROXY_PORT_LOW;
3314 r.rpool.proxy_port[1] =
3315 PF_NAT_PROXY_PORT_HIGH;
3316 } else if (!r.rpool.proxy_port[1])
3317 r.rpool.proxy_port[1] =
3318 r.rpool.proxy_port[0];
3319 break;
3320 default:
3321 break;
3322 }
3323
3585 if (!r.rpool.proxy_port[0] &&
3586 !r.rpool.proxy_port[1]) {
3587 r.rpool.proxy_port[0] =
3588 PF_NAT_PROXY_PORT_LOW;
3589 r.rpool.proxy_port[1] =
3590 PF_NAT_PROXY_PORT_HIGH;
3591 } else if (!r.rpool.proxy_port[1])
3592 r.rpool.proxy_port[1] =
3593 r.rpool.proxy_port[0];
3594 break;
3595 default:
3596 break;
3597 }
3598
3324 r.rpool.opts = $9.type;
3599 r.rpool.opts = $10.type;
3325 if ((r.rpool.opts & PF_POOL_TYPEMASK) ==
3600 if ((r.rpool.opts & PF_POOL_TYPEMASK) ==
3326 PF_POOL_NONE && ($8->host->next != NULL ||
3327 $8->host->addr.type == PF_ADDR_TABLE ||
3328 DYNIF_MULTIADDR($8->host->addr)))
3601 PF_POOL_NONE && ($9->host->next != NULL ||
3602 $9->host->addr.type == PF_ADDR_TABLE ||
3603 DYNIF_MULTIADDR($9->host->addr)))
3329 r.rpool.opts = PF_POOL_ROUNDROBIN;
3330 if ((r.rpool.opts & PF_POOL_TYPEMASK) !=
3331 PF_POOL_ROUNDROBIN &&
3604 r.rpool.opts = PF_POOL_ROUNDROBIN;
3605 if ((r.rpool.opts & PF_POOL_TYPEMASK) !=
3606 PF_POOL_ROUNDROBIN &&
3332 disallow_table($8->host, "tables are only "
3607 disallow_table($9->host, "tables are only "
3333 "supported in round-robin redirection "
3334 "pools"))
3335 YYERROR;
3336 if ((r.rpool.opts & PF_POOL_TYPEMASK) !=
3337 PF_POOL_ROUNDROBIN &&
3608 "supported in round-robin redirection "
3609 "pools"))
3610 YYERROR;
3611 if ((r.rpool.opts & PF_POOL_TYPEMASK) !=
3612 PF_POOL_ROUNDROBIN &&
3338 disallow_alias($8->host, "interface (%s) "
3613 disallow_alias($9->host, "interface (%s) "
3339 "is only supported in round-robin "
3340 "redirection pools"))
3341 YYERROR;
3614 "is only supported in round-robin "
3615 "redirection pools"))
3616 YYERROR;
3342 if ($8->host->next != NULL) {
3617 if ($9->host->next != NULL) {
3343 if ((r.rpool.opts & PF_POOL_TYPEMASK) !=
3344 PF_POOL_ROUNDROBIN) {
3345 yyerror("only round-robin "
3346 "valid for multiple "
3347 "redirection addresses");
3348 YYERROR;
3349 }
3350 }
3351 }
3352
3618 if ((r.rpool.opts & PF_POOL_TYPEMASK) !=
3619 PF_POOL_ROUNDROBIN) {
3620 yyerror("only round-robin "
3621 "valid for multiple "
3622 "redirection addresses");
3623 YYERROR;
3624 }
3625 }
3626 }
3627
3353 if ($9.key != NULL)
3354 memcpy(&r.rpool.key, $9.key,
3628 if ($10.key != NULL)
3629 memcpy(&r.rpool.key, $10.key,
3355 sizeof(struct pf_poolhashkey));
3356
3630 sizeof(struct pf_poolhashkey));
3631
3357 if ($9.opts)
3358 r.rpool.opts |= $9.opts;
3632 if ($10.opts)
3633 r.rpool.opts |= $10.opts;
3359
3634
3360 if ($9.staticport) {
3635 if ($10.staticport) {
3361 if (r.action != PF_NAT) {
3362 yyerror("the 'static-port' option is "
3363 "only valid with nat rules");
3364 YYERROR;
3365 }
3366 if (r.rpool.proxy_port[0] !=
3367 PF_NAT_PROXY_PORT_LOW &&
3368 r.rpool.proxy_port[1] !=
3369 PF_NAT_PROXY_PORT_HIGH) {
3370 yyerror("the 'static-port' option can't"
3371 " be used when specifying a port"
3372 " range");
3373 YYERROR;
3374 }
3375 r.rpool.proxy_port[0] = 0;
3376 r.rpool.proxy_port[1] = 0;
3377 }
3378
3636 if (r.action != PF_NAT) {
3637 yyerror("the 'static-port' option is "
3638 "only valid with nat rules");
3639 YYERROR;
3640 }
3641 if (r.rpool.proxy_port[0] !=
3642 PF_NAT_PROXY_PORT_LOW &&
3643 r.rpool.proxy_port[1] !=
3644 PF_NAT_PROXY_PORT_HIGH) {
3645 yyerror("the 'static-port' option can't"
3646 " be used when specifying a port"
3647 " range");
3648 YYERROR;
3649 }
3650 r.rpool.proxy_port[0] = 0;
3651 r.rpool.proxy_port[1] = 0;
3652 }
3653
3379 expand_rule(&r, $2, $8 == NULL ? NULL : $8->host, $4,
3654 expand_rule(&r, $2, $9 == NULL ? NULL : $9->host, $4,
3380 $5.src_os, $5.src.host, $5.src.port, $5.dst.host,
3381 $5.dst.port, 0, 0, 0, "");
3655 $5.src_os, $5.src.host, $5.src.port, $5.dst.host,
3656 $5.dst.port, 0, 0, 0, "");
3382 free($8);
3657 free($9);
3383 }
3384 ;
3385
3658 }
3659 ;
3660
3386binatrule : no BINAT natpass interface af proto FROM host TO ipspec tag tagged
3387 redirection
3661binatrule : no BINAT natpass interface af proto FROM host TO ipspec tag
3662 tagged rtable redirection
3388 {
3389 struct pf_rule binat;
3390 struct pf_pooladdr *pa;
3391
3392 if (check_rulestate(PFCTL_STATE_NAT))
3393 YYERROR;
3663 {
3664 struct pf_rule binat;
3665 struct pf_pooladdr *pa;
3666
3667 if (check_rulestate(PFCTL_STATE_NAT))
3668 YYERROR;
3669 if (disallow_urpf_failed($10, "\"urpf-failed\" is not "
3670 "permitted as a binat destination"))
3671 YYERROR;
3394
3395 memset(&binat, 0, sizeof(binat));
3396
3672
3673 memset(&binat, 0, sizeof(binat));
3674
3675 if ($1 && $3.b1) {
3676 yyerror("\"pass\" not valid with \"no\"");
3677 YYERROR;
3678 }
3397 if ($1)
3398 binat.action = PF_NOBINAT;
3399 else
3400 binat.action = PF_BINAT;
3679 if ($1)
3680 binat.action = PF_NOBINAT;
3681 else
3682 binat.action = PF_BINAT;
3401 binat.natpass = $3;
3683 binat.natpass = $3.b1;
3684 binat.log = $3.b2;
3685 binat.logif = $3.w2;
3402 binat.af = $5;
3403 if (!binat.af && $8 != NULL && $8->af)
3404 binat.af = $8->af;
3405 if (!binat.af && $10 != NULL && $10->af)
3406 binat.af = $10->af;
3407
3686 binat.af = $5;
3687 if (!binat.af && $8 != NULL && $8->af)
3688 binat.af = $8->af;
3689 if (!binat.af && $10 != NULL && $10->af)
3690 binat.af = $10->af;
3691
3408 if (!binat.af && $13 != NULL && $13->host)
3409 binat.af = $13->host->af;
3692 if (!binat.af && $14 != NULL && $14->host)
3693 binat.af = $14->host->af;
3410 if (!binat.af) {
3411 yyerror("address family (inet/inet6) "
3412 "undefined");
3413 YYERROR;
3414 }
3415
3416 if ($4 != NULL) {
3417 memcpy(binat.ifname, $4->ifname,

--- 12 unchanged lines hidden (view full) ---

3430 if ($12.name)
3431 if (strlcpy(binat.match_tagname, $12.name,
3432 PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
3433 yyerror("tag too long, max %u chars",
3434 PF_TAG_NAME_SIZE - 1);
3435 YYERROR;
3436 }
3437 binat.match_tag_not = $12.neg;
3694 if (!binat.af) {
3695 yyerror("address family (inet/inet6) "
3696 "undefined");
3697 YYERROR;
3698 }
3699
3700 if ($4 != NULL) {
3701 memcpy(binat.ifname, $4->ifname,

--- 12 unchanged lines hidden (view full) ---

3714 if ($12.name)
3715 if (strlcpy(binat.match_tagname, $12.name,
3716 PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
3717 yyerror("tag too long, max %u chars",
3718 PF_TAG_NAME_SIZE - 1);
3719 YYERROR;
3720 }
3721 binat.match_tag_not = $12.neg;
3722 binat.rtableid = $13;
3438
3439 if ($6 != NULL) {
3440 binat.proto = $6->proto;
3441 free($6);
3442 }
3443
3444 if ($8 != NULL && disallow_table($8, "invalid use of "
3445 "table <%s> as the source address of a binat rule"))
3446 YYERROR;
3447 if ($8 != NULL && disallow_alias($8, "invalid use of "
3448 "interface (%s) as the source address of a binat "
3449 "rule"))
3450 YYERROR;
3723
3724 if ($6 != NULL) {
3725 binat.proto = $6->proto;
3726 free($6);
3727 }
3728
3729 if ($8 != NULL && disallow_table($8, "invalid use of "
3730 "table <%s> as the source address of a binat rule"))
3731 YYERROR;
3732 if ($8 != NULL && disallow_alias($8, "invalid use of "
3733 "interface (%s) as the source address of a binat "
3734 "rule"))
3735 YYERROR;
3451 if ($13 != NULL && $13->host != NULL && disallow_table(
3452 $13->host, "invalid use of table <%s> as the "
3736 if ($14 != NULL && $14->host != NULL && disallow_table(
3737 $14->host, "invalid use of table <%s> as the "
3453 "redirect address of a binat rule"))
3454 YYERROR;
3738 "redirect address of a binat rule"))
3739 YYERROR;
3455 if ($13 != NULL && $13->host != NULL && disallow_alias(
3456 $13->host, "invalid use of interface (%s) as the "
3740 if ($14 != NULL && $14->host != NULL && disallow_alias(
3741 $14->host, "invalid use of interface (%s) as the "
3457 "redirect address of a binat rule"))
3458 YYERROR;
3459
3460 if ($8 != NULL) {
3461 if ($8->next) {
3462 yyerror("multiple binat ip addresses");
3463 YYERROR;
3464 }

--- 22 unchanged lines hidden (view full) ---

3487 YYERROR;
3488 memcpy(&binat.dst.addr, &$10->addr,
3489 sizeof(binat.dst.addr));
3490 binat.dst.neg = $10->not;
3491 free($10);
3492 }
3493
3494 if (binat.action == PF_NOBINAT) {
3742 "redirect address of a binat rule"))
3743 YYERROR;
3744
3745 if ($8 != NULL) {
3746 if ($8->next) {
3747 yyerror("multiple binat ip addresses");
3748 YYERROR;
3749 }

--- 22 unchanged lines hidden (view full) ---

3772 YYERROR;
3773 memcpy(&binat.dst.addr, &$10->addr,
3774 sizeof(binat.dst.addr));
3775 binat.dst.neg = $10->not;
3776 free($10);
3777 }
3778
3779 if (binat.action == PF_NOBINAT) {
3495 if ($13 != NULL) {
3780 if ($14 != NULL) {
3496 yyerror("'no binat' rule does not need"
3497 " '->'");
3498 YYERROR;
3499 }
3500 } else {
3781 yyerror("'no binat' rule does not need"
3782 " '->'");
3783 YYERROR;
3784 }
3785 } else {
3501 if ($13 == NULL || $13->host == NULL) {
3786 if ($14 == NULL || $14->host == NULL) {
3502 yyerror("'binat' rule requires"
3503 " '-> address'");
3504 YYERROR;
3505 }
3506
3787 yyerror("'binat' rule requires"
3788 " '-> address'");
3789 YYERROR;
3790 }
3791
3507 remove_invalid_hosts(&$13->host, &binat.af);
3508 if (invalid_redirect($13->host, binat.af))
3792 remove_invalid_hosts(&$14->host, &binat.af);
3793 if (invalid_redirect($14->host, binat.af))
3509 YYERROR;
3794 YYERROR;
3510 if ($13->host->next != NULL) {
3795 if ($14->host->next != NULL) {
3511 yyerror("binat rule must redirect to "
3512 "a single address");
3513 YYERROR;
3514 }
3796 yyerror("binat rule must redirect to "
3797 "a single address");
3798 YYERROR;
3799 }
3515 if (check_netmask($13->host, binat.af))
3800 if (check_netmask($14->host, binat.af))
3516 YYERROR;
3517
3518 if (!PF_AZERO(&binat.src.addr.v.a.mask,
3519 binat.af) &&
3520 !PF_AEQ(&binat.src.addr.v.a.mask,
3801 YYERROR;
3802
3803 if (!PF_AZERO(&binat.src.addr.v.a.mask,
3804 binat.af) &&
3805 !PF_AEQ(&binat.src.addr.v.a.mask,
3521 &$13->host->addr.v.a.mask, binat.af)) {
3806 &$14->host->addr.v.a.mask, binat.af)) {
3522 yyerror("'binat' source mask and "
3523 "redirect mask must be the same");
3524 YYERROR;
3525 }
3526
3527 TAILQ_INIT(&binat.rpool.list);
3528 pa = calloc(1, sizeof(struct pf_pooladdr));
3529 if (pa == NULL)
3530 err(1, "binat: calloc");
3807 yyerror("'binat' source mask and "
3808 "redirect mask must be the same");
3809 YYERROR;
3810 }
3811
3812 TAILQ_INIT(&binat.rpool.list);
3813 pa = calloc(1, sizeof(struct pf_pooladdr));
3814 if (pa == NULL)
3815 err(1, "binat: calloc");
3531 pa->addr = $13->host->addr;
3816 pa->addr = $14->host->addr;
3532 pa->ifname[0] = 0;
3533 TAILQ_INSERT_TAIL(&binat.rpool.list,
3534 pa, entries);
3535
3817 pa->ifname[0] = 0;
3818 TAILQ_INSERT_TAIL(&binat.rpool.list,
3819 pa, entries);
3820
3536 free($13);
3821 free($14);
3537 }
3538
3539 pfctl_add_rule(pf, &binat, "");
3540 }
3541 ;
3542
3543tag : /* empty */ { $$ = NULL; }
3544 | TAG STRING { $$ = $2; }
3545 ;
3546
3547tagged : /* empty */ { $$.neg = 0; $$.name = NULL; }
3548 | not TAGGED string { $$.neg = $1; $$.name = $3; }
3549 ;
3550
3822 }
3823
3824 pfctl_add_rule(pf, &binat, "");
3825 }
3826 ;
3827
3828tag : /* empty */ { $$ = NULL; }
3829 | TAG STRING { $$ = $2; }
3830 ;
3831
3832tagged : /* empty */ { $$.neg = 0; $$.name = NULL; }
3833 | not TAGGED string { $$.neg = $1; $$.name = $3; }
3834 ;
3835
3836rtable : /* empty */ { $$ = -1; }
3837 | RTABLE number {
3838#ifdef __FreeBSD__
3839 yyerror("rtable id not supported in FreeBSD, yet");
3840 YYERROR;
3841#else
3842 if ($2 > RT_TABLEID_MAX || $2 < 0) {
3843 yyerror("invalid rtable id");
3844 YYERROR;
3845 }
3846 $$ = $2;
3847#endif
3848 }
3849 ;
3850
3551route_host : STRING {
3552 $$ = calloc(1, sizeof(struct node_host));
3553 if ($$ == NULL)
3554 err(1, "route_host: calloc");
3555 $$->ifname = $1;
3556 set_ipmask($$, 128);
3557 $$->next = NULL;
3558 $$->tail = $$;

--- 144 unchanged lines hidden (view full) ---

3703 if (h->addr.type == PF_ADDR_TABLE) {
3704 yyerror(fmt, h->addr.v.tblname);
3705 return (1);
3706 }
3707 return (0);
3708}
3709
3710int
3851route_host : STRING {
3852 $$ = calloc(1, sizeof(struct node_host));
3853 if ($$ == NULL)
3854 err(1, "route_host: calloc");
3855 $$->ifname = $1;
3856 set_ipmask($$, 128);
3857 $$->next = NULL;
3858 $$->tail = $$;

--- 144 unchanged lines hidden (view full) ---

4003 if (h->addr.type == PF_ADDR_TABLE) {
4004 yyerror(fmt, h->addr.v.tblname);
4005 return (1);
4006 }
4007 return (0);
4008}
4009
4010int
4011disallow_urpf_failed(struct node_host *h, const char *fmt)
4012{
4013 for (; h != NULL; h = h->next)
4014 if (h->addr.type == PF_ADDR_URPFFAILED) {
4015 yyerror(fmt);
4016 return (1);
4017 }
4018 return (0);
4019}
4020
4021int
3711disallow_alias(struct node_host *h, const char *fmt)
3712{
3713 for (; h != NULL; h = h->next)
3714 if (DYNIF_MULTIADDR(h->addr)) {
3715 yyerror(fmt, h->addr.v.tblname);
3716 return (1);
3717 }
3718 return (0);
3719}
3720
3721int
4022disallow_alias(struct node_host *h, const char *fmt)
4023{
4024 for (; h != NULL; h = h->next)
4025 if (DYNIF_MULTIADDR(h->addr)) {
4026 yyerror(fmt, h->addr.v.tblname);
4027 return (1);
4028 }
4029 return (0);
4030}
4031
4032int
3722rule_consistent(struct pf_rule *r)
4033rule_consistent(struct pf_rule *r, int anchor_call)
3723{
3724 int problems = 0;
3725
3726 switch (r->action) {
3727 case PF_PASS:
3728 case PF_DROP:
3729 case PF_SCRUB:
3730 case PF_NOSCRUB:
4034{
4035 int problems = 0;
4036
4037 switch (r->action) {
4038 case PF_PASS:
4039 case PF_DROP:
4040 case PF_SCRUB:
4041 case PF_NOSCRUB:
3731 problems = filter_consistent(r);
4042 problems = filter_consistent(r, anchor_call);
3732 break;
3733 case PF_NAT:
3734 case PF_NONAT:
3735 problems = nat_consistent(r);
3736 break;
3737 case PF_RDR:
3738 case PF_NORDR:
3739 problems = rdr_consistent(r);
3740 break;
3741 case PF_BINAT:
3742 case PF_NOBINAT:
3743 default:
3744 break;
3745 }
3746 return (problems);
3747}
3748
3749int
4043 break;
4044 case PF_NAT:
4045 case PF_NONAT:
4046 problems = nat_consistent(r);
4047 break;
4048 case PF_RDR:
4049 case PF_NORDR:
4050 problems = rdr_consistent(r);
4051 break;
4052 case PF_BINAT:
4053 case PF_NOBINAT:
4054 default:
4055 break;
4056 }
4057 return (problems);
4058}
4059
4060int
3750filter_consistent(struct pf_rule *r)
4061filter_consistent(struct pf_rule *r, int anchor_call)
3751{
3752 int problems = 0;
3753
3754 if (r->proto != IPPROTO_TCP && r->proto != IPPROTO_UDP &&
3755 (r->src.port_op || r->dst.port_op)) {
3756 yyerror("port only applies to tcp/udp");
3757 problems++;
3758 }

--- 35 unchanged lines hidden (view full) ---

3794 if (r->max_src_nodes && !(r->rule_flag & PFRULE_RULESRCTRACK)) {
3795 yyerror("max-src-nodes requires 'source-track rule'");
3796 problems++;
3797 }
3798 if (r->action == PF_DROP && r->keep_state) {
3799 yyerror("keep state on block rules doesn't make sense");
3800 problems++;
3801 }
4062{
4063 int problems = 0;
4064
4065 if (r->proto != IPPROTO_TCP && r->proto != IPPROTO_UDP &&
4066 (r->src.port_op || r->dst.port_op)) {
4067 yyerror("port only applies to tcp/udp");
4068 problems++;
4069 }

--- 35 unchanged lines hidden (view full) ---

4105 if (r->max_src_nodes && !(r->rule_flag & PFRULE_RULESRCTRACK)) {
4106 yyerror("max-src-nodes requires 'source-track rule'");
4107 problems++;
4108 }
4109 if (r->action == PF_DROP && r->keep_state) {
4110 yyerror("keep state on block rules doesn't make sense");
4111 problems++;
4112 }
3802 if ((r->tagname[0] || r->match_tagname[0]) && !r->keep_state &&
3803 r->action == PF_PASS) {
3804 yyerror("tags cannot be used without keep state");
3805 problems++;
3806 }
3807 return (-problems);
3808}
3809
3810int
3811nat_consistent(struct pf_rule *r)
3812{
3813 return (0); /* yeah! */
3814}

--- 51 unchanged lines hidden (view full) ---

3866 goto _error;
3867 }
3868 }
3869 if (pf->opts & PF_OPT_VERBOSE)
3870 print_tabledef(name, opts->flags, opts->init_addr,
3871 &opts->init_nodes);
3872 if (!(pf->opts & PF_OPT_NOACTION) &&
3873 pfctl_define_table(name, opts->flags, opts->init_addr,
4113 return (-problems);
4114}
4115
4116int
4117nat_consistent(struct pf_rule *r)
4118{
4119 return (0); /* yeah! */
4120}

--- 51 unchanged lines hidden (view full) ---

4172 goto _error;
4173 }
4174 }
4175 if (pf->opts & PF_OPT_VERBOSE)
4176 print_tabledef(name, opts->flags, opts->init_addr,
4177 &opts->init_nodes);
4178 if (!(pf->opts & PF_OPT_NOACTION) &&
4179 pfctl_define_table(name, opts->flags, opts->init_addr,
3874 pf->anchor, &ab, pf->tticket)) {
4180 pf->anchor->name, &ab, pf->anchor->ruleset.tticket)) {
3875 yyerror("cannot define table %s: %s", name,
3876 pfr_strerror(errno));
3877 goto _error;
3878 }
3879 pf->tdirty = 1;
3880 pfr_buf_clear(&ab);
3881 return (0);
3882_error:

--- 82 unchanged lines hidden (view full) ---

3965 snprintf(tmp, sizeof(tmp), "(%s)", h->addr.v.ifname);
3966 break;
3967 case PF_ADDR_TABLE:
3968 snprintf(tmp, sizeof(tmp), "<%s>", h->addr.v.tblname);
3969 break;
3970 case PF_ADDR_NOROUTE:
3971 snprintf(tmp, sizeof(tmp), "no-route");
3972 break;
4181 yyerror("cannot define table %s: %s", name,
4182 pfr_strerror(errno));
4183 goto _error;
4184 }
4185 pf->tdirty = 1;
4186 pfr_buf_clear(&ab);
4187 return (0);
4188_error:

--- 82 unchanged lines hidden (view full) ---

4271 snprintf(tmp, sizeof(tmp), "(%s)", h->addr.v.ifname);
4272 break;
4273 case PF_ADDR_TABLE:
4274 snprintf(tmp, sizeof(tmp), "<%s>", h->addr.v.tblname);
4275 break;
4276 case PF_ADDR_NOROUTE:
4277 snprintf(tmp, sizeof(tmp), "no-route");
4278 break;
4279 case PF_ADDR_URPFFAILED:
4280 snprintf(tmp, sizeof(tmp), "urpf-failed");
4281 break;
3973 case PF_ADDR_ADDRMASK:
3974 if (!af || (PF_AZERO(&h->addr.v.a.addr, af) &&
3975 PF_AZERO(&h->addr.v.a.mask, af)))
3976 snprintf(tmp, sizeof(tmp), "any");
3977 else {
3978 char a[48];
3979 int bits;
3980

--- 74 unchanged lines hidden (view full) ---

4055}
4056
4057void
4058expand_label_nr(const char *name, char *label, size_t len)
4059{
4060 char n[11];
4061
4062 if (strstr(label, name) != NULL) {
4282 case PF_ADDR_ADDRMASK:
4283 if (!af || (PF_AZERO(&h->addr.v.a.addr, af) &&
4284 PF_AZERO(&h->addr.v.a.mask, af)))
4285 snprintf(tmp, sizeof(tmp), "any");
4286 else {
4287 char a[48];
4288 int bits;
4289

--- 74 unchanged lines hidden (view full) ---

4364}
4365
4366void
4367expand_label_nr(const char *name, char *label, size_t len)
4368{
4369 char n[11];
4370
4371 if (strstr(label, name) != NULL) {
4063 snprintf(n, sizeof(n), "%u", pf->rule_nr);
4372 snprintf(n, sizeof(n), "%u", pf->anchor->match);
4064 expand_label_str(label, len, name, n);
4065 }
4066}
4067
4068void
4069expand_label(char *label, size_t len, const char *ifname, sa_family_t af,
4070 struct node_host *src_host, struct node_port *src_port,
4071 struct node_host *dst_host, struct node_port *dst_port,

--- 410 unchanged lines hidden (view full) ---

4482 sizeof(pa->ifname)) >=
4483 sizeof(pa->ifname))
4484 errx(1, "expand_rule: strlcpy");
4485 } else
4486 pa->ifname[0] = 0;
4487 TAILQ_INSERT_TAIL(&r->rpool.list, pa, entries);
4488 }
4489
4373 expand_label_str(label, len, name, n);
4374 }
4375}
4376
4377void
4378expand_label(char *label, size_t len, const char *ifname, sa_family_t af,
4379 struct node_host *src_host, struct node_port *src_port,
4380 struct node_host *dst_host, struct node_port *dst_port,

--- 410 unchanged lines hidden (view full) ---

4791 sizeof(pa->ifname)) >=
4792 sizeof(pa->ifname))
4793 errx(1, "expand_rule: strlcpy");
4794 } else
4795 pa->ifname[0] = 0;
4796 TAILQ_INSERT_TAIL(&r->rpool.list, pa, entries);
4797 }
4798
4490 if (rule_consistent(r) < 0 || error)
4799 if (rule_consistent(r, anchor_call[0]) < 0 || error)
4491 yyerror("skipping rule due to errors");
4492 else {
4800 yyerror("skipping rule due to errors");
4801 else {
4493 r->nr = pf->rule_nr++;
4802 r->nr = pf->astack[pf->asd]->match++;
4494 pfctl_add_rule(pf, r, anchor_call);
4495 added++;
4496 }
4497
4498 ))))))))));
4499
4500 FREE_LIST(struct node_if, interfaces);
4501 FREE_LIST(struct node_proto, protos);

--- 98 unchanged lines hidden (view full) ---

4600 { "flags", FLAGS},
4601 { "floating", FLOATING},
4602 { "flush", FLUSH},
4603 { "for", FOR},
4604 { "fragment", FRAGMENT},
4605 { "from", FROM},
4606 { "global", GLOBAL},
4607 { "group", GROUP},
4803 pfctl_add_rule(pf, r, anchor_call);
4804 added++;
4805 }
4806
4807 ))))))))));
4808
4809 FREE_LIST(struct node_if, interfaces);
4810 FREE_LIST(struct node_proto, protos);

--- 98 unchanged lines hidden (view full) ---

4909 { "flags", FLAGS},
4910 { "floating", FLOATING},
4911 { "flush", FLUSH},
4912 { "for", FOR},
4913 { "fragment", FRAGMENT},
4914 { "from", FROM},
4915 { "global", GLOBAL},
4916 { "group", GROUP},
4608 { "group-bound", GRBOUND},
4609 { "hfsc", HFSC},
4610 { "hostid", HOSTID},
4611 { "icmp-type", ICMPTYPE},
4612 { "icmp6-type", ICMP6TYPE},
4613 { "if-bound", IFBOUND},
4614 { "in", IN},
4615 { "inet", INET},
4616 { "inet6", INET6},
4617 { "keep", KEEP},
4618 { "label", LABEL},
4619 { "limit", LIMIT},
4620 { "linkshare", LINKSHARE},
4621 { "load", LOAD},
4622 { "log", LOG},
4917 { "hfsc", HFSC},
4918 { "hostid", HOSTID},
4919 { "icmp-type", ICMPTYPE},
4920 { "icmp6-type", ICMP6TYPE},
4921 { "if-bound", IFBOUND},
4922 { "in", IN},
4923 { "inet", INET},
4924 { "inet6", INET6},
4925 { "keep", KEEP},
4926 { "label", LABEL},
4927 { "limit", LIMIT},
4928 { "linkshare", LINKSHARE},
4929 { "load", LOAD},
4930 { "log", LOG},
4623 { "log-all", LOGALL},
4624 { "loginterface", LOGINTERFACE},
4625 { "max", MAXIMUM},
4626 { "max-mss", MAXMSS},
4627 { "max-src-conn", MAXSRCCONN},
4628 { "max-src-conn-rate", MAXSRCCONNRATE},
4629 { "max-src-nodes", MAXSRCNODES},
4630 { "max-src-states", MAXSRCSTATES},
4631 { "min-ttl", MINTTL},

--- 28 unchanged lines hidden (view full) ---

4660 { "require-order", REQUIREORDER},
4661 { "return", RETURN},
4662 { "return-icmp", RETURNICMP},
4663 { "return-icmp6", RETURNICMP6},
4664 { "return-rst", RETURNRST},
4665 { "round-robin", ROUNDROBIN},
4666 { "route", ROUTE},
4667 { "route-to", ROUTETO},
4931 { "loginterface", LOGINTERFACE},
4932 { "max", MAXIMUM},
4933 { "max-mss", MAXMSS},
4934 { "max-src-conn", MAXSRCCONN},
4935 { "max-src-conn-rate", MAXSRCCONNRATE},
4936 { "max-src-nodes", MAXSRCNODES},
4937 { "max-src-states", MAXSRCSTATES},
4938 { "min-ttl", MINTTL},

--- 28 unchanged lines hidden (view full) ---

4967 { "require-order", REQUIREORDER},
4968 { "return", RETURN},
4969 { "return-icmp", RETURNICMP},
4970 { "return-icmp6", RETURNICMP6},
4971 { "return-rst", RETURNRST},
4972 { "round-robin", ROUNDROBIN},
4973 { "route", ROUTE},
4974 { "route-to", ROUTETO},
4975 { "rtable", RTABLE},
4668 { "rule", RULE},
4976 { "rule", RULE},
4977 { "ruleset-optimization", RULESET_OPTIMIZATION},
4669 { "scrub", SCRUB},
4670 { "set", SET},
4671 { "skip", SKIP},
4672 { "source-hash", SOURCEHASH},
4673 { "source-track", SOURCETRACK},
4674 { "state", STATE},
4675 { "state-policy", STATEPOLICY},
4676 { "static-port", STATICPORT},
4677 { "sticky-address", STICKYADDRESS},
4678 { "synproxy", SYNPROXY},
4679 { "table", TABLE},
4680 { "tag", TAG},
4681 { "tagged", TAGGED},
4682 { "tbrsize", TBRSIZE},
4683 { "timeout", TIMEOUT},
4684 { "to", TO},
4685 { "tos", TOS},
4686 { "ttl", TTL},
4687 { "upperlimit", UPPERLIMIT},
4978 { "scrub", SCRUB},
4979 { "set", SET},
4980 { "skip", SKIP},
4981 { "source-hash", SOURCEHASH},
4982 { "source-track", SOURCETRACK},
4983 { "state", STATE},
4984 { "state-policy", STATEPOLICY},
4985 { "static-port", STATICPORT},
4986 { "sticky-address", STICKYADDRESS},
4987 { "synproxy", SYNPROXY},
4988 { "table", TABLE},
4989 { "tag", TAG},
4990 { "tagged", TAGGED},
4991 { "tbrsize", TBRSIZE},
4992 { "timeout", TIMEOUT},
4993 { "to", TO},
4994 { "tos", TOS},
4995 { "ttl", TTL},
4996 { "upperlimit", UPPERLIMIT},
4997 { "urpf-failed", URPFFAILED},
4688 { "user", USER},
4689 };
4690 const struct keywords *p;
4691
4692 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
4693 sizeof(keywords[0]), kw_cmp);
4694
4695 if (p) {

--- 31 unchanged lines hidden (view full) ---

4727 }
4728
4729 if (pushback_index)
4730 return (pushback_buffer[--pushback_index]);
4731
4732 while ((c = getc(f)) == '\\') {
4733 next = getc(f);
4734 if (next != '\n') {
4998 { "user", USER},
4999 };
5000 const struct keywords *p;
5001
5002 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
5003 sizeof(keywords[0]), kw_cmp);
5004
5005 if (p) {

--- 31 unchanged lines hidden (view full) ---

5037 }
5038
5039 if (pushback_index)
5040 return (pushback_buffer[--pushback_index]);
5041
5042 while ((c = getc(f)) == '\\') {
5043 next = getc(f);
5044 if (next != '\n') {
4735 if (isspace(next))
4736 yyerror("whitespace after \\");
4737 ungetc(next, f);
5045 c = next;
4738 break;
4739 }
4740 yylval.lineno = lineno;
4741 lineno++;
4742 }
4743 if (c == '\t' || c == ' ') {
4744 /* Compress blanks to a single space. */
4745 do {

--- 271 unchanged lines hidden (view full) ---

5017 if (strcmp(nam, sym->nam) == 0) {
5018 sym->used = 1;
5019 return (sym->val);
5020 }
5021 return (NULL);
5022}
5023
5024void
5046 break;
5047 }
5048 yylval.lineno = lineno;
5049 lineno++;
5050 }
5051 if (c == '\t' || c == ' ') {
5052 /* Compress blanks to a single space. */
5053 do {

--- 271 unchanged lines hidden (view full) ---

5325 if (strcmp(nam, sym->nam) == 0) {
5326 sym->used = 1;
5327 return (sym->val);
5328 }
5329 return (NULL);
5330}
5331
5332void
5025decide_address_family(struct node_host *n, sa_family_t *af)
5333mv_rules(struct pf_ruleset *src, struct pf_ruleset *dst)
5026{
5334{
5027 sa_family_t target_af = 0;
5335 int i;
5336 struct pf_rule *r;
5028
5337
5029 while (!*af && n != NULL) {
5030 if (n->af) {
5031 if (target_af == 0)
5032 target_af = n->af;
5033 if (target_af != n->af)
5034 return;
5338 for (i = 0; i < PF_RULESET_MAX; ++i) {
5339 while ((r = TAILQ_FIRST(src->rules[i].active.ptr))
5340 != NULL) {
5341 TAILQ_REMOVE(src->rules[i].active.ptr, r, entries);
5342 TAILQ_INSERT_TAIL(dst->rules[i].active.ptr, r, entries);
5343 dst->anchor->match++;
5035 }
5344 }
5036 n = n->next;
5345 src->anchor->match = 0;
5346 while ((r = TAILQ_FIRST(src->rules[i].inactive.ptr))
5347 != NULL) {
5348 TAILQ_REMOVE(src->rules[i].inactive.ptr, r, entries);
5349 TAILQ_INSERT_TAIL(dst->rules[i].inactive.ptr,
5350 r, entries);
5351 }
5037 }
5352 }
5038 if (!*af && target_af)
5039 *af = target_af;
5040}
5041
5042void
5353}
5354
5355void
5356decide_address_family(struct node_host *n, sa_family_t *af)
5357{
5358 if (*af != 0 || n == NULL)
5359 return;
5360 *af = n->af;
5361 while ((n = n->next) != NULL) {
5362 if (n->af != *af) {
5363 *af = 0;
5364 return;
5365 }
5366 }
5367}
5368
5369void
5043remove_invalid_hosts(struct node_host **nh, sa_family_t *af)
5044{
5045 struct node_host *n = *nh, *prev = NULL;
5046
5047 while (n != NULL) {
5048 if (*af && n->af && n->af != *af) {
5049 /* unlink and free n */
5050 struct node_host *next = n->next;

--- 121 unchanged lines hidden (view full) ---

5172 if (ulval > 255) {
5173 yyerror("invalid icmp code %lu", ulval);
5174 return (0);
5175 }
5176 return (icmptype << 8 | ulval);
5177}
5178
5179int
5370remove_invalid_hosts(struct node_host **nh, sa_family_t *af)
5371{
5372 struct node_host *n = *nh, *prev = NULL;
5373
5374 while (n != NULL) {
5375 if (*af && n->af && n->af != *af) {
5376 /* unlink and free n */
5377 struct node_host *next = n->next;

--- 121 unchanged lines hidden (view full) ---

5499 if (ulval > 255) {
5500 yyerror("invalid icmp code %lu", ulval);
5501 return (0);
5502 }
5503 return (icmptype << 8 | ulval);
5504}
5505
5506int
5180pfctl_load_anchors(int dev, int opts, struct pfr_buffer *trans)
5507pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
5181{
5182 struct loadanchors *la;
5508{
5509 struct loadanchors *la;
5510 FILE *fin;
5183
5184 TAILQ_FOREACH(la, &loadanchorshead, entries) {
5511
5512 TAILQ_FOREACH(la, &loadanchorshead, entries) {
5185 if (opts & PF_OPT_VERBOSE)
5513 if (pf->opts & PF_OPT_VERBOSE)
5186 fprintf(stderr, "\nLoading anchor %s from %s\n",
5187 la->anchorname, la->filename);
5514 fprintf(stderr, "\nLoading anchor %s from %s\n",
5515 la->anchorname, la->filename);
5188 if (pfctl_rules(dev, la->filename, opts, la->anchorname,
5189 trans) == -1)
5516 if ((fin = pfctl_fopen(la->filename, "r")) == NULL) {
5517 warn("%s", la->filename);
5518 continue;
5519 }
5520 if (pfctl_rules(dev, la->filename, fin, pf->opts, pf->optimize,
5521 la->anchorname, trans) == -1)
5190 return (-1);
5191 }
5192
5193 return (0);
5194}
5522 return (-1);
5523 }
5524
5525 return (0);
5526}
5195