summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorMarco Pfatschbacher <mpf@cvs.openbsd.org>2005-05-22 21:05:24 +0000
committerMarco Pfatschbacher <mpf@cvs.openbsd.org>2005-05-22 21:05:24 +0000
commit9d406d5395219f58cb21c7af414f7ae3ff2f31cd (patch)
tree41d05240eecdf05e0bcb39972e1e223df29709f2 /sbin
parent1ab007e874cbeba337139155761f26c8f44c67c6 (diff)
Add support to kill states that match networks.
man page from jmc@ OK dhartmei@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/pfctl/pfctl.849
-rw-r--r--sbin/pfctl/pfctl.c63
2 files changed, 89 insertions, 23 deletions
diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8
index 9fdb00e361a..7569903ee19 100644
--- a/sbin/pfctl/pfctl.8
+++ b/sbin/pfctl/pfctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pfctl.8,v 1.118 2005/01/05 23:41:45 jmc Exp $
+.\" $OpenBSD: pfctl.8,v 1.119 2005/05/22 21:05:23 mpf Exp $
.\"
.\" Copyright (c) 2001 Kjell Wooding. All rights reserved.
.\"
@@ -42,7 +42,7 @@
.Op Fl F Ar modifier
.Op Fl f Ar file
.Op Fl i Ar interface
-.Op Fl k Ar host
+.Op Fl k Ar host | network
.Op Fl p Ar device
.Op Fl s Ar modifier
.Oo Xo
@@ -138,8 +138,10 @@ rules from the main ruleset is described in
For example, the following will show all filter rules (see the
.Fl s
flag below) inside the anchor
-.Li authpf/smith(1234) ,
-which would have been created for user smith by
+.Dq authpf/smith(1234) ,
+which would have been created for user
+.Dq smith
+by
.Xr authpf 8 ,
PID 1234:
.Bd -literal -offset indent
@@ -215,29 +217,38 @@ Help.
.It Fl i Ar interface
Restrict the operation to the given
.Ar interface .
-.It Fl k Ar host
+.It Fl k Ar host | network
Kill all of the state entries originating from the specified
-.Ar host .
+.Ar host
+or
+.Ar network .
A second
.Fl k Ar host
+or
+.Fl k Ar network
option may be specified, which will kill all the state entries
-from the first
-.Ar host
-to the second
-.Ar host .
+from the first host/network to the second.
For example, to kill all of the state entries originating from
-.Li host :
-.Bd -literal -offset indent
-# pfctl -k host
-.Ed
+.Dq host :
+.Pp
+.Dl # pfctl -k host
.Pp
To kill all of the state entries from
-.Li host1
+.Dq host1
to
-.Li host2 :
-.Bd -literal -offset indent
-# pfctl -k host1 -k host2
-.Ed
+.Dq host2 :
+.Pp
+.Dl # pfctl -k host1 -k host2
+.Pp
+To kill all states originating from 192.168.1.0/24 to 172.16.0.0/16:
+.Pp
+.Dl # pfctl -k 192.168.1.0/24 -k 172.16.0.0/16
+.Pp
+A network prefix length of 0 can be used as a wildcard.
+To kill all states with the target
+.Dq host2 :
+.Pp
+.Dl # pfctl -k 0.0.0.0/0 -k host2
.It Fl m
Merge in explicitly given options without resetting those
which are omitted.
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 4035d17a490..f65c816d9d1 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.236 2005/05/21 21:03:58 henning Exp $ */
+/* $OpenBSD: pfctl.c,v 1.237 2005/05/22 21:05:23 mpf Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -65,6 +65,7 @@ int pfctl_clear_nat(int, int, char *);
int pfctl_clear_altq(int, int);
int pfctl_clear_src_nodes(int, int);
int pfctl_clear_states(int, const char *, int);
+void pfctl_addrprefix(char *, struct pf_addr *);
int pfctl_kill_states(int, const char *, int);
void pfctl_init_options(struct pfctl *);
int pfctl_load_options(struct pfctl *);
@@ -205,10 +206,10 @@ usage(void)
fprintf(stderr, "usage: %s [-AdeghmNnOoqRrvz] ", __progname);
fprintf(stderr, "[-a anchor] [-D macro=value] [-F modifier]\n");
fprintf(stderr, " ");
- fprintf(stderr, "[-f file] [-i interface] [-k host] ");
- fprintf(stderr, "[-p device] [-s modifier]\n");
+ fprintf(stderr, "[-f file] [-i interface] [-k host | network] ");
+ fprintf(stderr, "[-p device]\n");
fprintf(stderr, " ");
- fprintf(stderr, "[-t table -T command [address ...]] ");
+ fprintf(stderr, "[-s modifier] [-t table -T command [address ...]] ");
fprintf(stderr, "[-x level]\n");
exit(1);
}
@@ -357,6 +358,56 @@ pfctl_clear_states(int dev, const char *iface, int opts)
return (0);
}
+void
+pfctl_addrprefix(char *addr, struct pf_addr *mask)
+{
+ char *p;
+ const char *errstr;
+ int prefix, ret_ga, q, r;
+ struct addrinfo hints, *res;
+
+ if ((p = strchr(addr, '/')) == NULL)
+ return;
+
+ *p++ = '\0';
+ prefix = strtonum(p, 0, 128, &errstr);
+ if (errstr)
+ errx(1, "prefix is %s: %s", errstr, p);
+
+ bzero(&hints, sizeof(hints));
+ /* prefix only with numeric addresses */
+ hints.ai_flags |= AI_NUMERICHOST;
+
+ if ((ret_ga = getaddrinfo(addr, NULL, &hints, &res))) {
+ errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
+ /* NOTREACHED */
+ }
+
+ if (res->ai_family == AF_INET && prefix > 32)
+ errx(1, "prefix too long for AF_INET");
+ else if (res->ai_family == AF_INET6 && prefix > 128)
+ errx(1, "prefix too long for AF_INET6");
+
+ q = prefix >> 3;
+ r = prefix & 7;
+ switch (res->ai_family) {
+ case AF_INET:
+ bzero(&mask->v4, sizeof(mask->v4));
+ mask->v4.s_addr = htonl((u_int32_t)
+ (0xffffffffffULL << (32 - prefix)));
+ break;
+ case AF_INET6:
+ bzero(&mask->v6, sizeof(mask->v6));
+ if (q > 0)
+ memset((void *)&mask->v6, 0xff, q);
+ if (r > 0)
+ *((u_char *)&mask->v6 + q) =
+ (0xff00 >> r) & 0xff;
+ break;
+ }
+ freeaddrinfo(res);
+}
+
int
pfctl_kill_states(int dev, const char *iface, int opts)
{
@@ -377,6 +428,8 @@ pfctl_kill_states(int dev, const char *iface, int opts)
sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname))
errx(1, "invalid interface: %s", iface);
+ pfctl_addrprefix(state_kill[0], &psk.psk_src.addr.v.a.mask);
+
if ((ret_ga = getaddrinfo(state_kill[0], NULL, NULL, &res[0]))) {
errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
/* NOTREACHED */
@@ -407,6 +460,8 @@ pfctl_kill_states(int dev, const char *iface, int opts)
memset(&psk.psk_dst.addr.v.a.mask, 0xff,
sizeof(psk.psk_dst.addr.v.a.mask));
memset(&last_dst, 0xff, sizeof(last_dst));
+ pfctl_addrprefix(state_kill[1],
+ &psk.psk_dst.addr.v.a.mask);
if ((ret_ga = getaddrinfo(state_kill[1], NULL, NULL,
&res[1]))) {
errx(1, "getaddrinfo: %s",