00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 #include "lwip/opt.h"
00072
00073 #if LWIP_DHCP
00074
00075 #include "lwip/stats.h"
00076 #include "lwip/mem.h"
00077 #include "lwip/udp.h"
00078 #include "lwip/ip_addr.h"
00079 #include "lwip/netif.h"
00080 #include "lwip/inet.h"
00081 #include "lwip/sys.h"
00082 #include "lwip/dhcp.h"
00083 #include "lwip/autoip.h"
00084 #include "lwip/dns.h"
00085 #include "netif/etharp.h"
00086
00087 #include <string.h>
00088
00089
00090
00091
00092
00093
00094 #ifdef DHCP_GLOBAL_XID_HEADER
00095 #include DHCP_GLOBAL_XID_HEADER
00096 #endif
00097
00098
00099
00100 #define DHCP_MAX_MSG_LEN(netif) (netif->mtu)
00101 #define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576
00102
00103 #define DHCP_MIN_REPLY_LEN 44
00104
00105 #define REBOOT_TRIES 2
00106
00107
00108 static void dhcp_handle_ack(struct netif *netif);
00109 static void dhcp_handle_nak(struct netif *netif);
00110 static void dhcp_handle_offer(struct netif *netif);
00111
00112 static err_t dhcp_discover(struct netif *netif);
00113 static err_t dhcp_select(struct netif *netif);
00114 static void dhcp_bind(struct netif *netif);
00115 #if DHCP_DOES_ARP_CHECK
00116 static void dhcp_check(struct netif *netif);
00117 static err_t dhcp_decline(struct netif *netif);
00118 #endif
00119 static err_t dhcp_rebind(struct netif *netif);
00120 static err_t dhcp_reboot(struct netif *netif);
00121 static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
00122
00123
00124 static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
00125 static err_t dhcp_unfold_reply(struct dhcp *dhcp, struct pbuf *p);
00126 static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type);
00127 static u8_t dhcp_get_option_byte(u8_t *ptr);
00128 #if 0
00129 static u16_t dhcp_get_option_short(u8_t *ptr);
00130 #endif
00131 static u32_t dhcp_get_option_long(u8_t *ptr);
00132 static void dhcp_free_reply(struct dhcp *dhcp);
00133
00134
00135 static void dhcp_timeout(struct netif *netif);
00136 static void dhcp_t1_timeout(struct netif *netif);
00137 static void dhcp_t2_timeout(struct netif *netif);
00138
00139
00140
00141 static err_t dhcp_create_request(struct netif *netif);
00142
00143 static void dhcp_delete_request(struct netif *netif);
00144
00145 static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len);
00146
00147 static void dhcp_option_byte(struct dhcp *dhcp, u8_t value);
00148 static void dhcp_option_short(struct dhcp *dhcp, u16_t value);
00149 static void dhcp_option_long(struct dhcp *dhcp, u32_t value);
00150
00151 static void dhcp_option_trailer(struct dhcp *dhcp);
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 static void
00166 dhcp_handle_nak(struct netif *netif)
00167 {
00168 struct dhcp *dhcp = netif->dhcp;
00169 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n",
00170 (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
00171
00172 netif_set_down(netif);
00173
00174 netif_set_ipaddr(netif, IP_ADDR_ANY);
00175 netif_set_gw(netif, IP_ADDR_ANY);
00176 netif_set_netmask(netif, IP_ADDR_ANY);
00177
00178 dhcp_set_state(dhcp, DHCP_BACKING_OFF);
00179
00180 dhcp_discover(netif);
00181 }
00182
00183 #if DHCP_DOES_ARP_CHECK
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 static void
00194 dhcp_check(struct netif *netif)
00195 {
00196 struct dhcp *dhcp = netif->dhcp;
00197 err_t result;
00198 u16_t msecs;
00199 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],
00200 (s16_t)netif->name[1]));
00201 dhcp_set_state(dhcp, DHCP_CHECKING);
00202
00203
00204 result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);
00205 if (result != ERR_OK) {
00206 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n"));
00207 }
00208 dhcp->tries++;
00209 msecs = 500;
00210 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
00211 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs));
00212 }
00213 #endif
00214
00215
00216
00217
00218
00219
00220 static void
00221 dhcp_handle_offer(struct netif *netif)
00222 {
00223 struct dhcp *dhcp = netif->dhcp;
00224
00225 u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID);
00226 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",
00227 (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
00228 if (option_ptr != NULL) {
00229 dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
00230 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", dhcp->server_ip_addr.addr));
00231
00232 ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr);
00233 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr));
00234
00235 dhcp_select(netif);
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 static err_t
00248 dhcp_select(struct netif *netif)
00249 {
00250 struct dhcp *dhcp = netif->dhcp;
00251 err_t result;
00252 u16_t msecs;
00253 #if LWIP_NETIF_HOSTNAME
00254 const char *p;
00255 #endif
00256
00257 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));
00258 dhcp_set_state(dhcp, DHCP_REQUESTING);
00259
00260
00261 result = dhcp_create_request(netif);
00262 if (result == ERR_OK) {
00263 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
00264 dhcp_option_byte(dhcp, DHCP_REQUEST);
00265
00266 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
00267 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
00268
00269
00270 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
00271 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
00272
00273 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
00274 dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
00275
00276 dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4);
00277 dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
00278 dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
00279 dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
00280 dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
00281
00282 #if LWIP_NETIF_HOSTNAME
00283 p = (const char*)netif->hostname;
00284 if (p != NULL) {
00285 dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, strlen(p));
00286 while (*p) {
00287 dhcp_option_byte(dhcp, *p++);
00288 }
00289 }
00290 #endif
00291
00292 dhcp_option_trailer(dhcp);
00293
00294 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
00295
00296
00297 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
00298 dhcp_delete_request(netif);
00299 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n"));
00300 } else {
00301 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n"));
00302 }
00303 dhcp->tries++;
00304 msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
00305 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
00306 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs));
00307 return result;
00308 }
00309
00310
00311
00312
00313
00314 void
00315 dhcp_coarse_tmr()
00316 {
00317 struct netif *netif = netif_list;
00318 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n"));
00319
00320 while (netif != NULL) {
00321
00322 if (netif->dhcp != NULL) {
00323
00324 if (netif->dhcp->t2_timeout-- == 1) {
00325 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));
00326
00327 dhcp_t2_timeout(netif);
00328
00329 } else if (netif->dhcp->t1_timeout-- == 1) {
00330 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));
00331
00332 dhcp_t1_timeout(netif);
00333 }
00334 }
00335
00336 netif = netif->next;
00337 }
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347 void
00348 dhcp_fine_tmr()
00349 {
00350 struct netif *netif = netif_list;
00351
00352 while (netif != NULL) {
00353
00354 if (netif->dhcp != NULL) {
00355
00356 if (netif->dhcp->request_timeout > 1) {
00357 netif->dhcp->request_timeout--;
00358 }
00359 else if (netif->dhcp->request_timeout == 1) {
00360 netif->dhcp->request_timeout--;
00361
00362 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));
00363
00364 dhcp_timeout(netif);
00365 }
00366 }
00367
00368 netif = netif->next;
00369 }
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 static void
00381 dhcp_timeout(struct netif *netif)
00382 {
00383 struct dhcp *dhcp = netif->dhcp;
00384 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n"));
00385
00386 if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) {
00387 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n"));
00388 dhcp_discover(netif);
00389
00390 } else if (dhcp->state == DHCP_REQUESTING) {
00391 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));
00392 if (dhcp->tries <= 5) {
00393 dhcp_select(netif);
00394 } else {
00395 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
00396 dhcp_release(netif);
00397 dhcp_discover(netif);
00398 }
00399 #if DHCP_DOES_ARP_CHECK
00400
00401 } else if (dhcp->state == DHCP_CHECKING) {
00402 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
00403 if (dhcp->tries <= 1) {
00404 dhcp_check(netif);
00405
00406
00407 } else {
00408
00409 dhcp_bind(netif);
00410 }
00411 #endif
00412 }
00413
00414 else if (dhcp->state == DHCP_RENEWING) {
00415 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n"));
00416
00417
00418 dhcp_renew(netif);
00419
00420 } else if (dhcp->state == DHCP_REBINDING) {
00421 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n"));
00422 if (dhcp->tries <= 8) {
00423 dhcp_rebind(netif);
00424 } else {
00425 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n"));
00426 dhcp_release(netif);
00427 dhcp_discover(netif);
00428 }
00429 } else if (dhcp->state == DHCP_REBOOTING) {
00430 if (dhcp->tries < REBOOT_TRIES) {
00431 dhcp_reboot(netif);
00432 } else {
00433 dhcp_discover(netif);
00434 }
00435 }
00436 }
00437
00438
00439
00440
00441
00442
00443 static void
00444 dhcp_t1_timeout(struct netif *netif)
00445 {
00446 struct dhcp *dhcp = netif->dhcp;
00447 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n"));
00448 if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {
00449
00450
00451 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t1_timeout(): must renew\n"));
00452 dhcp_renew(netif);
00453 }
00454 }
00455
00456
00457
00458
00459
00460
00461 static void
00462 dhcp_t2_timeout(struct netif *netif)
00463 {
00464 struct dhcp *dhcp = netif->dhcp;
00465 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n"));
00466 if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {
00467
00468 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout(): must rebind\n"));
00469 dhcp_rebind(netif);
00470 }
00471 }
00472
00473
00474
00475
00476
00477
00478 static void
00479 dhcp_handle_ack(struct netif *netif)
00480 {
00481 struct dhcp *dhcp = netif->dhcp;
00482 u8_t *option_ptr;
00483
00484 dhcp->offered_sn_mask.addr = 0;
00485 dhcp->offered_gw_addr.addr = 0;
00486 dhcp->offered_bc_addr.addr = 0;
00487
00488
00489 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_LEASE_TIME);
00490 if (option_ptr != NULL) {
00491
00492 dhcp->offered_t0_lease = dhcp_get_option_long(option_ptr + 2);
00493 }
00494
00495 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T1);
00496 if (option_ptr != NULL) {
00497
00498 dhcp->offered_t1_renew = dhcp_get_option_long(option_ptr + 2);
00499 } else {
00500
00501 dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2;
00502 }
00503
00504
00505 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T2);
00506 if (option_ptr != NULL) {
00507
00508 dhcp->offered_t2_rebind = dhcp_get_option_long(option_ptr + 2);
00509 } else {
00510
00511 dhcp->offered_t2_rebind = dhcp->offered_t0_lease;
00512 }
00513
00514
00515 ip_addr_set(&dhcp->offered_ip_addr, &dhcp->msg_in->yiaddr);
00516
00517
00518
00519
00520
00521 #if 0
00522
00523 ip_addr_set(&dhcp->offered_si_addr, &dhcp->msg_in->siaddr);
00524
00525 if (dhcp->msg_in->file[0]) {
00526 dhcp->boot_file_name = mem_malloc(strlen(dhcp->msg_in->file) + 1);
00527 strcpy(dhcp->boot_file_name, dhcp->msg_in->file);
00528 }
00529 #endif
00530
00531
00532 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SUBNET_MASK);
00533
00534 if (option_ptr != NULL) {
00535 dhcp->offered_sn_mask.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
00536 }
00537
00538
00539 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_ROUTER);
00540 if (option_ptr != NULL) {
00541 dhcp->offered_gw_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
00542 }
00543
00544
00545 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_BROADCAST);
00546 if (option_ptr != NULL) {
00547 dhcp->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
00548 }
00549
00550
00551 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_DNS_SERVER);
00552 if (option_ptr != NULL) {
00553 u8_t n;
00554 dhcp->dns_count = dhcp_get_option_byte(&option_ptr[1]) / (u32_t)sizeof(struct ip_addr);
00555
00556 if (dhcp->dns_count > DHCP_MAX_DNS)
00557 dhcp->dns_count = DHCP_MAX_DNS;
00558 for (n = 0; n < dhcp->dns_count; n++) {
00559 dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2 + n * 4]));
00560 #if LWIP_DNS
00561 dns_setserver( n, (struct ip_addr *)(&(dhcp->offered_dns_addr[n].addr)));
00562 #endif
00563 }
00564 #if LWIP_DNS
00565 dns_setserver( n, (struct ip_addr *)(&ip_addr_any));
00566 #endif
00567 }
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 err_t
00583 dhcp_start(struct netif *netif)
00584 {
00585 struct dhcp *dhcp;
00586 err_t result = ERR_OK;
00587
00588 LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;);
00589 dhcp = netif->dhcp;
00590 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));
00591
00592
00593 netif->flags &= ~NETIF_FLAG_DHCP;
00594
00595
00596 if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) {
00597 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n"));
00598 return ERR_MEM;
00599 }
00600
00601
00602 if (dhcp == NULL) {
00603 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n"));
00604 dhcp = mem_malloc(sizeof(struct dhcp));
00605 if (dhcp == NULL) {
00606 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));
00607 return ERR_MEM;
00608 }
00609
00610 netif->dhcp = dhcp;
00611 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp"));
00612
00613 } else {
00614 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n"));
00615 if (dhcp->pcb != NULL) {
00616 udp_remove(dhcp->pcb);
00617 }
00618 LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL);
00619 LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL &&
00620 dhcp->options_in == NULL && dhcp->options_in_len == 0);
00621 }
00622
00623
00624 memset(dhcp, 0, sizeof(struct dhcp));
00625
00626 dhcp->pcb = udp_new();
00627 if (dhcp->pcb == NULL) {
00628 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));
00629 mem_free((void *)dhcp);
00630 netif->dhcp = dhcp = NULL;
00631 return ERR_MEM;
00632 }
00633 #if IP_SOF_BROADCAST
00634 dhcp->pcb->so_options|=SOF_BROADCAST;
00635 #endif
00636
00637 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
00638 udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
00639
00640 udp_recv(dhcp->pcb, dhcp_recv, netif);
00641 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
00642
00643 result = dhcp_discover(netif);
00644 if (result != ERR_OK) {
00645
00646 dhcp_stop(netif);
00647 return ERR_MEM;
00648 }
00649
00650 netif->flags |= NETIF_FLAG_DHCP;
00651 return result;
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 void
00664 dhcp_inform(struct netif *netif)
00665 {
00666 struct dhcp *dhcp, *old_dhcp;
00667 err_t result = ERR_OK;
00668 dhcp = mem_malloc(sizeof(struct dhcp));
00669 if (dhcp == NULL) {
00670 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not allocate dhcp\n"));
00671 return;
00672 }
00673 memset(dhcp, 0, sizeof(struct dhcp));
00674
00675 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): allocated dhcp\n"));
00676 dhcp->pcb = udp_new();
00677 if (dhcp->pcb == NULL) {
00678 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not obtain pcb"));
00679 goto free_dhcp_and_return;
00680 }
00681 old_dhcp = netif->dhcp;
00682 netif->dhcp = dhcp;
00683 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));
00684
00685 result = dhcp_create_request(netif);
00686 if (result == ERR_OK) {
00687
00688 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
00689 dhcp_option_byte(dhcp, DHCP_INFORM);
00690
00691 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
00692 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
00693
00694 dhcp_option_trailer(dhcp);
00695
00696 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
00697
00698 #if IP_SOF_BROADCAST
00699 dhcp->pcb->so_options|=SOF_BROADCAST;
00700 #endif
00701 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
00702 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n"));
00703 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
00704 dhcp_delete_request(netif);
00705 } else {
00706 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n"));
00707 }
00708
00709 udp_remove(dhcp->pcb);
00710 dhcp->pcb = NULL;
00711 netif->dhcp = old_dhcp;
00712 free_dhcp_and_return:
00713 mem_free((void *)dhcp);
00714 }
00715
00716
00717
00718
00719
00720
00721 void
00722 dhcp_network_changed(struct netif *netif)
00723 {
00724 struct dhcp *dhcp = netif->dhcp;
00725 if (!dhcp)
00726 return;
00727 switch (dhcp->state) {
00728 case DHCP_REBINDING:
00729 case DHCP_RENEWING:
00730 case DHCP_BOUND:
00731 case DHCP_REBOOTING:
00732 netif_set_down(netif);
00733 dhcp->tries = 0;
00734 dhcp_reboot(netif);
00735 break;
00736 case DHCP_OFF:
00737
00738 break;
00739 default:
00740 dhcp->tries = 0;
00741 dhcp_discover(netif);
00742 break;
00743 }
00744 }
00745
00746 #if DHCP_DOES_ARP_CHECK
00747
00748
00749
00750
00751
00752
00753 void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr)
00754 {
00755 LWIP_ERROR("netif != NULL", (netif != NULL), return;);
00756 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n"));
00757
00758 if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) {
00759 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", addr->addr));
00760
00761
00762 if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) {
00763
00764 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
00765 ("dhcp_arp_reply(): arp reply matched with offered address, declining\n"));
00766 dhcp_decline(netif);
00767 }
00768 }
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 static err_t
00781 dhcp_decline(struct netif *netif)
00782 {
00783 struct dhcp *dhcp = netif->dhcp;
00784 err_t result = ERR_OK;
00785 u16_t msecs;
00786 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n"));
00787 dhcp_set_state(dhcp, DHCP_BACKING_OFF);
00788
00789 result = dhcp_create_request(netif);
00790 if (result == ERR_OK) {
00791 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
00792 dhcp_option_byte(dhcp, DHCP_DECLINE);
00793
00794 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
00795 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
00796
00797 dhcp_option_trailer(dhcp);
00798
00799 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
00800
00801
00802 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
00803 dhcp_delete_request(netif);
00804 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n"));
00805 } else {
00806 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
00807 ("dhcp_decline: could not allocate DHCP request\n"));
00808 }
00809 dhcp->tries++;
00810 msecs = 10*1000;
00811 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
00812 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));
00813 return result;
00814 }
00815 #endif
00816
00817
00818
00819
00820
00821
00822
00823 static err_t
00824 dhcp_discover(struct netif *netif)
00825 {
00826 struct dhcp *dhcp = netif->dhcp;
00827 err_t result = ERR_OK;
00828 u16_t msecs;
00829 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n"));
00830 ip_addr_set(&dhcp->offered_ip_addr, IP_ADDR_ANY);
00831 dhcp_set_state(dhcp, DHCP_SELECTING);
00832
00833 result = dhcp_create_request(netif);
00834 if (result == ERR_OK) {
00835 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n"));
00836 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
00837 dhcp_option_byte(dhcp, DHCP_DISCOVER);
00838
00839 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
00840 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
00841
00842 dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4);
00843 dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
00844 dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
00845 dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
00846 dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
00847
00848 dhcp_option_trailer(dhcp);
00849
00850 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n"));
00851 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
00852
00853 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));
00854 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
00855 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
00856 dhcp_delete_request(netif);
00857 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n"));
00858 } else {
00859 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n"));
00860 }
00861 dhcp->tries++;
00862 #if LWIP_DHCP_AUTOIP_COOP
00863 if(dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) {
00864 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON;
00865 autoip_start(netif);
00866 }
00867 #endif
00868 msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
00869 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
00870 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
00871 return result;
00872 }
00873
00874
00875
00876
00877
00878
00879
00880 static void
00881 dhcp_bind(struct netif *netif)
00882 {
00883 u32_t timeout;
00884 struct dhcp *dhcp;
00885 struct ip_addr sn_mask, gw_addr;
00886 LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;);
00887 dhcp = netif->dhcp;
00888 LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;);
00889 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));
00890
00891
00892 if (dhcp->offered_t1_renew != 0xffffffffUL) {
00893
00894 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));
00895 timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
00896 if(timeout > 0xffff) {
00897 timeout = 0xffff;
00898 }
00899 dhcp->t1_timeout = (u16_t)timeout;
00900 if (dhcp->t1_timeout == 0) {
00901 dhcp->t1_timeout = 1;
00902 }
00903 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000));
00904 }
00905
00906 if (dhcp->offered_t2_rebind != 0xffffffffUL) {
00907 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));
00908 timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
00909 if(timeout > 0xffff) {
00910 timeout = 0xffff;
00911 }
00912 dhcp->t2_timeout = (u16_t)timeout;
00913 if (dhcp->t2_timeout == 0) {
00914 dhcp->t2_timeout = 1;
00915 }
00916 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000));
00917 }
00918
00919 ip_addr_set(&sn_mask, &dhcp->offered_sn_mask);
00920
00921
00922
00923 if (sn_mask.addr == 0) {
00924
00925 u8_t first_octet = ip4_addr1(&sn_mask);
00926 if (first_octet <= 127) {
00927 sn_mask.addr = htonl(0xff000000);
00928 } else if (first_octet >= 192) {
00929 sn_mask.addr = htonl(0xffffff00);
00930 } else {
00931 sn_mask.addr = htonl(0xffff0000);
00932 }
00933 }
00934
00935 ip_addr_set(&gw_addr, &dhcp->offered_gw_addr);
00936
00937 if (gw_addr.addr == 0) {
00938
00939 gw_addr.addr = (dhcp->offered_ip_addr.addr & sn_mask.addr);
00940
00941 gw_addr.addr |= htonl(0x00000001);
00942 }
00943
00944 #if LWIP_DHCP_AUTOIP_COOP
00945 if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
00946 autoip_stop(netif);
00947 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
00948 }
00949 #endif
00950
00951 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr));
00952 netif_set_ipaddr(netif, &dhcp->offered_ip_addr);
00953 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n", sn_mask.addr));
00954 netif_set_netmask(netif, &sn_mask);
00955 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n", gw_addr.addr));
00956 netif_set_gw(netif, &gw_addr);
00957
00958 netif_set_up(netif);
00959
00960 dhcp_set_state(dhcp, DHCP_BOUND);
00961 }
00962
00963
00964
00965
00966
00967
00968 err_t
00969 dhcp_renew(struct netif *netif)
00970 {
00971 struct dhcp *dhcp = netif->dhcp;
00972 err_t result;
00973 u16_t msecs;
00974 #if LWIP_NETIF_HOSTNAME
00975 const char *p;
00976 #endif
00977 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n"));
00978 dhcp_set_state(dhcp, DHCP_RENEWING);
00979
00980
00981 result = dhcp_create_request(netif);
00982 if (result == ERR_OK) {
00983
00984 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
00985 dhcp_option_byte(dhcp, DHCP_REQUEST);
00986
00987 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
00988 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
00989
00990 #if LWIP_NETIF_HOSTNAME
00991 p = (const char*)netif->hostname;
00992 if (p != NULL) {
00993 dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, strlen(p));
00994 while (*p) {
00995 dhcp_option_byte(dhcp, *p++);
00996 }
00997 }
00998 #endif
00999
01000 #if 0
01001 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
01002 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
01003 #endif
01004
01005 #if 0
01006 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
01007 dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
01008 #endif
01009
01010 dhcp_option_trailer(dhcp);
01011
01012 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
01013
01014 udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
01015 dhcp_delete_request(netif);
01016
01017 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n"));
01018 } else {
01019 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n"));
01020 }
01021 dhcp->tries++;
01022
01023 msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000;
01024 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
01025 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs));
01026 return result;
01027 }
01028
01029
01030
01031
01032
01033
01034 static err_t
01035 dhcp_rebind(struct netif *netif)
01036 {
01037 struct dhcp *dhcp = netif->dhcp;
01038 err_t result;
01039 u16_t msecs;
01040 #if LWIP_NETIF_HOSTNAME
01041 const char *p;
01042 #endif
01043 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n"));
01044 dhcp_set_state(dhcp, DHCP_REBINDING);
01045
01046
01047 result = dhcp_create_request(netif);
01048 if (result == ERR_OK) {
01049
01050 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
01051 dhcp_option_byte(dhcp, DHCP_REQUEST);
01052
01053 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
01054 dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif));
01055
01056 #if LWIP_NETIF_HOSTNAME
01057 p = (const char*)netif->hostname;
01058 if (p != NULL) {
01059 dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, strlen(p));
01060 while (*p) {
01061 dhcp_option_byte(dhcp, *p++);
01062 }
01063 }
01064 #endif
01065
01066 #if 0
01067 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
01068 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
01069
01070 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
01071 dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
01072 #endif
01073
01074 dhcp_option_trailer(dhcp);
01075
01076 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
01077
01078
01079 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
01080 dhcp_delete_request(netif);
01081 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n"));
01082 } else {
01083 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n"));
01084 }
01085 dhcp->tries++;
01086 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
01087 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
01088 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs));
01089 return result;
01090 }
01091
01092
01093
01094
01095
01096
01097 static err_t
01098 dhcp_reboot(struct netif *netif)
01099 {
01100 struct dhcp *dhcp = netif->dhcp;
01101 err_t result;
01102 u16_t msecs;
01103 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n"));
01104 dhcp_set_state(dhcp, DHCP_REBOOTING);
01105
01106
01107 result = dhcp_create_request(netif);
01108 if (result == ERR_OK) {
01109
01110 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
01111 dhcp_option_byte(dhcp, DHCP_REQUEST);
01112
01113 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
01114 dhcp_option_short(dhcp, 576);
01115
01116 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
01117 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
01118
01119 dhcp_option_trailer(dhcp);
01120
01121 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
01122
01123
01124 udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
01125 dhcp_delete_request(netif);
01126 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n"));
01127 } else {
01128 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n"));
01129 }
01130 dhcp->tries++;
01131 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
01132 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
01133 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs));
01134 return result;
01135 }
01136
01137
01138
01139
01140
01141
01142
01143 err_t
01144 dhcp_release(struct netif *netif)
01145 {
01146 struct dhcp *dhcp = netif->dhcp;
01147 err_t result;
01148 u16_t msecs;
01149 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n"));
01150
01151
01152 dhcp_set_state(dhcp, DHCP_OFF);
01153
01154 dhcp->server_ip_addr.addr = 0;
01155 dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0;
01156 dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0;
01157 dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
01158 dhcp->dns_count = 0;
01159
01160
01161 result = dhcp_create_request(netif);
01162 if (result == ERR_OK) {
01163 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
01164 dhcp_option_byte(dhcp, DHCP_RELEASE);
01165
01166 dhcp_option_trailer(dhcp);
01167
01168 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
01169
01170 udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
01171 dhcp_delete_request(netif);
01172 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n"));
01173 } else {
01174 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n"));
01175 }
01176 dhcp->tries++;
01177 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
01178 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
01179 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs));
01180
01181 netif_set_down(netif);
01182
01183 netif_set_ipaddr(netif, IP_ADDR_ANY);
01184 netif_set_gw(netif, IP_ADDR_ANY);
01185 netif_set_netmask(netif, IP_ADDR_ANY);
01186
01187
01188 return result;
01189 }
01190
01191
01192
01193
01194
01195
01196 void
01197 dhcp_stop(struct netif *netif)
01198 {
01199 struct dhcp *dhcp = netif->dhcp;
01200 LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;);
01201
01202 netif->flags &= ~NETIF_FLAG_DHCP;
01203
01204 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop()\n"));
01205
01206 if (dhcp != NULL) {
01207 #if LWIP_DHCP_AUTOIP_COOP
01208 if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
01209 autoip_stop(netif);
01210 dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
01211 }
01212 #endif
01213
01214 if (dhcp->pcb != NULL) {
01215 udp_remove(dhcp->pcb);
01216 dhcp->pcb = NULL;
01217 }
01218 LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL &&
01219 dhcp->options_in == NULL && dhcp->options_in_len == 0);
01220 mem_free((void *)dhcp);
01221 netif->dhcp = NULL;
01222 }
01223 }
01224
01225
01226
01227
01228
01229
01230
01231
01232 static void
01233 dhcp_set_state(struct dhcp *dhcp, u8_t new_state)
01234 {
01235 if (new_state != dhcp->state) {
01236 dhcp->state = new_state;
01237 dhcp->tries = 0;
01238 }
01239 }
01240
01241
01242
01243
01244
01245
01246 static void
01247 dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len)
01248 {
01249 LWIP_ASSERT("dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN);
01250 dhcp->msg_out->options[dhcp->options_out_len++] = option_type;
01251 dhcp->msg_out->options[dhcp->options_out_len++] = option_len;
01252 }
01253
01254
01255
01256
01257 static void
01258 dhcp_option_byte(struct dhcp *dhcp, u8_t value)
01259 {
01260 LWIP_ASSERT("dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);
01261 dhcp->msg_out->options[dhcp->options_out_len++] = value;
01262 }
01263
01264 static void
01265 dhcp_option_short(struct dhcp *dhcp, u16_t value)
01266 {
01267 LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN);
01268 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
01269 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t) (value & 0x00ffU);
01270 }
01271
01272 static void
01273 dhcp_option_long(struct dhcp *dhcp, u32_t value)
01274 {
01275 LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN);
01276 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24);
01277 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16);
01278 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8);
01279 dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL));
01280 }
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292 static err_t
01293 dhcp_unfold_reply(struct dhcp *dhcp, struct pbuf *p)
01294 {
01295 u16_t ret;
01296 LWIP_ERROR("dhcp != NULL", (dhcp != NULL), return ERR_ARG;);
01297
01298 dhcp_free_reply(dhcp);
01299
01300 if (p->tot_len > (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN)) {
01301 dhcp->options_in_len = p->tot_len - (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
01302 dhcp->options_in = mem_malloc(dhcp->options_in_len);
01303 if (dhcp->options_in == NULL) {
01304 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
01305 ("dhcp_unfold_reply(): could not allocate dhcp->options\n"));
01306 dhcp->options_in_len = 0;
01307 return ERR_MEM;
01308 }
01309 }
01310 dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
01311 if (dhcp->msg_in == NULL) {
01312 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
01313 ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n"));
01314 if (dhcp->options_in != NULL) {
01315 mem_free(dhcp->options_in);
01316 dhcp->options_in = NULL;
01317 dhcp->options_in_len = 0;
01318 }
01319 return ERR_MEM;
01320 }
01321
01322
01323 ret = pbuf_copy_partial(p, dhcp->msg_in, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN, 0);
01324 LWIP_ASSERT("ret == sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN", ret == sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
01325 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes into dhcp->msg_in[]\n",
01326 sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN));
01327
01328 if (dhcp->options_in != NULL) {
01329
01330 ret = pbuf_copy_partial(p, dhcp->options_in, dhcp->options_in_len, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
01331 LWIP_ASSERT("ret == dhcp->options_in_len", ret == dhcp->options_in_len);
01332 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes to dhcp->options_in[]\n",
01333 dhcp->options_in_len));
01334 }
01335 LWIP_UNUSED_ARG(ret);
01336 return ERR_OK;
01337 }
01338
01339
01340
01341
01342
01343 static void dhcp_free_reply(struct dhcp *dhcp)
01344 {
01345 if (dhcp->msg_in != NULL) {
01346 mem_free((void *)dhcp->msg_in);
01347 dhcp->msg_in = NULL;
01348 }
01349 if (dhcp->options_in) {
01350 mem_free(dhcp->options_in);
01351 dhcp->options_in = NULL;
01352 dhcp->options_in_len = 0;
01353 }
01354 LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n"));
01355 }
01356
01357
01358
01359
01360 static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
01361 {
01362 struct netif *netif = (struct netif *)arg;
01363 struct dhcp *dhcp = netif->dhcp;
01364 struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload;
01365 u8_t *options_ptr;
01366 u8_t msg_type;
01367 u8_t i;
01368 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,
01369 (u16_t)(ntohl(addr->addr) >> 24 & 0xff), (u16_t)(ntohl(addr->addr) >> 16 & 0xff),
01370 (u16_t)(ntohl(addr->addr) >> 8 & 0xff), (u16_t)(ntohl(addr->addr) & 0xff), port));
01371 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
01372 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
01373
01374 LWIP_UNUSED_ARG(pcb);
01375 LWIP_UNUSED_ARG(addr);
01376 LWIP_UNUSED_ARG(port);
01377
01378 LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL &&
01379 dhcp->options_in == NULL && dhcp->options_in_len == 0);
01380
01381 if (p->len < DHCP_MIN_REPLY_LEN) {
01382 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message too short\n"));
01383 goto free_pbuf_and_return;
01384 }
01385
01386 if (reply_msg->op != DHCP_BOOTREPLY) {
01387 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));
01388 goto free_pbuf_and_return;
01389 }
01390
01391 for (i = 0; i < netif->hwaddr_len; i++) {
01392 if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
01393 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
01394 ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",
01395 (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));
01396 goto free_pbuf_and_return;
01397 }
01398 }
01399
01400 if (ntohl(reply_msg->xid) != dhcp->xid) {
01401 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
01402 ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",ntohl(reply_msg->xid),dhcp->xid));
01403 goto free_pbuf_and_return;
01404 }
01405
01406 if (dhcp_unfold_reply(dhcp, p) != ERR_OK) {
01407 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
01408 ("problem unfolding DHCP message - too short on memory?\n"));
01409 goto free_pbuf_and_return;
01410 }
01411
01412 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));
01413
01414 options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE);
01415 if (options_ptr == NULL) {
01416 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));
01417 goto free_pbuf_and_return;
01418 }
01419
01420
01421 msg_type = dhcp_get_option_byte(options_ptr + 2);
01422
01423 if (msg_type == DHCP_ACK) {
01424 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n"));
01425
01426 if (dhcp->state == DHCP_REQUESTING) {
01427 dhcp_handle_ack(netif);
01428 dhcp->request_timeout = 0;
01429 #if DHCP_DOES_ARP_CHECK
01430
01431 dhcp_check(netif);
01432 #else
01433
01434 dhcp_bind(netif);
01435 #endif
01436 }
01437
01438 else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) {
01439 dhcp->request_timeout = 0;
01440 dhcp_bind(netif);
01441 }
01442 }
01443
01444 else if ((msg_type == DHCP_NAK) &&
01445 ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||
01446 (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) {
01447 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n"));
01448 dhcp->request_timeout = 0;
01449 dhcp_handle_nak(netif);
01450 }
01451
01452 else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {
01453 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_SELECTING state\n"));
01454 dhcp->request_timeout = 0;
01455
01456 dhcp_handle_offer(netif);
01457 }
01458 free_pbuf_and_return:
01459 dhcp_free_reply(dhcp);
01460 pbuf_free(p);
01461 }
01462
01463
01464
01465
01466
01467
01468 static err_t
01469 dhcp_create_request(struct netif *netif)
01470 {
01471 struct dhcp *dhcp;
01472 u16_t i;
01473 #ifndef DHCP_GLOBAL_XID
01474
01475
01476
01477
01478 static u32_t xid = 0xABCD0000;
01479 #else
01480 static u32_t xid;
01481 static u8_t xid_initialised = 0;
01482 if (!xid_initialised) {
01483 xid = DHCP_GLOBAL_XID;
01484 xid_initialised = !xid_initialised;
01485 }
01486 #endif
01487 LWIP_ERROR("dhcp_create_request: netif != NULL", (netif != NULL), return ERR_ARG;);
01488 dhcp = netif->dhcp;
01489 LWIP_ERROR("dhcp_create_request: dhcp != NULL", (dhcp != NULL), return ERR_VAL;);
01490 LWIP_ASSERT("dhcp_create_request: dhcp->p_out == NULL", dhcp->p_out == NULL);
01491 LWIP_ASSERT("dhcp_create_request: dhcp->msg_out == NULL", dhcp->msg_out == NULL);
01492 dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
01493 if (dhcp->p_out == NULL) {
01494 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
01495 ("dhcp_create_request(): could not allocate pbuf\n"));
01496 return ERR_MEM;
01497 }
01498 LWIP_ASSERT("dhcp_create_request: check that first pbuf can hold struct dhcp_msg",
01499 (dhcp->p_out->len >= sizeof(struct dhcp_msg)));
01500
01501
01502 if (dhcp->tries==0)
01503 xid++;
01504 dhcp->xid = xid;
01505 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
01506 ("transaction id xid(%"X32_F")\n", xid));
01507
01508 dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;
01509
01510 dhcp->msg_out->op = DHCP_BOOTREQUEST;
01511
01512 dhcp->msg_out->htype = DHCP_HTYPE_ETH;
01513
01514 dhcp->msg_out->hlen = DHCP_HLEN_ETH;
01515 dhcp->msg_out->hops = 0;
01516 dhcp->msg_out->xid = htonl(dhcp->xid);
01517 dhcp->msg_out->secs = 0;
01518 dhcp->msg_out->flags = 0;
01519 dhcp->msg_out->ciaddr.addr = 0;
01520 if (dhcp->state==DHCP_BOUND || dhcp->state==DHCP_RENEWING || dhcp->state==DHCP_REBINDING) {
01521 dhcp->msg_out->ciaddr.addr = netif->ip_addr.addr;
01522 }
01523 dhcp->msg_out->yiaddr.addr = 0;
01524 dhcp->msg_out->siaddr.addr = 0;
01525 dhcp->msg_out->giaddr.addr = 0;
01526 for (i = 0; i < DHCP_CHADDR_LEN; i++) {
01527
01528 dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0;
01529 }
01530 for (i = 0; i < DHCP_SNAME_LEN; i++) {
01531 dhcp->msg_out->sname[i] = 0;
01532 }
01533 for (i = 0; i < DHCP_FILE_LEN; i++) {
01534 dhcp->msg_out->file[i] = 0;
01535 }
01536 dhcp->msg_out->cookie = htonl(0x63825363UL);
01537 dhcp->options_out_len = 0;
01538
01539 for (i = 0; i < DHCP_OPTIONS_LEN; i++) {
01540 dhcp->msg_out->options[i] = (u8_t)i;
01541 }
01542 return ERR_OK;
01543 }
01544
01545
01546
01547
01548
01549
01550 static void
01551 dhcp_delete_request(struct netif *netif)
01552 {
01553 struct dhcp *dhcp;
01554 LWIP_ERROR("dhcp_delete_request: netif != NULL", (netif != NULL), return;);
01555 dhcp = netif->dhcp;
01556 LWIP_ERROR("dhcp_delete_request: dhcp != NULL", (dhcp != NULL), return;);
01557 LWIP_ASSERT("dhcp_delete_request: dhcp->p_out != NULL", dhcp->p_out != NULL);
01558 LWIP_ASSERT("dhcp_delete_request: dhcp->msg_out != NULL", dhcp->msg_out != NULL);
01559 if (dhcp->p_out != NULL) {
01560 pbuf_free(dhcp->p_out);
01561 }
01562 dhcp->p_out = NULL;
01563 dhcp->msg_out = NULL;
01564 }
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574 static void
01575 dhcp_option_trailer(struct dhcp *dhcp)
01576 {
01577 LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;);
01578 LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL);
01579 LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
01580 dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;
01581
01582 while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) {
01583
01584 LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
01585
01586 dhcp->msg_out->options[dhcp->options_out_len++] = 0;
01587 }
01588 }
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599 static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type)
01600 {
01601 u8_t overload = DHCP_OVERLOAD_NONE;
01602
01603
01604 if ((dhcp->options_in != NULL) && (dhcp->options_in_len > 0)) {
01605
01606 u8_t *options = (u8_t *)dhcp->options_in;
01607 u16_t offset = 0;
01608
01609 while ((offset < dhcp->options_in_len) && (options[offset] != DHCP_OPTION_END)) {
01610
01611
01612 if (options[offset] == DHCP_OPTION_OVERLOAD) {
01613 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded message detected\n"));
01614
01615 offset += 2;
01616 overload = options[offset++];
01617 }
01618
01619 else if (options[offset] == option_type) {
01620 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("option found at offset %"U16_F" in options\n", offset));
01621 return &options[offset];
01622
01623 } else {
01624 LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", options[offset]));
01625
01626 offset++;
01627
01628 offset += 1 + options[offset];
01629 }
01630 }
01631
01632 if (overload != DHCP_OVERLOAD_NONE) {
01633 u16_t field_len;
01634 if (overload == DHCP_OVERLOAD_FILE) {
01635 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n"));
01636 options = (u8_t *)&dhcp->msg_in->file;
01637 field_len = DHCP_FILE_LEN;
01638 } else if (overload == DHCP_OVERLOAD_SNAME) {
01639 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n"));
01640 options = (u8_t *)&dhcp->msg_in->sname;
01641 field_len = DHCP_SNAME_LEN;
01642
01643 } else {
01644 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n"));
01645 options = (u8_t *)&dhcp->msg_in->sname;
01646 field_len = DHCP_FILE_LEN + DHCP_SNAME_LEN;
01647 }
01648 offset = 0;
01649
01650
01651 while ((offset < field_len) && (options[offset] != DHCP_OPTION_END)) {
01652 if (options[offset] == option_type) {
01653 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("option found at offset=%"U16_F"\n", offset));
01654 return &options[offset];
01655
01656 } else {
01657 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("skipping option %"U16_F"\n", options[offset]));
01658
01659 offset++;
01660 offset += 1 + options[offset];
01661 }
01662 }
01663 }
01664 }
01665 return NULL;
01666 }
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676 static u8_t
01677 dhcp_get_option_byte(u8_t *ptr)
01678 {
01679 LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%"U16_F"\n", (u16_t)(*ptr)));
01680 return *ptr;
01681 }
01682
01683 #if 0
01684
01685
01686
01687
01688
01689
01690
01691
01692 static u16_t
01693 dhcp_get_option_short(u8_t *ptr)
01694 {
01695 u16_t value;
01696 value = *ptr++ << 8;
01697 value |= *ptr;
01698 LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%"U16_F"\n", value));
01699 return value;
01700 }
01701 #endif
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711 static u32_t dhcp_get_option_long(u8_t *ptr)
01712 {
01713 u32_t value;
01714 value = (u32_t)(*ptr++) << 24;
01715 value |= (u32_t)(*ptr++) << 16;
01716 value |= (u32_t)(*ptr++) << 8;
01717 value |= (u32_t)(*ptr++);
01718 LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%"U32_F"\n", value));
01719 return value;
01720 }
01721
01722 #endif