summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2013-11-03 19:20:54 +0100
committerDenys Vlasenko2013-11-03 19:20:54 +0100
commit8d3efaf35eb9d138114563bba4173c39c1231198 (patch)
tree69b514394ecf1b1f63afbda195359d596c34e7f5
parentb21bc80c7651bfb5a9e001cc220a598cf89b7cfd (diff)
downloadbusybox-8d3efaf35eb9d138114563bba4173c39c1231198.zip
busybox-8d3efaf35eb9d138114563bba4173c39c1231198.tar.gz
udhcpc: allow zero server-id. Closes 6614.
function old new delta bcast_or_ucast - 47 +47 udhcp_send_kernel_packet 271 295 +24 udhcpc_main 2696 2705 +9 udhcp_send_raw_packet 456 459 +3 send_release 90 76 -14 send_renew 105 77 -28 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 3/2 up/down: 83/-42) Total: 41 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/udhcp/dhcpc.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 53d8a5e..8dee916 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -667,6 +667,15 @@ static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet)
client_config.ifindex);
}
+static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server)
+{
+ if (server)
+ return udhcp_send_kernel_packet(packet,
+ ciaddr, CLIENT_PORT,
+ server, SERVER_PORT);
+ return raw_bcast_from_client_config_ifindex(packet);
+}
+
/* Broadcast a DHCP discover packet to the network, with an optionally requested IP */
/* NOINLINE: limit stack usage in caller */
static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
@@ -773,11 +782,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
add_client_options(&packet);
bb_info_msg("Sending renew...");
- if (server)
- return udhcp_send_kernel_packet(&packet,
- ciaddr, CLIENT_PORT,
- server, SERVER_PORT);
- return raw_bcast_from_client_config_ifindex(&packet);
+ return bcast_or_ucast(&packet, ciaddr, server);
}
#if ENABLE_FEATURE_UDHCPC_ARPING
@@ -826,7 +831,11 @@ static int send_release(uint32_t server, uint32_t ciaddr)
udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
bb_info_msg("Sending release...");
- return udhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT);
+ /* Note: normally we unicast here since "server" is not zero.
+ * However, there _are_ people who run "address-less" DHCP servers,
+ * and reportedly ISC dhcp client and Windows allow that.
+ */
+ return bcast_or_ucast(&packet, ciaddr, server);
}
/* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */
@@ -1648,14 +1657,19 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
* might work too.
* "Next server" and router are definitely wrong ones to use, though...
*/
+/* We used to ignore pcakets without DHCP_SERVER_ID.
+ * I've got user reports from people who run "address-less" servers.
+ * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all.
+ * They say ISC DHCP client supports this case.
+ */
+ server_addr = 0;
temp = udhcp_get_option(&packet, DHCP_SERVER_ID);
if (!temp) {
- bb_error_msg("no server ID, ignoring packet");
- continue;
- /* still selecting - this server looks bad */
+ bb_error_msg("no server ID, using 0.0.0.0");
+ } else {
+ /* it IS unaligned sometimes, don't "optimize" */
+ move_from_unaligned32(server_addr, temp);
}
- /* it IS unaligned sometimes, don't "optimize" */
- move_from_unaligned32(server_addr, temp);
/*xid = packet.xid; - already is */
requested_ip = packet.yiaddr;