From owner-svn-src-head@FreeBSD.ORG Fri Sep 14 11:51:52 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 942DC1065673; Fri, 14 Sep 2012 11:51:52 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7AC868FC12; Fri, 14 Sep 2012 11:51:52 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q8EBpqac014863; Fri, 14 Sep 2012 11:51:52 GMT (envelope-from glebius@svn.freebsd.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q8EBppm1014858; Fri, 14 Sep 2012 11:51:51 GMT (envelope-from glebius@svn.freebsd.org) Message-Id: <201209141151.q8EBppm1014858@svn.freebsd.org> From: Gleb Smirnoff Date: Fri, 14 Sep 2012 11:51:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r240494 - in head: contrib/pf/man contrib/pf/pfctl include sbin/pfctl sbin/pfctl/missing share/man/man4 share/man/man5 sys/conf sys/contrib/pf sys/modules/dummynet sys/modules/ipfw sys/... X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Sep 2012 11:51:52 -0000 Author: glebius Date: Fri Sep 14 11:51:49 2012 New Revision: 240494 URL: http://svn.freebsd.org/changeset/base/240494 Log: o Create directory sys/netpfil, where all packet filters should reside, and move there ipfw(4) and pf(4). o Move most modified parts of pf out of contrib. Actual movements: sys/contrib/pf/net/*.c -> sys/netpfil/pf/ sys/contrib/pf/net/*.h -> sys/net/ contrib/pf/pfctl/*.c -> sbin/pfctl contrib/pf/pfctl/*.h -> sbin/pfctl contrib/pf/pfctl/pfctl.8 -> sbin/pfctl contrib/pf/pfctl/*.4 -> share/man/man4 contrib/pf/pfctl/*.5 -> share/man/man5 sys/netinet/ipfw -> sys/netpfil/ipfw The arguable movement is pf/net/*.h -> sys/net. There are future plans to refactor pf includes, so I decided not to break things twice. Not modified bits of pf left in contrib: authpf, ftp-proxy, tftp-proxy, pflogd. The ipfw(4) movement is planned to be merged to stable/9, to make head and stable match. Discussed with: bz, luigi Added: head/sbin/pfctl/parse.y - copied unchanged from r240390, head/contrib/pf/pfctl/parse.y head/sbin/pfctl/pf_print_state.c - copied unchanged from r240390, head/contrib/pf/pfctl/pf_print_state.c head/sbin/pfctl/pfctl.8 - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl.8 head/sbin/pfctl/pfctl.c - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl.c head/sbin/pfctl/pfctl.h - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl.h head/sbin/pfctl/pfctl_altq.c - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl_altq.c head/sbin/pfctl/pfctl_optimize.c - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl_optimize.c head/sbin/pfctl/pfctl_osfp.c - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl_osfp.c head/sbin/pfctl/pfctl_parser.c - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl_parser.c head/sbin/pfctl/pfctl_parser.h - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl_parser.h head/sbin/pfctl/pfctl_qstats.c - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl_qstats.c head/sbin/pfctl/pfctl_radix.c - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl_radix.c head/sbin/pfctl/pfctl_table.c - copied unchanged from r240390, head/contrib/pf/pfctl/pfctl_table.c head/share/man/man4/pf.4 - copied unchanged from r240390, head/contrib/pf/man/pf.4 head/share/man/man4/pflog.4 - copied unchanged from r240390, head/contrib/pf/man/pflog.4 head/share/man/man4/pfsync.4 - copied unchanged from r240390, head/contrib/pf/man/pfsync.4 head/share/man/man5/pf.conf.5 - copied unchanged from r240390, head/contrib/pf/man/pf.conf.5 head/share/man/man5/pf.os.5 - copied unchanged from r240390, head/contrib/pf/man/pf.os.5 head/sys/net/if_pflog.h - copied unchanged from r240390, head/sys/contrib/pf/net/if_pflog.h head/sys/net/if_pfsync.h - copied unchanged from r240390, head/sys/contrib/pf/net/if_pfsync.h head/sys/net/pf_mtag.h - copied unchanged from r240390, head/sys/contrib/pf/net/pf_mtag.h head/sys/net/pfvar.h - copied unchanged from r240390, head/sys/contrib/pf/net/pfvar.h head/sys/netpfil/ head/sys/netpfil/ipfw/ - copied from r240390, head/sys/netinet/ipfw/ head/sys/netpfil/pf/ head/sys/netpfil/pf/if_pflog.c - copied unchanged from r240390, head/sys/contrib/pf/net/if_pflog.c head/sys/netpfil/pf/if_pfsync.c - copied unchanged from r240390, head/sys/contrib/pf/net/if_pfsync.c head/sys/netpfil/pf/in4_cksum.c - copied unchanged from r240390, head/sys/contrib/pf/netinet/in4_cksum.c head/sys/netpfil/pf/pf.c - copied, changed from r240390, head/sys/contrib/pf/net/pf.c head/sys/netpfil/pf/pf_if.c - copied unchanged from r240390, head/sys/contrib/pf/net/pf_if.c head/sys/netpfil/pf/pf_ioctl.c - copied unchanged from r240390, head/sys/contrib/pf/net/pf_ioctl.c head/sys/netpfil/pf/pf_lb.c - copied unchanged from r240390, head/sys/contrib/pf/net/pf_lb.c head/sys/netpfil/pf/pf_norm.c - copied unchanged from r240390, head/sys/contrib/pf/net/pf_norm.c head/sys/netpfil/pf/pf_osfp.c - copied unchanged from r240390, head/sys/contrib/pf/net/pf_osfp.c head/sys/netpfil/pf/pf_ruleset.c - copied unchanged from r240390, head/sys/contrib/pf/net/pf_ruleset.c head/sys/netpfil/pf/pf_table.c - copied unchanged from r240390, head/sys/contrib/pf/net/pf_table.c Deleted: head/contrib/pf/man/ head/contrib/pf/pfctl/ head/sbin/pfctl/missing/ head/sys/contrib/pf/ head/sys/netinet/ipfw/ Modified: head/include/Makefile head/sbin/pfctl/Makefile head/share/man/man4/Makefile head/share/man/man5/Makefile head/sys/conf/files head/sys/conf/kern.pre.mk head/sys/modules/dummynet/Makefile head/sys/modules/ipfw/Makefile head/sys/modules/ipfw_nat/Makefile head/sys/modules/pf/Makefile head/sys/modules/pflog/Makefile head/sys/modules/pfsync/Makefile head/sys/netgraph/ng_ipfw.c head/sys/netpfil/ipfw/dn_heap.c head/sys/netpfil/ipfw/dn_sched_fifo.c head/sys/netpfil/ipfw/dn_sched_prio.c head/sys/netpfil/ipfw/dn_sched_qfq.c head/sys/netpfil/ipfw/dn_sched_rr.c head/sys/netpfil/ipfw/dn_sched_wf2q.c head/sys/netpfil/ipfw/ip_dn_glue.c head/sys/netpfil/ipfw/ip_dn_io.c head/sys/netpfil/ipfw/ip_dummynet.c head/sys/netpfil/ipfw/ip_fw2.c head/sys/netpfil/ipfw/ip_fw_dynamic.c head/sys/netpfil/ipfw/ip_fw_log.c head/sys/netpfil/ipfw/ip_fw_nat.c head/sys/netpfil/ipfw/ip_fw_pfil.c head/sys/netpfil/ipfw/ip_fw_sockopt.c head/sys/netpfil/ipfw/ip_fw_table.c head/usr.sbin/authpf/Makefile head/usr.sbin/ftp-proxy/ftp-proxy/Makefile Modified: head/include/Makefile ============================================================================== --- head/include/Makefile Fri Sep 14 10:06:56 2012 (r240493) +++ head/include/Makefile Fri Sep 14 11:51:49 2012 (r240494) @@ -186,9 +186,6 @@ copies: ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}${INCLUDEDIR}/netinet .endif - cd ${.CURDIR}/../sys/contrib/pf/net; \ - ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ - ${DESTDIR}${INCLUDEDIR}/net cd ${.CURDIR}/../sys/crypto; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 rijndael/rijndael.h \ ${DESTDIR}${INCLUDEDIR}/crypto @@ -272,11 +269,6 @@ symlinks: ${DESTDIR}${INCLUDEDIR}/netinet; \ done .endif - cd ${.CURDIR}/../sys/contrib/pf/net; \ - for h in *.h; do \ - ln -fs ../../../sys/contrib/pf/net/$$h \ - ${DESTDIR}${INCLUDEDIR}/net; \ - done cd ${.CURDIR}/../sys/crypto; \ for h in rijndael/rijndael.h; do \ ln -fs ../../../sys/crypto/$$h \ Modified: head/sbin/pfctl/Makefile ============================================================================== --- head/sbin/pfctl/Makefile Fri Sep 14 10:06:56 2012 (r240493) +++ head/sbin/pfctl/Makefile Fri Sep 14 11:51:49 2012 (r240494) @@ -1,11 +1,10 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../contrib/pf/pfctl -.PATH: ${.CURDIR}/../../sys/contrib/pf/net -.PATH: ${.CURDIR}/../../contrib/pf/man +# pf_ruleset.c is shared between kernel and pfctl +.PATH: ${.CURDIR}/../../sys/netpfil/pf PROG= pfctl -MAN= pfctl.8 pf.4 pflog.4 pfsync.4 pf.conf.5 pf.os.5 +MAN= pfctl.8 SRCS = pfctl.c parse.y pfctl_parser.c pf_print_state.c pfctl_altq.c SRCS+= pfctl_osfp.c pfctl_radix.c pfctl_table.c pfctl_qstats.c @@ -14,11 +13,8 @@ SRCS+= pf_ruleset.c WARNS?= 2 CFLAGS+= -Wall -Wmissing-prototypes -Wno-uninitialized -CFLAGS+= -Wstrict-prototypes -I${.CURDIR}/../../contrib/pf/pfctl - -# XXX ALTQ -CFLAGS+= -DENABLE_ALTQ -#CFLAGS+= -I${.CURDIR}/missing +CFLAGS+= -Wstrict-prototypes +CFLAGS+= -DENABLE_ALTQ -I${.CURDIR} YFLAGS= Copied: head/sbin/pfctl/parse.y (from r240390, head/contrib/pf/pfctl/parse.y) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sbin/pfctl/parse.y Fri Sep 14 11:51:49 2012 (r240494, copy of r240390, head/contrib/pf/pfctl/parse.y) @@ -0,0 +1,6038 @@ +/* $OpenBSD: parse.y,v 1.554 2008/10/17 12:59:53 henning Exp $ */ + +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2001 Daniel Hartmeier. All rights reserved. + * Copyright (c) 2001 Theo de Raadt. All rights reserved. + * Copyright (c) 2002,2003 Henning Brauer. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +%{ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#ifdef __FreeBSD__ +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pfctl_parser.h" +#include "pfctl.h" + +static struct pfctl *pf = NULL; +static int debug = 0; +static int rulestate = 0; +static u_int16_t returnicmpdefault = + (ICMP_UNREACH << 8) | ICMP_UNREACH_PORT; +static u_int16_t returnicmp6default = + (ICMP6_DST_UNREACH << 8) | ICMP6_DST_UNREACH_NOPORT; +static int blockpolicy = PFRULE_DROP; +static int require_order = 1; +static int default_statelock; + +TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); +static struct file { + TAILQ_ENTRY(file) entry; + FILE *stream; + char *name; + int lineno; + int errors; +} *file; +struct file *pushfile(const char *, int); +int popfile(void); +int check_file_secrecy(int, const char *); +int yyparse(void); +int yylex(void); +int yyerror(const char *, ...); +int kw_cmp(const void *, const void *); +int lookup(char *); +int lgetc(int); +int lungetc(int); +int findeol(void); + +TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); +struct sym { + TAILQ_ENTRY(sym) entry; + int used; + int persist; + char *nam; + char *val; +}; +int symset(const char *, const char *, int); +char *symget(const char *); + +int atoul(char *, u_long *); + +enum { + PFCTL_STATE_NONE, + PFCTL_STATE_OPTION, + PFCTL_STATE_SCRUB, + PFCTL_STATE_QUEUE, + PFCTL_STATE_NAT, + PFCTL_STATE_FILTER +}; + +struct node_proto { + u_int8_t proto; + struct node_proto *next; + struct node_proto *tail; +}; + +struct node_port { + u_int16_t port[2]; + u_int8_t op; + struct node_port *next; + struct node_port *tail; +}; + +struct node_uid { + uid_t uid[2]; + u_int8_t op; + struct node_uid *next; + struct node_uid *tail; +}; + +struct node_gid { + gid_t gid[2]; + u_int8_t op; + struct node_gid *next; + struct node_gid *tail; +}; + +struct node_icmp { + u_int8_t code; + u_int8_t type; + u_int8_t proto; + struct node_icmp *next; + struct node_icmp *tail; +}; + +enum { PF_STATE_OPT_MAX, PF_STATE_OPT_NOSYNC, PF_STATE_OPT_SRCTRACK, + PF_STATE_OPT_MAX_SRC_STATES, PF_STATE_OPT_MAX_SRC_CONN, + PF_STATE_OPT_MAX_SRC_CONN_RATE, PF_STATE_OPT_MAX_SRC_NODES, + PF_STATE_OPT_OVERLOAD, PF_STATE_OPT_STATELOCK, + PF_STATE_OPT_TIMEOUT, PF_STATE_OPT_SLOPPY, }; + +enum { PF_SRCTRACK_NONE, PF_SRCTRACK, PF_SRCTRACK_GLOBAL, PF_SRCTRACK_RULE }; + +struct node_state_opt { + int type; + union { + u_int32_t max_states; + u_int32_t max_src_states; + u_int32_t max_src_conn; + struct { + u_int32_t limit; + u_int32_t seconds; + } max_src_conn_rate; + struct { + u_int8_t flush; + char tblname[PF_TABLE_NAME_SIZE]; + } overload; + u_int32_t max_src_nodes; + u_int8_t src_track; + u_int32_t statelock; + struct { + int number; + u_int32_t seconds; + } timeout; + } data; + struct node_state_opt *next; + struct node_state_opt *tail; +}; + +struct peer { + struct node_host *host; + struct node_port *port; +}; + +struct node_queue { + char queue[PF_QNAME_SIZE]; + char parent[PF_QNAME_SIZE]; + char ifname[IFNAMSIZ]; + int scheduler; + struct node_queue *next; + struct node_queue *tail; +} *queues = NULL; + +struct node_qassign { + char *qname; + char *pqname; +}; + +struct filter_opts { + int marker; +#define FOM_FLAGS 0x01 +#define FOM_ICMP 0x02 +#define FOM_TOS 0x04 +#define FOM_KEEP 0x08 +#define FOM_SRCTRACK 0x10 + struct node_uid *uid; + struct node_gid *gid; + struct { + u_int8_t b1; + u_int8_t b2; + u_int16_t w; + u_int16_t w2; + } flags; + struct node_icmp *icmpspec; + u_int32_t tos; + u_int32_t prob; + struct { + int action; + struct node_state_opt *options; + } keep; + int fragment; + int allowopts; + char *label; + struct node_qassign queues; + char *tag; + char *match_tag; + u_int8_t match_tag_not; + u_int rtableid; + struct { + struct node_host *addr; + u_int16_t port; + } divert; +} filter_opts; + +struct antispoof_opts { + char *label; + u_int rtableid; +} antispoof_opts; + +struct scrub_opts { + int marker; +#define SOM_MINTTL 0x01 +#define SOM_MAXMSS 0x02 +#define SOM_FRAGCACHE 0x04 +#define SOM_SETTOS 0x08 + int nodf; + int minttl; + int maxmss; + int settos; + int fragcache; + int randomid; + int reassemble_tcp; + char *match_tag; + u_int8_t match_tag_not; + u_int rtableid; +} scrub_opts; + +struct queue_opts { + int marker; +#define QOM_BWSPEC 0x01 +#define QOM_SCHEDULER 0x02 +#define QOM_PRIORITY 0x04 +#define QOM_TBRSIZE 0x08 +#define QOM_QLIMIT 0x10 + struct node_queue_bw queue_bwspec; + struct node_queue_opt scheduler; + int priority; + int tbrsize; + int qlimit; +} queue_opts; + +struct table_opts { + int flags; + int init_addr; + struct node_tinithead init_nodes; +} table_opts; + +struct pool_opts { + int marker; +#define POM_TYPE 0x01 +#define POM_STICKYADDRESS 0x02 + u_int8_t opts; + int type; + int staticport; + struct pf_poolhashkey *key; + +} pool_opts; + + +struct node_hfsc_opts hfsc_opts; +struct node_state_opt *keep_state_defaults = NULL; + +int disallow_table(struct node_host *, const char *); +int disallow_urpf_failed(struct node_host *, const char *); +int disallow_alias(struct node_host *, const char *); +int rule_consistent(struct pf_rule *, int); +int filter_consistent(struct pf_rule *, int); +int nat_consistent(struct pf_rule *); +int rdr_consistent(struct pf_rule *); +int process_tabledef(char *, struct table_opts *); +void expand_label_str(char *, size_t, const char *, const char *); +void expand_label_if(const char *, char *, size_t, const char *); +void expand_label_addr(const char *, char *, size_t, u_int8_t, + struct node_host *); +void expand_label_port(const char *, char *, size_t, + struct node_port *); +void expand_label_proto(const char *, char *, size_t, u_int8_t); +void expand_label_nr(const char *, char *, size_t); +void expand_label(char *, size_t, const char *, u_int8_t, + struct node_host *, struct node_port *, struct node_host *, + struct node_port *, u_int8_t); +void expand_rule(struct pf_rule *, struct node_if *, + struct node_host *, struct node_proto *, struct node_os *, + struct node_host *, struct node_port *, struct node_host *, + struct node_port *, struct node_uid *, struct node_gid *, + struct node_icmp *, const char *); +int expand_altq(struct pf_altq *, struct node_if *, + struct node_queue *, struct node_queue_bw bwspec, + struct node_queue_opt *); +int expand_queue(struct pf_altq *, struct node_if *, + struct node_queue *, struct node_queue_bw, + struct node_queue_opt *); +int expand_skip_interface(struct node_if *); + +int check_rulestate(int); +int getservice(char *); +int rule_label(struct pf_rule *, char *); +int rt_tableid_max(void); + +void mv_rules(struct pf_ruleset *, struct pf_ruleset *); +void decide_address_family(struct node_host *, sa_family_t *); +void remove_invalid_hosts(struct node_host **, sa_family_t *); +int invalid_redirect(struct node_host *, sa_family_t); +u_int16_t parseicmpspec(char *, sa_family_t); + +TAILQ_HEAD(loadanchorshead, loadanchors) + loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead); + +struct loadanchors { + TAILQ_ENTRY(loadanchors) entries; + char *anchorname; + char *filename; +}; + +typedef struct { + union { + int64_t number; + double probability; + int i; + char *string; + u_int rtableid; + struct { + u_int8_t b1; + u_int8_t b2; + u_int16_t w; + u_int16_t w2; + } b; + struct range { + int a; + int b; + int t; + } range; + struct node_if *interface; + struct node_proto *proto; + struct node_icmp *icmp; + struct node_host *host; + struct node_os *os; + struct node_port *port; + struct node_uid *uid; + struct node_gid *gid; + struct node_state_opt *state_opt; + struct peer peer; + struct { + struct peer src, dst; + struct node_os *src_os; + } fromto; + struct { + struct node_host *host; + u_int8_t rt; + u_int8_t pool_opts; + sa_family_t af; + struct pf_poolhashkey *key; + } route; + struct redirection { + struct node_host *host; + struct range rport; + } *redirection; + struct { + int action; + struct node_state_opt *options; + } keep_state; + struct { + u_int8_t log; + u_int8_t logif; + u_int8_t quick; + } logquick; + struct { + int neg; + char *name; + } tagged; + struct pf_poolhashkey *hashkey; + struct node_queue *queue; + struct node_queue_opt queue_options; + struct node_queue_bw queue_bwspec; + struct node_qassign qassign; + struct filter_opts filter_opts; + struct antispoof_opts antispoof_opts; + struct queue_opts queue_opts; + struct scrub_opts scrub_opts; + struct table_opts table_opts; + struct pool_opts pool_opts; + struct node_hfsc_opts hfsc_opts; + } v; + int lineno; +} YYSTYPE; + +#define PPORT_RANGE 1 +#define PPORT_STAR 2 +int parseport(char *, struct range *r, int); + +#define DYNIF_MULTIADDR(addr) ((addr).type == PF_ADDR_DYNIFTL && \ + (!((addr).iflags & PFI_AFLAG_NOALIAS) || \ + !isdigit((addr).v.ifname[strlen((addr).v.ifname)-1]))) + +%} + +%token PASS BLOCK SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS +%token RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE +%token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF +%token MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL +%token NOROUTE URPFFAILED FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS DROP TABLE +%token REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR +%token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY RANDOMID +%token REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID +%token ANTISPOOF FOR INCLUDE +%token BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY +%token ALTQ CBQ PRIQ HFSC BANDWIDTH TBRSIZE LINKSHARE REALTIME UPPERLIMIT +%token QUEUE PRIORITY QLIMIT RTABLE +%token LOAD RULESET_OPTIMIZATION +%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE +%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY +%token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS +%token DIVERTTO DIVERTREPLY +%token STRING +%token NUMBER +%token PORTBINARY +%type interface if_list if_item_not if_item +%type number icmptype icmp6type uid gid +%type tos not yesno +%type probability +%type no dir af fragcache optimizer +%type sourcetrack flush unaryop statelock +%type action nataction natpasslog scrubaction +%type flags flag blockspec +%type portplain portstar portrange +%type hashkey +%type proto proto_list proto_item +%type protoval +%type icmpspec +%type icmp_list icmp_item +%type icmp6_list icmp6_item +%type reticmpspec reticmp6spec +%type fromto +%type ipportspec from to +%type ipspec toipspec xhost host dynaddr host_list +%type redir_host_list redirspec +%type route_host route_host_list routespec +%type os xos os_list +%type portspec port_list port_item +%type uids uid_list uid_item +%type gids gid_list gid_item +%type route +%type redirection redirpool +%type label stringall tag anchorname +%type string varstring numberstring +%type keep +%type state_opt_spec state_opt_list state_opt_item +%type logquick quick log logopts logopt +%type antispoof_ifspc antispoof_iflst antispoof_if +%type qname +%type qassign qassign_list qassign_item +%type scheduler +%type cbqflags_list cbqflags_item +%type priqflags_list priqflags_item +%type hfscopts_list hfscopts_item hfsc_opts +%type bandwidth +%type filter_opts filter_opt filter_opts_l +%type antispoof_opts antispoof_opt antispoof_opts_l +%type queue_opts queue_opt queue_opts_l +%type scrub_opts scrub_opt scrub_opts_l +%type table_opts table_opt table_opts_l +%type pool_opts pool_opt pool_opts_l +%type tagged +%type rtable +%% + +ruleset : /* empty */ + | ruleset include '\n' + | ruleset '\n' + | ruleset option '\n' + | ruleset scrubrule '\n' + | ruleset natrule '\n' + | ruleset binatrule '\n' + | ruleset pfrule '\n' + | ruleset anchorrule '\n' + | ruleset loadrule '\n' + | ruleset altqif '\n' + | ruleset queuespec '\n' + | ruleset varset '\n' + | ruleset antispoof '\n' + | ruleset tabledef '\n' + | '{' fakeanchor '}' '\n'; + | ruleset error '\n' { file->errors++; } + ; + +include : INCLUDE STRING { + struct file *nfile; + + if ((nfile = pushfile($2, 0)) == NULL) { + yyerror("failed to include file %s", $2); + free($2); + YYERROR; + } + free($2); + + file = nfile; + lungetc('\n'); + } + ; + +/* + * apply to previouslys specified rule: must be careful to note + * what that is: pf or nat or binat or rdr + */ +fakeanchor : fakeanchor '\n' + | fakeanchor anchorrule '\n' + | fakeanchor binatrule '\n' + | fakeanchor natrule '\n' + | fakeanchor pfrule '\n' + | fakeanchor error '\n' + ; + +optimizer : string { + if (!strcmp($1, "none")) + $$ = 0; + else if (!strcmp($1, "basic")) + $$ = PF_OPTIMIZE_BASIC; + else if (!strcmp($1, "profile")) + $$ = PF_OPTIMIZE_BASIC | PF_OPTIMIZE_PROFILE; + else { + yyerror("unknown ruleset-optimization %s", $1); + YYERROR; + } + } + ; + +option : SET OPTIMIZATION STRING { + if (check_rulestate(PFCTL_STATE_OPTION)) { + free($3); + YYERROR; + } + if (pfctl_set_optimization(pf, $3) != 0) { + yyerror("unknown optimization %s", $3); + free($3); + YYERROR; + } + free($3); + } + | SET RULESET_OPTIMIZATION optimizer { + if (!(pf->opts & PF_OPT_OPTIMIZE)) { + pf->opts |= PF_OPT_OPTIMIZE; + pf->optimize = $3; + } + } + | SET TIMEOUT timeout_spec + | SET TIMEOUT '{' optnl timeout_list '}' + | SET LIMIT limit_spec + | SET LIMIT '{' optnl limit_list '}' + | SET LOGINTERFACE stringall { + if (check_rulestate(PFCTL_STATE_OPTION)) { + free($3); + YYERROR; + } + if (pfctl_set_logif(pf, $3) != 0) { + yyerror("error setting loginterface %s", $3); + free($3); + YYERROR; + } + free($3); + } + | SET HOSTID number { + if ($3 == 0 || $3 > UINT_MAX) { + yyerror("hostid must be non-zero"); + YYERROR; + } + if (pfctl_set_hostid(pf, $3) != 0) { + yyerror("error setting hostid %08x", $3); + YYERROR; + } + } + | SET BLOCKPOLICY DROP { + if (pf->opts & PF_OPT_VERBOSE) + printf("set block-policy drop\n"); + if (check_rulestate(PFCTL_STATE_OPTION)) + YYERROR; + blockpolicy = PFRULE_DROP; + } + | SET BLOCKPOLICY RETURN { + if (pf->opts & PF_OPT_VERBOSE) + printf("set block-policy return\n"); + if (check_rulestate(PFCTL_STATE_OPTION)) + YYERROR; + blockpolicy = PFRULE_RETURN; + } + | SET REQUIREORDER yesno { + if (pf->opts & PF_OPT_VERBOSE) + printf("set require-order %s\n", + $3 == 1 ? "yes" : "no"); + require_order = $3; + } + | SET FINGERPRINTS STRING { + if (pf->opts & PF_OPT_VERBOSE) + printf("set fingerprints \"%s\"\n", $3); + if (check_rulestate(PFCTL_STATE_OPTION)) { + free($3); + YYERROR; + } + if (!pf->anchor->name[0]) { + if (pfctl_file_fingerprints(pf->dev, + pf->opts, $3)) { + yyerror("error loading " + "fingerprints %s", $3); + free($3); + YYERROR; + } + } + free($3); + } + | SET STATEPOLICY statelock { + if (pf->opts & PF_OPT_VERBOSE) + switch ($3) { + case 0: + printf("set state-policy floating\n"); + break; + case PFRULE_IFBOUND: + printf("set state-policy if-bound\n"); + break; + } + default_statelock = $3; + } + | SET DEBUG STRING { + if (check_rulestate(PFCTL_STATE_OPTION)) { + free($3); + YYERROR; + } + if (pfctl_set_debug(pf, $3) != 0) { + yyerror("error setting debuglevel %s", $3); + free($3); + YYERROR; + } + free($3); + } + | SET SKIP interface { + if (expand_skip_interface($3) != 0) { + yyerror("error setting skip interface(s)"); + YYERROR; + } + } + | SET STATEDEFAULTS state_opt_list { + if (keep_state_defaults != NULL) { + yyerror("cannot redefine state-defaults"); + YYERROR; + } + keep_state_defaults = $3; + } + ; + +stringall : STRING { $$ = $1; } + | ALL { + if (($$ = strdup("all")) == NULL) { + err(1, "stringall: strdup"); + } + } + ; + +string : STRING string { + if (asprintf(&$$, "%s %s", $1, $2) == -1) + err(1, "string: asprintf"); + free($1); + free($2); + } + | STRING + ; + +varstring : numberstring varstring { + if (asprintf(&$$, "%s %s", $1, $2) == -1) + err(1, "string: asprintf"); + free($1); + free($2); + } + | numberstring + ; + +numberstring : NUMBER { + char *s; + if (asprintf(&s, "%lld", (long long)$1) == -1) { + yyerror("string: asprintf"); + YYERROR; + } + $$ = s; + } + | STRING + ; + +varset : STRING '=' varstring { + if (pf->opts & PF_OPT_VERBOSE) + printf("%s = \"%s\"\n", $1, $3); + if (symset($1, $3, 0) == -1) + err(1, "cannot store variable %s", $1); + free($1); + free($3); + } + ; + +anchorname : STRING { $$ = $1; } + | /* empty */ { $$ = NULL; } + ; + +pfa_anchorlist : /* empty */ + | pfa_anchorlist '\n' + | pfa_anchorlist pfrule '\n' + | pfa_anchorlist anchorrule '\n' + ; + +pfa_anchor : '{' + { + char ta[PF_ANCHOR_NAME_SIZE]; + struct pf_ruleset *rs; + + /* steping into a brace anchor */ + pf->asd++; + pf->bn++; + pf->brace = 1; + + /* create a holding ruleset in the root */ + snprintf(ta, PF_ANCHOR_NAME_SIZE, "_%d", pf->bn); + rs = pf_find_or_create_ruleset(ta); + if (rs == NULL) + err(1, "pfa_anchor: pf_find_or_create_ruleset"); + pf->astack[pf->asd] = rs->anchor; + pf->anchor = rs->anchor; + } '\n' pfa_anchorlist '}' + { + pf->alast = pf->anchor; + pf->asd--; + pf->anchor = pf->astack[pf->asd]; + } + | /* empty */ + ; + +anchorrule : ANCHOR anchorname dir quick interface af proto fromto + filter_opts pfa_anchor + { + struct pf_rule r; + struct node_proto *proto; + + if (check_rulestate(PFCTL_STATE_FILTER)) { + if ($2) + free($2); + YYERROR; + } + + if ($2 && ($2[0] == '_' || strstr($2, "/_") != NULL)) { + free($2); + yyerror("anchor names beginning with '_' " + "are reserved for internal use"); + YYERROR; + } + + memset(&r, 0, sizeof(r)); + if (pf->astack[pf->asd + 1]) { + /* move inline rules into relative location */ + pf_anchor_setup(&r, + &pf->astack[pf->asd]->ruleset, + $2 ? $2 : pf->alast->name); + + if (r.anchor == NULL) + err(1, "anchorrule: unable to " + "create ruleset"); + + if (pf->alast != r.anchor) { + if (r.anchor->match) { + yyerror("inline anchor '%s' " + "already exists", + r.anchor->name); + YYERROR; + } + mv_rules(&pf->alast->ruleset, + &r.anchor->ruleset); + } + pf_remove_if_empty_ruleset(&pf->alast->ruleset); + pf->alast = r.anchor; + } else { + if (!$2) { + yyerror("anchors without explicit " + "rules must specify a name"); + YYERROR; + } + } + r.direction = $3; + r.quick = $4.quick; + r.af = $6; + r.prob = $9.prob; + r.rtableid = $9.rtableid; + + if ($9.tag) + if (strlcpy(r.tagname, $9.tag, + PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) { + yyerror("tag too long, max %u chars", + PF_TAG_NAME_SIZE - 1); + YYERROR; + } + if ($9.match_tag) + if (strlcpy(r.match_tagname, $9.match_tag, + PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) { + yyerror("tag too long, max %u chars", + PF_TAG_NAME_SIZE - 1); + YYERROR; + } + r.match_tag_not = $9.match_tag_not; + if (rule_label(&r, $9.label)) + YYERROR; + free($9.label); + r.flags = $9.flags.b1; + r.flagset = $9.flags.b2; + if (($9.flags.b1 & $9.flags.b2) != $9.flags.b1) { + yyerror("flags always false"); + YYERROR; + } + if ($9.flags.b1 || $9.flags.b2 || $8.src_os) { + for (proto = $7; proto != NULL && + proto->proto != IPPROTO_TCP; + proto = proto->next) + ; /* nothing */ + if (proto == NULL && $7 != NULL) { + if ($9.flags.b1 || $9.flags.b2) + yyerror( + "flags only apply to tcp"); + if ($8.src_os) + yyerror( + "OS fingerprinting only " + "applies to tcp"); + YYERROR; + } + } + + r.tos = $9.tos; + + if ($9.keep.action) { + yyerror("cannot specify state handling " + "on anchors"); + YYERROR; + } + + if ($9.match_tag) + if (strlcpy(r.match_tagname, $9.match_tag, + PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) { + yyerror("tag too long, max %u chars", + PF_TAG_NAME_SIZE - 1); + YYERROR; + } + r.match_tag_not = $9.match_tag_not; + + decide_address_family($8.src.host, &r.af); + decide_address_family($8.dst.host, &r.af); + + expand_rule(&r, $5, NULL, $7, $8.src_os, + $8.src.host, $8.src.port, $8.dst.host, $8.dst.port, + $9.uid, $9.gid, $9.icmpspec, + pf->astack[pf->asd + 1] ? pf->alast->name : $2); + free($2); + pf->astack[pf->asd + 1] = NULL; + } + | NATANCHOR string interface af proto fromto rtable { + struct pf_rule r; + + if (check_rulestate(PFCTL_STATE_NAT)) { + free($2); + YYERROR; + } + + memset(&r, 0, sizeof(r)); + r.action = PF_NAT; + r.af = $4; + r.rtableid = $7; + + decide_address_family($6.src.host, &r.af); + decide_address_family($6.dst.host, &r.af); + + expand_rule(&r, $3, NULL, $5, $6.src_os, + $6.src.host, $6.src.port, $6.dst.host, $6.dst.port, + 0, 0, 0, $2); + free($2); + } + | RDRANCHOR string interface af proto fromto rtable { + struct pf_rule r; + + if (check_rulestate(PFCTL_STATE_NAT)) { + free($2); + YYERROR; + } + + memset(&r, 0, sizeof(r)); + r.action = PF_RDR; + r.af = $4; + r.rtableid = $7; + + decide_address_family($6.src.host, &r.af); + decide_address_family($6.dst.host, &r.af); + + if ($6.src.port != NULL) { + yyerror("source port parameter not supported" + " in rdr-anchor"); + YYERROR; + } + if ($6.dst.port != NULL) { + if ($6.dst.port->next != NULL) { + yyerror("destination port list " + "expansion not supported in " + "rdr-anchor"); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***