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