diff options
-rw-r--r-- | sbin/pfctl/pfctl.c | 79 |
1 files changed, 32 insertions, 47 deletions
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 0fee44796c1..2dc5b54e803 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.366 2019/01/19 11:48:54 kn Exp $ */ +/* $OpenBSD: pfctl.c,v 1.367 2019/01/28 10:25:20 kn Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -66,7 +66,8 @@ void pfctl_clear_interface_flags(int, int); void pfctl_clear_rules(int, int, char *); void pfctl_clear_src_nodes(int, int); void pfctl_clear_states(int, const char *, int); -void pfctl_addrprefix(char *, struct pf_addr *); +struct addrinfo * + pfctl_addrprefix(char *, struct pf_addr *, int); void pfctl_kill_src_nodes(int, int); void pfctl_net_kill_states(int, const char *, int, int); void pfctl_label_kill_states(int, const char *, int, int); @@ -354,35 +355,36 @@ pfctl_clear_states(int dev, const char *iface, int opts) fprintf(stderr, "%d states cleared\n", psk.psk_killed); } -void -pfctl_addrprefix(char *addr, struct pf_addr *mask) +struct addrinfo * +pfctl_addrprefix(char *addr, struct pf_addr *mask, int numeric) { 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; + hints.ai_socktype = SOCK_DGRAM; /* dummy */ + if (numeric) + hints.ai_flags = AI_NUMERICHOST; + + if ((p = strchr(addr, '/')) != NULL) { + *p++ = '\0'; + /* 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"); + if (p == NULL) + return res; + + prefix = strtonum(p, 0, res->ai_family == AF_INET6 ? 128 : 32, &errstr); + if (errstr) + errx(1, "prefix is %s: %s", errstr, p); q = prefix >> 3; r = prefix & 7; @@ -401,7 +403,8 @@ pfctl_addrprefix(char *addr, struct pf_addr *mask) (0xff00 >> r) & 0xff; break; } - freeaddrinfo(res); + + return res; } void @@ -411,7 +414,6 @@ pfctl_kill_src_nodes(int dev, int opts) struct addrinfo *res[2], *resp[2]; struct sockaddr last_src, last_dst; int killed, sources, dests; - int ret_ga; killed = sources = dests = 0; @@ -421,12 +423,9 @@ pfctl_kill_src_nodes(int dev, int opts) 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); + res[0] = pfctl_addrprefix(src_node_kill[0], + &psnk.psnk_src.addr.v.a.mask, (opts & PF_OPT_NODNS)); - 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; @@ -453,14 +452,9 @@ pfctl_kill_src_nodes(int dev, int opts) 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 */ - } + res[1] = pfctl_addrprefix(src_node_kill[1], + &psnk.psnk_dst.addr.v.a.mask, + (opts & PF_OPT_NODNS)); for (resp[1] = res[1]; resp[1]; resp[1] = resp[1]->ai_next) { if (resp[1]->ai_addr == NULL) @@ -513,7 +507,6 @@ pfctl_net_kill_states(int dev, const char *iface, int opts, int rdomain) struct addrinfo *res[2], *resp[2]; struct sockaddr last_src, last_dst; int killed, sources, dests; - int ret_ga; killed = sources = dests = 0; @@ -528,12 +521,9 @@ pfctl_net_kill_states(int dev, const char *iface, int opts, int rdomain) psk.psk_rdomain = rdomain; - pfctl_addrprefix(state_kill[0], &psk.psk_src.addr.v.a.mask); + res[0] = pfctl_addrprefix(state_kill[0], + &psk.psk_src.addr.v.a.mask, (opts & PF_OPT_NODNS)); - if ((ret_ga = getaddrinfo(state_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; @@ -560,14 +550,9 @@ pfctl_net_kill_states(int dev, const char *iface, int opts, int rdomain) 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", - gai_strerror(ret_ga)); - /* NOTREACHED */ - } + res[1] = pfctl_addrprefix(state_kill[1], + &psk.psk_dst.addr.v.a.mask, + (opts & PF_OPT_NODNS)); for (resp[1] = res[1]; resp[1]; resp[1] = resp[1]->ai_next) { if (resp[1]->ai_addr == NULL) |