📄 dhcp.c.svn-base
字号:
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 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 | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n")); if (dhcp->tries <= 8) { dhcp_rebind(netif); } else { LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n")); dhcp_release(netif); dhcp_discover(netif); } }}/** * The renewal period has timed out. * * @param netif the netif under DHCP control */static void dhcp_t1_timeout(struct netif *netif){ struct dhcp *dhcp = netif->dhcp; LWIP_DEBUGF(DHCP_DEBUG | 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 | DBG_TRACE | DBG_STATE, ("dhcp_t1_timeout(): must renew\n")); dhcp_renew(netif); }}/** * The rebind period has timed out. * */static void dhcp_t2_timeout(struct netif *netif){ struct dhcp *dhcp = netif->dhcp; LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 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 | DBG_TRACE | DBG_STATE, ("dhcp_t2_timeout(): must rebind\n")); dhcp_rebind(netif); }}/** * * @param netif the netif under DHCP control */static void dhcp_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]); /* 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<<2)])); } }}/** * 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_t dhcp_start(struct netif *netif){ struct dhcp *dhcp = netif->dhcp; err_t result = ERR_OK; LWIP_ASSERT("netif != NULL", netif != NULL); LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_start(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num)); netif->flags &= ~NETIF_FLAG_DHCP; /* no DHCP client attached yet? */ if (dhcp == NULL) { LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting new DHCP client\n")); dhcp = mem_malloc(sizeof(struct dhcp)); if (dhcp == NULL) { LWIP_DEBUGF(DHCP_DEBUG | 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 | DBG_TRACE, ("dhcp_start(): allocated dhcp")); /* already has DHCP client attached */ } else { LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 3, ("dhcp_start(): restarting DHCP configuration\n")); } /* clear data structure */ memset(dhcp, 0, sizeof(struct dhcp)); /* allocate UDP PCB */ dhcp->pcb = udp_new(); if (dhcp->pcb == NULL) { LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); mem_free((void *)dhcp); netif->dhcp = dhcp = NULL; return ERR_MEM; } LWIP_DEBUGF(DHCP_DEBUG | 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; } 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 * */void dhcp_inform(struct netif *netif){ struct dhcp *dhcp; err_t result = ERR_OK; dhcp = mem_malloc(sizeof(struct dhcp)); if (dhcp == NULL) { LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n")); return; } netif->dhcp = dhcp; memset(dhcp, 0, sizeof(struct dhcp)); LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_inform(): allocated dhcp\n")); dhcp->pcb = udp_new(); if (dhcp->pcb == NULL) { LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not obtain pcb")); mem_free((void *)dhcp); return; } LWIP_DEBUGF(DHCP_DEBUG | 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); dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); /* TODO: use netif->mtu ?! */ dhcp_option_short(dhcp, 576); dhcp_option_trailer(dhcp); pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT); LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_inform: INFORMING\n")); udp_send(dhcp->pcb, dhcp->p_out); udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); dhcp_delete_request(netif); } else { LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform: could not allocate DHCP request\n")); } if (dhcp != NULL) { if (dhcp->pcb != NULL) udp_remove(dhcp->pcb); dhcp->pcb = NULL; mem_free((void *)dhcp); netif->dhcp = NULL; }}#if DHCP_DOES_ARP_CHECK/** * Match an ARP reply with the offered IP address. * * @param addr The IP address we received a reply from * */void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr){ LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_arp_reply()\n")); /* is this DHCP client doing an ARP check? */ if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) { LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08lx\n", addr->addr)); /* did a host respond with the address we were offered by the DHCP server? */ if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) { /* we will not accept the offered address */ LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 1, ("dhcp_arp_reply(): arp reply matched with offered address, declining\n")); dhcp_decline(netif); } }}/** * Decline an offered lease. * * Tell the DHCP server we do not accept the offered address. * One reason to decline the lease is when we find out the address * is already in use by another host (through ARP). */static err_t dhcp_decline(struct netif *netif){ struct dhcp *dhcp = netif->dhcp; err_t result = ERR_OK; u16_t msecs; LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_decline()\n")); dhcp_set_state(dhcp, DHCP_BACKING_OFF); /* 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_DECLINE); dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); dhcp_option_short(dhcp, 576); dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); dhcp_option_trailer(dhcp); /* resize pbuf to reflect true size of options */ pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); /* @todo: should we really connect here? we are performing sendto() */ udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); /* per section 4.4.4, broadcast DECLINE messages */ udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT); dhcp_delete_request(netif); LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_decline: BACKING OFF\n")); } else { LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_decline: could not allocate DHCP request\n")); } dhcp->tries++; msecs = 10*1000; dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_decline(): set request timeout %u msecs\n", msecs)); return result;}#endif/** * Start the DHCP process, discover a DHCP server. * */static err_t dhcp_discover(struct netif *netif){ struct dhcp *dhcp = netif->dhcp; err_t result = ERR_OK; u16_t msecs; LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_discover()\n")); ip_addr_set(&dhcp->offered_ip_addr, IP_ADDR_ANY); /* create and initialize the DHCP message header */ result = dhcp_create_request(netif); if (result == ERR_OK) { LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: making request\n")); dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); dhcp_option_byte(dhcp, DHCP_DISCOVER); dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); dhcp_option_short(dhcp, 576); dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); dhcp_option_trailer(dhcp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -