Re: RFC 7217: sysctl [1/8]

2017-07-16 Thread Leighton Sheppard
This is great newsi, thanks for your efforts implementing this. It is also 
encouraging to hear this should be in 6.2 release. I'll commit to testing on my 
hardware and report any bugs.


Regards,
Leighton
On Sat, Jul 15, 2017 at 05:05:52PM +, Florian Obser wrote:
> 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, , mib, flags, );
>   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 = 
>   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 < 

RFC 7217: sysctl [1/8]

2017-07-15 Thread Florian Obser
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, , mib, flags, );
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 = 
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) {
+