aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/udhcp/common.c33
-rw-r--r--networking/udhcp/common.h11
-rw-r--r--networking/udhcp/d6_dhcpc.c14
-rw-r--r--networking/udhcp/dhcpc.c5
-rw-r--r--networking/udhcp/dhcpd.c5
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 {