diff options
author | Ron Yorston <rmy@pobox.com> | 2021-06-28 07:46:32 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-06-28 07:46:32 +0100 |
commit | e1ad66c0b8fd58a7158d40771175a7dab224202d (patch) | |
tree | 959d687eee9637151ad5798322586174de331141 /networking | |
parent | 0fdf99bee07b6c38795eb5415b5e337ab82cfba8 (diff) | |
parent | 5dbbd0a6f52befe6bc57baf97d39168e595197f1 (diff) | |
download | busybox-w32-e1ad66c0b8fd58a7158d40771175a7dab224202d.tar.gz busybox-w32-e1ad66c0b8fd58a7158d40771175a7dab224202d.tar.bz2 busybox-w32-e1ad66c0b8fd58a7158d40771175a7dab224202d.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'networking')
-rw-r--r-- | networking/ftpd.c | 4 | ||||
-rw-r--r-- | networking/nameif.c | 4 | ||||
-rw-r--r-- | networking/telnetd.c | 1 | ||||
-rw-r--r-- | networking/tftp.c | 5 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 74 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 131 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.h | 1 | ||||
-rw-r--r-- | networking/vconfig.c | 12 |
8 files changed, 111 insertions, 121 deletions
diff --git a/networking/ftpd.c b/networking/ftpd.c index 6ca231c90..0d6a289c7 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c | |||
@@ -54,7 +54,7 @@ | |||
54 | //kbuild:lib-$(CONFIG_FTPD) += ftpd.o | 54 | //kbuild:lib-$(CONFIG_FTPD) += ftpd.o |
55 | 55 | ||
56 | //usage:#define ftpd_trivial_usage | 56 | //usage:#define ftpd_trivial_usage |
57 | //usage: "[-wvS]"IF_FEATURE_FTPD_AUTHENTICATION(" [-a USER]")" [-t N] [-T N] [DIR]" | 57 | //usage: "[-wvS]"IF_FEATURE_FTPD_AUTHENTICATION(" [-a USER]")" [-t SEC] [-T SEC] [DIR]" |
58 | //usage:#define ftpd_full_usage "\n\n" | 58 | //usage:#define ftpd_full_usage "\n\n" |
59 | //usage: IF_NOT_FEATURE_FTPD_AUTHENTICATION( | 59 | //usage: IF_NOT_FEATURE_FTPD_AUTHENTICATION( |
60 | //usage: "Anonymous FTP server. Client access occurs under ftpd's UID.\n" | 60 | //usage: "Anonymous FTP server. Client access occurs under ftpd's UID.\n" |
@@ -63,7 +63,7 @@ | |||
63 | //usage: "FTP server. " | 63 | //usage: "FTP server. " |
64 | //usage: ) | 64 | //usage: ) |
65 | //usage: "Chroots to DIR, if this fails (run by non-root), cds to it.\n" | 65 | //usage: "Chroots to DIR, if this fails (run by non-root), cds to it.\n" |
66 | //usage: "Should be used as inetd service, inetd.conf line:\n" | 66 | //usage: "It is an inetd service, inetd.conf line:\n" |
67 | //usage: " 21 stream tcp nowait root ftpd ftpd /files/to/serve\n" | 67 | //usage: " 21 stream tcp nowait root ftpd ftpd /files/to/serve\n" |
68 | //usage: "Can be run from tcpsvd:\n" | 68 | //usage: "Can be run from tcpsvd:\n" |
69 | //usage: " tcpsvd -vE 0.0.0.0 21 ftpd /files/to/serve" | 69 | //usage: " tcpsvd -vE 0.0.0.0 21 ftpd /files/to/serve" |
diff --git a/networking/nameif.c b/networking/nameif.c index 854594c83..66e042688 100644 --- a/networking/nameif.c +++ b/networking/nameif.c | |||
@@ -52,10 +52,10 @@ | |||
52 | //usage:#define nameif_full_usage "\n\n" | 52 | //usage:#define nameif_full_usage "\n\n" |
53 | //usage: "Rename network interface while it in the down state." | 53 | //usage: "Rename network interface while it in the down state." |
54 | //usage: IF_NOT_FEATURE_NAMEIF_EXTENDED( | 54 | //usage: IF_NOT_FEATURE_NAMEIF_EXTENDED( |
55 | //usage: "\nThe device with address HWADDR is renamed to IFACE." | 55 | //usage: "\nThe device with address HWADDR is renamed to IFNAME." |
56 | //usage: ) | 56 | //usage: ) |
57 | //usage: IF_FEATURE_NAMEIF_EXTENDED( | 57 | //usage: IF_FEATURE_NAMEIF_EXTENDED( |
58 | //usage: "\nThe device matched by SELECTOR is renamed to IFACE." | 58 | //usage: "\nThe device matched by SELECTOR is renamed to IFNAME." |
59 | //usage: "\nSELECTOR can be a combination of:" | 59 | //usage: "\nSELECTOR can be a combination of:" |
60 | //usage: "\n driver=STRING" | 60 | //usage: "\n driver=STRING" |
61 | //usage: "\n bus=STRING" | 61 | //usage: "\n bus=STRING" |
diff --git a/networking/telnetd.c b/networking/telnetd.c index 29f805de7..de4d733f9 100644 --- a/networking/telnetd.c +++ b/networking/telnetd.c | |||
@@ -109,6 +109,7 @@ | |||
109 | //usage: "\n -i Inetd mode" | 109 | //usage: "\n -i Inetd mode" |
110 | //usage: IF_FEATURE_TELNETD_INETD_WAIT( | 110 | //usage: IF_FEATURE_TELNETD_INETD_WAIT( |
111 | //usage: "\n -w SEC Inetd 'wait' mode, linger time SEC" | 111 | //usage: "\n -w SEC Inetd 'wait' mode, linger time SEC" |
112 | //usage: "\n inetd.conf line: 23 stream tcp wait root telnetd telnetd -w10" | ||
112 | //usage: "\n -S Log to syslog (implied by -i or without -F and -w)" | 113 | //usage: "\n -S Log to syslog (implied by -i or without -F and -w)" |
113 | //usage: ) | 114 | //usage: ) |
114 | //usage: ) | 115 | //usage: ) |
diff --git a/networking/tftp.c b/networking/tftp.c index 4b86ed9de..f5b4367ca 100644 --- a/networking/tftp.c +++ b/networking/tftp.c | |||
@@ -113,10 +113,9 @@ | |||
113 | //usage:#define tftpd_full_usage "\n\n" | 113 | //usage:#define tftpd_full_usage "\n\n" |
114 | //usage: "Transfer a file on tftp client's request\n" | 114 | //usage: "Transfer a file on tftp client's request\n" |
115 | //usage: "\n" | 115 | //usage: "\n" |
116 | //usage: "tftpd should be used as an inetd service.\n" | 116 | //usage: "tftpd is an inetd service, inetd.conf line:\n" |
117 | //usage: "tftpd's line for inetd.conf:\n" | ||
118 | //usage: " 69 dgram udp nowait root tftpd tftpd -l /files/to/serve\n" | 117 | //usage: " 69 dgram udp nowait root tftpd tftpd -l /files/to/serve\n" |
119 | //usage: "It also can be ran from udpsvd:\n" | 118 | //usage: "Can be run from udpsvd:\n" |
120 | //usage: " udpsvd -vE 0.0.0.0 69 tftpd /files/to/serve\n" | 119 | //usage: " udpsvd -vE 0.0.0.0 69 tftpd /files/to/serve\n" |
121 | //usage: "\n -r Prohibit upload" | 120 | //usage: "\n -r Prohibit upload" |
122 | //usage: "\n -c Allow file creation via upload" | 121 | //usage: "\n -c Allow file creation via upload" |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 7f288f891..8d11a7539 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 */ |
482 | static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid) | 482 | static 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 */ |
588 | static NOINLINE int send_d6_info_request(uint32_t xid) | 588 | static 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 */ |
687 | static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ipv6) | 687 | static 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 */ |
766 | static NOINLINE int send_d6_select(uint32_t xid) | 766 | static 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 */ |
839 | static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) | 839 | static 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"); |
@@ -1126,23 +1127,23 @@ static void client_background(void) | |||
1126 | //usage:# define IF_UDHCP_VERBOSE(...) | 1127 | //usage:# define IF_UDHCP_VERBOSE(...) |
1127 | //usage:#endif | 1128 | //usage:#endif |
1128 | //usage:#define udhcpc6_trivial_usage | 1129 | //usage:#define udhcpc6_trivial_usage |
1129 | //usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"odR] [-i IFACE] [-r IPv6] [-s PROG] [-p PIDFILE]\n" | 1130 | //usage: "[-fbq"IF_UDHCP_VERBOSE("v")"R] [-t N] [-T SEC] [-A SEC|-n] [-i IFACE] [-s PROG]\n" |
1130 | //usage: " [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P PORT]") | 1131 | //usage: " [-p PIDFILE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-ldo] [-r IPv6] [-x OPT:VAL]... [-O OPT]..." |
1131 | //usage:#define udhcpc6_full_usage "\n" | 1132 | //usage:#define udhcpc6_full_usage "\n" |
1132 | //usage: "\n -i IFACE Interface to use (default "CONFIG_UDHCPC_DEFAULT_INTERFACE")" | 1133 | //usage: "\n -i IFACE Interface to use (default "CONFIG_UDHCPC_DEFAULT_INTERFACE")" |
1133 | //usage: "\n -p FILE Create pidfile" | 1134 | //usage: "\n -p FILE Create pidfile" |
1134 | //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" | 1135 | //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" |
1135 | //usage: "\n -B Request broadcast replies" | 1136 | //usage: "\n -B Request broadcast replies" |
1136 | //usage: "\n -t N Send up to N discover packets" | 1137 | //usage: "\n -t N Send up to N discover packets" |
1137 | //usage: "\n -T N Pause between packets (default 3 seconds)" | 1138 | //usage: "\n -T SEC Pause between packets (default 3)" |
1138 | //usage: "\n -A N Wait N seconds (default 20) after failure" | 1139 | //usage: "\n -A SEC Wait if lease is not obtained (default 20)" |
1139 | //usage: "\n -f Run in foreground" | ||
1140 | //usage: USE_FOR_MMU( | 1140 | //usage: USE_FOR_MMU( |
1141 | //usage: "\n -b Background if lease is not obtained" | 1141 | //usage: "\n -b Background if lease is not obtained" |
1142 | //usage: ) | 1142 | //usage: ) |
1143 | //usage: "\n -n Exit if lease is not obtained" | 1143 | //usage: "\n -n Exit if lease is not obtained" |
1144 | //usage: "\n -q Exit after obtaining lease" | 1144 | //usage: "\n -q Exit after obtaining lease" |
1145 | //usage: "\n -R Release IP on exit" | 1145 | //usage: "\n -R Release IP on exit" |
1146 | //usage: "\n -f Run in foreground" | ||
1146 | //usage: "\n -S Log to syslog too" | 1147 | //usage: "\n -S Log to syslog too" |
1147 | //usage: IF_FEATURE_UDHCP_PORT( | 1148 | //usage: IF_FEATURE_UDHCP_PORT( |
1148 | //usage: "\n -P PORT Use PORT (default 546)" | 1149 | //usage: "\n -P PORT Use PORT (default 546)" |
@@ -1150,12 +1151,12 @@ static void client_background(void) | |||
1150 | ////usage: IF_FEATURE_UDHCPC_ARPING( | 1151 | ////usage: IF_FEATURE_UDHCPC_ARPING( |
1151 | ////usage: "\n -a Use arping to validate offered address" | 1152 | ////usage: "\n -a Use arping to validate offered address" |
1152 | ////usage: ) | 1153 | ////usage: ) |
1153 | //usage: "\n -O OPT Request option OPT from server (cumulative)" | ||
1154 | //usage: "\n -o Don't request any options (unless -O is given)" | ||
1155 | //usage: "\n -r IPv6 Request this address ('no' to not request any IP)" | ||
1156 | //usage: "\n -d Request prefix" | ||
1157 | //usage: "\n -l Send 'information request' instead of 'solicit'" | 1154 | //usage: "\n -l Send 'information request' instead of 'solicit'" |
1158 | //usage: "\n (used for servers which do not assign IPv6 addresses)" | 1155 | //usage: "\n (used for servers which do not assign IPv6 addresses)" |
1156 | //usage: "\n -r IPv6 Request this address ('no' to not request any IP)" | ||
1157 | //usage: "\n -d Request prefix" | ||
1158 | //usage: "\n -o Don't request any options (unless -O is given)" | ||
1159 | //usage: "\n -O OPT Request option OPT from server (cumulative)" | ||
1159 | //usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)" | 1160 | //usage: "\n -x OPT:VAL Include option OPT in sent packets (cumulative)" |
1160 | //usage: "\n Examples of string, numeric, and hex byte opts:" | 1161 | //usage: "\n Examples of string, numeric, and hex byte opts:" |
1161 | //usage: "\n -x hostname:bbox - option 12" | 1162 | //usage: "\n -x hostname:bbox - option 12" |
@@ -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 4e3d8ca5e..331f13a8c 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) |
@@ -663,6 +663,24 @@ static void add_client_options(struct dhcp_packet *packet) | |||
663 | // ...add (DHCP_VENDOR, "udhcp "BB_VER) opt... | 663 | // ...add (DHCP_VENDOR, "udhcp "BB_VER) opt... |
664 | } | 664 | } |
665 | 665 | ||
666 | static void add_serverid_and_clientid_options(struct dhcp_packet *packet, uint32_t server) | ||
667 | { | ||
668 | struct option_set *ci; | ||
669 | |||
670 | udhcp_add_simple_option(packet, DHCP_SERVER_ID, server); | ||
671 | |||
672 | /* RFC 2131 section 2: | ||
673 | * If the client uses a 'client identifier' in one message, | ||
674 | * it MUST use that same identifier in all subsequent messages. | ||
675 | * section 3.1.6: | ||
676 | * If the client used a 'client identifier' when it obtained the lease, | ||
677 | * it MUST use the same 'client identifier' in the DHCPRELEASE message. | ||
678 | */ | ||
679 | ci = udhcp_find_option(client_data.options, DHCP_CLIENT_ID); | ||
680 | if (ci) | ||
681 | udhcp_add_binary_option(packet, ci->data); | ||
682 | } | ||
683 | |||
666 | /* RFC 2131 | 684 | /* RFC 2131 |
667 | * 4.4.4 Use of broadcast and unicast | 685 | * 4.4.4 Use of broadcast and unicast |
668 | * | 686 | * |
@@ -701,17 +719,15 @@ static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t | |||
701 | 719 | ||
702 | /* 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 */ |
703 | /* NOINLINE: limit stack usage in caller */ | 721 | /* NOINLINE: limit stack usage in caller */ |
704 | static NOINLINE int send_discover(uint32_t xid, uint32_t requested) | 722 | static NOINLINE int send_discover(uint32_t requested) |
705 | { | 723 | { |
706 | struct dhcp_packet packet; | 724 | struct dhcp_packet packet; |
707 | 725 | ||
708 | /* Fill in: op, htype, hlen, cookie, chaddr fields, | 726 | /* Fill in: op, htype, hlen, cookie, chaddr fields, |
709 | * random xid field (we override it below), | 727 | * xid field, message type option: |
710 | * message type option: | ||
711 | */ | 728 | */ |
712 | init_packet(&packet, DHCPDISCOVER); | 729 | init_packet(&packet, DHCPDISCOVER); |
713 | 730 | ||
714 | packet.xid = xid; | ||
715 | if (requested) | 731 | if (requested) |
716 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); | 732 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); |
717 | 733 | ||
@@ -729,7 +745,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested) | |||
729 | * "The client _broadcasts_ a DHCPREQUEST message..." | 745 | * "The client _broadcasts_ a DHCPREQUEST message..." |
730 | */ | 746 | */ |
731 | /* NOINLINE: limit stack usage in caller */ | 747 | /* NOINLINE: limit stack usage in caller */ |
732 | static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requested) | 748 | static NOINLINE int send_select(uint32_t server, uint32_t requested) |
733 | { | 749 | { |
734 | struct dhcp_packet packet; | 750 | struct dhcp_packet packet; |
735 | struct in_addr temp_addr; | 751 | struct in_addr temp_addr; |
@@ -748,18 +764,16 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste | |||
748 | * include that list in all subsequent messages. | 764 | * include that list in all subsequent messages. |
749 | */ | 765 | */ |
750 | /* Fill in: op, htype, hlen, cookie, chaddr fields, | 766 | /* Fill in: op, htype, hlen, cookie, chaddr fields, |
751 | * random xid field (we override it below), | 767 | * xid field, message type option: |
752 | * message type option: | ||
753 | */ | 768 | */ |
754 | init_packet(&packet, DHCPREQUEST); | 769 | init_packet(&packet, DHCPREQUEST); |
755 | 770 | ||
756 | packet.xid = xid; | ||
757 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); | 771 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); |
758 | 772 | ||
759 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); | 773 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
760 | 774 | ||
761 | /* Add options: maxsize, | 775 | /* Add options: maxsize, |
762 | * "param req" option according to -O, and options specified with -x | 776 | * "param req" option according to -O, options specified with -x |
763 | */ | 777 | */ |
764 | add_client_options(&packet); | 778 | add_client_options(&packet); |
765 | 779 | ||
@@ -775,7 +789,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste | |||
775 | 789 | ||
776 | /* Unicast or broadcast a DHCP renew message */ | 790 | /* Unicast or broadcast a DHCP renew message */ |
777 | /* NOINLINE: limit stack usage in caller */ | 791 | /* NOINLINE: limit stack usage in caller */ |
778 | static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | 792 | static NOINLINE int send_renew(uint32_t server, uint32_t ciaddr) |
779 | { | 793 | { |
780 | struct dhcp_packet packet; | 794 | struct dhcp_packet packet; |
781 | 795 | ||
@@ -794,16 +808,14 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | |||
794 | * replying to the client. | 808 | * replying to the client. |
795 | */ | 809 | */ |
796 | /* Fill in: op, htype, hlen, cookie, chaddr fields, | 810 | /* Fill in: op, htype, hlen, cookie, chaddr fields, |
797 | * random xid field (we override it below), | 811 | * xid field, message type option: |
798 | * message type option: | ||
799 | */ | 812 | */ |
800 | init_packet(&packet, DHCPREQUEST); | 813 | init_packet(&packet, DHCPREQUEST); |
801 | 814 | ||
802 | packet.xid = xid; | ||
803 | packet.ciaddr = ciaddr; | 815 | packet.ciaddr = ciaddr; |
804 | 816 | ||
805 | /* Add options: maxsize, | 817 | /* Add options: maxsize, |
806 | * "param req" option according to -O, and options specified with -x | 818 | * "param req" option according to -O, options specified with -x |
807 | */ | 819 | */ |
808 | add_client_options(&packet); | 820 | add_client_options(&packet); |
809 | 821 | ||
@@ -821,7 +833,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | |||
821 | #if ENABLE_FEATURE_UDHCPC_ARPING | 833 | #if ENABLE_FEATURE_UDHCPC_ARPING |
822 | /* Broadcast a DHCP decline message */ | 834 | /* Broadcast a DHCP decline message */ |
823 | /* NOINLINE: limit stack usage in caller */ | 835 | /* NOINLINE: limit stack usage in caller */ |
824 | static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t requested) | 836 | static NOINLINE int send_decline(uint32_t server, uint32_t requested) |
825 | { | 837 | { |
826 | struct dhcp_packet packet; | 838 | struct dhcp_packet packet; |
827 | 839 | ||
@@ -830,20 +842,10 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req | |||
830 | */ | 842 | */ |
831 | init_packet(&packet, DHCPDECLINE); | 843 | init_packet(&packet, DHCPDECLINE); |
832 | 844 | ||
833 | #if 0 | ||
834 | /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client, | ||
835 | * but in case the server is buggy and wants DHCPDECLINE's xid | ||
836 | * to match the xid which started entire handshake, | ||
837 | * we use the same xid we used in initial DHCPDISCOVER: | ||
838 | */ | ||
839 | packet.xid = xid; | ||
840 | #endif | ||
841 | /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */ | 845 | /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */ |
842 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); | 846 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); |
843 | 847 | ||
844 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); | 848 | add_serverid_and_clientid_options(&packet, server); |
845 | |||
846 | //TODO: add client-id opt? | ||
847 | 849 | ||
848 | bb_simple_info_msg("broadcasting decline"); | 850 | bb_simple_info_msg("broadcasting decline"); |
849 | return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); | 851 | return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); |
@@ -856,7 +858,6 @@ ALWAYS_INLINE /* one caller, help compiler to use this fact */ | |||
856 | int send_release(uint32_t server, uint32_t ciaddr) | 858 | int send_release(uint32_t server, uint32_t ciaddr) |
857 | { | 859 | { |
858 | struct dhcp_packet packet; | 860 | struct dhcp_packet packet; |
859 | struct option_set *ci; | ||
860 | 861 | ||
861 | /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields, | 862 | /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields, |
862 | * message type option: | 863 | * message type option: |
@@ -866,15 +867,7 @@ int send_release(uint32_t server, uint32_t ciaddr) | |||
866 | /* DHCPRELEASE uses ciaddr, not "requested ip", to store IP being released */ | 867 | /* DHCPRELEASE uses ciaddr, not "requested ip", to store IP being released */ |
867 | packet.ciaddr = ciaddr; | 868 | packet.ciaddr = ciaddr; |
868 | 869 | ||
869 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); | 870 | add_serverid_and_clientid_options(&packet, server); |
870 | |||
871 | /* RFC 2131 section 3.1.6: | ||
872 | * If the client used a 'client identifier' when it obtained the lease, | ||
873 | * it MUST use the same 'client identifier' in the DHCPRELEASE message. | ||
874 | */ | ||
875 | ci = udhcp_find_option(client_data.options, DHCP_CLIENT_ID); | ||
876 | if (ci) | ||
877 | udhcp_add_binary_option(&packet, ci->data); | ||
878 | 871 | ||
879 | bb_info_msg("sending %s", "release"); | 872 | bb_info_msg("sending %s", "release"); |
880 | /* Note: normally we unicast here since "server" is not zero. | 873 | /* Note: normally we unicast here since "server" is not zero. |
@@ -1120,7 +1113,7 @@ static void change_listen_mode(int new_mode) | |||
1120 | /* else LISTEN_NONE: client_data.sockfd stays closed */ | 1113 | /* else LISTEN_NONE: client_data.sockfd stays closed */ |
1121 | } | 1114 | } |
1122 | 1115 | ||
1123 | static void perform_release(uint32_t server_addr, uint32_t requested_ip) | 1116 | static void perform_release(uint32_t server_id, uint32_t requested_ip) |
1124 | { | 1117 | { |
1125 | char buffer[sizeof("255.255.255.255")]; | 1118 | char buffer[sizeof("255.255.255.255")]; |
1126 | struct in_addr temp_addr; | 1119 | struct in_addr temp_addr; |
@@ -1133,12 +1126,13 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip) | |||
1133 | || client_data.state == REBINDING | 1126 | || client_data.state == REBINDING |
1134 | || client_data.state == RENEW_REQUESTED | 1127 | || client_data.state == RENEW_REQUESTED |
1135 | ) { | 1128 | ) { |
1136 | temp_addr.s_addr = server_addr; | 1129 | temp_addr.s_addr = server_id; |
1137 | strcpy(buffer, inet_ntoa(temp_addr)); | 1130 | strcpy(buffer, inet_ntoa(temp_addr)); |
1138 | temp_addr.s_addr = requested_ip; | 1131 | temp_addr.s_addr = requested_ip; |
1139 | bb_info_msg("unicasting a release of %s to %s", | 1132 | bb_info_msg("unicasting a release of %s to %s", |
1140 | inet_ntoa(temp_addr), buffer); | 1133 | inet_ntoa(temp_addr), buffer); |
1141 | send_release(server_addr, requested_ip); /* unicast */ | 1134 | client_data.xid = random_xid(); //TODO: can omit? |
1135 | send_release(server_id, requested_ip); /* unicast */ | ||
1142 | } | 1136 | } |
1143 | bb_simple_info_msg("entering released state"); | 1137 | bb_simple_info_msg("entering released state"); |
1144 | /* | 1138 | /* |
@@ -1167,7 +1161,7 @@ static void client_background(void) | |||
1167 | //usage:# define IF_UDHCP_VERBOSE(...) | 1161 | //usage:# define IF_UDHCP_VERBOSE(...) |
1168 | //usage:#endif | 1162 | //usage:#endif |
1169 | //usage:#define udhcpc_trivial_usage | 1163 | //usage:#define udhcpc_trivial_usage |
1170 | //usage: "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_ARPING(" [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC/-n]\n" | 1164 | //usage: "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_ARPING(" [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC|-n]\n" |
1171 | //usage: " [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n" | 1165 | //usage: " [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n" |
1172 | //usage: " [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..." | 1166 | //usage: " [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..." |
1173 | //usage:#define udhcpc_full_usage "\n" | 1167 | //usage:#define udhcpc_full_usage "\n" |
@@ -1224,9 +1218,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1224 | int tryagain_timeout = 20; | 1218 | int tryagain_timeout = 20; |
1225 | int discover_timeout = 3; | 1219 | int discover_timeout = 3; |
1226 | int discover_retries = 3; | 1220 | int discover_retries = 3; |
1227 | uint32_t server_addr = server_addr; /* for compiler */ | 1221 | uint32_t server_id = server_id; /* for compiler */ |
1228 | uint32_t requested_ip = 0; | 1222 | uint32_t requested_ip = 0; |
1229 | uint32_t xid = xid; /* for compiler */ | ||
1230 | int packet_num; | 1223 | int packet_num; |
1231 | int timeout; /* must be signed */ | 1224 | int timeout; /* must be signed */ |
1232 | int lease_remaining; /* must be signed */ | 1225 | int lease_remaining; /* must be signed */ |
@@ -1291,7 +1284,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1291 | memcpy(p + OPT_DATA + 3, str_F, len); /* do not store NUL byte */ | 1284 | memcpy(p + OPT_DATA + 3, str_F, len); /* do not store NUL byte */ |
1292 | } | 1285 | } |
1293 | if (opt & OPT_r) | 1286 | if (opt & OPT_r) |
1294 | requested_ip = inet_addr(str_r); | 1287 | if (!inet_aton(str_r, (void*)&requested_ip)) |
1288 | bb_show_usage(); | ||
1295 | #if ENABLE_FEATURE_UDHCP_PORT | 1289 | #if ENABLE_FEATURE_UDHCP_PORT |
1296 | if (opt & OPT_P) { | 1290 | if (opt & OPT_P) { |
1297 | CLIENT_PORT = xatou16(str_P); | 1291 | CLIENT_PORT = xatou16(str_P); |
@@ -1451,10 +1445,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1451 | if (!discover_retries || packet_num < discover_retries) { | 1445 | if (!discover_retries || packet_num < discover_retries) { |
1452 | if (packet_num == 0) { | 1446 | if (packet_num == 0) { |
1453 | change_listen_mode(LISTEN_RAW); | 1447 | change_listen_mode(LISTEN_RAW); |
1454 | xid = random_xid(); | 1448 | client_data.xid = random_xid(); |
1455 | } | 1449 | } |
1456 | /* broadcast */ | 1450 | /* broadcast */ |
1457 | send_discover(xid, requested_ip); | 1451 | send_discover(requested_ip); |
1458 | timeout = discover_timeout; | 1452 | timeout = discover_timeout; |
1459 | packet_num++; | 1453 | packet_num++; |
1460 | continue; | 1454 | continue; |
@@ -1488,7 +1482,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1488 | case REQUESTING: | 1482 | case REQUESTING: |
1489 | if (packet_num < 3) { | 1483 | if (packet_num < 3) { |
1490 | /* send broadcast select packet */ | 1484 | /* send broadcast select packet */ |
1491 | send_select(xid, server_addr, requested_ip); | 1485 | send_select(server_id, requested_ip); |
1492 | timeout = discover_timeout; | 1486 | timeout = discover_timeout; |
1493 | packet_num++; | 1487 | packet_num++; |
1494 | continue; | 1488 | continue; |
@@ -1519,7 +1513,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1519 | * Anyway, it does recover by eventually failing through | 1513 | * Anyway, it does recover by eventually failing through |
1520 | * into INIT_SELECTING state. | 1514 | * into INIT_SELECTING state. |
1521 | */ | 1515 | */ |
1522 | if (send_renew(xid, server_addr, requested_ip) >= 0) { | 1516 | if (send_renew(server_id, requested_ip) >= 0) { |
1523 | timeout = discover_timeout; | 1517 | timeout = discover_timeout; |
1524 | packet_num++; | 1518 | packet_num++; |
1525 | continue; | 1519 | continue; |
@@ -1548,7 +1542,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1548 | * try to find DHCP server using broadcast */ | 1542 | * try to find DHCP server using broadcast */ |
1549 | if (lease_remaining > 0 && packet_num < 3) { | 1543 | if (lease_remaining > 0 && packet_num < 3) { |
1550 | /* send a broadcast renew request */ | 1544 | /* send a broadcast renew request */ |
1551 | send_renew(xid, 0 /*INADDR_ANY*/, requested_ip); | 1545 | send_renew(0 /*INADDR_ANY*/, requested_ip); |
1552 | timeout = discover_timeout; | 1546 | timeout = discover_timeout; |
1553 | packet_num++; | 1547 | packet_num++; |
1554 | continue; | 1548 | continue; |
@@ -1610,7 +1604,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1610 | timeout = 0; | 1604 | timeout = 0; |
1611 | continue; | 1605 | continue; |
1612 | case SIGUSR2: | 1606 | case SIGUSR2: |
1613 | perform_release(server_addr, requested_ip); | 1607 | perform_release(server_id, requested_ip); |
1614 | /* ^^^ switches to LISTEN_NONE */ | 1608 | /* ^^^ switches to LISTEN_NONE */ |
1615 | timeout = INT_MAX; | 1609 | timeout = INT_MAX; |
1616 | continue; | 1610 | continue; |
@@ -1641,9 +1635,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1641 | continue; | 1635 | continue; |
1642 | } | 1636 | } |
1643 | 1637 | ||
1644 | if (packet.xid != xid) { | 1638 | if (packet.xid != client_data.xid) { |
1645 | log1("xid %x (our is %x)%s", | 1639 | log1("xid %x (our is %x)%s", |
1646 | (unsigned)packet.xid, (unsigned)xid, | 1640 | (unsigned)packet.xid, (unsigned)client_data.xid, |
1647 | ", ignoring packet" | 1641 | ", ignoring packet" |
1648 | ); | 1642 | ); |
1649 | continue; | 1643 | continue; |
@@ -1695,13 +1689,13 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1695 | * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all. | 1689 | * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all. |
1696 | * They say ISC DHCP client supports this case. | 1690 | * They say ISC DHCP client supports this case. |
1697 | */ | 1691 | */ |
1698 | server_addr = 0; | 1692 | server_id = 0; |
1699 | temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); | 1693 | temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); |
1700 | if (!temp) { | 1694 | if (!temp) { |
1701 | bb_simple_info_msg("no server ID, using 0.0.0.0"); | 1695 | bb_simple_info_msg("no server ID, using 0.0.0.0"); |
1702 | } else { | 1696 | } else { |
1703 | /* it IS unaligned sometimes, don't "optimize" */ | 1697 | /* it IS unaligned sometimes, don't "optimize" */ |
1704 | move_from_unaligned32(server_addr, temp); | 1698 | move_from_unaligned32(server_id, temp); |
1705 | } | 1699 | } |
1706 | /*xid = packet.xid; - already is */ | 1700 | /*xid = packet.xid; - already is */ |
1707 | temp_addr.s_addr = requested_ip = packet.yiaddr; | 1701 | temp_addr.s_addr = requested_ip = packet.yiaddr; |
@@ -1725,7 +1719,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1725 | 1719 | ||
1726 | change_listen_mode(LISTEN_NONE); | 1720 | change_listen_mode(LISTEN_NONE); |
1727 | 1721 | ||
1728 | temp_addr.s_addr = server_addr; | 1722 | temp_addr.s_addr = server_id; |
1729 | strcpy(server_str, inet_ntoa(temp_addr)); | 1723 | strcpy(server_str, inet_ntoa(temp_addr)); |
1730 | temp_addr.s_addr = packet.yiaddr; | 1724 | temp_addr.s_addr = packet.yiaddr; |
1731 | 1725 | ||
@@ -1772,7 +1766,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1772 | ) { | 1766 | ) { |
1773 | bb_simple_info_msg("offered address is in use " | 1767 | bb_simple_info_msg("offered address is in use " |
1774 | "(got ARP reply), declining"); | 1768 | "(got ARP reply), declining"); |
1775 | send_decline(/*xid,*/ server_addr, packet.yiaddr); | 1769 | client_data.xid = random_xid(); //TODO: can omit? |
1770 | send_decline(server_id, packet.yiaddr); | ||
1776 | 1771 | ||
1777 | if (client_data.state != REQUESTING) | 1772 | if (client_data.state != REQUESTING) |
1778 | d4_run_script_deconfig(); | 1773 | d4_run_script_deconfig(); |
@@ -1807,7 +1802,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1807 | timeout = (unsigned)lease_remaining / 2; | 1802 | timeout = (unsigned)lease_remaining / 2; |
1808 | client_data.state = BOUND; | 1803 | client_data.state = BOUND; |
1809 | /* make future renew packets use different xid */ | 1804 | /* make future renew packets use different xid */ |
1810 | /* xid = random_xid(); ...but why bother? */ | 1805 | /* client_data.xid = random_xid(); ...but why bother? */ |
1811 | packet_num = 0; | 1806 | packet_num = 0; |
1812 | continue; /* back to main loop */ | 1807 | continue; /* back to main loop */ |
1813 | } | 1808 | } |
@@ -1816,20 +1811,14 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1816 | * "wrong" server can reply first, with a NAK. | 1811 | * "wrong" server can reply first, with a NAK. |
1817 | * Do not interpret it as a NAK from "our" server. | 1812 | * Do not interpret it as a NAK from "our" server. |
1818 | */ | 1813 | */ |
1819 | if (server_addr != 0) { | 1814 | uint32_t svid = 0; /* we treat no server id as 0.0.0.0 */ |
1820 | uint32_t svid; | 1815 | uint8_t *temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); |
1821 | uint8_t *temp; | 1816 | if (temp) |
1822 | |||
1823 | temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); | ||
1824 | if (!temp) { | ||
1825 | non_matching_svid: | ||
1826 | log1("received DHCP NAK with wrong" | ||
1827 | " server ID%s", ", ignoring packet"); | ||
1828 | continue; | ||
1829 | } | ||
1830 | move_from_unaligned32(svid, temp); | 1817 | move_from_unaligned32(svid, temp); |
1831 | if (svid != server_addr) | 1818 | if (svid != server_id) { |
1832 | goto non_matching_svid; | 1819 | log1("received DHCP NAK with wrong" |
1820 | " server ID%s", ", ignoring packet"); | ||
1821 | continue; | ||
1833 | } | 1822 | } |
1834 | /* return to init state */ | 1823 | /* return to init state */ |
1835 | change_listen_mode(LISTEN_NONE); | 1824 | change_listen_mode(LISTEN_NONE); |
@@ -1853,7 +1842,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1853 | 1842 | ||
1854 | ret0: | 1843 | ret0: |
1855 | if (opt & OPT_R) /* release on quit */ | 1844 | if (opt & OPT_R) /* release on quit */ |
1856 | perform_release(server_addr, requested_ip); | 1845 | perform_release(server_id, requested_ip); |
1857 | retval = 0; | 1846 | retval = 0; |
1858 | ret: | 1847 | ret: |
1859 | /*if (client_data.pidfile) - remove_pidfile has its own check */ | 1848 | /*if (client_data.pidfile) - remove_pidfile has its own check */ |
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 */ |
diff --git a/networking/vconfig.c b/networking/vconfig.c index 4f1fbe280..7e805be9c 100644 --- a/networking/vconfig.c +++ b/networking/vconfig.c | |||
@@ -20,12 +20,12 @@ | |||
20 | //usage: "COMMAND [OPTIONS]" | 20 | //usage: "COMMAND [OPTIONS]" |
21 | //usage:#define vconfig_full_usage "\n\n" | 21 | //usage:#define vconfig_full_usage "\n\n" |
22 | //usage: "Create and remove virtual ethernet devices\n" | 22 | //usage: "Create and remove virtual ethernet devices\n" |
23 | //usage: "\n add IFACE VLAN_ID" | 23 | //usage: "\n add IFACE VLAN_ID" |
24 | //usage: "\n rem VLAN_NAME" | 24 | //usage: "\n rem VLAN_NAME" |
25 | //usage: "\n set_flag IFACE 0|1 VLAN_QOS" | 25 | //usage: "\n set_flag IFACE 0|1 VLAN_QOS" |
26 | //usage: "\n set_egress_map VLAN_NAME SKB_PRIO VLAN_QOS" | 26 | //usage: "\n set_egress_map VLAN_NAME SKB_PRIO VLAN_QOS" |
27 | //usage: "\n set_ingress_map VLAN_NAME SKB_PRIO VLAN_QOS" | 27 | //usage: "\n set_ingress_map VLAN_NAME SKB_PRIO VLAN_QOS" |
28 | //usage: "\n set_name_type NAME_TYPE" | 28 | //usage: "\n set_name_type NAME_TYPE" |
29 | 29 | ||
30 | #include "libbb.h" | 30 | #include "libbb.h" |
31 | #include <net/if.h> | 31 | #include <net/if.h> |