[Differential] D48204: Add IPv6 support for address parsing and unparsing in ng_ksocket.

"glebius (Gleb Smirnoff)" <[email protected]>
Newsgroups gmane.os.freebsd.devel.net
Message-ID <[email protected]>
This revision was not accepted when it landed; it landed in state "Needs Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9234a50752cd: ng_ksocket: add IPv6 support for address parsing and unparsing (authored by p.mousavizadeh_protonmail.com, committed by glebius).

REPOSITORY
  rG FreeBSD src repository

CHANGES SINCE LAST UPDATE
  https://reviews.freebsd.org/D48204?vs=149039&id=149093

CHANGES SINCE LAST ACTION
  https://reviews.freebsd.org/D48204/new/

REVISION DETAIL
  https://reviews.freebsd.org/D48204

AFFECTED FILES
  share/man/man4/ng_ksocket.4
  sys/netgraph/ng_ksocket.c

EMAIL PREFERENCES
  https://reviews.freebsd.org/settings/panel/emailpreferences/

To: p.mousavizadeh_protonmail.com, #manpages, #network
Cc: imp, nc, donner, freebsd-net-list, melifaro, glebius, #src_committers, p.mousavizadeh_protonmail.com, ghislain_smartix.llc, konrad.kreciwilk_korbank.pl, cmiller_netapp.com, rajeshasp, mmacy, kpraveen.lkml_gmail.com, chris_cretaforce.gr, simonvella_gmail.com, novice_techie.com, herbert_mailbox.org, tommi.pernila_iki.fi, zec, delphij, pstef
D48204.149093.patch (text/x-patch, 4.4 KB)
diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c
--- a/sys/netgraph/ng_ksocket.c
+++ b/sys/netgraph/ng_ksocket.c
@@ -58,6 +58,9 @@
 #include <sys/uio.h>
 #include <sys/un.h>
 
+#include <net/if.h>
+#include <net/if_var.h>
+
 #include <netgraph/ng_message.h>
 #include <netgraph/netgraph.h>
 #include <netgraph/ng_parse.h>
@@ -66,6 +69,8 @@
 #include <netinet/in.h>
 #include <netinet/ip.h>
 
+#include <netinet6/scope6_var.h>
+
 #ifdef NG_SEPARATE_MALLOC
 static MALLOC_DEFINE(M_NETGRAPH_KSOCKET, "netgraph_ksock",
     "netgraph ksock node");
@@ -147,6 +152,19 @@
 	{ "swipe",	IPPROTO_SWIPE,		PF_INET		},
 	{ "encap",	IPPROTO_ENCAP,		PF_INET		},
 	{ "pim",	IPPROTO_PIM,		PF_INET		},
+	{ "ip6",	IPPROTO_IPV6,		PF_INET6	},
+	{ "raw6",	IPPROTO_RAW,		PF_INET6	},
+	{ "icmp6",	IPPROTO_ICMPV6,		PF_INET6	},
+	{ "igmp6",	IPPROTO_IGMP,		PF_INET6	},
+	{ "tcp6",	IPPROTO_TCP,		PF_INET6	},
+	{ "udp6",	IPPROTO_UDP,		PF_INET6	},
+	{ "gre6",	IPPROTO_GRE,		PF_INET6	},
+	{ "esp6",	IPPROTO_ESP,		PF_INET6	},
+	{ "ah6",	IPPROTO_AH,		PF_INET6	},
+	{ "swipe6",	IPPROTO_SWIPE,		PF_INET6	},
+	{ "encap6",	IPPROTO_ENCAP,		PF_INET6	},
+	{ "divert6",	IPPROTO_DIVERT,		PF_INET6	},
+	{ "pim6",	IPPROTO_PIM,		PF_INET6	},
 	{ NULL,		-1					},
 };
 
@@ -296,9 +314,58 @@
 		break;
 	    }
 
