Skip to content

Commit

Permalink
net/ip/dhcpv4: Set source IP address in DHCP Request
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
pfl authored and nashif committed May 8, 2019
1 parent 16a74a2 commit 6cbdf40
Showing 1 changed file with 15 additions and 5 deletions.
20 changes: 15 additions & 5 deletions subsys/net/ip/dhcpv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 6cbdf40

Please sign in to comment.