Index: share/man/man4/ng_ksocket.4 =================================================================== --- share/man/man4/ng_ksocket.4 +++ share/man/man4/ng_ksocket.4 @@ -185,7 +185,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 @@ -193,8 +194,12 @@ 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 possibly 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. .Pp @@ -204,6 +209,8 @@ local/"/tmp/foo.socket" .It Dv PF_INET inet/192.168.1.1:1234 +.It Dv PF_INET +inet6/[2001::1]:1234 .It Other .Dv "\&{ family=16 len=16 data=[0x70 0x00 0x01 0x23] \&}" .El Index: sys/netgraph/ng_ksocket.c =================================================================== --- sys/netgraph/ng_ksocket.c +++ sys/netgraph/ng_ksocket.c @@ -60,6 +60,9 @@ #include #include +#include +#include + #include #include #include @@ -68,6 +71,8 @@ #include #include +#include + #ifdef NG_SEPARATE_MALLOC static MALLOC_DEFINE(M_NETGRAPH_KSOCKET, "netgraph_ksock", "netgraph ksock node"); @@ -149,6 +154,19 @@ { "encap", IPPROTO_ENCAP, PF_INET }, { "divert", IPPROTO_DIVERT, 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 }, }; @@ -294,10 +312,50 @@ 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; + if (s[*off] == '[') + (*off)++; + if ((eptr = strstr(&s[*off], "%")) == NULL) { + hasifname = false; + eptr = strstr(&s[*off], "]"); + } + snprintf(addr, eptr - (s + *off), "%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(NULL, "]"); + snprintf(ifname, eptr - (s + *off), "%s", &s[*off]); + *off += (eptr - (s + *off)); + + if (ntohl(sin6->sin6_addr.s6_addr16[0]) != 0xfe80) + return (EINVAL); + scope = in6_getscope(&sin6->sin6_addr); + sin6->sin6_scope_id = + in6_getscopezone(ifunit(ifname), scope); + } + + if (s[*off] == ']') { + (*off)++; + port = strtoul(s + *off, &eptr, 10); + if (port > 0xffff || eptr == s + *off) + return (EINVAL); + sin6->sin6_port = htons(port); + } + break; + } + default: return (EINVAL); } @@ -356,9 +414,21 @@ 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)); + } + return(0); + } default: return (*ng_ksocket_generic_sockaddr_type.supertype->unparse)