aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/udhcp/common.c63
-rw-r--r--networking/udhcp/common.h11
-rw-r--r--networking/udhcp/d6_dhcpc.c58
-rw-r--r--networking/udhcp/dhcpc.c56
-rw-r--r--networking/udhcp/dhcpc.h4
5 files changed, 115 insertions, 77 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index f2d6907ad..684d76b2b 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -420,6 +420,43 @@ int FAST_FUNC udhcp_str2nip(const char *str, void *arg)
420 return 1; 420 return 1;
421} 421}
422 422
423void* FAST_FUNC udhcp_insert_new_option(
424 struct option_set **opt_list,
425 unsigned code,
426 const void *buffer,
427 unsigned length,
428 bool dhcpv6)
429{
430 IF_NOT_UDHCPC6(bool dhcpv6 = 0;)
431 struct option_set *new, **curr;
432
433 log2("attaching option %02x to list", code);
434 new = xmalloc(sizeof(*new));
435 if (!dhcpv6) {
436 new->data = xmalloc(length + OPT_DATA);
437 new->data[OPT_CODE] = code;
438 new->data[OPT_LEN] = length;
439 memcpy(new->data + OPT_DATA, buffer, length);
440 } else {
441 new->data = xmalloc(length + D6_OPT_DATA);
442 new->data[D6_OPT_CODE] = code >> 8;
443 new->data[D6_OPT_CODE + 1] = code & 0xff;
444 new->data[D6_OPT_LEN] = length >> 8;
445 new->data[D6_OPT_LEN + 1] = length & 0xff;
446 memcpy(new->data + D6_OPT_DATA, buffer, length);
447 }
448
449 curr = opt_list;
450//FIXME: DHCP6 codes > 255!!
451 while (*curr && (*curr)->data[OPT_CODE] < code)
452 curr = &(*curr)->next;
453
454 new->next = *curr;
455 *curr = new;
456
457 return new->data;
458}
459
423/* udhcp_str2optset: 460/* udhcp_str2optset:
424 * Parse string option representation to binary form and add it to opt_list. 461 * Parse string option representation to binary form and add it to opt_list.
425 * Called to parse "udhcpc -x OPTNAME:OPTVAL" 462 * Called to parse "udhcpc -x OPTNAME:OPTVAL"
@@ -459,32 +496,8 @@ static NOINLINE void attach_option(
459 496
460 existing = udhcp_find_option(*opt_list, optflag->code); 497 existing = udhcp_find_option(*opt_list, optflag->code);
461 if (!existing) { 498 if (!existing) {
462 struct option_set *new, **curr;
463
464 /* make a new option */ 499 /* make a new option */
465 log2("attaching option %02x to list", optflag->code); 500 udhcp_insert_new_option(opt_list, optflag->code, buffer, length, dhcpv6);
466 new = xmalloc(sizeof(*new));
467 if (!dhcpv6) {
468 new->data = xmalloc(length + OPT_DATA);
469 new->data[OPT_CODE] = optflag->code;
470 new->data[OPT_LEN] = length;
471 memcpy(new->data + OPT_DATA, buffer, length);
472 } else {
473 new->data = xmalloc(length + D6_OPT_DATA);
474 new->data[D6_OPT_CODE] = optflag->code >> 8;
475 new->data[D6_OPT_CODE + 1] = optflag->code & 0xff;
476 new->data[D6_OPT_LEN] = length >> 8;
477 new->data[D6_OPT_LEN + 1] = length & 0xff;
478 memcpy(new->data + D6_OPT_DATA, buffer,
479 length);
480 }
481
482 curr = opt_list;
483 while (*curr && (*curr)->data[OPT_CODE] < optflag->code)
484 curr = &(*curr)->next;
485
486 new->next = *curr;
487 *curr = new;
488 goto ret; 501 goto ret;
489 } 502 }
490 503
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index cc0abd269..e5af62874 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -319,6 +319,17 @@ void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC;
319 319
320/* 2nd param is "uint32_t*" */ 320/* 2nd param is "uint32_t*" */
321int FAST_FUNC udhcp_str2nip(const char *str, void *arg); 321int FAST_FUNC udhcp_str2nip(const char *str, void *arg);
322
323#if !ENABLE_UDHCPC6
324#define udhcp_insert_new_option(opt_list, code, buffer, length, dhcpv6) \
325 udhcp_insert_new_option(opt_list, code, buffer, length)
326#endif
327void* FAST_FUNC udhcp_insert_new_option(struct option_set **opt_list,
328 unsigned code,
329 const void *buffer,
330 unsigned length,
331 bool dhcpv6);
332
322/* 2nd param is "struct option_set**" */ 333/* 2nd param is "struct option_set**" */
323#if !ENABLE_UDHCPC6 334#if !ENABLE_UDHCPC6
324#define udhcp_str2optset(str, arg, optflags, option_strings, dhcpv6) \ 335#define udhcp_str2optset(str, arg, optflags, option_strings, dhcpv6) \
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index 5bca4a824..c4bedb259 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -482,7 +482,6 @@ static ALWAYS_INLINE uint32_t random_xid(void)
482static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid) 482static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid)
483{ 483{
484 uint8_t *ptr; 484 uint8_t *ptr;
485 struct d6_option *clientid;
486 unsigned secs; 485 unsigned secs;
487 486
488 memset(packet, 0, sizeof(*packet)); 487 memset(packet, 0, sizeof(*packet));
@@ -503,9 +502,7 @@ static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid
503 *((uint16_t*)ptr) = (secs < 0xffff) ? htons(secs) : 0xffff; 502 *((uint16_t*)ptr) = (secs < 0xffff) ? htons(secs) : 0xffff;
504 ptr += 2; 503 ptr += 2;
505 504
506 /* add CLIENTID option */ 505 return ptr;
507 clientid = (void*)client_data.clientid;
508 return mempcpy(ptr, clientid, clientid->len + 2+2);
509} 506}
510 507
511static uint8_t *add_d6_client_options(uint8_t *ptr) 508static uint8_t *add_d6_client_options(uint8_t *ptr)
@@ -593,10 +590,10 @@ static NOINLINE int send_d6_info_request(uint32_t xid)
593 struct d6_packet packet; 590 struct d6_packet packet;
594 uint8_t *opt_ptr; 591 uint8_t *opt_ptr;
595 592
596 /* Fill in: msg type, client id */ 593 /* Fill in: msg type */
597 opt_ptr = init_d6_packet(&packet, D6_MSG_INFORMATION_REQUEST, xid); 594 opt_ptr = init_d6_packet(&packet, D6_MSG_INFORMATION_REQUEST, xid);
598 595
599 /* Add options: 596 /* Add options: client-id,
600 * "param req" option according to -O, options specified with -x 597 * "param req" option according to -O, options specified with -x
601 */ 598 */
602 opt_ptr = add_d6_client_options(opt_ptr); 599 opt_ptr = add_d6_client_options(opt_ptr);
@@ -693,7 +690,7 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip
693 uint8_t *opt_ptr; 690 uint8_t *opt_ptr;
694 unsigned len; 691 unsigned len;
695 692
696 /* Fill in: msg type, client id */ 693 /* Fill in: msg type */
697 opt_ptr = init_d6_packet(&packet, D6_MSG_SOLICIT, xid); 694 opt_ptr = init_d6_packet(&packet, D6_MSG_SOLICIT, xid);
698 695
699 /* Create new IA_NA, optionally with included IAADDR with requested IP */ 696 /* Create new IA_NA, optionally with included IAADDR with requested IP */
@@ -726,7 +723,7 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip
726 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, len); 723 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, len);
727 } 724 }
728 725
729 /* Add options: 726 /* Add options: client-id,
730 * "param req" option according to -O, options specified with -x 727 * "param req" option according to -O, options specified with -x
731 */ 728 */
732 opt_ptr = add_d6_client_options(opt_ptr); 729 opt_ptr = add_d6_client_options(opt_ptr);
@@ -771,7 +768,7 @@ static NOINLINE int send_d6_select(uint32_t xid)
771 struct d6_packet packet; 768 struct d6_packet packet;
772 uint8_t *opt_ptr; 769 uint8_t *opt_ptr;
773 770
774 /* Fill in: msg type, client id */ 771 /* Fill in: msg type */
775 opt_ptr = init_d6_packet(&packet, D6_MSG_REQUEST, xid); 772 opt_ptr = init_d6_packet(&packet, D6_MSG_REQUEST, xid);
776 773
777 /* server id */ 774 /* server id */
@@ -783,7 +780,7 @@ static NOINLINE int send_d6_select(uint32_t xid)
783 if (client6_data.ia_pd) 780 if (client6_data.ia_pd)
784 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2); 781 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2);
785 782
786 /* Add options: 783 /* Add options: client-id,
787 * "param req" option according to -O, options specified with -x 784 * "param req" option according to -O, options specified with -x
788 */ 785 */
789 opt_ptr = add_d6_client_options(opt_ptr); 786 opt_ptr = add_d6_client_options(opt_ptr);
@@ -844,7 +841,7 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st
844 struct d6_packet packet; 841 struct d6_packet packet;
845 uint8_t *opt_ptr; 842 uint8_t *opt_ptr;
846 843
847 /* Fill in: msg type, client id */ 844 /* Fill in: msg type */
848 opt_ptr = init_d6_packet(&packet, DHCPREQUEST, xid); 845 opt_ptr = init_d6_packet(&packet, DHCPREQUEST, xid);
849 846
850 /* server id */ 847 /* server id */
@@ -856,7 +853,7 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st
856 if (client6_data.ia_pd) 853 if (client6_data.ia_pd)
857 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2); 854 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2);
858 855
859 /* Add options: 856 /* Add options: client-id,
860 * "param req" option according to -O, options specified with -x 857 * "param req" option according to -O, options specified with -x
861 */ 858 */
862 opt_ptr = add_d6_client_options(opt_ptr); 859 opt_ptr = add_d6_client_options(opt_ptr);
@@ -878,6 +875,7 @@ int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6)
878{ 875{
879 struct d6_packet packet; 876 struct d6_packet packet;
880 uint8_t *opt_ptr; 877 uint8_t *opt_ptr;
878 struct option_set *ci;
881 879
882 /* Fill in: msg type, client id */ 880 /* Fill in: msg type, client id */
883 opt_ptr = init_d6_packet(&packet, D6_MSG_RELEASE, random_xid()); 881 opt_ptr = init_d6_packet(&packet, D6_MSG_RELEASE, random_xid());
@@ -889,6 +887,10 @@ int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6)
889 /* IA PD */ 887 /* IA PD */
890 if (client6_data.ia_pd) 888 if (client6_data.ia_pd)
891 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2); 889 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2);
890 /* Client-id */
891 ci = udhcp_find_option(client_data.options, D6_OPT_CLIENTID);
892 if (ci)
893 opt_ptr = mempcpy(opt_ptr, ci->data, D6_OPT_DATA + 2+2 + 6);
892 894
893 bb_info_msg("sending %s", "release"); 895 bb_info_msg("sending %s", "release");
894 return d6_send_kernel_packet_from_client_data_ifindex( 896 return d6_send_kernel_packet_from_client_data_ifindex(
@@ -1184,7 +1186,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1184{ 1186{
1185 const char *str_r; 1187 const char *str_r;
1186 IF_FEATURE_UDHCP_PORT(char *str_P;) 1188 IF_FEATURE_UDHCP_PORT(char *str_P;)
1187 void *clientid_mac_ptr; 1189 uint8_t *clientid_mac_ptr;
1188 llist_t *list_O = NULL; 1190 llist_t *list_O = NULL;
1189 llist_t *list_x = NULL; 1191 llist_t *list_x = NULL;
1190 int tryagain_timeout = 20; 1192 int tryagain_timeout = 20;
@@ -1284,22 +1286,19 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1284 if (d6_read_interface(client_data.interface, 1286 if (d6_read_interface(client_data.interface,
1285 &client_data.ifindex, 1287 &client_data.ifindex,
1286 &client6_data.ll_ip6, 1288 &client6_data.ll_ip6,
1287 client_data.client_mac) 1289 client_data_client_mac)
1288 ) { 1290 ) {
1289 return 1; 1291 return 1;
1290 } 1292 }
1291 1293
1292 /* Create client ID based on mac, set clientid_mac_ptr */ 1294 clientid_mac_ptr = NULL;
1293 { 1295 if (!udhcp_find_option(client_data.options, D6_OPT_CLIENTID)) {
1294 struct d6_option *clientid; 1296 /* not set, set the default client ID */
1295 clientid = xzalloc(2+2+2+2+6); 1297 client_data.clientid[1] = 3; /* DUID-LL */
1296 clientid->code = D6_OPT_CLIENTID; 1298 client_data.clientid[3] = 1; /* ethernet */
1297 clientid->len = 2+2+6; 1299 clientid_mac_ptr = udhcp_insert_new_option(&client_data.options, D6_OPT_CLIENTID,
1298 clientid->data[1] = 3; /* DUID-LL */ 1300 client_data.clientid, 2+2 + 6, /*dhcp6:*/ 1);
1299 clientid->data[3] = 1; /* ethernet */ 1301 clientid_mac_ptr += 2+2 + 2+2; /* skip option code, len, DUID-LL, ethernet */
1300 clientid_mac_ptr = clientid->data + 2+2;
1301 memcpy(clientid_mac_ptr, client_data.client_mac, 6);
1302 client_data.clientid = (void*)clientid;
1303 } 1302 }
1304 1303
1305#if !BB_MMU 1304#if !BB_MMU
@@ -1386,12 +1385,13 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1386 if (d6_read_interface(client_data.interface, 1385 if (d6_read_interface(client_data.interface,
1387 &client_data.ifindex, 1386 &client_data.ifindex,
1388 &client6_data.ll_ip6, 1387 &client6_data.ll_ip6,
1389 client_data.client_mac) 1388 client_data_client_mac)
1390 ) { 1389 ) {
1391 goto ret0; /* iface is gone? */ 1390 goto ret0; /* iface is gone? */
1392 } 1391 }
1393 1392
1394 memcpy(clientid_mac_ptr, client_data.client_mac, 6); 1393 if (clientid_mac_ptr)
1394 memcpy(clientid_mac_ptr, client_data_client_mac, 6);
1395 1395
1396 switch (client_data.state) { 1396 switch (client_data.state) {
1397 case INIT_SELECTING: 1397 case INIT_SELECTING:
@@ -1505,7 +1505,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1505 continue; 1505 continue;
1506 /* case RELEASED: */ 1506 /* case RELEASED: */
1507 } 1507 }
1508 /* yah, I know, *you* say it would never happen */ 1508 /* RELEASED state (when we got SIGUSR2) ends up here.
1509 * (wait for SIGUSR1 to re-init, or for TERM, etc)
1510 */
1509 timeout = INT_MAX; 1511 timeout = INT_MAX;
1510 continue; /* back to main loop */ 1512 continue; /* back to main loop */
1511 } /* if poll timed out */ 1513 } /* if poll timed out */
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index ea06405ba..a06eeaa16 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -612,9 +612,7 @@ static void init_packet(struct dhcp_packet *packet, char type)
612 secs = client_data.last_secs - client_data.first_secs; 612 secs = client_data.last_secs - client_data.first_secs;
613 packet->secs = (secs < 0xffff) ? htons(secs) : 0xffff; 613 packet->secs = (secs < 0xffff) ? htons(secs) : 0xffff;
614 614
615 memcpy(packet->chaddr, client_data.client_mac, 6); 615 memcpy(packet->chaddr, client_data_client_mac, 6);
616 if (client_data.clientid)
617 udhcp_add_binary_option(packet, client_data.clientid);
618} 616}
619 617
620static void add_client_options(struct dhcp_packet *packet) 618static void add_client_options(struct dhcp_packet *packet)
@@ -715,7 +713,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
715 713
716 /* Fill in: op, htype, hlen, cookie, chaddr fields, 714 /* Fill in: op, htype, hlen, cookie, chaddr fields,
717 * random xid field (we override it below), 715 * random xid field (we override it below),
718 * client-id option (unless -C), message type option: 716 * message type option:
719 */ 717 */
720 init_packet(&packet, DHCPDISCOVER); 718 init_packet(&packet, DHCPDISCOVER);
721 719
@@ -724,7 +722,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
724 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); 722 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
725 723
726 /* Add options: maxsize, 724 /* Add options: maxsize,
727 * optionally: hostname, fqdn, vendorclass, 725 * optionally: hostname, fqdn, vendorclass, client-id,
728 * "param req" option according to -O, options specified with -x 726 * "param req" option according to -O, options specified with -x
729 */ 727 */
730 add_client_options(&packet); 728 add_client_options(&packet);
@@ -758,7 +756,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste
758 */ 756 */
759 /* Fill in: op, htype, hlen, cookie, chaddr fields, 757 /* Fill in: op, htype, hlen, cookie, chaddr fields,
760 * random xid field (we override it below), 758 * random xid field (we override it below),
761 * client-id option (unless -C), message type option: 759 * message type option:
762 */ 760 */
763 init_packet(&packet, DHCPREQUEST); 761 init_packet(&packet, DHCPREQUEST);
764 762
@@ -768,7 +766,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste
768 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); 766 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
769 767
770 /* Add options: maxsize, 768 /* Add options: maxsize,
771 * optionally: hostname, fqdn, vendorclass, 769 * optionally: hostname, fqdn, vendorclass, client-id,
772 * "param req" option according to -O, and options specified with -x 770 * "param req" option according to -O, and options specified with -x
773 */ 771 */
774 add_client_options(&packet); 772 add_client_options(&packet);
@@ -805,7 +803,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
805 */ 803 */
806 /* Fill in: op, htype, hlen, cookie, chaddr fields, 804 /* Fill in: op, htype, hlen, cookie, chaddr fields,
807 * random xid field (we override it below), 805 * random xid field (we override it below),
808 * client-id option (unless -C), message type option: 806 * message type option:
809 */ 807 */
810 init_packet(&packet, DHCPREQUEST); 808 init_packet(&packet, DHCPREQUEST);
811 809
@@ -813,7 +811,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
813 packet.ciaddr = ciaddr; 811 packet.ciaddr = ciaddr;
814 812
815 /* Add options: maxsize, 813 /* Add options: maxsize,
816 * optionally: hostname, fqdn, vendorclass, 814 * optionally: hostname, fqdn, vendorclass, client-id,
817 * "param req" option according to -O, and options specified with -x 815 * "param req" option according to -O, and options specified with -x
818 */ 816 */
819 add_client_options(&packet); 817 add_client_options(&packet);
@@ -837,7 +835,7 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req
837 struct dhcp_packet packet; 835 struct dhcp_packet packet;
838 836
839 /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields, 837 /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields,
840 * client-id option (unless -C), message type option: 838 * message type option:
841 */ 839 */
842 init_packet(&packet, DHCPDECLINE); 840 init_packet(&packet, DHCPDECLINE);
843 841
@@ -854,6 +852,8 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req
854 852
855 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); 853 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
856 854
855//TODO: add client-id opt?
856
857 bb_simple_info_msg("broadcasting decline"); 857 bb_simple_info_msg("broadcasting decline");
858 return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); 858 return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY);
859} 859}
@@ -865,9 +865,10 @@ ALWAYS_INLINE /* one caller, help compiler to use this fact */
865int send_release(uint32_t server, uint32_t ciaddr) 865int send_release(uint32_t server, uint32_t ciaddr)
866{ 866{
867 struct dhcp_packet packet; 867 struct dhcp_packet packet;
868 struct option_set *ci;
868 869
869 /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields, 870 /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields,
870 * client-id option (unless -C), message type option: 871 * message type option:
871 */ 872 */
872 init_packet(&packet, DHCPRELEASE); 873 init_packet(&packet, DHCPRELEASE);
873 874
@@ -876,6 +877,14 @@ int send_release(uint32_t server, uint32_t ciaddr)
876 877
877 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); 878 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
878 879
880 /* RFC 2131 section 3.1.6:
881 * If the client used a 'client identifier' when it obtained the lease,
882 * it MUST use the same 'client identifier' in the DHCPRELEASE message.
883 */
884 ci = udhcp_find_option(client_data.options, DHCP_CLIENT_ID);
885 if (ci)
886 udhcp_add_binary_option(&packet, ci->data);
887
879 bb_info_msg("sending %s", "release"); 888 bb_info_msg("sending %s", "release");
880 /* Note: normally we unicast here since "server" is not zero. 889 /* Note: normally we unicast here since "server" is not zero.
881 * However, there _are_ people who run "address-less" DHCP servers, 890 * However, there _are_ people who run "address-less" DHCP servers,
@@ -1230,7 +1239,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1230 const char *str_V, *str_h, *str_F, *str_r; 1239 const char *str_V, *str_h, *str_F, *str_r;
1231 IF_FEATURE_UDHCPC_ARPING(const char *str_a = "2000";) 1240 IF_FEATURE_UDHCPC_ARPING(const char *str_a = "2000";)
1232 IF_FEATURE_UDHCP_PORT(char *str_P;) 1241 IF_FEATURE_UDHCP_PORT(char *str_P;)
1233 void *clientid_mac_ptr; 1242 uint8_t *clientid_mac_ptr;
1234 llist_t *list_O = NULL; 1243 llist_t *list_O = NULL;
1235 llist_t *list_x = NULL; 1244 llist_t *list_x = NULL;
1236 int tryagain_timeout = 20; 1245 int tryagain_timeout = 20;
@@ -1339,7 +1348,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1339 if (udhcp_read_interface(client_data.interface, 1348 if (udhcp_read_interface(client_data.interface,
1340 &client_data.ifindex, 1349 &client_data.ifindex,
1341 NULL, 1350 NULL,
1342 client_data.client_mac) 1351 client_data_client_mac)
1343 ) { 1352 ) {
1344 return 1; 1353 return 1;
1345 } 1354 }
@@ -1347,10 +1356,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1347 clientid_mac_ptr = NULL; 1356 clientid_mac_ptr = NULL;
1348 if (!(opt & OPT_C) && !udhcp_find_option(client_data.options, DHCP_CLIENT_ID)) { 1357 if (!(opt & OPT_C) && !udhcp_find_option(client_data.options, DHCP_CLIENT_ID)) {
1349 /* not suppressed and not set, set the default client ID */ 1358 /* not suppressed and not set, set the default client ID */
1350 client_data.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7); 1359 client_data_client_mac[-1] = 1; /* type: ethernet */
1351 client_data.clientid[OPT_DATA] = 1; /* type: ethernet */ 1360 clientid_mac_ptr = udhcp_insert_new_option(
1352 clientid_mac_ptr = client_data.clientid + OPT_DATA+1; 1361 &client_data.options, DHCP_CLIENT_ID,
1353 memcpy(clientid_mac_ptr, client_data.client_mac, 6); 1362 client_data_client_mac - 1, 1 + 6, /*dhcp6:*/ 0);
1363 clientid_mac_ptr += 3; /* skip option code, len, ethernet */
1354 } 1364 }
1355 if (str_V[0] != '\0') { 1365 if (str_V[0] != '\0') {
1356 // can drop -V, str_V, client_data.vendorclass, 1366 // can drop -V, str_V, client_data.vendorclass,
@@ -1447,12 +1457,12 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1447 if (udhcp_read_interface(client_data.interface, 1457 if (udhcp_read_interface(client_data.interface,
1448 &client_data.ifindex, 1458 &client_data.ifindex,
1449 NULL, 1459 NULL,
1450 client_data.client_mac) 1460 client_data_client_mac)
1451 ) { 1461 ) {
1452 goto ret0; /* iface is gone? */ 1462 goto ret0; /* iface is gone? */
1453 } 1463 }
1454 if (clientid_mac_ptr) 1464 if (clientid_mac_ptr)
1455 memcpy(clientid_mac_ptr, client_data.client_mac, 6); 1465 memcpy(clientid_mac_ptr, client_data_client_mac, 6);
1456 1466
1457 switch (client_data.state) { 1467 switch (client_data.state) {
1458 case INIT_SELECTING: 1468 case INIT_SELECTING:
@@ -1569,7 +1579,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1569 continue; 1579 continue;
1570 /* case RELEASED: */ 1580 /* case RELEASED: */
1571 } 1581 }
1572 /* yah, I know, *you* say it would never happen */ 1582 /* RELEASED state (when we got SIGUSR2) ends up here.
1583 * (wait for SIGUSR1 to re-init, or for TERM, etc)
1584 */
1573 timeout = INT_MAX; 1585 timeout = INT_MAX;
1574 continue; /* back to main loop */ 1586 continue; /* back to main loop */
1575 } /* if poll timed out */ 1587 } /* if poll timed out */
@@ -1645,7 +1657,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1645 1657
1646 /* Ignore packets that aren't for us */ 1658 /* Ignore packets that aren't for us */
1647 if (packet.hlen != 6 1659 if (packet.hlen != 6
1648 || memcmp(packet.chaddr, client_data.client_mac, 6) != 0 1660 || memcmp(packet.chaddr, client_data_client_mac, 6) != 0
1649 ) { 1661 ) {
1650//FIXME: need to also check that last 10 bytes are zero 1662//FIXME: need to also check that last 10 bytes are zero
1651 log1("chaddr does not match%s", ", ignoring packet"); // log2? 1663 log1("chaddr does not match%s", ", ignoring packet"); // log2?
@@ -1757,7 +1769,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1757 if (!arpping(requested_ip, 1769 if (!arpping(requested_ip,
1758 NULL, 1770 NULL,
1759 (uint32_t) 0, 1771 (uint32_t) 0,
1760 client_data.client_mac, 1772 client_data_client_mac,
1761 client_data.interface, 1773 client_data.interface,
1762 arpping_ms) 1774 arpping_ms)
1763 ) { 1775 ) {
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index 7ad01ea8f..a4cc188b6 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -8,7 +8,8 @@
8PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 8PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
9 9
10struct client_data_t { 10struct client_data_t {
11 uint8_t client_mac[6]; /* Our mac address */ 11 uint8_t clientid[2+2 + 6]; /* Our mac address (prefixed by padding used for client-id) */
12#define client_data_client_mac (client_data.clientid + 2+2)
12 IF_FEATURE_UDHCP_PORT(uint16_t port;) 13 IF_FEATURE_UDHCP_PORT(uint16_t port;)
13 int ifindex; /* Index number of the interface to use */ 14 int ifindex; /* Index number of the interface to use */
14 uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O option) */ 15 uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O option) */
@@ -17,7 +18,6 @@ struct client_data_t {
17 char *pidfile; /* Optionally store the process ID */ 18 char *pidfile; /* Optionally store the process ID */
18 const char *script; /* User script to run at dhcp events */ 19 const char *script; /* User script to run at dhcp events */
19 struct option_set *options; /* list of DHCP options to send to server */ 20 struct option_set *options; /* list of DHCP options to send to server */
20 uint8_t *clientid; /* Optional client id to use */
21 uint8_t *vendorclass; /* Optional vendor class-id to use */ 21 uint8_t *vendorclass; /* Optional vendor class-id to use */
22 uint8_t *hostname; /* Optional hostname to use */ 22 uint8_t *hostname; /* Optional hostname to use */
23 uint8_t *fqdn; /* Optional fully qualified domain name to use */ 23 uint8_t *fqdn; /* Optional fully qualified domain name to use */