summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-12-06 00:47:33 +0000
committerDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-12-06 00:47:33 +0000
commit0c408b075f1e6e1911db1000cfcbb398ffdae48e (patch)
treef080855d3f372b0b1c7eccc81c79a14a8dcc5067 /sbin
parent7654c4a4b93a0c8473a697480f604acf3272bbcc (diff)
Introduce anchors and named rule sets, allowing to load additional rule
sets with pfctl and evaluate them from the main rule set using a new type of rule (which will support conditional evaluation soon). Makes maintenance of sub-rulesets simpler for pfctl and daemons. Idea and ok deraadt@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/pfctl/parse.y219
-rw-r--r--sbin/pfctl/pfctl.829
-rw-r--r--sbin/pfctl/pfctl.c178
-rw-r--r--sbin/pfctl/pfctl_parser.c42
4 files changed, 344 insertions, 124 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 1ed17e8819b..cbddf31d85a 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.236 2002/12/05 15:28:00 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.237 2002/12/06 00:47:31 dhartmei Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -313,6 +313,18 @@ typedef struct {
int lineno;
} YYSTYPE;
+#define PREPARE_ANCHOR_RULE(r, a) \
+ do { \
+ if (strlen(a) >= PF_ANCHOR_NAME_SIZE) { \
+ yyerror("anchor name '%s' too long", \
+ (a)); \
+ YYERROR; \
+ } \
+ memset(&(r), 0, sizeof(r)); \
+ strcpy(r.anchorname, (a)); \
+ } while (0)
+
+
%}
%token PASS BLOCK SCRUB RETURN IN OUT LOG LOGALL QUICK ON FROM TO FLAGS
@@ -320,7 +332,7 @@ typedef struct {
%token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF
%token MINTTL ERROR ALLOWOPTS FASTROUTE ROUTETO DUPTO REPLYTO NO LABEL
%token NOROUTE FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS DROP
-%token FRAGNORM FRAGDROP FRAGCROP
+%token FRAGNORM FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR
%token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY
%token REQUIREORDER YES
%token ANTISPOOF FOR
@@ -373,6 +385,7 @@ ruleset : /* empty */
| ruleset binatrule '\n'
| ruleset rdrrule '\n'
| ruleset pfrule '\n'
+ | ruleset anchorrule '\n'
| ruleset altqif '\n'
| ruleset queuespec '\n'
| ruleset varset '\n'
@@ -451,6 +464,33 @@ varset : STRING PORTUNARY string {
}
;
+anchorrule : ANCHOR string {
+ struct pf_rule r;
+
+ PREPARE_ANCHOR_RULE(r, $2);
+ r.nr = pf->rule_nr++;
+ pfctl_add_rule(pf, &r);
+ }
+ | NATANCHOR string {
+ struct pf_nat r;
+
+ PREPARE_ANCHOR_RULE(r, $2);
+ pfctl_add_nat(pf, &r);
+ }
+ | RDRANCHOR string {
+ struct pf_rdr r;
+
+ PREPARE_ANCHOR_RULE(r, $2);
+ pfctl_add_rdr(pf, &r);
+ }
+ | BINATANCHOR string {
+ struct pf_binat r;
+
+ PREPARE_ANCHOR_RULE(r, $2);
+ pfctl_add_binat(pf, &r);
+ }
+ ;
+
scrubrule : SCRUB dir interface af fromto nodf minttl maxmss fragcache
{
struct pf_rule r;
@@ -992,7 +1032,8 @@ fragcache : /* empty */ { $$ = 0; }
;
-dir : IN { $$ = PF_IN; }
+dir : /* empty */ { $$ = 0; }
+ | IN { $$ = PF_IN; }
| OUT { $$ = PF_OUT; }
;
@@ -1131,9 +1172,11 @@ host_list : xhost { $$ = $1; }
;
xhost : '!' host {
- struct node_host *h;
- for (h = $2; h; h = h->next)
- h->not = 1;
+ if ($2->next != NULL) {
+ yyerror("negated address list");
+ YYERROR;
+ } else
+ $2->not = 1;
$$ = $2;
}
| host { $$ = $1; }
@@ -3022,86 +3065,90 @@ lookup(char *s)
{
/* this has to be sorted always */
static const struct keywords keywords[] = {
- { "all", ALL},
- { "allow-opts", ALLOWOPTS},
- { "altq", ALTQ},
- { "antispoof", ANTISPOOF},
- { "any", ANY},
- { "bandwidth", BANDWIDTH},
- { "binat", BINAT},
- { "bitmask", BITMASK},
- { "block", BLOCK},
- { "block-policy", BLOCKPOLICY},
- { "borrow", BORROW},
- { "cbq", CBQ},
- { "code", CODE},
- { "control", CONTROL},
- { "crop", FRAGCROP},
- { "default", DEFAULT},
- { "drop", DROP},
- { "drop-ovl", FRAGDROP},
- { "dup-to", DUPTO},
- { "ecn", ECN},
- { "fastroute", FASTROUTE},
- { "flags", FLAGS},
- { "for", FOR},
- { "fragment", FRAGMENT},
- { "from", FROM},
- { "group", GROUP},
- { "icmp-type", ICMPTYPE},
- { "in", IN},
- { "inet", INET},
- { "inet6", INET6},
- { "ipv6-icmp-type", ICMP6TYPE},
- { "keep", KEEP},
- { "label", LABEL},
- { "limit", LIMIT},
- { "log", LOG},
- { "log-all", LOGALL},
- { "loginterface", LOGINTERFACE},
- { "max", MAXIMUM},
- { "max-mss", MAXMSS},
- { "min-ttl", MINTTL},
- { "modulate", MODULATE},
- { "nat", NAT},
- { "no", NO},
- { "no-df", NODF},
- { "no-route", NOROUTE},
- { "on", ON},
- { "optimization", OPTIMIZATION},
- { "out", OUT},
- { "pass", PASS},
- { "port", PORT},
- { "priority", PRIORITY},
- { "proto", PROTO},
- { "qlimit", QLIMIT},
- { "queue", QUEUE},
- { "quick", QUICK},
- { "random", RANDOM},
- { "rdr", RDR},
- { "reassemble", FRAGNORM},
- { "red", RED},
- { "reply-to", REPLYTO},
- { "require-order", REQUIREORDER},
- { "return", RETURN},
- { "return-icmp",RETURNICMP},
- { "return-icmp6",RETURNICMP6},
- { "return-rst", RETURNRST},
- { "rio", RIO},
- { "round-robin",ROUNDROBIN},
- { "route-to", ROUTETO},
- { "scheduler", SCHEDULER},
- { "scrub", SCRUB},
- { "set", SET},
- { "source-hash",SOURCEHASH},
- { "state", STATE},
- { "tbrsize", TBRSIZE},
- { "timeout", TIMEOUT},
- { "to", TO},
- { "tos", TOS},
- { "ttl", TTL},
- { "user", USER},
- { "yes", YES},
+ { "all", ALL},
+ { "allow-opts", ALLOWOPTS},
+ { "altq", ALTQ},
+ { "anchor", ANCHOR},
+ { "antispoof", ANTISPOOF},
+ { "any", ANY},
+ { "bandwidth", BANDWIDTH},
+ { "binat", BINAT},
+ { "binat-anchor", BINATANCHOR},
+ { "bitmask", BITMASK},
+ { "block", BLOCK},
+ { "block-policy", BLOCKPOLICY},
+ { "borrow", BORROW},
+ { "cbq", CBQ},
+ { "code", CODE},
+ { "control", CONTROL},
+ { "crop", FRAGCROP},
+ { "default", DEFAULT},
+ { "drop", DROP},
+ { "drop-ovl", FRAGDROP},
+ { "dup-to", DUPTO},
+ { "ecn", ECN},
+ { "fastroute", FASTROUTE},
+ { "flags", FLAGS},
+ { "for", FOR},
+ { "fragment", FRAGMENT},
+ { "from", FROM},
+ { "group", GROUP},
+ { "icmp-type", ICMPTYPE},
+ { "in", IN},
+ { "inet", INET},
+ { "inet6", INET6},
+ { "ipv6-icmp-type", ICMP6TYPE},
+ { "keep", KEEP},
+ { "label", LABEL},
+ { "limit", LIMIT},
+ { "log", LOG},
+ { "log-all", LOGALL},
+ { "loginterface", LOGINTERFACE},
+ { "max", MAXIMUM},
+ { "max-mss", MAXMSS},
+ { "min-ttl", MINTTL},
+ { "modulate", MODULATE},
+ { "nat", NAT},
+ { "nat-anchor", NATANCHOR},
+ { "no", NO},
+ { "no-df", NODF},
+ { "no-route", NOROUTE},
+ { "on", ON},
+ { "optimization", OPTIMIZATION},
+ { "out", OUT},
+ { "pass", PASS},
+ { "port", PORT},
+ { "priority", PRIORITY},
+ { "proto", PROTO},
+ { "qlimit", QLIMIT},
+ { "queue", QUEUE},
+ { "quick", QUICK},
+ { "random", RANDOM},
+ { "rdr", RDR},
+ { "rdr-anchor", RDRANCHOR},
+ { "reassemble", FRAGNORM},
+ { "red", RED},
+ { "reply-to", REPLYTO},
+ { "require-order", REQUIREORDER},
+ { "return", RETURN},
+ { "return-icmp", RETURNICMP},
+ { "return-icmp6", RETURNICMP6},
+ { "return-rst", RETURNRST},
+ { "rio", RIO},
+ { "round-robin", ROUNDROBIN},
+ { "route-to", ROUTETO},
+ { "scheduler", SCHEDULER},
+ { "scrub", SCRUB},
+ { "set", SET},
+ { "source-hash", SOURCEHASH},
+ { "state", STATE},
+ { "tbrsize", TBRSIZE},
+ { "timeout", TIMEOUT},
+ { "to", TO},
+ { "tos", TOS},
+ { "ttl", TTL},
+ { "user", USER},
+ { "yes", YES},
};
const struct keywords *p;
diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8
index 059366dea2e..f22229b56f8 100644
--- a/sbin/pfctl/pfctl.8
+++ b/sbin/pfctl/pfctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pfctl.8,v 1.57 2002/12/04 08:07:28 deraadt Exp $
+.\" $OpenBSD: pfctl.8,v 1.58 2002/12/06 00:47:31 dhartmei Exp $
.\"
.\" Copyright (c) 2001 Kjell Wooding. All rights reserved.
.\"
@@ -33,6 +33,7 @@
.Sh SYNOPSIS
.Nm pfctl
.Op Fl AdehnNqrRvzO
+.Op Fl a Ar anchor[:ruleset]
.Op Fl F Ar modifier
.Op Fl f Ar file
.Op Fl k Ar host
@@ -84,6 +85,26 @@ The
utility provides several commands.
The options are as follows:
.Bl -tag -width Ds
+.It Fl a Ar anchor Ns Op Ar :ruleset
+Apply flags
+.Fl f ,
+.Fl F
+and
+.Fl s
+only to the rules in the specified
+.Pa anchor
+and optional named rule set
+.Ar ruleset .
+In addition to the main rule set,
+.Nm
+can load and manipulate additional rule sets by name.
+Named rule sets are attached at
+.Pa anchor
+points, which are also referenced by name.
+Evaluation of
+.Pa anchor
+rules from the main rule set is described in
+.Xr pf.conf 5 .
.It Fl A
Load only the queue rules present in the rule file.
Other rules and options are ignored.
@@ -159,6 +180,12 @@ will skip evaluation of rules where possible.
Packets passed statefully are counted in the rule that created the state
(even though the rule isn't evaluated more than once for the entire
connection).
+.It Fl s Ar anchor
+Show the currently loaded anchors.
+If
+.Fl a
+is specified, the named rule sets currently loaded in the specified
+anchor are shown instead.
.It Fl s Ar state
Show the contents of the state table.
.It Fl s Ar info
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index d4f9848a58f..b4d4e765256 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.98 2002/12/05 14:10:45 henning Exp $ */
+/* $OpenBSD: pfctl.c,v 1.99 2002/12/06 00:47:31 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -76,15 +76,19 @@ int pfctl_debug(int, u_int32_t, int);
int pfctl_clear_rule_counters(int, int);
int pfctl_add_pool(struct pfctl *, struct pf_pool *, sa_family_t);
int pfctl_test_altqsupport(int);
+int pfctl_show_anchors(int, int);
char *clearopt;
char *rulesopt;
char *showopt;
char *debugopt;
+char *anchoropt;
int state_killers;
char *state_kill[2];
int loadopt = PFCTL_FLAG_ALL;
int altqsupport;
+char anchorname[PF_ANCHOR_NAME_SIZE];
+char rulesetname[PF_RULESET_NAME_SIZE];
const char *infile;
@@ -156,10 +160,10 @@ usage(void)
{
extern char *__progname;
- fprintf(stderr, "usage: %s [-AdeqhnNrROvz] [-f file] ", __progname);
- fprintf(stderr, "[-F modifier] [-k host]\n");
+ fprintf(stderr, "usage: %s [-AdeqhnNrROvz] ", __progname);
+ fprintf(stderr, "[-a anchor:ruleset] [-f file]\n");
fprintf(stderr, " ");
- fprintf(stderr, "[-s modifier] [-x level]\n");
+ fprintf(stderr, "[-F modifier] [-k host] [-s modifier] [-x level]\n");
exit(1);
}
@@ -230,9 +234,12 @@ pfctl_clear_rules(int dev, int opts)
{
struct pfioc_rule pr;
- if (ioctl(dev, DIOCBEGINRULES, &pr.ticket))
+ memset(&pr, 0, sizeof(pr));
+ memcpy(pr.anchor, anchorname, sizeof(pr.anchor));
+ memcpy(pr.ruleset, rulesetname, sizeof(pr.ruleset));
+ if (ioctl(dev, DIOCBEGINRULES, &pr))
err(1, "DIOCBEGINRULES");
- else if (ioctl(dev, DIOCCOMMITRULES, &pr.ticket))
+ else if (ioctl(dev, DIOCCOMMITRULES, &pr))
err(1, "DIOCCOMMITRULES");
if ((opts & PF_OPT_QUIET) == 0)
fprintf(stderr, "rules cleared\n");
@@ -246,17 +253,26 @@ pfctl_clear_nat(int dev, int opts)
struct pfioc_binat pb;
struct pfioc_rdr pr;
- if (ioctl(dev, DIOCBEGINNATS, &pn.ticket))
+ memset(&pn, 0, sizeof(pn));
+ memset(&pb, 0, sizeof(pb));
+ memset(&pr, 0, sizeof(pr));
+ memcpy(pn.anchor, anchorname, sizeof(pn.anchor));
+ memcpy(pn.ruleset, rulesetname, sizeof(pn.ruleset));
+ memcpy(pb.anchor, anchorname, sizeof(pb.anchor));
+ memcpy(pb.ruleset, rulesetname, sizeof(pb.ruleset));
+ memcpy(pr.anchor, anchorname, sizeof(pr.anchor));
+ memcpy(pr.ruleset, rulesetname, sizeof(pr.ruleset));
+ if (ioctl(dev, DIOCBEGINNATS, &pn))
err(1, "DIOCBEGINNATS");
- else if (ioctl(dev, DIOCCOMMITNATS, &pn.ticket))
+ else if (ioctl(dev, DIOCCOMMITNATS, &pn))
err(1, "DIOCCOMMITNATS");
- if (ioctl(dev, DIOCBEGINBINATS, &pb.ticket))
+ if (ioctl(dev, DIOCBEGINBINATS, &pb))
err(1, "DIOCBEGINBINATS");
- else if (ioctl(dev, DIOCCOMMITBINATS, &pb.ticket))
+ else if (ioctl(dev, DIOCCOMMITBINATS, &pb))
err(1, "DIOCCOMMITBINATS");
- else if (ioctl(dev, DIOCBEGINRDRS, &pr.ticket))
+ else if (ioctl(dev, DIOCBEGINRDRS, &pr))
err(1, "DIOCBEGINRDRS");
- else if (ioctl(dev, DIOCCOMMITRDRS, &pr.ticket))
+ else if (ioctl(dev, DIOCCOMMITRDRS, &pr))
err(1, "DIOCCOMMITRDRS");
if ((opts & PF_OPT_QUIET) == 0)
fprintf(stderr, "nat cleared\n");
@@ -270,7 +286,7 @@ pfctl_clear_altq(int dev, int opts)
if (!altqsupport)
return (-1);
-
+ memset(&pa, 0, sizeof(pa));
if (ioctl(dev, DIOCBEGINALTQS, &pa.ticket))
err(1, "DIOCBEGINALTQS");
else if (ioctl(dev, DIOCCOMMITALTQS, &pa.ticket))
@@ -399,6 +415,9 @@ pfctl_get_pool(int dev, struct pf_pool *pool, u_int32_t nr,
struct pf_pooladdr *pa;
u_int32_t pnr, mpnr;
+ memset(&pp, 0, sizeof(pp));
+ memcpy(pp.anchor, anchorname, sizeof(pp.anchor));
+ memcpy(pp.ruleset, rulesetname, sizeof(pp.ruleset));
pp.r_id = id;
pp.r_num = nr;
pp.ticket = ticket;
@@ -443,6 +462,9 @@ pfctl_show_rules(int dev, int opts, int format)
struct pfioc_rule pr;
u_int32_t nr, mnr;
+ memset(&pr, 0, sizeof(pr));
+ memcpy(pr.anchor, anchorname, sizeof(pr.anchor));
+ memcpy(pr.ruleset, rulesetname, sizeof(pr.ruleset));
if (ioctl(dev, DIOCGETRULES, &pr)) {
warn("DIOCGETRULES");
return (-1);
@@ -495,7 +517,7 @@ pfctl_show_altq(int dev)
if (!altqsupport)
return (-1);
-
+ memset(&pa, 0, sizeof(pa));
if (ioctl(dev, DIOCGETALTQS, &pa)) {
warn("DIOCGETALTQS");
return (-1);
@@ -523,6 +545,15 @@ pfctl_show_nat(int dev)
struct pfioc_binat pb;
u_int32_t mnr, nr;
+ memset(&pn, 0, sizeof(pn));
+ memset(&pr, 0, sizeof(pr));
+ memset(&pb, 0, sizeof(pb));
+ memcpy(pn.anchor, anchorname, sizeof(pn.anchor));
+ memcpy(pn.ruleset, rulesetname, sizeof(pn.ruleset));
+ memcpy(pr.anchor, anchorname, sizeof(pr.anchor));
+ memcpy(pr.ruleset, rulesetname, sizeof(pr.ruleset));
+ memcpy(pb.anchor, anchorname, sizeof(pb.anchor));
+ memcpy(pb.ruleset, rulesetname, sizeof(pb.ruleset));
if (ioctl(dev, DIOCGETNATS, &pn)) {
warn("DIOCGETNATS");
return (-1);
@@ -582,6 +613,7 @@ pfctl_show_states(int dev, u_int8_t proto, int opts)
unsigned len = 0;
int i;
+ memset(&ps, 0, sizeof(ps));
for (;;) {
ps.ps_len = len;
if (len) {
@@ -631,6 +663,7 @@ pfctl_show_timeouts(int dev)
struct pfioc_tm pt;
int i;
+ memset(&pt, 0, sizeof(pt));
for (i = 0; pf_timeouts[i].name; i++) {
pt.timeout = pf_timeouts[i].timeout;
if (ioctl(dev, DIOCGETTIMEOUT, &pt))
@@ -647,6 +680,7 @@ pfctl_show_limits(int dev)
struct pfioc_limit pl;
int i;
+ memset(&pl, 0, sizeof(pl));
for (i = 0; pf_limits[i].name; i++) {
pl.index = i;
if (ioctl(dev, DIOCGETLIMIT, &pl))
@@ -667,7 +701,7 @@ pfctl_add_pool(struct pfctl *pf, struct pf_pool *p, sa_family_t af)
struct pf_pooladdr *pa;
if ((pf->opts & PF_OPT_NOACTION) == 0) {
- if (ioctl(pf->dev, DIOCBEGINADDRS, &pf->paddr.ticket))
+ if (ioctl(pf->dev, DIOCBEGINADDRS, &pf->paddr))
err(1, "DIOCBEGINADDRS");
}
@@ -781,6 +815,20 @@ pfctl_rules(int dev, char *filename, int opts)
struct pfioc_altq pa;
struct pfctl pf;
+ memset(&pn, 0, sizeof(pn));
+ memset(&pb, 0, sizeof(pb));
+ memset(&pr, 0, sizeof(pr));
+ memset(&pl, 0, sizeof(pl));
+ memset(&pa, 0, sizeof(pa));
+ memset(&pf, 0, sizeof(pf));
+ memcpy(pn.anchor, anchorname, sizeof(pn.anchor));
+ memcpy(pn.ruleset, rulesetname, sizeof(pn.ruleset));
+ memcpy(pb.anchor, anchorname, sizeof(pb.anchor));
+ memcpy(pb.ruleset, rulesetname, sizeof(pb.ruleset));
+ memcpy(pr.anchor, anchorname, sizeof(pr.anchor));
+ memcpy(pr.ruleset, rulesetname, sizeof(pr.ruleset));
+ memcpy(pl.anchor, anchorname, sizeof(pl.anchor));
+ memcpy(pl.ruleset, rulesetname, sizeof(pl.ruleset));
if (strcmp(filename, "-") == 0) {
fin = stdin;
infile = "stdin";
@@ -794,11 +842,11 @@ pfctl_rules(int dev, char *filename, int opts)
}
if ((opts & PF_OPT_NOACTION) == 0) {
if ((loadopt & (PFCTL_FLAG_NAT | PFCTL_FLAG_ALL)) != 0) {
- if (ioctl(dev, DIOCBEGINNATS, &pn.ticket))
+ if (ioctl(dev, DIOCBEGINNATS, &pn))
err(1, "DIOCBEGINNATS");
- if (ioctl(dev, DIOCBEGINRDRS, &pr.ticket))
+ if (ioctl(dev, DIOCBEGINRDRS, &pr))
err(1, "DIOCBEGINRDRS");
- if (ioctl(dev, DIOCBEGINBINATS, &pb.ticket))
+ if (ioctl(dev, DIOCBEGINBINATS, &pb))
err(1, "DIOCBEGINBINATS");
}
if (((altqsupport && loadopt
@@ -807,7 +855,7 @@ pfctl_rules(int dev, char *filename, int opts)
err(1, "DIOCBEGINALTQS");
}
if (((loadopt & (PFCTL_FLAG_FILTER | PFCTL_FLAG_ALL)) != 0) &&
- ioctl(dev, DIOCBEGINRULES, &pl.ticket))
+ ioctl(dev, DIOCBEGINRULES, &pl))
err(1, "DIOCBEGINRULES");
}
/* fill in callback data */
@@ -826,11 +874,11 @@ pfctl_rules(int dev, char *filename, int opts)
errx(1, "errors in altq config");
if ((opts & PF_OPT_NOACTION) == 0) {
if ((loadopt & (PFCTL_FLAG_NAT | PFCTL_FLAG_ALL)) != 0) {
- if (ioctl(dev, DIOCCOMMITNATS, &pn.ticket))
+ if (ioctl(dev, DIOCCOMMITNATS, &pn))
err(1, "DIOCCOMMITNATS");
- if (ioctl(dev, DIOCCOMMITRDRS, &pr.ticket))
+ if (ioctl(dev, DIOCCOMMITRDRS, &pr))
err(1, "DIOCCOMMITRDRS");
- if (ioctl(dev, DIOCCOMMITBINATS, &pb.ticket))
+ if (ioctl(dev, DIOCCOMMITBINATS, &pb))
err(1, "DIOCCOMMITBINATS");
}
if (((altqsupport && loadopt
@@ -838,7 +886,7 @@ pfctl_rules(int dev, char *filename, int opts)
ioctl(dev, DIOCCOMMITALTQS, &pa.ticket))
err(1, "DIOCCOMMITALTQS");
if (((loadopt & (PFCTL_FLAG_FILTER | PFCTL_FLAG_ALL)) != 0) &&
- ioctl(dev, DIOCCOMMITRULES, &pl.ticket))
+ ioctl(dev, DIOCCOMMITRULES, &pl))
err(1, "DIOCCOMMITRULES");
#if 0
if ((opts & PF_OPT_QUIET) == 0) {
@@ -860,6 +908,7 @@ pfctl_set_limit(struct pfctl *pf, const char *opt, unsigned int limit)
struct pfioc_limit pl;
int i;
+ memset(&pl, 0, sizeof(pl));
if ((loadopt & (PFCTL_FLAG_OPTION | PFCTL_FLAG_ALL)) != 0) {
for (i = 0; pf_limits[i].name; i++) {
if (strcasecmp(opt, pf_limits[i].name) == 0) {
@@ -894,6 +943,7 @@ pfctl_set_timeout(struct pfctl *pf, const char *opt, int seconds)
struct pfioc_tm pt;
int i;
+ memset(&pt, 0, sizeof(pt));
if ((loadopt & (PFCTL_FLAG_OPTION | PFCTL_FLAG_ALL)) != 0) {
for (i = 0; pf_timeouts[i].name; i++) {
if (strcasecmp(opt, pf_timeouts[i].name) == 0) {
@@ -946,6 +996,7 @@ pfctl_set_logif(struct pfctl *pf, char *ifname)
{
struct pfioc_if pi;
+ memset(&pi, 0, sizeof(pi));
if ((loadopt & (PFCTL_FLAG_OPTION | PFCTL_FLAG_ALL)) != 0) {
if ((pf->opts & PF_OPT_NOACTION) == 0) {
if (!strcmp(ifname, "none"))
@@ -1012,6 +1063,56 @@ pfctl_test_altqsupport(int dev)
}
int
+pfctl_show_anchors(int dev, int opts)
+{
+ u_int32_t nr, mnr;
+
+ if (!*anchorname) {
+ struct pfioc_anchor pa;
+
+ memset(&pa, 0, sizeof(pa));
+ if (ioctl(dev, DIOCGETANCHORS, &pa)) {
+ warnx("DIOCGETANCHORS");
+ return (-1);
+ }
+ mnr = pa.nr;
+ printf("%u anchors:\n", mnr);
+ for (nr = 0; nr < mnr; ++nr) {
+ pa.nr = nr;
+ if (ioctl(dev, DIOCGETANCHOR, &pa)) {
+ warnx("DIOCGETANCHOR");
+ return (-1);
+ }
+ printf(" %s\n", pa.name);
+ }
+ } else {
+ struct pfioc_ruleset pr;
+
+ memset(&pr, 0, sizeof(pr));
+ memcpy(pr.anchor, anchorname, sizeof(pr.anchor));
+ if (ioctl(dev, DIOCGETRULESETS, &pr)) {
+ if (errno == EINVAL)
+ fprintf(stderr, "No rulesets in anchor '%s'.\n",
+ anchorname);
+ else
+ warnx("DIOCGETRULESETS");
+ return (-1);
+ }
+ mnr = pr.nr;
+ printf("%u rulesets in anchor %s:\n", mnr, anchorname);
+ for (nr = 0; nr < mnr; ++nr) {
+ pr.nr = nr;
+ if (ioctl(dev, DIOCGETRULESET, &pr)) {
+ warnx("DIOCGETRULESET");
+ return (-1);
+ }
+ printf(" %s:%s\n", pr.anchor, pr.name);
+ }
+ }
+ return (0);
+}
+
+int
main(int argc, char *argv[])
{
int error = 0;
@@ -1023,8 +1124,11 @@ main(int argc, char *argv[])
if (argc < 2)
usage();
- while ((ch = getopt(argc, argv, "Adeqf:F:hk:nNOrRs:vx:z")) != -1) {
+ while ((ch = getopt(argc, argv, "a:Adeqf:F:hk:nNOrRs:vx:z")) != -1) {
switch (ch) {
+ case 'a':
+ anchoropt = optarg;
+ break;
case 'd':
opts |= PF_OPT_DISABLE;
mode = O_RDWR;
@@ -1105,6 +1209,29 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
+ memset(anchorname, 0, sizeof(anchorname));
+ memset(rulesetname, 0, sizeof(rulesetname));
+ if (anchoropt != NULL) {
+ char *t = strchr(anchoropt, ':');
+
+ if (t == NULL) {
+ if (strlen(anchoropt) >= sizeof(anchorname))
+ err(1, "anchor name '%s' too long",
+ anchoropt);
+ strcpy(anchorname, anchoropt);
+ } else {
+ if (t == anchoropt || !strlen(t+1))
+ err(1, "anchor names '%s' invalid",
+ anchoropt);
+ if (t-anchoropt >= sizeof(anchorname) ||
+ strlen(t+1) >= sizeof(rulesetname))
+ err(1, "anchor names '%s' too long",
+ anchoropt);
+ strncpy(anchorname, anchoropt, t-anchoropt);
+ strcpy(rulesetname, t+1);
+ }
+ }
+
if (opts & PF_OPT_NOACTION)
mode = O_RDONLY;
if ((opts & PF_OPT_NOACTION) == 0) {
@@ -1161,6 +1288,9 @@ main(int argc, char *argv[])
if (showopt != NULL) {
switch (*showopt) {
+ case 'A':
+ pfctl_show_anchors(dev, opts);
+ break;
case 'r':
pfctl_show_rules(dev, opts, 0);
break;
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index d97fa66256f..25984b2d228 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.116 2002/12/05 14:10:45 henning Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.117 2002/12/06 00:47:32 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -471,6 +471,10 @@ print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2,
void
print_nat(struct pf_nat *n)
{
+ if (n->anchorname[0]) {
+ printf("nat-anchor %s\n", n->anchorname);
+ return;
+ }
if (n->no)
printf("no ");
printf("nat ");
@@ -506,6 +510,10 @@ print_nat(struct pf_nat *n)
void
print_binat(struct pf_binat *b)
{
+ if (b->anchorname[0]) {
+ printf("binat-anchor %s\n", b->anchorname);
+ return;
+ }
if (b->no)
printf("no ");
printf("binat ");
@@ -549,6 +557,10 @@ print_binat(struct pf_binat *b)
void
print_rdr(struct pf_rdr *r)
{
+ if (r->anchorname[0]) {
+ printf("rdr-anchor %s\n", r->anchorname);
+ return;
+ }
if (r->no)
printf("no ");
printf("rdr ");
@@ -645,23 +657,23 @@ print_status(struct pf_status *s)
printf("Interface Stats for %-16s %5s %16s\n",
s->ifname, "IPv4", "IPv6");
printf(" %-25s %14llu %16llu\n", "Bytes In",
- s->bcounters[0][PF_IN], s->bcounters[1][PF_IN]);
+ s->bcounters[0][0], s->bcounters[1][0]);
printf(" %-25s %14llu %16llu\n", "Bytes Out",
- s->bcounters[0][PF_OUT], s->bcounters[1][PF_OUT]);
+ s->bcounters[0][1], s->bcounters[1][1]);
printf(" Packets In\n");
printf(" %-23s %14llu %16llu\n", "Passed",
- s->pcounters[0][PF_IN][PF_PASS],
- s->pcounters[1][PF_IN][PF_PASS]);
+ s->pcounters[0][0][PF_PASS],
+ s->pcounters[1][0][PF_PASS]);
printf(" %-23s %14llu %16llu\n", "Blocked",
- s->pcounters[0][PF_IN][PF_DROP],
- s->pcounters[1][PF_IN][PF_DROP]);
+ s->pcounters[0][0][PF_DROP],
+ s->pcounters[1][0][PF_DROP]);
printf(" Packets Out\n");
printf(" %-23s %14llu %16llu\n", "Passed",
- s->pcounters[0][PF_OUT][PF_PASS],
- s->pcounters[1][PF_OUT][PF_PASS]);
+ s->pcounters[0][1][PF_PASS],
+ s->pcounters[1][1][PF_PASS]);
printf(" %-23s %14llu %16llu\n\n", "Blocked",
- s->pcounters[0][PF_OUT][PF_DROP],
- s->pcounters[1][PF_OUT][PF_DROP]);
+ s->pcounters[0][1][PF_DROP],
+ s->pcounters[1][1][PF_DROP]);
}
printf("%-27s %14s %16s\n", "State Table", "Total", "Rate");
printf(" %-25s %14u %14s\n", "current entries", s->states, "");
@@ -693,6 +705,10 @@ print_rule(struct pf_rule *r, int verbose)
if (verbose)
printf("@%d ", r->nr);
+ if (r->anchorname[0]) {
+ printf("anchor %s\n", r->anchorname);
+ return;
+ }
if (r->action == PF_PASS)
printf("pass ");
else if (r->action == PF_DROP) {
@@ -743,9 +759,9 @@ print_rule(struct pf_rule *r, int verbose)
} else {
printf("scrub ");
}
- if (r->direction == 0)
+ if (r->direction == PF_IN)
printf("in ");
- else
+ else if (r->direction == PF_OUT)
printf("out ");
if (r->log == 1)
printf("log ");