-#if 0
-	case PF_INET6:	/* XXX implement this someday */
-#endif
+	case PF_INET6:
+	    {
+		struct sockaddr_in6 *const sin6 = (struct sockaddr_in6 *)sa;
+		char *eptr;
+		char addr[INET6_ADDRSTRLEN];
+		char ifname[16];
+		u_long port;
+		bool hasifname = true;
+
+		/* RFC 3986 Section 3.2.2, Validate IP literal within square brackets. */
+		if (s[*off] == '[' && (strstr(&s[*off], "]")))
+			(*off)++;
+		else
+			return (EINVAL);
+		if ((eptr = strstr(&s[*off], "%")) == NULL) {
+			hasifname = false;
+			eptr = strstr(&s[*off], "]");
+		}
+		snprintf(addr, eptr - (s + *off) + 1, "%s", &s[*off]);
+		*off += (eptr - (s + *off));
+		if (!inet_pton(AF_INET6, addr, &sin6->sin6_addr))
+			return (EINVAL);
+
+		if (hasifname) {
+			uint16_t scope;
+
+			eptr = strstr(&s[*off], "]");
+			(*off)++;
+			snprintf(ifname, eptr - (s + *off) + 1, "%s", &s[*off]);
+			*off += (eptr - (s + *off));
+
+			if (sin6->sin6_addr.s6_addr16[0] != IPV6_ADDR_INT16_ULL)
+				return (EINVAL);
+			scope = in6_getscope(&sin6->sin6_addr);
+			sin6->sin6_scope_id =
+			    in6_getscopezone(ifunit(ifname), scope);
+		}
+
+		(*off)++;
+		if (s[*off] == ':') {
+			(*off)++;
+			port = strtoul(s + *off, &eptr, 10);
+			if (port > 0xffff || eptr == s + *off)
+				return (EINVAL);
+			*off += (eptr - (s + *off));
+			sin6->sin6_port = htons(port);
+		} else
+			sin6->sin6_port = 0;
+
+		sin6->sin6_len = sizeof(*sin6);
+		break;
+	    }
 
 	default:
 		return (EINVAL);
@@ -358,9 +425,24 @@
 		return(0);
 	    }
 
-#if 0
-	case PF_INET6:	/* XXX implement this someday */
-#endif
+	case PF_INET6:
+	    {
+		const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+		char addr[INET6_ADDRSTRLEN];
+
+		inet_ntop(AF_INET6, &sin6->sin6_addr, addr, INET6_ADDRSTRLEN);
+		slen += snprintf(cbuf, cbuflen, "inet6/[%s]", addr);
+
+		if (sin6->sin6_port != 0) {
+			slen += snprintf(cbuf + strlen(cbuf),
+			    cbuflen - strlen(cbuf), ":%d",
+			    (u_int)ntohs(sin6->sin6_port));
+		}
+		if (slen >= cbuflen)
+			return (ERANGE);
+		*off += sizeof(*sin6);
+		return(0);
+	    }
 
 	default:
 		return (*ng_ksocket_generic_sockaddr_type.supertype->unparse)
diff --git a/share/man/man4/ng_ksocket.4 b/share/man/man4/ng_ksocket.4
--- a/share/man/man4/ng_ksocket.4
+++ b/share/man/man4/ng_ksocket.4
@@ -32,7 +32,7 @@
 .\"
 .\" Author: Archie Cobbs <[email protected]>
 .\"
-.Dd January 9, 2012
+.Dd January 9, 2025
 .Dt NG_KSOCKET 4
 .Os
 .Sh NAME
@@ -183,7 +183,8 @@
 equivalent of the C structure
 is an acceptable form.
 For the
-.Dv PF_INET
+.Dv PF_INET ,
+.Dv PF_INET6
 and
 .Dv PF_LOCAL
 address families, a more convenient form is also used, which is
@@ -191,7 +192,11 @@
 address.
 For
 .Dv PF_INET ,
-the address is an IP address followed by an optional colon and port number.
+the address is an IPv4 address followed by an optional colon and port number.
+For
+.Dv PF_INET6 ,
+the address is an IPv6 address enclosed in square brackets followed
+by an optional colon and port number.
 For
 .Dv PF_LOCAL ,
 the address is the pathname as a doubly quoted string.
@@ -202,6 +207,8 @@
 local/"/tmp/foo.socket"
 .It Dv PF_INET
 inet/192.168.1.1:1234
+.It Dv PF_INET6
+inet6/[2001::1]:1234
 .It Other
 .Dv "\&{ family=16 len=16 data=[0x70 0x00 0x01 0x23] \&}"
 .El
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.