Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_dhcp.c Source File

lwip_dhcp.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * Dynamic Host Configuration Protocol client
00004  *
00005  * @defgroup dhcp4 DHCPv4
00006  * @ingroup ip4
00007  * DHCP (IPv4) related functions
00008  * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform
00009  * with RFC 2131 and RFC 2132.
00010  *
00011  * @todo:
00012  * - Support for interfaces other than Ethernet (SLIP, PPP, ...)
00013  *
00014  * Options:
00015  * @ref DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute)
00016  * @ref DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer)
00017  *
00018  * dhcp_start() starts a DHCP client instance which
00019  * configures the interface by obtaining an IP address lease and maintaining it.
00020  *
00021  * Use dhcp_release() to end the lease and use dhcp_stop()
00022  * to remove the DHCP client.
00023  *
00024  * @see netifapi_dhcp4
00025  */
00026 
00027 /*
00028  * Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
00029  * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
00030  * All rights reserved.
00031  *
00032  * Redistribution and use in source and binary forms, with or without modification,
00033  * are permitted provided that the following conditions are met:
00034  *
00035  * 1. Redistributions of source code must retain the above copyright notice,
00036  *    this list of conditions and the following disclaimer.
00037  * 2. Redistributions in binary form must reproduce the above copyright notice,
00038  *    this list of conditions and the following disclaimer in the documentation
00039  *    and/or other materials provided with the distribution.
00040  * 3. The name of the author may not be used to endorse or promote products
00041  *    derived from this software without specific prior written permission.
00042  *
00043  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00044  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00045  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00046  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00047  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00048  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00049  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00050  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00051  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00052  * OF SUCH DAMAGE.
00053  *
00054  * This file is part of the lwIP TCP/IP stack.
00055  * The Swedish Institute of Computer Science and Adam Dunkels
00056  * are specifically granted permission to redistribute this
00057  * source code.
00058  *
00059  * Author: Leon Woestenberg <leon.woestenberg@gmx.net>
00060  *
00061  */
00062 
00063 #include "lwip/opt.h"
00064 
00065 #if LWIP_IPV4 && LWIP_DHCP /* don't build if not configured for use in lwipopts.h */
00066 
00067 #include "lwip/stats.h"
00068 #include "lwip/mem.h"
00069 #include "lwip/udp.h"
00070 #include "lwip/ip_addr.h"
00071 #include "lwip/netif.h"
00072 #include "lwip/def.h"
00073 #include "lwip/dhcp.h"
00074 #include "lwip/autoip.h"
00075 #include "lwip/dns.h"
00076 #include "lwip/etharp.h"
00077 #include "lwip/prot/dhcp.h"
00078 
00079 #include <string.h>
00080 
00081 /** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using
00082  * LWIP_RAND() (this overrides DHCP_GLOBAL_XID)
00083  */
00084 #ifndef DHCP_CREATE_RAND_XID
00085 #define DHCP_CREATE_RAND_XID        1
00086 #endif
00087 
00088 /** Default for DHCP_GLOBAL_XID is 0xABCD0000
00089  * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g.
00090  *  \#define DHCP_GLOBAL_XID_HEADER "stdlib.h"
00091  *  \#define DHCP_GLOBAL_XID rand()
00092  */
00093 #ifdef DHCP_GLOBAL_XID_HEADER
00094 #include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */
00095 #endif
00096 
00097 /** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU
00098  * MTU is checked to be big enough in dhcp_start */
00099 #define DHCP_MAX_MSG_LEN(netif)        (netif->mtu)
00100 #define DHCP_MAX_MSG_LEN_MIN_REQUIRED  576
00101 /** Minimum length for reply before packet is parsed */
00102 #define DHCP_MIN_REPLY_LEN             44
00103 
00104 #define REBOOT_TRIES                2
00105 
00106 #if LWIP_DNS && LWIP_DHCP_MAX_DNS_SERVERS
00107 #if DNS_MAX_SERVERS > LWIP_DHCP_MAX_DNS_SERVERS
00108 #define LWIP_DHCP_PROVIDE_DNS_SERVERS LWIP_DHCP_MAX_DNS_SERVERS
00109 #else
00110 #define LWIP_DHCP_PROVIDE_DNS_SERVERS DNS_MAX_SERVERS
00111 #endif
00112 #else
00113 #define LWIP_DHCP_PROVIDE_DNS_SERVERS 0
00114 #endif
00115 
00116 /** Option handling: options are parsed in dhcp_parse_reply
00117  * and saved in an array where other functions can load them from.
00118  * This might be moved into the struct dhcp (not necessarily since
00119  * lwIP is single-threaded and the array is only used while in recv
00120  * callback). */
00121 enum dhcp_option_idx {
00122   DHCP_OPTION_IDX_OVERLOAD = 0,
00123   DHCP_OPTION_IDX_MSG_TYPE,
00124   DHCP_OPTION_IDX_SERVER_ID,
00125   DHCP_OPTION_IDX_LEASE_TIME,
00126   DHCP_OPTION_IDX_T1,
00127   DHCP_OPTION_IDX_T2,
00128   DHCP_OPTION_IDX_SUBNET_MASK,
00129   DHCP_OPTION_IDX_ROUTER,
00130 #if LWIP_DHCP_PROVIDE_DNS_SERVERS
00131   DHCP_OPTION_IDX_DNS_SERVER,
00132   DHCP_OPTION_IDX_DNS_SERVER_LAST = DHCP_OPTION_IDX_DNS_SERVER + LWIP_DHCP_PROVIDE_DNS_SERVERS - 1,
00133 #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
00134 #if LWIP_DHCP_GET_NTP_SRV
00135   DHCP_OPTION_IDX_NTP_SERVER,
00136   DHCP_OPTION_IDX_NTP_SERVER_LAST = DHCP_OPTION_IDX_NTP_SERVER + LWIP_DHCP_MAX_NTP_SERVERS - 1,
00137 #endif /* LWIP_DHCP_GET_NTP_SRV */
00138   DHCP_OPTION_IDX_MAX
00139 };
00140 
00141 /** Holds the decoded option values, only valid while in dhcp_recv.
00142     @todo: move this into struct dhcp? */
00143 u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX];
00144 /** Holds a flag which option was received and is contained in dhcp_rx_options_val,
00145     only valid while in dhcp_recv.
00146     @todo: move this into struct dhcp? */
00147 u8_t  dhcp_rx_options_given[DHCP_OPTION_IDX_MAX];
00148 
00149 static u8_t dhcp_discover_request_options[] = {
00150   DHCP_OPTION_SUBNET_MASK,
00151   DHCP_OPTION_ROUTER,
00152   DHCP_OPTION_BROADCAST
00153 #if LWIP_DHCP_PROVIDE_DNS_SERVERS
00154   , DHCP_OPTION_DNS_SERVER
00155 #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
00156 #if LWIP_DHCP_GET_NTP_SRV
00157   , DHCP_OPTION_NTP
00158 #endif /* LWIP_DHCP_GET_NTP_SRV */
00159   };
00160 
00161 #ifdef DHCP_GLOBAL_XID
00162 static u32_t xid;
00163 static u8_t xid_initialised;
00164 #endif /* DHCP_GLOBAL_XID */
00165 
00166 #define dhcp_option_given(dhcp, idx)          (dhcp_rx_options_given[idx] != 0)
00167 #define dhcp_got_option(dhcp, idx)            (dhcp_rx_options_given[idx] = 1)
00168 #define dhcp_clear_option(dhcp, idx)          (dhcp_rx_options_given[idx] = 0)
00169 #define dhcp_clear_all_options(dhcp)          (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given)))
00170 #define dhcp_get_option_value(dhcp, idx)      (dhcp_rx_options_val[idx])
00171 #define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val))
00172 
00173 static struct udp_pcb *dhcp_pcb;
00174 static u8_t dhcp_pcb_refcount;
00175 
00176 /* DHCP client state machine functions */
00177 static err_t dhcp_discover(struct netif *netif);
00178 static err_t dhcp_select(struct netif *netif);
00179 static void dhcp_bind(struct netif *netif);
00180 #if DHCP_DOES_ARP_CHECK
00181 static err_t dhcp_decline(struct netif *netif);
00182 #endif /* DHCP_DOES_ARP_CHECK */
00183 static err_t dhcp_rebind(struct netif *netif);
00184 static err_t dhcp_reboot(struct netif *netif);
00185 static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
00186 
00187 /* receive, unfold, parse and free incoming messages */
00188 static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
00189 
00190 /* set the DHCP timers */
00191 static void dhcp_timeout(struct netif *netif);
00192 static void dhcp_t1_timeout(struct netif *netif);
00193 static void dhcp_t2_timeout(struct netif *netif);
00194 
00195 /* build outgoing messages */
00196 /* create a DHCP message, fill in common headers */
00197 static err_t dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type);
00198 /* free a DHCP request */
00199 static void dhcp_delete_msg(struct dhcp *dhcp);
00200 /* add a DHCP option (type, then length in bytes) */
00201 static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len);
00202 /* add option values */
00203 static void dhcp_option_byte(struct dhcp *dhcp, u8_t value);
00204 static void dhcp_option_short(struct dhcp *dhcp, u16_t value);
00205 static void dhcp_option_long(struct dhcp *dhcp, u32_t value);
00206 #if LWIP_NETIF_HOSTNAME
00207 static void dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif);
00208 #endif /* LWIP_NETIF_HOSTNAME */
00209 /* always add the DHCP options trailer to end and pad */
00210 static void dhcp_option_trailer(struct dhcp *dhcp);
00211 
00212 /** Ensure DHCP PCB is allocated and bound */
00213 static err_t
00214 dhcp_inc_pcb_refcount(void)
00215 {
00216   if (dhcp_pcb_refcount == 0) {
00217     LWIP_ASSERT("dhcp_inc_pcb_refcount(): memory leak", dhcp_pcb == NULL);
00218 
00219     /* allocate UDP PCB */
00220     dhcp_pcb = udp_new();
00221 
00222     if (dhcp_pcb == NULL) {
00223       return ERR_MEM;
00224     }
00225 
00226     ip_set_option(dhcp_pcb, SOF_BROADCAST);
00227 
00228     /* set up local and remote port for the pcb -> listen on all interfaces on all src/dest IPs */
00229     udp_bind(dhcp_pcb, IP4_ADDR_ANY, DHCP_CLIENT_PORT);
00230     udp_connect(dhcp_pcb, IP4_ADDR_ANY, DHCP_SERVER_PORT);
00231     udp_recv(dhcp_pcb, dhcp_recv, NULL);
00232   }
00233 
00234   dhcp_pcb_refcount++;
00235 
00236   return ERR_OK;
00237 }
00238 
00239 /** Free DHCP PCB if the last netif stops using it */
00240 static void
00241 dhcp_dec_pcb_refcount(void)
00242 {
00243   LWIP_ASSERT("dhcp_pcb_refcount(): refcount error", (dhcp_pcb_refcount > 0));
00244   dhcp_pcb_refcount--;
00245 
00246   if (dhcp_pcb_refcount == 0) {
00247     udp_remove(dhcp_pcb);
00248     dhcp_pcb = NULL;
00249   }
00250 }
00251 
00252 /**
00253  * Back-off the DHCP client (because of a received NAK response).
00254  *
00255  * Back-off the DHCP client because of a received NAK. Receiving a
00256  * NAK means the client asked for something non-sensible, for
00257  * example when it tries to renew a lease obtained on another network.
00258  *
00259  * We clear any existing set IP address and restart DHCP negotiation
00260  * afresh (as per RFC2131 3.2.3).
00261  *
00262  * @param netif the netif under DHCP control
00263  */
00264 static void
00265 dhcp_handle_nak(struct netif *netif)
00266 {
00267   struct dhcp *dhcp = netif_dhcp_data(netif);
00268 
00269   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n",
00270     (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
00271   /* Change to a defined state - set this before assigning the address
00272      to ensure the callback can use dhcp_supplied_address() */
00273   dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF);
00274   /* remove IP address from interface (must no longer be used, as per RFC2131) */
00275   netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
00276   /* We can immediately restart discovery */
00277   dhcp_discover(netif);
00278 }
00279 
00280 #if DHCP_DOES_ARP_CHECK
00281 /**
00282  * Checks if the offered IP address is already in use.
00283  *
00284  * It does so by sending an ARP request for the offered address and
00285  * entering CHECKING state. If no ARP reply is received within a small
00286  * interval, the address is assumed to be free for use by us.
00287  *
00288  * @param netif the netif under DHCP control
00289  */
00290 static void
00291 dhcp_check(struct netif *netif)
00292 {
00293   struct dhcp *dhcp = netif_dhcp_data(netif);
00294   err_t result;
00295   u16_t msecs;
00296   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],
00297     (s16_t)netif->name[1]));
00298   dhcp_set_state(dhcp, DHCP_STATE_CHECKING);
00299   /* create an ARP query for the offered IP address, expecting that no host
00300      responds, as the IP address should not be in use. */
00301   result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);
00302   if (result != ERR_OK) {
00303     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n"));
00304   }
00305   if (dhcp->tries < 255) {
00306     dhcp->tries++;
00307   }
00308   msecs = 500;
00309   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
00310   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs));
00311 }
00312 #endif /* DHCP_DOES_ARP_CHECK */
00313 
00314 /**
00315  * Remember the configuration offered by a DHCP server.
00316  *
00317  * @param netif the netif under DHCP control
00318  */
00319 static void
00320 dhcp_handle_offer(struct netif *netif)
00321 {
00322   struct dhcp *dhcp = netif_dhcp_data(netif);
00323 
00324   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",
00325     (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
00326   /* obtain the server address */
00327   if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) {
00328     ip_addr_set_ip4_u32(&dhcp->server_ip_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID)));
00329     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n",
00330       ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
00331     /* remember offered address */
00332     ip4_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr);
00333     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n",
00334       ip4_addr_get_u32(&dhcp->offered_ip_addr)));
00335 
00336     dhcp_select(netif);
00337   } else {
00338     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
00339       ("dhcp_handle_offer(netif=%p) did not get server ID!\n", (void*)netif));
00340   }
00341 }
00342 
00343 /**
00344  * Select a DHCP server offer out of all offers.
00345  *
00346  * Simply select the first offer received.
00347  *
00348  * @param netif the netif under DHCP control
00349  * @return lwIP specific error (see error.h)
00350  */
00351 static err_t
00352 dhcp_select(struct netif *netif)
00353 {
00354   struct dhcp *dhcp = netif_dhcp_data(netif);
00355   err_t result;
00356   u16_t msecs;
00357   u8_t i;
00358 
00359   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));
00360   dhcp_set_state(dhcp, DHCP_STATE_REQUESTING);
00361 
00362   /* create and initialize the DHCP message header */
00363   result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
00364   if (result == ERR_OK) {
00365     dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
00366     dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
00367 
00368     /* MUST request the offered IP address */
00369     dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
00370     dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
00371 
00372     dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
00373     dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
00374 
00375     dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
00376     for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
00377       dhcp_option_byte(dhcp, dhcp_discover_request_options[i]);
00378     }
00379 
00380 #if LWIP_NETIF_HOSTNAME
00381     dhcp_option_hostname(dhcp, netif);
00382 #endif /* LWIP_NETIF_HOSTNAME */
00383 
00384     dhcp_option_trailer(dhcp);
00385     /* shrink the pbuf to the actual content length */
00386     pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
00387 
00388     /* send broadcast to any DHCP server */
00389     udp_sendto_if_src(dhcp_pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif, IP4_ADDR_ANY);
00390     dhcp_delete_msg(dhcp);
00391     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n"));
00392   } else {
00393     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n"));
00394   }
00395   if (dhcp->tries < 255) {
00396     dhcp->tries++;
00397   }
00398   msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
00399   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
00400   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs));
00401   return result;
00402 }
00403 
00404 /**
00405  * The DHCP timer that checks for lease renewal/rebind timeouts.
00406  * Must be called once a minute (see @ref DHCP_COARSE_TIMER_SECS).
00407  */
00408 void
00409 dhcp_coarse_tmr(void)
00410 {
00411   struct netif *netif = netif_list;
00412   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n"));
00413   /* iterate through all network interfaces */
00414   while (netif != NULL) {
00415     /* only act on DHCP configured interfaces */
00416     struct dhcp *dhcp = netif_dhcp_data(netif);
00417     if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF)) {
00418       /* compare lease time to expire timeout */
00419       if (dhcp->t0_timeout && (++dhcp->lease_used == dhcp->t0_timeout)) {
00420         LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t0 timeout\n"));
00421         /* this clients' lease time has expired */
00422         dhcp_release(netif);
00423         dhcp_discover(netif);
00424       /* timer is active (non zero), and triggers (zeroes) now? */
00425       } else if (dhcp->t2_rebind_time && (dhcp->t2_rebind_time-- == 1)) {
00426         LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));
00427         /* this clients' rebind timeout triggered */
00428         dhcp_t2_timeout(netif);
00429       /* timer is active (non zero), and triggers (zeroes) now */
00430       } else if (dhcp->t1_renew_time && (dhcp->t1_renew_time-- == 1)) {
00431         LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));
00432         /* this clients' renewal timeout triggered */
00433         dhcp_t1_timeout(netif);
00434       }
00435     }
00436     /* proceed to next netif */
00437     netif = netif->next;
00438   }
00439 }
00440 
00441 /**
00442  * DHCP transaction timeout handling (this function must be called every 500ms,
00443  * see @ref DHCP_FINE_TIMER_MSECS).
00444  *
00445  * A DHCP server is expected to respond within a short period of time.
00446  * This timer checks whether an outstanding DHCP request is timed out.
00447  */
00448 void
00449 dhcp_fine_tmr(void)
00450 {
00451   struct netif *netif = netif_list;
00452   /* loop through netif's */
00453   while (netif != NULL) {
00454     struct dhcp *dhcp = netif_dhcp_data(netif);
00455     /* only act on DHCP configured interfaces */
00456     if (dhcp != NULL) {
00457       /* timer is active (non zero), and is about to trigger now */
00458       if (dhcp->request_timeout > 1) {
00459         dhcp->request_timeout--;
00460       }
00461       else if (dhcp->request_timeout == 1) {
00462         dhcp->request_timeout--;
00463         /* { netif->dhcp->request_timeout == 0 } */
00464         LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));
00465         /* this client's request timeout triggered */
00466         dhcp_timeout(netif);
00467       }
00468     }
00469     /* proceed to next network interface */
00470     netif = netif->next;
00471   }
00472 }
00473 
00474 /**
00475  * A DHCP negotiation transaction, or ARP request, has timed out.
00476  *
00477  * The timer that was started with the DHCP or ARP request has
00478  * timed out, indicating no response was received in time.
00479  *
00480  * @param netif the netif under DHCP control
00481  */
00482 static void
00483 dhcp_timeout(struct netif *netif)
00484 {
00485   struct dhcp *dhcp = netif_dhcp_data(netif);
00486 
00487   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n"));
00488   /* back-off period has passed, or server selection timed out */
00489   if ((dhcp->state == DHCP_STATE_BACKING_OFF) || (dhcp->state == DHCP_STATE_SELECTING)) {
00490     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n"));
00491     dhcp_discover(netif);
00492   /* receiving the requested lease timed out */
00493   } else if (dhcp->state == DHCP_STATE_REQUESTING) {
00494     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));
00495     if (dhcp->tries <= 5) {
00496       dhcp_select(netif);
00497     } else {
00498       LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
00499       dhcp_release(netif);
00500       dhcp_discover(netif);
00501     }
00502 #if DHCP_DOES_ARP_CHECK
00503   /* received no ARP reply for the offered address (which is good) */
00504   } else if (dhcp->state == DHCP_STATE_CHECKING) {
00505     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
00506     if (dhcp->tries <= 1) {
00507       dhcp_check(netif);
00508     /* no ARP replies on the offered address,
00509        looks like the IP address is indeed free */
00510     } else {
00511       /* bind the interface to the offered address */
00512       dhcp_bind(netif);
00513     }
00514 #endif /* DHCP_DOES_ARP_CHECK */
00515   } else if (dhcp->state == DHCP_STATE_REBOOTING) {
00516     if (dhcp->tries < REBOOT_TRIES) {
00517       dhcp_reboot(netif);
00518     } else {
00519       dhcp_discover(netif);
00520     }
00521   }
00522 }
00523 
00524 /**
00525  * The renewal period has timed out.
00526  *
00527  * @param netif the netif under DHCP control
00528  */
00529 static void
00530 dhcp_t1_timeout(struct netif *netif)
00531 {
00532   struct dhcp *dhcp = netif_dhcp_data(netif);
00533 
00534   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n"));
00535   if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
00536       (dhcp->state == DHCP_STATE_RENEWING)) {
00537     /* just retry to renew - note that the rebind timer (t2) will
00538      * eventually time-out if renew tries fail. */
00539     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00540                 ("dhcp_t1_timeout(): must renew\n"));
00541     /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
00542        DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */
00543     dhcp_renew(netif);
00544     /* Calculate next timeout */
00545     if (((dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS))
00546     {
00547        dhcp->t1_renew_time = ((dhcp->t2_timeout - dhcp->lease_used) / 2);
00548     }
00549   }
00550 }
00551 
00552 /**
00553  * The rebind period has timed out.
00554  *
00555  * @param netif the netif under DHCP control
00556  */
00557 static void
00558 dhcp_t2_timeout(struct netif *netif)
00559 {
00560   struct dhcp *dhcp = netif_dhcp_data(netif);
00561 
00562   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n"));
00563   if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
00564       (dhcp->state == DHCP_STATE_RENEWING) || (dhcp->state == DHCP_STATE_REBINDING)) {
00565     /* just retry to rebind */
00566     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00567                 ("dhcp_t2_timeout(): must rebind\n"));
00568     /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
00569        DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */
00570     dhcp_rebind(netif);
00571     /* Calculate next timeout */
00572     if (((dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS))
00573     {
00574        dhcp->t2_rebind_time = ((dhcp->t0_timeout - dhcp->lease_used) / 2);
00575     }
00576   }
00577 }
00578 
00579 /**
00580  * Handle a DHCP ACK packet
00581  *
00582  * @param netif the netif under DHCP control
00583  */
00584 static void
00585 dhcp_handle_ack(struct netif *netif)
00586 {
00587   struct dhcp *dhcp = netif_dhcp_data(netif);
00588 
00589 #if LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV
00590   u8_t n;
00591 #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV */
00592 #if LWIP_DHCP_GET_NTP_SRV
00593   ip4_addr_t ntp_server_addrs[LWIP_DHCP_MAX_NTP_SERVERS];
00594 #endif
00595 
00596   /* clear options we might not get from the ACK */
00597   ip4_addr_set_zero(&dhcp->offered_sn_mask);
00598   ip4_addr_set_zero(&dhcp->offered_gw_addr);
00599 #if LWIP_DHCP_BOOTP_FILE
00600   ip4_addr_set_zero(&dhcp->offered_si_addr);
00601 #endif /* LWIP_DHCP_BOOTP_FILE */
00602 
00603   /* lease time given? */
00604   if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) {
00605     /* remember offered lease time */
00606     dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME);
00607   }
00608   /* renewal period given? */
00609   if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) {
00610     /* remember given renewal period */
00611     dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1);
00612   } else {
00613     /* calculate safe periods for renewal */
00614     dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;
00615   }
00616 
00617   /* renewal period given? */
00618   if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) {
00619     /* remember given rebind period */
00620     dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2);
00621   } else {
00622     /* calculate safe periods for rebinding (offered_t0_lease * 0.875 -> 87.5%)*/
00623     dhcp->offered_t2_rebind = (dhcp->offered_t0_lease * 7U) / 8U;
00624   }
00625 
00626   /* (y)our internet address */
00627   ip4_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr);
00628 
00629 #if LWIP_DHCP_BOOTP_FILE
00630   /* copy boot server address,
00631      boot file name copied in dhcp_parse_reply if not overloaded */
00632   ip4_addr_copy(dhcp->offered_si_addr, dhcp->msg_in->siaddr);
00633 #endif /* LWIP_DHCP_BOOTP_FILE */
00634 
00635   /* subnet mask given? */
00636   if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) {
00637     /* remember given subnet mask */
00638     ip4_addr_set_u32(&dhcp->offered_sn_mask, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)));
00639     dhcp->subnet_mask_given = 1;
00640   } else {
00641     dhcp->subnet_mask_given = 0;
00642   }
00643 
00644   /* gateway router */
00645   if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) {
00646     ip4_addr_set_u32(&dhcp->offered_gw_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER)));
00647   }
00648 
00649 #if LWIP_DHCP_GET_NTP_SRV
00650   /* NTP servers */
00651   for (n = 0; (n < LWIP_DHCP_MAX_NTP_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n); n++) {
00652     ip4_addr_set_u32(&ntp_server_addrs[n], lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n)));
00653   }
00654   dhcp_set_ntp_servers(n, ntp_server_addrs);
00655 #endif /* LWIP_DHCP_GET_NTP_SRV */
00656 
00657 #if LWIP_DHCP_PROVIDE_DNS_SERVERS
00658   /* DNS servers */
00659   for (n = 0; (n < LWIP_DHCP_PROVIDE_DNS_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) {
00660     ip_addr_t dns_addr;
00661     ip_addr_set_ip4_u32(&dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n)));
00662     dns_setserver(n, &dns_addr);
00663   }
00664 #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
00665 }
00666 
00667 /**
00668  * @ingroup dhcp4
00669  * Set a statically allocated struct dhcp to work with.
00670  * Using this prevents dhcp_start to allocate it using mem_malloc.
00671  *
00672  * @param netif the netif for which to set the struct dhcp
00673  * @param dhcp (uninitialised) dhcp struct allocated by the application
00674  */
00675 void
00676 dhcp_set_struct(struct netif *netif, struct dhcp *dhcp)
00677 {
00678   LWIP_ASSERT("netif != NULL", netif != NULL);
00679   LWIP_ASSERT("dhcp != NULL", dhcp != NULL);
00680   LWIP_ASSERT("netif already has a struct dhcp set", netif_dhcp_data(netif) == NULL);
00681 
00682   /* clear data structure */
00683   memset(dhcp, 0, sizeof(struct dhcp));
00684   /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */
00685   netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp);
00686 }
00687 
00688 /**
00689  * @ingroup dhcp4
00690  * Removes a struct dhcp from a netif.
00691  *
00692  * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the
00693  *            struct dhcp since the memory is passed back to the heap.
00694  *
00695  * @param netif the netif from which to remove the struct dhcp
00696  */
00697 void dhcp_cleanup(struct netif *netif)
00698 {
00699   LWIP_ASSERT("netif != NULL", netif != NULL);
00700 
00701   if (netif_dhcp_data(netif) != NULL) {
00702     mem_free(netif_dhcp_data(netif));
00703     netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, NULL);
00704   }
00705 }
00706 
00707 /**
00708  * @ingroup dhcp4
00709  * Start DHCP negotiation for a network interface.
00710  *
00711  * If no DHCP client instance was attached to this interface,
00712  * a new client is created first. If a DHCP client instance
00713  * was already present, it restarts negotiation.
00714  *
00715  * @param netif The lwIP network interface
00716  * @return lwIP error code
00717  * - ERR_OK - No error
00718  * - ERR_MEM - Out of memory
00719  */
00720 err_t
00721 dhcp_start(struct netif *netif)
00722 {
00723   struct dhcp *dhcp;
00724   err_t result;
00725 
00726   LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;);
00727   LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
00728   dhcp = netif_dhcp_data(netif);
00729   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));
00730 
00731   /* check MTU of the netif */
00732   if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) {
00733     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n"));
00734     return ERR_MEM;
00735   }
00736 
00737   /* no DHCP client attached yet? */
00738   if (dhcp == NULL) {
00739     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n"));
00740     dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp));
00741     if (dhcp == NULL) {
00742       LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));
00743       return ERR_MEM;
00744     }
00745 
00746     /* store this dhcp client in the netif */
00747     netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp);
00748     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp"));
00749   /* already has DHCP client attached */
00750   } else {
00751     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n"));
00752     LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL);
00753     LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL );
00754 
00755     if (dhcp->pcb_allocated != 0) {
00756       dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */
00757     }
00758     /* dhcp is cleared below, no need to reset flag*/
00759   }
00760 
00761   /* clear data structure */
00762   memset(dhcp, 0, sizeof(struct dhcp));
00763   /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */
00764 
00765   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
00766 
00767   if (dhcp_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP PCB is allocated */
00768     return ERR_MEM;
00769   }
00770   dhcp->pcb_allocated = 1;
00771 
00772 #if LWIP_DHCP_CHECK_LINK_UP
00773   if (!netif_is_link_up(netif)) {
00774     /* set state INIT and wait for dhcp_network_changed() to call dhcp_discover() */
00775     dhcp_set_state(dhcp, DHCP_STATE_INIT);
00776     return ERR_OK;
00777   }
00778 #endif /* LWIP_DHCP_CHECK_LINK_UP */
00779 
00780 
00781   /* (re)start the DHCP negotiation */
00782   result = dhcp_discover(netif);
00783   if (result != ERR_OK) {
00784     /* free resources allocated above */
00785     dhcp_stop(netif);
00786     return ERR_MEM;
00787   }
00788   return result;
00789 }
00790 
00791 /**
00792  * @ingroup dhcp4
00793  * Inform a DHCP server of our manual configuration.
00794  *
00795  * This informs DHCP servers of our fixed IP address configuration
00796  * by sending an INFORM message. It does not involve DHCP address
00797  * configuration, it is just here to be nice to the network.
00798  *
00799  * @param netif The lwIP network interface
00800  */
00801 void
00802 dhcp_inform(struct netif *netif)
00803 {
00804   struct dhcp dhcp;
00805   err_t result = ERR_OK;
00806 
00807   LWIP_ERROR("netif != NULL", (netif != NULL), return;);
00808 
00809   if (dhcp_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP PCB is allocated */
00810     return;
00811   }
00812 
00813   memset(&dhcp, 0, sizeof(struct dhcp));
00814   dhcp_set_state(&dhcp, DHCP_STATE_INFORMING);
00815 
00816   /* create and initialize the DHCP message header */
00817   result = dhcp_create_msg(netif, &dhcp, DHCP_INFORM);
00818   if (result == ERR_OK) {
00819     dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
00820     dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(netif));
00821 
00822     dhcp_option_trailer(&dhcp);
00823 
00824     pbuf_realloc(dhcp.p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp.options_out_len);
00825 
00826     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n"));
00827 
00828     udp_sendto_if(dhcp_pcb, dhcp.p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
00829 
00830     dhcp_delete_msg(&dhcp);
00831   } else {
00832     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n"));
00833   }
00834 
00835   dhcp_dec_pcb_refcount(); /* delete DHCP PCB if not needed any more */
00836 }
00837 
00838 /** Handle a possible change in the network configuration.
00839  *
00840  * This enters the REBOOTING state to verify that the currently bound
00841  * address is still valid.
00842  */
00843 void
00844 dhcp_network_changed(struct netif *netif)
00845 {
00846   struct dhcp *dhcp = netif_dhcp_data(netif);
00847 
00848   if (!dhcp)
00849     return;
00850   switch (dhcp->state) {
00851   case DHCP_STATE_REBINDING:
00852   case DHCP_STATE_RENEWING:
00853   case DHCP_STATE_BOUND:
00854   case DHCP_STATE_REBOOTING:
00855     dhcp->tries = 0;
00856     dhcp_reboot(netif);
00857     break;
00858   case DHCP_STATE_OFF:
00859     /* stay off */
00860     break;
00861   default:
00862     /* INIT/REQUESTING/CHECKING/BACKING_OFF restart with new 'rid' because the
00863        state changes, SELECTING: continue with current 'rid' as we stay in the
00864        same state */
00865 #if LWIP_DHCP_AUTOIP_COOP
00866     if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
00867       autoip_stop(netif);
00868       dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
00869     }
00870 #endif /* LWIP_DHCP_AUTOIP_COOP */
00871     /* ensure we start with short timeouts, even if already discovering */
00872     dhcp->tries = 0;
00873     dhcp_discover(netif);
00874     break;
00875   }
00876 }
00877 
00878 #if DHCP_DOES_ARP_CHECK
00879 /**
00880  * Match an ARP reply with the offered IP address:
00881  * check whether the offered IP address is not in use using ARP
00882  *
00883  * @param netif the network interface on which the reply was received
00884  * @param addr The IP address we received a reply from
00885  */
00886 void
00887 dhcp_arp_reply(struct netif *netif, const ip4_addr_t *addr)
00888 {
00889   struct dhcp *dhcp;
00890 
00891   LWIP_ERROR("netif != NULL", (netif != NULL), return;);
00892   dhcp = netif_dhcp_data(netif);
00893   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n"));
00894   /* is a DHCP client doing an ARP check? */
00895   if ((dhcp != NULL) && (dhcp->state == DHCP_STATE_CHECKING)) {
00896     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n",
00897       ip4_addr_get_u32(addr)));
00898     /* did a host respond with the address we
00899        were offered by the DHCP server? */
00900     if (ip4_addr_cmp(addr, &dhcp->offered_ip_addr)) {
00901       /* we will not accept the offered address */
00902       LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
00903         ("dhcp_arp_reply(): arp reply matched with offered address, declining\n"));
00904       dhcp_decline(netif);
00905     }
00906   }
00907 }
00908 
00909 /**
00910  * Decline an offered lease.
00911  *
00912  * Tell the DHCP server we do not accept the offered address.
00913  * One reason to decline the lease is when we find out the address
00914  * is already in use by another host (through ARP).
00915  *
00916  * @param netif the netif under DHCP control
00917  */
00918 static err_t
00919 dhcp_decline(struct netif *netif)
00920 {
00921   struct dhcp *dhcp = netif_dhcp_data(netif);
00922   err_t result = ERR_OK;
00923   u16_t msecs;
00924   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n"));
00925   dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF);
00926   /* create and initialize the DHCP message header */
00927   result = dhcp_create_msg(netif, dhcp, DHCP_DECLINE);
00928   if (result == ERR_OK) {
00929     dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
00930     dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
00931 
00932     dhcp_option_trailer(dhcp);
00933     /* resize pbuf to reflect true size of options */
00934     pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
00935 
00936     /* per section 4.4.4, broadcast DECLINE messages */
00937     udp_sendto_if_src(dhcp_pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif, IP4_ADDR_ANY);
00938     dhcp_delete_msg(dhcp);
00939     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n"));
00940   } else {
00941     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
00942       ("dhcp_decline: could not allocate DHCP request\n"));
00943   }
00944   if (dhcp->tries < 255) {
00945     dhcp->tries++;
00946   }
00947   msecs = 10*1000;
00948   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
00949   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));
00950   return result;
00951 }
00952 #endif /* DHCP_DOES_ARP_CHECK */
00953 
00954 
00955 /**
00956  * Start the DHCP process, discover a DHCP server.
00957  *
00958  * @param netif the netif under DHCP control
00959  */
00960 static err_t
00961 dhcp_discover(struct netif *netif)
00962 {
00963   struct dhcp *dhcp = netif_dhcp_data(netif);
00964   err_t result = ERR_OK;
00965   u16_t msecs;
00966   u8_t i;
00967   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n"));
00968   ip4_addr_set_any(&dhcp->offered_ip_addr);
00969   dhcp_set_state(dhcp, DHCP_STATE_SELECTING);
00970   /* create and initialize the DHCP message header */
00971   result = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER);
00972   if (result == ERR_OK) {
00973     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n"));
00974 
00975     dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
00976     dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
00977 
00978     dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
00979     for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
00980       dhcp_option_byte(dhcp, dhcp_discover_request_options[i]);
00981     }
00982     dhcp_option_trailer(dhcp);
00983 
00984     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n"));
00985     pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
00986 
00987     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));
00988     udp_sendto_if_src(dhcp_pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif, IP4_ADDR_ANY);
00989     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
00990     dhcp_delete_msg(dhcp);
00991     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n"));
00992   } else {
00993     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n"));
00994   }
00995   if (dhcp->tries < 255) {
00996     dhcp->tries++;
00997   }
00998 #if LWIP_DHCP_AUTOIP_COOP
00999   if (dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) {
01000     dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON;
01001     autoip_start(netif);
01002   }
01003 #endif /* LWIP_DHCP_AUTOIP_COOP */
01004   msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
01005   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
01006   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
01007   return result;
01008 }
01009 
01010 
01011 /**
01012  * Bind the interface to the offered IP address.
01013  *
01014  * @param netif network interface to bind to the offered address
01015  */
01016 static void
01017 dhcp_bind(struct netif *netif)
01018 {
01019   u32_t timeout;
01020   struct dhcp *dhcp;
01021   ip4_addr_t sn_mask, gw_addr;
01022   LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;);
01023   dhcp = netif_dhcp_data(netif);
01024   LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;);
01025   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));
01026 
01027   /* reset time used of lease */
01028   dhcp->lease_used = 0;
01029 
01030   if (dhcp->offered_t0_lease != 0xffffffffUL) {
01031      /* set renewal period timer */
01032      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease));
01033      timeout = (dhcp->offered_t0_lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
01034      if (timeout > 0xffff) {
01035        timeout = 0xffff;
01036      }
01037      dhcp->t0_timeout = (u16_t)timeout;
01038      if (dhcp->t0_timeout == 0) {
01039        dhcp->t0_timeout = 1;
01040      }
01041      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease*1000));
01042   }
01043 
01044   /* temporary DHCP lease? */
01045   if (dhcp->offered_t1_renew != 0xffffffffUL) {
01046     /* set renewal period timer */
01047     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));
01048     timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
01049     if (timeout > 0xffff) {
01050       timeout = 0xffff;
01051     }
01052     dhcp->t1_timeout = (u16_t)timeout;
01053     if (dhcp->t1_timeout == 0) {
01054       dhcp->t1_timeout = 1;
01055     }
01056     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000));
01057     dhcp->t1_renew_time = dhcp->t1_timeout;
01058   }
01059   /* set renewal period timer */
01060   if (dhcp->offered_t2_rebind != 0xffffffffUL) {
01061     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));
01062     timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
01063     if (timeout > 0xffff) {
01064       timeout = 0xffff;
01065     }
01066     dhcp->t2_timeout = (u16_t)timeout;
01067     if (dhcp->t2_timeout == 0) {
01068       dhcp->t2_timeout = 1;
01069     }
01070     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000));
01071     dhcp->t2_rebind_time = dhcp->t2_timeout;
01072   }
01073 
01074   /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */
01075   if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) {
01076     dhcp->t1_timeout = 0;
01077   }
01078 
01079   if (dhcp->subnet_mask_given) {
01080     /* copy offered network mask */
01081     ip4_addr_copy(sn_mask, dhcp->offered_sn_mask);
01082   } else {
01083     /* subnet mask not given, choose a safe subnet mask given the network class */
01084     u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr);
01085     if (first_octet <= 127) {
01086       ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL));
01087     } else if (first_octet >= 192) {
01088       ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL));
01089     } else {
01090       ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL));
01091     }
01092   }
01093 
01094   ip4_addr_copy(gw_addr, dhcp->offered_gw_addr);
01095   /* gateway address not given? */
01096   if (ip4_addr_isany_val(gw_addr)) {
01097     /* copy network address */
01098     ip4_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask);
01099     /* use first host address on network as gateway */
01100     ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL));
01101   }
01102 
01103 #if LWIP_DHCP_AUTOIP_COOP
01104   if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
01105     autoip_stop(netif);
01106     dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
01107   }
01108 #endif /* LWIP_DHCP_AUTOIP_COOP */
01109 
01110   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",
01111     ip4_addr_get_u32(&dhcp->offered_ip_addr), ip4_addr_get_u32(&sn_mask), ip4_addr_get_u32(&gw_addr)));
01112   /* netif is now bound to DHCP leased address - set this before assigning the address
01113      to ensure the callback can use dhcp_supplied_address() */
01114   dhcp_set_state(dhcp, DHCP_STATE_BOUND);
01115 
01116   netif_set_addr(netif, &dhcp->offered_ip_addr, &sn_mask, &gw_addr);
01117   /* interface is used by routing now that an address is set */
01118 }
01119 
01120 /**
01121  * @ingroup dhcp4
01122  * Renew an existing DHCP lease at the involved DHCP server.
01123  *
01124  * @param netif network interface which must renew its lease
01125  */
01126 err_t
01127 dhcp_renew(struct netif *netif)
01128 {
01129   struct dhcp *dhcp = netif_dhcp_data(netif);
01130   err_t result;
01131   u16_t msecs;
01132   u8_t i;
01133   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n"));
01134   dhcp_set_state(dhcp, DHCP_STATE_RENEWING);
01135 
01136   /* create and initialize the DHCP message header */
01137   result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
01138   if (result == ERR_OK) {
01139     dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
01140     dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
01141 
01142     dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
01143     for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
01144       dhcp_option_byte(dhcp, dhcp_discover_request_options[i]);
01145     }
01146 
01147 #if LWIP_NETIF_HOSTNAME
01148     dhcp_option_hostname(dhcp, netif);
01149 #endif /* LWIP_NETIF_HOSTNAME */
01150 
01151     /* append DHCP message trailer */
01152     dhcp_option_trailer(dhcp);
01153 
01154     pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
01155 
01156     udp_sendto_if(dhcp_pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
01157     dhcp_delete_msg(dhcp);
01158 
01159     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n"));
01160   } else {
01161     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n"));
01162   }
01163   if (dhcp->tries < 255) {
01164     dhcp->tries++;
01165   }
01166   /* back-off on retries, but to a maximum of 20 seconds */
01167   msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000;
01168   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
01169   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs));
01170   return result;
01171 }
01172 
01173 /**
01174  * Rebind with a DHCP server for an existing DHCP lease.
01175  *
01176  * @param netif network interface which must rebind with a DHCP server
01177  */
01178 static err_t
01179 dhcp_rebind(struct netif *netif)
01180 {
01181   struct dhcp *dhcp = netif_dhcp_data(netif);
01182   err_t result;
01183   u16_t msecs;
01184   u8_t i;
01185   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n"));
01186   dhcp_set_state(dhcp, DHCP_STATE_REBINDING);
01187 
01188   /* create and initialize the DHCP message header */
01189   result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
01190   if (result == ERR_OK) {
01191     dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
01192     dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
01193 
01194     dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
01195     for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
01196       dhcp_option_byte(dhcp, dhcp_discover_request_options[i]);
01197     }
01198 
01199 #if LWIP_NETIF_HOSTNAME
01200     dhcp_option_hostname(dhcp, netif);
01201 #endif /* LWIP_NETIF_HOSTNAME */
01202 
01203     dhcp_option_trailer(dhcp);
01204 
01205     pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
01206 
01207     /* broadcast to server */
01208     udp_sendto_if(dhcp_pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
01209     dhcp_delete_msg(dhcp);
01210     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n"));
01211   } else {
01212     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n"));
01213   }
01214   if (dhcp->tries < 255) {
01215     dhcp->tries++;
01216   }
01217   msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
01218   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
01219   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs));
01220   return result;
01221 }
01222 
01223 /**
01224  * Enter REBOOTING state to verify an existing lease
01225  *
01226  * @param netif network interface which must reboot
01227  */
01228 static err_t
01229 dhcp_reboot(struct netif *netif)
01230 {
01231   struct dhcp *dhcp = netif_dhcp_data(netif);
01232   err_t result;
01233   u16_t msecs;
01234   u8_t i;
01235   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n"));
01236   dhcp_set_state(dhcp, DHCP_STATE_REBOOTING);
01237 
01238   /* create and initialize the DHCP message header */
01239   result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
01240   if (result == ERR_OK) {
01241     dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
01242     dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN_MIN_REQUIRED);
01243 
01244     dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
01245     dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
01246 
01247     dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
01248     for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
01249       dhcp_option_byte(dhcp, dhcp_discover_request_options[i]);
01250     }
01251 
01252     dhcp_option_trailer(dhcp);
01253 
01254     pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
01255 
01256     /* broadcast to server */
01257     udp_sendto_if(dhcp_pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
01258     dhcp_delete_msg(dhcp);
01259     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n"));
01260   } else {
01261     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n"));
01262   }
01263   if (dhcp->tries < 255) {
01264     dhcp->tries++;
01265   }
01266   msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
01267   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
01268   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs));
01269   return result;
01270 }
01271 
01272 
01273 /**
01274  * @ingroup dhcp4
01275  * Release a DHCP lease (usually called before @ref dhcp_stop).
01276  *
01277  * @param netif network interface which must release its lease
01278  */
01279 err_t
01280 dhcp_release(struct netif *netif)
01281 {
01282   struct dhcp *dhcp = netif_dhcp_data(netif);
01283   err_t result;
01284   ip_addr_t server_ip_addr;
01285   u8_t is_dhcp_supplied_address;
01286 
01287   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n"));
01288   if (dhcp == NULL) {
01289     return ERR_ARG;
01290   }
01291   ip_addr_copy(server_ip_addr, dhcp->server_ip_addr);
01292 
01293   is_dhcp_supplied_address = dhcp_supplied_address(netif);
01294 
01295   /* idle DHCP client */
01296   dhcp_set_state(dhcp, DHCP_STATE_OFF);
01297   /* clean old DHCP offer */
01298   ip_addr_set_zero_ip4(&dhcp->server_ip_addr);
01299   ip4_addr_set_zero(&dhcp->offered_ip_addr);
01300   ip4_addr_set_zero(&dhcp->offered_sn_mask);
01301   ip4_addr_set_zero(&dhcp->offered_gw_addr);
01302 #if LWIP_DHCP_BOOTP_FILE
01303   ip4_addr_set_zero(&dhcp->offered_si_addr);
01304 #endif /* LWIP_DHCP_BOOTP_FILE */
01305   dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
01306   dhcp->t1_renew_time = dhcp->t2_rebind_time = dhcp->lease_used = dhcp->t0_timeout = 0;
01307 
01308   if (!is_dhcp_supplied_address) {
01309     /* don't issue release message when address is not dhcp-assigned */
01310     return ERR_OK;
01311   }
01312 
01313   /* create and initialize the DHCP message header */
01314   result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE);
01315   if (result == ERR_OK) {
01316     dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
01317     dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&server_ip_addr))));
01318 
01319     dhcp_option_trailer(dhcp);
01320 
01321     pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
01322 
01323     udp_sendto_if(dhcp_pcb, dhcp->p_out, &server_ip_addr, DHCP_SERVER_PORT, netif);
01324     dhcp_delete_msg(dhcp);
01325     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_STATE_OFF\n"));
01326   } else {
01327     /* sending release failed, but that's not a problem since the correct behaviour of dhcp does not rely on release */
01328     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n"));
01329   }
01330   /* remove IP address from interface (prevents routing from selecting this interface) */
01331   netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
01332 
01333   return result;
01334 }
01335 
01336 /**
01337  * @ingroup dhcp4
01338  * Remove the DHCP client from the interface.
01339  *
01340  * @param netif The network interface to stop DHCP on
01341  */
01342 void
01343 dhcp_stop(struct netif *netif)
01344 {
01345   struct dhcp *dhcp;
01346   LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;);
01347   dhcp = netif_dhcp_data(netif);
01348 
01349   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop()\n"));
01350   /* netif is DHCP configured? */
01351   if (dhcp != NULL) {
01352 #if LWIP_DHCP_AUTOIP_COOP
01353     if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
01354       autoip_stop(netif);
01355       dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
01356     }
01357 #endif /* LWIP_DHCP_AUTOIP_COOP */
01358 
01359     LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL);
01360     dhcp_set_state(dhcp, DHCP_STATE_OFF);
01361 
01362     if (dhcp->pcb_allocated != 0) {
01363       dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */
01364       dhcp->pcb_allocated = 0;
01365     }
01366   }
01367 }
01368 
01369 /*
01370  * Set the DHCP state of a DHCP client.
01371  *
01372  * If the state changed, reset the number of tries.
01373  */
01374 static void
01375 dhcp_set_state(struct dhcp *dhcp, u8_t new_state)
01376 {
01377   if (new_state != dhcp->state) {
01378     dhcp->state = new_state;
01379     dhcp->tries = 0;
01380     dhcp->request_timeout = 0;
01381   }
01382 }
01383 
01384 /*
01385  * Concatenate an option type and length field to the outgoing
01386  * DHCP message.
01387  *
01388  */
01389 static void
01390 dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len)
01391 {
01392   LWIP_ASSERT("dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN);
01393   dhcp->msg_out->options[dhcp->options_out_len++] = option_type;
01394   dhcp->msg_out->options[dhcp->options_out_len++] = option_len;
01395 }
01396 /*
01397  * Concatenate a single byte to the outgoing DHCP message.
01398  *
01399  */
01400 static void
01401 dhcp_option_byte(struct dhcp *dhcp, u8_t value)
01402 {
01403   LWIP_ASSERT("dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);
01404   dhcp->msg_out->options[dhcp->options_out_len++] = value;
01405 }
01406 
01407 static void
01408 dhcp_option_short(struct dhcp *dhcp, u16_t value)
01409 {
01410   LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN);
01411   dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
01412   dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t) (value & 0x00ffU);
01413 }
01414 
01415 static void
01416 dhcp_option_long(struct dhcp *dhcp, u32_t value)
01417 {
01418   LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN);
01419   dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24);
01420   dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16);
01421   dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8);
01422   dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL));
01423 }
01424 
01425 #if LWIP_NETIF_HOSTNAME
01426 static void
01427 dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif)
01428 {
01429   if (netif->hostname != NULL) {
01430     size_t namelen = strlen(netif->hostname);
01431     if (namelen > 0) {
01432       size_t len;
01433       const char *p = netif->hostname;
01434       /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME
01435          and 1 byte for trailer) */
01436       size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3;
01437       LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available);
01438       len = LWIP_MIN(namelen, available);
01439       LWIP_ASSERT("DHCP: hostname is too long!", len <= 0xFF);
01440       dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, (u8_t)len);
01441       while (len--) {
01442         dhcp_option_byte(dhcp, *p++);
01443       }
01444     }
01445   }
01446 }
01447 #endif /* LWIP_NETIF_HOSTNAME */
01448 
01449 /**
01450  * Extract the DHCP message and the DHCP options.
01451  *
01452  * Extract the DHCP message and the DHCP options, each into a contiguous
01453  * piece of memory. As a DHCP message is variable sized by its options,
01454  * and also allows overriding some fields for options, the easy approach
01455  * is to first unfold the options into a contiguous piece of memory, and
01456  * use that further on.
01457  *
01458  */
01459 static err_t
01460 dhcp_parse_reply(struct dhcp *dhcp, struct pbuf *p)
01461 {
01462   u8_t *options;
01463   u16_t offset;
01464   u16_t offset_max;
01465   u16_t options_idx;
01466   u16_t options_idx_max;
01467   struct pbuf *q;
01468   int parse_file_as_options = 0;
01469   int parse_sname_as_options = 0;
01470 
01471   /* clear received options */
01472   dhcp_clear_all_options(dhcp);
01473   /* check that beginning of dhcp_msg (up to and including chaddr) is in first pbuf */
01474   if (p->len < DHCP_SNAME_OFS) {
01475     return ERR_BUF;
01476   }
01477   dhcp->msg_in = (struct dhcp_msg *)p->payload;
01478 #if LWIP_DHCP_BOOTP_FILE
01479   /* clear boot file name */
01480   dhcp->boot_file_name[0] = 0;
01481 #endif /* LWIP_DHCP_BOOTP_FILE */
01482 
01483   /* parse options */
01484 
01485   /* start with options field */
01486   options_idx = DHCP_OPTIONS_OFS;
01487   /* parse options to the end of the received packet */
01488   options_idx_max = p->tot_len;
01489 again:
01490   q = p;
01491   while ((q != NULL) && (options_idx >= q->len)) {
01492     options_idx -= q->len;
01493     options_idx_max -= q->len;
01494     q = q->next;
01495   }
01496   if (q == NULL) {
01497     return ERR_BUF;
01498   }
01499   offset = options_idx;
01500   offset_max = options_idx_max;
01501   options = (u8_t*)q->payload;
01502   /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */
01503   while ((q != NULL) && (options[offset] != DHCP_OPTION_END) && (offset < offset_max)) {
01504     u8_t op = options[offset];
01505     u8_t len;
01506     u8_t decode_len = 0;
01507     int decode_idx = -1;
01508     u16_t val_offset = offset + 2;
01509     /* len byte might be in the next pbuf */
01510     if ((offset + 1) < q->len) {
01511       len = options[offset + 1];
01512     } else {
01513       len = (q->next != NULL ? ((u8_t*)q->next->payload)[0] : 0);
01514     }
01515     /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */
01516     decode_len = len;
01517     switch(op) {
01518       /* case(DHCP_OPTION_END): handled above */
01519       case(DHCP_OPTION_PAD):
01520         /* special option: no len encoded */
01521         decode_len = len = 0;
01522         /* will be increased below */
01523         offset--;
01524         break;
01525       case(DHCP_OPTION_SUBNET_MASK):
01526         LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
01527         decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
01528         break;
01529       case(DHCP_OPTION_ROUTER):
01530         decode_len = 4; /* only copy the first given router */
01531         LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
01532         decode_idx = DHCP_OPTION_IDX_ROUTER;
01533         break;
01534 #if LWIP_DHCP_PROVIDE_DNS_SERVERS
01535       case(DHCP_OPTION_DNS_SERVER):
01536         /* special case: there might be more than one server */
01537         LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
01538         /* limit number of DNS servers */
01539         decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS);
01540         LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
01541         decode_idx = DHCP_OPTION_IDX_DNS_SERVER;
01542         break;
01543 #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
01544       case(DHCP_OPTION_LEASE_TIME):
01545         LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
01546         decode_idx = DHCP_OPTION_IDX_LEASE_TIME;
01547         break;
01548 #if LWIP_DHCP_GET_NTP_SRV
01549       case(DHCP_OPTION_NTP):
01550         /* special case: there might be more than one server */
01551         LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
01552         /* limit number of NTP servers */
01553         decode_len = LWIP_MIN(len, 4 * LWIP_DHCP_MAX_NTP_SERVERS);
01554         LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
01555         decode_idx = DHCP_OPTION_IDX_NTP_SERVER;
01556         break;
01557 #endif /* LWIP_DHCP_GET_NTP_SRV*/
01558       case(DHCP_OPTION_OVERLOAD):
01559         LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
01560         /* decode overload only in options, not in file/sname: invalid packet */
01561         LWIP_ERROR("overload in file/sname", options_idx == DHCP_OPTIONS_OFS, return ERR_VAL;);
01562         decode_idx = DHCP_OPTION_IDX_OVERLOAD;
01563         break;
01564       case(DHCP_OPTION_MESSAGE_TYPE):
01565         LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
01566         decode_idx = DHCP_OPTION_IDX_MSG_TYPE;
01567         break;
01568       case(DHCP_OPTION_SERVER_ID):
01569         LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
01570         decode_idx = DHCP_OPTION_IDX_SERVER_ID;
01571         break;
01572       case(DHCP_OPTION_T1):
01573         LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
01574         decode_idx = DHCP_OPTION_IDX_T1;
01575         break;
01576       case(DHCP_OPTION_T2):
01577         LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
01578         decode_idx = DHCP_OPTION_IDX_T2;
01579         break;
01580       default:
01581         decode_len = 0;
01582         LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", (u16_t)op));
01583         break;
01584     }
01585     offset += len + 2;
01586     if (decode_len > 0) {
01587       u32_t value = 0;
01588       u16_t copy_len;
01589 decode_next:
01590       LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX);
01591       if (!dhcp_option_given(dhcp, decode_idx)) {
01592         copy_len = LWIP_MIN(decode_len, 4);
01593         if (pbuf_copy_partial(q, &value, copy_len, val_offset) != copy_len) {
01594           return ERR_BUF;
01595         }
01596         if (decode_len > 4) {
01597           /* decode more than one u32_t */
01598           LWIP_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
01599           dhcp_got_option(dhcp, decode_idx);
01600           dhcp_set_option_value(dhcp, decode_idx, lwip_htonl(value));
01601           decode_len -= 4;
01602           val_offset += 4;
01603           decode_idx++;
01604           goto decode_next;
01605         } else if (decode_len == 4) {
01606           value = lwip_ntohl(value);
01607         } else {
01608           LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
01609           value = ((u8_t*)&value)[0];
01610         }
01611         dhcp_got_option(dhcp, decode_idx);
01612         dhcp_set_option_value(dhcp, decode_idx, value);
01613       }
01614     }
01615     if (offset >= q->len) {
01616       offset -= q->len;
01617       offset_max -= q->len;
01618       if ((offset < offset_max) && offset_max) {
01619         q = q->next;
01620         LWIP_ASSERT("next pbuf was null", q);
01621         options = (u8_t*)q->payload;
01622       } else {
01623         /* We've run out of bytes, probably no end marker. Don't proceed. */
01624         break;
01625       }
01626     }
01627   }
01628   /* is this an overloaded message? */
01629   if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) {
01630     u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD);
01631     dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD);
01632     if (overload == DHCP_OVERLOAD_FILE) {
01633       parse_file_as_options = 1;
01634       LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n"));
01635     } else if (overload == DHCP_OVERLOAD_SNAME) {
01636       parse_sname_as_options = 1;
01637       LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n"));
01638     } else if (overload == DHCP_OVERLOAD_SNAME_FILE) {
01639       parse_sname_as_options = 1;
01640       parse_file_as_options = 1;
01641       LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n"));
01642     } else {
01643       LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload));
01644     }
01645 #if LWIP_DHCP_BOOTP_FILE
01646     if (!parse_file_as_options) {
01647       /* only do this for ACK messages */
01648       if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) &&
01649         (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
01650       /* copy bootp file name, don't care for sname (server hostname) */
01651       if (pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS) != (DHCP_FILE_LEN-1)) {
01652         return ERR_BUF;
01653       }
01654       /* make sure the string is really NULL-terminated */
01655       dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0;
01656     }
01657 #endif /* LWIP_DHCP_BOOTP_FILE */
01658   }
01659   if (parse_file_as_options) {
01660     /* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */
01661     parse_file_as_options = 0;
01662     options_idx = DHCP_FILE_OFS;
01663     options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN;
01664     goto again;
01665   } else if (parse_sname_as_options) {
01666     parse_sname_as_options = 0;
01667     options_idx = DHCP_SNAME_OFS;
01668     options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN;
01669     goto again;
01670   }
01671   return ERR_OK;
01672 }
01673 
01674 /**
01675  * If an incoming DHCP message is in response to us, then trigger the state machine
01676  */
01677 static void
01678 dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
01679 {
01680   struct netif *netif = ip_current_input_netif();
01681   struct dhcp *dhcp = netif_dhcp_data(netif);
01682   struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload;
01683   u8_t msg_type;
01684   u8_t i;
01685 
01686   LWIP_UNUSED_ARG(arg);
01687 
01688   /* Caught DHCP message from netif that does not have DHCP enabled? -> not interested */
01689   if ((dhcp == NULL) || (dhcp->pcb_allocated == 0)) {
01690     goto free_pbuf_and_return;
01691   }
01692 
01693   LWIP_ASSERT("invalid server address type", IP_IS_V4(addr));
01694 
01695   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,
01696     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));
01697   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
01698   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
01699   /* prevent warnings about unused arguments */
01700   LWIP_UNUSED_ARG(pcb);
01701   LWIP_UNUSED_ARG(addr);
01702   LWIP_UNUSED_ARG(port);
01703 
01704   LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL);
01705 
01706   if (p->len < DHCP_MIN_REPLY_LEN) {
01707     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message or pbuf too short\n"));
01708     goto free_pbuf_and_return;
01709   }
01710 
01711   if (reply_msg->op != DHCP_BOOTREPLY) {
01712     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));
01713     goto free_pbuf_and_return;
01714   }
01715   /* iterate through hardware address and match against DHCP message */
01716   for (i = 0; i < netif->hwaddr_len && i < NETIF_MAX_HWADDR_LEN && i < DHCP_CHADDR_LEN; i++) {
01717     if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
01718       LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
01719         ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",
01720         (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));
01721       goto free_pbuf_and_return;
01722     }
01723   }
01724   /* match transaction ID against what we expected */
01725   if (lwip_ntohl(reply_msg->xid) != dhcp->xid) {
01726     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
01727       ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",lwip_ntohl(reply_msg->xid),dhcp->xid));
01728     goto free_pbuf_and_return;
01729   }
01730   /* option fields could be unfold? */
01731   if (dhcp_parse_reply(dhcp, p) != ERR_OK) {
01732     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
01733       ("problem unfolding DHCP message - too short on memory?\n"));
01734     goto free_pbuf_and_return;
01735   }
01736 
01737   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));
01738   /* obtain pointer to DHCP message type */
01739   if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) {
01740     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));
01741     goto free_pbuf_and_return;
01742   }
01743 
01744   /* read DHCP message type */
01745   msg_type = (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE);
01746   /* message type is DHCP ACK? */
01747   if (msg_type == DHCP_ACK) {
01748     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n"));
01749     /* in requesting state? */
01750     if (dhcp->state == DHCP_STATE_REQUESTING) {
01751       dhcp_handle_ack(netif);
01752 #if DHCP_DOES_ARP_CHECK
01753       if ((netif->flags & NETIF_FLAG_ETHARP) != 0) {
01754         /* check if the acknowledged lease address is already in use */
01755         dhcp_check(netif);
01756       } else {
01757         /* bind interface to the acknowledged lease address */
01758         dhcp_bind(netif);
01759       }
01760 #else
01761       /* bind interface to the acknowledged lease address */
01762       dhcp_bind(netif);
01763 #endif
01764     }
01765     /* already bound to the given lease address? */
01766     else if ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REBINDING) ||
01767              (dhcp->state == DHCP_STATE_RENEWING)) {
01768       dhcp_handle_ack(netif);
01769       dhcp_bind(netif);
01770     }
01771   }
01772   /* received a DHCP_NAK in appropriate state? */
01773   else if ((msg_type == DHCP_NAK) &&
01774     ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) ||
01775      (dhcp->state == DHCP_STATE_REBINDING) || (dhcp->state == DHCP_STATE_RENEWING  ))) {
01776     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n"));
01777     dhcp_handle_nak(netif);
01778   }
01779   /* received a DHCP_OFFER in DHCP_STATE_SELECTING state? */
01780   else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_STATE_SELECTING)) {
01781     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_STATE_SELECTING state\n"));
01782     dhcp->request_timeout = 0;
01783     /* remember offered lease */
01784     dhcp_handle_offer(netif);
01785   }
01786 
01787 free_pbuf_and_return:
01788   if (dhcp != NULL) {
01789     dhcp->msg_in = NULL;
01790   }
01791   pbuf_free(p);
01792 }
01793 
01794 /**
01795  * Create a DHCP request, fill in common headers
01796  *
01797  * @param netif the netif under DHCP control
01798  * @param dhcp dhcp control struct
01799  * @param message_type message type of the request
01800  */
01801 static err_t
01802 dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type)
01803 {
01804   u16_t i;
01805 #ifndef DHCP_GLOBAL_XID
01806   /** default global transaction identifier starting value (easy to match
01807    *  with a packet analyser). We simply increment for each new request.
01808    *  Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one
01809    *  at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */
01810 #if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
01811   static u32_t xid;
01812 #else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
01813   static u32_t xid = 0xABCD0000;
01814 #endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
01815 #else
01816   if (!xid_initialised) {
01817     xid = DHCP_GLOBAL_XID;
01818     xid_initialised = !xid_initialised;
01819   }
01820 #endif
01821   LWIP_ERROR("dhcp_create_msg: netif != NULL", (netif != NULL), return ERR_ARG;);
01822   LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return ERR_VAL;);
01823   LWIP_ASSERT("dhcp_create_msg: dhcp->p_out == NULL", dhcp->p_out == NULL);
01824   LWIP_ASSERT("dhcp_create_msg: dhcp->msg_out == NULL", dhcp->msg_out == NULL);
01825   dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
01826   if (dhcp->p_out == NULL) {
01827     LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
01828       ("dhcp_create_msg(): could not allocate pbuf\n"));
01829     return ERR_MEM;
01830   }
01831   LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg",
01832            (dhcp->p_out->len >= sizeof(struct dhcp_msg)));
01833 
01834   /* DHCP_REQUEST should reuse 'xid' from DHCPOFFER */
01835   if (message_type != DHCP_REQUEST) {
01836     /* reuse transaction identifier in retransmissions */
01837     if (dhcp->tries == 0) {
01838 #if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
01839       xid = LWIP_RAND();
01840 #else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
01841       xid++;
01842 #endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
01843     }
01844     dhcp->xid = xid;
01845   }
01846   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
01847               ("transaction id xid(%"X32_F")\n", xid));
01848 
01849   dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;
01850 
01851   dhcp->msg_out->op = DHCP_BOOTREQUEST;
01852   /* @todo: make link layer independent */
01853   dhcp->msg_out->htype = DHCP_HTYPE_ETH;
01854   dhcp->msg_out->hlen = netif->hwaddr_len;
01855   dhcp->msg_out->hops = 0;
01856   dhcp->msg_out->xid = lwip_htonl(dhcp->xid);
01857   dhcp->msg_out->secs = 0;
01858   /* we don't need the broadcast flag since we can receive unicast traffic
01859      before being fully configured! */
01860   dhcp->msg_out->flags = 0;
01861   ip4_addr_set_zero(&dhcp->msg_out->ciaddr);
01862   /* set ciaddr to netif->ip_addr based on message_type and state */
01863   if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || (message_type == DHCP_RELEASE) ||
01864       ((message_type == DHCP_REQUEST) && /* DHCP_STATE_BOUND not used for sending! */
01865        ((dhcp->state== DHCP_STATE_RENEWING) || dhcp->state== DHCP_STATE_REBINDING))) {
01866     ip4_addr_copy(dhcp->msg_out->ciaddr, *netif_ip4_addr(netif));
01867   }
01868   ip4_addr_set_zero(&dhcp->msg_out->yiaddr);
01869   ip4_addr_set_zero(&dhcp->msg_out->siaddr);
01870   ip4_addr_set_zero(&dhcp->msg_out->giaddr);
01871   for (i = 0; i < DHCP_CHADDR_LEN; i++) {
01872     /* copy netif hardware address, pad with zeroes */
01873     dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len && i < NETIF_MAX_HWADDR_LEN) ? netif->hwaddr[i] : 0/* pad byte*/;
01874   }
01875   for (i = 0; i < DHCP_SNAME_LEN; i++) {
01876     dhcp->msg_out->sname[i] = 0;
01877   }
01878   for (i = 0; i < DHCP_FILE_LEN; i++) {
01879     dhcp->msg_out->file[i] = 0;
01880   }
01881   dhcp->msg_out->cookie = PP_HTONL(DHCP_MAGIC_COOKIE);
01882   dhcp->options_out_len = 0;
01883   /* fill options field with an incrementing array (for debugging purposes) */
01884   for (i = 0; i < DHCP_OPTIONS_LEN; i++) {
01885     dhcp->msg_out->options[i] = (u8_t)i; /* for debugging only, no matter if truncated */
01886   }
01887   /* Add option MESSAGE_TYPE */
01888   dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
01889   dhcp_option_byte(dhcp, message_type);
01890   return ERR_OK;
01891 }
01892 
01893 /**
01894  * Free previously allocated memory used to send a DHCP request.
01895  *
01896  * @param dhcp the dhcp struct to free the request from
01897  */
01898 static void
01899 dhcp_delete_msg(struct dhcp *dhcp)
01900 {
01901   LWIP_ERROR("dhcp_delete_msg: dhcp != NULL", (dhcp != NULL), return;);
01902   LWIP_ASSERT("dhcp_delete_msg: dhcp->p_out != NULL", dhcp->p_out != NULL);
01903   LWIP_ASSERT("dhcp_delete_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL);
01904   if (dhcp->p_out != NULL) {
01905     pbuf_free(dhcp->p_out);
01906   }
01907   dhcp->p_out = NULL;
01908   dhcp->msg_out = NULL;
01909 }
01910 
01911 /**
01912  * Add a DHCP message trailer
01913  *
01914  * Adds the END option to the DHCP message, and if
01915  * necessary, up to three padding bytes.
01916  *
01917  * @param dhcp DHCP state structure
01918  */
01919 static void
01920 dhcp_option_trailer(struct dhcp *dhcp)
01921 {
01922   LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;);
01923   LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL);
01924   LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
01925   dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;
01926   /* packet is too small, or not 4 byte aligned? */
01927   while (((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) &&
01928          (dhcp->options_out_len < DHCP_OPTIONS_LEN)) {
01929     /* add a fill/padding byte */
01930     dhcp->msg_out->options[dhcp->options_out_len++] = 0;
01931   }
01932 }
01933 
01934 /** check if DHCP supplied netif->ip_addr
01935  *
01936  * @param netif the netif to check
01937  * @return 1 if DHCP supplied netif->ip_addr (states BOUND or RENEWING),
01938  *         0 otherwise
01939  */
01940 u8_t
01941 dhcp_supplied_address(const struct netif *netif)
01942 {
01943   if ((netif != NULL) && (netif_dhcp_data(netif) != NULL)) {
01944     struct dhcp* dhcp = netif_dhcp_data(netif);
01945     return (dhcp->state == DHCP_STATE_BOUND) || (dhcp->state == DHCP_STATE_RENEWING);
01946   }
01947   return 0;
01948 }
01949 
01950 #endif /* LWIP_IPV4 && LWIP_DHCP */