Index: sbin/sysctl/sysctl.c =================================================================== RCS file: /cvs/src/sbin/sysctl/sysctl.c,v retrieving revision 1.226 diff -u -p -r1.226 sysctl.c --- sbin/sysctl/sysctl.c 25 Apr 2017 17:33:16 -0000 1.226 +++ sbin/sysctl/sysctl.c 12 Jul 2017 03:39:33 -0000 @@ -212,7 +212,7 @@ int sysctl_chipset(char *, char **, int #endif void vfsinit(void); -char *equ = "="; +const char *equ = "="; int main(int argc, char *argv[]) @@ -286,6 +286,52 @@ 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'); + if (ch >= 'A' && ch <= 'F') + return (ch - 'A'); + + 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. @@ -566,6 +612,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 +766,29 @@ parse(char *string, int flags) newval = &quadval; newsize = sizeof(quadval); break; + case CTLTYPE_STRING: + if (special & HEX) { + ssize_t len; + + len = parse_hex_string(buf, sizeof(buf), + newval); + if (len == -1) { + warnx("%s: hex string %s: invalid", + string, newval); + return; + } + if (len > sizeof(buf)) { + warnx("%s: hex string %s: too long", + string, newval); + return; + } + + newval = buf; + newsize = len; + + printf("newsize = %zu\n", newsize); + } + break; } } size = (special & SMALLBUF) ? 512 : SYSCTL_BUFSIZ; @@ -936,13 +1008,26 @@ 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", 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", buf[i]); + } else + (void)printf("%s", cp); + + (void)printf(" -> "); } + (void)puts(cp); } return; Index: sys/netinet6/in6.h =================================================================== RCS file: /cvs/src/sys/netinet6/in6.h,v retrieving revision 1.96 diff -u -p -r1.96 in6.h --- sys/netinet6/in6.h 30 May 2017 09:10:49 -0000 1.96 +++ sys/netinet6/in6.h 12 Jul 2017 03:39:33 -0000 @@ -592,7 +592,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 */ @@ -652,6 +653,7 @@ ifatoia6(struct ifaddr *ifa) { "ifq", CTLTYPE_NODE }, \ { "mrtmif", CTLTYPE_STRUCT }, \ { "mrtmfc", CTLTYPE_STRUCT }, \ + { "soiikey", CTLTYPE_STRING }, /* binary string */ \ } #define IPV6CTL_VARS { \ Index: sys/netinet6/ip6_input.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.198 diff -u -p -r1.198 ip6_input.c --- sys/netinet6/ip6_input.c 5 Jul 2017 11:34:10 -0000 1.198 +++ sys/netinet6/ip6_input.c 12 Jul 2017 03:39:34 -0000 @@ -1375,6 +1375,56 @@ ip6_sysctl_ip6stat(void *oldp, size_t *o return (ret); } +struct ip6_soiikey { + unsigned int len; + unsigned char key[32]; +}; + +struct ip6_soiikey ip6_soiikey = { .len = 0 }; + +int +ip6_sysctl_soiikey(void *oldp, size_t *oldlenp, void *newp, size_t newlen) +{ + unsigned char key[32]; + int error; + + error = suser(curproc, 0); + if (error != 0) + return (error); + + if (oldp != NULL) { + if (newp == NULL && ip6_soiikey.len == 0) + return (EOPNOTSUPP); + if (*oldlenp < ip6_soiikey.len) + return (ENOMEM); + } + if (newp != NULL) { + /* check securelevel? */ + if (newlen > sizeof(ip6_soiikey.key)) + return (EINVAL); + if (newlen > 0) { + error = copyin(newp, key, newlen); + if (error != 0) + return (error); + } + } + if (oldp != NULL) { + error = copyout(ip6_soiikey.key, oldp, *oldlenp); + if (error != 0) + return (error); + *oldlenp = ip6_soiikey.len; + } + + if (newp != NULL) { + /* commit */ + if (newlen > 0) + memcpy(ip6_soiikey.key, key, newlen); + ip6_soiikey.len = newlen; + } + + return (0); +} + int ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) @@ -1429,6 +1479,8 @@ ip6_sysctl(int *name, u_int namelen, voi 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,