76#include "lwip/ip_addr.h"
89#ifndef DHCP_CREATE_RAND_XID
90#define DHCP_CREATE_RAND_XID 1
98#ifdef DHCP_GLOBAL_XID_HEADER
99#include DHCP_GLOBAL_XID_HEADER
104#define DHCP_MAX_MSG_LEN(netif) (netif->mtu)
105#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576
107#define DHCP_MIN_REPLY_LEN 44
109#define REBOOT_TRIES 2
116#define DHCP_OPTION_IDX_OVERLOAD 0
117#define DHCP_OPTION_IDX_MSG_TYPE 1
118#define DHCP_OPTION_IDX_SERVER_ID 2
119#define DHCP_OPTION_IDX_LEASE_TIME 3
120#define DHCP_OPTION_IDX_T1 4
121#define DHCP_OPTION_IDX_T2 5
122#define DHCP_OPTION_IDX_SUBNET_MASK 6
123#define DHCP_OPTION_IDX_ROUTER 7
124#define DHCP_OPTION_IDX_DNS_SERVER 8
125#define DHCP_OPTION_IDX_MAX (DHCP_OPTION_IDX_DNS_SERVER + DNS_MAX_SERVERS)
129u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX];
133u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX];
135#ifdef DHCP_GLOBAL_XID
137static u8_t xid_initialised;
140#define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0)
141#define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1)
142#define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0)
143#define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given)))
144#define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx])
145#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val))
152#if DHCP_DOES_ARP_CHECK
157static void dhcp_set_state(
struct dhcp *dhcp,
u8_t new_state);
160static void dhcp_recv(
void *arg,
struct udp_pcb *pcb,
struct pbuf *p,
ip_addr_t *addr,
u16_t port);
164static void dhcp_t1_timeout(
struct netif *
netif);
165static void dhcp_t2_timeout(
struct netif *
netif);
171static void dhcp_delete_msg(
struct dhcp *dhcp);
173static void dhcp_option(
struct dhcp *dhcp,
u8_t option_type,
u8_t option_len);
175static void dhcp_option_byte(
struct dhcp *dhcp,
u8_t value);
176static void dhcp_option_short(
struct dhcp *dhcp,
u16_t value);
177static void dhcp_option_long(
struct dhcp *dhcp,
u32_t value);
178#if LWIP_NETIF_HOSTNAME
179static void dhcp_option_hostname(
struct dhcp *dhcp,
struct netif *
netif);
182static void dhcp_option_trailer(
struct dhcp *dhcp);
199 struct dhcp *dhcp =
netif->dhcp;
209 dhcp_set_state(dhcp, DHCP_BACKING_OFF);
211 dhcp_discover(
netif);
214#if DHCP_DOES_ARP_CHECK
227 struct dhcp *dhcp =
netif->dhcp;
232 dhcp_set_state(dhcp, DHCP_CHECKING);
235 result = etharp_query(
netif, &dhcp->offered_ip_addr,
NULL);
241 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
254 struct dhcp *dhcp =
netif->dhcp;
258 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) {
259 ip4_addr_set_u32(&dhcp->server_ip_addr,
htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID)));
263 ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr);
270 (
"dhcp_handle_offer(netif=%p) did not get server ID!\n", (
void*)
netif));
285 struct dhcp *dhcp =
netif->dhcp;
290 dhcp_set_state(dhcp, DHCP_REQUESTING);
293 result = dhcp_create_msg(
netif, dhcp, DHCP_REQUEST);
295 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
296 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(
netif));
299 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
302 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
305 dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4);
306 dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
307 dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
308 dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
309 dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
311#if LWIP_NETIF_HOSTNAME
312 dhcp_option_hostname(dhcp,
netif);
315 dhcp_option_trailer(dhcp);
317 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
321 dhcp_delete_msg(dhcp);
327 msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
328 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
346 if (
netif->dhcp->t2_timeout-- == 1) {
349 dhcp_t2_timeout(
netif);
351 }
else if (
netif->dhcp->t1_timeout-- == 1) {
354 dhcp_t1_timeout(
netif);
377 if (
netif->dhcp->request_timeout > 1) {
378 netif->dhcp->request_timeout--;
380 else if (
netif->dhcp->request_timeout == 1) {
381 netif->dhcp->request_timeout--;
404 struct dhcp *dhcp =
netif->dhcp;
407 if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) {
409 dhcp_discover(
netif);
411 }
else if (dhcp->state == DHCP_REQUESTING) {
413 if (dhcp->tries <= 5) {
418 dhcp_discover(
netif);
420#if DHCP_DOES_ARP_CHECK
422 }
else if (dhcp->state == DHCP_CHECKING) {
424 if (dhcp->tries <= 1) {
435 else if (dhcp->state == DHCP_RENEWING) {
441 }
else if (dhcp->state == DHCP_REBINDING) {
443 if (dhcp->tries <= 8) {
448 dhcp_discover(
netif);
450 }
else if (dhcp->state == DHCP_REBOOTING) {
451 if (dhcp->tries < REBOOT_TRIES) {
454 dhcp_discover(
netif);
467 struct dhcp *dhcp =
netif->dhcp;
469 if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) ||
470 (dhcp->state == DHCP_RENEWING)) {
474 (
"dhcp_t1_timeout(): must renew\n"));
489 struct dhcp *dhcp =
netif->dhcp;
491 if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) ||
492 (dhcp->state == DHCP_RENEWING)) {
495 (
"dhcp_t2_timeout(): must rebind\n"));
510 struct dhcp *dhcp =
netif->dhcp;
518#if LWIP_DHCP_BOOTP_FILE
523 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) {
525 dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME);
528 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) {
530 dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1);
533 dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;
537 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) {
539 dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2);
542 dhcp->offered_t2_rebind = dhcp->offered_t0_lease;
546 ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr);
548#if LWIP_DHCP_BOOTP_FILE
551 ip_addr_copy(dhcp->offered_si_addr, dhcp->msg_in->siaddr);
555 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) {
557 ip4_addr_set_u32(&dhcp->offered_sn_mask,
htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)));
558 dhcp->subnet_mask_given = 1;
560 dhcp->subnet_mask_given = 0;
564 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) {
565 ip4_addr_set_u32(&dhcp->offered_gw_addr,
htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER)));
571 while(dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n) && (n <
DNS_MAX_SERVERS)) {
574 dns_setserver(n, &dns_addr);
587dhcp_set_struct(
struct netif *
netif,
struct dhcp *dhcp)
594 memset(dhcp, 0,
sizeof(
struct dhcp));
648 if (
netif->
mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) {
656 dhcp = (
struct dhcp *)
mem_malloc(
sizeof(
struct dhcp));
667 if (dhcp->pcb !=
NULL) {
668 udp_remove(dhcp->pcb);
675 memset(dhcp, 0,
sizeof(
struct dhcp));
678 dhcp->pcb = udp_new();
679 if (dhcp->pcb ==
NULL) {
685 udp_bind(dhcp->pcb,
IP_ADDR_ANY, DHCP_CLIENT_PORT);
686 udp_connect(dhcp->pcb,
IP_ADDR_ANY, DHCP_SERVER_PORT);
688 udp_recv(dhcp->pcb, dhcp_recv,
netif);
691 result = dhcp_discover(
netif);
720 memset(&dhcp, 0,
sizeof(
struct dhcp));
721 dhcp_set_state(&dhcp, DHCP_INFORM);
725 pcb =
netif->dhcp->pcb;
738 result = dhcp_create_msg(
netif, &dhcp, DHCP_INFORM);
740 dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
741 dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(
netif));
743 dhcp_option_trailer(&dhcp);
745 pbuf_realloc(dhcp.p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp.options_out_len);
749 dhcp_delete_msg(&dhcp);
754 if (dhcp.pcb !=
NULL) {
756 udp_remove(dhcp.pcb);
768 struct dhcp *dhcp =
netif->dhcp;
771 switch (dhcp->state) {
785#if LWIP_DHCP_AUTOIP_COOP
786 if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
788 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
791 dhcp_discover(
netif);
796#if DHCP_DOES_ARP_CHECK
816 (
"dhcp_arp_reply(): arp reply matched with offered address, declining\n"));
834 struct dhcp *dhcp =
netif->dhcp;
838 dhcp_set_state(dhcp, DHCP_BACKING_OFF);
840 result = dhcp_create_msg(
netif, dhcp, DHCP_DECLINE);
842 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
845 dhcp_option_trailer(dhcp);
847 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
851 dhcp_delete_msg(dhcp);
855 (
"dhcp_decline: could not allocate DHCP request\n"));
859 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
874 struct dhcp *dhcp =
netif->dhcp;
879 dhcp_set_state(dhcp, DHCP_SELECTING);
881 result = dhcp_create_msg(
netif, dhcp, DHCP_DISCOVER);
885 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
886 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(
netif));
888 dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4);
889 dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
890 dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
891 dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
892 dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
894 dhcp_option_trailer(dhcp);
897 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
902 dhcp_delete_msg(dhcp);
908#if LWIP_DHCP_AUTOIP_COOP
910 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON;
914 msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
915 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
938 if (dhcp->offered_t1_renew != 0xffffffffUL) {
941 timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
942 if(timeout > 0xffff) {
945 dhcp->t1_timeout = (
u16_t)timeout;
946 if (dhcp->t1_timeout == 0) {
947 dhcp->t1_timeout = 1;
952 if (dhcp->offered_t2_rebind != 0xffffffffUL) {
954 timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
955 if(timeout > 0xffff) {
958 dhcp->t2_timeout = (
u16_t)timeout;
959 if (dhcp->t2_timeout == 0) {
960 dhcp->t2_timeout = 1;
966 if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) {
967 dhcp->t1_timeout = 0;
970 if (dhcp->subnet_mask_given) {
976 if (first_octet <= 127) {
978 }
else if (first_octet >= 192) {
994#if LWIP_DHCP_AUTOIP_COOP
995 if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
997 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
1013 dhcp_set_state(dhcp, DHCP_BOUND);
1024 struct dhcp *dhcp =
netif->dhcp;
1028 dhcp_set_state(dhcp, DHCP_RENEWING);
1031 result = dhcp_create_msg(
netif, dhcp, DHCP_REQUEST);
1033 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
1034 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(
netif));
1037 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
1038 dhcp_option_long(dhcp,
ntohl(dhcp->offered_ip_addr.addr));
1042 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
1043 dhcp_option_long(dhcp,
ntohl(dhcp->server_ip_addr.addr));
1046#if LWIP_NETIF_HOSTNAME
1047 dhcp_option_hostname(dhcp,
netif);
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;
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 dhcp_option_hostname(dhcp,
netif);
1095 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
1096 dhcp_option_long(dhcp,
ntohl(dhcp->offered_ip_addr.addr));
1098 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
1099 dhcp_option_long(dhcp,
ntohl(dhcp->server_ip_addr.addr));
1102 dhcp_option_trailer(dhcp);
1104 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1108 dhcp_delete_msg(dhcp);
1114 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
1115 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1128 struct dhcp *dhcp =
netif->dhcp;
1132 dhcp_set_state(dhcp, DHCP_REBOOTING);
1135 result = dhcp_create_msg(
netif, dhcp, DHCP_REQUEST);
1137 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
1138 dhcp_option_short(dhcp, 576);
1140 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
1143 dhcp_option_trailer(dhcp);
1145 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1149 dhcp_delete_msg(dhcp);
1155 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
1156 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1170 struct dhcp *dhcp =
netif->dhcp;
1176 dhcp_set_state(dhcp, DHCP_OFF);
1182#if LWIP_DHCP_BOOTP_FILE
1185 dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
1188 result = dhcp_create_msg(
netif, dhcp, DHCP_RELEASE);
1190 dhcp_option_trailer(dhcp);
1192 pbuf_realloc(dhcp->p_out,
sizeof(
struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1194 udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT,
netif);
1195 dhcp_delete_msg(dhcp);
1201 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
1202 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1231#if LWIP_DHCP_AUTOIP_COOP
1232 if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
1234 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
1238 if (dhcp->pcb !=
NULL) {
1239 udp_remove(dhcp->pcb);
1243 dhcp_set_state(dhcp, DHCP_OFF);
1253dhcp_set_state(
struct dhcp *dhcp,
u8_t new_state)
1255 if (new_state != dhcp->state) {
1256 dhcp->state = new_state;
1258 dhcp->request_timeout = 0;
1268dhcp_option(
struct dhcp *dhcp,
u8_t option_type,
u8_t option_len)
1270 LWIP_ASSERT(
"dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN);
1271 dhcp->msg_out->options[dhcp->options_out_len++] = option_type;
1272 dhcp->msg_out->options[dhcp->options_out_len++] = option_len;
1279dhcp_option_byte(
struct dhcp *dhcp,
u8_t value)
1281 LWIP_ASSERT(
"dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);
1282 dhcp->msg_out->options[dhcp->options_out_len++] = value;
1286dhcp_option_short(
struct dhcp *dhcp,
u16_t value)
1288 LWIP_ASSERT(
"dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN);
1289 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t)((value & 0xff00U) >> 8);
1290 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t) (value & 0x00ffU);
1294dhcp_option_long(
struct dhcp *dhcp,
u32_t value)
1296 LWIP_ASSERT(
"dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN);
1297 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t)((value & 0xff000000UL) >> 24);
1298 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t)((value & 0x00ff0000UL) >> 16);
1299 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t)((value & 0x0000ff00UL) >> 8);
1300 dhcp->msg_out->options[dhcp->options_out_len++] = (
u8_t)((value & 0x000000ffUL));
1303#if LWIP_NETIF_HOSTNAME
1305dhcp_option_hostname(
struct dhcp *dhcp,
struct netif *
netif)
1308 size_t namelen = strlen(
netif->hostname);
1311 const char *p =
netif->hostname;
1314 size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3;
1315 LWIP_ASSERT(
"DHCP: hostname is too long!", namelen <= available);
1316 len =
LWIP_MIN(namelen, available);
1317 dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, len);
1319 dhcp_option_byte(dhcp, *p++);
1337dhcp_parse_reply(
struct dhcp *dhcp,
struct pbuf *p)
1343 u16_t options_idx_max;
1345 int parse_file_as_options = 0;
1346 int parse_sname_as_options = 0;
1349 dhcp_clear_all_options(dhcp);
1351 if (p->
len < DHCP_SNAME_OFS) {
1354 dhcp->msg_in = (
struct dhcp_msg *)p->
payload;
1355#
if LWIP_DHCP_BOOTP_FILE
1357 dhcp->boot_file_name[0] = 0;
1363 options_idx = DHCP_OPTIONS_OFS;
1368 while((q !=
NULL) && (options_idx >= q->
len)) {
1369 options_idx -= q->
len;
1370 options_idx_max -= q->
len;
1376 offset = options_idx;
1377 offset_max = options_idx_max;
1380 while((q !=
NULL) && (options[offset] != DHCP_OPTION_END) && (offset < offset_max)) {
1381 u8_t op = options[offset];
1383 u8_t decode_len = 0;
1384 int decode_idx = -1;
1385 u16_t val_offset = offset + 2;
1387 if (offset + 1 < q->
len) {
1388 len = options[offset + 1];
1396 case(DHCP_OPTION_PAD):
1398 decode_len = len = 0;
1402 case(DHCP_OPTION_SUBNET_MASK):
1404 decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
1406 case(DHCP_OPTION_ROUTER):
1409 decode_idx = DHCP_OPTION_IDX_ROUTER;
1411 case(DHCP_OPTION_DNS_SERVER):
1417 decode_idx = DHCP_OPTION_IDX_DNS_SERVER;
1419 case(DHCP_OPTION_LEASE_TIME):
1421 decode_idx = DHCP_OPTION_IDX_LEASE_TIME;
1423 case(DHCP_OPTION_OVERLOAD):
1425 decode_idx = DHCP_OPTION_IDX_OVERLOAD;
1427 case(DHCP_OPTION_MESSAGE_TYPE):
1429 decode_idx = DHCP_OPTION_IDX_MSG_TYPE;
1431 case(DHCP_OPTION_SERVER_ID):
1433 decode_idx = DHCP_OPTION_IDX_SERVER_ID;
1435 case(DHCP_OPTION_T1):
1437 decode_idx = DHCP_OPTION_IDX_T1;
1439 case(DHCP_OPTION_T2):
1441 decode_idx = DHCP_OPTION_IDX_T2;
1449 if (decode_len > 0) {
1453 LWIP_ASSERT(
"check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX);
1454 if (!dhcp_option_given(dhcp, decode_idx)) {
1455 copy_len =
LWIP_MIN(decode_len, 4);
1457 if (decode_len > 4) {
1460 dhcp_got_option(dhcp, decode_idx);
1461 dhcp_set_option_value(dhcp, decode_idx,
htonl(value));
1466 }
else if (decode_len == 4) {
1467 value =
ntohl(value);
1470 value = ((
u8_t*)&value)[0];
1472 dhcp_got_option(dhcp, decode_idx);
1473 dhcp_set_option_value(dhcp, decode_idx, value);
1476 if (offset >= q->
len) {
1478 offset_max -= q->
len;
1479 if ((offset < offset_max) && offset_max) {
1490 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) {
1491 u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD);
1492 dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD);
1493 if (overload == DHCP_OVERLOAD_FILE) {
1494 parse_file_as_options = 1;
1496 }
else if (overload == DHCP_OVERLOAD_SNAME) {
1497 parse_sname_as_options = 1;
1499 }
else if (overload == DHCP_OVERLOAD_SNAME_FILE) {
1500 parse_sname_as_options = 1;
1501 parse_file_as_options = 1;
1506#if LWIP_DHCP_BOOTP_FILE
1507 if (!parse_file_as_options) {
1509 if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) &&
1510 (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
1514 dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0;
1518 if (parse_file_as_options) {
1520 parse_file_as_options = 0;
1521 options_idx = DHCP_FILE_OFS;
1522 options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN;
1524 }
else if (parse_sname_as_options) {
1525 parse_sname_as_options = 0;
1526 options_idx = DHCP_SNAME_OFS;
1527 options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN;
1537dhcp_recv(
void *arg,
struct udp_pcb *pcb,
struct pbuf *p,
ip_addr_t *addr,
u16_t port)
1540 struct dhcp *dhcp =
netif->dhcp;
1541 struct dhcp_msg *reply_msg = (
struct dhcp_msg *)p->
payload;
1555 if (p->
len < DHCP_MIN_REPLY_LEN) {
1557 goto free_pbuf_and_return;
1560 if (reply_msg->op != DHCP_BOOTREPLY) {
1562 goto free_pbuf_and_return;
1570 goto free_pbuf_and_return;
1574 if (
ntohl(reply_msg->xid) != dhcp->xid) {
1576 (
"transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",
ntohl(reply_msg->xid),dhcp->xid));
1577 goto free_pbuf_and_return;
1580 if (dhcp_parse_reply(dhcp, p) !=
ERR_OK) {
1582 (
"problem unfolding DHCP message - too short on memory?\n"));
1583 goto free_pbuf_and_return;
1588 if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) {
1590 goto free_pbuf_and_return;
1594 msg_type = (
u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE);
1596 if (msg_type == DHCP_ACK) {
1599 if (dhcp->state == DHCP_REQUESTING) {
1600 dhcp_handle_ack(
netif);
1601#if DHCP_DOES_ARP_CHECK
1610 else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) {
1615 else if ((msg_type == DHCP_NAK) &&
1616 ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||
1617 (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) {
1619 dhcp_handle_nak(
netif);
1622 else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {
1624 dhcp->request_timeout = 0;
1626 dhcp_handle_offer(
netif);
1628free_pbuf_and_return:
1629 dhcp->msg_in =
NULL;
1641dhcp_create_msg(
struct netif *
netif,
struct dhcp *dhcp,
u8_t message_type)
1644#ifndef DHCP_GLOBAL_XID
1649#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
1652 static u32_t xid = 0xABCD0000;
1655 if (!xid_initialised) {
1656 xid = DHCP_GLOBAL_XID;
1657 xid_initialised = !xid_initialised;
1662 LWIP_ASSERT(
"dhcp_create_msg: dhcp->p_out == NULL", dhcp->p_out ==
NULL);
1663 LWIP_ASSERT(
"dhcp_create_msg: dhcp->msg_out == NULL", dhcp->msg_out ==
NULL);
1665 if (dhcp->p_out ==
NULL) {
1667 (
"dhcp_create_msg(): could not allocate pbuf\n"));
1670 LWIP_ASSERT(
"dhcp_create_msg: check that first pbuf can hold struct dhcp_msg",
1671 (dhcp->p_out->len >=
sizeof(
struct dhcp_msg)));
1674 if (dhcp->tries == 0) {
1675#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
1683 (
"transaction id xid(%"X32_F")\n", xid));
1685 dhcp->msg_out = (
struct dhcp_msg *)dhcp->p_out->payload;
1687 dhcp->msg_out->op = DHCP_BOOTREQUEST;
1689 dhcp->msg_out->htype = DHCP_HTYPE_ETH;
1691 dhcp->msg_out->hops = 0;
1692 dhcp->msg_out->xid =
htonl(dhcp->xid);
1693 dhcp->msg_out->secs = 0;
1696 dhcp->msg_out->flags = 0;
1699 if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) ||
1700 ((message_type == DHCP_REQUEST) &&
1701 ((dhcp->state==DHCP_RENEWING) || dhcp->state==DHCP_REBINDING))) {
1707 for (i = 0; i < DHCP_CHADDR_LEN; i++) {
1711 for (i = 0; i < DHCP_SNAME_LEN; i++) {
1712 dhcp->msg_out->sname[i] = 0;
1714 for (i = 0; i < DHCP_FILE_LEN; i++) {
1715 dhcp->msg_out->file[i] = 0;
1717 dhcp->msg_out->cookie =
PP_HTONL(DHCP_MAGIC_COOKIE);
1718 dhcp->options_out_len = 0;
1720 for (i = 0; i < DHCP_OPTIONS_LEN; i++) {
1721 dhcp->msg_out->options[i] = (
u8_t)i;
1724 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
1725 dhcp_option_byte(dhcp, message_type);
1735dhcp_delete_msg(
struct dhcp *dhcp)
1737 LWIP_ERROR(
"dhcp_delete_msg: dhcp != NULL", (dhcp !=
NULL),
return;);
1738 LWIP_ASSERT(
"dhcp_delete_msg: dhcp->p_out != NULL", dhcp->p_out !=
NULL);
1739 LWIP_ASSERT(
"dhcp_delete_msg: dhcp->msg_out != NULL", dhcp->msg_out !=
NULL);
1740 if (dhcp->p_out !=
NULL) {
1744 dhcp->msg_out =
NULL;
1756dhcp_option_trailer(
struct dhcp *dhcp)
1758 LWIP_ERROR(
"dhcp_option_trailer: dhcp != NULL", (dhcp !=
NULL),
return;);
1759 LWIP_ASSERT(
"dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out !=
NULL);
1760 LWIP_ASSERT(
"dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
1761 dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;
1763 while (((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) &&
1764 (dhcp->options_out_len < DHCP_OPTIONS_LEN)) {
1766 dhcp->msg_out->options[dhcp->options_out_len++] = 0;
#define LWIP_UNUSED_ARG(x)
#define LWIP_DBG_LEVEL_SERIOUS
#define LWIP_DEBUGF(debug, message)
#define LWIP_DBG_LEVEL_WARNING
#define LWIP_ERROR(message, expression, handler)
#define LWIP_ASSERT(message, assertion)
#define ip_set_option(pcb, opt)
#define ip_addr_cmp(addr1, addr2)
#define ip_addr_isany(addr1)
#define ip4_addr1_16(ipaddr)
#define ip4_addr1(ipaddr)
#define ip4_addr2_16(ipaddr)
#define ip_addr_copy(dest, src)
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
#define ip_addr_set_any(ipaddr)
#define ip4_addr3_16(ipaddr)
#define ip_addr_set_zero(ipaddr)
#define ip_addr_get_network(target, host, netmask)
#define ip4_addr4_16(ipaddr)
#define ip4_addr_get_u32(src_ipaddr)
#define IP_ADDR_BROADCAST
#define ip4_addr_set_u32(dest_ipaddr, src_u32)
void * mem_malloc(mem_size_t size)
void mem_free(void *rmem)
void netif_set_netmask(struct netif *netif, ip_addr_t *netmask)
struct netif * netif_list
void netif_set_down(struct netif *netif)
void netif_set_gw(struct netif *netif, ip_addr_t *gw)
void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr)
void netif_set_up(struct netif *netif)
#define NETIF_FLAG_ETHARP
#define LWIP_DHCP_AUTOIP_COOP_TRIES
void pbuf_realloc(struct pbuf *p, u16_t new_len)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u16_t pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
u8_t pbuf_free(struct pbuf *p)
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]