I didn't not hear any objections to RFC 7217 support, so I guess it's time to get this thing in to get some operational experience with it before 6.2 is cut. Also the big diff gets a bit unwieldy, further improvement can happen in-tree.
This is the sysctl part for "net.inet6.ip6.soiikey", written by dlg with a few tweaks by me. Therefore he should commit it. This is OK florian@, anyone else? diff --git sbin/sysctl/sysctl.c sbin/sysctl/sysctl.c index 94f78c0d673..cbacaca19d2 100644 --- sbin/sysctl/sysctl.c +++ sbin/sysctl/sysctl.c @@ -212,7 +212,7 @@ int sysctl_chipset(char *, char **, int *, int, int *); #endif void vfsinit(void); -char *equ = "="; +const char *equ = "="; int main(int argc, char *argv[]) @@ -286,6 +286,53 @@ listall(char *prefix, struct list *lp) } } +int +parse_hex_char(char ch) +{ + if (ch >= '0' && ch <= '9') + return (ch - '0'); + if (ch >= 'a' && ch <= 'f') + return (ch - 'a' + 10); + if (ch >= 'A' && ch <= 'F') + return (ch - 'A' + 10); + + return (-1); +} + +ssize_t +parse_hex_string(unsigned char *dst, size_t dstlen, const char *src) +{ + ssize_t len = 0; + int digit; + + while (len < dstlen) { + if (*src == '\0') + return (len); + + digit = parse_hex_char(*src++); + if (digit == -1) + return (-1); + dst[len] = digit << 4; + + digit = parse_hex_char(*src++); + if (digit == -1) + return (-1); + + dst[len] |= digit; + len++; + } + + while (*src != '\0') { + if (parse_hex_char(*src++) == -1 || + parse_hex_char(*src++) == -1) + return (-1); + + len++; + } + + return (len); +} + /* * Parse a name into a MIB entry. * Lookup and print out the MIB entry if it exists. @@ -302,6 +349,7 @@ parse(char *string, int flags) struct list *lp; int mib[CTL_MAXNAME]; char *cp, *bufp, buf[SYSCTL_BUFSIZ]; + unsigned char hex[SYSCTL_BUFSIZ]; (void)strlcpy(buf, string, sizeof(buf)); bufp = buf; @@ -566,6 +614,9 @@ parse(char *string, int flags) len = sysctl_inet6(string, &bufp, mib, flags, &type); if (len < 0) return; + if (mib[2] == IPPROTO_IPV6 && + mib[3] == IPV6CTL_SOIIKEY) + special |= HEX; if ((mib[2] == IPPROTO_IPV6 && mib[3] == IPV6CTL_MRTMFC) || (mib[2] == IPPROTO_IPV6 && mib[3] == IPV6CTL_MRTMIF) || @@ -717,6 +768,27 @@ parse(char *string, int flags) newval = &quadval; newsize = sizeof(quadval); break; + case CTLTYPE_STRING: + if (special & HEX) { + ssize_t len; + + len = parse_hex_string(hex, sizeof(hex), + newval); + if (len == -1) { + warnx("%s: hex string %s: invalid", + string, newval); + return; + } + if (len > sizeof(hex)) { + warnx("%s: hex string %s: too long", + string, newval); + return; + } + + newval = hex; + newsize = len; + } + break; } } size = (special & SMALLBUF) ? 512 : SYSCTL_BUFSIZ; @@ -936,13 +1008,30 @@ parse(char *string, int flags) if (newval == NULL) { if (!nflag) (void)printf("%s%s", string, equ); - (void)puts(buf); - } else { - if (!qflag) { - if (!nflag) - (void)printf("%s: %s -> ", string, buf); - (void)puts((char *)newval); + if (special & HEX) { + size_t i; + for (i = 0; i < size; i++) { + (void)printf("%02x", + (unsigned char)buf[i]); + } + (void)printf("\n"); + } else + (void)puts(buf); + } else if (!qflag) { + if (!nflag) { + (void)printf("%s: ", string); + if (special & HEX) { + size_t i; + for (i = 0; i < size; i++) { + (void)printf("%02x", + (unsigned char)buf[i]); + } + } else + (void)printf("%s", cp); + + (void)printf(" -> "); } + (void)puts(cp); } return; diff --git sys/netinet6/in6.h sys/netinet6/in6.h index ac0120e4217..549cf0c5159 100644 --- sys/netinet6/in6.h +++ sys/netinet6/in6.h @@ -590,7 +590,8 @@ ifatoia6(struct ifaddr *ifa) #define IPV6CTL_IFQUEUE 51 #define IPV6CTL_MRTMIF 52 #define IPV6CTL_MRTMFC 53 -#define IPV6CTL_MAXID 54 +#define IPV6CTL_SOIIKEY 54 +#define IPV6CTL_MAXID 55 /* New entries should be added here from current IPV6CTL_MAXID value. */ /* to define items, should talk with KAME guys first, for *BSD compatibility */ @@ -650,6 +651,7 @@ ifatoia6(struct ifaddr *ifa) { "ifq", CTLTYPE_NODE }, \ { "mrtmif", CTLTYPE_STRUCT }, \ { "mrtmfc", CTLTYPE_STRUCT }, \ + { "soiikey", CTLTYPE_STRING }, /* binary string */ \ } #define IPV6CTL_VARS { \ diff --git sys/netinet6/ip6_input.c sys/netinet6/ip6_input.c index ed8702fa71a..4aaf8cee6d6 100644 --- sys/netinet6/ip6_input.c +++ sys/netinet6/ip6_input.c @@ -118,6 +118,8 @@ struct niqueue ip6intrq = NIQUEUE_INITIALIZER(IFQ_MAXLEN, NETISR_IPV6); struct cpumem *ip6counters; +uint8_t ip6_soiikey[IP6_SOIIKEY_LEN]; + int ip6_ours(struct mbuf **, int *, int, int); int ip6_local(struct mbuf **, int *, int, int); int ip6_check_rh0hdr(struct mbuf *, int *); @@ -1376,6 +1378,21 @@ ip6_sysctl_ip6stat(void *oldp, size_t *oldlenp, void *newp) } int +ip6_sysctl_soiikey(void *oldp, size_t *oldlenp, void *newp, size_t newlen) +{ + int error; + + error = suser(curproc, 0); + if (error != 0) + return (error); + + error = sysctl_struct(oldp, oldlenp, newp, newlen, ip6_soiikey, + sizeof(ip6_soiikey)); + + return (error); +} + +int ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { @@ -1429,6 +1446,8 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, case IPV6CTL_IFQUEUE: return (sysctl_niq(name + 1, namelen - 1, oldp, oldlenp, newp, newlen, &ip6intrq)); + case IPV6CTL_SOIIKEY: + return (ip6_sysctl_soiikey(oldp, oldlenp, newp, newlen)); default: if (name[0] < IPV6CTL_MAXID) return (sysctl_int_arr(ipv6ctl_vars, name, namelen, diff --git sys/netinet6/ip6_var.h sys/netinet6/ip6_var.h index 2b9f86cab2f..f1ae3680b81 100644 --- sys/netinet6/ip6_var.h +++ sys/netinet6/ip6_var.h @@ -294,6 +294,9 @@ extern int ip6_dad_pending; /* number of currently running DADs */ extern int ip6_auto_flowlabel; extern int ip6_auto_linklocal; +#define IP6_SOIIKEY_LEN 16 +extern uint8_t ip6_soiikey[IP6_SOIIKEY_LEN]; + struct in6pcb; struct inpcb; -- 2.13.0 -- I'm not entirely sure you are real.