1 /**
2 * @file
3 * Dynamic Host Configuration Protocol client
4 *
5 * @defgroup dhcp4 DHCPv4
6 * @ingroup ip4
7 * DHCP (IPv4) related functions
8 * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform
9 * with RFC 2131 and RFC 2132.
10 *
11 * @todo:
12 * - Support for interfaces other than Ethernet (SLIP, PPP, ...)
13 *
14 * Options:
15 * @ref DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute)
16 * @ref DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer)
17 *
18 * dhcp_start() starts a DHCP client instance which
19 * configures the interface by obtaining an IP address lease and maintaining it.
20 *
21 * Use dhcp_release() to end the lease and use dhcp_stop()
22 * to remove the DHCP client.
23 *
24 * @see LWIP_HOOK_DHCP_APPEND_OPTIONS
25 * @see LWIP_HOOK_DHCP_PARSE_OPTION
26 *
27 * @see netifapi_dhcp4
28 */
29
30 /*
31 * Copyright (c) 2001-2004 Leon Woestenberg <[email protected]>
32 * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
33 * All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without modification,
36 * are permitted provided that the following conditions are met:
37 *
38 * 1. Redistributions of source code must retain the above copyright notice,
39 * this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright notice,
41 * this list of conditions and the following disclaimer in the documentation
42 * and/or other materials provided with the distribution.
43 * 3. The name of the author may not be used to endorse or promote products
44 * derived from this software without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
47 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
48 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
49 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
50 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
51 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
54 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
55 * OF SUCH DAMAGE.
56 *
57 * This file is part of the lwIP TCP/IP stack.
58 * The Swedish Institute of Computer Science and Adam Dunkels
59 * are specifically granted permission to redistribute this
60 * source code.
61 *
62 * Author: Leon Woestenberg <[email protected]>
63 *
64 */
65
66 #include "lwip/opt.h"
67
68 #if LWIP_IPV4 && LWIP_DHCP /* don't build if not configured for use in lwipopts.h */
69
70 #include "lwip/stats.h"
71 #include "lwip/mem.h"
72 #include "lwip/udp.h"
73 #include "lwip/ip_addr.h"
74 #include "lwip/netif.h"
75 #include "lwip/def.h"
76 #include "lwip/dhcp.h"
77 #include "lwip/autoip.h"
78 #include "lwip/acd.h"
79 #include "lwip/dns.h"
80 #include "lwip/etharp.h"
81 #include "lwip/prot/dhcp.h"
82 #include "lwip/prot/iana.h"
83
84 #include <string.h>
85
86 #ifdef LWIP_HOOK_FILENAME
87 #include LWIP_HOOK_FILENAME
88 #endif
89 #ifndef LWIP_HOOK_DHCP_APPEND_OPTIONS
90 #define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr)
91 #endif
92 #ifndef LWIP_HOOK_DHCP_PARSE_OPTION
93 #define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) do { LWIP_UNUSED_ARG(msg); } while(0)
94 #endif
95
96 /** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using
97 * LWIP_RAND() (this overrides DHCP_GLOBAL_XID)
98 */
99 #ifndef DHCP_CREATE_RAND_XID
100 #define DHCP_CREATE_RAND_XID 1
101 #endif
102
103 /** Default for DHCP_GLOBAL_XID is 0xABCD0000
104 * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g.
105 * \#define DHCP_GLOBAL_XID_HEADER "stdlib.h"
106 * \#define DHCP_GLOBAL_XID rand()
107 */
108 #ifdef DHCP_GLOBAL_XID_HEADER
109 #include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */
110 #endif
111
112 /** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU
113 * MTU is checked to be big enough in dhcp_start */
114 #define DHCP_MAX_MSG_LEN(netif) (netif->mtu)
115 #define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576
116 /** Minimum length for reply before packet is parsed */
117 #define DHCP_MIN_REPLY_LEN 44
118
119 #define REBOOT_TRIES 2
120
121 #if LWIP_DNS && LWIP_DHCP_MAX_DNS_SERVERS
122 #if DNS_MAX_SERVERS > LWIP_DHCP_MAX_DNS_SERVERS
123 #define LWIP_DHCP_PROVIDE_DNS_SERVERS LWIP_DHCP_MAX_DNS_SERVERS
124 #else
125 #define LWIP_DHCP_PROVIDE_DNS_SERVERS DNS_MAX_SERVERS
126 #endif
127 #else
128 #define LWIP_DHCP_PROVIDE_DNS_SERVERS 0
129 #endif
130
131 /** Option handling: options are parsed in dhcp_parse_reply
132 * and saved in an array where other functions can load them from.
133 * This might be moved into the struct dhcp (not necessarily since
134 * lwIP is single-threaded and the array is only used while in recv
135 * callback). */
136 enum dhcp_option_idx {
137 DHCP_OPTION_IDX_OVERLOAD = 0,
138 DHCP_OPTION_IDX_MSG_TYPE,
139 DHCP_OPTION_IDX_SERVER_ID,
140 DHCP_OPTION_IDX_LEASE_TIME,
141 DHCP_OPTION_IDX_T1,
142 DHCP_OPTION_IDX_T2,
143 DHCP_OPTION_IDX_SUBNET_MASK,
144 DHCP_OPTION_IDX_ROUTER,
145 #if LWIP_DHCP_PROVIDE_DNS_SERVERS
146 DHCP_OPTION_IDX_DNS_SERVER,
147 DHCP_OPTION_IDX_DNS_SERVER_LAST = DHCP_OPTION_IDX_DNS_SERVER + LWIP_DHCP_PROVIDE_DNS_SERVERS - 1,
148 #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
149 #if LWIP_DHCP_GET_NTP_SRV
150 DHCP_OPTION_IDX_NTP_SERVER,
151 DHCP_OPTION_IDX_NTP_SERVER_LAST = DHCP_OPTION_IDX_NTP_SERVER + LWIP_DHCP_MAX_NTP_SERVERS - 1,
152 #endif /* LWIP_DHCP_GET_NTP_SRV */
153 DHCP_OPTION_IDX_MAX
154 };
155
156 /** Holds the decoded option values, only valid while in dhcp_recv.
157 @todo: move this into struct dhcp? */
158 u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX];
159 /** Holds a flag which option was received and is contained in dhcp_rx_options_val,
160 only valid while in dhcp_recv.
161 @todo: move this into struct dhcp? */
162 u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX];
163
164 static u8_t dhcp_discover_request_options[] = {
165 DHCP_OPTION_SUBNET_MASK,
166 DHCP_OPTION_ROUTER,
167 DHCP_OPTION_BROADCAST
168 #if LWIP_DHCP_PROVIDE_DNS_SERVERS
169 , DHCP_OPTION_DNS_SERVER
170 #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
171 #if LWIP_DHCP_GET_NTP_SRV
172 , DHCP_OPTION_NTP
173 #endif /* LWIP_DHCP_GET_NTP_SRV */
174 };
175
176 #ifdef DHCP_GLOBAL_XID
177 static u32_t xid;
178 static u8_t xid_initialised;
179 #endif /* DHCP_GLOBAL_XID */
180
181 #define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0)
182 #define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1)
183 #define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0)
184 #define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given)))
185 #define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx])
186 #define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val))
187
188 static struct udp_pcb *dhcp_pcb;
189 static u8_t dhcp_pcb_refcount;
190
191 /* DHCP client state machine functions */
192 static err_t dhcp_discover(struct netif *netif);
193 static err_t dhcp_select(struct netif *netif);
194 static void dhcp_bind(struct netif *netif);
195 #if LWIP_DHCP_DOES_ACD_CHECK
196 static err_t dhcp_decline(struct netif *netif);
197 #endif /* LWIP_DHCP_DOES_ACD_CHECK */
198 static err_t dhcp_rebind(struct netif *netif);
199 static err_t dhcp_reboot(struct netif *netif);
200 static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
201
202 /* receive, unfold, parse and free incoming messages */
203 static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
204
205 /* set the DHCP timers */
206 static void dhcp_timeout(struct netif *netif);
207 static void dhcp_t1_timeout(struct netif *netif);
208 static void dhcp_t2_timeout(struct netif *netif);
209
210 /* build outgoing messages */
211 /* create a DHCP message, fill in common headers */
212 static struct pbuf *dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t *options_out_len);
213 /* add a DHCP option (type, then length in bytes) */
214 static u16_t dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len);
215 /* add option values */
216 static u16_t dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value);
217 static u16_t dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value);
218 static u16_t dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value);
219 #if LWIP_NETIF_HOSTNAME
220 static u16_t dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif);
221 #endif /* LWIP_NETIF_HOSTNAME */
222 /* always add the DHCP options trailer to end and pad */
223 static void dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out);
224
225 /** Ensure DHCP PCB is allocated and bound */
226 static err_t
dhcp_inc_pcb_refcount(void)227 dhcp_inc_pcb_refcount(void)
228 {
229 if (dhcp_pcb_refcount == 0) {
230 LWIP_ASSERT("dhcp_inc_pcb_refcount(): memory leak", dhcp_pcb == NULL);
231
232 /* allocate UDP PCB */
233 dhcp_pcb = udp_new();
234
235 if (dhcp_pcb == NULL) {
236 return ERR_MEM;
237 }
238
239 ip_set_option(dhcp_pcb, SOF_BROADCAST);
240
241 /* set up local and remote port for the pcb -> listen on all interfaces on all src/dest IPs */
242 udp_bind(dhcp_pcb, IP4_ADDR_ANY, LWIP_IANA_PORT_DHCP_CLIENT);
243 udp_connect(dhcp_pcb, IP4_ADDR_ANY, LWIP_IANA_PORT_DHCP_SERVER);
244 udp_recv(dhcp_pcb, dhcp_recv, NULL);
245 }
246
247 dhcp_pcb_refcount++;
248
249 return ERR_OK;
250 }
251
252 /** Free DHCP PCB if the last netif stops using it */
253 static void
dhcp_dec_pcb_refcount(void)254 dhcp_dec_pcb_refcount(void)
255 {
256 LWIP_ASSERT("dhcp_pcb_refcount(): refcount error", (dhcp_pcb_refcount > 0));
257 dhcp_pcb_refcount--;
258
259 if (dhcp_pcb_refcount == 0) {
260 udp_remove(dhcp_pcb);
261 dhcp_pcb = NULL;
262 }
263 }
264
265 /**
266 * Back-off the DHCP client (because of a received NAK response).
267 *
268 * Back-off the DHCP client because of a received NAK. Receiving a
269 * NAK means the client asked for something non-sensible, for
270 * example when it tries to renew a lease obtained on another network.
271 *
272 * We clear any existing set IP address and restart DHCP negotiation
273 * afresh (as per RFC2131 3.2.3).
274 *
275 * @param netif the netif under DHCP control
276 */
277 static void
dhcp_handle_nak(struct netif * netif)278 dhcp_handle_nak(struct netif *netif)
279 {
280 struct dhcp *dhcp = netif_dhcp_data(netif);
281
282 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n",
283 (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
284 /* Change to a defined state - set this before assigning the address
285 to ensure the callback can use dhcp_supplied_address() */
286 dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF);
287 /* remove IP address from interface (must no longer be used, as per RFC2131) */
288 netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
289 /* We can immediately restart discovery */
290 dhcp_discover(netif);
291 }
292
293 #if LWIP_DHCP_DOES_ACD_CHECK
294 /**
295 * Handle conflict information from ACD module
296 *
297 * @param netif network interface to handle conflict information on
298 * @param state acd_callback_enum_t
299 */
300 static void
dhcp_conflict_callback(struct netif * netif,acd_callback_enum_t state)301 dhcp_conflict_callback(struct netif *netif, acd_callback_enum_t state)
302 {
303 struct dhcp *dhcp = netif_dhcp_data(netif);
304 u16_t msecs;
305
306 switch (state) {
307 case ACD_IP_OK:
308 dhcp_bind(netif);
309 break;
310 case ACD_RESTART_CLIENT:
311 /* wait 10s before restarting
312 * According to RFC2131 section 3.1 point 5:
313 * If the client detects that the address is already in use (e.g., through
314 * the use of ARP), the client MUST send a DHCPDECLINE message to the
315 * server and restarts the configuration process. The client SHOULD wait
316 * a minimum of ten seconds before restarting the configuration process to
317 * avoid excessive network traffic in case of looping. */
318 dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF);
319 msecs = 10 * 1000;
320 dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
321 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));
322 break;
323 case ACD_DECLINE:
324 /* remove IP address from interface
325 * (prevents routing from selecting this interface) */
326 netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
327 /* Let the DHCP server know we will not use the address */
328 dhcp_decline(netif);
329 break;
330 default:
331 break;
332 }
333 }
334
335 /**
336 * Checks if the offered IP address is already in use.
337 *
338 * It does this according to the address conflict detection method described in
339 * RFC5227.
340 *
341 * @param netif the netif under DHCP control
342 */
343 static void
dhcp_check(struct netif * netif)344 dhcp_check(struct netif *netif)
345 {
346 struct dhcp *dhcp = netif_dhcp_data(netif);
347
348 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],
349 (s16_t)netif->name[1]));
350 dhcp_set_state(dhcp, DHCP_STATE_CHECKING);
351
352 /* start ACD module */
353 acd_start(netif, &dhcp->acd, dhcp->offered_ip_addr);
354 }
355 #endif /* LWIP_DHCP_DOES_ACD_CHECK */
356
357 /**
358 * Remember the configuration offered by a DHCP server.
359 *
360 * @param netif the netif under DHCP control
361 */
362 static void
dhcp_handle_offer(struct netif * netif,struct dhcp_msg * msg_in)363 dhcp_handle_offer(struct netif *netif, struct dhcp_msg *msg_in)
364 {
365 struct dhcp *dhcp = netif_dhcp_data(netif);
366
367 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",
368 (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
369 /* obtain the server address */
370 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) {
371 dhcp->request_timeout = 0; /* stop timer */
372
373 ip_addr_set_ip4_u32(&dhcp->server_ip_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID)));
374 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n",
375 ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
376 /* remember offered address */
377 ip4_addr_copy(dhcp->offered_ip_addr, msg_in->yiaddr);
378 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n",
379 ip4_addr_get_u32(&dhcp->offered_ip_addr)));
380
381 dhcp_select(netif);
382 } else {
383 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
384 ("dhcp_handle_offer(netif=%p) did not get server ID!\n", (void *)netif));
385 }
386 }
387
388 /**
389 * Select a DHCP server offer out of all offers.
390 *
391 * Simply select the first offer received.
392 *
393 * @param netif the netif under DHCP control
394 * @return lwIP specific error (see error.h)
395 */
396 static err_t
dhcp_select(struct netif * netif)397 dhcp_select(struct netif *netif)
398 {
399 struct dhcp *dhcp;
400 err_t result;
401 u16_t msecs;
402 u8_t i;
403 struct pbuf *p_out;
404 u16_t options_out_len;
405
406 LWIP_ERROR("dhcp_select: netif != NULL", (netif != NULL), return ERR_ARG;);
407 dhcp = netif_dhcp_data(netif);
408 LWIP_ERROR("dhcp_select: dhcp != NULL", (dhcp != NULL), return ERR_VAL;);
409
410 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
411 dhcp_set_state(dhcp, DHCP_STATE_REQUESTING);
412
413 /* create and initialize the DHCP message header */
414 p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
415 if (p_out != NULL) {
416 struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
417 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
418 options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
419
420 /* MUST request the offered IP address */
421 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4);
422 options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
423
424 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4);
425 options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
426
427 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
428 for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
429 options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
430 }
431
432 #if LWIP_NETIF_HOSTNAME
433 options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif);
434 #endif /* LWIP_NETIF_HOSTNAME */
435
436 LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REQUESTING, msg_out, DHCP_REQUEST, &options_out_len);
437 dhcp_option_trailer(options_out_len, msg_out->options, p_out);
438
439 /* send broadcast to any DHCP server */
440 result = udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY);
441 pbuf_free(p_out);
442 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n"));
443 } else {
444 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n"));
445 result = ERR_MEM;
446 }
447 if (dhcp->tries < 255) {
448 dhcp->tries++;
449 }
450 msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000);
451 dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
452 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs));
453 return result;
454 }
455
456 /**
457 * The DHCP timer that checks for lease renewal/rebind timeouts.
458 * Must be called once a minute (see @ref DHCP_COARSE_TIMER_SECS).
459 */
460 void
dhcp_coarse_tmr(void)461 dhcp_coarse_tmr(void)
462 {
463 struct netif *netif;
464 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n"));
465 /* iterate through all network interfaces */
466 NETIF_FOREACH(netif) {
467 /* only act on DHCP configured interfaces */
468 struct dhcp *dhcp = netif_dhcp_data(netif);
469 if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF)) {
470 /* compare lease time to expire timeout */
471 if (dhcp->t0_timeout && (++dhcp->lease_used == dhcp->t0_timeout)) {
472 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t0 timeout\n"));
473 /* this clients' lease time has expired */
474 dhcp_release_and_stop(netif);
475 dhcp_start(netif);
476 /* timer is active (non zero), and triggers (zeroes) now? */
477 } else if (dhcp->t2_rebind_time && (dhcp->t2_rebind_time-- == 1)) {
478 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));
479 /* this clients' rebind timeout triggered */
480 dhcp_t2_timeout(netif);
481 /* timer is active (non zero), and triggers (zeroes) now */
482 } else if (dhcp->t1_renew_time && (dhcp->t1_renew_time-- == 1)) {
483 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));
484 /* this clients' renewal timeout triggered */
485 dhcp_t1_timeout(netif);
486 }
487 }
488 }
489 }
490
491 /**
492 * DHCP transaction timeout handling (this function must be called every 500ms,
493 * see @ref DHCP_FINE_TIMER_MSECS).
494 *
495 * A DHCP server is expected to respond within a short period of time.
496 * This timer checks whether an outstanding DHCP request is timed out.
497 */
498 void
dhcp_fine_tmr(void)499 dhcp_fine_tmr(void)
500 {
501 struct netif *netif;
502 /* loop through netif's */
503 NETIF_FOREACH(netif) {
504 struct dhcp *dhcp = netif_dhcp_data(netif);
505 /* only act on DHCP configured interfaces */
506 if (dhcp != NULL) {
507 /* timer is active (non zero), and is about to trigger now */
508 if (dhcp->request_timeout > 1) {
509 dhcp->request_timeout--;
510 } else if (dhcp->request_timeout == 1) {
511 dhcp->request_timeout--;
512 /* { dhcp->request_timeout == 0 } */
513 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));
514 /* this client's request timeout triggered */
515 dhcp_timeout(netif);
516 }
517 }
518 }
519 }
520
521 /**
522 * A DHCP negotiation transaction, or ARP request, has timed out.
523 *
524 * The timer that was started with the DHCP or ARP request has
525 * timed out, indicating no response was received in time.
526 *
527 * @param netif the netif under DHCP control
528 */
529 static void
dhcp_timeout(struct netif * netif)530 dhcp_timeout(struct netif *netif)
531 {
532 struct dhcp *dhcp = netif_dhcp_data(netif);
533
534 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n"));
535 /* back-off period has passed, or server selection timed out */
536 if ((dhcp->state == DHCP_STATE_BACKING_OFF) || (dhcp->state == DHCP_STATE_SELECTING)) {
537 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n"));
538 dhcp_discover(netif);
539 /* receiving the requested lease timed out */
540 } else if (dhcp->state == DHCP_STATE_REQUESTING) {
541 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));
542 if (dhcp->tries <= 5) {
543 dhcp_select(netif);
544 } else {
545 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
546 dhcp_release_and_stop(netif);
547 dhcp_start(netif);
548 }
549 } else if (dhcp->state == DHCP_STATE_REBOOTING) {
550 if (dhcp->tries < REBOOT_TRIES) {
551 dhcp_reboot(netif);
552 } else {
553 dhcp_discover(netif);
554 }
555 }
556 }
557
558 /**
559 * The renewal period has timed out.
560 *
561 * @param netif the netif under DHCP control
562 */
563 static void
dhcp_t1_timeout(struct netif * netif)564 dhcp_t1_timeout(struct netif *netif)
565 {
566 struct dhcp *dhcp = netif_dhcp_data(netif);
567
568 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n"));
569 if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
570 (dhcp->state == DHCP_STATE_RENEWING)) {
571 /* just retry to renew - note that the rebind timer (t2) will
572 * eventually time-out if renew tries fail. */
573 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
574 ("dhcp_t1_timeout(): must renew\n"));
575 /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
576 DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */
577 dhcp_renew(netif);
578 /* Calculate next timeout */
579 if (((dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) {
580 dhcp->t1_renew_time = (u16_t)((dhcp->t2_timeout - dhcp->lease_used) / 2);
581 }
582 }
583 }
584
585 /**
586 * The rebind period has timed out.
587 *
588 * @param netif the netif under DHCP control
589 */
590 static void
dhcp_t2_timeout(struct netif * netif)591 dhcp_t2_timeout(struct netif *netif)
592 {
593 struct dhcp *dhcp = netif_dhcp_data(netif);
594
595 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n"));
596 if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
597 (dhcp->state == DHCP_STATE_RENEWING) || (dhcp->state == DHCP_STATE_REBINDING)) {
598 /* just retry to rebind */
599 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
600 ("dhcp_t2_timeout(): must rebind\n"));
601 /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
602 DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */
603 dhcp_rebind(netif);
604 /* Calculate next timeout */
605 if (((dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) {
606 dhcp->t2_rebind_time = (u16_t)((dhcp->t0_timeout - dhcp->lease_used) / 2);
607 }
608 }
609 }
610
611 /**
612 * Handle a DHCP ACK packet
613 *
614 * @param netif the netif under DHCP control
615 */
616 static void
dhcp_handle_ack(struct netif * netif,struct dhcp_msg * msg_in)617 dhcp_handle_ack(struct netif *netif, struct dhcp_msg *msg_in)
618 {
619 struct dhcp *dhcp = netif_dhcp_data(netif);
620
621 #if LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV
622 u8_t n;
623 #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV */
624 #if LWIP_DHCP_GET_NTP_SRV
625 ip4_addr_t ntp_server_addrs[LWIP_DHCP_MAX_NTP_SERVERS];
626 #endif
627
628 /* clear options we might not get from the ACK */
629 ip4_addr_set_zero(&dhcp->offered_sn_mask);
630 ip4_addr_set_zero(&dhcp->offered_gw_addr);
631 #if LWIP_DHCP_BOOTP_FILE
632 ip4_addr_set_zero(&dhcp->offered_si_addr);
633 #endif /* LWIP_DHCP_BOOTP_FILE */
634
635 /* lease time given? */
636 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) {
637 /* remember offered lease time */
638 dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME);
639 }
640 /* renewal period given? */
641 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) {
642 /* remember given renewal period */
643 dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1);
644 } else {
645 /* calculate safe periods for renewal */
646 dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;
647 }
648
649 /* renewal period given? */
650 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) {
651 /* remember given rebind period */
652 dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2);
653 } else {
654 /* calculate safe periods for rebinding (offered_t0_lease * 0.875 -> 87.5%)*/
655 dhcp->offered_t2_rebind = (dhcp->offered_t0_lease * 7U) / 8U;
656 }
657
658 /* (y)our internet address */
659 ip4_addr_copy(dhcp->offered_ip_addr, msg_in->yiaddr);
660
661 #if LWIP_DHCP_BOOTP_FILE
662 /* copy boot server address,
663 boot file name copied in dhcp_parse_reply if not overloaded */
664 ip4_addr_copy(dhcp->offered_si_addr, msg_in->siaddr);
665 #endif /* LWIP_DHCP_BOOTP_FILE */
666
667 /* subnet mask given? */
668 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) {
669 /* remember given subnet mask */
670 ip4_addr_set_u32(&dhcp->offered_sn_mask, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)));
671 dhcp->subnet_mask_given = 1;
672 } else {
673 dhcp->subnet_mask_given = 0;
674 }
675
676 /* gateway router */
677 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) {
678 ip4_addr_set_u32(&dhcp->offered_gw_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER)));
679 }
680
681 #if LWIP_DHCP_GET_NTP_SRV
682 /* NTP servers */
683 for (n = 0; (n < LWIP_DHCP_MAX_NTP_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n); n++) {
684 ip4_addr_set_u32(&ntp_server_addrs[n], lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n)));
685 }
686 dhcp_set_ntp_servers(n, ntp_server_addrs);
687 #endif /* LWIP_DHCP_GET_NTP_SRV */
688
689 #if LWIP_DHCP_PROVIDE_DNS_SERVERS
690 /* DNS servers */
691 for (n = 0; (n < LWIP_DHCP_PROVIDE_DNS_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) {
692 ip_addr_t dns_addr;
693 ip_addr_set_ip4_u32_val(dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n)));
694 dns_setserver(n, &dns_addr);
695 }
696 #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
697 }
698
699 /**
700 * @ingroup dhcp4
701 * Set a statically allocated struct dhcp to work with.
702 * Using this prevents dhcp_start to allocate it using mem_malloc.
703 *
704 * @param netif the netif for which to set the struct dhcp
705 * @param dhcp (uninitialised) dhcp struct allocated by the application
706 */
707 void
dhcp_set_struct(struct netif * netif,struct dhcp * dhcp)708 dhcp_set_struct(struct netif *netif, struct dhcp *dhcp)
709 {
710 LWIP_ASSERT_CORE_LOCKED();
711 LWIP_ASSERT("netif != NULL", netif != NULL);
712 LWIP_ASSERT("dhcp != NULL", dhcp != NULL);
713 LWIP_ASSERT("netif already has a struct dhcp set", netif_dhcp_data(netif) == NULL);
714
715 /* clear data structure */
716 memset(dhcp, 0, sizeof(struct dhcp));
717 /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */
718 netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp);
719 }
720
721 /**
722 * @ingroup dhcp4
723 * Removes a struct dhcp from a netif.
724 *
725 * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the
726 * struct dhcp since the memory is passed back to the heap.
727 *
728 * @param netif the netif from which to remove the struct dhcp
729 */
dhcp_cleanup(struct netif * netif)730 void dhcp_cleanup(struct netif *netif)
731 {
732 LWIP_ASSERT_CORE_LOCKED();
733 LWIP_ASSERT("netif != NULL", netif != NULL);
734
735 if (netif_dhcp_data(netif) != NULL) {
736 mem_free(netif_dhcp_data(netif));
737 netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, NULL);
738 }
739 }
740
741 /**
742 * @ingroup dhcp4
743 * Start DHCP negotiation for a network interface.
744 *
745 * If no DHCP client instance was attached to this interface,
746 * a new client is created first. If a DHCP client instance
747 * was already present, it restarts negotiation.
748 *
749 * @param netif The lwIP network interface
750 * @return lwIP error code
751 * - ERR_OK - No error
752 * - ERR_MEM - Out of memory
753 */
754 err_t
dhcp_start(struct netif * netif)755 dhcp_start(struct netif *netif)
756 {
757 struct dhcp *dhcp;
758 err_t result;
759
760 LWIP_ASSERT_CORE_LOCKED();
761 LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;);
762 LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
763 dhcp = netif_dhcp_data(netif);
764 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
765
766 /* check MTU of the netif */
767 if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) {
768 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n"));
769 return ERR_MEM;
770 }
771
772 /* no DHCP client attached yet? */
773 if (dhcp == NULL) {
774 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): mallocing new DHCP client\n"));
775 dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp));
776 if (dhcp == NULL) {
777 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));
778 return ERR_MEM;
779 }
780
781 /* store this dhcp client in the netif */
782 netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp);
783 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp"));
784 /* already has DHCP client attached */
785 } else {
786 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n"));
787
788 if (dhcp->pcb_allocated != 0) {
789 dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */
790 }
791 /* dhcp is cleared below, no need to reset flag*/
792 }
793
794 /* clear data structure */
795 memset(dhcp, 0, sizeof(struct dhcp));
796 /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */
797
798
799 #if LWIP_DHCP_DOES_ACD_CHECK
800 /* add acd struct to list*/
801 acd_add(netif, &dhcp->acd, dhcp_conflict_callback);
802 #endif /* LWIP_DHCP_DOES_ACD_CHECK */
803
804
805 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
806
807 if (dhcp_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP PCB is allocated */
808 return ERR_MEM;
809 }
810 dhcp->pcb_allocated = 1;
811
812 if (!netif_is_link_up(netif)) {
813 /* set state INIT and wait for dhcp_network_changed() to call dhcp_discover() */
814 dhcp_set_state(dhcp, DHCP_STATE_INIT);
815 return ERR_OK;
816 }
817
818 /* (re)start the DHCP negotiation */
819 result = dhcp_discover(netif);
820 if (result != ERR_OK) {
821 /* free resources allocated above */
822 dhcp_release_and_stop(netif);
823 return ERR_MEM;
824 }
825 return result;
826 }
827
828 /**
829 * @ingroup dhcp4
830 * Inform a DHCP server of our manual configuration.
831 *
832 * This informs DHCP servers of our fixed IP address configuration
833 * by sending an INFORM message. It does not involve DHCP address
834 * configuration, it is just here to be nice to the network.
835 *
836 * @param netif The lwIP network interface
837 */
838 void
dhcp_inform(struct netif * netif)839 dhcp_inform(struct netif *netif)
840 {
841 struct dhcp dhcp;
842 struct pbuf *p_out;
843 u16_t options_out_len;
844
845 LWIP_ASSERT_CORE_LOCKED();
846 LWIP_ERROR("netif != NULL", (netif != NULL), return;);
847
848 if (dhcp_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP PCB is allocated */
849 return;
850 }
851
852 memset(&dhcp, 0, sizeof(struct dhcp));
853 dhcp_set_state(&dhcp, DHCP_STATE_INFORMING);
854
855 /* create and initialize the DHCP message header */
856 p_out = dhcp_create_msg(netif, &dhcp, DHCP_INFORM, &options_out_len);
857 if (p_out != NULL) {
858 struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
859 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
860 options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
861
862 LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, &dhcp, DHCP_STATE_INFORMING, msg_out, DHCP_INFORM, &options_out_len);
863 dhcp_option_trailer(options_out_len, msg_out->options, p_out);
864
865 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n"));
866
867 udp_sendto_if(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif);
868
869 pbuf_free(p_out);
870 } else {
871 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n"));
872 }
873
874 dhcp_dec_pcb_refcount(); /* delete DHCP PCB if not needed any more */
875 }
876
877 /** Handle a possible change in the network configuration.
878 *
879 * This enters the REBOOTING state to verify that the currently bound
880 * address is still valid.
881 */
882 void
dhcp_network_changed_link_up(struct netif * netif)883 dhcp_network_changed_link_up(struct netif *netif)
884 {
885 struct dhcp *dhcp = netif_dhcp_data(netif);
886
887 if (!dhcp) {
888 return;
889 }
890 switch (dhcp->state) {
891 case DHCP_STATE_REBINDING:
892 case DHCP_STATE_RENEWING:
893 case DHCP_STATE_BOUND:
894 case DHCP_STATE_REBOOTING:
895 dhcp->tries = 0;
896 dhcp_reboot(netif);
897 break;
898 case DHCP_STATE_OFF:
899 /* stay off */
900 break;
901 default:
902 LWIP_ASSERT("invalid dhcp->state", dhcp->state <= DHCP_STATE_BACKING_OFF);
903 /* INIT/REQUESTING/CHECKING/BACKING_OFF restart with new 'rid' because the
904 state changes, SELECTING: continue with current 'rid' as we stay in the
905 same state */
906 /* ensure we start with short timeouts, even if already discovering */
907 dhcp->tries = 0;
908 dhcp_discover(netif);
909 break;
910 }
911 }
912
913 #if LWIP_DHCP_DOES_ACD_CHECK
914 /**
915 * Decline an offered lease.
916 *
917 * Tell the DHCP server we do not accept the offered address.
918 * One reason to decline the lease is when we find out the address
919 * is already in use by another host (through ARP).
920 *
921 * @param netif the netif under DHCP control
922 */
923 static err_t
dhcp_decline(struct netif * netif)924 dhcp_decline(struct netif *netif)
925 {
926 struct dhcp *dhcp = netif_dhcp_data(netif);
927 err_t result;
928 struct pbuf *p_out;
929 u16_t options_out_len;
930
931 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n"));
932 dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF);
933
934 /* create and initialize the DHCP message header */
935 p_out = dhcp_create_msg(netif, dhcp, DHCP_DECLINE, &options_out_len);
936 if (p_out != NULL) {
937 struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
938 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4);
939 options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
940
941 LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_BACKING_OFF, msg_out, DHCP_DECLINE, &options_out_len);
942 dhcp_option_trailer(options_out_len, msg_out->options, p_out);
943
944 /* per section 4.4.4, broadcast DECLINE messages */
945 result = udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY);
946 pbuf_free(p_out);
947 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n"));
948 } else {
949 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
950 ("dhcp_decline: could not allocate DHCP request\n"));
951 result = ERR_MEM;
952 }
953 return result;
954 }
955 #endif /* LWIP_DHCP_DOES_ACD_CHECK */
956
957
958 /**
959 * Start the DHCP process, discover a DHCP server.
960 *
961 * @param netif the netif under DHCP control
962 */
963 static err_t
dhcp_discover(struct netif * netif)964 dhcp_discover(struct netif *netif)
965 {
966 struct dhcp *dhcp = netif_dhcp_data(netif);
967 err_t result = ERR_OK;
968 u16_t msecs;
969 u8_t i;
970 struct pbuf *p_out;
971 u16_t options_out_len;
972
973 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n"));
974
975 #if LWIP_DHCP_AUTOIP_COOP
976 if (dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES) {
977 autoip_start(netif);
978 }
979 #endif /* LWIP_DHCP_AUTOIP_COOP */
980
981 ip4_addr_set_any(&dhcp->offered_ip_addr);
982 dhcp_set_state(dhcp, DHCP_STATE_SELECTING);
983 /* create and initialize the DHCP message header */
984 p_out = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER, &options_out_len);
985 if (p_out != NULL) {
986 struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
987 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n"));
988
989 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
990 options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
991
992 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
993 for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
994 options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
995 }
996 LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_SELECTING, msg_out, DHCP_DISCOVER, &options_out_len);
997 dhcp_option_trailer(options_out_len, msg_out->options, p_out);
998
999 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER)\n"));
1000 udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY);
1001 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()\n"));
1002 pbuf_free(p_out);
1003 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n"));
1004 } else {
1005 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n"));
1006 }
1007
1008 if (dhcp->tries < 255) {
1009 dhcp->tries++;
1010 }
1011 msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000);
1012 dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
1013 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
1014 return result;
1015 }
1016
1017
1018 /**
1019 * Bind the interface to the offered IP address.
1020 *
1021 * @param netif network interface to bind to the offered address
1022 */
1023 static void
dhcp_bind(struct netif * netif)1024 dhcp_bind(struct netif *netif)
1025 {
1026 u32_t timeout;
1027 struct dhcp *dhcp;
1028 ip4_addr_t sn_mask, gw_addr;
1029 LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;);
1030 dhcp = netif_dhcp_data(netif);
1031 LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;);
1032 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
1033
1034 /* reset time used of lease */
1035 dhcp->lease_used = 0;
1036
1037 if (dhcp->offered_t0_lease != 0xffffffffUL) {
1038 /* set renewal period timer */
1039 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease));
1040 timeout = (dhcp->offered_t0_lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
1041 if (timeout > 0xffff) {
1042 timeout = 0xffff;
1043 }
1044 dhcp->t0_timeout = (u16_t)timeout;
1045 if (dhcp->t0_timeout == 0) {
1046 dhcp->t0_timeout = 1;
1047 }
1048 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease * 1000));
1049 }
1050
1051 /* temporary DHCP lease? */
1052 if (dhcp->offered_t1_renew != 0xffffffffUL) {
1053 /* set renewal period timer */
1054 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));
1055 timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
1056 if (timeout > 0xffff) {
1057 timeout = 0xffff;
1058 }
1059 dhcp->t1_timeout = (u16_t)timeout;
1060 if (dhcp->t1_timeout == 0) {
1061 dhcp->t1_timeout = 1;
1062 }
1063 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew * 1000));
1064 dhcp->t1_renew_time = dhcp->t1_timeout;
1065 }
1066 /* set renewal period timer */
1067 if (dhcp->offered_t2_rebind != 0xffffffffUL) {
1068 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));
1069 timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
1070 if (timeout > 0xffff) {
1071 timeout = 0xffff;
1072 }
1073 dhcp->t2_timeout = (u16_t)timeout;
1074 if (dhcp->t2_timeout == 0) {
1075 dhcp->t2_timeout = 1;
1076 }
1077 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind * 1000));
1078 dhcp->t2_rebind_time = dhcp->t2_timeout;
1079 }
1080
1081 /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */
1082 if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) {
1083 dhcp->t1_timeout = 0;
1084 }
1085
1086 if (dhcp->subnet_mask_given) {
1087 /* copy offered network mask */
1088 ip4_addr_copy(sn_mask, dhcp->offered_sn_mask);
1089 } else {
1090 /* subnet mask not given, choose a safe subnet mask given the network class */
1091 u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr);
1092 if (first_octet <= 127) {
1093 ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL));
1094 } else if (first_octet >= 192) {
1095 ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL));
1096 } else {
1097 ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL));
1098 }
1099 }
1100
1101 ip4_addr_copy(gw_addr, dhcp->offered_gw_addr);
1102 /* gateway address not given? */
1103 if (ip4_addr_isany_val(gw_addr)) {
1104 /* copy network address */
1105 ip4_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask);
1106 /* use first host address on network as gateway */
1107 ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL));
1108 }
1109
1110 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F" SN: 0x%08"X32_F" GW: 0x%08"X32_F"\n",
1111 ip4_addr_get_u32(&dhcp->offered_ip_addr), ip4_addr_get_u32(&sn_mask), ip4_addr_get_u32(&gw_addr)));
1112 /* netif is now bound to DHCP leased address - set this before assigning the address
1113 to ensure the callback can use dhcp_supplied_address() */
1114 dhcp_set_state(dhcp, DHCP_STATE_BOUND);
1115
1116 netif_set_addr(netif, &dhcp->offered_ip_addr, &sn_mask, &gw_addr);
1117 /* interface is used by routing now that an address is set */
1118 }
1119
1120 /**
1121 * @ingroup dhcp4
1122 * Renew an existing DHCP lease at the involved DHCP server.
1123 *
1124 * @param netif network interface which must renew its lease
1125 */
1126 err_t
dhcp_renew(struct netif * netif)1127 dhcp_renew(struct netif *netif)
1128 {
1129 struct dhcp *dhcp = netif_dhcp_data(netif);
1130 err_t result;
1131 u16_t msecs;
1132 u8_t i;
1133 struct pbuf *p_out;
1134 u16_t options_out_len;
1135
1136 LWIP_ASSERT_CORE_LOCKED();
1137 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n"));
1138 dhcp_set_state(dhcp, DHCP_STATE_RENEWING);
1139
1140 /* create and initialize the DHCP message header */
1141 p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
1142 if (p_out != NULL) {
1143 struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
1144 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
1145 options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
1146
1147 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
1148 for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
1149 options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
1150 }
1151
1152 #if LWIP_NETIF_HOSTNAME
1153 options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif);
1154 #endif /* LWIP_NETIF_HOSTNAME */
1155
1156 LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_RENEWING, msg_out, DHCP_REQUEST, &options_out_len);
1157 dhcp_option_trailer(options_out_len, msg_out->options, p_out);
1158
1159 result = udp_sendto_if(dhcp_pcb, p_out, &dhcp->server_ip_addr, LWIP_IANA_PORT_DHCP_SERVER, netif);
1160 pbuf_free(p_out);
1161
1162 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n"));
1163 } else {
1164 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n"));
1165 result = ERR_MEM;
1166 }
1167 if (dhcp->tries < 255) {
1168 dhcp->tries++;
1169 }
1170 /* back-off on retries, but to a maximum of 20 seconds */
1171 msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000);
1172 dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
1173 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs));
1174 return result;
1175 }
1176
1177 /**
1178 * Rebind with a DHCP server for an existing DHCP lease.
1179 *
1180 * @param netif network interface which must rebind with a DHCP server
1181 */
1182 static err_t
dhcp_rebind(struct netif * netif)1183 dhcp_rebind(struct netif *netif)
1184 {
1185 struct dhcp *dhcp = netif_dhcp_data(netif);
1186 err_t result;
1187 u16_t msecs;
1188 u8_t i;
1189 struct pbuf *p_out;
1190 u16_t options_out_len;
1191
1192 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n"));
1193 dhcp_set_state(dhcp, DHCP_STATE_REBINDING);
1194
1195 /* create and initialize the DHCP message header */
1196 p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
1197 if (p_out != NULL) {
1198 struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
1199 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
1200 options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
1201
1202 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
1203 for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
1204 options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
1205 }
1206
1207 #if LWIP_NETIF_HOSTNAME
1208 options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif);
1209 #endif /* LWIP_NETIF_HOSTNAME */
1210
1211 LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REBINDING, msg_out, DHCP_DISCOVER, &options_out_len);
1212 dhcp_option_trailer(options_out_len, msg_out->options, p_out);
1213
1214 /* broadcast to server */
1215 result = udp_sendto_if(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif);
1216 pbuf_free(p_out);
1217 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n"));
1218 } else {
1219 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n"));
1220 result = ERR_MEM;
1221 }
1222 if (dhcp->tries < 255) {
1223 dhcp->tries++;
1224 }
1225 msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000);
1226 dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
1227 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs));
1228 return result;
1229 }
1230
1231 /**
1232 * Enter REBOOTING state to verify an existing lease
1233 *
1234 * @param netif network interface which must reboot
1235 */
1236 static err_t
dhcp_reboot(struct netif * netif)1237 dhcp_reboot(struct netif *netif)
1238 {
1239 struct dhcp *dhcp = netif_dhcp_data(netif);
1240 err_t result;
1241 u16_t msecs;
1242 u8_t i;
1243 struct pbuf *p_out;
1244 u16_t options_out_len;
1245
1246 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n"));
1247 dhcp_set_state(dhcp, DHCP_STATE_REBOOTING);
1248
1249 /* create and initialize the DHCP message header */
1250 p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
1251 if (p_out != NULL) {
1252 struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
1253 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
1254 options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN_MIN_REQUIRED);
1255
1256 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4);
1257 options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
1258
1259 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
1260 for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
1261 options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
1262 }
1263
1264 #if LWIP_NETIF_HOSTNAME
1265 options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif);
1266 #endif /* LWIP_NETIF_HOSTNAME */
1267
1268 LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REBOOTING, msg_out, DHCP_REQUEST, &options_out_len);
1269 dhcp_option_trailer(options_out_len, msg_out->options, p_out);
1270
1271 /* broadcast to server */
1272 result = udp_sendto_if(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif);
1273 pbuf_free(p_out);
1274 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n"));
1275 } else {
1276 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n"));
1277 result = ERR_MEM;
1278 }
1279 if (dhcp->tries < 255) {
1280 dhcp->tries++;
1281 }
1282 msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000);
1283 dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
1284 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs));
1285 return result;
1286 }
1287
1288 /**
1289 * @ingroup dhcp4
1290 * Release a DHCP lease and stop DHCP statemachine (and AUTOIP if LWIP_DHCP_AUTOIP_COOP).
1291 *
1292 * @param netif network interface
1293 */
1294 void
dhcp_release_and_stop(struct netif * netif)1295 dhcp_release_and_stop(struct netif *netif)
1296 {
1297 struct dhcp *dhcp = netif_dhcp_data(netif);
1298 ip_addr_t server_ip_addr;
1299
1300 LWIP_ASSERT_CORE_LOCKED();
1301 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release_and_stop()\n"));
1302 if (dhcp == NULL) {
1303 return;
1304 }
1305
1306 /* already off? -> nothing to do */
1307 if (dhcp->state == DHCP_STATE_OFF) {
1308 return;
1309 }
1310
1311 ip_addr_copy(server_ip_addr, dhcp->server_ip_addr);
1312
1313 /* clean old DHCP offer */
1314 ip_addr_set_zero_ip4(&dhcp->server_ip_addr);
1315 ip4_addr_set_zero(&dhcp->offered_ip_addr);
1316 ip4_addr_set_zero(&dhcp->offered_sn_mask);
1317 ip4_addr_set_zero(&dhcp->offered_gw_addr);
1318 #if LWIP_DHCP_BOOTP_FILE
1319 ip4_addr_set_zero(&dhcp->offered_si_addr);
1320 #endif /* LWIP_DHCP_BOOTP_FILE */
1321 dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
1322 dhcp->t1_renew_time = dhcp->t2_rebind_time = dhcp->lease_used = dhcp->t0_timeout = 0;
1323
1324 /* send release message when current IP was assigned via DHCP */
1325 if (dhcp_supplied_address(netif)) {
1326 /* create and initialize the DHCP message header */
1327 struct pbuf *p_out;
1328 u16_t options_out_len;
1329 p_out = dhcp_create_msg(netif, dhcp, DHCP_RELEASE, &options_out_len);
1330 if (p_out != NULL) {
1331 struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
1332 options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4);
1333 options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&server_ip_addr))));
1334
1335 LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, dhcp->state, msg_out, DHCP_RELEASE, &options_out_len);
1336 dhcp_option_trailer(options_out_len, msg_out->options, p_out);
1337
1338 udp_sendto_if(dhcp_pcb, p_out, &server_ip_addr, LWIP_IANA_PORT_DHCP_SERVER, netif);
1339 pbuf_free(p_out);
1340 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_STATE_OFF\n"));
1341 } else {
1342 /* sending release failed, but that's not a problem since the correct behaviour of dhcp does not rely on release */
1343 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n"));
1344 }
1345
1346 /* remove IP address from interface (prevents routing from selecting this interface) */
1347 netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
1348 }
1349
1350 dhcp_set_state(dhcp, DHCP_STATE_OFF);
1351
1352 if (dhcp->pcb_allocated != 0) {
1353 dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */
1354 dhcp->pcb_allocated = 0;
1355 }
1356 }
1357
1358 /**
1359 * @ingroup dhcp4
1360 * This function calls dhcp_release_and_stop() internally.
1361 * @deprecated Use dhcp_release_and_stop() instead.
1362 */
1363 err_t
dhcp_release(struct netif * netif)1364 dhcp_release(struct netif *netif)
1365 {
1366 dhcp_release_and_stop(netif);
1367 return ERR_OK;
1368 }
1369
1370 /**
1371 * @ingroup dhcp4
1372 * This function calls dhcp_release_and_stop() internally.
1373 * @deprecated Use dhcp_release_and_stop() instead.
1374 */
1375 void
dhcp_stop(struct netif * netif)1376 dhcp_stop(struct netif *netif)
1377 {
1378 dhcp_release_and_stop(netif);
1379 }
1380
1381 /*
1382 * Set the DHCP state of a DHCP client.
1383 *
1384 * If the state changed, reset the number of tries.
1385 */
1386 static void
dhcp_set_state(struct dhcp * dhcp,u8_t new_state)1387 dhcp_set_state(struct dhcp *dhcp, u8_t new_state)
1388 {
1389 if (new_state != dhcp->state) {
1390 dhcp->state = new_state;
1391 dhcp->tries = 0;
1392 dhcp->request_timeout = 0;
1393 }
1394 }
1395
1396 /*
1397 * Concatenate an option type and length field to the outgoing
1398 * DHCP message.
1399 *
1400 */
1401 static u16_t
dhcp_option(u16_t options_out_len,u8_t * options,u8_t option_type,u8_t option_len)1402 dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len)
1403 {
1404 LWIP_ASSERT("dhcp_option: options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN);
1405 options[options_out_len++] = option_type;
1406 options[options_out_len++] = option_len;
1407 return options_out_len;
1408 }
1409 /*
1410 * Concatenate a single byte to the outgoing DHCP message.
1411 *
1412 */
1413 static u16_t
dhcp_option_byte(u16_t options_out_len,u8_t * options,u8_t value)1414 dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value)
1415 {
1416 LWIP_ASSERT("dhcp_option_byte: options_out_len < DHCP_OPTIONS_LEN", options_out_len < DHCP_OPTIONS_LEN);
1417 options[options_out_len++] = value;
1418 return options_out_len;
1419 }
1420
1421 static u16_t
dhcp_option_short(u16_t options_out_len,u8_t * options,u16_t value)1422 dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value)
1423 {
1424 LWIP_ASSERT("dhcp_option_short: options_out_len + 2 <= DHCP_OPTIONS_LEN", options_out_len + 2U <= DHCP_OPTIONS_LEN);
1425 options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
1426 options[options_out_len++] = (u8_t) (value & 0x00ffU);
1427 return options_out_len;
1428 }
1429
1430 static u16_t
dhcp_option_long(u16_t options_out_len,u8_t * options,u32_t value)1431 dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value)
1432 {
1433 LWIP_ASSERT("dhcp_option_long: options_out_len + 4 <= DHCP_OPTIONS_LEN", options_out_len + 4U <= DHCP_OPTIONS_LEN);
1434 options[options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24);
1435 options[options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16);
1436 options[options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8);
1437 options[options_out_len++] = (u8_t)((value & 0x000000ffUL));
1438 return options_out_len;
1439 }
1440
1441 #if LWIP_NETIF_HOSTNAME
1442 static u16_t
dhcp_option_hostname(u16_t options_out_len,u8_t * options,struct netif * netif)1443 dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif)
1444 {
1445 if (netif->hostname != NULL) {
1446 size_t namelen = strlen(netif->hostname);
1447 if (namelen > 0) {
1448 size_t len;
1449 const char *p = netif->hostname;
1450 /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME
1451 and 1 byte for trailer) */
1452 size_t available = DHCP_OPTIONS_LEN - options_out_len - 3;
1453 LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available);
1454 len = LWIP_MIN(namelen, available);
1455 LWIP_ASSERT("DHCP: hostname is too long!", len <= 0xFF);
1456 options_out_len = dhcp_option(options_out_len, options, DHCP_OPTION_HOSTNAME, (u8_t)len);
1457 while (len--) {
1458 options_out_len = dhcp_option_byte(options_out_len, options, *p++);
1459 }
1460 }
1461 }
1462 return options_out_len;
1463 }
1464 #endif /* LWIP_NETIF_HOSTNAME */
1465
1466 /**
1467 * Extract the DHCP message and the DHCP options.
1468 *
1469 * Extract the DHCP message and the DHCP options, each into a contiguous
1470 * piece of memory. As a DHCP message is variable sized by its options,
1471 * and also allows overriding some fields for options, the easy approach
1472 * is to first unfold the options into a contiguous piece of memory, and
1473 * use that further on.
1474 *
1475 */
1476 static err_t
dhcp_parse_reply(struct pbuf * p,struct dhcp * dhcp)1477 dhcp_parse_reply(struct pbuf *p, struct dhcp *dhcp)
1478 {
1479 u8_t *options;
1480 u16_t offset;
1481 u16_t offset_max;
1482 u16_t options_offset;
1483 u16_t options_idx;
1484 u16_t options_idx_max;
1485 struct pbuf *q;
1486 int parse_file_as_options = 0;
1487 int parse_sname_as_options = 0;
1488 struct dhcp_msg *msg_in;
1489 #if LWIP_DHCP_BOOTP_FILE
1490 int file_overloaded = 0;
1491 #endif
1492
1493 LWIP_UNUSED_ARG(dhcp);
1494
1495 /* clear received options */
1496 dhcp_clear_all_options(dhcp);
1497 /* check that beginning of dhcp_msg (up to and including chaddr) is in first pbuf */
1498 if (p->len < DHCP_SNAME_OFS) {
1499 return ERR_BUF;
1500 }
1501 msg_in = (struct dhcp_msg *)p->payload;
1502 #if LWIP_DHCP_BOOTP_FILE
1503 /* clear boot file name */
1504 dhcp->boot_file_name[0] = 0;
1505 #endif /* LWIP_DHCP_BOOTP_FILE */
1506
1507 /* parse options */
1508
1509 /* start with options field */
1510 options_idx = DHCP_OPTIONS_OFS;
1511 /* parse options to the end of the received packet */
1512 options_idx_max = p->tot_len;
1513 again:
1514 q = p;
1515 options_offset = options_idx;
1516 while ((q != NULL) && (options_idx >= q->len)) {
1517 options_idx = (u16_t)(options_idx - q->len);
1518 options_idx_max = (u16_t)(options_idx_max - q->len);
1519 q = q->next;
1520 }
1521 if (q == NULL) {
1522 return ERR_BUF;
1523 }
1524 offset = options_idx;
1525 offset_max = options_idx_max;
1526 options = (u8_t *)q->payload;
1527 /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */
1528 while ((q != NULL) && (offset < offset_max) && (options[offset] != DHCP_OPTION_END)) {
1529 u8_t op = options[offset];
1530 u8_t len;
1531 u8_t decode_len = 0;
1532 int decode_idx = -1;
1533 u16_t val_offset = (u16_t)(offset + 2);
1534 if (val_offset < offset) {
1535 /* overflow */
1536 return ERR_BUF;
1537 }
1538 /* len byte might be in the next pbuf */
1539 if ((offset + 1) < q->len) {
1540 len = options[offset + 1];
1541 } else {
1542 len = (q->next != NULL ? ((u8_t *)q->next->payload)[0] : 0);
1543 }
1544 /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */
1545 decode_len = len;
1546 switch (op) {
1547 /* case(DHCP_OPTION_END): handled above */
1548 case (DHCP_OPTION_PAD):
1549 /* special option: no len encoded */
1550 decode_len = len = 0;
1551 /* will be increased below */
1552 break;
1553 case (DHCP_OPTION_SUBNET_MASK):
1554 LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
1555 decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
1556 break;
1557 case (DHCP_OPTION_ROUTER):
1558 decode_len = 4; /* only copy the first given router */
1559 LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
1560 decode_idx = DHCP_OPTION_IDX_ROUTER;
1561 break;
1562 #if LWIP_DHCP_PROVIDE_DNS_SERVERS
1563 case (DHCP_OPTION_DNS_SERVER):
1564 /* special case: there might be more than one server */
1565 LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
1566 /* limit number of DNS servers */
1567 decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS);
1568 LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
1569 decode_idx = DHCP_OPTION_IDX_DNS_SERVER;
1570 break;
1571 #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
1572 case (DHCP_OPTION_LEASE_TIME):
1573 LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
1574 decode_idx = DHCP_OPTION_IDX_LEASE_TIME;
1575 break;
1576 #if LWIP_DHCP_GET_NTP_SRV
1577 case (DHCP_OPTION_NTP):
1578 /* special case: there might be more than one server */
1579 LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
1580 /* limit number of NTP servers */
1581 decode_len = LWIP_MIN(len, 4 * LWIP_DHCP_MAX_NTP_SERVERS);
1582 LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
1583 decode_idx = DHCP_OPTION_IDX_NTP_SERVER;
1584 break;
1585 #endif /* LWIP_DHCP_GET_NTP_SRV*/
1586 case (DHCP_OPTION_OVERLOAD):
1587 LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
1588 /* decode overload only in options, not in file/sname: invalid packet */
1589 LWIP_ERROR("overload in file/sname", options_offset == DHCP_OPTIONS_OFS, return ERR_VAL;);
1590 decode_idx = DHCP_OPTION_IDX_OVERLOAD;
1591 break;
1592 case (DHCP_OPTION_MESSAGE_TYPE):
1593 LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
1594 decode_idx = DHCP_OPTION_IDX_MSG_TYPE;
1595 break;
1596 case (DHCP_OPTION_SERVER_ID):
1597 LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
1598 decode_idx = DHCP_OPTION_IDX_SERVER_ID;
1599 break;
1600 case (DHCP_OPTION_T1):
1601 LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
1602 decode_idx = DHCP_OPTION_IDX_T1;
1603 break;
1604 case (DHCP_OPTION_T2):
1605 LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
1606 decode_idx = DHCP_OPTION_IDX_T2;
1607 break;
1608 default:
1609 decode_len = 0;
1610 LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", (u16_t)op));
1611 LWIP_HOOK_DHCP_PARSE_OPTION(ip_current_netif(), dhcp, dhcp->state, msg_in,
1612 dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) ? (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) : 0,
1613 op, len, q, val_offset);
1614 break;
1615 }
1616 if (op == DHCP_OPTION_PAD) {
1617 offset++;
1618 } else {
1619 if (offset + len + 2 > 0xFFFF) {
1620 /* overflow */
1621 return ERR_BUF;
1622 }
1623 offset = (u16_t)(offset + len + 2);
1624 if (decode_len > 0) {
1625 u32_t value = 0;
1626 u16_t copy_len;
1627 decode_next:
1628 LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX);
1629 if (!dhcp_option_given(dhcp, decode_idx)) {
1630 copy_len = LWIP_MIN(decode_len, 4);
1631 if (pbuf_copy_partial(q, &value, copy_len, val_offset) != copy_len) {
1632 return ERR_BUF;
1633 }
1634 if (decode_len > 4) {
1635 /* decode more than one u32_t */
1636 u16_t next_val_offset;
1637 LWIP_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
1638 dhcp_got_option(dhcp, decode_idx);
1639 dhcp_set_option_value(dhcp, decode_idx, lwip_htonl(value));
1640 decode_len = (u8_t)(decode_len - 4);
1641 next_val_offset = (u16_t)(val_offset + 4);
1642 if (next_val_offset < val_offset) {
1643 /* overflow */
1644 return ERR_BUF;
1645 }
1646 val_offset = next_val_offset;
1647 decode_idx++;
1648 goto decode_next;
1649 } else if (decode_len == 4) {
1650 value = lwip_ntohl(value);
1651 } else {
1652 LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
1653 value = ((u8_t *)&value)[0];
1654 }
1655 dhcp_got_option(dhcp, decode_idx);
1656 dhcp_set_option_value(dhcp, decode_idx, value);
1657 }
1658 }
1659 }
1660 if (offset >= q->len) {
1661 offset = (u16_t)(offset - q->len);
1662 offset_max = (u16_t)(offset_max - q->len);
1663 if (offset < offset_max) {
1664 q = q->next;
1665 LWIP_ERROR("next pbuf was null", q != NULL, return ERR_VAL;);
1666 options = (u8_t *)q->payload;
1667 } else {
1668 /* We've run out of bytes, probably no end marker. Don't proceed. */
1669 return ERR_BUF;
1670 }
1671 }
1672 }
1673 /* is this an overloaded message? */
1674 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) {
1675 u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD);
1676 dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD);
1677 if (overload == DHCP_OVERLOAD_FILE) {
1678 parse_file_as_options = 1;
1679 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n"));
1680 } else if (overload == DHCP_OVERLOAD_SNAME) {
1681 parse_sname_as_options = 1;
1682 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n"));
1683 } else if (overload == DHCP_OVERLOAD_SNAME_FILE) {
1684 parse_sname_as_options = 1;
1685 parse_file_as_options = 1;
1686 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n"));
1687 } else {
1688 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload));
1689 }
1690 }
1691 if (parse_file_as_options) {
1692 /* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */
1693 parse_file_as_options = 0;
1694 options_idx = DHCP_FILE_OFS;
1695 options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN;
1696 #if LWIP_DHCP_BOOTP_FILE
1697 file_overloaded = 1;
1698 #endif
1699 goto again;
1700 } else if (parse_sname_as_options) {
1701 parse_sname_as_options = 0;
1702 options_idx = DHCP_SNAME_OFS;
1703 options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN;
1704 goto again;
1705 }
1706 #if LWIP_DHCP_BOOTP_FILE
1707 if (!file_overloaded) {
1708 /* only do this for ACK messages */
1709 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) &&
1710 (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
1711 /* copy bootp file name, don't care for sname (server hostname) */
1712 if (pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS) != (DHCP_FILE_LEN-1)) {
1713 return ERR_BUF;
1714 }
1715 /* make sure the string is really NULL-terminated */
1716 dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0;
1717 }
1718 #endif /* LWIP_DHCP_BOOTP_FILE */
1719 return ERR_OK;
1720 }
1721
1722 /**
1723 * If an incoming DHCP message is in response to us, then trigger the state machine
1724 */
1725 static void
dhcp_recv(void * arg,struct udp_pcb * pcb,struct pbuf * p,const ip_addr_t * addr,u16_t port)1726 dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
1727 {
1728 struct netif *netif = ip_current_input_netif();
1729 struct dhcp *dhcp = netif_dhcp_data(netif);
1730 struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload;
1731 u8_t msg_type;
1732 u8_t i;
1733 struct dhcp_msg *msg_in;
1734
1735 LWIP_UNUSED_ARG(arg);
1736
1737 /* Caught DHCP message from netif that does not have DHCP enabled? -> not interested */
1738 if ((dhcp == NULL) || (dhcp->pcb_allocated == 0)) {
1739 goto free_pbuf_and_return;
1740 }
1741
1742 LWIP_ASSERT("invalid server address type", IP_IS_V4(addr));
1743
1744 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void *)p,
1745 ip4_addr1_16(ip_2_ip4(addr)), ip4_addr2_16(ip_2_ip4(addr)), ip4_addr3_16(ip_2_ip4(addr)), ip4_addr4_16(ip_2_ip4(addr)), port));
1746 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
1747 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
1748 /* prevent warnings about unused arguments */
1749 LWIP_UNUSED_ARG(pcb);
1750 LWIP_UNUSED_ARG(addr);
1751 LWIP_UNUSED_ARG(port);
1752
1753 if (p->len < DHCP_MIN_REPLY_LEN) {
1754 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message or pbuf too short\n"));
1755 goto free_pbuf_and_return;
1756 }
1757
1758 if (reply_msg->op != DHCP_BOOTREPLY) {
1759 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op));
1760 goto free_pbuf_and_return;
1761 }
1762 /* iterate through hardware address and match against DHCP message */
1763 for (i = 0; i < netif->hwaddr_len && i < LWIP_MIN(DHCP_CHADDR_LEN, NETIF_MAX_HWADDR_LEN); i++) {
1764 if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
1765 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
1766 ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",
1767 (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));
1768 goto free_pbuf_and_return;
1769 }
1770 }
1771 /* match transaction ID against what we expected */
1772 if (lwip_ntohl(reply_msg->xid) != dhcp->xid) {
1773 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
1774 ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n", lwip_ntohl(reply_msg->xid), dhcp->xid));
1775 goto free_pbuf_and_return;
1776 }
1777 /* option fields could be unfold? */
1778 if (dhcp_parse_reply(p, dhcp) != ERR_OK) {
1779 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
1780 ("problem unfolding DHCP message - too short on memory?\n"));
1781 goto free_pbuf_and_return;
1782 }
1783
1784 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));
1785 /* obtain pointer to DHCP message type */
1786 if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) {
1787 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));
1788 goto free_pbuf_and_return;
1789 }
1790
1791 msg_in = (struct dhcp_msg *)p->payload;
1792 /* read DHCP message type */
1793 msg_type = (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE);
1794 /* message type is DHCP ACK? */
1795 if (msg_type == DHCP_ACK) {
1796 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n"));
1797 /* in requesting state or just reconnected to the network? */
1798 if ((dhcp->state == DHCP_STATE_REQUESTING) ||
1799 (dhcp->state == DHCP_STATE_REBOOTING)) {
1800 dhcp_handle_ack(netif, msg_in);
1801 #if LWIP_DHCP_DOES_ACD_CHECK
1802 if ((netif->flags & NETIF_FLAG_ETHARP) != 0) {
1803 /* check if the acknowledged lease address is already in use */
1804 dhcp_check(netif);
1805 } else {
1806 /* bind interface to the acknowledged lease address */
1807 dhcp_bind(netif);
1808 }
1809 #else
1810 /* bind interface to the acknowledged lease address */
1811 dhcp_bind(netif);
1812 #endif
1813 }
1814 /* already bound to the given lease address and using it? */
1815 else if ((dhcp->state == DHCP_STATE_REBINDING) ||
1816 (dhcp->state == DHCP_STATE_RENEWING)) {
1817 dhcp_handle_ack(netif, msg_in);
1818 dhcp_bind(netif);
1819 }
1820 }
1821 /* received a DHCP_NAK in appropriate state? */
1822 else if ((msg_type == DHCP_NAK) &&
1823 ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) ||
1824 (dhcp->state == DHCP_STATE_REBINDING) || (dhcp->state == DHCP_STATE_RENEWING ))) {
1825 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n"));
1826 dhcp_handle_nak(netif);
1827 }
1828 /* received a DHCP_OFFER in DHCP_STATE_SELECTING state? */
1829 else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_STATE_SELECTING)) {
1830 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_STATE_SELECTING state\n"));
1831 /* remember offered lease */
1832 dhcp_handle_offer(netif, msg_in);
1833 }
1834
1835 free_pbuf_and_return:
1836 pbuf_free(p);
1837 }
1838
1839 /**
1840 * Create a DHCP request, fill in common headers
1841 *
1842 * @param netif the netif under DHCP control
1843 * @param dhcp dhcp control struct
1844 * @param message_type message type of the request
1845 */
1846 static struct pbuf *
dhcp_create_msg(struct netif * netif,struct dhcp * dhcp,u8_t message_type,u16_t * options_out_len)1847 dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t *options_out_len)
1848 {
1849 u16_t i;
1850 struct pbuf *p_out;
1851 struct dhcp_msg *msg_out;
1852 u16_t options_out_len_loc;
1853
1854 #ifndef DHCP_GLOBAL_XID
1855 /** default global transaction identifier starting value (easy to match
1856 * with a packet analyser). We simply increment for each new request.
1857 * Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one
1858 * at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */
1859 #if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
1860 static u32_t xid;
1861 #else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
1862 static u32_t xid = 0xABCD0000;
1863 #endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
1864 #else
1865 if (!xid_initialised) {
1866 xid = DHCP_GLOBAL_XID;
1867 xid_initialised = !xid_initialised;
1868 }
1869 #endif
1870 LWIP_ERROR("dhcp_create_msg: netif != NULL", (netif != NULL), return NULL;);
1871 LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return NULL;);
1872 p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
1873 if (p_out == NULL) {
1874 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
1875 ("dhcp_create_msg(): could not allocate pbuf\n"));
1876 return NULL;
1877 }
1878 LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg",
1879 (p_out->len >= sizeof(struct dhcp_msg)));
1880
1881 /* DHCP_REQUEST should reuse 'xid' from DHCPOFFER */
1882 if ((message_type != DHCP_REQUEST) || (dhcp->state == DHCP_STATE_REBOOTING)) {
1883 /* reuse transaction identifier in retransmissions */
1884 if (dhcp->tries == 0) {
1885 #if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
1886 xid = LWIP_RAND();
1887 #else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
1888 xid++;
1889 #endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
1890 }
1891 dhcp->xid = xid;
1892 }
1893 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
1894 ("transaction id xid(%"X32_F")\n", xid));
1895
1896 msg_out = (struct dhcp_msg *)p_out->payload;
1897 memset(msg_out, 0, sizeof(struct dhcp_msg));
1898
1899 msg_out->op = DHCP_BOOTREQUEST;
1900 /* @todo: make link layer independent */
1901 msg_out->htype = LWIP_IANA_HWTYPE_ETHERNET;
1902 msg_out->hlen = netif->hwaddr_len;
1903 msg_out->xid = lwip_htonl(dhcp->xid);
1904 /* we don't need the broadcast flag since we can receive unicast traffic
1905 before being fully configured! */
1906 /* set ciaddr to netif->ip_addr based on message_type and state */
1907 if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || (message_type == DHCP_RELEASE) ||
1908 ((message_type == DHCP_REQUEST) && /* DHCP_STATE_BOUND not used for sending! */
1909 ((dhcp->state == DHCP_STATE_RENEWING) || dhcp->state == DHCP_STATE_REBINDING))) {
1910 ip4_addr_copy(msg_out->ciaddr, *netif_ip4_addr(netif));
1911 }
1912 for (i = 0; i < LWIP_MIN(DHCP_CHADDR_LEN, NETIF_MAX_HWADDR_LEN); i++) {
1913 /* copy netif hardware address (padded with zeroes through memset already) */
1914 msg_out->chaddr[i] = netif->hwaddr[i];
1915 }
1916 msg_out->cookie = PP_HTONL(DHCP_MAGIC_COOKIE);
1917 /* Add option MESSAGE_TYPE */
1918 options_out_len_loc = dhcp_option(0, msg_out->options, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
1919 options_out_len_loc = dhcp_option_byte(options_out_len_loc, msg_out->options, message_type);
1920 if (options_out_len) {
1921 *options_out_len = options_out_len_loc;
1922 }
1923 return p_out;
1924 }
1925
1926 /**
1927 * Add a DHCP message trailer
1928 *
1929 * Adds the END option to the DHCP message, and if
1930 * necessary, up to three padding bytes.
1931 */
1932 static void
dhcp_option_trailer(u16_t options_out_len,u8_t * options,struct pbuf * p_out)1933 dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out)
1934 {
1935 options[options_out_len++] = DHCP_OPTION_END;
1936 /* packet is too small, or not 4 byte aligned? */
1937 while (((options_out_len < DHCP_MIN_OPTIONS_LEN) || (options_out_len & 3)) &&
1938 (options_out_len < DHCP_OPTIONS_LEN)) {
1939 /* add a fill/padding byte */
1940 options[options_out_len++] = 0;
1941 }
1942 /* shrink the pbuf to the actual content length */
1943 pbuf_realloc(p_out, (u16_t)(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + options_out_len));
1944 }
1945
1946 /** check if DHCP supplied netif->ip_addr
1947 *
1948 * @param netif the netif to check
1949 * @return 1 if DHCP supplied netif->ip_addr (states BOUND or RENEWING),
1950 * 0 otherwise
1951 */
1952 u8_t
dhcp_supplied_address(const struct netif * netif)1953 dhcp_supplied_address(const struct netif *netif)
1954 {
1955 if ((netif != NULL) && (netif_dhcp_data(netif) != NULL)) {
1956 struct dhcp *dhcp = netif_dhcp_data(netif);
1957 return (dhcp->state == DHCP_STATE_BOUND) || (dhcp->state == DHCP_STATE_RENEWING) ||
1958 (dhcp->state == DHCP_STATE_REBINDING);
1959 }
1960 return 0;
1961 }
1962
1963 #endif /* LWIP_IPV4 && LWIP_DHCP */
1964