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