diff options
author | 2008-05-09 13:59:31 +0000 | |
---|---|---|
committer | 2008-05-09 13:59:31 +0000 | |
commit | 316145087cf1ebb10b44bb943d11febb770d72e6 (patch) | |
tree | 07e17160753be905bc161786761c6d254ff1955d | |
parent | Add support for NTT DoCoMo A2502. (diff) | |
download | wireguard-openbsd-316145087cf1ebb10b44bb943d11febb770d72e6.tar.xz wireguard-openbsd-316145087cf1ebb10b44bb943d11febb770d72e6.zip |
Add support to kill states by rule label or state id.
Fix printing of the state id in pfctl -ss -vv.
Remove the psnk_af hack to return the number of killed states.
OK markus, beck. "I like it" henning, deraadt.
Manpage help from jmc.
-rw-r--r-- | sbin/pfctl/pf_print_state.c | 4 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.8 | 59 | ||||
-rw-r--r-- | sbin/pfctl/pfctl.c | 98 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 31 | ||||
-rw-r--r-- | sys/net/pfvar.h | 8 |
5 files changed, 158 insertions, 42 deletions
diff --git a/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c index 8489c38c73a..ea726184add 100644 --- a/sbin/pfctl/pf_print_state.c +++ b/sbin/pfctl/pf_print_state.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_print_state.c,v 1.46 2007/08/30 09:28:49 dhartmei Exp $ */ +/* $OpenBSD: pf_print_state.c,v 1.47 2008/05/09 13:59:31 mpf Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -308,7 +308,7 @@ print_state(struct pfsync_state *s, int opts) } if (opts & PF_OPT_VERBOSE2) { printf(" id: %016llx creatorid: %08x%s\n", - pf_state_counter_from_pfsync(s->id), ntohl(s->creatorid), + betoh64(*(u_int64_t *)(s->id)), ntohl(s->creatorid), ((s->sync_flags & PFSTATE_NOSYNC) ? " (no-sync)" : "")); } } diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8 index 1273538d142..d8e510212d4 100644 --- a/sbin/pfctl/pfctl.8 +++ b/sbin/pfctl/pfctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pfctl.8,v 1.134 2008/05/06 03:50:03 mpf Exp $ +.\" $OpenBSD: pfctl.8,v 1.135 2008/05/09 13:59:31 mpf Exp $ .\" .\" Copyright (c) 2001 Kjell Wooding. All rights reserved. .\" @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 6 2008 $ +.Dd $Mdocdate: May 9 2008 $ .Dt PFCTL 8 .Os .Sh NAME @@ -41,7 +41,10 @@ .Op Fl f Ar file .Op Fl i Ar interface .Op Fl K Ar host | network -.Op Fl k Ar host | network +.Xo +.Oo Fl k +.Ar host | network | label | id +.Oc Xc .Op Fl o Ar level .Op Fl p Ar device .Op Fl s Ar modifier @@ -249,22 +252,28 @@ or .Fl K Ar network option may be specified, which will kill all the source tracking entries from the first host/network to the second. -.It Fl k Ar host | network -Kill all of the state entries originating from the specified -.Ar host +.It Xo +.Fl k +.Ar host | network | label | id +.Xc +Kill all of the state entries matching the specified +.Ar host , +.Ar network , +.Ar label , or -.Ar network . +.Ar id . +.Pp +For example, to kill all of the state entries originating from +.Dq host : +.Pp +.Dl # pfctl -k host +.Pp 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 host/network to the second. -For example, to kill all of the state entries originating from -.Dq host : -.Pp -.Dl # pfctl -k host -.Pp To kill all of the state entries from .Dq host1 to @@ -281,6 +290,32 @@ To kill all states with the target .Dq host2 : .Pp .Dl # pfctl -k 0.0.0.0/0 -k host2 +.Pp +It is also possible to kill states by rule label or state ID. +In this mode the first +.Fl k +argument is used to specify the type +of the second argument. +The following command would kill all states that have been created +from rules carrying the label +.Dq foobar : +.Pp +.Dl # pfctl -k label -k foobar +.Pp +To kill one specific state by its unique state ID +(as shown by pfctl -s state -vv), +use the +.Ar id +modifier and as a second argument the state ID and optional creator ID. +To kill a state with ID 4823e84500000003 use: +.Pp +.Dl # pfctl -k id -k 4823e84500000003 +.Pp +To kill a state with ID 4823e84500000018 created from a backup +firewall with hostid 00000002 use: +.Pp +.Dl # pfctl -k id -k 4823e84500000018/2 +.Pp .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 a9ba4e76b64..ee6b40b6766 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.274 2008/05/06 03:45:21 mpf Exp $ */ +/* $OpenBSD: pfctl.c,v 1.275 2008/05/09 13:59:31 mpf Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -68,7 +68,9 @@ 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_src_nodes(int, const char *, int); -int pfctl_kill_states(int, const char *, int); +int pfctl_net_kill_states(int, const char *, int); +int pfctl_label_kill_states(int, const char *, int); +int pfctl_id_kill_states(int, const char *, int); void pfctl_init_options(struct pfctl *); int pfctl_load_options(struct pfctl *); int pfctl_load_limit(struct pfctl *, unsigned int, unsigned int); @@ -229,7 +231,7 @@ usage(void) fprintf(stderr, "usage: %s [-AdeghmNnOqRrvz] ", __progname); fprintf(stderr, "[-a anchor] [-D macro=value] [-F modifier]\n"); fprintf(stderr, "\t[-f file] [-i interface] [-K host | network] "); - fprintf(stderr, "[-k host | network]\n"); + fprintf(stderr, "[-k host | network | label | id]\n"); fprintf(stderr, "\t[-o level] [-p device] [-s modifier]\n"); fprintf(stderr, "\t[-t table -T command [address ...]] [-x level]\n"); exit(1); @@ -515,17 +517,13 @@ pfctl_kill_src_nodes(int dev, const char *iface, int opts) if (ioctl(dev, DIOCKILLSRCNODES, &psnk)) err(1, "DIOCKILLSRCNODES"); - killed += psnk.psnk_af; - /* fixup psnk.psnk_af */ - psnk.psnk_af = resp[1]->ai_family; + killed += psnk.psnk_killed; } freeaddrinfo(res[1]); } else { if (ioctl(dev, DIOCKILLSRCNODES, &psnk)) err(1, "DIOCKILLSRCNODES"); - killed += psnk.psnk_af; - /* fixup psnk.psnk_af */ - psnk.psnk_af = res[0]->ai_family; + killed += psnk.psnk_killed; } } @@ -538,7 +536,7 @@ pfctl_kill_src_nodes(int dev, const char *iface, int opts) } int -pfctl_kill_states(int dev, const char *iface, int opts) +pfctl_net_kill_states(int dev, const char *iface, int opts) { struct pfioc_state_kill psk; struct addrinfo *res[2], *resp[2]; @@ -625,17 +623,13 @@ pfctl_kill_states(int dev, const char *iface, int opts) if (ioctl(dev, DIOCKILLSTATES, &psk)) err(1, "DIOCKILLSTATES"); - killed += psk.psk_af; - /* fixup psk.psk_af */ - psk.psk_af = resp[1]->ai_family; + killed += psk.psk_killed; } freeaddrinfo(res[1]); } else { if (ioctl(dev, DIOCKILLSTATES, &psk)) err(1, "DIOCKILLSTATES"); - killed += psk.psk_af; - /* fixup psk.psk_af */ - psk.psk_af = res[0]->ai_family; + killed += psk.psk_killed; } } @@ -648,6 +642,68 @@ pfctl_kill_states(int dev, const char *iface, int opts) } int +pfctl_label_kill_states(int dev, const char *iface, int opts) +{ + struct pfioc_state_kill psk; + + if (state_killers != 2 || (strlen(state_kill[1]) == 0)) { + warnx("no label specified"); + usage(); + } + memset(&psk, 0, sizeof(psk)); + if (iface != NULL && strlcpy(psk.psk_ifname, iface, + sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname)) + errx(1, "invalid interface: %s", iface); + + if (strlcpy(psk.psk_label, state_kill[1], sizeof(psk.psk_label)) >= + sizeof(psk.psk_label)) + errx(1, "label too long: %s", state_kill[1]); + + if (ioctl(dev, DIOCKILLSTATES, &psk)) + err(1, "DIOCKILLSTATES"); + + if ((opts & PF_OPT_QUIET) == 0) + fprintf(stderr, "killed %d states\n", psk.psk_killed); + + return (0); +} + +int +pfctl_id_kill_states(int dev, const char *iface, int opts) +{ + struct pfioc_state_kill psk; + + if (state_killers != 2 || (strlen(state_kill[1]) == 0)) { + warnx("no id specified"); + usage(); + } + + memset(&psk, 0, sizeof(psk)); + if ((sscanf(state_kill[1], "%llx/%x", + &psk.psk_pfcmp.id, &psk.psk_pfcmp.creatorid)) == 2) + HTONL(psk.psk_pfcmp.creatorid); + else if ((sscanf(state_kill[1], "%llx", &psk.psk_pfcmp.id)) == 1) { + psk.psk_pfcmp.creatorid = 0; + } else { + warnx("wrong id format specified"); + usage(); + } + if (psk.psk_pfcmp.id == 0) { + warnx("cannot kill id 0"); + usage(); + } + + psk.psk_pfcmp.id = htobe64(psk.psk_pfcmp.id); + if (ioctl(dev, DIOCKILLSTATES, &psk)) + err(1, "DIOCKILLSTATES"); + + if ((opts & PF_OPT_QUIET) == 0) + fprintf(stderr, "killed %d states\n", psk.psk_killed); + + return (0); +} + +int pfctl_get_pool(int dev, struct pf_pool *pool, u_int32_t nr, u_int32_t ticket, int r_action, char *anchorname) { @@ -2247,8 +2303,14 @@ main(int argc, char *argv[]) break; } } - if (state_killers) - pfctl_kill_states(dev, ifaceopt, opts); + if (state_killers) { + if (!strcmp(state_kill[0], "label")) + pfctl_label_kill_states(dev, ifaceopt, opts); + else if (!strcmp(state_kill[0], "id")) + pfctl_id_kill_states(dev, ifaceopt, opts); + else + pfctl_net_kill_states(dev, ifaceopt, opts); + } if (src_node_killers) pfctl_kill_src_nodes(dev, ifaceopt, opts); diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c index 50b319a9b9f..5243d3aea4e 100644 --- a/sys/net/pf_ioctl.c +++ b/sys/net/pf_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_ioctl.c,v 1.195 2008/05/06 03:45:22 mpf Exp $ */ +/* $OpenBSD: pf_ioctl.c,v 1.196 2008/05/09 13:59:31 mpf Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1557,7 +1557,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) case DIOCCLRSTATES: { struct pf_state *s, *nexts; struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; - int killed = 0; + u_int killed = 0; for (s = RB_MIN(pf_state_tree_id, &tree_id); s; s = nexts) { nexts = RB_NEXT(pf_state_tree_id, &tree_id, s); @@ -1572,7 +1572,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) killed++; } } - psk->psk_af = killed; + psk->psk_killed = killed; #if NPFSYNC pfsync_clear_states(pf_status.hostid, psk->psk_ifname); #endif @@ -1584,7 +1584,22 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) struct pf_state_key *sk; struct pf_state_host *src, *dst; struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr; - int killed = 0; + u_int killed = 0; + + if (psk->psk_pfcmp.id) { + if (psk->psk_pfcmp.creatorid == 0) + psk->psk_pfcmp.creatorid = pf_status.hostid; + if ((s = pf_find_state_byid(&psk->psk_pfcmp))) { +#if NPFSYNC > 0 + /* send immediate delete of state */ + pfsync_delete_state(s); + s->sync_flags |= PFSTATE_NOSYNC; +#endif + pf_unlink_state(s); + psk->psk_killed = 1; + } + break; + } for (s = RB_MIN(pf_state_tree_id, &tree_id); s; s = nexts) { @@ -1617,6 +1632,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) pf_match_port(psk->psk_dst.port_op, psk->psk_dst.port[0], psk->psk_dst.port[1], dst->port)) && + (!psk->psk_label[0] || (s->rule.ptr->label[0] && + !strcmp(psk->psk_label, s->rule.ptr->label))) && (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname, s->kif->pfik_name))) { #if NPFSYNC > 0 @@ -1628,7 +1645,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) killed++; } } - psk->psk_af = killed; + psk->psk_killed = killed; break; } @@ -2852,7 +2869,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) struct pf_state *s; struct pfioc_src_node_kill *psnk = \ (struct pfioc_src_node_kill *) addr; - int killed = 0; + u_int killed = 0; RB_FOREACH(sn, pf_src_tree, &tree_src_tracking) { if (PF_MATCHA(psnk->psnk_src.neg, \ @@ -2882,7 +2899,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (killed > 0) pf_purge_expired_src_nodes(1); - psnk->psnk_af = killed; + psnk->psnk_killed = killed; break; } diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 340071c3577..d9e27c57787 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.265 2008/05/09 02:44:54 markus Exp $ */ +/* $OpenBSD: pfvar.h,v 1.266 2008/05/09 13:59:31 mpf Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1351,19 +1351,21 @@ struct pfioc_state { }; struct pfioc_src_node_kill { - /* XXX returns the number of src nodes killed in psnk_af */ sa_family_t psnk_af; struct pf_rule_addr psnk_src; struct pf_rule_addr psnk_dst; + u_int psnk_killed; }; struct pfioc_state_kill { - /* XXX returns the number of states killed in psk_af */ + struct pf_state_cmp psk_pfcmp; sa_family_t psk_af; int psk_proto; struct pf_rule_addr psk_src; struct pf_rule_addr psk_dst; char psk_ifname[IFNAMSIZ]; + char psk_label[PF_RULE_LABEL_SIZE]; + u_int psk_killed; }; struct pfioc_states { |