Skip to content
Permalink
Browse files

net/ip/dhcpv4: Set source IP address in DHCP Request

The source address in unicast DHCPv4 Request packets was found out
to be all zeros address 0.0.0.0. This address is only acceptable if
the destination is a multicast one, where the host in question is
acquiring a DHCP address lease. This is true for the DHCP Discover
and the initial DHCP Request message from the client towards the
server. As subsequent DHCP Request renewal messages are sent as
unicast to the server, the server will drop such packets.

Fix this issue by explicitely specifying what source IP address is
to be used, if none is specified, the all zeros address 0.0.0.0 is
used in multicast addresses. The source address in the other
unicast cases is identical to the 'ciaddr' in the DHCP message.

Signed-off-by: Patrik Flykt <patrik.flykt@intel.com>
  • Loading branch information...
Patrik Flykt authored and galak committed Apr 4, 2019
1 parent fa0083a commit 91ca8aabc89a623b071ad5f833390157f81e8339
Showing with 15 additions and 5 deletions.
  1. +15 −5 subsys/net/ip/dhcpv4.c
@@ -150,15 +150,22 @@ static inline bool dhcpv4_add_sname(struct net_pkt *pkt)
/* Create DHCPv4 message and add options as per message type */
static struct net_pkt *dhcpv4_create_message(struct net_if *iface, u8_t type,
const struct in_addr *ciaddr,
const struct in_addr *src_addr,
const struct in_addr *server_addr,
bool server_id, bool requested_ip)
{
NET_PKT_DATA_ACCESS_DEFINE(dhcp_access, struct dhcp_msg);
const struct in_addr src = INADDR_ANY_INIT;
const struct in_addr *addr;
size_t size = DHCPV4_MESSAGE_SIZE;
struct net_pkt *pkt;
struct dhcp_msg *msg;

if (src_addr == NULL) {
addr = net_ipv4_unspecified_address();
} else {
addr = src_addr;
}

if (server_id) {
size += DHCPV4_OLV_MSG_SERVER_ID;
}
@@ -176,7 +183,7 @@ static struct net_pkt *dhcpv4_create_message(struct net_if *iface, u8_t type,

net_pkt_set_ipv4_ttl(pkt, 0xFF);

if (net_ipv4_create(pkt, &src, server_addr) ||
if (net_ipv4_create(pkt, addr, server_addr) ||
net_udp_create(pkt, htons(DHCPV4_CLIENT_PORT),
htons(DHCPV4_SERVER_PORT))) {
goto fail;
@@ -247,6 +254,7 @@ static u32_t dhcpv4_send_request(struct net_if *iface)
{
const struct in_addr *server_addr = net_ipv4_broadcast_address();
const struct in_addr *ciaddr = NULL;
const struct in_addr *src_addr = NULL;
bool with_server_id = false;
bool with_requested_ip = false;
struct net_pkt *pkt;
@@ -273,6 +281,7 @@ static u32_t dhcpv4_send_request(struct net_if *iface)
ciaddr = &iface->config.dhcpv4.requested_ip;

/* UNICAST the DHCPREQUEST */
src_addr = ciaddr;
server_addr = &iface->config.dhcpv4.server_id;

/* RFC2131 4.4.5 Client MUST NOT include server
@@ -283,13 +292,14 @@ static u32_t dhcpv4_send_request(struct net_if *iface)
/* Since we have an address populate the ciaddr field.
*/
ciaddr = &iface->config.dhcpv4.requested_ip;
src_addr = ciaddr;

break;
}

pkt = dhcpv4_create_message(iface, DHCPV4_MSG_TYPE_REQUEST,
ciaddr, server_addr, with_server_id,
with_requested_ip);
ciaddr, src_addr, server_addr,
with_server_id, with_requested_ip);
if (!pkt) {
goto fail;
}
@@ -333,7 +343,7 @@ static u32_t dhcpv4_send_discover(struct net_if *iface)
iface->config.dhcpv4.xid++;

pkt = dhcpv4_create_message(iface, DHCPV4_MSG_TYPE_DISCOVER,
NULL, net_ipv4_broadcast_address(),
NULL, NULL, net_ipv4_broadcast_address(),
false, false);
if (!pkt) {
goto fail;

0 comments on commit 91ca8aa

Please sign in to comment.
You can’t perform that action at this time.