From 6027597fd1a1a9293818db4729625fff375bf907 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 14 May 2018 11:06:35 +0200 Subject: [PATCH] udhcpc6: set -x options in request 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 --- networking/udhcp/common.c | 33 ++++++++++++++++++++++++++------- networking/udhcp/common.h | 11 ++++++++++- networking/udhcp/d6_dhcpc.c | 14 ++++++++++++-- networking/udhcp/dhcpc.c | 5 ++++- networking/udhcp/dhcpd.c | 5 ++++- 5 files changed, 56 insertions(+), 12 deletions(-) diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index b7c04da73..52ef875f0 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c @@ -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; diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 13059f106..5f890459c 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -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; diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 85068721a..9e3ce8b1c 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -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); } diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index bd9e8fdc2..c206a5825 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -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); } diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 19f94a2d7..ef59dca5c 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -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 {