udhcpc6: set -x options in request
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 14 May 2018 09:06:35 +0000 (11:06 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 14 May 2018 09:11:08 +0000 (11:11 +0200)
Last foru commits:

function                                             old     new   delta
option_to_env                                        621     791    +170
.rodata                                           168351  168505    +154
attach_option                                        431     506     +75
add_d6_client_options                                112     167     +55
d6_option_strings                                     30      84     +54
udhcp_str2optset                                     644     660     +16
d6_optflags                                           12      20      +8
udhcpc6_main                                        2590    2596      +6
udhcpc_main                                         2648    2651      +3
read_optset                                           15      18      +3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 10/0 up/down: 544/0)            Total: 544 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
networking/udhcp/common.c
networking/udhcp/common.h
networking/udhcp/d6_dhcpc.c
networking/udhcp/dhcpc.c
networking/udhcp/dhcpd.c

index b7c04da738dc703aa91c4870be3e932cf07ee6f5..52ef875f0e195c5997bb89e56f9662b49bd13951 100644 (file)
@@ -379,12 +379,18 @@ int FAST_FUNC udhcp_str2nip(const char *str, void *arg)
  * and to parse udhcpd.conf's "opt OPTNAME OPTVAL" directives.
  */
 /* helper: add an option to the opt_list */
+#if !ENABLE_UDHCPC6
+#define attach_option(opt_list, optflag, buffer, length, dhcpv6) \
+       attach_option(opt_list, optflag, buffer, length)
+#endif
 static NOINLINE void attach_option(
                struct option_set **opt_list,
                const struct dhcp_optflag *optflag,
                char *buffer,
-               int length)
+               int length,
+               bool dhcpv6)
 {
+       IF_NOT_UDHCPC6(bool dhcpv6 = 0;)
        struct option_set *existing;
        char *allocated = NULL;
 
@@ -410,10 +416,21 @@ static NOINLINE void attach_option(
                /* make a new option */
                log2("attaching option %02x to list", optflag->code);
                new = xmalloc(sizeof(*new));
-               new->data = xmalloc(length + OPT_DATA);
-               new->data[OPT_CODE] = optflag->code;
-               new->data[OPT_LEN] = length;
-               memcpy(new->data + OPT_DATA, (allocated ? allocated : buffer), length);
+               if (!dhcpv6) {
+                       new->data = xmalloc(length + OPT_DATA);
+                       new->data[OPT_CODE] = optflag->code;
+                       new->data[OPT_LEN] = length;
+                       memcpy(new->data + OPT_DATA, (allocated ? allocated : buffer),
+                                       length);
+               } else {
+                       new->data = xmalloc(length + D6_OPT_DATA);
+                       new->data[D6_OPT_CODE] = optflag->code >> 8;
+                       new->data[D6_OPT_CODE + 1] = optflag->code & 0xff;
+                       new->data[D6_OPT_LEN] = length >> 8;
+                       new->data[D6_OPT_LEN + 1] = length & 0xff;
+                       memcpy(new->data + D6_OPT_DATA, (allocated ? allocated : buffer),
+                                       length);
+               }
 
                curr = opt_list;
                while (*curr && (*curr)->data[OPT_CODE] < optflag->code)
@@ -450,7 +467,9 @@ static NOINLINE void attach_option(
        free(allocated);
 }
 
-int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg, const struct dhcp_optflag *optflags, const char *option_strings)
+int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg,
+               const struct dhcp_optflag *optflags, const char *option_strings,
+               bool dhcpv6)
 {
        struct option_set **opt_list = arg;
        char *opt;
@@ -602,7 +621,7 @@ case_OPTION_STRING:
                }
 
                if (retval)
-                       attach_option(opt_list, optflag, opt, length);
+                       attach_option(opt_list, optflag, opt, length, dhcpv6);
        } while (retval && (optflag->flags & OPTION_LIST));
 
        return retval;
