⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcp.c

📁 《嵌入式网络系统设计-基于Atmel ARM7 系列》这个本书的光盘资料
💻 C
📖 第 1 页 / 共 4 页
字号:
  }  /* did not get response to renew request? */  else if (dhcp->state == DHCP_RENEWING) {    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]) / (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]));    }  }}/** * 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%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)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_ASSERT("netif != NULL", netif != NULL);  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_arp_reply()\n"));  /* is a 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%08"X32_F"\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 %"U16_F" 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -