#include "lwip/stats.h"
#include "lwip/mem.h"
#include "lwip/udp.h"
#include "lwip/netif.h"
#include "lwip/inet.h"
#include "lwip/ip_addr.h"
#include "netif/etharp.h"
#include "lwip/sys.h"
#include "lwip/opt.h"
#include "lwip/dhcp.h"
Include dependency graph for dhcp.c:
Go to the source code of this file.
Definition in file dhcp.c.
|
Bind the interface to the offered IP address.
Definition at line 721 of file dhcp.c. References ip_addr::addr, DBG_STATE, DBG_TRACE, DEBUGF, DHCP_BOUND, DHCP_COARSE_TIMER_SECS, DHCP_DEBUG, dhcp_set_state(), htonl, ip4_addr1, ip_addr_set, netif_set_gw(), netif_set_ipaddr(), netif_set_netmask(), and u8_t. Referenced by dhcp_recv(), and dhcp_timeout().
00722 { 00723 struct dhcp *dhcp = netif->dhcp; 00724 struct ip_addr sn_mask, gw_addr; 00725 00726 /* temporary DHCP lease? */ 00727 if (dhcp->offered_t1_renew != 0xffffffffUL) { 00728 /* set renewal period timer */ 00729 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t1 renewal timer %lu secs\n", dhcp->offered_t1_renew)); 00730 dhcp->t1_timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; 00731 if (dhcp->t1_timeout == 0) dhcp->t1_timeout = 1; 00732 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %u msecs\n", dhcp->offered_t1_renew*1000)); 00733 } 00734 /* set renewal period timer */ 00735 if (dhcp->offered_t2_rebind != 0xffffffffUL) { 00736 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t2 rebind timer %lu secs\n", dhcp->offered_t2_rebind)); 00737 dhcp->t2_timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; 00738 if (dhcp->t2_timeout == 0) dhcp->t2_timeout = 1; 00739 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %u msecs\n", dhcp->offered_t2_rebind*1000)); 00740 } 00741 /* copy offered network mask */ 00742 ip_addr_set(&sn_mask, &dhcp->offered_sn_mask); 00743 00744 /* subnet mask not given? */ 00745 /* TODO: this is not a valid check. what if the network mask is 0? */ 00746 if (sn_mask.addr == 0) { 00747 /* choose a safe subnet mask given the network class */ 00748 u8_t first_octet = ip4_addr1(&sn_mask); 00749 if (first_octet <= 127) sn_mask.addr = htonl(0xff000000); 00750 else if (first_octet >= 192) sn_mask.addr = htonl(0xffffff00); 00751 else sn_mask.addr = htonl(0xffff0000); 00752 } 00753 00754 ip_addr_set(&gw_addr, &dhcp->offered_gw_addr); 00755 /* gateway address not given? */ 00756 if (gw_addr.addr == 0) { 00757 /* copy network address */ 00758 gw_addr.addr = (dhcp->offered_ip_addr.addr & sn_mask.addr); 00759 /* use first host address on network as gateway */ 00760 gw_addr.addr |= htonl(0x00000001); 00761 } 00762 00763 DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): IP: 0x%08lx\n", dhcp->offered_ip_addr.addr)); 00764 netif_set_ipaddr(netif, &dhcp->offered_ip_addr); 00765 DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): SN: 0x%08lx\n", sn_mask.addr)); 00766 netif_set_netmask(netif, &sn_mask); 00767 DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): GW: 0x%08lx\n", gw_addr.addr)); 00768 netif_set_gw(netif, &gw_addr); 00769 /* netif is now bound to DHCP leased address */ 00770 dhcp_set_state(dhcp, DHCP_BOUND); 00771 } |
Here is the call graph for this function:
|
Checks if the offered IP address is already in use. It does so by sending an ARP request for the offered address and entering CHECKING state. If no ARP reply is received within a small interval, the address is assumed to be free for use by us. Definition at line 162 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_CHECKING, DHCP_DEBUG, DHCP_FINE_TIMER_MSECS, dhcp_set_state(), ERR_OK, err_t, etharp_query(), NULL, and u16_t. Referenced by dhcp_recv(), and dhcp_timeout().
00163 { 00164 struct dhcp *dhcp = netif->dhcp; 00165 err_t result; 00166 u16_t msecs; 00167 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_check()\n")); 00168 /* create an ARP query for the offered IP address, expecting that no host 00169 responds, as the IP address should not be in use. */ 00170 result = etharp_query(netif, &dhcp->offered_ip_addr, NULL); 00171 if (result != ERR_OK) { 00172 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_check: could not perform ARP query\n")); 00173 } 00174 dhcp->tries++; 00175 msecs = 500; 00176 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; 00177 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_check(): set request timeout %u msecs\n", msecs)); 00178 dhcp_set_state(dhcp, DHCP_CHECKING); 00179 } |
Here is the call graph for this function:
|
The DHCP timer that checks for lease renewal/rebind timeouts. Definition at line 268 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_DEBUG, dhcp_t1_timeout(), dhcp_t2_timeout(), netif_list, and NULL.
00269 { 00270 struct netif *netif = netif_list; 00271 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_coarse_tmr()\n")); 00272 /* iterate through all network interfaces */ 00273 while (netif != NULL) { 00274 /* only act on DHCP configured interfaces */ 00275 if (netif->dhcp != NULL) { 00276 /* timer is active (non zero), and triggers (zeroes) now? */ 00277 if (netif->dhcp->t2_timeout-- == 1) { 00278 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); 00279 /* this clients' rebind timeout triggered */ 00280 dhcp_t2_timeout(netif); 00281 /* timer is active (non zero), and triggers (zeroes) now */ 00282 } else if (netif->dhcp->t1_timeout-- == 1) { 00283 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n")); 00284 /* this clients' renewal timeout triggered */ 00285 dhcp_t1_timeout(netif); 00286 } 00287 } 00288 /* proceed to next netif */ 00289 netif = netif->next; 00290 } 00291 } |
Here is the call graph for this function:
|
create a DHCP request, fill in common headers Definition at line 1188 of file dhcp.c. References ip_addr::addr, DBG_TRACE, DEBUGF, DHCP_BOOTREQUEST, DHCP_CHADDR_LEN, DHCP_DEBUG, DHCP_FILE_LEN, DHCP_HLEN_ETH, DHCP_HTYPE_ETH, DHCP_OPTIONS_LEN, DHCP_SNAME_LEN, ERR_MEM, ERR_OK, err_t, htonl, netif::hwaddr, netif::hwaddr_len, netif::ip_addr, LWIP_ASSERT, NULL, pbuf_alloc(), PBUF_RAM, PBUF_TRANSPORT, u16_t, and xid. Referenced by dhcp_discover(), dhcp_inform(), dhcp_rebind(), dhcp_release(), dhcp_renew(), and dhcp_select().
01189 { 01190 struct dhcp *dhcp = netif->dhcp; 01191 u16_t i; 01192 LWIP_ASSERT("dhcp_create_request: dhcp->p_out == NULL", dhcp->p_out == NULL); 01193 LWIP_ASSERT("dhcp_create_request: dhcp->msg_out == NULL", dhcp->msg_out == NULL); 01194 dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM); 01195 if (dhcp->p_out == NULL) { 01196 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_create_request(): could not allocate pbuf\n")); 01197 return ERR_MEM; 01198 } 01199 /* give unique transaction identifier to this request */ 01200 dhcp->xid = xid++; 01201 01202 dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload; 01203 01204 dhcp->msg_out->op = DHCP_BOOTREQUEST; 01205 /* TODO: make link layer independent */ 01206 dhcp->msg_out->htype = DHCP_HTYPE_ETH; 01207 /* TODO: make link layer independent */ 01208 dhcp->msg_out->hlen = DHCP_HLEN_ETH; 01209 dhcp->msg_out->hops = 0; 01210 dhcp->msg_out->xid = htonl(dhcp->xid); 01211 dhcp->msg_out->secs = 0; 01212 dhcp->msg_out->flags = 0; 01213 dhcp->msg_out->ciaddr = netif->ip_addr.addr; 01214 dhcp->msg_out->yiaddr = 0; 01215 dhcp->msg_out->siaddr = 0; 01216 dhcp->msg_out->giaddr = 0; 01217 for (i = 0; i < DHCP_CHADDR_LEN; i++) { 01218 /* copy netif hardware address, pad with zeroes */ 01219 dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/; 01220 } 01221 for (i = 0; i < DHCP_SNAME_LEN; i++) dhcp->msg_out->sname[i] = 0; 01222 for (i = 0; i < DHCP_FILE_LEN; i++) dhcp->msg_out->file[i] = 0; 01223 dhcp->msg_out->cookie = htonl(0x63825363UL); 01224 dhcp->options_out_len = 0; 01225 /* fill options field with an incrementing array (for debugging purposes) */ 01226 for (i = 0; i < DHCP_OPTIONS_LEN; i++) dhcp->msg_out->options[i] = i; 01227 return ERR_OK; 01228 } |
Here is the call graph for this function:
|
|
|
free a DHCP request Definition at line 1230 of file dhcp.c. References LWIP_ASSERT, NULL, and pbuf_free(). Referenced by dhcp_discover(), dhcp_inform(), dhcp_rebind(), dhcp_release(), dhcp_renew(), and dhcp_select().
|
Here is the call graph for this function:
|
Start the DHCP process, discover a DHCP server. Definition at line 661 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_CLIENT_PORT, dhcp_create_request(), DHCP_DEBUG, dhcp_delete_request(), DHCP_DISCOVER, DHCP_FINE_TIMER_MSECS, dhcp_option(), DHCP_OPTION_BROADCAST, dhcp_option_byte(), DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, DHCP_OPTION_PARAMETER_REQUEST_LIST, DHCP_OPTION_ROUTER, dhcp_option_short(), DHCP_OPTION_SUBNET_MASK, dhcp_option_trailer(), DHCP_OPTIONS_LEN, dhcp_recv(), DHCP_SELECTING, DHCP_SERVER_PORT, dhcp_set_state(), ERR_OK, err_t, IP_ADDR_ANY, IP_ADDR_BROADCAST, ip_addr_set, pbuf_realloc(), u16_t, udp_bind(), udp_connect(), udp_recv(), and udp_send(). Referenced by dhcp_start(), and dhcp_timeout().
00662 { 00663 struct dhcp *dhcp = netif->dhcp; 00664 err_t result = ERR_OK; 00665 u16_t msecs; 00666 DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_discover()\n")); 00667 ip_addr_set(&dhcp->offered_ip_addr, IP_ADDR_ANY); 00668 /* create and initialize the DHCP message header */ 00669 result = dhcp_create_request(netif); 00670 if (result == ERR_OK) 00671 { 00672 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: making request\n")); 00673 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); 00674 dhcp_option_byte(dhcp, DHCP_DISCOVER); 00675 00676 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); 00677 dhcp_option_short(dhcp, 576); 00678 00679 dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 3); 00680 dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); 00681 dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); 00682 dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); 00683 00684 dhcp_option_trailer(dhcp); 00685 00686 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: realloc()ing\n")); 00687 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); 00688 00689 /* set receive callback function with netif as user data */ 00690 udp_recv(dhcp->pcb, dhcp_recv, netif); 00691 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); 00692 udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT); 00693 00694 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: send()ing\n")); 00695 00696 udp_send(dhcp->pcb, dhcp->p_out); 00697 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: bind()ing\n")); 00698 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); 00699 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: connect()ing\n")); 00700 udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); 00701 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: deleting()ing\n")); 00702 dhcp_delete_request(netif); 00703 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover: SELECTING\n")); 00704 dhcp_set_state(dhcp, DHCP_SELECTING); 00705 } else { 00706 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_discover: could not allocate DHCP request\n")); 00707 } 00708 dhcp->tries++; 00709 msecs = dhcp->tries < 4 ? (dhcp->tries + 1) * 1000 : 10 * 1000; 00710 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; 00711 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover(): set request timeout %u msecs\n", msecs)); 00712 return result; 00713 } |
Here is the call graph for this function:
|
DHCP transaction timeout handling A DHCP server is expected to respond within a short period of time. Definition at line 299 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_DEBUG, dhcp_timeout(), netif_list, and NULL.
00300 { 00301 struct netif *netif = netif_list; 00302 /* loop through clients */ 00303 while (netif != NULL) { 00304 /* only act on DHCP configured interfaces */ 00305 if (netif->dhcp != NULL) { 00306 /* timer is active (non zero), and triggers (zeroes) now */ 00307 if (netif->dhcp->request_timeout-- == 1) { 00308 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_fine_tmr(): request timeout\n")); 00309 /* this clients' request timeout triggered */ 00310 dhcp_timeout(netif); 00311 } 00312 } 00313 /* proceed to next network interface */ 00314 netif = netif->next; 00315 } 00316 } |
Here is the call graph for this function:
|
Free the incoming DHCP message including contiguous copy of its DHCP options. Definition at line 1081 of file dhcp.c. References DEBUGF, DHCP_DEBUG, mem_free(), dhcp::msg_in, NULL, dhcp::options_in, and dhcp::options_in_len. Referenced by dhcp_stop(), and dhcp_unfold_reply().
01082 { 01083 if (dhcp->msg_in != NULL) { 01084 mem_free((void *)dhcp->msg_in); 01085 dhcp->msg_in = NULL; 01086 } 01087 if (dhcp->options_in) { 01088 mem_free((void *)dhcp->options_in); 01089 dhcp->options_in = NULL; 01090 dhcp->options_in_len = 0; 01091 } 01092 DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n")); 01093 } |
Here is the call graph for this function:
|
Return the byte of DHCP option data.
Definition at line 1347 of file dhcp.c. References DEBUGF, DHCP_DEBUG, and u8_t. Referenced by dhcp_recv().
01348 { 01349 DEBUGF(DHCP_DEBUG, ("option byte value=%u\n", *ptr)); 01350 return *ptr; 01351 } |
|
Return the 32-bit value of DHCP option data.
Definition at line 1378 of file dhcp.c. References DEBUGF, DHCP_DEBUG, u32_t, and u8_t. Referenced by dhcp_handle_ack(), and dhcp_handle_offer().
|
|
Find the offset of a DHCP option inside the DHCP message.
Definition at line 1270 of file dhcp.c. References DBG_TRACE, DEBUGF, DHCP_DEBUG, DHCP_FILE_LEN, DHCP_OPTION_END, DHCP_OPTION_OVERLOAD, DHCP_OVERLOAD_FILE, DHCP_OVERLOAD_NONE, DHCP_OVERLOAD_SNAME, DHCP_SNAME_LEN, dhcp::msg_in, NULL, dhcp::options_in, dhcp::options_in_len, u16_t, and u8_t. Referenced by dhcp_handle_ack(), dhcp_handle_offer(), and dhcp_recv().
01271 { 01272 u8_t overload = DHCP_OVERLOAD_NONE; 01273 01274 /* options available? */ 01275 if ((dhcp->options_in != NULL) && (dhcp->options_in_len > 0)) { 01276 /* start with options field */ 01277 u8_t *options = (u8_t *)dhcp->options_in; 01278 u16_t offset = 0; 01279 /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */ 01280 while ((offset < dhcp->options_in_len) && (options[offset] != DHCP_OPTION_END)) { 01281 /* DEBUGF(DHCP_DEBUG, ("msg_offset=%u, q->len=%u", msg_offset, q->len)); */ 01282 /* are the sname and/or file field overloaded with options? */ 01283 if (options[offset] == DHCP_OPTION_OVERLOAD) { 01284 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("overloaded message detected\n")); 01285 /* skip option type and length */ 01286 offset += 2; 01287 overload = options[offset++]; 01288 } 01289 /* requested option found */ 01290 else if (options[offset] == option_type) { 01291 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset %u in options\n", offset)); 01292 return &options[offset]; 01293 /* skip option */ 01294 } else { 01295 DEBUGF(DHCP_DEBUG, ("skipping option %u in options\n", options[offset])); 01296 /* skip option type */ 01297 offset++; 01298 /* skip option length, and then length bytes */ 01299 offset += 1 + options[offset]; 01300 } 01301 } 01302 /* is this an overloaded message? */ 01303 if (overload != DHCP_OVERLOAD_NONE) { 01304 u16_t field_len; 01305 if (overload == DHCP_OVERLOAD_FILE) { 01306 DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded file field\n")); 01307 options = (u8_t *)&dhcp->msg_in->file; 01308 field_len = DHCP_FILE_LEN; 01309 } else if (overload == DHCP_OVERLOAD_SNAME) { 01310 DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded sname field\n")); 01311 options = (u8_t *)&dhcp->msg_in->sname; 01312 field_len = DHCP_SNAME_LEN; 01313 /* TODO: check if else if () is necessary */ 01314 } else { 01315 DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("overloaded sname and file field\n")); 01316 options = (u8_t *)&dhcp->msg_in->sname; 01317 field_len = DHCP_FILE_LEN + DHCP_SNAME_LEN; 01318 } 01319 offset = 0; 01320 01321 /* at least 1 byte to read and no end marker */ 01322 while ((offset < field_len) && (options[offset] != DHCP_OPTION_END)) { 01323 if (options[offset] == option_type) { 01324 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset=%u\n", offset)); 01325 return &options[offset]; 01326 /* skip option */ 01327 } else { 01328 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("skipping option %u\n", options[offset])); 01329 /* skip option type */ 01330 offset++; 01331 offset += 1 + options[offset]; 01332 } 01333 } 01334 } 01335 } 01336 return 0; 01337 } |
|
Return the 16-bit value of DHCP option data.
Definition at line 1361 of file dhcp.c. References DEBUGF, DHCP_DEBUG, u16_t, and u8_t.
|
|
Extract options from the server ACK message.
Definition at line 413 of file dhcp.c. References dhcp_get_option_long(), dhcp_get_option_ptr(), DHCP_OPTION_BROADCAST, DHCP_OPTION_LEASE_TIME, DHCP_OPTION_ROUTER, DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_T1, DHCP_OPTION_T2, htonl, ip_addr_set, NULL, and u8_t. Referenced by dhcp_recv().
00414 { 00415 struct dhcp *dhcp = netif->dhcp; 00416 u8_t *option_ptr; 00417 /* clear options we might not get from the ACK */ 00418 dhcp->offered_sn_mask.addr = 0; 00419 dhcp->offered_gw_addr.addr = 0; 00420 dhcp->offered_bc_addr.addr = 0; 00421 00422 /* lease time given? */ 00423 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_LEASE_TIME); 00424 if (option_ptr != NULL) { 00425 /* remember offered lease time */ 00426 dhcp->offered_t0_lease = dhcp_get_option_long(option_ptr + 2); 00427 } 00428 /* renewal period given? */ 00429 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T1); 00430 if (option_ptr != NULL) { 00431 /* remember given renewal period */ 00432 dhcp->offered_t1_renew = dhcp_get_option_long(option_ptr + 2); 00433 } else { 00434 /* calculate safe periods for renewal */ 00435 dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2; 00436 } 00437 00438 /* renewal period given? */ 00439 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T2); 00440 if (option_ptr != NULL) { 00441 /* remember given rebind period */ 00442 dhcp->offered_t2_rebind = dhcp_get_option_long(option_ptr + 2); 00443 } else { 00444 /* calculate safe periods for rebinding */ 00445 dhcp->offered_t2_rebind = dhcp->offered_t0_lease; 00446 } 00447 00448 /* (y)our internet address */ 00449 ip_addr_set(&dhcp->offered_ip_addr, &dhcp->msg_in->yiaddr); 00450 00451 /* subnet mask */ 00452 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SUBNET_MASK); 00453 /* subnet mask given? */ 00454 if (option_ptr != NULL) { 00455 dhcp->offered_sn_mask.addr = htonl(dhcp_get_option_long(&option_ptr[2])); 00456 } 00457 00458 /* gateway router */ 00459 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_ROUTER); 00460 if (option_ptr != NULL) { 00461 dhcp->offered_gw_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2])); 00462 } 00463 00464 /* broadcast address */ 00465 option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_BROADCAST); 00466 if (option_ptr != NULL) { 00467 dhcp->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2])); 00468 } 00469 } |
Here is the call graph for this function:
|
Back-off the DHCP client (because of a received NAK response). Back-off the DHCP client because of a received NAK. Receiving a NAK means the client asked for something non-sensible, for example when it tries to renew a lease obtained on another network. We back-off and will end up restarting a fresh DHCP negotiation later.
Definition at line 146 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_BACKING_OFF, DHCP_DEBUG, DHCP_FINE_TIMER_MSECS, dhcp_set_state(), and u16_t. Referenced by dhcp_recv().
00146 { 00147 struct dhcp *dhcp = netif->dhcp; 00148 u16_t msecs = 10 * 1000; 00149 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_handle_nak()\n")); 00150 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; 00151 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %u msecs\n", msecs)); 00152 dhcp_set_state(dhcp, DHCP_BACKING_OFF); 00153 } |
Here is the call graph for this function:
|
Remember the configuration offered by a DHCP server.
Definition at line 186 of file dhcp.c. References DBG_STATE, DEBUGF, DHCP_DEBUG, dhcp_get_option_long(), dhcp_get_option_ptr(), DHCP_OPTION_SERVER_ID, dhcp_select(), htonl, ip_addr_set, NULL, and u8_t. Referenced by dhcp_recv().
00187 { 00188 struct dhcp *dhcp = netif->dhcp; 00189 /* obtain the server address */ 00190 u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID); 00191 if (option_ptr != NULL) 00192 { 00193 dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2])); 00194 DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): server 0x%08lx\n", dhcp->server_ip_addr.addr)); 00195 /* remember offered address */ 00196 ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr); 00197 DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08lx\n", dhcp->offered_ip_addr.addr)); 00198 dhcp_select(netif); 00199 } 00200 } |
Here is the call graph for this function:
|
Inform a DHCP server of our manual configuration. This informs DHCP servers of our fixed IP address configuration by sending an INFORM message. It does not involve DHCP address configuration, it is just here to be nice to the network.
Definition at line 537 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_CLIENT_PORT, dhcp_create_request(), DHCP_DEBUG, dhcp_delete_request(), DHCP_INFORM, dhcp_option(), dhcp_option_byte(), DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, dhcp_option_short(), dhcp_option_trailer(), DHCP_OPTIONS_LEN, DHCP_SERVER_PORT, ERR_OK, err_t, IP_ADDR_ANY, IP_ADDR_BROADCAST, mem_free(), mem_malloc(), NULL, pbuf_realloc(), udp_bind(), udp_connect(), udp_new(), udp_remove(), and udp_send().
00538 { 00539 struct dhcp *dhcp; 00540 err_t result = ERR_OK; 00541 dhcp = mem_malloc(sizeof(struct dhcp)); 00542 if (dhcp == NULL) { 00543 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n")); 00544 return; 00545 } 00546 memset(dhcp, 0, sizeof(struct dhcp)); 00547 00548 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): allocated dhcp\n")); 00549 dhcp->pcb = udp_new(); 00550 if (dhcp->pcb == NULL) { 00551 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not obtain pcb")); 00552 mem_free((void *)dhcp); 00553 return; 00554 } 00555 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); 00556 /* create and initialize the DHCP message header */ 00557 result = dhcp_create_request(netif); 00558 if (result == ERR_OK) { 00559 00560 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); 00561 dhcp_option_byte(dhcp, DHCP_INFORM); 00562 00563 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); 00564 /* TODO: use netif->mtu ?! */ 00565 dhcp_option_short(dhcp, 576); 00566 00567 dhcp_option_trailer(dhcp); 00568 00569 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); 00570 00571 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); 00572 udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT); 00573 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_inform: INFORMING\n")); 00574 udp_send(dhcp->pcb, dhcp->p_out); 00575 udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); 00576 dhcp_delete_request(netif); 00577 } else { 00578 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform: could not allocate DHCP request\n")); 00579 } 00580 00581 if (dhcp != NULL) 00582 { 00583 if (dhcp->pcb != NULL) udp_remove(dhcp->pcb); 00584 dhcp->pcb = NULL; 00585 mem_free((void *)dhcp); 00586 } 00587 } |
Here is the call graph for this function:
|
add a DHCP option (type, then length in bytes) Definition at line 975 of file dhcp.c. References DHCP_OPTIONS_LEN, LWIP_ASSERT, dhcp::msg_out, dhcp::options_out_len, and u8_t. Referenced by dhcp_discover(), dhcp_inform(), dhcp_rebind(), dhcp_release(), dhcp_renew(), and dhcp_select().
00976 { 00977 LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN); 00978 dhcp->msg_out->options[dhcp->options_out_len++] = option_type; 00979 dhcp->msg_out->options[dhcp->options_out_len++] = option_len; 00980 } |
|
add option values Definition at line 985 of file dhcp.c. References DHCP_OPTIONS_LEN, LWIP_ASSERT, dhcp::msg_out, dhcp::options_out_len, and u8_t. Referenced by dhcp_discover(), dhcp_inform(), dhcp_rebind(), dhcp_release(), dhcp_renew(), and dhcp_select().
00986 { 00987 LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN); 00988 dhcp->msg_out->options[dhcp->options_out_len++] = value; 00989 } |
|
Definition at line 996 of file dhcp.c. References DHCP_OPTIONS_LEN, LWIP_ASSERT, dhcp::msg_out, dhcp::options_out_len, and u32_t. Referenced by dhcp_rebind(), dhcp_renew(), and dhcp_select().
00997 { 00998 LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN); 00999 dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0xff000000UL) >> 24; 01000 dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x00ff0000UL) >> 16; 01001 dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x0000ff00UL) >> 8; 01002 dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0x000000ffUL); 01003 } |
|
Definition at line 990 of file dhcp.c. References DHCP_OPTIONS_LEN, LWIP_ASSERT, dhcp::msg_out, dhcp::options_out_len, and u16_t. Referenced by dhcp_discover(), dhcp_inform(), dhcp_rebind(), dhcp_renew(), and dhcp_select().
00991 { 00992 LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN); 00993 dhcp->msg_out->options[dhcp->options_out_len++] = (value & 0xff00U) >> 8; 00994 dhcp->msg_out->options[dhcp->options_out_len++] = value & 0x00ffU; 00995 } |
|
Add a DHCP message trailer Adds the END option to the DHCP message, and if necessary, up to three padding bytes. Definition at line 1247 of file dhcp.c. References DHCP_MIN_OPTIONS_LEN, DHCP_OPTION_END, DHCP_OPTIONS_LEN, LWIP_ASSERT, dhcp::msg_out, NULL, and dhcp::options_out_len. Referenced by dhcp_discover(), dhcp_inform(), dhcp_rebind(), dhcp_release(), dhcp_renew(), and dhcp_select().
01248 { 01249 LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL); 01250 LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); 01251 dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END; 01252 /* packet is too small, or not 4 byte aligned? */ 01253 while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) { 01254 /* DEBUGF(DHCP_DEBUG, ("dhcp_option_trailer: dhcp->options_out_len=%u, DHCP_OPTIONS_LEN=%u", dhcp->options_out_len, DHCP_OPTIONS_LEN)); */ 01255 LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); 01256 /* add a fill/padding byte */ 01257 dhcp->msg_out->options[dhcp->options_out_len++] = 0; 01258 } 01259 } |
|
Rebind with a DHCP server for an existing DHCP lease.
Definition at line 833 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_CLIENT_PORT, dhcp_create_request(), DHCP_DEBUG, dhcp_delete_request(), DHCP_FINE_TIMER_MSECS, dhcp_option(), dhcp_option_byte(), dhcp_option_long(), DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, DHCP_OPTION_REQUESTED_IP, DHCP_OPTION_SERVER_ID, dhcp_option_short(), dhcp_option_trailer(), DHCP_OPTIONS_LEN, DHCP_REBINDING, DHCP_REQUEST, DHCP_SERVER_PORT, dhcp_set_state(), ERR_OK, err_t, IP_ADDR_ANY, IP_ADDR_BROADCAST, ntohl, pbuf_realloc(), u16_t, udp_bind(), udp_connect(), and udp_send(). Referenced by dhcp_t2_timeout(), and dhcp_timeout().
00834 { 00835 struct dhcp *dhcp = netif->dhcp; 00836 err_t result; 00837 u16_t msecs; 00838 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind()\n")); 00839 dhcp_set_state(dhcp, DHCP_REBINDING); 00840 00841 /* create and initialize the DHCP message header */ 00842 result = dhcp_create_request(netif); 00843 if (result == ERR_OK) 00844 { 00845 00846 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); 00847 dhcp_option_byte(dhcp, DHCP_REQUEST); 00848 00849 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); 00850 dhcp_option_short(dhcp, 576); 00851 00852 #if 0 00853 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); 00854 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); 00855 00856 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); 00857 dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); 00858 #endif 00859 00860 dhcp_option_trailer(dhcp); 00861 00862 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); 00863 00864 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); 00865 udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT); 00866 udp_send(dhcp->pcb, dhcp->p_out); 00867 udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); 00868 dhcp_delete_request(netif); 00869 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind: REBINDING\n")); 00870 } else { 00871 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_rebind: could not allocate DHCP request\n")); 00872 } 00873 dhcp->tries++; 00874 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; 00875 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; 00876 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind(): set request timeout %u msecs\n", msecs)); 00877 return result; 00878 } |
Here is the call graph for this function:
|
If an incoming DHCP message is in response to use, then trigger the state machine Definition at line 1099 of file dhcp.c. References DBG_TRACE, DEBUGF, DHCP_ACK, dhcp_bind(), DHCP_BOOTREPLY, dhcp_check(), DHCP_DEBUG, dhcp_get_option_byte(), dhcp_get_option_ptr(), dhcp_handle_ack(), dhcp_handle_nak(), dhcp_handle_offer(), DHCP_NAK, DHCP_OFFER, DHCP_OPTION_MESSAGE_TYPE, DHCP_REBINDING, DHCP_REBOOTING, DHCP_RENEWING, DHCP_REQUESTING, DHCP_SELECTING, dhcp_unfold_reply(), ERR_OK, netif::hwaddr, netif::hwaddr_len, pbuf::len, ntohl, NULL, pbuf::payload, pbuf_free(), pbuf::tot_len, u16_t, and u8_t. Referenced by dhcp_discover().
01100 { 01101 struct netif *netif = (struct netif *)arg; 01102 struct dhcp *dhcp = netif->dhcp; 01103 struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload; 01104 u8_t *options_ptr; 01105 u8_t msg_type; 01106 u8_t i; 01107 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_recv()\n")); 01108 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->len = %u\n", p->len)); 01109 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->tot_len = %u\n", p->tot_len)); 01110 dhcp->p = p; 01111 if (reply_msg->op != DHCP_BOOTREPLY) { 01112 DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("not a DHCP reply message, but type %u\n", reply_msg->op)); 01113 pbuf_free(p); 01114 } 01115 /* iterate through hardware address and match against DHCP message */ 01116 for (i = 0; i < netif->hwaddr_len; i++) { 01117 if (netif->hwaddr[i] != reply_msg->chaddr[i]) { 01118 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%u]==%02x != reply_msg->chaddr[%u]==%02x\n", 01119 i, netif->hwaddr[i], i, reply_msg->chaddr[i])); 01120 pbuf_free(p); 01121 return; 01122 } 01123 } 01124 /* match transaction ID against what we expected */ 01125 if (ntohl(reply_msg->xid) != dhcp->xid) { 01126 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("transaction id mismatch\n")); 01127 pbuf_free(p); 01128 return; 01129 } 01130 /* option fields could be unfold? */ 01131 if (dhcp_unfold_reply(dhcp) != ERR_OK) { 01132 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("problem unfolding DHCP message - too short on memory?\n")); 01133 pbuf_free(p); 01134 return; 01135 } 01136 01137 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n")); 01138 /* obtain pointer to DHCP message type */ 01139 options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE); 01140 if (options_ptr == NULL) { 01141 DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); 01142 pbuf_free(p); 01143 return; 01144 } 01145 01146 /* read DHCP message type */ 01147 msg_type = dhcp_get_option_byte(options_ptr + 2); 01148 /* message type is DHCP ACK? */ 01149 if (msg_type == DHCP_ACK) { 01150 DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_ACK received\n")); 01151 /* in requesting state? */ 01152 if (dhcp->state == DHCP_REQUESTING) { 01153 dhcp_handle_ack(netif); 01154 dhcp->request_timeout = 0; 01155 #if DHCP_DOES_ARP_CHECK 01156 /* check if the acknowledged lease address is already in use */ 01157 dhcp_check(netif); 01158 #else 01159 /* bind interface to the acknowledged lease address */ 01160 dhcp_bind(netif); 01161 #endif 01162 } 01163 /* already bound to the given lease address? */ 01164 else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) { 01165 dhcp->request_timeout = 0; 01166 dhcp_bind(netif); 01167 } 01168 } 01169 /* received a DHCP_NAK in appropriate state? */ 01170 else if ((msg_type == DHCP_NAK) && 01171 ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) || 01172 (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) { 01173 DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_NAK received\n")); 01174 dhcp->request_timeout = 0; 01175 dhcp_handle_nak(netif); 01176 } 01177 /* received a DHCP_OFFER in DHCP_SELECTING state? */ 01178 else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) { 01179 DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OFFER received in DHCP_SELECTING state\n")); 01180 dhcp->request_timeout = 0; 01181 /* remember offered lease */ 01182 dhcp_handle_offer(netif); 01183 } 01184 pbuf_free(p); 01185 } |
Here is the call graph for this function:
|
Release a DHCP lease.
Definition at line 885 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_CLIENT_PORT, dhcp_create_request(), DHCP_DEBUG, dhcp_delete_request(), DHCP_FINE_TIMER_MSECS, DHCP_OFF, dhcp_option(), dhcp_option_byte(), DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, dhcp_option_trailer(), DHCP_OPTIONS_LEN, DHCP_RELEASE, DHCP_SERVER_PORT, dhcp_set_state(), ERR_OK, err_t, IP_ADDR_ANY, netif_set_gw(), netif_set_ipaddr(), netif_set_netmask(), pbuf_realloc(), u16_t, udp_bind(), udp_connect(), and udp_send(). Referenced by dhcp_timeout().
00886 { 00887 struct dhcp *dhcp = netif->dhcp; 00888 err_t result; 00889 u16_t msecs; 00890 DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_release()\n")); 00891 00892 /* idle DHCP client */ 00893 dhcp_set_state(dhcp, DHCP_OFF); 00894 00895 00896 /* create and initialize the DHCP message header */ 00897 result = dhcp_create_request(netif); 00898 if (result == ERR_OK) { 00899 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); 00900 dhcp_option_byte(dhcp, DHCP_RELEASE); 00901 00902 dhcp_option_trailer(dhcp); 00903 00904 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); 00905 00906 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); 00907 udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT); 00908 udp_send(dhcp->pcb, dhcp->p_out); 00909 dhcp_delete_request(netif); 00910 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n")); 00911 } else { 00912 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_release: could not allocate DHCP request\n")); 00913 } 00914 dhcp->tries++; 00915 msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; 00916 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; 00917 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release(): set request timeout %u msecs\n", msecs)); 00918 /* remove IP address from interface */ 00919 netif_set_ipaddr(netif, IP_ADDR_ANY); 00920 netif_set_gw(netif, IP_ADDR_ANY); 00921 netif_set_netmask(netif, IP_ADDR_ANY); 00922 /* TODO: netif_down(netif); */ 00923 return result; 00924 } |
Here is the call graph for this function:
|
Renew an existing DHCP lease at the involved DHCP server.
Definition at line 778 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_CLIENT_PORT, dhcp_create_request(), DHCP_DEBUG, dhcp_delete_request(), DHCP_FINE_TIMER_MSECS, dhcp_option(), dhcp_option_byte(), dhcp_option_long(), DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, DHCP_OPTION_REQUESTED_IP, DHCP_OPTION_SERVER_ID, dhcp_option_short(), dhcp_option_trailer(), DHCP_OPTIONS_LEN, DHCP_RENEWING, DHCP_REQUEST, DHCP_SERVER_PORT, dhcp_set_state(), ERR_OK, err_t, IP_ADDR_ANY, ntohl, pbuf_realloc(), u16_t, udp_bind(), udp_connect(), and udp_send(). Referenced by dhcp_t1_timeout(), and dhcp_timeout().
00779 { 00780 struct dhcp *dhcp = netif->dhcp; 00781 err_t result; 00782 u16_t msecs; 00783 DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_renew()\n")); 00784 dhcp_set_state(dhcp, DHCP_RENEWING); 00785 00786 /* create and initialize the DHCP message header */ 00787 result = dhcp_create_request(netif); 00788 if (result == ERR_OK) { 00789 00790 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); 00791 dhcp_option_byte(dhcp, DHCP_REQUEST); 00792 00793 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); 00794 /* TODO: use netif->mtu in some way */ 00795 dhcp_option_short(dhcp, 576); 00796 00797 #if 0 00798 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); 00799 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); 00800 #endif 00801 00802 #if 0 00803 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); 00804 dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); 00805 #endif 00806 /* append DHCP message trailer */ 00807 dhcp_option_trailer(dhcp); 00808 00809 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); 00810 00811 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); 00812 udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT); 00813 udp_send(dhcp->pcb, dhcp->p_out); 00814 dhcp_delete_request(netif); 00815 00816 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew: RENEWING\n")); 00817 } else { 00818 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_renew: could not allocate DHCP request\n")); 00819 } 00820 dhcp->tries++; 00821 /* back-off on retries, but to a maximum of 20 seconds */ 00822 msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000; 00823 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; 00824 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew(): set request timeout %u msecs\n", msecs)); 00825 return result; 00826 } |
Here is the call graph for this function:
|
Select a DHCP server offer out of all offers. Simply select the first offer received.
Definition at line 210 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_CLIENT_PORT, dhcp_create_request(), DHCP_DEBUG, dhcp_delete_request(), DHCP_FINE_TIMER_MSECS, dhcp_option(), DHCP_OPTION_BROADCAST, dhcp_option_byte(), dhcp_option_long(), DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, DHCP_OPTION_PARAMETER_REQUEST_LIST, DHCP_OPTION_REQUESTED_IP, DHCP_OPTION_ROUTER, DHCP_OPTION_SERVER_ID, dhcp_option_short(), DHCP_OPTION_SUBNET_MASK, dhcp_option_trailer(), DHCP_OPTIONS_LEN, DHCP_REQUEST, DHCP_REQUESTING, DHCP_SERVER_PORT, dhcp_set_state(), ERR_OK, err_t, IP_ADDR_ANY, IP_ADDR_BROADCAST, ntohl, pbuf_realloc(), u32_t, udp_bind(), udp_connect(), and udp_send(). Referenced by dhcp_handle_offer(), and dhcp_timeout().
00211 { 00212 struct dhcp *dhcp = netif->dhcp; 00213 err_t result; 00214 u32_t msecs; 00215 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_select()\n")); 00216 00217 /* create and initialize the DHCP message header */ 00218 result = dhcp_create_request(netif); 00219 if (result == ERR_OK) 00220 { 00221 dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); 00222 dhcp_option_byte(dhcp, DHCP_REQUEST); 00223 00224 dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); 00225 dhcp_option_short(dhcp, 576); 00226 00227 /* MUST request the offered IP address */ 00228 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); 00229 dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); 00230 00231 dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); 00232 dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); 00233 00234 dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 3); 00235 dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); 00236 dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); 00237 dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); 00238 00239 dhcp_option_trailer(dhcp); 00240 /* shrink the pbuf to the actual content length */ 00241 pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); 00242 00243 /* TODO: we really should bind to a specific local interface here 00244 but we cannot specify an unconfigured netif as it is addressless */ 00245 udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); 00246 /* send broadcast to any DHCP server */ 00247 udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT); 00248 udp_send(dhcp->pcb, dhcp->p_out); 00249 /* reconnect to any (or to server here?!) */ 00250 udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); 00251 dhcp_delete_request(netif); 00252 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_select: REQUESTING\n")); 00253 dhcp_set_state(dhcp, DHCP_REQUESTING); 00254 } else { 00255 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_select: could not allocate DHCP request\n")); 00256 } 00257 dhcp->tries++; 00258 msecs = dhcp->tries < 4 ? dhcp->tries * 1000 : 4 * 1000; 00259 dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; 00260 DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_select(): set request timeout %u msecs\n", msecs)); 00261 return result; 00262 } |
Here is the call graph for this function:
|
Definition at line 961 of file dhcp.c. References dhcp::state, and dhcp::tries. Referenced by dhcp_bind(), dhcp_check(), dhcp_discover(), dhcp_handle_nak(), dhcp_rebind(), dhcp_release(), dhcp_renew(), and dhcp_select().
|
|
Start DHCP negotiation for a network interface. If no DHCP client instance was attached to this interface, a new client is created first. If a DHCP client instance was already present, it restarts negotiation.
Definition at line 484 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_DEBUG, dhcp_discover(), dhcp_stop(), ERR_MEM, ERR_OK, err_t, netif::flags, LWIP_ASSERT, mem_free(), mem_malloc(), netif::name, NETIF_FLAG_DHCP, NULL, netif::num, and udp_new().
00485 { 00486 struct dhcp *dhcp = netif->dhcp; 00487 err_t result = ERR_OK; 00488 00489 LWIP_ASSERT("netif != NULL", netif != NULL); 00490 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_start(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num)); 00491 00492 if (dhcp == NULL) { 00493 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting new DHCP client\n")); 00494 dhcp = mem_malloc(sizeof(struct dhcp)); 00495 if (dhcp == NULL) { 00496 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n")); 00497 netif->flags &= ~NETIF_FLAG_DHCP; 00498 return ERR_MEM; 00499 } 00500 /* clear data structure */ 00501 memset(dhcp, 0, sizeof(struct dhcp)); 00502 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): allocated dhcp")); 00503 dhcp->pcb = udp_new(); 00504 if (dhcp->pcb == NULL) { 00505 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); 00506 mem_free((void *)dhcp); 00507 dhcp = NULL; 00508 netif->flags &= ~NETIF_FLAG_DHCP; 00509 return ERR_MEM; 00510 } 00511 /* store this dhcp client in the netif */ 00512 netif->dhcp = dhcp; 00513 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): created new udp pcb\n")); 00514 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n")); 00515 } else { 00516 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 3, ("dhcp_start(): restarting DHCP configuration\n")); 00517 } 00518 /* (re)start the DHCP negotiation */ 00519 result = dhcp_discover(netif); 00520 if (result != ERR_OK) { 00521 /* free resources allocated above */ 00522 dhcp_stop(netif); 00523 } 00524 return result; 00525 } |
Here is the call graph for this function:
|
Remove the DHCP client from the interface.
Definition at line 930 of file dhcp.c. References DBG_TRACE, DEBUGF, DHCP_DEBUG, dhcp_free_reply(), mem_free(), NULL, pbuf_free(), and udp_remove(). Referenced by dhcp_start().
00931 { 00932 struct dhcp *dhcp = netif->dhcp; 00933 DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_stop()\n")); 00934 /* netif is DHCP configured? */ 00935 if (dhcp != NULL) 00936 { 00937 if (dhcp->pcb != NULL) 00938 { 00939 udp_remove(dhcp->pcb); 00940 dhcp->pcb = NULL; 00941 } 00942 if (dhcp->p != NULL) 00943 { 00944 pbuf_free(dhcp->p); 00945 dhcp->p = NULL; 00946 } 00947 /* free unfolded reply */ 00948 dhcp_free_reply(dhcp); 00949 mem_free((void *)dhcp); 00950 netif->dhcp = NULL; 00951 } 00952 } |
Here is the call graph for this function:
|
The renewal period has timed out.
Definition at line 381 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_BOUND, DHCP_DEBUG, dhcp_renew(), DHCP_RENEWING, and DHCP_REQUESTING. Referenced by dhcp_coarse_tmr().
00382 { 00383 struct dhcp *dhcp = netif->dhcp; 00384 DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_t1_timeout()\n")); 00385 if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) { 00386 /* just retry to renew */ 00387 /* note that the rebind timer will eventually time-out if renew does not work */ 00388 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t1_timeout(): must renew\n")); 00389 dhcp_renew(netif); 00390 } 00391 } |
Here is the call graph for this function:
|
The rebind period has timed out. Definition at line 397 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_BOUND, DHCP_DEBUG, dhcp_rebind(), DHCP_RENEWING, and DHCP_REQUESTING. Referenced by dhcp_coarse_tmr().
00398 { 00399 struct dhcp *dhcp = netif->dhcp; 00400 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout()\n")); 00401 if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) { 00402 /* just retry to rebind */ 00403 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout(): must rebind\n")); 00404 dhcp_rebind(netif); 00405 } 00406 } |
Here is the call graph for this function:
|
A DHCP negotiation transaction, or ARP request, has timed out. The timer that was started with the DHCP or ARP request has timed out, indicating no response was received in time.
Definition at line 327 of file dhcp.c. References DBG_STATE, DBG_TRACE, DEBUGF, DHCP_BACKING_OFF, dhcp_bind(), dhcp_check(), DHCP_CHECKING, DHCP_DEBUG, dhcp_discover(), dhcp_rebind(), DHCP_REBINDING, dhcp_release(), dhcp_renew(), DHCP_RENEWING, DHCP_REQUESTING, dhcp_select(), and DHCP_SELECTING. Referenced by dhcp_fine_tmr().
00328 { 00329 struct dhcp *dhcp = netif->dhcp; 00330 DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_timeout()\n")); 00331 /* back-off period has passed, or server selection timed out */ 00332 if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) { 00333 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_timeout(): restarting discovery\n")); 00334 dhcp_discover(netif); 00335 /* receiving the requested lease timed out */ 00336 } else if (dhcp->state == DHCP_REQUESTING) { 00337 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n")); 00338 if (dhcp->tries <= 5) { 00339 dhcp_select(netif); 00340 } else { 00341 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n")); 00342 dhcp_release(netif); 00343 dhcp_discover(netif); 00344 } 00345 /* received no ARP reply for the offered address (which is good) */ 00346 } else if (dhcp->state == DHCP_CHECKING) { 00347 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); 00348 if (dhcp->tries <= 1) { 00349 dhcp_check(netif); 00350 /* no ARP replies on the offered address, 00351 looks like the IP address is indeed free */ 00352 } else { 00353 /* bind the interface to the offered address */ 00354 dhcp_bind(netif); 00355 } 00356 } 00357 /* did not get response to renew request? */ 00358 else if (dhcp->state == DHCP_RENEWING) { 00359 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n")); 00360 /* just retry renewal */ 00361 /* note that the rebind timer will eventually time-out if renew does not work */ 00362 dhcp_renew(netif); 00363 /* did not get response to rebind request? */ 00364 } else if (dhcp->state == DHCP_REBINDING) { 00365 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n")); 00366 if (dhcp->tries <= 8) { 00367 dhcp_rebind(netif); 00368 } else { 00369 DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n")); 00370 dhcp_release(netif); 00371 dhcp_discover(netif); 00372 } 00373 } 00374 } |
Here is the call graph for this function:
|
Extract the DHCP message and the DHCP options. Extract the DHCP message and the DHCP options, each into a contiguous piece of memory. As a DHCP message is variable sized by its options, and also allows overriding some fields for options, the easy approach is to first unfold the options into a conitguous piece of memory, and use that further on. Definition at line 1015 of file dhcp.c. References DBG_TRACE, DEBUGF, DHCP_DEBUG, dhcp_free_reply(), DHCP_OPTIONS_LEN, ERR_MEM, ERR_OK, err_t, mem_free(), mem_malloc(), dhcp::msg_in, NULL, dhcp::options_in, dhcp::options_in_len, dhcp::p, pbuf::tot_len, u16_t, and u8_t. Referenced by dhcp_recv().
01016 { 01017 struct pbuf *p = dhcp->p; 01018 u8_t *ptr; 01019 u16_t i; 01020 u16_t j = 0; 01021 /* free any left-overs from previous unfolds */ 01022 dhcp_free_reply(dhcp); 01023 dhcp->msg_in = NULL; 01024 dhcp->options_in = NULL; 01025 /* options present? */ 01026 if (dhcp->p->tot_len > (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN)) 01027 { 01028 dhcp->options_in_len = dhcp->p->tot_len - (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN); 01029 dhcp->options_in = mem_malloc(dhcp->options_in_len); 01030 if (dhcp->options_in == NULL) 01031 { 01032 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->options\n")); 01033 return ERR_MEM; 01034 } 01035 } 01036 dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN); 01037 if (dhcp->msg_in == NULL) 01038 { 01039 DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n")); 01040 mem_free((void *)dhcp->options_in); 01041 dhcp->options_in = NULL; 01042 return ERR_MEM; 01043 } 01044 01045 ptr = (u8_t *)dhcp->msg_in; 01046 /* proceed through struct dhcp_msg */ 01047 for (i = 0; i < sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN; i++) 01048 { 01049 *ptr++ = ((u8_t *)p->payload)[j++]; 01050 /* reached end of pbuf? */ 01051 if (j == p->len) 01052 { 01053 /* proceed to next pbuf in chain */ 01054 p = p->next; 01055 j = 0; 01056 } 01057 } 01058 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes into dhcp->msg_in[]\n", i)); 01059 if (dhcp->options_in != NULL) { 01060 ptr = (u8_t *)dhcp->options_in; 01061 /* proceed through options */ 01062 for (i = 0; i < dhcp->options_in_len; i++) { 01063 *ptr++ = ((u8_t *)p->payload)[j++]; 01064 /* reached end of pbuf? */ 01065 if (j == p->len) { 01066 /* proceed to next pbuf in chain */ 01067 p = p->next; 01068 j = 0; 01069 } 01070 } 01071 DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes to dhcp->options_in[]\n", i)); 01072 } 01073 return ERR_OK; 01074 } |
Here is the call graph for this function:
|
global transaction identifier, must be unique for each DHCP request. Definition at line 91 of file dhcp.c. Referenced by dhcp_create_request(). |