diff options
Diffstat (limited to 'networking')
-rw-r--r-- | networking/udhcp/dhcpc.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 53d8a5e08..8dee916d9 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; |