Skip to content

Commit 91ca8aa

Browse files
pflgalak
authored andcommitted
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 <[email protected]>
1 parent fa0083a commit 91ca8aa

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

subsys/net/ip/dhcpv4.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,22 @@ static inline bool dhcpv4_add_sname(struct net_pkt *pkt)
150150
/* Create DHCPv4 message and add options as per message type */
151151
static struct net_pkt *dhcpv4_create_message(struct net_if *iface, u8_t type,
152152
const struct in_addr *ciaddr,
153+
const struct in_addr *src_addr,
153154
const struct in_addr *server_addr,
154155
bool server_id, bool requested_ip)
155156
{
156157
NET_PKT_DATA_ACCESS_DEFINE(dhcp_access, struct dhcp_msg);
157-
const struct in_addr src = INADDR_ANY_INIT;
158+
const struct in_addr *addr;
158159
size_t size = DHCPV4_MESSAGE_SIZE;
159160
struct net_pkt *pkt;
160161
struct dhcp_msg *msg;
161162

163+
if (src_addr == NULL) {
164+
addr = net_ipv4_unspecified_address();
165+
} else {
166+
addr = src_addr;
167+
}
168+
162169
if (server_id) {
163170
size += DHCPV4_OLV_MSG_SERVER_ID;
164171
}
@@ -176,7 +183,7 @@ static struct net_pkt *dhcpv4_create_message(struct net_if *iface, u8_t type,
176183

177184
net_pkt_set_ipv4_ttl(pkt, 0xFF);
178185

179-
if (net_ipv4_create(pkt, &src, server_addr) ||
186+
if (net_ipv4_create(pkt, addr, server_addr) ||
180187
net_udp_create(pkt, htons(DHCPV4_CLIENT_PORT),
181188
htons(DHCPV4_SERVER_PORT))) {
182189
goto fail;
@@ -247,6 +254,7 @@ static u32_t dhcpv4_send_request(struct net_if *iface)
247254
{
248255
const struct in_addr *server_addr = net_ipv4_broadcast_address();
249256
const struct in_addr *ciaddr = NULL;
257+
const struct in_addr *src_addr = NULL;
250258
bool with_server_id = false;
251259
bool with_requested_ip = false;
252260
struct net_pkt *pkt;
@@ -273,6 +281,7 @@ static u32_t dhcpv4_send_request(struct net_if *iface)
273281
ciaddr = &iface->config.dhcpv4.requested_ip;
274282

275283
/* UNICAST the DHCPREQUEST */
284+
src_addr = ciaddr;
276285
server_addr = &iface->config.dhcpv4.server_id;
277286

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

287297
break;
288298
}
289299

290300
pkt = dhcpv4_create_message(iface, DHCPV4_MSG_TYPE_REQUEST,
291-
ciaddr, server_addr, with_server_id,
292-
with_requested_ip);
301+
ciaddr, src_addr, server_addr,
302+
with_server_id, with_requested_ip);
293303
if (!pkt) {
294304
goto fail;
295305
}
@@ -333,7 +343,7 @@ static u32_t dhcpv4_send_discover(struct net_if *iface)
333343
iface->config.dhcpv4.xid++;
334344

335345
pkt = dhcpv4_create_message(iface, DHCPV4_MSG_TYPE_DISCOVER,
336-
NULL, net_ipv4_broadcast_address(),
346+
NULL, NULL, net_ipv4_broadcast_address(),
337347
false, false);
338348
if (!pkt) {
339349
goto fail;

0 commit comments

Comments
 (0)