3 |
* |
* |
4 |
* Dynamic Host Configuration Protocol client |
* Dynamic Host Configuration Protocol client |
5 |
*/ |
*/ |
6 |
|
|
7 |
/* |
/* |
8 |
* |
* |
9 |
* Copyright (c) 2001-2003 Leon Woestenberg <leon.woestenberg@gmx.net> |
* Copyright (c) 2001-2003 Leon Woestenberg <leon.woestenberg@gmx.net> |
10 |
* Copyright (c) 2001-2003 Axon Digital Design B.V., The Netherlands. |
* Copyright (c) 2001-2003 Axon Digital Design B.V., The Netherlands. |
11 |
* All rights reserved. |
* All rights reserved. |
12 |
* |
* |
13 |
* Redistribution and use in source and binary forms, with or without modification, |
* Redistribution and use in source and binary forms, with or without modification, |
14 |
* are permitted provided that the following conditions are met: |
* are permitted provided that the following conditions are met: |
15 |
* |
* |
16 |
* 1. Redistributions of source code must retain the above copyright notice, |
* 1. Redistributions of source code must retain the above copyright notice, |
19 |
* this list of conditions and the following disclaimer in the documentation |
* this list of conditions and the following disclaimer in the documentation |
20 |
* and/or other materials provided with the distribution. |
* and/or other materials provided with the distribution. |
21 |
* 3. The name of the author may not be used to endorse or promote products |
* 3. The name of the author may not be used to endorse or promote products |
22 |
* derived from this software without specific prior written permission. |
* derived from this software without specific prior written permission. |
23 |
* |
* |
24 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
25 |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
26 |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
27 |
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
28 |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
29 |
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
30 |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
31 |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
32 |
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
33 |
* OF SUCH DAMAGE. |
* OF SUCH DAMAGE. |
34 |
* |
* |
35 |
* This file is a contribution to the lwIP TCP/IP stack. |
* This file is a contribution to the lwIP TCP/IP stack. |
36 |
* The Swedish Institute of Computer Science and Adam Dunkels |
* The Swedish Institute of Computer Science and Adam Dunkels |
37 |
* are specifically granted permission to redistribute this |
* are specifically granted permission to redistribute this |
38 |
* source code. |
* source code. |
39 |
* |
* |
40 |
* Author: Leon Woestenberg <leon.woestenberg@gmx.net> |
* Author: Leon Woestenberg <leon.woestenberg@gmx.net> |
41 |
* |
* |
42 |
* This is a DHCP client for the lwIP TCP/IP stack. It aims to conform |
* This is a DHCP client for the lwIP TCP/IP stack. It aims to conform |
43 |
* with RFC 2131 and RFC 2132. |
* with RFC 2131 and RFC 2132. |
44 |
* |
* |
135 |
* We back-off and will end up restarting a fresh DHCP negotiation later. |
* We back-off and will end up restarting a fresh DHCP negotiation later. |
136 |
* |
* |
137 |
* @param state pointer to DHCP state structure |
* @param state pointer to DHCP state structure |
138 |
*/ |
*/ |
139 |
static void dhcp_handle_nak(struct netif *netif) { |
static void dhcp_handle_nak(struct netif *netif) { |
140 |
struct dhcp *dhcp = netif->dhcp; |
struct dhcp *dhcp = netif->dhcp; |
141 |
u16_t msecs = 10 * 1000; |
u16_t msecs = 10 * 1000; |
142 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_nak(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num)); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_nak(netif=%p) %c%c%u\n", netif, |
143 |
|
netif->name[0], netif->name[1], (unsigned int)netif->num)); |
144 |
dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; |
dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; |
145 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %u msecs\n", msecs)); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %u msecs\n", msecs)); |
146 |
dhcp_set_state(dhcp, DHCP_BACKING_OFF); |
dhcp_set_state(dhcp, DHCP_BACKING_OFF); |
148 |
|
|
149 |
/** |
/** |
150 |
* Checks if the offered IP address is already in use. |
* Checks if the offered IP address is already in use. |
151 |
* |
* |
152 |
* It does so by sending an ARP request for the offered address and |
* It does so by sending an ARP request for the offered address and |
153 |
* entering CHECKING state. If no ARP reply is received within a small |
* entering CHECKING state. If no ARP reply is received within a small |
154 |
* interval, the address is assumed to be free for use by us. |
* interval, the address is assumed to be free for use by us. |
158 |
struct dhcp *dhcp = netif->dhcp; |
struct dhcp *dhcp = netif->dhcp; |
159 |
err_t result; |
err_t result; |
160 |
u16_t msecs; |
u16_t msecs; |
161 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_check(netif=%p) %c%c\n", netif, netif->name[0], netif->name[1])); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (unsigned int)netif->name[0], |
162 |
|
(unsigned int)netif->name[1])); |
163 |
/* create an ARP query for the offered IP address, expecting that no host |
/* create an ARP query for the offered IP address, expecting that no host |
164 |
responds, as the IP address should not be in use. */ |
responds, as the IP address should not be in use. */ |
165 |
result = etharp_query(netif, &dhcp->offered_ip_addr, NULL); |
result = etharp_query(netif, &dhcp->offered_ip_addr, NULL); |
175 |
|
|
176 |
/** |
/** |
177 |
* Remember the configuration offered by a DHCP server. |
* Remember the configuration offered by a DHCP server. |
178 |
* |
* |
179 |
* @param state pointer to DHCP state structure |
* @param state pointer to DHCP state structure |
180 |
*/ |
*/ |
181 |
static void dhcp_handle_offer(struct netif *netif) |
static void dhcp_handle_offer(struct netif *netif) |
183 |
struct dhcp *dhcp = netif->dhcp; |
struct dhcp *dhcp = netif->dhcp; |
184 |
/* obtain the server address */ |
/* obtain the server address */ |
185 |
u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID); |
u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID); |
186 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_offer(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num)); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_offer(netif=%p) %c%c%u\n", netif, |
187 |
|
netif->name[0], netif->name[1], netif->num)); |
188 |
if (option_ptr != NULL) |
if (option_ptr != NULL) |
189 |
{ |
{ |
190 |
dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2])); |
dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2])); |
316 |
* A DHCP negotiation transaction, or ARP request, has timed out. |
* A DHCP negotiation transaction, or ARP request, has timed out. |
317 |
* |
* |
318 |
* The timer that was started with the DHCP or ARP request has |
* The timer that was started with the DHCP or ARP request has |
319 |
* timed out, indicating no response was received in time. |
* timed out, indicating no response was received in time. |
320 |
* |
* |
321 |
* @param netif the netif under DHCP control |
* @param netif the netif under DHCP control |
322 |
* |
* |
323 |
*/ |
*/ |
324 |
static void dhcp_timeout(struct netif *netif) |
static void dhcp_timeout(struct netif *netif) |
325 |
{ |
{ |
344 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); |
345 |
if (dhcp->tries <= 1) { |
if (dhcp->tries <= 1) { |
346 |
dhcp_check(netif); |
dhcp_check(netif); |
347 |
/* no ARP replies on the offered address, |
/* no ARP replies on the offered address, |
348 |
looks like the IP address is indeed free */ |
looks like the IP address is indeed free */ |
349 |
} else { |
} else { |
350 |
/* bind the interface to the offered address */ |
/* bind the interface to the offered address */ |
354 |
/* did not get response to renew request? */ |
/* did not get response to renew request? */ |
355 |
else if (dhcp->state == DHCP_RENEWING) { |
else if (dhcp->state == DHCP_RENEWING) { |
356 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n")); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n")); |
357 |
/* just retry renewal */ |
/* just retry renewal */ |
358 |
/* note that the rebind timer will eventually time-out if renew does not work */ |
/* note that the rebind timer will eventually time-out if renew does not work */ |
359 |
dhcp_renew(netif); |
dhcp_renew(netif); |
360 |
/* did not get response to rebind request? */ |
/* did not get response to rebind request? */ |
486 |
* a new client is created first. If a DHCP client instance |
* a new client is created first. If a DHCP client instance |
487 |
* was already present, it restarts negotiation. |
* was already present, it restarts negotiation. |
488 |
* |
* |
489 |
* @param netif The lwIP network interface |
* @param netif The lwIP network interface |
490 |
* @return lwIP error code |
* @return lwIP error code |
491 |
* - ERR_OK - No error |
* - ERR_OK - No error |
492 |
* - ERR_MEM - Out of memory |
* - ERR_MEM - Out of memory |
537 |
|
|
538 |
/** |
/** |
539 |
* Inform a DHCP server of our manual configuration. |
* Inform a DHCP server of our manual configuration. |
540 |
* |
* |
541 |
* This informs DHCP servers of our fixed IP address configuration |
* This informs DHCP servers of our fixed IP address configuration |
542 |
* by sending an INFORM message. It does not involve DHCP address |
* by sending an INFORM message. It does not involve DHCP address |
543 |
* configuration, it is just here to be nice to the network. |
* configuration, it is just here to be nice to the network. |
544 |
* |
* |
545 |
* @param netif The lwIP network interface |
* @param netif The lwIP network interface |
546 |
* |
* |
547 |
*/ |
*/ |
548 |
void dhcp_inform(struct netif *netif) |
void dhcp_inform(struct netif *netif) |
549 |
{ |
{ |
550 |
struct dhcp *dhcp; |
struct dhcp *dhcp; |
553 |
if (dhcp == NULL) { |
if (dhcp == NULL) { |
554 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n")); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n")); |
555 |
return; |
return; |
556 |
} |
} |
557 |
netif->dhcp = dhcp; |
netif->dhcp = dhcp; |
558 |
memset(dhcp, 0, sizeof(struct dhcp)); |
memset(dhcp, 0, sizeof(struct dhcp)); |
559 |
|
|
622 |
} |
} |
623 |
} |
} |
624 |
|
|
625 |
/** |
/** |
626 |
* Decline an offered lease. |
* Decline an offered lease. |
627 |
* |
* |
628 |
* Tell the DHCP server we do not accept the offered address. |
* Tell the DHCP server we do not accept the offered address. |
738 |
LWIP_ASSERT("dhcp_bind: netif != NULL", netif != NULL); |
LWIP_ASSERT("dhcp_bind: netif != NULL", netif != NULL); |
739 |
LWIP_ASSERT("dhcp_bind: dhcp != NULL", dhcp != NULL); |
LWIP_ASSERT("dhcp_bind: dhcp != NULL", dhcp != NULL); |
740 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_bind(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num)); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_bind(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num)); |
741 |
|
|
742 |
/* temporary DHCP lease? */ |
/* temporary DHCP lease? */ |
743 |
if (dhcp->offered_t1_renew != 0xffffffffUL) { |
if (dhcp->offered_t1_renew != 0xffffffffUL) { |
744 |
/* set renewal period timer */ |
/* set renewal period timer */ |
788 |
|
|
789 |
/** |
/** |
790 |
* Renew an existing DHCP lease at the involved DHCP server. |
* Renew an existing DHCP lease at the involved DHCP server. |
791 |
* |
* |
792 |
* @param netif network interface which must renew its lease |
* @param netif network interface which must renew its lease |
793 |
*/ |
*/ |
794 |
err_t dhcp_renew(struct netif *netif) |
err_t dhcp_renew(struct netif *netif) |
843 |
|
|
844 |
/** |
/** |
845 |
* Rebind with a DHCP server for an existing DHCP lease. |
* Rebind with a DHCP server for an existing DHCP lease. |
846 |
* |
* |
847 |
* @param netif network interface which must rebind with a DHCP server |
* @param netif network interface which must rebind with a DHCP server |
848 |
*/ |
*/ |
849 |
static err_t dhcp_rebind(struct netif *netif) |
static err_t dhcp_rebind(struct netif *netif) |
895 |
|
|
896 |
/** |
/** |
897 |
* Release a DHCP lease. |
* Release a DHCP lease. |
898 |
* |
* |
899 |
* @param netif network interface which must release its lease |
* @param netif network interface which must release its lease |
900 |
*/ |
*/ |
901 |
static err_t dhcp_release(struct netif *netif) |
static err_t dhcp_release(struct netif *netif) |
971 |
|
|
972 |
/* |
/* |
973 |
* Set the DHCP state of a DHCP client. |
* Set the DHCP state of a DHCP client. |
974 |
* |
* |
975 |
* If the state changed, reset the number of tries. |
* If the state changed, reset the number of tries. |
976 |
* |
* |
977 |
* TODO: we might also want to reset the timeout here? |
* TODO: we might also want to reset the timeout here? |
1004 |
{ |
{ |
1005 |
LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN); |
LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN); |
1006 |
dhcp->msg_out->options[dhcp->options_out_len++] = value; |
dhcp->msg_out->options[dhcp->options_out_len++] = value; |
1007 |
} |
} |
1008 |
static void dhcp_option_short(struct dhcp *dhcp, u16_t value) |
static void dhcp_option_short(struct dhcp *dhcp, u16_t value) |
1009 |
{ |
{ |
1010 |
LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN); |
LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN); |
1028 |
* and also allows overriding some fields for options, the easy approach |
* and also allows overriding some fields for options, the easy approach |
1029 |
* is to first unfold the options into a conitguous piece of memory, and |
* is to first unfold the options into a conitguous piece of memory, and |
1030 |
* use that further on. |
* use that further on. |
1031 |
* |
* |
1032 |
*/ |
*/ |
1033 |
static err_t dhcp_unfold_reply(struct dhcp *dhcp) |
static err_t dhcp_unfold_reply(struct dhcp *dhcp) |
1034 |
{ |
{ |
1046 |
dhcp->options_in = mem_malloc(dhcp->options_in_len); |
dhcp->options_in = mem_malloc(dhcp->options_in_len); |
1047 |
if (dhcp->options_in == NULL) |
if (dhcp->options_in == NULL) |
1048 |
{ |
{ |
1049 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->options\n")); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->options\n")); |
1050 |
return ERR_MEM; |
return ERR_MEM; |
1051 |
} |
} |
1052 |
} |
} |
1053 |
dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN); |
dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN); |
1054 |
if (dhcp->msg_in == NULL) |
if (dhcp->msg_in == NULL) |
1055 |
{ |
{ |
1056 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n")); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n")); |
1057 |
mem_free((void *)dhcp->options_in); |
mem_free((void *)dhcp->options_in); |
1058 |
dhcp->options_in = NULL; |
dhcp->options_in = NULL; |
1059 |
return ERR_MEM; |
return ERR_MEM; |
1072 |
j = 0; |
j = 0; |
1073 |
} |
} |
1074 |
} |
} |
1075 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes into dhcp->msg_in[]\n", i)); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes into dhcp->msg_in[]\n", i)); |
1076 |
if (dhcp->options_in != NULL) { |
if (dhcp->options_in != NULL) { |
1077 |
ptr = (u8_t *)dhcp->options_in; |
ptr = (u8_t *)dhcp->options_in; |
1078 |
/* proceed through options */ |
/* proceed through options */ |
1085 |
j = 0; |
j = 0; |
1086 |
} |
} |
1087 |
} |
} |
1088 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes to dhcp->options_in[]\n", i)); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes to dhcp->options_in[]\n", i)); |
1089 |
} |
} |
1090 |
return ERR_OK; |
return ERR_OK; |
1091 |
} |
} |
1092 |
|
|
1093 |
/** |
/** |
1094 |
* Free the incoming DHCP message including contiguous copy of |
* Free the incoming DHCP message including contiguous copy of |
1095 |
* its DHCP options. |
* its DHCP options. |
1096 |
* |
* |
1097 |
*/ |
*/ |
1106 |
dhcp->options_in = NULL; |
dhcp->options_in = NULL; |
1107 |
dhcp->options_in_len = 0; |
dhcp->options_in_len = 0; |
1108 |
} |
} |
1109 |
LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n")); |
LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n")); |
1110 |
} |
} |
1111 |
|
|
1112 |
|
|
1138 |
} |
} |
1139 |
/* iterate through hardware address and match against DHCP message */ |
/* iterate through hardware address and match against DHCP message */ |
1140 |
for (i = 0; i < netif->hwaddr_len; i++) { |
for (i = 0; i < netif->hwaddr_len; i++) { |
1141 |
if (netif->hwaddr[i] != reply_msg->chaddr[i]) { |
if (netif->hwaddr[i] != reply_msg->chaddr[i]) { |
1142 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%u]==%02x != reply_msg->chaddr[%u]==%02x\n", |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%u]==%02x != reply_msg->chaddr[%u]==%02x\n", |
1143 |
i, netif->hwaddr[i], i, reply_msg->chaddr[i])); |
i, netif->hwaddr[i], i, reply_msg->chaddr[i])); |
1144 |
pbuf_free(p); |
pbuf_free(p); |
1160 |
dhcp->p = NULL; |
dhcp->p = NULL; |
1161 |
return; |
return; |
1162 |
} |
} |
1163 |
|
|
1164 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n")); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n")); |
1165 |
/* obtain pointer to DHCP message type */ |
/* obtain pointer to DHCP message type */ |
1166 |
options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE); |
options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE); |
1167 |
if (options_ptr == NULL) { |
if (options_ptr == NULL) { |
1168 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); |
1169 |
pbuf_free(p); |
pbuf_free(p); |
1170 |
dhcp->p = NULL; |
dhcp->p = NULL; |
1171 |
return; |
return; |
1172 |
} |
} |
1173 |
|
|
1174 |
/* read DHCP message type */ |
/* read DHCP message type */ |
1175 |
msg_type = dhcp_get_option_byte(options_ptr + 2); |
msg_type = dhcp_get_option_byte(options_ptr + 2); |
1176 |
/* message type is DHCP ACK? */ |
/* message type is DHCP ACK? */ |
1177 |
if (msg_type == DHCP_ACK) { |
if (msg_type == DHCP_ACK) { |
1178 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_ACK received\n")); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_ACK received\n")); |
1179 |
/* in requesting state? */ |
/* in requesting state? */ |
1180 |
if (dhcp->state == DHCP_REQUESTING) { |
if (dhcp->state == DHCP_REQUESTING) { |
1181 |
dhcp_handle_ack(netif); |
dhcp_handle_ack(netif); |
1196 |
} |
} |
1197 |
/* received a DHCP_NAK in appropriate state? */ |
/* received a DHCP_NAK in appropriate state? */ |
1198 |
else if ((msg_type == DHCP_NAK) && |
else if ((msg_type == DHCP_NAK) && |
1199 |
((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) || |
((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) || |
1200 |
(dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) { |
(dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) { |
1201 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_NAK received\n")); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_NAK received\n")); |
1202 |
dhcp->request_timeout = 0; |
dhcp->request_timeout = 0; |
1203 |
dhcp_handle_nak(netif); |
dhcp_handle_nak(netif); |
1204 |
} |
} |
1205 |
/* received a DHCP_OFFER in DHCP_SELECTING state? */ |
/* received a DHCP_OFFER in DHCP_SELECTING state? */ |
1206 |
else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) { |
else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) { |
1207 |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OFFER received in DHCP_SELECTING state\n")); |
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OFFER received in DHCP_SELECTING state\n")); |
1208 |
dhcp->request_timeout = 0; |
dhcp->request_timeout = 0; |
1209 |
/* remember offered lease */ |
/* remember offered lease */ |
1210 |
dhcp_handle_offer(netif); |
dhcp_handle_offer(netif); |
1226 |
return ERR_MEM; |
return ERR_MEM; |
1227 |
} |
} |
1228 |
/* give unique transaction identifier to this request */ |
/* give unique transaction identifier to this request */ |
1229 |
dhcp->xid = xid++; |
dhcp->xid = xid++; |
1230 |
|
|
1231 |
dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload; |
dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload; |
1232 |
|
|
1233 |
dhcp->msg_out->op = DHCP_BOOTREQUEST; |
dhcp->msg_out->op = DHCP_BOOTREQUEST; |
1234 |
/* TODO: make link layer independent */ |
/* TODO: make link layer independent */ |
1235 |
dhcp->msg_out->htype = DHCP_HTYPE_ETH; |
dhcp->msg_out->htype = DHCP_HTYPE_ETH; |
1236 |
/* TODO: make link layer independent */ |
/* TODO: make link layer independent */ |
1237 |
dhcp->msg_out->hlen = DHCP_HLEN_ETH; |
dhcp->msg_out->hlen = DHCP_HLEN_ETH; |
1238 |
dhcp->msg_out->hops = 0; |
dhcp->msg_out->hops = 0; |
1239 |
dhcp->msg_out->xid = htonl(dhcp->xid); |
dhcp->msg_out->xid = htonl(dhcp->xid); |
1240 |
dhcp->msg_out->secs = 0; |
dhcp->msg_out->secs = 0; |
1241 |
dhcp->msg_out->flags = 0; |
dhcp->msg_out->flags = 0; |
1242 |
dhcp->msg_out->ciaddr = netif->ip_addr.addr; |
dhcp->msg_out->ciaddr = netif->ip_addr.addr; |
1377 |
{ |
{ |
1378 |
LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%u\n", *ptr)); |
LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%u\n", *ptr)); |
1379 |
return *ptr; |
return *ptr; |
1380 |
} |
} |
1381 |
|
|
1382 |
/** |
/** |
1383 |
* Return the 16-bit value of DHCP option data. |
* Return the 16-bit value of DHCP option data. |
1394 |
value |= *ptr; |
value |= *ptr; |
1395 |
LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%u\n", value)); |
LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%u\n", value)); |
1396 |
return value; |
return value; |
1397 |
} |
} |
1398 |
|
|
1399 |
/** |
/** |
1400 |
* Return the 32-bit value of DHCP option data. |
* Return the 32-bit value of DHCP option data. |
1413 |
value |= (u32_t)(*ptr++); |
value |= (u32_t)(*ptr++); |
1414 |
LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%lu\n", value)); |
LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%lu\n", value)); |
1415 |
return value; |
return value; |
1416 |
} |
} |