dhcpc: fix the case where we might add extra space at the end of envvar.
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 20 Oct 2011 11:21:55 +0000 (13:21 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 20 Oct 2011 11:21:55 +0000 (13:21 +0200)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
networking/udhcp/common.c
networking/udhcp/dhcpc.c

index ba41905ccad33e292c8805d08fa4010a4c656359..2e6113627a0ff6883a9424b11dc845d34af2a30b 100644 (file)
@@ -36,6 +36,9 @@ const struct dhcp_optflag dhcp_optflags[] = {
        { OPTION_STRING                           , 0x11 }, /* DHCP_ROOT_PATH     */
        { OPTION_U8                               , 0x17 }, /* DHCP_IP_TTL        */
        { OPTION_U16                              , 0x1a }, /* DHCP_MTU           */
+//TODO: why do we request DHCP_BROADCAST? Can't we assume that
+//in the unlikely case it is different from typical N.N.255.255,
+//server would let us know anyway?
        { OPTION_IP                   | OPTION_REQ, 0x1c }, /* DHCP_BROADCAST     */
        { OPTION_IP_PAIR | OPTION_LIST            , 0x21 }, /* DHCP_ROUTES        */
        { OPTION_STRING                           , 0x28 }, /* DHCP_NIS_DOMAIN    */
index d9269f27757c2872973cf9ab0c1d0f824d0840a4..d67769e657463a20ecac84a820293e66f2a9ea76 100644 (file)
@@ -173,16 +173,13 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
        dest += sprintf(ret, "%s=", opt_name);
 
        while (len >= optlen) {
-               unsigned ip_ofs = 0;
-
                switch (type) {
+               case OPTION_IP:
                case OPTION_IP_PAIR:
                        dest += sprint_nip(dest, "", option);
-                       *dest++ = '/';
-                       ip_ofs = 4;
-                       /* fall through */
-               case OPTION_IP:
-                       dest += sprint_nip(dest, "", option + ip_ofs);
+                       if (type == OPTION_IP)
+                               break;
+                       dest += sprint_nip(dest, "/", option + 4);
                        break;
 //             case OPTION_BOOLEAN:
 //                     dest += sprintf(dest, *option ? "yes" : "no");
@@ -204,10 +201,14 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
                        dest += sprintf(dest, type == OPTION_U32 ? "%lu" : "%ld", (unsigned long) ntohl(val_u32));
                        break;
                }
+               /* Note: options which use 'return' instead of 'break'
+                * (for example, OPTION_STRING) skip the code which handles
+                * the case of list of options.
+                */
                case OPTION_STRING:
                        memcpy(dest, option, len);
                        dest[len] = '\0';
-                       return ret;      /* Short circuit this case */
+                       return ret;
                case OPTION_STATIC_ROUTES: {
                        /* Option binary format:
                         * mask [one byte, 0..32]
@@ -347,7 +348,7 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
 // TODO: it can be a list only if (optflag->flags & OPTION_LIST).
 // Should we bail out/warn if we see multi-ip option which is
 // not allowed to be such (for example, DHCP_BROADCAST)? -
-               if (len <= 0 /* || !(optflag->flags & OPTION_LIST) */)
+               if (len < optlen /* || !(optflag->flags & OPTION_LIST) */)
                        break;
                *dest++ = ' ';
                *dest = '\0';