Warning, cross-references for /kernel/lwip/core/dhcp.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 #include "lwip/opt.h"
0072
0073 #if LWIP_DHCP
0074
0075 #include "lwip/stats.h"
0076 #include "lwip/mem.h"
0077 #include "lwip/udp.h"
0078 #include "lwip/ip_addr.h"
0079 #include "lwip/netif.h"
0080 #include "lwip/inet.h"
0081 #include "lwip/sys.h"
0082 #include "lwip/dhcp.h"
0083 #include "lwip/autoip.h"
0084 #include "lwip/dns.h"
0085 #include "netif/etharp.h"
0086
0087 #include <string.h>
0088
0089
0090
0091
0092
0093
0094 #ifdef DHCP_GLOBAL_XID_HEADER
0095 #include DHCP_GLOBAL_XID_HEADER
0096 #endif
0097
0098
0099
0100 #define DHCP_MAX_MSG_LEN(netif) (netif->mtu)
0101 #define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576
0102
0103 #define DHCP_MIN_REPLY_LEN 44
0104
0105 #define REBOOT_TRIES 2
0106
0107
0108 static void dhcp_handle_ack(struct netif *netif);
0109 static void dhcp_handle_nak(struct netif *netif);
0110 static void dhcp_handle_offer(struct netif *netif);
0111
0112 static err_t dhcp_discover(struct netif *netif);
0113 static err_t dhcp_select(struct netif *netif);
0114 static void dhcp_bind(struct netif *netif);
0115 #if DHCP_DOES_ARP_CHECK
0116 static void dhcp_check(struct netif *netif);
0117 static err_t dhcp_decline(struct netif *netif);
0118 #endif
0119 static err_t dhcp_rebind(struct netif *netif);
0120 static err_t dhcp_reboot(struct netif *netif);
0121 static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
0122
0123
0124 static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
0125 static err_t dhcp_unfold_reply(struct dhcp *dhcp, struct pbuf *p);
0126 static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type);
0127 static u8_t dhcp_get_option_byte(u8_t *ptr);
0128 #if 0
0129 static u16_t dhcp_get_option_short(u8_t *ptr);
0130 #endif
0131 static u32_t dhcp_get_option_long(u8_t *ptr);
0132 static void dhcp_free_reply(struct dhcp *dhcp);
0133
0134
0135 static void dhcp_timeout(struct netif *netif);
0136 static void dhcp_t1_timeout(struct netif *netif);
0137 static void dhcp_t2_timeout(struct netif *netif);
0138
0139
0140
0141 static err_t dhcp_create_request(struct netif *netif);
0142
0143 static void dhcp_delete_request(struct netif *netif);
0144
0145 static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len);
0146
0147 static void dhcp_option_byte(struct dhcp *dhcp, u8_t value);
0148 static void dhcp_option_short(struct dhcp *dhcp, u16_t value);
0149 static void dhcp_option_long(struct dhcp *dhcp, u32_t value);
0150
0151 static void dhcp_option_trailer(struct dhcp *dhcp);
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 static void
0166 dhcp_handle_nak(struct netif *netif)
0167 {
0168 struct dhcp *dhcp = netif->dhcp;
0169 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n",
0170 (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
0171
0172 netif_set_down(netif);
0173
0174 netif_set_ipaddr(netif, IP_ADDR_ANY);
0175 netif_set_gw(netif, IP_ADDR_ANY);
0176 netif_set_netmask(netif, IP_ADDR_ANY);
0177
0178 dhcp_set_state(dhcp, DHCP_BACKING_OFF);
0179
0180 dhcp_discover(netif);
0181 }
0182
0183 #if DHCP_DOES_ARP_CHECK
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193 static void
0194 dhcp_check(struct netif *netif)
0195 {
0196 struct dhcp *dhcp = netif->dhcp;
0197 err_t result;
0198 u16_t msecs;
0199 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],
0200 (s16_t)netif->name[1]));
0201 dhcp_set_state(dhcp, DHCP_CHECKING);
0202
0203
0204 result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);
0205 if (result != ERR_OK) {
0206 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n"));
0207 }
0208 dhcp->tries++;
0209 msecs = 500;
0210 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
0211 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs));
0212 }
0213 #endif
0214
0215
0216
0217
0218
0219
0220 static void
0221 dhcp_handle_offer(struct netif *netif)
0222 {
0223 struct dhcp *dhcp = netif->dhcp;
0224
0225 u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID);
0226 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",
0227 (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
0228 if (option_ptr != NULL) {
0229 dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
0230 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", dhcp->server_ip_addr.addr));
0231
0232 ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr);
0233 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr));
0234
0235 dhcp_select(netif);
0236 }
0237 }
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 static err_t
0248 dhcp_select(struct netif *netif)
0249 {
0250 struct dhcp *dhcp = netif->dhcp;
0251 err_t result;
0252 u16_t msecs;
0253 #if LWIP_NETIF_HOSTNAME
0254 const char *p;
0255 #endif
0256
0257 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));
0258 dhcp_set_state(dhcp, DHCP_REQUESTING);
0259
0260
0261 result = dhcp_create_request(netif);
0262 if (result == ERR_OK) {
0263 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
0264 dhcp_option_byte(dhcp, DHCP_REQUEST);
0265
0266 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
0267 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
0268
0269
0270 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
0271 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
0272
0273 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
0274 dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
0275
0276 dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4);
0277 dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
0278 dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
0279 dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
0280 dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
0281
0282 #if LWIP_NETIF_HOSTNAME
0283 p = (const char*)netif->hostname;
0284 if (p != NULL) {
0285 dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, strlen(p));
0286 while (*p) {
0287 dhcp_option_byte(dhcp, *p++);
0288 }
0289 }
0290 #endif
0291
0292 dhcp_option_trailer(dhcp);
0293
0294 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
0295
0296
0297 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
0298 dhcp_delete_request(netif);
0299 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n"));
0300 } else {
0301 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n"));
0302 }
0303 dhcp->tries++;
0304 msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
0305 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
0306 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs));
0307 return result;
0308 }
0309
0310
0311
0312
0313
0314 void
0315 dhcp_coarse_tmr()
0316 {
0317 struct netif *netif = netif_list;
0318 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n"));
0319
0320 while (netif != NULL) {
0321
0322 if (netif->dhcp != NULL) {
0323
0324 if (netif->dhcp->t2_timeout-- == 1) {
0325 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));
0326
0327 dhcp_t2_timeout(netif);
0328
0329 } else if (netif->dhcp->t1_timeout-- == 1) {
0330 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));
0331
0332 dhcp_t1_timeout(netif);
0333 }
0334 }
0335
0336 netif = netif->next;
0337 }
0338 }
0339
0340
0341
0342
0343
0344
0345
0346
0347 void
0348 dhcp_fine_tmr()
0349 {
0350 struct netif *netif = netif_list;
0351
0352 while (netif != NULL) {
0353
0354 if (netif->dhcp != NULL) {
0355
0356 if (netif->dhcp->request_timeout > 1) {
0357 netif->dhcp->request_timeout--;
0358 }
0359 else if (netif->dhcp->request_timeout == 1) {
0360 netif->dhcp->request_timeout--;
0361
0362 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));
0363
0364 dhcp_timeout(netif);
0365 }
0366 }
0367
0368 netif = netif->next;
0369 }
0370 }
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 static void
0381 dhcp_timeout(struct netif *netif)
0382 {
0383 struct dhcp *dhcp = netif->dhcp;
0384 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n"));
0385
0386 if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) {
0387 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n"));
0388 dhcp_discover(netif);
0389
0390 } else if (dhcp->state == DHCP_REQUESTING) {
0391 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));
0392 if (dhcp->tries <= 5) {
0393 dhcp_select(netif);
0394 } else {
0395 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
0396 dhcp_release(netif);
0397 dhcp_discover(netif);
0398 }
0399 #if DHCP_DOES_ARP_CHECK
0400
0401 } else if (dhcp->state == DHCP_CHECKING) {
0402 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
0403 if (dhcp->tries <= 1) {
0404 dhcp_check(netif);
0405
0406
0407 } else {
0408
0409 dhcp_bind(netif);
0410 }
0411 #endif
0412 }
0413
0414 else if (dhcp->state == DHCP_RENEWING) {
0415 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n"));
0416
0417
0418 dhcp_renew(netif);
0419
0420 } else if (dhcp->state == DHCP_REBINDING) {
0421 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n"));
0422 if (dhcp->tries <= 8) {
0423 dhcp_rebind(netif);
0424 } else {
0425 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n"));
0426 dhcp_release(netif);
0427 dhcp_discover(netif);
0428 }
0429 } else if (dhcp->state == DHCP_REBOOTING) {
0430 if (dhcp->tries < REBOOT_TRIES) {
0431 dhcp_reboot(netif);
0432 } else {
0433 dhcp_discover(netif);
0434 }
0435 }
0436 }
0437
0438
0439
0440
0441
0442
0443 static void
0444 dhcp_t1_timeout(struct netif *netif)
0445 {
0446 struct dhcp *dhcp = netif->dhcp;
0447 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n"));
0448 if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {
0449
0450
0451 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t1_timeout(): must renew\n"));
0452 dhcp_renew(netif);
0453 }
0454 }
0455
0456
0457
0458
0459
0460
0461 static void
0462 dhcp_t2_timeout(struct netif *netif)
0463 {
0464 struct dhcp *dhcp = netif->dhcp;
0465 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n"));
0466 if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {
0467
0468 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout(): must rebind\n"));
0469 dhcp_rebind(netif);
0470 }
0471 }
0472
0473
0474
0475
0476
0477
0478 static void
0479 dhcp_handle_ack(struct netif *netif)
0480 {
0481 struct dhcp *dhcp = netif->dhcp;
0482 u8_t *option_ptr;
0483
0484 dhcp->offered_sn_mask.addr = 0;
0485 dhcp->offered_gw_addr.addr = 0;
0486 dhcp->offered_bc_addr.addr = 0;
0487
0488
0489 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_LEASE_TIME);
0490 if (option_ptr != NULL) {
0491
0492 dhcp->offered_t0_lease = dhcp_get_option_long(option_ptr + 2);
0493 }
0494
0495 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T1);
0496 if (option_ptr != NULL) {
0497
0498 dhcp->offered_t1_renew = dhcp_get_option_long(option_ptr + 2);
0499 } else {
0500
0501 dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;
0502 }
0503
0504
0505 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T2);
0506 if (option_ptr != NULL) {
0507
0508 dhcp->offered_t2_rebind = dhcp_get_option_long(option_ptr + 2);
0509 } else {
0510
0511 dhcp->offered_t2_rebind = dhcp->offered_t0_lease;
0512 }
0513
0514
0515 ip_addr_set(&dhcp->offered_ip_addr, &dhcp->msg_in->yiaddr);
0516
0517
0518
0519
0520
0521 #if 0
0522
0523 ip_addr_set(&dhcp->offered_si_addr, &dhcp->msg_in->siaddr);
0524
0525 if (dhcp->msg_in->file[0]) {
0526 dhcp->boot_file_name = mem_malloc(strlen(dhcp->msg_in->file) + 1);
0527 strcpy(dhcp->boot_file_name, dhcp->msg_in->file);
0528 }
0529 #endif
0530
0531
0532 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SUBNET_MASK);
0533
0534 if (option_ptr != NULL) {
0535 dhcp->offered_sn_mask.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
0536 }
0537
0538
0539 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_ROUTER);
0540 if (option_ptr != NULL) {
0541 dhcp->offered_gw_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
0542 }
0543
0544
0545 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_BROADCAST);
0546 if (option_ptr != NULL) {
0547 dhcp->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
0548 }
0549
0550
0551 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_DNS_SERVER);
0552 if (option_ptr != NULL) {
0553 u8_t n;
0554 dhcp->dns_count = dhcp_get_option_byte(&option_ptr[1]) / (u32_t)sizeof(struct ip_addr);
0555
0556 if (dhcp->dns_count > DHCP_MAX_DNS)
0557 dhcp->dns_count = DHCP_MAX_DNS;
0558 for (n = 0; n < dhcp->dns_count; n++) {
0559 dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2 + n * 4]));
0560 #if LWIP_DNS
0561 dns_setserver( n, (struct ip_addr *)(&(dhcp->offered_dns_addr[n].addr)));
0562 #endif
0563 }
0564 #if LWIP_DNS
0565 dns_setserver( n, (struct ip_addr *)(&ip_addr_any));
0566 #endif
0567 }
0568 }
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582 err_t
0583 dhcp_start(struct netif *netif)
0584 {
0585 struct dhcp *dhcp;
0586 err_t result = ERR_OK;
0587
0588 LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;);
0589 dhcp = netif->dhcp;
0590 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));
0591
0592
0593 netif->flags &= ~NETIF_FLAG_DHCP;
0594
0595
0596 if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) {
0597 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n"));
0598 return ERR_MEM;
0599 }
0600
0601
0602 if (dhcp == NULL) {
0603 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n"));
0604 dhcp = mem_malloc(sizeof(struct dhcp));
0605 if (dhcp == NULL) {
0606 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));
0607 return ERR_MEM;
0608 }
0609
0610 netif->dhcp = dhcp;
0611 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp"));
0612
0613 } else {
0614 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n"));
0615 if (dhcp->pcb != NULL) {
0616 udp_remove(dhcp->pcb);
0617 }
0618 LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL);
0619 LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL &&
0620 dhcp->options_in == NULL && dhcp->options_in_len == 0);
0621 }
0622
0623
0624 memset(dhcp, 0, sizeof(struct dhcp));
0625
0626 dhcp->pcb = udp_new();
0627 if (dhcp->pcb == NULL) {
0628 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));
0629 mem_free((void *)dhcp);
0630 netif->dhcp = dhcp = NULL;
0631 return ERR_MEM;
0632 }
0633 #if IP_SOF_BROADCAST
0634 dhcp->pcb->so_options|=SOF_BROADCAST;
0635 #endif
0636
0637 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
0638 udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
0639
0640 udp_recv(dhcp->pcb, dhcp_recv, netif);
0641 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
0642
0643 result = dhcp_discover(netif);
0644 if (result != ERR_OK) {
0645
0646 dhcp_stop(netif);
0647 return ERR_MEM;
0648 }
0649
0650 netif->flags |= NETIF_FLAG_DHCP;
0651 return result;
0652 }
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663 void
0664 dhcp_inform(struct netif *netif)
0665 {
0666 struct dhcp *dhcp, *old_dhcp;
0667 err_t result = ERR_OK;
0668 dhcp = mem_malloc(sizeof(struct dhcp));
0669 if (dhcp == NULL) {
0670 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not allocate dhcp\n"));
0671 return;
0672 }
0673 memset(dhcp, 0, sizeof(struct dhcp));
0674
0675 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): allocated dhcp\n"));
0676 dhcp->pcb = udp_new();
0677 if (dhcp->pcb == NULL) {
0678 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not obtain pcb"));
0679 goto free_dhcp_and_return;
0680 }
0681 old_dhcp = netif->dhcp;
0682 netif->dhcp = dhcp;
0683 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));
0684
0685 result = dhcp_create_request(netif);
0686 if (result == ERR_OK) {
0687
0688 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
0689 dhcp_option_byte(dhcp, DHCP_INFORM);
0690
0691 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
0692 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
0693
0694 dhcp_option_trailer(dhcp);
0695
0696 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
0697
0698 #if IP_SOF_BROADCAST
0699 dhcp->pcb->so_options|=SOF_BROADCAST;
0700 #endif
0701 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
0702 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n"));
0703 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
0704 dhcp_delete_request(netif);
0705 } else {
0706 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n"));
0707 }
0708
0709 udp_remove(dhcp->pcb);
0710 dhcp->pcb = NULL;
0711 netif->dhcp = old_dhcp;
0712 free_dhcp_and_return:
0713 mem_free((void *)dhcp);
0714 }
0715
0716
0717
0718
0719
0720
0721 void
0722 dhcp_network_changed(struct netif *netif)
0723 {
0724 struct dhcp *dhcp = netif->dhcp;
0725 if (!dhcp)
0726 return;
0727 switch (dhcp->state) {
0728 case DHCP_REBINDING:
0729 case DHCP_RENEWING:
0730 case DHCP_BOUND:
0731 case DHCP_REBOOTING:
0732 netif_set_down(netif);
0733 dhcp->tries = 0;
0734 dhcp_reboot(netif);
0735 break;
0736 case DHCP_OFF:
0737
0738 break;
0739 default:
0740 dhcp->tries = 0;
0741 dhcp_discover(netif);
0742 break;
0743 }
0744 }
0745
0746 #if DHCP_DOES_ARP_CHECK
0747
0748
0749
0750
0751
0752
0753 void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr)
0754 {
0755 LWIP_ERROR("netif != NULL", (netif != NULL), return;);
0756 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n"));
0757
0758 if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) {
0759 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", addr->addr));
0760
0761
0762 if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) {
0763
0764 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
0765 ("dhcp_arp_reply(): arp reply matched with offered address, declining\n"));
0766 dhcp_decline(netif);
0767 }
0768 }
0769 }
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780 static err_t
0781 dhcp_decline(struct netif *netif)
0782 {
0783 struct dhcp *dhcp = netif->dhcp;
0784 err_t result = ERR_OK;
0785 u16_t msecs;
0786 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n"));
0787 dhcp_set_state(dhcp, DHCP_BACKING_OFF);
0788
0789 result = dhcp_create_request(netif);
0790 if (result == ERR_OK) {
0791 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
0792 dhcp_option_byte(dhcp, DHCP_DECLINE);
0793
0794 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
0795 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
0796
0797 dhcp_option_trailer(dhcp);
0798
0799 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
0800
0801
0802 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
0803 dhcp_delete_request(netif);
0804 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n"));
0805 } else {
0806 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
0807 ("dhcp_decline: could not allocate DHCP request\n"));
0808 }
0809 dhcp->tries++;
0810 msecs = 10*1000;
0811 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
0812 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));
0813 return result;
0814 }
0815 #endif
0816
0817
0818
0819
0820
0821
0822
0823 static err_t
0824 dhcp_discover(struct netif *netif)
0825 {
0826 struct dhcp *dhcp = netif->dhcp;
0827 err_t result = ERR_OK;
0828 u16_t msecs;
0829 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n"));
0830 ip_addr_set(&dhcp->offered_ip_addr, IP_ADDR_ANY);
0831 dhcp_set_state(dhcp, DHCP_SELECTING);
0832
0833 result = dhcp_create_request(netif);
0834 if (result == ERR_OK) {
0835 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n"));
0836 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
0837 dhcp_option_byte(dhcp, DHCP_DISCOVER);
0838
0839 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
0840 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
0841
0842 dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4);
0843 dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
0844 dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
0845 dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
0846 dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
0847
0848 dhcp_option_trailer(dhcp);
0849
0850 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n"));
0851 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
0852
0853 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));
0854 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
0855 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
0856 dhcp_delete_request(netif);
0857 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n"));
0858 } else {
0859 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n"));
0860 }
0861 dhcp->tries++;
0862 #if LWIP_DHCP_AUTOIP_COOP
0863 if(dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) {
0864 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON;
0865 autoip_start(netif);
0866 }
0867 #endif
0868 msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
0869 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
0870 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
0871 return result;
0872 }
0873
0874
0875
0876
0877
0878
0879
0880 static void
0881 dhcp_bind(struct netif *netif)
0882 {
0883 u32_t timeout;
0884 struct dhcp *dhcp;
0885 struct ip_addr sn_mask, gw_addr;
0886 LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;);
0887 dhcp = netif->dhcp;
0888 LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;);
0889 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));
0890
0891
0892 if (dhcp->offered_t1_renew != 0xffffffffUL) {
0893
0894 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));
0895 timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
0896 if(timeout > 0xffff) {
0897 timeout = 0xffff;
0898 }
0899 dhcp->t1_timeout = (u16_t)timeout;
0900 if (dhcp->t1_timeout == 0) {
0901 dhcp->t1_timeout = 1;
0902 }
0903 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000));
0904 }
0905
0906 if (dhcp->offered_t2_rebind != 0xffffffffUL) {
0907 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));
0908 timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
0909 if(timeout > 0xffff) {
0910 timeout = 0xffff;
0911 }
0912 dhcp->t2_timeout = (u16_t)timeout;
0913 if (dhcp->t2_timeout == 0) {
0914 dhcp->t2_timeout = 1;
0915 }
0916 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000));
0917 }
0918
0919 ip_addr_set(&sn_mask, &dhcp->offered_sn_mask);
0920
0921
0922
0923 if (sn_mask.addr == 0) {
0924
0925 u8_t first_octet = ip4_addr1(&sn_mask);
0926 if (first_octet <= 127) {
0927 sn_mask.addr = htonl(0xff000000);
0928 } else if (first_octet >= 192) {
0929 sn_mask.addr = htonl(0xffffff00);
0930 } else {
0931 sn_mask.addr = htonl(0xffff0000);
0932 }
0933 }
0934
0935 ip_addr_set(&gw_addr, &dhcp->offered_gw_addr);
0936
0937 if (gw_addr.addr == 0) {
0938
0939 gw_addr.addr = (dhcp->offered_ip_addr.addr & sn_mask.addr);
0940
0941 gw_addr.addr |= htonl(0x00000001);
0942 }
0943
0944 #if LWIP_DHCP_AUTOIP_COOP
0945 if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
0946 autoip_stop(netif);
0947 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
0948 }
0949 #endif
0950
0951 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr));
0952 netif_set_ipaddr(netif, &dhcp->offered_ip_addr);
0953 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n", sn_mask.addr));
0954 netif_set_netmask(netif, &sn_mask);
0955 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n", gw_addr.addr));
0956 netif_set_gw(netif, &gw_addr);
0957
0958 netif_set_up(netif);
0959
0960 dhcp_set_state(dhcp, DHCP_BOUND);
0961 }
0962
0963
0964
0965
0966
0967
0968 err_t
0969 dhcp_renew(struct netif *netif)
0970 {
0971 struct dhcp *dhcp = netif->dhcp;
0972 err_t result;
0973 u16_t msecs;
0974 #if LWIP_NETIF_HOSTNAME
0975 const char *p;
0976 #endif
0977 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n"));
0978 dhcp_set_state(dhcp, DHCP_RENEWING);
0979
0980
0981 result = dhcp_create_request(netif);
0982 if (result == ERR_OK) {
0983
0984 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
0985 dhcp_option_byte(dhcp, DHCP_REQUEST);
0986
0987 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
0988 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
0989
0990 #if LWIP_NETIF_HOSTNAME
0991 p = (const char*)netif->hostname;
0992 if (p != NULL) {
0993 dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, strlen(p));
0994 while (*p) {
0995 dhcp_option_byte(dhcp, *p++);
0996 }
0997 }
0998 #endif
0999
1000 #if 0
1001 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
1002 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
1003 #endif
1004
1005 #if 0
1006 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
1007 dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
1008 #endif
1009
1010 dhcp_option_trailer(dhcp);
1011
1012 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1013
1014 udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
1015 dhcp_delete_request(netif);
1016
1017 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n"));
1018 } else {
1019 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n"));
1020 }
1021 dhcp->tries++;
1022
1023 msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000;
1024 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1025 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs));
1026 return result;
1027 }
1028
1029
1030
1031
1032
1033
1034 static err_t
1035 dhcp_rebind(struct netif *netif)
1036 {
1037 struct dhcp *dhcp = netif->dhcp;
1038 err_t result;
1039 u16_t msecs;
1040 #if LWIP_NETIF_HOSTNAME
1041 const char *p;
1042 #endif
1043 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n"));
1044 dhcp_set_state(dhcp, DHCP_REBINDING);
1045
1046
1047 result = dhcp_create_request(netif);
1048 if (result == ERR_OK) {
1049
1050 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
1051 dhcp_option_byte(dhcp, DHCP_REQUEST);
1052
1053 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
1054 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
1055
1056 #if LWIP_NETIF_HOSTNAME
1057 p = (const char*)netif->hostname;
1058 if (p != NULL) {
1059 dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, strlen(p));
1060 while (*p) {
1061 dhcp_option_byte(dhcp, *p++);
1062 }
1063 }
1064 #endif
1065
1066 #if 0
1067 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
1068 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
1069
1070 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
1071 dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
1072 #endif
1073
1074 dhcp_option_trailer(dhcp);
1075
1076 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1077
1078
1079 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
1080 dhcp_delete_request(netif);
1081 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n"));
1082 } else {
1083 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n"));
1084 }
1085 dhcp->tries++;
1086 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
1087 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1088 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs));
1089 return result;
1090 }
1091
1092
1093
1094
1095
1096
1097 static err_t
1098 dhcp_reboot(struct netif *netif)
1099 {
1100 struct dhcp *dhcp = netif->dhcp;
1101 err_t result;
1102 u16_t msecs;
1103 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n"));
1104 dhcp_set_state(dhcp, DHCP_REBOOTING);
1105
1106
1107 result = dhcp_create_request(netif);
1108 if (result == ERR_OK) {
1109
1110 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
1111 dhcp_option_byte(dhcp, DHCP_REQUEST);
1112
1113 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
1114 dhcp_option_short(dhcp, 576);
1115
1116 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
1117 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
1118
1119 dhcp_option_trailer(dhcp);
1120
1121 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1122
1123
1124 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
1125 dhcp_delete_request(netif);
1126 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n"));
1127 } else {
1128 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n"));
1129 }
1130 dhcp->tries++;
1131 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
1132 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1133 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs));
1134 return result;
1135 }
1136
1137
1138
1139
1140
1141
1142
1143 err_t
1144 dhcp_release(struct netif *netif)
1145 {
1146 struct dhcp *dhcp = netif->dhcp;
1147 err_t result;
1148 u16_t msecs;
1149 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n"));
1150
1151
1152 dhcp_set_state(dhcp, DHCP_OFF);
1153
1154 dhcp->server_ip_addr.addr = 0;
1155 dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0;
1156 dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0;
1157 dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
1158 dhcp->dns_count = 0;
1159
1160
1161 result = dhcp_create_request(netif);
1162 if (result == ERR_OK) {
1163 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
1164 dhcp_option_byte(dhcp, DHCP_RELEASE);
1165
1166 dhcp_option_trailer(dhcp);
1167
1168 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
1169
1170 udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
1171 dhcp_delete_request(netif);
1172 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n"));
1173 } else {
1174 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n"));
1175 }
1176 dhcp->tries++;
1177 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
1178 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
1179 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs));
1180
1181 netif_set_down(netif);
1182
1183 netif_set_ipaddr(netif, IP_ADDR_ANY);
1184 netif_set_gw(netif, IP_ADDR_ANY);
1185 netif_set_netmask(netif, IP_ADDR_ANY);
1186
1187
1188 return result;
1189 }
1190
1191
1192
1193
1194
1195
1196 void
1197 dhcp_stop(struct netif *netif)
1198 {
1199 struct dhcp *dhcp = netif->dhcp;
1200 LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;);
1201
1202 netif->flags &= ~NETIF_FLAG_DHCP;
1203
1204 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop()\n"));
1205
1206 if (dhcp != NULL) {
1207 #if LWIP_DHCP_AUTOIP_COOP
1208 if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
1209 autoip_stop(netif);
1210 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
1211 }
1212 #endif
1213
1214 if (dhcp->pcb != NULL) {
1215 udp_remove(dhcp->pcb);
1216 dhcp->pcb = NULL;
1217 }
1218 LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL &&
1219 dhcp->options_in == NULL && dhcp->options_in_len == 0);
1220 mem_free((void *)dhcp);
1221 netif->dhcp = NULL;
1222 }
1223 }
1224
1225
1226
1227
1228
1229
1230
1231
1232 static void
1233 dhcp_set_state(struct dhcp *dhcp, u8_t new_state)
1234 {
1235 if (new_state != dhcp->state) {
1236 dhcp->state = new_state;
1237 dhcp->tries = 0;
1238 }
1239 }
1240
1241
1242
1243
1244
1245
1246 static void
1247 dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len)
1248 {
1249 LWIP_ASSERT("dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN);
1250 dhcp->msg_out->options[dhcp->options_out_len++] = option_type;
1251 dhcp->msg_out->options[dhcp->options_out_len++] = option_len;
1252 }
1253
1254
1255
1256
1257 static void
1258 dhcp_option_byte(struct dhcp *dhcp, u8_t value)
1259 {
1260 LWIP_ASSERT("dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);
1261 dhcp->msg_out->options[dhcp->options_out_len++] = value;
1262 }
1263
1264 static void
1265 dhcp_option_short(struct dhcp *dhcp, u16_t value)
1266 {
1267 LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN);
1268 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
1269 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t) (value & 0x00ffU);
1270 }
1271
1272 static void
1273 dhcp_option_long(struct dhcp *dhcp, u32_t value)
1274 {
1275 LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN);
1276 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24);
1277 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16);
1278 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8);
1279 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL));
1280 }
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292 static err_t
1293 dhcp_unfold_reply(struct dhcp *dhcp, struct pbuf *p)
1294 {
1295 u16_t ret;
1296 LWIP_ERROR("dhcp != NULL", (dhcp != NULL), return ERR_ARG;);
1297
1298 dhcp_free_reply(dhcp);
1299
1300 if (p->tot_len > (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN)) {
1301 dhcp->options_in_len = p->tot_len - (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
1302 dhcp->options_in = mem_malloc(dhcp->options_in_len);
1303 if (dhcp->options_in == NULL) {
1304 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
1305 ("dhcp_unfold_reply(): could not allocate dhcp->options\n"));
1306 dhcp->options_in_len = 0;
1307 return ERR_MEM;
1308 }
1309 }
1310 dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
1311 if (dhcp->msg_in == NULL) {
1312 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
1313 ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n"));
1314 if (dhcp->options_in != NULL) {
1315 mem_free(dhcp->options_in);
1316 dhcp->options_in = NULL;
1317 dhcp->options_in_len = 0;
1318 }
1319 return ERR_MEM;
1320 }
1321
1322
1323 ret = pbuf_copy_partial(p, dhcp->msg_in, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN, 0);
1324 LWIP_ASSERT("ret == sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN", ret == sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
1325 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes into dhcp->msg_in[]\n",
1326 sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN));
1327
1328 if (dhcp->options_in != NULL) {
1329
1330 ret = pbuf_copy_partial(p, dhcp->options_in, dhcp->options_in_len, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
1331 LWIP_ASSERT("ret == dhcp->options_in_len", ret == dhcp->options_in_len);
1332 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes to dhcp->options_in[]\n",
1333 dhcp->options_in_len));
1334 }
1335 LWIP_UNUSED_ARG(ret);
1336 return ERR_OK;
1337 }
1338
1339
1340
1341
1342
1343 static void dhcp_free_reply(struct dhcp *dhcp)
1344 {
1345 if (dhcp->msg_in != NULL) {
1346 mem_free((void *)dhcp->msg_in);
1347 dhcp->msg_in = NULL;
1348 }
1349 if (dhcp->options_in) {
1350 mem_free(dhcp->options_in);
1351 dhcp->options_in = NULL;
1352 dhcp->options_in_len = 0;
1353 }
1354 LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n"));
1355 }
1356
1357
1358
1359
1360 static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
1361 {
1362 struct netif *netif = (struct netif *)arg;
1363 struct dhcp *dhcp = netif->dhcp;
1364 struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload;
1365 u8_t *options_ptr;
1366 u8_t msg_type;
1367 u8_t i;
1368 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,
1369 (u16_t)(ntohl(addr->addr) >> 24 & 0xff), (u16_t)(ntohl(addr->addr) >> 16 & 0xff),
1370 (u16_t)(ntohl(addr->addr) >> 8 & 0xff), (u16_t)(ntohl(addr->addr) & 0xff), port));
1371 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
1372 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
1373
1374 LWIP_UNUSED_ARG(pcb);
1375 LWIP_UNUSED_ARG(addr);
1376 LWIP_UNUSED_ARG(port);
1377
1378 LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL &&
1379 dhcp->options_in == NULL && dhcp->options_in_len == 0);
1380
1381 if (p->len < DHCP_MIN_REPLY_LEN) {
1382 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message too short\n"));
1383 goto free_pbuf_and_return;
1384 }
1385
1386 if (reply_msg->op != DHCP_BOOTREPLY) {
1387 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));
1388 goto free_pbuf_and_return;
1389 }
1390
1391 for (i = 0; i < netif->hwaddr_len; i++) {
1392 if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
1393 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
1394 ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",
1395 (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));
1396 goto free_pbuf_and_return;
1397 }
1398 }
1399
1400 if (ntohl(reply_msg->xid) != dhcp->xid) {
1401 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
1402 ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",ntohl(reply_msg->xid),dhcp->xid));
1403 goto free_pbuf_and_return;
1404 }
1405
1406 if (dhcp_unfold_reply(dhcp, p) != ERR_OK) {
1407 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
1408 ("problem unfolding DHCP message - too short on memory?\n"));
1409 goto free_pbuf_and_return;
1410 }
1411
1412 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));
1413
1414 options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE);
1415 if (options_ptr == NULL) {
1416 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));
1417 goto free_pbuf_and_return;
1418 }
1419
1420
1421 msg_type = dhcp_get_option_byte(options_ptr + 2);
1422
1423 if (msg_type == DHCP_ACK) {
1424 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n"));
1425
1426 if (dhcp->state == DHCP_REQUESTING) {
1427 dhcp_handle_ack(netif);
1428 dhcp->request_timeout = 0;
1429 #if DHCP_DOES_ARP_CHECK
1430
1431 dhcp_check(netif);
1432 #else
1433
1434 dhcp_bind(netif);
1435 #endif
1436 }
1437
1438 else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) {
1439 dhcp->request_timeout = 0;
1440 dhcp_bind(netif);
1441 }
1442 }
1443
1444 else if ((msg_type == DHCP_NAK) &&
1445 ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||
1446 (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) {
1447 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n"));
1448 dhcp->request_timeout = 0;
1449 dhcp_handle_nak(netif);
1450 }
1451
1452 else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {
1453 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_SELECTING state\n"));
1454 dhcp->request_timeout = 0;
1455
1456 dhcp_handle_offer(netif);
1457 }
1458 free_pbuf_and_return:
1459 dhcp_free_reply(dhcp);
1460 pbuf_free(p);
1461 }
1462
1463
1464
1465
1466
1467
1468 static err_t
1469 dhcp_create_request(struct netif *netif)
1470 {
1471 struct dhcp *dhcp;
1472 u16_t i;
1473 #ifndef DHCP_GLOBAL_XID
1474
1475
1476
1477
1478 static u32_t xid = 0xABCD0000;
1479 #else
1480 static u32_t xid;
1481 static u8_t xid_initialised = 0;
1482 if (!xid_initialised) {
1483 xid = DHCP_GLOBAL_XID;
1484 xid_initialised = !xid_initialised;
1485 }
1486 #endif
1487 LWIP_ERROR("dhcp_create_request: netif != NULL", (netif != NULL), return ERR_ARG;);
1488 dhcp = netif->dhcp;
1489 LWIP_ERROR("dhcp_create_request: dhcp != NULL", (dhcp != NULL), return ERR_VAL;);
1490 LWIP_ASSERT("dhcp_create_request: dhcp->p_out == NULL", dhcp->p_out == NULL);
1491 LWIP_ASSERT("dhcp_create_request: dhcp->msg_out == NULL", dhcp->msg_out == NULL);
1492 dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
1493 if (dhcp->p_out == NULL) {
1494 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
1495 ("dhcp_create_request(): could not allocate pbuf\n"));
1496 return ERR_MEM;
1497 }
1498 LWIP_ASSERT("dhcp_create_request: check that first pbuf can hold struct dhcp_msg",
1499 (dhcp->p_out->len >= sizeof(struct dhcp_msg)));
1500
1501
1502 if (dhcp->tries==0)
1503 xid++;
1504 dhcp->xid = xid;
1505 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
1506 ("transaction id xid(%"X32_F")\n", xid));
1507
1508 dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;
1509
1510 dhcp->msg_out->op = DHCP_BOOTREQUEST;
1511
1512 dhcp->msg_out->htype = DHCP_HTYPE_ETH;
1513
1514 dhcp->msg_out->hlen = DHCP_HLEN_ETH;
1515 dhcp->msg_out->hops = 0;
1516 dhcp->msg_out->xid = htonl(dhcp->xid);
1517 dhcp->msg_out->secs = 0;
1518 dhcp->msg_out->flags = 0;
1519 dhcp->msg_out->ciaddr.addr = 0;
1520 if (dhcp->state==DHCP_BOUND || dhcp->state==DHCP_RENEWING || dhcp->state==DHCP_REBINDING) {
1521 dhcp->msg_out->ciaddr.addr = netif->ip_addr.addr;
1522 }
1523 dhcp->msg_out->yiaddr.addr = 0;
1524 dhcp->msg_out->siaddr.addr = 0;
1525 dhcp->msg_out->giaddr.addr = 0;
1526 for (i = 0; i < DHCP_CHADDR_LEN; i++) {
1527
1528 dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0;
1529 }
1530 for (i = 0; i < DHCP_SNAME_LEN; i++) {
1531 dhcp->msg_out->sname[i] = 0;
1532 }
1533 for (i = 0; i < DHCP_FILE_LEN; i++) {
1534 dhcp->msg_out->file[i] = 0;
1535 }
1536 dhcp->msg_out->cookie = htonl(0x63825363UL);
1537 dhcp->options_out_len = 0;
1538
1539 for (i = 0; i < DHCP_OPTIONS_LEN; i++) {
1540 dhcp->msg_out->options[i] = (u8_t)i;
1541 }
1542 return ERR_OK;
1543 }
1544
1545
1546
1547
1548
1549
1550 static void
1551 dhcp_delete_request(struct netif *netif)
1552 {
1553 struct dhcp *dhcp;
1554 LWIP_ERROR("dhcp_delete_request: netif != NULL", (netif != NULL), return;);
1555 dhcp = netif->dhcp;
1556 LWIP_ERROR("dhcp_delete_request: dhcp != NULL", (dhcp != NULL), return;);
1557 LWIP_ASSERT("dhcp_delete_request: dhcp->p_out != NULL", dhcp->p_out != NULL);
1558 LWIP_ASSERT("dhcp_delete_request: dhcp->msg_out != NULL", dhcp->msg_out != NULL);
1559 if (dhcp->p_out != NULL) {
1560 pbuf_free(dhcp->p_out);
1561 }
1562 dhcp->p_out = NULL;
1563 dhcp->msg_out = NULL;
1564 }
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574 static void
1575 dhcp_option_trailer(struct dhcp *dhcp)
1576 {
1577 LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;);
1578 LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL);
1579 LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
1580 dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;
1581
1582 while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) {
1583
1584 LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
1585
1586 dhcp->msg_out->options[dhcp->options_out_len++] = 0;
1587 }
1588 }
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599 static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type)
1600 {
1601 u8_t overload = DHCP_OVERLOAD_NONE;
1602
1603
1604 if ((dhcp->options_in != NULL) && (dhcp->options_in_len > 0)) {
1605
1606 u8_t *options = (u8_t *)dhcp->options_in;
1607 u16_t offset = 0;
1608
1609 while ((offset < dhcp->options_in_len) && (options[offset] != DHCP_OPTION_END)) {
1610
1611
1612 if (options[offset] == DHCP_OPTION_OVERLOAD) {
1613 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded message detected\n"));
1614
1615 offset += 2;
1616 overload = options[offset++];
1617 }
1618
1619 else if (options[offset] == option_type) {
1620 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("option found at offset %"U16_F" in options\n", offset));
1621 return &options[offset];
1622
1623 } else {
1624 LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", options[offset]));
1625
1626 offset++;
1627
1628 offset += 1 + options[offset];
1629 }
1630 }
1631
1632 if (overload != DHCP_OVERLOAD_NONE) {
1633 u16_t field_len;
1634 if (overload == DHCP_OVERLOAD_FILE) {
1635 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n"));
1636 options = (u8_t *)&dhcp->msg_in->file;
1637 field_len = DHCP_FILE_LEN;
1638 } else if (overload == DHCP_OVERLOAD_SNAME) {
1639 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n"));
1640 options = (u8_t *)&dhcp->msg_in->sname;
1641 field_len = DHCP_SNAME_LEN;
1642
1643 } else {
1644 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n"));
1645 options = (u8_t *)&dhcp->msg_in->sname;
1646 field_len = DHCP_FILE_LEN + DHCP_SNAME_LEN;
1647 }
1648 offset = 0;
1649
1650
1651 while ((offset < field_len) && (options[offset] != DHCP_OPTION_END)) {
1652 if (options[offset] == option_type) {
1653 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("option found at offset=%"U16_F"\n", offset));
1654 return &options[offset];
1655
1656 } else {
1657 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("skipping option %"U16_F"\n", options[offset]));
1658
1659 offset++;
1660 offset += 1 + options[offset];
1661 }
1662 }
1663 }
1664 }
1665 return NULL;
1666 }
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676 static u8_t
1677 dhcp_get_option_byte(u8_t *ptr)
1678 {
1679 LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%"U16_F"\n", (u16_t)(*ptr)));
1680 return *ptr;
1681 }
1682
1683 #if 0
1684
1685
1686
1687
1688
1689
1690
1691
1692 static u16_t
1693 dhcp_get_option_short(u8_t *ptr)
1694 {
1695 u16_t value;
1696 value = *ptr++ << 8;
1697 value |= *ptr;
1698 LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%"U16_F"\n", value));
1699 return value;
1700 }
1701 #endif
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711 static u32_t dhcp_get_option_long(u8_t *ptr)
1712 {
1713 u32_t value;
1714 value = (u32_t)(*ptr++) << 24;
1715 value |= (u32_t)(*ptr++) << 16;
1716 value |= (u32_t)(*ptr++) << 8;
1717 value |= (u32_t)(*ptr++);
1718 LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%"U32_F"\n", value));
1719 return value;
1720 }
1721
1722 #endif