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