aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-15 01:02:01 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-15 01:06:42 +0200
commit827b690fa7b9dd006f305449c342fb1b9bff6fb7 (patch)
treec781d097d894f1a501531ce4080799e319eea79e
parent40a327aeae87ab53f42a5669e8c16c4615fb09c7 (diff)
downloadbusybox-w32-827b690fa7b9dd006f305449c342fb1b9bff6fb7.tar.gz
busybox-w32-827b690fa7b9dd006f305449c342fb1b9bff6fb7.tar.bz2
busybox-w32-827b690fa7b9dd006f305449c342fb1b9bff6fb7.zip
udhcpc[6]: do not pass xid around, keep it in client_data.xid
function old new delta perform_release 105 169 +64 perform_d6_release 259 262 +3 init_d6_packet 84 85 +1 send_d6_discover 286 285 -1 send_d6_select 128 126 -2 send_d6_renew 176 174 -2 send_d6_info_request 65 63 -2 udhcpc_main 2555 2551 -4 send_select 130 122 -8 send_renew 99 91 -8 send_discover 89 81 -8 udhcpc6_main 2636 2602 -34 send_release 74 - -74 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 3/9 up/down: 68/-143) Total: -75 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/udhcp/d6_dhcpc.c56
-rw-r--r--networking/udhcp/dhcpc.c51
-rw-r--r--networking/udhcp/dhcpc.h1
3 files changed, 48 insertions, 60 deletions
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index 7f288f891..802a27521 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -479,15 +479,15 @@ static ALWAYS_INLINE uint32_t random_xid(void)
479} 479}
480 480
481/* Initialize the packet with the proper defaults */ 481/* Initialize the packet with the proper defaults */
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)
483{ 483{
484 uint8_t *ptr; 484 uint8_t *ptr;
485 unsigned secs; 485 unsigned secs;
486 486
487 memset(packet, 0, sizeof(*packet)); 487 memset(packet, 0, sizeof(*packet));
488 488
489 packet->d6_xid32 = xid; 489 packet->d6_xid32 = client_data.xid;
490 packet->d6_msg_type = type; 490 packet->d6_msg_type = type; /* union, overwrites lowest byte of d6_xid32 */
491 491
492 /* ELAPSED_TIME option is required to be present by the RFC, 492 /* ELAPSED_TIME option is required to be present by the RFC,
493 * and some servers do check for its presense. [which?] 493 * and some servers do check for its presense. [which?]
@@ -585,13 +585,13 @@ static int d6_mcast_from_client_data_ifindex(struct d6_packet *packet, uint8_t *
585 * about parameter values the client would like to have returned. 585 * about parameter values the client would like to have returned.
586 */ 586 */
587/* NOINLINE: limit stack usage in caller */ 587/* NOINLINE: limit stack usage in caller */
588static NOINLINE int send_d6_info_request(uint32_t xid) 588static NOINLINE int send_d6_info_request(void)
589{ 589{
590 struct d6_packet packet; 590 struct d6_packet packet;
591 uint8_t *opt_ptr; 591 uint8_t *opt_ptr;
592 592
593 /* Fill in: msg type */ 593 /* Fill in: msg type, xid, ELAPSED_TIME */
594 opt_ptr = init_d6_packet(&packet, D6_MSG_INFORMATION_REQUEST, xid); 594 opt_ptr = init_d6_packet(&packet, D6_MSG_INFORMATION_REQUEST);
595 595
596 /* Add options: client-id, 596 /* Add options: client-id,
597 * "param req" option according to -O, options specified with -x 597 * "param req" option according to -O, options specified with -x
@@ -684,14 +684,14 @@ static NOINLINE int send_d6_info_request(uint32_t xid)
684 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 684 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
685 */ 685 */
686/* NOINLINE: limit stack usage in caller */ 686/* NOINLINE: limit stack usage in caller */
687static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ipv6) 687static NOINLINE int send_d6_discover(struct in6_addr *requested_ipv6)
688{ 688{
689 struct d6_packet packet; 689 struct d6_packet packet;
690 uint8_t *opt_ptr; 690 uint8_t *opt_ptr;
691 unsigned len; 691 unsigned len;
692 692
693 /* Fill in: msg type */ 693 /* Fill in: msg type, xid, ELAPSED_TIME */
694 opt_ptr = init_d6_packet(&packet, D6_MSG_SOLICIT, xid); 694 opt_ptr = init_d6_packet(&packet, D6_MSG_SOLICIT);
695 695
696 /* Create new IA_NA, optionally with included IAADDR with requested IP */ 696 /* Create new IA_NA, optionally with included IAADDR with requested IP */
697 free(client6_data.ia_na); 697 free(client6_data.ia_na);
@@ -763,13 +763,13 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip
763 * messages from the server. 763 * messages from the server.
764 */ 764 */
765/* NOINLINE: limit stack usage in caller */ 765/* NOINLINE: limit stack usage in caller */
766static NOINLINE int send_d6_select(uint32_t xid) 766static NOINLINE int send_d6_select(void)
767{ 767{
768 struct d6_packet packet; 768 struct d6_packet packet;
769 uint8_t *opt_ptr; 769 uint8_t *opt_ptr;
770 770
771 /* Fill in: msg type */ 771 /* Fill in: msg type, xid, ELAPSED_TIME */
772 opt_ptr = init_d6_packet(&packet, D6_MSG_REQUEST, xid); 772 opt_ptr = init_d6_packet(&packet, D6_MSG_REQUEST);
773 773
774 /* server id */ 774 /* server id */
775 opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); 775 opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2);
@@ -836,13 +836,13 @@ static NOINLINE int send_d6_select(uint32_t xid)
836 * about parameter values the client would like to have returned. 836 * about parameter values the client would like to have returned.
837 */ 837 */
838/* NOINLINE: limit stack usage in caller */ 838/* NOINLINE: limit stack usage in caller */
839static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) 839static NOINLINE int send_d6_renew(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6)
840{ 840{
841 struct d6_packet packet; 841 struct d6_packet packet;
842 uint8_t *opt_ptr; 842 uint8_t *opt_ptr;
843 843
844 /* Fill in: msg type */ 844 /* Fill in: msg type, xid, ELAPSED_TIME */
845 opt_ptr = init_d6_packet(&packet, DHCPREQUEST, xid); 845 opt_ptr = init_d6_packet(&packet, DHCPREQUEST);
846 846
847 /* server id */ 847 /* server id */
848 opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); 848 opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2);
@@ -877,8 +877,8 @@ int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6)
877 uint8_t *opt_ptr; 877 uint8_t *opt_ptr;
878 struct option_set *ci; 878 struct option_set *ci;
879 879
880 /* Fill in: msg type, client id */ 880 /* Fill in: msg type, xid, ELAPSED_TIME */
881 opt_ptr = init_d6_packet(&packet, D6_MSG_RELEASE, random_xid()); 881 opt_ptr = init_d6_packet(&packet, D6_MSG_RELEASE);
882 /* server id */ 882 /* server id */
883 opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); 883 opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2);
884 /* IA NA (contains our current IP) */ 884 /* IA NA (contains our current IP) */
@@ -1097,6 +1097,7 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou
1097 || client_data.state == RENEW_REQUESTED 1097 || client_data.state == RENEW_REQUESTED
1098 ) { 1098 ) {
1099 bb_simple_info_msg("unicasting a release"); 1099 bb_simple_info_msg("unicasting a release");
1100 client_data.xid = random_xid(); //TODO: can omit?
1100 send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ 1101 send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */
1101 } 1102 }
1102 bb_simple_info_msg("entering released state"); 1103 bb_simple_info_msg("entering released state");
@@ -1183,7 +1184,6 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1183 struct in6_addr srv6_buf; 1184 struct in6_addr srv6_buf;
1184 struct in6_addr ipv6_buf; 1185 struct in6_addr ipv6_buf;
1185 struct in6_addr *requested_ipv6; 1186 struct in6_addr *requested_ipv6;
1186 uint32_t xid = 0;
1187 int packet_num; 1187 int packet_num;
1188 int timeout; /* must be signed */ 1188 int timeout; /* must be signed */
1189 int lease_remaining; /* must be signed */ 1189 int lease_remaining; /* must be signed */
@@ -1387,13 +1387,13 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1387 if (!discover_retries || packet_num < discover_retries) { 1387 if (!discover_retries || packet_num < discover_retries) {
1388 if (packet_num == 0) { 1388 if (packet_num == 0) {
1389 change_listen_mode(LISTEN_RAW); 1389 change_listen_mode(LISTEN_RAW);
1390 xid = random_xid(); 1390 client_data.xid = random_xid();
1391 } 1391 }
1392 /* multicast */ 1392 /* multicast */
1393 if (opt & OPT_l) 1393 if (opt & OPT_l)
1394 send_d6_info_request(xid); 1394 send_d6_info_request();
1395 else 1395 else
1396 send_d6_discover(xid, requested_ipv6); 1396 send_d6_discover(requested_ipv6);
1397 timeout = discover_timeout; 1397 timeout = discover_timeout;
1398 packet_num++; 1398 packet_num++;
1399 continue; 1399 continue;
@@ -1427,7 +1427,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1427 case REQUESTING: 1427 case REQUESTING:
1428 if (!discover_retries || packet_num < discover_retries) { 1428 if (!discover_retries || packet_num < discover_retries) {
1429 /* send multicast select packet */ 1429 /* send multicast select packet */
1430 send_d6_select(xid); 1430 send_d6_select();
1431 timeout = discover_timeout; 1431 timeout = discover_timeout;
1432 packet_num++; 1432 packet_num++;
1433 continue; 1433 continue;
@@ -1459,9 +1459,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1459 * into INIT_SELECTING state. 1459 * into INIT_SELECTING state.
1460 */ 1460 */
1461 if (opt & OPT_l) 1461 if (opt & OPT_l)
1462 send_d6_info_request(xid); 1462 send_d6_info_request();
1463 else 1463 else
1464 send_d6_renew(xid, &srv6_buf, requested_ipv6); 1464 send_d6_renew(&srv6_buf, requested_ipv6);
1465 timeout = discover_timeout; 1465 timeout = discover_timeout;
1466 packet_num++; 1466 packet_num++;
1467 continue; 1467 continue;
@@ -1484,9 +1484,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1484 * try to find DHCP server using broadcast */ 1484 * try to find DHCP server using broadcast */
1485 if (lease_remaining > 0 && packet_num < 3) { 1485 if (lease_remaining > 0 && packet_num < 3) {
1486 if (opt & OPT_l) 1486 if (opt & OPT_l)
1487 send_d6_info_request(xid); 1487 send_d6_info_request();
1488 else /* send a broadcast renew request */ 1488 else /* send a broadcast renew request */
1489 send_d6_renew(xid, /*server_ipv6:*/ NULL, requested_ipv6); 1489 send_d6_renew(/*server_ipv6:*/ NULL, requested_ipv6);
1490 timeout = discover_timeout; 1490 timeout = discover_timeout;
1491 packet_num++; 1491 packet_num++;
1492 continue; 1492 continue;
@@ -1581,9 +1581,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1581 packet_end = (uint8_t*)&packet + len; 1581 packet_end = (uint8_t*)&packet + len;
1582 } 1582 }
1583 1583
1584 if ((packet.d6_xid32 & htonl(0x00ffffff)) != xid) { 1584 if ((packet.d6_xid32 & htonl(0x00ffffff)) != client_data.xid) {
1585 log1("xid %x (our is %x)%s", 1585 log1("xid %x (our is %x)%s",
1586 (unsigned)(packet.d6_xid32 & htonl(0x00ffffff)), (unsigned)xid, 1586 (unsigned)(packet.d6_xid32 & htonl(0x00ffffff)), (unsigned)client_data.xid,
1587 ", ignoring packet" 1587 ", ignoring packet"
1588 ); 1588 );
1589 continue; 1589 continue;
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index b80ea2f40..1c3c478ac 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -605,7 +605,7 @@ static void init_packet(struct dhcp_packet *packet, char type)
605 /* Fill in: op, htype, hlen, cookie fields; message type option: */ 605 /* Fill in: op, htype, hlen, cookie fields; message type option: */
606 udhcp_init_header(packet, type); 606 udhcp_init_header(packet, type);
607 607
608 packet->xid = random_xid(); 608 packet->xid = client_data.xid;
609 609
610 client_data.last_secs = monotonic_sec(); 610 client_data.last_secs = monotonic_sec();
611 if (client_data.first_secs == 0) 611 if (client_data.first_secs == 0)
@@ -719,17 +719,15 @@ static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t
719 719
720/* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ 720/* Broadcast a DHCP discover packet to the network, with an optionally requested IP */
721/* NOINLINE: limit stack usage in caller */ 721/* NOINLINE: limit stack usage in caller */
722static NOINLINE int send_discover(uint32_t xid, uint32_t requested) 722static NOINLINE int send_discover(uint32_t requested)
723{ 723{
724 struct dhcp_packet packet; 724 struct dhcp_packet packet;
725 725
726 /* Fill in: op, htype, hlen, cookie, chaddr fields, 726 /* Fill in: op, htype, hlen, cookie, chaddr fields,
727 * random xid field (we override it below), 727 * xid field, message type option:
728 * message type option:
729 */ 728 */
730 init_packet(&packet, DHCPDISCOVER); 729 init_packet(&packet, DHCPDISCOVER);
731 730
732 packet.xid = xid;
733 if (requested) 731 if (requested)
734 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); 732 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
735 733
@@ -747,7 +745,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
747 * "The client _broadcasts_ a DHCPREQUEST message..." 745 * "The client _broadcasts_ a DHCPREQUEST message..."
748 */ 746 */
749/* NOINLINE: limit stack usage in caller */ 747/* NOINLINE: limit stack usage in caller */
750static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requested) 748static NOINLINE int send_select(uint32_t server, uint32_t requested)
751{ 749{
752 struct dhcp_packet packet; 750 struct dhcp_packet packet;
753 struct in_addr temp_addr; 751 struct in_addr temp_addr;
@@ -766,12 +764,10 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste
766 * include that list in all subsequent messages. 764 * include that list in all subsequent messages.
767 */ 765 */
768 /* Fill in: op, htype, hlen, cookie, chaddr fields, 766 /* Fill in: op, htype, hlen, cookie, chaddr fields,
769 * random xid field (we override it below), 767 * xid field, message type option:
770 * message type option:
771 */ 768 */
772 init_packet(&packet, DHCPREQUEST); 769 init_packet(&packet, DHCPREQUEST);
773 770
774 packet.xid = xid;
775 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); 771 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
776 772
777 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); 773 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
@@ -793,7 +789,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste
793 789
794/* Unicast or broadcast a DHCP renew message */ 790/* Unicast or broadcast a DHCP renew message */
795/* NOINLINE: limit stack usage in caller */ 791/* NOINLINE: limit stack usage in caller */
796static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) 792static NOINLINE int send_renew(uint32_t server, uint32_t ciaddr)
797{ 793{
798 struct dhcp_packet packet; 794 struct dhcp_packet packet;
799 795
@@ -812,12 +808,10 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
812 * replying to the client. 808 * replying to the client.
813 */ 809 */
814 /* Fill in: op, htype, hlen, cookie, chaddr fields, 810 /* Fill in: op, htype, hlen, cookie, chaddr fields,
815 * random xid field (we override it below), 811 * xid field, message type option:
816 * message type option:
817 */ 812 */
818 init_packet(&packet, DHCPREQUEST); 813 init_packet(&packet, DHCPREQUEST);
819 814
820 packet.xid = xid;
821 packet.ciaddr = ciaddr; 815 packet.ciaddr = ciaddr;
822 816
823 /* Add options: maxsize, 817 /* Add options: maxsize,
@@ -839,7 +833,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
839#if ENABLE_FEATURE_UDHCPC_ARPING 833#if ENABLE_FEATURE_UDHCPC_ARPING
840/* Broadcast a DHCP decline message */ 834/* Broadcast a DHCP decline message */
841/* NOINLINE: limit stack usage in caller */ 835/* NOINLINE: limit stack usage in caller */
842static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t requested) 836static NOINLINE int send_decline(uint32_t server, uint32_t requested)
843{ 837{
844 struct dhcp_packet packet; 838 struct dhcp_packet packet;
845 839
@@ -848,14 +842,6 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req
848 */ 842 */
849 init_packet(&packet, DHCPDECLINE); 843 init_packet(&packet, DHCPDECLINE);
850 844
851#if 0
852 /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client,
853 * but in case the server is buggy and wants DHCPDECLINE's xid
854 * to match the xid which started entire handshake,
855 * we use the same xid we used in initial DHCPDISCOVER:
856 */
857 packet.xid = xid;
858#endif
859 /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */ 845 /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */
860 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); 846 udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
861 847
@@ -1145,6 +1131,7 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip)
1145 temp_addr.s_addr = requested_ip; 1131 temp_addr.s_addr = requested_ip;
1146 bb_info_msg("unicasting a release of %s to %s", 1132 bb_info_msg("unicasting a release of %s to %s",
1147 inet_ntoa(temp_addr), buffer); 1133 inet_ntoa(temp_addr), buffer);
1134 client_data.xid = random_xid(); //TODO: can omit?
1148 send_release(server_addr, requested_ip); /* unicast */ 1135 send_release(server_addr, requested_ip); /* unicast */
1149 } 1136 }
1150 bb_simple_info_msg("entering released state"); 1137 bb_simple_info_msg("entering released state");
@@ -1233,7 +1220,6 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1233 int discover_retries = 3; 1220 int discover_retries = 3;
1234 uint32_t server_addr = server_addr; /* for compiler */ 1221 uint32_t server_addr = server_addr; /* for compiler */
1235 uint32_t requested_ip = 0; 1222 uint32_t requested_ip = 0;
1236 uint32_t xid = xid; /* for compiler */
1237 int packet_num; 1223 int packet_num;
1238 int timeout; /* must be signed */ 1224 int timeout; /* must be signed */
1239 int lease_remaining; /* must be signed */ 1225 int lease_remaining; /* must be signed */
@@ -1458,10 +1444,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1458 if (!discover_retries || packet_num < discover_retries) { 1444 if (!discover_retries || packet_num < discover_retries) {
1459 if (packet_num == 0) { 1445 if (packet_num == 0) {
1460 change_listen_mode(LISTEN_RAW); 1446 change_listen_mode(LISTEN_RAW);
1461 xid = random_xid(); 1447 client_data.xid = random_xid();
1462 } 1448 }
1463 /* broadcast */ 1449 /* broadcast */
1464 send_discover(xid, requested_ip); 1450 send_discover(requested_ip);
1465 timeout = discover_timeout; 1451 timeout = discover_timeout;
1466 packet_num++; 1452 packet_num++;
1467 continue; 1453 continue;
@@ -1495,7 +1481,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1495 case REQUESTING: 1481 case REQUESTING:
1496 if (packet_num < 3) { 1482 if (packet_num < 3) {
1497 /* send broadcast select packet */ 1483 /* send broadcast select packet */
1498 send_select(xid, server_addr, requested_ip); 1484 send_select(server_addr, requested_ip);
1499 timeout = discover_timeout; 1485 timeout = discover_timeout;
1500 packet_num++; 1486 packet_num++;
1501 continue; 1487 continue;
@@ -1526,7 +1512,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1526 * Anyway, it does recover by eventually failing through 1512 * Anyway, it does recover by eventually failing through
1527 * into INIT_SELECTING state. 1513 * into INIT_SELECTING state.
1528 */ 1514 */
1529 if (send_renew(xid, server_addr, requested_ip) >= 0) { 1515 if (send_renew(server_addr, requested_ip) >= 0) {
1530 timeout = discover_timeout; 1516 timeout = discover_timeout;
1531 packet_num++; 1517 packet_num++;
1532 continue; 1518 continue;
@@ -1555,7 +1541,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1555 * try to find DHCP server using broadcast */ 1541 * try to find DHCP server using broadcast */
1556 if (lease_remaining > 0 && packet_num < 3) { 1542 if (lease_remaining > 0 && packet_num < 3) {
1557 /* send a broadcast renew request */ 1543 /* send a broadcast renew request */
1558 send_renew(xid, 0 /*INADDR_ANY*/, requested_ip); 1544 send_renew(0 /*INADDR_ANY*/, requested_ip);
1559 timeout = discover_timeout; 1545 timeout = discover_timeout;
1560 packet_num++; 1546 packet_num++;
1561 continue; 1547 continue;
@@ -1648,9 +1634,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1648 continue; 1634 continue;
1649 } 1635 }
1650 1636
1651 if (packet.xid != xid) { 1637 if (packet.xid != client_data.xid) {
1652 log1("xid %x (our is %x)%s", 1638 log1("xid %x (our is %x)%s",
1653 (unsigned)packet.xid, (unsigned)xid, 1639 (unsigned)packet.xid, (unsigned)client_data.xid,
1654 ", ignoring packet" 1640 ", ignoring packet"
1655 ); 1641 );
1656 continue; 1642 continue;
@@ -1779,7 +1765,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1779 ) { 1765 ) {
1780 bb_simple_info_msg("offered address is in use " 1766 bb_simple_info_msg("offered address is in use "
1781 "(got ARP reply), declining"); 1767 "(got ARP reply), declining");
1782 send_decline(/*xid,*/ server_addr, packet.yiaddr); 1768 client_data.xid = random_xid(); //TODO: can omit?
1769 send_decline(server_addr, packet.yiaddr);
1783 1770
1784 if (client_data.state != REQUESTING) 1771 if (client_data.state != REQUESTING)
1785 d4_run_script_deconfig(); 1772 d4_run_script_deconfig();
@@ -1814,7 +1801,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1814 timeout = (unsigned)lease_remaining / 2; 1801 timeout = (unsigned)lease_remaining / 2;
1815 client_data.state = BOUND; 1802 client_data.state = BOUND;
1816 /* make future renew packets use different xid */ 1803 /* make future renew packets use different xid */
1817 /* xid = random_xid(); ...but why bother? */ 1804 /* client_data.xid = random_xid(); ...but why bother? */
1818 packet_num = 0; 1805 packet_num = 0;
1819 continue; /* back to main loop */ 1806 continue; /* back to main loop */
1820 } 1807 }
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index cd9ead6bd..19b054b32 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -11,6 +11,7 @@ struct client_data_t {
11 uint8_t client_mac[6]; /* Our mac address */ 11 uint8_t client_mac[6]; /* Our mac address */
12 IF_FEATURE_UDHCP_PORT(uint16_t port;) 12 IF_FEATURE_UDHCP_PORT(uint16_t port;)
13 int ifindex; /* Index number of the interface to use */ 13 int ifindex; /* Index number of the interface to use */
14 uint32_t xid;
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) */
15// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TODO: DHCPv6 has 16-bit option numbers 16// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TODO: DHCPv6 has 16-bit option numbers
16 const char *interface; /* The name of the interface to use */ 17 const char *interface; /* The name of the interface to use */