📄 dhcp.c
字号:
*/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 clients' 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")); 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")); 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; u8_t *option_ptr; /* clear options we might not get from the ACK */ dhcp->offered_sn_mask.addr = 0; dhcp->offered_gw_addr.addr = 0; dhcp->offered_bc_addr.addr = 0; /* lease time given? */ option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_LEASE_TIME); if (option_ptr != NULL) { /* remember offered lease time */ dhcp->offered_t0_lease = dhcp_get_option_long(option_ptr + 2); } /* renewal period given? */ option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T1); if (option_ptr != NULL) { /* remember given renewal period */ dhcp->offered_t1_renew = dhcp_get_option_long(option_ptr + 2); } else { /* calculate safe periods for renewal */ dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2; } /* renewal period given? */ option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T2); if (option_ptr != NULL) { /* remember given rebind period */ dhcp->offered_t2_rebind = dhcp_get_option_long(option_ptr + 2); } else { /* calculate safe periods for rebinding */ dhcp->offered_t2_rebind = dhcp->offered_t0_lease; } /* (y)our internet address */ ip_addr_set(&dhcp->offered_ip_addr, &dhcp->msg_in->yiaddr);/** * Patch #1308 * TODO: we must check if the file field is not overloaded by DHCP options! */#if 0 /* boot server address */ ip_addr_set(&dhcp->offered_si_addr, &dhcp->msg_in->siaddr); /* boot file name */ if (dhcp->msg_in->file[0]) { dhcp->boot_file_name = mem_malloc(strlen(dhcp->msg_in->file) + 1); strcpy(dhcp->boot_file_name, dhcp->msg_in->file); }#endif /* subnet mask */ option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SUBNET_MASK); /* subnet mask given? */ if (option_ptr != NULL) { dhcp->offered_sn_mask.addr = htonl(dhcp_get_option_long(&option_ptr[2])); } /* gateway router */ option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_ROUTER); if (option_ptr != NULL) { dhcp->offered_gw_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2])); } /* broadcast address */ option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_BROADCAST); if (option_ptr != NULL) { dhcp->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2])); } /* DNS servers */ option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_DNS_SERVER); if (option_ptr != NULL) { u8_t n; dhcp->dns_count = dhcp_get_option_byte(&option_ptr[1]) / (u32_t)sizeof(struct ip_addr); /* limit to at most DHCP_MAX_DNS DNS servers */ if (dhcp->dns_count > DHCP_MAX_DNS) dhcp->dns_count = DHCP_MAX_DNS; for (n = 0; n < dhcp->dns_count; n++) { dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2 + n * 4]));#if LWIP_DNS dns_setserver( n, (struct ip_addr *)(&(dhcp->offered_dns_addr[n].addr)));#endif /* LWIP_DNS */ }#if LWIP_DNS dns_setserver( n, (struct ip_addr *)(&ip_addr_any));#endif /* LWIP_DNS */ }}/** * 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 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 = 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 && dhcp->options_in == NULL && dhcp->options_in_len == 0); } /* clear data structure */ memset(dhcp, 0, sizeof(struct dhcp)); /* 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")); mem_free((void *)dhcp); netif->dhcp = dhcp = NULL; return ERR_MEM; }#if IP_SOF_BROADCAST dhcp->pcb->so_options|=SOF_BROADCAST;#endif /* IP_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. * * 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. * * @param netif The lwIP network interface */voiddhcp_inform(struct netif *netif){ struct dhcp *dhcp, *old_dhcp; err_t result = ERR_OK; dhcp = mem_malloc(sizeof(struct dhcp)); if (dhcp == NULL) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not allocate dhcp\n")); return; } memset(dhcp, 0, sizeof(struct dhcp)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): allocated dhcp\n")); dhcp->pcb = udp_new(); if (dhcp->pcb == NULL) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not obtain pcb")); goto free_dhcp_and_return; } old_dhcp = netif->dhcp; netif->dhcp = dhcp; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); /* create and initialize the DHCP message header */ result = dhcp_create_request(netif); if (result == ERR_OK) { dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); dhcp_option_byte(dhcp, DHCP_INFORM);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -