diff options
author | Marco Pfatschbacher <mpf@cvs.openbsd.org> | 2005-05-22 21:05:24 +0000 |
---|---|---|
committer | Marco Pfatschbacher <mpf@cvs.openbsd.org> | 2005-05-22 21:05:24 +0000 |
commit | 9d406d5395219f58cb21c7af414f7ae3ff2f31cd (patch) | |
tree | 41d05240eecdf05e0bcb39972e1e223df29709f2 /sbin | |
parent | 1ab007e874cbeba337139155761f26c8f44c67c6 (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.8 | 49 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.c | 63 |
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", |