aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/common.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-12-12 17:13:54 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-12-12 17:13:54 +0100
commite67b80f4739c4075b51b0a575701b73928fe0bf1 (patch)
tree20c9163f50db185493b7fa7d6e778742c51a3b37 /networking/udhcp/common.c
parent9b678807198611308cfd8b10427f9e08c62f7bec (diff)
downloadbusybox-w32-e67b80f4739c4075b51b0a575701b73928fe0bf1.tar.gz
busybox-w32-e67b80f4739c4075b51b0a575701b73928fe0bf1.tar.bz2
busybox-w32-e67b80f4739c4075b51b0a575701b73928fe0bf1.zip
udhcpc6: fix udhcp_find_option to actually find DHCP6 options
udhcp_insert_new_option treats code for IPv6 as follows: new->data[D6_OPT_CODE] = code >> 8; new->data[D6_OPT_CODE + 1] = code & 0xff; udhcp_find_option tests the code as follows: while (opt_list && opt_list->data[OPT_CODE] < code) ... if (opt_list && opt_list->data[OPT_CODE] == code) So yes, OPT_CODE and D6_OPT_CODE are both 0, but the D6_OPT_CLIENTID = 1 value means that the 1 is in the seconds byte, and udhcp_find_option is only looking at the first byte, So the send_d6_release can never find it the created option. function old new delta udhcp_find_option 28 53 +25 attach_option 276 284 +8 udhcpc6_main 2602 2607 +5 perform_d6_release 262 267 +5 udhcpd_main 1518 1520 +2 udhcpc_main 2542 2544 +2 add_serverid_and_clientid_options 46 48 +2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 7/0 up/down: 49/0) Total: 49 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/udhcp/common.c')
-rw-r--r--networking/udhcp/common.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index 31e525cb0..8e9b93655 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -404,14 +404,29 @@ void FAST_FUNC udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code,
404#endif 404#endif
405 405
406/* Find option 'code' in opt_list */ 406/* Find option 'code' in opt_list */
407struct option_set* FAST_FUNC udhcp_find_option(struct option_set *opt_list, uint8_t code) 407struct option_set* FAST_FUNC udhcp_find_option(struct option_set *opt_list, uint8_t code, bool dhcpv6)
408{ 408{
409 while (opt_list && opt_list->data[OPT_CODE] < code) 409 IF_NOT_UDHCPC6(bool dhcpv6 = 0;)
410 opt_list = opt_list->next; 410 uint8_t cur_code;
411 411
412 if (opt_list && opt_list->data[OPT_CODE] == code) 412 for (;;) {
413 return opt_list; 413 if (!opt_list)
414 return NULL; 414 return opt_list; /* NULL */
415 if (!dhcpv6) {
416 cur_code = opt_list->data[OPT_CODE];
417 } else {
418//FIXME: add support for code > 0xff
419 if (opt_list->data[D6_OPT_CODE] != 0)
420 return NULL;
421 cur_code = opt_list->data[D6_OPT_CODE + 1];
422 }
423 if (cur_code >= code) {
424 if (cur_code == code)
425 return opt_list;
426 return NULL;
427 }
428 opt_list = opt_list->next;
429 }
415} 430}
416 431
417/* Parse string to IP in network order */ 432/* Parse string to IP in network order */
@@ -499,7 +514,7 @@ static NOINLINE void attach_option(
499 } 514 }
500#endif 515#endif
501 516
502 existing = udhcp_find_option(*opt_list, optflag->code); 517 existing = udhcp_find_option(*opt_list, optflag->code, dhcpv6);
503 if (!existing) { 518 if (!existing) {
504 /* make a new option */ 519 /* make a new option */
505 uint8_t *p = udhcp_insert_new_option(opt_list, optflag->code, length, dhcpv6); 520 uint8_t *p = udhcp_insert_new_option(opt_list, optflag->code, length, dhcpv6);