git: cbca60158062 - main - pfctl: Merge host_v{4,6}() into simpler host_ip()

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Thu, 03 Jul 2025 12:01:07 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=cbca601580626662f03933a617e88c5ff2fc329f

commit cbca601580626662f03933a617e88c5ff2fc329f
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-06-27 14:57:57 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-07-03 07:16:13 +0000

    pfctl: Merge host_v{4,6}() into simpler host_ip()
    
    Except for networks such as "10/8" host_ip() now handles addresses in an
    AF-agnostic way with more duplicate code removed/merged.
    
    OK sashan (as for earlier copy_satopfaddr() diff) henning
    
    Obtained from:  OpenBSD, kn <kn@openbsd.org>, 1b6fdc2f24
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sbin/pfctl/pfctl_parser.c | 71 ++++++++++++++++++-----------------------------
 1 file changed, 27 insertions(+), 44 deletions(-)

diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 244531ead280..8eb9bd1d6f5a 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -76,8 +76,7 @@ void		 print_fromto(struct pf_rule_addr *, pf_osfp_t,
 int		 ifa_skip_if(const char *filter, struct node_host *p);
 
 struct node_host	*host_if(const char *, int);
-struct node_host	*host_v4(const char *, int);
-struct node_host	*host_v6(const char *, int);
+struct node_host	*host_ip(const char *, int);
 struct node_host	*host_dns(const char *, int, int);
 
 const char * const tcpflags = "FSRPAUEWe";
@@ -1805,8 +1804,7 @@ host(const char *s, int opts)
 			err(1, "host: strdup");
 	}
 
-	if ((h = host_v4(s, mask)) == NULL &&
-	    (h = host_v6(ps, mask)) == NULL &&
+	if ((h = host_ip(ps, mask)) == NULL &&
 	    (h = host_if(ps, mask)) == NULL &&
 	    (h = host_dns(ps, mask, (opts & PF_OPT_NODNS))) == NULL) {
 		fprintf(stderr, "no IP address found for %s\n", s);
@@ -1863,57 +1861,42 @@ error:
 }
 
 struct node_host *
-host_v4(const char *s, int mask)
-{
-	struct node_host	*h = NULL;
-	struct in_addr		 ina;
-
-	memset(&ina, 0, sizeof(ina));
-	if (mask > -1) {
-		if (inet_net_pton(AF_INET, s, &ina, sizeof(ina)) == -1)
-			return (NULL);
-	} else {
-		if (inet_pton(AF_INET, s, &ina) != 1)
-			return (NULL);
-	}
-
-	h = calloc(1, sizeof(struct node_host));
-	if (h == NULL)
-		err(1, "address: calloc");
-	h->ifname = NULL;
-	h->af = AF_INET;
-	h->addr.v.a.addr.addr32[0] = ina.s_addr;
-	set_ipmask(h, mask);
-	h->next = NULL;
-	h->tail = h;
-
-	return (h);
-}
-
-struct node_host *
-host_v6(const char *s, int mask)
+host_ip(const char *s, int mask)
 {
 	struct addrinfo		 hints, *res;
 	struct node_host	*h = NULL;
 
 	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET6;
+	hints.ai_family = AF_UNSPEC;
 	hints.ai_socktype = SOCK_DGRAM; /*dummy*/
 	hints.ai_flags = AI_NUMERICHOST;
-	if (getaddrinfo(s, "0", &hints, &res) == 0) {
-		h = calloc(1, sizeof(struct node_host));
+	if (getaddrinfo(s, NULL, &hints, &res) == 0) {
+		h = calloc(1, sizeof(*h));
 		if (h == NULL)
-			err(1, "address: calloc");
-		h->ifname = NULL;
-		h->af = AF_INET6;
+			err(1, "%s: calloc", __func__);
+		h->af = res->ai_family;
 		copy_satopfaddr(&h->addr.v.a.addr, res->ai_addr);
-		h->ifindex =
-		    ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
-		set_ipmask(h, mask);
+		if (h->af == AF_INET6)
+			h->ifindex =
+			    ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
 		freeaddrinfo(res);
-		h->next = NULL;
-		h->tail = h;
+	} else { /* ie. for 10/8 parsing */
+		if (mask == -1)
+			return (NULL);
+		h = calloc(1, sizeof(*h));
+		if (h == NULL)
+			err(1, "%s: calloc", __func__);
+		h->af = AF_INET;
+		if (inet_net_pton(AF_INET, s, &h->addr.v.a.addr.v4,
+			sizeof(h->addr.v.a.addr.v4)) == -1) {
+			free(h);
+			return (NULL);
+		}
 	}
+	set_ipmask(h, mask);
+	h->ifname = NULL;
+	h->next = NULL;
+	h->tail = h;
 
 	return (h);
 }