udhcpc6: set -x options in request
No binary (build failed)
—
(log yok)
| @@ -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; | |
| @@ -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; | |
| @@ -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); | |
| } | |
| @@ -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); | |
| } | |
| @@ -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 { | |