index 13059f10637c8367786cfb15111e1404e9c4c33b..5f890459cf8448546e1ff579240a89f1ad278e94 100644 (file)
@@ -164,6 +164,10 @@ enum {
 #define OPT_CODE                0
 #define OPT_LEN                 1
 #define OPT_DATA                2
+/* Offsets in option byte sequence for DHCPv6 */
+#define D6_OPT_CODE                            0
+#define D6_OPT_LEN                             2
+#define D6_OPT_DATA                            4
 /* Bits in "overload" option */
 #define OPTION_FIELD            0
 #define FILE_FIELD              1
@@ -290,10 +294,15 @@ void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC;
 /* 2nd param is "uint32_t*" */
 int FAST_FUNC udhcp_str2nip(const char *str, void *arg);
 /* 2nd param is "struct option_set**" */
+#if !ENABLE_UDHCPC6
+#define udhcp_str2optset(str, arg, optflags, option_strings, dhcpv6) \
+       udhcp_str2optset(str, arg, optflags, option_strings)
+#endif
 int FAST_FUNC udhcp_str2optset(const char *str,
                void *arg,
                const struct dhcp_optflag *optflags,
-               const char *option_strings);
+               const char *option_strings,
+               bool dhcpv6);
 
 #if ENABLE_UDHCPC || ENABLE_UDHCPD
 void udhcp_init_header(struct dhcp_packet *packet, char type) FAST_FUNC;
index 85068721a6c6768a14592369249465b04ba230db..9e3ce8b1ce2c14e4f8f841210ce29720694b3955 100644 (file)
@@ -484,8 +484,10 @@ static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid
 
 static uint8_t *add_d6_client_options(uint8_t *ptr)
 {
+       struct option_set *curr;
        uint8_t *start = ptr;
        unsigned option;
+       uint16_t len;
 
        ptr += 4;
        for (option = 1; option < 256; option++) {
@@ -508,7 +510,12 @@ static uint8_t *add_d6_client_options(uint8_t *ptr)
        ptr = mempcpy(ptr, &opt_fqdn_req, sizeof(opt_fqdn_req));
 #endif
        /* Add -x options if any */
-       //...
+       curr = client_config.options;
+       while (curr) {
+               len = (curr->data[D6_OPT_LEN] << 8) | curr->data[D6_OPT_LEN + 1];
+               ptr = mempcpy(ptr, curr->data, D6_OPT_DATA + len);
+               curr = curr->next;
+       }
 
        return ptr;
 }
@@ -1215,7 +1222,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
        }
        while (list_x) {
                char *optstr = xstrdup(llist_pop(&list_x));
-               udhcp_str2optset(optstr, &client_config.options, d6_optflags, d6_option_strings);
+               udhcp_str2optset(optstr, &client_config.options,
+                               d6_optflags, d6_option_strings,
+                               /*dhcpv6:*/ 1
+               );
                free(optstr);
        }
 
index bd9e8fdc2d4edd7fd04df3556348121ea9ea6e54..c206a58259279f1efb97477c677323b32e4ec45a 100644 (file)
@@ -1337,7 +1337,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
        }
        while (list_x) {
                char *optstr = xstrdup(llist_pop(&list_x));
-               udhcp_str2optset(optstr, &client_config.options, dhcp_optflags, dhcp_option_strings);
+               udhcp_str2optset(optstr, &client_config.options,
+                               dhcp_optflags, dhcp_option_strings,
+                               /*dhcpv6:*/ 0
+               );
                free(optstr);
        }
 
index 19f94a2d7e716202b1870d051e6818537863641f..ef59dca5c1a181b193a6d70d16a64ea2c643e6e1 100644 (file)
@@ -362,7 +362,10 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg)
 }
 
 static int FAST_FUNC read_optset(const char *line, void *arg) {
-       return udhcp_str2optset(line, arg, dhcp_optflags, dhcp_option_strings);
+       return udhcp_str2optset(line, arg,
+                       dhcp_optflags, dhcp_option_strings,
+                       /*dhcpv6:*/ 0
+       );
 }
 
 struct config_keyword {