Replace another snprintf() dance with easier to read code using
authorkrw <krw@openbsd.org>
Sat, 8 Apr 2017 18:54:52 +0000 (18:54 +0000)
committerkrw <krw@openbsd.org>
Sat, 8 Apr 2017 18:54:52 +0000 (18:54 +0000)
strlcat(). Shorter, clearer, fewer signed vs unsigned questions.

Use an 8K static buffer for pretty_print_classless() and use it
rather scribbling intermediate values into the final destination.

No intentional functional change.

sbin/dhclient/dhcpd.h
sbin/dhclient/options.c

index 6104b8a..e18593f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpd.h,v 1.167 2017/04/08 17:00:10 krw Exp $ */
+/*     $OpenBSD: dhcpd.h,v 1.168 2017/04/08 18:54:52 krw Exp $ */
 
 /*
  * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@@ -189,8 +189,7 @@ int cons_options(struct interface_info *, struct option_data *);
 char *pretty_print_option(unsigned int, struct option_data *, int);
 char *pretty_print_domain_search(unsigned char *, size_t);
 char *pretty_print_string(unsigned char *, size_t, int);
-int pretty_print_classless_routes(unsigned char *, size_t, unsigned char *,
-    size_t);
+char *pretty_print_classless_routes(unsigned char *, size_t);
 void do_packet(struct interface_info *, unsigned int, struct in_addr,
     struct ether_addr *);
 
index affb0e2..51ea475 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: options.c,v 1.85 2017/04/08 17:00:10 krw Exp $        */
+/*     $OpenBSD: options.c,v 1.86 2017/04/08 18:54:52 krw Exp $        */
 
 /* DHCP options parsing and reassembly. */
 
@@ -249,44 +249,48 @@ pretty_print_string(unsigned char *src, size_t srclen, int emit_punct)
  * Must special case *_CLASSLESS_* route options due to the variable size
  * of the CIDR element in its CIA format.
  */
-int
-pretty_print_classless_routes(unsigned char *dst, size_t dstlen,
-    unsigned char *src, size_t srclen)
+char *
+pretty_print_classless_routes(unsigned char *src, size_t srclen)
 {
-       struct in_addr mask, gateway;
-       int opcount = 0, total = 0, bits, bytes;
-       char ntoabuf[INET_ADDRSTRLEN];
+       static char string[8196];
+       char bitsbuf[5];        /* to hold "/nn " */
+       struct in_addr net, gateway;
+       int bits, bytes, rslt;
+
+       memset(string, 0, sizeof(string));
 
-       while (srclen && dstlen) {
+       while (srclen) {
                bits = *src;
                src++;
                srclen--;
+
                bytes = (bits + 7) / 8;
-               if (srclen < bytes || bytes > sizeof(mask.s_addr))
-                       break;
-               memset(&mask, 0, sizeof(mask));
-               memcpy(&mask.s_addr, src, bytes);
+               if (srclen < (bytes + sizeof(gateway.s_addr)) ||
+                   bytes > sizeof(net.s_addr))
+                       return (NULL);
+               rslt = snprintf(bitsbuf, sizeof(bitsbuf), "/%d ", bits);
+               if (rslt == -1 || rslt >= sizeof(bitsbuf))
+                       return (NULL);
+
+               memset(&net, 0, sizeof(net));
+               memcpy(&net.s_addr, src, bytes);
                src += bytes;
                srclen -= bytes;
-               strlcpy(ntoabuf, inet_ntoa(mask), sizeof(ntoabuf));
-               if (srclen < sizeof(gateway.s_addr))
-                       break;
+
                memcpy(&gateway.s_addr, src, sizeof(gateway.s_addr));
                src += sizeof(gateway.s_addr);
                srclen -= sizeof(gateway.s_addr);
-               opcount = snprintf(dst, dstlen, "%s%s/%u %s",
-                   total ? ", " : "", ntoabuf, bits,
-                   inet_ntoa(gateway));
-               if (opcount == -1)
-                       return (-1);
-               total += opcount;
-               if (opcount >= dstlen)
-                       break;
-               dst += opcount;
-               dstlen -= opcount;
+
+               if (strlen(string) > 0)
+                       strlcat(string, ", ", sizeof(string));
+               strlcat(string, inet_ntoa(net), sizeof(string));
+               strlcat(string, bitsbuf, sizeof(string));
+               rslt = strlcat(string, inet_ntoa(gateway), sizeof(string));
+               if (rslt >= sizeof(string))
+                       return (NULL);
        }
 
-       return (total);
+       return (string);
 }
 
 int
@@ -441,9 +445,10 @@ pretty_print_option(unsigned int code, struct option_data *option,
        switch (code) {
        case DHO_CLASSLESS_STATIC_ROUTES:
        case DHO_CLASSLESS_MS_STATIC_ROUTES:
-               opcount = pretty_print_classless_routes(op, opleft, dp, len);
-               if (opcount >= opleft || opcount == -1)
+               buf = pretty_print_classless_routes(dp, len);
+               if (buf == NULL)
                        goto toobig;
+               strlcat(optbuf, buf, sizeof(optbuf));
                goto done;
        default:
                break;