📄 dhcp.c
字号:
} } /* proceed to next netif */ netif = netif->next; }}/** * DHCP transaction timeout handling * * A DHCP server is expected to respond within a short period of time. * This timer checks whether an outstanding DHCP request is timed out. */voiddhcp_fine_tmr(){ struct netif *netif = netif_list; /* loop through netif's */ while (netif != NULL) { /* only act on DHCP configured interfaces */ if (netif->dhcp != NULL) { /* timer is active (non zero), and is about to trigger now */ if (netif->dhcp->request_timeout > 1) { netif->dhcp->request_timeout--; } else if (netif->dhcp->request_timeout == 1) { netif->dhcp->request_timeout--; /* { netif->dhcp->request_timeout == 0 } */ LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n")); /* this client's request timeout triggered */ dhcp_timeout(netif); } } /* proceed to next network interface */ netif = netif->next; }}/** * 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. * * @param netif the netif under DHCP control */static voiddhcp_timeout(struct netif *netif){ struct dhcp *dhcp = netif->dhcp; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n")); /* back-off period has passed, or server selection timed out */ if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n")); dhcp_discover(netif); /* receiving the requested lease timed out */ } else if (dhcp->state == DHCP_REQUESTING) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n")); if (dhcp->tries <= 5) { dhcp_select(netif); } else { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n")); dhcp_release(netif); dhcp_discover(netif); }#if DHCP_DOES_ARP_CHECK /* received no ARP reply for the offered address (which is good) */ } else if (dhcp->state == DHCP_CHECKING) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); if (dhcp->tries <= 1) { dhcp_check(netif); /* no ARP replies on the offered address, looks like the IP address is indeed free */ } else { /* bind the interface to the offered address */ dhcp_bind(netif); }#endif /* DHCP_DOES_ARP_CHECK */ } /* did not get response to renew request? */ else if (dhcp->state == DHCP_RENEWING) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n")); /* just retry renewal */ /* note that the rebind timer will eventually time-out if renew does not work */ dhcp_renew(netif); /* did not get response to rebind request? */ } else if (dhcp->state == DHCP_REBINDING) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n")); if (dhcp->tries <= 8) { dhcp_rebind(netif); } else { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n")); dhcp_release(netif); dhcp_discover(netif); } } else if (dhcp->state == DHCP_REBOOTING) { if (dhcp->tries < REBOOT_TRIES) { dhcp_reboot(netif); } else { dhcp_discover(netif); } }}/** * The renewal period has timed out. * * @param netif the netif under DHCP control */static voiddhcp_t1_timeout(struct netif *netif){ struct dhcp *dhcp = netif->dhcp; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n")); if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) { /* just retry to renew - note that the rebind timer (t2) will * eventually time-out if renew tries fail. */ LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t1_timeout(): must renew\n")); /* This slightly different to RFC2131: DHCPREQUEST will be sent from state DHCP_RENEWING, not DHCP_BOUND */ dhcp_renew(netif); }}/** * The rebind period has timed out. * * @param netif the netif under DHCP control */static voiddhcp_t2_timeout(struct netif *netif){ struct dhcp *dhcp = netif->dhcp; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n")); if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) { /* just retry to rebind */ LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout(): must rebind\n")); /* This slightly different to RFC2131: DHCPREQUEST will be sent from state DHCP_REBINDING, not DHCP_BOUND */ dhcp_rebind(netif); }}/** * Handle a DHCP ACK packet * * @param netif the netif under DHCP control */static voiddhcp_handle_ack(struct netif *netif){ struct dhcp *dhcp = netif->dhcp;#if LWIP_DNS u8_t n;#endif /* LWIP_DNS */ /* clear options we might not get from the ACK */ ip_addr_set_zero(&dhcp->offered_sn_mask); ip_addr_set_zero(&dhcp->offered_gw_addr);#if LWIP_DHCP_BOOTP_FILE ip_addr_set_zero(&dhcp->offered_si_addr);#endif /* LWIP_DHCP_BOOTP_FILE */ /* lease time given? */ if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) { /* remember offered lease time */ dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME); } /* renewal period given? */ if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) { /* remember given renewal period */ dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1); } else { /* calculate safe periods for renewal */ dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2; } /* renewal period given? */ if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) { /* remember given rebind period */ dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2); } else { /* calculate safe periods for rebinding */ dhcp->offered_t2_rebind = dhcp->offered_t0_lease; } /* (y)our internet address */ ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr);#if LWIP_DHCP_BOOTP_FILE /* copy boot server address, boot file name copied in dhcp_parse_reply if not overloaded */ ip_addr_copy(dhcp->offered_si_addr, dhcp->msg_in->siaddr);#endif /* LWIP_DHCP_BOOTP_FILE */ /* subnet mask given? */ if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) { /* remember given subnet mask */ ip4_addr_set_u32(&dhcp->offered_sn_mask, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK))); dhcp->subnet_mask_given = 1; } else { dhcp->subnet_mask_given = 0; } /* gateway router */ if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) { ip4_addr_set_u32(&dhcp->offered_gw_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER))); } #if LWIP_DNS /* DNS servers */ n = 0; while(dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n) && (n < DNS_MAX_SERVERS)) { ip_addr_t dns_addr; ip4_addr_set_u32(&dns_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n))); dns_setserver(n, &dns_addr); n++; }#endif /* LWIP_DNS */}/** Set a statically allocated struct dhcp to work with. * Using this prevents dhcp_start to allocate it using mem_malloc. * * @param netif the netif for which to set the struct dhcp * @param dhcp (uninitialised) dhcp struct allocated by the application */voiddhcp_set_struct(struct netif *netif, struct dhcp *dhcp){ LWIP_ASSERT("netif != NULL", netif != NULL); LWIP_ASSERT("dhcp != NULL", dhcp != NULL); LWIP_ASSERT("netif already has a struct dhcp set", netif->dhcp == NULL); /* clear data structure */ memset(dhcp, 0, sizeof(struct dhcp)); /* dhcp_set_state(&dhcp, DHCP_OFF); */ netif->dhcp = dhcp;}/** Removes a struct dhcp from a netif. * * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the * struct dhcp since the memory is passed back to the heap. * * @param netif the netif from which to remove the struct dhcp */void dhcp_cleanup(struct netif *netif){ LWIP_ASSERT("netif != NULL", netif != NULL); if (netif->dhcp != NULL) { mem_free(netif->dhcp); netif->dhcp = NULL; }}/** * 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. * * @param netif The lwIP network interface * @return lwIP error code * - ERR_OK - No error * - ERR_MEM - Out of memory */err_tdhcp_start(struct netif *netif){ struct dhcp *dhcp; err_t result = ERR_OK; LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); dhcp = netif->dhcp; 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)); /* Remove the flag that says this netif is handled by DHCP, it is set when we succeeded starting. */ netif->flags &= ~NETIF_FLAG_DHCP; /* check hwtype of the netif */ if ((netif->flags & NETIF_FLAG_ETHARP) == 0) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): No ETHARP netif\n")); return ERR_ARG; } /* check MTU of the netif */ if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n")); return ERR_MEM; } /* no DHCP client attached yet? */ if (dhcp == NULL) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n")); dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp)); if (dhcp == NULL) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n")); return ERR_MEM; } /* store this dhcp client in the netif */ netif->dhcp = dhcp; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp")); /* already has DHCP client attached */ } else { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n")); if (dhcp->pcb != NULL) { udp_remove(dhcp->pcb); } LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL); LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL ); } /* clear data structure */ memset(dhcp, 0, sizeof(struct dhcp)); /* dhcp_set_state(&dhcp, DHCP_OFF); */ /* allocate UDP PCB */ dhcp->pcb = udp_new(); if (dhcp->pcb == NULL) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); return ERR_MEM; } dhcp->pcb->so_options |= SOF_BROADCAST; /* set up local and remote port for the pcb */ udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); /* set up the recv callback and argument */ udp_recv(dhcp->pcb, dhcp_recv, netif); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n")); /* (re)start the DHCP negotiation */ result = dhcp_discover(netif); if (result != ERR_OK) { /* free resources allocated above */ dhcp_stop(netif); return ERR_MEM; } /* Set the flag that says this netif is handled by DHCP. */ netif->flags |= NETIF_FLAG_DHCP; return result;}/** * Inform a DHCP server of our manual configuration. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -