From c7dc79e71ddbc1498736a2bbf65a3da179557f83 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 21 Mar 2010 06:15:28 +0100 Subject: udhcpd: untangle incredibly messy handling of DHCPREQUEST Also fixes attacks possible via DHCPDECLINE / DHCPRELEASE function old new delta udhcpd_main 1846 1949 +103 send_renew 105 142 +37 send_NAK 61 - -61 send_ACK 180 - -180 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 2/0 up/down: 140/-241) Total: -101 bytes Signed-off-by: Denys Vlasenko --- networking/udhcp/clientpacket.c | 52 ++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 22 deletions(-) (limited to 'networking/udhcp/clientpacket.c') diff --git a/networking/udhcp/clientpacket.c b/networking/udhcp/clientpacket.c index a255d6e84..a0be42885 100644 --- a/networking/udhcp/clientpacket.c +++ b/networking/udhcp/clientpacket.c @@ -109,24 +109,6 @@ static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet) } -#if ENABLE_FEATURE_UDHCPC_ARPING -/* Broadcast a DHCP decline message */ -int FAST_FUNC send_decline(uint32_t xid, uint32_t server, uint32_t requested) -{ - struct dhcp_packet packet; - - init_packet(&packet, DHCPDECLINE); - packet.xid = xid; - add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); - add_simple_option(packet.options, DHCP_SERVER_ID, server); - - bb_info_msg("Sending decline..."); - - return raw_bcast_from_client_config_ifindex(&packet); -} -#endif - - /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ int FAST_FUNC send_discover(uint32_t xid, uint32_t requested) { @@ -136,11 +118,9 @@ int FAST_FUNC send_discover(uint32_t xid, uint32_t requested) packet.xid = xid; if (requested) add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); - /* Explicitly saying that we want RFC-compliant packets helps * some buggy DHCP servers to NOT send bigger packets */ add_simple_option(packet.options, DHCP_MAX_SIZE, htons(576)); - add_param_req_option(&packet); bb_info_msg("Sending discover..."); @@ -159,7 +139,6 @@ int FAST_FUNC send_select(uint32_t xid, uint32_t server, uint32_t requested) init_packet(&packet, DHCPREQUEST); packet.xid = xid; - add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); add_simple_option(packet.options, DHCP_SERVER_ID, server); add_param_req_option(&packet); @@ -177,17 +156,46 @@ int FAST_FUNC send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) init_packet(&packet, DHCPREQUEST); packet.xid = xid; + /* RFC 2131: + * "3.2 Client-server interaction - reusing a previously + * allocated network address"... + * The client broadcasts a DHCPREQUEST message on its local subnet. + * The message includes the client's network address in the + * REQUESTED_IP option. As the client has not received its + * network address, it MUST NOT fill in the 'ciaddr' field." + * + * FIXME: we seem to not follow this, we do set ciaddr. + */ packet.ciaddr = ciaddr; - + add_simple_option(packet.options, DHCP_REQUESTED_IP, ciaddr); + if (server) + add_simple_option(packet.options, DHCP_SERVER_ID, server); add_param_req_option(&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); +} + + +#if ENABLE_FEATURE_UDHCPC_ARPING +/* Broadcast a DHCP decline message */ +int FAST_FUNC send_decline(uint32_t xid, uint32_t server, uint32_t requested) +{ + struct dhcp_packet packet; + + init_packet(&packet, DHCPDECLINE); + packet.xid = xid; + add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); + add_simple_option(packet.options, DHCP_SERVER_ID, server); + bb_info_msg("Sending decline..."); return raw_bcast_from_client_config_ifindex(&packet); } +#endif /* Unicast a DHCP release message */ -- cgit v1.2.3