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 <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-05-14 11:06:35 +02:00
parent 30f4d52ed1
commit 6027597fd1
5 changed files with 56 additions and 12 deletions

View 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;

View 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;

View 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);
}

View 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);
}

View 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 {