summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Thomas McBride <mcbride@cvs.openbsd.org>2006-11-20 14:31:18 +0000
committerRyan Thomas McBride <mcbride@cvs.openbsd.org>2006-11-20 14:31:18 +0000
commit88bb23964ecc7e42dcff2537fd1af3c72f6cfe6e (patch)
tree0bf7396bdba5e34049b43e66790eb6b369e4bb3f
parent2a08eb329d34dbab9c8d2c46e0a242364325e19b (diff)
-K argument to kill source tracking nodes explicitly, behaves like the
-k argument for killing states; From Berk D. Demir <bdd@mindcast.org> ok dhartmei henning
-rw-r--r--sbin/pfctl/pfctl.814
-rw-r--r--sbin/pfctl/pfctl.c135
2 files changed, 141 insertions, 8 deletions
diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8
index 160530332e6..3d29b8ece0a 100644
--- a/sbin/pfctl/pfctl.8
+++ b/sbin/pfctl/pfctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pfctl.8,v 1.125 2006/11/01 09:03:00 jmc Exp $
+.\" $OpenBSD: pfctl.8,v 1.126 2006/11/20 14:31:17 mcbride Exp $
.\"
.\" Copyright (c) 2001 Kjell Wooding. All rights reserved.
.\"
@@ -40,6 +40,7 @@
.Op Fl F Ar modifier
.Op Fl f Ar file
.Op Fl i Ar interface
+.Op Fl K Ar host | network
.Op Fl k Ar host | network
.Op Fl o Op Ar level
.Op Fl p Ar device
@@ -237,6 +238,17 @@ Help.
.It Fl i Ar interface
Restrict the operation to the given
.Ar interface .
+.It Fl K Ar host | network
+Kill all of the source tracking entries originating from the specified
+.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 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
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index e9e96ead821..b9ff168aea2 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.256 2006/11/07 06:16:56 mcbride Exp $ */
+/* $OpenBSD: pfctl.c,v 1.257 2006/11/20 14:31:17 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -66,6 +66,7 @@ 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_src_nodes(int, const char *, int);
int pfctl_kill_states(int, const char *, int);
void pfctl_init_options(struct pfctl *);
int pfctl_load_options(struct pfctl *);
@@ -107,6 +108,8 @@ char *pf_device = "/dev/pf";
char *ifaceopt;
char *tableopt;
const char *tblcmdopt;
+int src_node_killers;
+char *src_node_kill[2];
int state_killers;
char *state_kill[2];
int loadopt;
@@ -227,11 +230,10 @@ 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, "[-o [level]]\n");
- fprintf(stderr, "\t[-p device] [-s modifier] ");
- fprintf(stderr, "[-t table -T command [address ...]]\n");
- fprintf(stderr, "\t[-x level]\n");
+ fprintf(stderr, "\t[-f file] [-i interface] [-K host | network] ");
+ fprintf(stderr, "[-k host | network ]\n");
+ fprintf(stderr, "\t[-o [level]] [-p device] [-s modifier ]\n");
+ fprintf(stderr, "\t[-t table -T command [address ...]] [-x level]\n");
exit(1);
}
@@ -431,6 +433,113 @@ pfctl_addrprefix(char *addr, struct pf_addr *mask)
}
int
+pfctl_kill_src_nodes(int dev, const char *iface, int opts)
+{
+ struct pfioc_src_node_kill psnk;
+ struct addrinfo *res[2], *resp[2];
+ struct sockaddr last_src, last_dst;
+ int killed, sources, dests;
+ int ret_ga;
+
+ killed = sources = dests = 0;
+
+ memset(&psnk, 0, sizeof(psnk));
+ memset(&psnk.psnk_src.addr.v.a.mask, 0xff,
+ sizeof(psnk.psnk_src.addr.v.a.mask));
+ memset(&last_src, 0xff, sizeof(last_src));
+ memset(&last_dst, 0xff, sizeof(last_dst));
+
+ pfctl_addrprefix(src_node_kill[0], &psnk.psnk_src.addr.v.a.mask);
+
+ if ((ret_ga = getaddrinfo(src_node_kill[0], NULL, NULL, &res[0]))) {
+ errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
+ /* NOTREACHED */
+ }
+ for (resp[0] = res[0]; resp[0]; resp[0] = resp[0]->ai_next) {
+ if (resp[0]->ai_addr == NULL)
+ continue;
+ /* We get lots of duplicates. Catch the easy ones */
+ if (memcmp(&last_src, resp[0]->ai_addr, sizeof(last_src)) == 0)
+ continue;
+ last_src = *(struct sockaddr *)resp[0]->ai_addr;
+
+ psnk.psnk_af = resp[0]->ai_family;
+ sources++;
+
+ if (psnk.psnk_af == AF_INET)
+ psnk.psnk_src.addr.v.a.addr.v4 =
+ ((struct sockaddr_in *)resp[0]->ai_addr)->sin_addr;
+ else if (psnk.psnk_af == AF_INET6)
+ psnk.psnk_src.addr.v.a.addr.v6 =
+ ((struct sockaddr_in6 *)resp[0]->ai_addr)->
+ sin6_addr;
+ else
+ errx(1, "Unknown address family %d", psnk.psnk_af);
+
+ if (src_node_killers > 1) {
+ dests = 0;
+ memset(&psnk.psnk_dst.addr.v.a.mask, 0xff,
+ sizeof(psnk.psnk_dst.addr.v.a.mask));
+ memset(&last_dst, 0xff, sizeof(last_dst));
+ pfctl_addrprefix(src_node_kill[1],
+ &psnk.psnk_dst.addr.v.a.mask);
+ if ((ret_ga = getaddrinfo(src_node_kill[1], NULL, NULL,
+ &res[1]))) {
+ errx(1, "getaddrinfo: %s",
+ gai_strerror(ret_ga));
+ /* NOTREACHED */
+ }
+ for (resp[1] = res[1]; resp[1];
+ resp[1] = resp[1]->ai_next) {
+ if (resp[1]->ai_addr == NULL)
+ continue;
+ if (psnk.psnk_af != resp[1]->ai_family)
+ continue;
+
+ if (memcmp(&last_dst, resp[1]->ai_addr,
+ sizeof(last_dst)) == 0)
+ continue;
+ last_dst = *(struct sockaddr *)resp[1]->ai_addr;
+
+ dests++;
+
+ if (psnk.psnk_af == AF_INET)
+ psnk.psnk_dst.addr.v.a.addr.v4 =
+ ((struct sockaddr_in *)resp[1]->
+ ai_addr)->sin_addr;
+ else if (psnk.psnk_af == AF_INET6)
+ psnk.psnk_dst.addr.v.a.addr.v6 =
+ ((struct sockaddr_in6 *)resp[1]->
+ ai_addr)->sin6_addr;
+ else
+ errx(1, "Unknown address family %d",
+ psnk.psnk_af);
+
+ if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
+ err(1, "DIOCKILLSRCNODES");
+ killed += psnk.psnk_af;
+ /* fixup psnk.psnk_af */
+ psnk.psnk_af = resp[1]->ai_family;
+ }
+ 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;
+ }
+ }
+
+ freeaddrinfo(res[0]);
+
+ if ((opts & PF_OPT_QUIET) == 0)
+ fprintf(stderr, "killed %d src nodes from %d sources and %d "
+ "destinations\n", killed, sources, dests);
+ return (0);
+}
+
+int
pfctl_kill_states(int dev, const char *iface, int opts)
{
struct pfioc_state_kill psk;
@@ -1844,7 +1953,7 @@ main(int argc, char *argv[])
usage();
while ((ch = getopt(argc, argv,
- "a:AdD:eqf:F:ghi:k:mnNOo::p:rRs:t:T:vx:z")) != -1) {
+ "a:AdD:eqf:F:ghi:k:K:mnNOo::p:rRs:t:T:vx:z")) != -1) {
switch (ch) {
case 'a':
anchoropt = optarg;
@@ -1885,6 +1994,15 @@ main(int argc, char *argv[])
state_kill[state_killers++] = optarg;
mode = O_RDWR;
break;
+ case 'K':
+ if (src_node_killers >= 2) {
+ warnx("can only specify -K twice");
+ usage();
+ /* NOTREACHED */
+ }
+ src_node_kill[src_node_killers++] = optarg;
+ mode = O_RDWR;
+ break;
case 'm':
opts |= PF_OPT_MERGE;
break;
@@ -2151,6 +2269,9 @@ main(int argc, char *argv[])
if (state_killers)
pfctl_kill_states(dev, ifaceopt, opts);
+ if (src_node_killers)
+ pfctl_kill_src_nodes(dev, ifaceopt, opts);
+
if (tblcmdopt != NULL) {
error = pfctl_command_tables(argc, argv, tableopt,
tblcmdopt, rulesopt, anchorname, opts);