76 #include "lwip/ip_addr.h"
92 #ifdef DHCP_GLOBAL_XID_HEADER
93 #include DHCP_GLOBAL_XID_HEADER
98 #define DHCP_MAX_MSG_LEN(netif) (netif->mtu)
99 #define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576
101 #define DHCP_MIN_REPLY_LEN 44
103 #define REBOOT_TRIES 2
110 #define DHCP_OPTION_IDX_OVERLOAD 0
111 #define DHCP_OPTION_IDX_MSG_TYPE 1
112 #define DHCP_OPTION_IDX_SERVER_ID 2
113 #define DHCP_OPTION_IDX_LEASE_TIME 3
114 #define DHCP_OPTION_IDX_T1 4
115 #define DHCP_OPTION_IDX_T2 5
116 #define DHCP_OPTION_IDX_SUBNET_MASK 6
117 #define DHCP_OPTION_IDX_ROUTER 7
118 #define DHCP_OPTION_IDX_DNS_SERVER 8
119 #define DHCP_OPTION_IDX_MAX (DHCP_OPTION_IDX_DNS_SERVER + DNS_MAX_SERVERS)
123 u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX];
127 u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX];
129 #define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0)
130 #define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1)
131 #define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0)
132 #define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given)))
133 #define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx])
134 #define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val))
141 #if DHCP_DOES_ARP_CHECK
146 static void dhcp_set_state(
struct dhcp *dhcp,
u8_t new_state);
149 static void dhcp_recv(
void *arg,
struct udp_pcb *pcb,
struct pbuf *p,
ip_addr_t *addr,
u16_t port);
152 static void dhcp_timeout(
struct netif *
netif);
153 static void dhcp_t1_timeout(
struct netif *
netif);
154 static void dhcp_t2_timeout(
struct netif *
netif);
160 static void dhcp_delete_msg(
struct dhcp *dhcp);
162 static void dhcp_option(
struct dhcp *dhcp,
u8_t option_type,
u8_t option_len);
164 static void dhcp_option_byte(
struct dhcp *dhcp,
u8_t value);
165 static void dhcp_option_short(
struct dhcp *dhcp,
u16_t value);
166 static void dhcp_option_long(
struct dhcp *dhcp,
u32_t value);
168 static void dhcp_option_trailer(
struct dhcp *dhcp);
185 struct dhcp *dhcp = netif->dhcp;
195 dhcp_set_state(dhcp, DHCP_BACKING_OFF);
197 dhcp_discover(netif);
200 #if DHCP_DOES_ARP_CHECK
211 dhcp_check(
struct netif *netif)
213 struct dhcp *dhcp = netif->dhcp;
218 dhcp_set_state(dhcp, DHCP_CHECKING);
221 result = etharp_query(netif, &dhcp->offered_ip_addr,
NULL);
227 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
238 dhcp_handle_offer(
struct netif *netif)
240 struct dhcp *dhcp = netif->dhcp;
244 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) {
245 ip4_addr_set_u32(&dhcp->server_ip_addr,
htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID)));
249 ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr);
256 (
"dhcp_handle_offer(netif=%p) did not get server ID!\n", (
void*)netif));
269 dhcp_select(
struct netif *netif)
271 struct dhcp *dhcp = netif->dhcp;
276 dhcp_set_state(dhcp, DHCP_REQUESTING);
279 result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
281 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
282 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
285 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
288 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
291 dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4);
292 dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
293 dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
294 dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
295 dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
297 #if LWIP_NETIF_HOSTNAME
298 if (netif->hostname !=
NULL) {
299 const char *p = (
const char*)netif->hostname;
302 LWIP_ASSERT(
"DHCP: hostname is too long!", namelen < 255);
303 dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, namelen);
305 dhcp_option_byte(dhcp, *p++);
311 dhcp_option_trailer(dhcp);
313 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
316 udp_sendto_if(dhcp->pcb, dhcp->p_out,
IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
317 dhcp_delete_msg(dhcp);
323 msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
324 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
338 while (netif !=
NULL) {
340 if (netif->dhcp !=
NULL) {
342 if (netif->dhcp->t2_timeout-- == 1) {
345 dhcp_t2_timeout(netif);
347 }
else if (netif->dhcp->t1_timeout-- == 1) {
350 dhcp_t1_timeout(netif);
369 while (netif !=
NULL) {
371 if (netif->dhcp !=
NULL) {
373 if (netif->dhcp->request_timeout > 1) {
374 netif->dhcp->request_timeout--;
376 else if (netif->dhcp->request_timeout == 1) {
377 netif->dhcp->request_timeout--;
398 dhcp_timeout(
struct netif *netif)
400 struct dhcp *dhcp = netif->dhcp;
403 if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) {
405 dhcp_discover(netif);
407 }
else if (dhcp->state == DHCP_REQUESTING) {
409 if (dhcp->tries <= 5) {
414 dhcp_discover(netif);
416 #if DHCP_DOES_ARP_CHECK
418 }
else if (dhcp->state == DHCP_CHECKING) {
420 if (dhcp->tries <= 1) {
431 else if (dhcp->state == DHCP_RENEWING) {
437 }
else if (dhcp->state == DHCP_REBINDING) {
439 if (dhcp->tries <= 8) {
444 dhcp_discover(netif);
446 }
else if (dhcp->state == DHCP_REBOOTING) {
447 if (dhcp->tries < REBOOT_TRIES) {
450 dhcp_discover(netif);
461 dhcp_t1_timeout(
struct netif *netif)
463 struct dhcp *dhcp = netif->dhcp;
465 if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) ||
466 (dhcp->state == DHCP_RENEWING)) {
470 (
"dhcp_t1_timeout(): must renew\n"));
483 dhcp_t2_timeout(
struct netif *netif)
485 struct dhcp *dhcp = netif->dhcp;
487 if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) ||
488 (dhcp->state == DHCP_RENEWING)) {
491 (
"dhcp_t2_timeout(): must rebind\n"));
504 dhcp_handle_ack(
struct netif *netif)
506 struct dhcp *dhcp = netif->dhcp;
514 #if LWIP_DHCP_BOOTP_FILE
519 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) {
521 dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME);
524 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) {
526 dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1);
529 dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;
533 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) {
535 dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2);
538 dhcp->offered_t2_rebind = dhcp->offered_t0_lease;
542 ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr);
544 #if LWIP_DHCP_BOOTP_FILE
547 ip_addr_copy(dhcp->offered_si_addr, dhcp->msg_in->siaddr);
551 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) {
553 ip4_addr_set_u32(&dhcp->offered_sn_mask,
htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)));
554 dhcp->subnet_mask_given = 1;
556 dhcp->subnet_mask_given = 0;
560 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) {
561 ip4_addr_set_u32(&dhcp->offered_gw_addr,
htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER)));
567 while((n <
DNS_MAX_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n)) {
570 dns_setserver(n, &dns_addr);
583 dhcp_set_struct(
struct netif *netif,
struct dhcp *dhcp)
587 LWIP_ASSERT(
"netif already has a struct dhcp set", netif->dhcp ==
NULL);
590 memset(dhcp, 0,
sizeof(
struct dhcp));
602 void dhcp_cleanup(
struct netif *netif)
606 if (netif->dhcp !=
NULL) {
625 dhcp_start(
struct netif *netif)
644 if (netif->
mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) {
652 dhcp = (
struct dhcp *)
mem_malloc(
sizeof(
struct dhcp));
663 if (dhcp->pcb !=
NULL) {
664 udp_remove(dhcp->pcb);
671 memset(dhcp, 0,
sizeof(
struct dhcp));
674 dhcp->pcb = udp_new();
675 if (dhcp->pcb ==
NULL) {
681 udp_bind(dhcp->pcb,
IP_ADDR_ANY, DHCP_CLIENT_PORT);
682 udp_connect(dhcp->pcb,
IP_ADDR_ANY, DHCP_SERVER_PORT);
684 udp_recv(dhcp->pcb, dhcp_recv, netif);
687 result = dhcp_discover(netif);
708 dhcp_inform(
struct netif *netif)
716 memset(&dhcp, 0,
sizeof(
struct dhcp));
717 dhcp_set_state(&dhcp, DHCP_INFORM);
719 if ((netif->dhcp !=
NULL) && (netif->dhcp->pcb !=
NULL)) {
721 pcb = netif->dhcp->pcb;
734 result = dhcp_create_msg(netif, &dhcp, DHCP_INFORM);
736 dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
737 dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(netif));
739 dhcp_option_trailer(&dhcp);
741 pbuf_realloc(dhcp.p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp.options_out_len);
745 dhcp_delete_msg(&dhcp);
750 if (dhcp.pcb !=
NULL) {
752 udp_remove(dhcp.pcb);
762 dhcp_network_changed(
struct netif *netif)
764 struct dhcp *dhcp = netif->dhcp;
767 switch (dhcp->state) {
781 #if LWIP_DHCP_AUTOIP_COOP
782 if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
784 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
787 dhcp_discover(netif);
792 #if DHCP_DOES_ARP_CHECK
799 void dhcp_arp_reply(
struct netif *netif,
ip_addr_t *addr)
804 if ((netif->dhcp !=
NULL) && (netif->dhcp->
state == DHCP_CHECKING)) {
809 if (
ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) {
812 (
"dhcp_arp_reply(): arp reply matched with offered address, declining\n"));
828 dhcp_decline(
struct netif *netif)
830 struct dhcp *dhcp = netif->dhcp;
834 dhcp_set_state(dhcp, DHCP_BACKING_OFF);
836 result = dhcp_create_msg(netif, dhcp, DHCP_DECLINE);
838 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
841 dhcp_option_trailer(dhcp);
843 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
846 udp_sendto_if(dhcp->pcb, dhcp->p_out,
IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
847 dhcp_delete_msg(dhcp);
851 (
"dhcp_decline: could not allocate DHCP request\n"));
855 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
868 dhcp_discover(
struct netif *netif)
870 struct dhcp *dhcp = netif->dhcp;
875 dhcp_set_state(dhcp, DHCP_SELECTING);
877 result = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER);
881 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
882 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
884 dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4);
885 dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
886 dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
887 dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
888 dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
890 dhcp_option_trailer(dhcp);
893 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
896 udp_sendto_if(dhcp->pcb, dhcp->p_out,
IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
898 dhcp_delete_msg(dhcp);
904 #if LWIP_DHCP_AUTOIP_COOP
906 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON;
910 msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
911 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
923 dhcp_bind(
struct netif *netif)
934 if (dhcp->offered_t1_renew != 0xffffffffUL) {
937 timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
938 if(timeout > 0xffff) {
941 dhcp->t1_timeout = (
u16_t)timeout;
942 if (dhcp->t1_timeout == 0) {
943 dhcp->t1_timeout = 1;
948 if (dhcp->offered_t2_rebind != 0xffffffffUL) {
950 timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
951 if(timeout > 0xffff) {
954 dhcp->t2_timeout = (
u16_t)timeout;
955 if (dhcp->t2_timeout == 0) {
956 dhcp->t2_timeout = 1;
961 if (dhcp->subnet_mask_given) {
967 if (first_octet <= 127) {
969 }
else if (first_octet >= 192) {
985 #if LWIP_DHCP_AUTOIP_COOP
986 if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
988 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
1004 dhcp_set_state(dhcp, DHCP_BOUND);
1013 dhcp_renew(
struct netif *netif)
1015 struct dhcp *dhcp = netif->dhcp;
1019 dhcp_set_state(dhcp, DHCP_RENEWING);
1022 result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
1024 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
1025 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
1027 #if LWIP_NETIF_HOSTNAME
1028 if (netif->hostname !=
NULL) {
1029 const char *p = (
const char*)netif->hostname;
1032 LWIP_ASSERT(
"DHCP: hostname is too long!", namelen < 255);
1033 dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, namelen);
1035 dhcp_option_byte(dhcp, *p++);
1042 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
1043 dhcp_option_long(dhcp,
ntohl(dhcp->offered_ip_addr.addr));
1047 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
1048 dhcp_option_long(dhcp,
ntohl(dhcp->server_ip_addr.addr));
1051 dhcp_option_trailer(dhcp);
1053 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1055 udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
1056 dhcp_delete_msg(dhcp);
1064 msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000;
1065 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1076 dhcp_rebind(
struct netif *netif)
1078 struct dhcp *dhcp = netif->dhcp;
1082 dhcp_set_state(dhcp, DHCP_REBINDING);
1085 result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
1087 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
1088 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
1090 #if LWIP_NETIF_HOSTNAME
1091 if (netif->hostname !=
NULL) {
1092 const char *p = (
const char*)netif->hostname;
1095 LWIP_ASSERT(
"DHCP: hostname is too long!", namelen < 255);
1096 dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, namelen);
1098 dhcp_option_byte(dhcp, *p++);
1105 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
1106 dhcp_option_long(dhcp,
ntohl(dhcp->offered_ip_addr.addr));
1108 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
1109 dhcp_option_long(dhcp,
ntohl(dhcp->server_ip_addr.addr));
1112 dhcp_option_trailer(dhcp);
1114 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1117 udp_sendto_if(dhcp->pcb, dhcp->p_out,
IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
1118 dhcp_delete_msg(dhcp);
1124 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
1125 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1136 dhcp_reboot(
struct netif *netif)
1138 struct dhcp *dhcp = netif->dhcp;
1142 dhcp_set_state(dhcp, DHCP_REBOOTING);
1145 result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST);
1147 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
1148 dhcp_option_short(dhcp, 576);
1150 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
1153 dhcp_option_trailer(dhcp);
1155 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1158 udp_sendto_if(dhcp->pcb, dhcp->p_out,
IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
1159 dhcp_delete_msg(dhcp);
1165 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
1166 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1178 dhcp_release(
struct netif *netif)
1180 struct dhcp *dhcp = netif->dhcp;
1186 dhcp_set_state(dhcp, DHCP_OFF);
1192 #if LWIP_DHCP_BOOTP_FILE
1195 dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
1198 result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE);
1200 dhcp_option_trailer(dhcp);
1202 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1204 udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
1205 dhcp_delete_msg(dhcp);
1211 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
1212 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1230 dhcp_stop(
struct netif *netif)
1233 LWIP_ERROR(
"dhcp_stop: netif != NULL", (netif !=
NULL),
return;);
1241 #if LWIP_DHCP_AUTOIP_COOP
1242 if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
1244 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
1248 if (dhcp->pcb !=
NULL) {
1249 udp_remove(dhcp->pcb);
1253 dhcp_set_state(dhcp, DHCP_OFF);
1263 dhcp_set_state(
struct dhcp *dhcp,
u8_t new_state)
1265 if (new_state != dhcp->state) {
1266 dhcp->state = new_state;
1268 dhcp->request_timeout = 0;
1278 dhcp_option(
struct dhcp *dhcp,
u8_t option_type,
u8_t option_len)
1280 LWIP_ASSERT(
"dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN);
1281 dhcp->msg_out->options[dhcp->options_out_len++] = option_type;
1282 dhcp->msg_out->options[dhcp->options_out_len++] = option_len;
1289 dhcp_option_byte(
struct dhcp *dhcp,
u8_t value)
1291 LWIP_ASSERT(
"dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);
1292 dhcp->msg_out->options[dhcp->options_out_len++] = value;
1296 dhcp_option_short(
struct dhcp *dhcp,
u16_t value)
1298 LWIP_ASSERT(
"dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN);
1299 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t)((value & 0xff00U) >> 8);
1300 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t) (value & 0x00ffU);
1304 dhcp_option_long(
struct dhcp *dhcp,
u32_t value)
1306 LWIP_ASSERT(
"dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN);
1307 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t)((value & 0xff000000UL) >> 24);
1308 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t)((value & 0x00ff0000UL) >> 16);
1309 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t)((value & 0x0000ff00UL) >> 8);
1310 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t)((value & 0x000000ffUL));
1324 dhcp_parse_reply(
struct dhcp *dhcp,
struct pbuf *p)
1330 u16_t options_idx_max;
1332 int parse_file_as_options = 0;
1333 int parse_sname_as_options = 0;
1336 dhcp_clear_all_options(dhcp);
1338 if (p->
len < DHCP_SNAME_OFS) {
1341 dhcp->msg_in = (
struct dhcp_msg *)p->
payload;
1342 #
if LWIP_DHCP_BOOTP_FILE
1344 dhcp->boot_file_name[0] = 0;
1350 options_idx = DHCP_OPTIONS_OFS;
1355 while((q !=
NULL) && (options_idx >= q->
len)) {
1356 options_idx -= q->
len;
1357 options_idx_max -= q->
len;
1363 offset = options_idx;
1364 offset_max = options_idx_max;
1367 while((q !=
NULL) && (options[offset] != DHCP_OPTION_END) && (offset < offset_max)) {
1368 u8_t op = options[offset];
1370 u8_t decode_len = 0;
1371 int decode_idx = -1;
1372 u16_t val_offset = offset + 2;
1374 if (offset + 1 < q->
len) {
1375 len = options[offset + 1];
1383 case(DHCP_OPTION_PAD):
1385 decode_len = len = 0;
1389 case(DHCP_OPTION_SUBNET_MASK):
1391 decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
1393 case(DHCP_OPTION_ROUTER):
1395 LWIP_ASSERT(
"len >= decode_len", len >= decode_len);
1396 decode_idx = DHCP_OPTION_IDX_ROUTER;
1398 case(DHCP_OPTION_DNS_SERVER):
1403 LWIP_ASSERT(
"len >= decode_len", len >= decode_len);
1404 decode_idx = DHCP_OPTION_IDX_DNS_SERVER;
1406 case(DHCP_OPTION_LEASE_TIME):
1408 decode_idx = DHCP_OPTION_IDX_LEASE_TIME;
1410 case(DHCP_OPTION_OVERLOAD):
1412 decode_idx = DHCP_OPTION_IDX_OVERLOAD;
1414 case(DHCP_OPTION_MESSAGE_TYPE):
1416 decode_idx = DHCP_OPTION_IDX_MSG_TYPE;
1418 case(DHCP_OPTION_SERVER_ID):
1420 decode_idx = DHCP_OPTION_IDX_SERVER_ID;
1422 case(DHCP_OPTION_T1):
1424 decode_idx = DHCP_OPTION_IDX_T1;
1426 case(DHCP_OPTION_T2):
1428 decode_idx = DHCP_OPTION_IDX_T2;
1436 if (decode_len > 0) {
1440 LWIP_ASSERT(
"check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX);
1441 LWIP_ASSERT(
"option already decoded", !dhcp_option_given(dhcp, decode_idx));
1442 copy_len =
LWIP_MIN(decode_len, 4);
1444 if (decode_len > 4) {
1446 LWIP_ASSERT(
"decode_len % 4 == 0", decode_len % 4 == 0);
1447 dhcp_got_option(dhcp, decode_idx);
1448 dhcp_set_option_value(dhcp, decode_idx,
htonl(value));
1453 }
else if (decode_len == 4) {
1454 value =
ntohl(value);
1456 LWIP_ASSERT(
"invalid decode_len", decode_len == 1);
1457 value = ((
u8_t*)&value)[0];
1459 dhcp_got_option(dhcp, decode_idx);
1460 dhcp_set_option_value(dhcp, decode_idx, value);
1462 if (offset >= q->
len) {
1464 offset_max -= q->
len;
1470 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) {
1471 u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD);
1472 dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD);
1473 if (overload == DHCP_OVERLOAD_FILE) {
1474 parse_file_as_options = 1;
1476 }
else if (overload == DHCP_OVERLOAD_SNAME) {
1477 parse_sname_as_options = 1;
1479 }
else if (overload == DHCP_OVERLOAD_SNAME_FILE) {
1480 parse_sname_as_options = 1;
1481 parse_file_as_options = 1;
1486 #if LWIP_DHCP_BOOTP_FILE
1487 if (!parse_file_as_options) {
1489 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) &&
1490 (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
1494 dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0;
1498 if (parse_file_as_options) {
1500 parse_file_as_options = 0;
1501 options_idx = DHCP_FILE_OFS;
1502 options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN;
1504 }
else if (parse_sname_as_options) {
1505 parse_sname_as_options = 0;
1506 options_idx = DHCP_SNAME_OFS;
1507 options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN;
1517 dhcp_recv(
void *arg,
struct udp_pcb *pcb,
struct pbuf *p,
ip_addr_t *addr,
u16_t port)
1519 struct netif *netif = (
struct netif *)arg;
1520 struct dhcp *dhcp = netif->dhcp;
1521 struct dhcp_msg *reply_msg = (
struct dhcp_msg *)p->
payload;
1535 if (p->
len < DHCP_MIN_REPLY_LEN) {
1537 goto free_pbuf_and_return;
1540 if (reply_msg->op != DHCP_BOOTREPLY) {
1542 goto free_pbuf_and_return;
1546 if (netif->
hwaddr[i] != reply_msg->chaddr[i]) {
1548 (
"netif->hwaddr[%"U16_F
"]==%02"X16_F" != reply_msg->chaddr[%"U16_F
"]==%02"X16_F"\n",
1550 goto free_pbuf_and_return;
1554 if (
ntohl(reply_msg->xid) != dhcp->xid) {
1556 (
"transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",
ntohl(reply_msg->xid),dhcp->xid));
1557 goto free_pbuf_and_return;
1560 if (dhcp_parse_reply(dhcp, p) !=
ERR_OK) {
1562 (
"problem unfolding DHCP message - too short on memory?\n"));
1563 goto free_pbuf_and_return;
1568 if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) {
1570 goto free_pbuf_and_return;
1574 msg_type = (
u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE);
1576 if (msg_type == DHCP_ACK) {
1579 if (dhcp->state == DHCP_REQUESTING) {
1580 dhcp_handle_ack(netif);
1581 #if DHCP_DOES_ARP_CHECK
1590 else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) {
1595 else if ((msg_type == DHCP_NAK) &&
1596 ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||
1597 (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) {
1599 dhcp_handle_nak(netif);
1602 else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {
1604 dhcp->request_timeout = 0;
1606 dhcp_handle_offer(netif);
1608 free_pbuf_and_return:
1609 dhcp->msg_in =
NULL;
1621 dhcp_create_msg(
struct netif *netif,
struct dhcp *dhcp,
u8_t message_type)
1624 #ifndef DHCP_GLOBAL_XID
1629 static u32_t xid = 0xABCD0000;
1632 static u8_t xid_initialised = 0;
1633 if (!xid_initialised) {
1634 xid = DHCP_GLOBAL_XID;
1635 xid_initialised = !xid_initialised;
1640 LWIP_ASSERT(
"dhcp_create_msg: dhcp->p_out == NULL", dhcp->p_out ==
NULL);
1641 LWIP_ASSERT(
"dhcp_create_msg: dhcp->msg_out == NULL", dhcp->msg_out ==
NULL);
1643 if (dhcp->p_out ==
NULL) {
1645 (
"dhcp_create_msg(): could not allocate pbuf\n"));
1648 LWIP_ASSERT(
"dhcp_create_msg: check that first pbuf can hold struct dhcp_msg",
1649 (dhcp->p_out->len >=
sizeof(
struct dhcp_msg)));
1652 if (dhcp->tries == 0) {
1657 (
"transaction id xid(%"X32_F")\n", xid));
1659 dhcp->msg_out = (
struct dhcp_msg *)dhcp->p_out->payload;
1661 dhcp->msg_out->op = DHCP_BOOTREQUEST;
1663 dhcp->msg_out->htype = DHCP_HTYPE_ETH;
1665 dhcp->msg_out->hops = 0;
1666 dhcp->msg_out->xid =
htonl(dhcp->xid);
1667 dhcp->msg_out->secs = 0;
1670 dhcp->msg_out->flags = 0;
1673 if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) ||
1674 ((message_type == DHCP_REQUEST) &&
1675 ((dhcp->state==DHCP_RENEWING) || dhcp->state==DHCP_REBINDING))) {
1681 for (i = 0; i < DHCP_CHADDR_LEN; i++) {
1685 for (i = 0; i < DHCP_SNAME_LEN; i++) {
1686 dhcp->msg_out->sname[i] = 0;
1688 for (i = 0; i < DHCP_FILE_LEN; i++) {
1689 dhcp->msg_out->file[i] = 0;
1691 dhcp->msg_out->cookie =
PP_HTONL(DHCP_MAGIC_COOKIE);
1692 dhcp->options_out_len = 0;
1694 for (i = 0; i < DHCP_OPTIONS_LEN; i++) {
1695 dhcp->msg_out->options[i] = (
u8_t)i;
1698 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
1699 dhcp_option_byte(dhcp, message_type);
1709 dhcp_delete_msg(
struct dhcp *dhcp)
1711 LWIP_ERROR(
"dhcp_delete_msg: dhcp != NULL", (dhcp !=
NULL),
return;);
1712 LWIP_ASSERT(
"dhcp_delete_msg: dhcp->p_out != NULL", dhcp->p_out !=
NULL);
1713 LWIP_ASSERT(
"dhcp_delete_msg: dhcp->msg_out != NULL", dhcp->msg_out !=
NULL);
1714 if (dhcp->p_out !=
NULL) {
1718 dhcp->msg_out =
NULL;
1730 dhcp_option_trailer(
struct dhcp *dhcp)
1732 LWIP_ERROR(
"dhcp_option_trailer: dhcp != NULL", (dhcp !=
NULL),
return;);
1733 LWIP_ASSERT(
"dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out !=
NULL);
1734 LWIP_ASSERT(
"dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
1735 dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;
1737 while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) {
1739 LWIP_ASSERT(
"dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
1741 dhcp->msg_out->options[dhcp->options_out_len++] = 0;