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

📄 dhcp.c

📁 freescale k40/k60 freertos-lwip例程
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (p->len < DHCP_MIN_REPLY_LEN) {    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message too short\n"));    goto free_pbuf_and_return;  }  if (reply_msg->op != DHCP_BOOTREPLY) {    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op));    goto free_pbuf_and_return;  }  /* iterate through hardware address and match against DHCP message */  for (i = 0; i < netif->hwaddr_len; i++) {    if (netif->hwaddr[i] != reply_msg->chaddr[i]) {      LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,        ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",        (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));      goto free_pbuf_and_return;    }  }  /* match transaction ID against what we expected */  if (ntohl(reply_msg->xid) != dhcp->xid) {    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,      ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",ntohl(reply_msg->xid),dhcp->xid));    goto free_pbuf_and_return;  }  /* option fields could be unfold? */  if (dhcp_unfold_reply(dhcp, p) != ERR_OK) {    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,      ("problem unfolding DHCP message - too short on memory?\n"));    goto free_pbuf_and_return;  }  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));  /* obtain pointer to DHCP message type */  options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE);  if (options_ptr == NULL) {    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));    goto free_pbuf_and_return;  }  /* read DHCP message type */  msg_type = dhcp_get_option_byte(options_ptr + 2);  /* message type is DHCP ACK? */  if (msg_type == DHCP_ACK) {    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n"));    /* in requesting state? */    if (dhcp->state == DHCP_REQUESTING) {      dhcp_handle_ack(netif);      dhcp->request_timeout = 0;#if DHCP_DOES_ARP_CHECK      /* check if the acknowledged lease address is already in use */      dhcp_check(netif);#else      /* bind interface to the acknowledged lease address */      dhcp_bind(netif);#endif    }    /* already bound to the given lease address? */    else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) {      dhcp->request_timeout = 0;      dhcp_bind(netif);    }  }  /* received a DHCP_NAK in appropriate state? */  else if ((msg_type == DHCP_NAK) &&    ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||     (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING  ))) {    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n"));    dhcp->request_timeout = 0;    dhcp_handle_nak(netif);  }  /* received a DHCP_OFFER in DHCP_SELECTING state? */  else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_SELECTING state\n"));    dhcp->request_timeout = 0;    /* remember offered lease */    dhcp_handle_offer(netif);  }free_pbuf_and_return:  dhcp_free_reply(dhcp);  pbuf_free(p);}/** * Create a DHCP request, fill in common headers * * @param netif the netif under DHCP control */static err_tdhcp_create_request(struct netif *netif){  struct dhcp *dhcp;  u16_t i;#ifndef DHCP_GLOBAL_XID  /** default global transaction identifier starting value (easy to match   *  with a packet analyser). We simply increment for each new request.   *  Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one   *  at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */  static u32_t xid = 0xABCD0000;#else  static u32_t xid;  static u8_t xid_initialised = 0;  if (!xid_initialised) {    xid = DHCP_GLOBAL_XID;    xid_initialised = !xid_initialised;  }#endif  LWIP_ERROR("dhcp_create_request: netif != NULL", (netif != NULL), return ERR_ARG;);  dhcp = netif->dhcp;  LWIP_ERROR("dhcp_create_request: dhcp != NULL", (dhcp != NULL), return ERR_VAL;);  LWIP_ASSERT("dhcp_create_request: dhcp->p_out == NULL", dhcp->p_out == NULL);  LWIP_ASSERT("dhcp_create_request: dhcp->msg_out == NULL", dhcp->msg_out == NULL);  dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);  if (dhcp->p_out == NULL) {    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,      ("dhcp_create_request(): could not allocate pbuf\n"));    return ERR_MEM;  }  LWIP_ASSERT("dhcp_create_request: check that first pbuf can hold struct dhcp_msg",           (dhcp->p_out->len >= sizeof(struct dhcp_msg)));  /* reuse transaction identifier in retransmissions */  if (dhcp->tries==0)      xid++;  dhcp->xid = xid;  LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,              ("transaction id xid(%"X32_F")\n", xid));  dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;  dhcp->msg_out->op = DHCP_BOOTREQUEST;  /* TODO: make link layer independent */  dhcp->msg_out->htype = DHCP_HTYPE_ETH;  /* TODO: make link layer independent */  dhcp->msg_out->hlen = DHCP_HLEN_ETH;  dhcp->msg_out->hops = 0;  dhcp->msg_out->xid = htonl(dhcp->xid);  dhcp->msg_out->secs = 0;  dhcp->msg_out->flags = 0;  dhcp->msg_out->ciaddr.addr = 0;  if (dhcp->state==DHCP_BOUND || dhcp->state==DHCP_RENEWING || dhcp->state==DHCP_REBINDING) {    dhcp->msg_out->ciaddr.addr = netif->ip_addr.addr;  }  dhcp->msg_out->yiaddr.addr = 0;  dhcp->msg_out->siaddr.addr = 0;  dhcp->msg_out->giaddr.addr = 0;  for (i = 0; i < DHCP_CHADDR_LEN; i++) {    /* copy netif hardware address, pad with zeroes */    dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/;  }  for (i = 0; i < DHCP_SNAME_LEN; i++) {    dhcp->msg_out->sname[i] = 0;  }  for (i = 0; i < DHCP_FILE_LEN; i++) {    dhcp->msg_out->file[i] = 0;  }  dhcp->msg_out->cookie = htonl(0x63825363UL);  dhcp->options_out_len = 0;  /* fill options field with an incrementing array (for debugging purposes) */  for (i = 0; i < DHCP_OPTIONS_LEN; i++) {    dhcp->msg_out->options[i] = (u8_t)i; /* for debugging only, no matter if truncated */  }  return ERR_OK;}/** * Free previously allocated memory used to send a DHCP request. * * @param netif the netif under DHCP control */static voiddhcp_delete_request(struct netif *netif){  struct dhcp *dhcp;  LWIP_ERROR("dhcp_delete_request: netif != NULL", (netif != NULL), return;);  dhcp = netif->dhcp;  LWIP_ERROR("dhcp_delete_request: dhcp != NULL", (dhcp != NULL), return;);  LWIP_ASSERT("dhcp_delete_request: dhcp->p_out != NULL", dhcp->p_out != NULL);  LWIP_ASSERT("dhcp_delete_request: dhcp->msg_out != NULL", dhcp->msg_out != NULL);  if (dhcp->p_out != NULL) {    pbuf_free(dhcp->p_out);  }  dhcp->p_out = NULL;  dhcp->msg_out = NULL;}/** * Add a DHCP message trailer * * Adds the END option to the DHCP message, and if * necessary, up to three padding bytes. * * @param dhcp DHCP state structure */static voiddhcp_option_trailer(struct dhcp *dhcp){  LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;);  LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL);  LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);  dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;  /* packet is too small, or not 4 byte aligned? */  while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) {    /* LWIP_DEBUGF(DHCP_DEBUG,("dhcp_option_trailer:dhcp->options_out_len=%"U16_F", DHCP_OPTIONS_LEN=%"U16_F, dhcp->options_out_len, DHCP_OPTIONS_LEN)); */    LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);    /* add a fill/padding byte */    dhcp->msg_out->options[dhcp->options_out_len++] = 0;  }}/** * Find the offset of a DHCP option inside the DHCP message. * * @param dhcp DHCP client * @param option_type * * @return a byte offset into the UDP message where the option was found, or * zero if the given option was not found. */static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type){  u8_t overload = DHCP_OVERLOAD_NONE;  /* options available? */  if ((dhcp->options_in != NULL) && (dhcp->options_in_len > 0)) {    /* start with options field */    u8_t *options = (u8_t *)dhcp->options_in;    u16_t offset = 0;    /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */    while ((offset < dhcp->options_in_len) && (options[offset] != DHCP_OPTION_END)) {      /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */      /* are the sname and/or file field overloaded with options? */      if (options[offset] == DHCP_OPTION_OVERLOAD) {        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded message detected\n"));        /* skip option type and length */        offset += 2;        overload = options[offset++];      }      /* requested option found */      else if (options[offset] == option_type) {        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("option found at offset %"U16_F" in options\n", offset));        return &options[offset];      /* skip option */      } else {         LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", options[offset]));        /* skip option type */        offset++;        /* skip option length, and then length bytes */        offset += 1 + options[offset];      }    }    /* is this an overloaded message? */    if (overload != DHCP_OVERLOAD_NONE) {      u16_t field_len;      if (overload == DHCP_OVERLOAD_FILE) {        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n"));        options = (u8_t *)&dhcp->msg_in->file;        field_len = DHCP_FILE_LEN;      } else if (overload == DHCP_OVERLOAD_SNAME) {        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n"));        options = (u8_t *)&dhcp->msg_in->sname;        field_len = DHCP_SNAME_LEN;      /* TODO: check if else if () is necessary */      } else {        LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n"));        options = (u8_t *)&dhcp->msg_in->sname;        field_len = DHCP_FILE_LEN + DHCP_SNAME_LEN;      }      offset = 0;      /* at least 1 byte to read and no end marker */      while ((offset < field_len) && (options[offset] != DHCP_OPTION_END)) {        if (options[offset] == option_type) {           LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("option found at offset=%"U16_F"\n", offset));          return &options[offset];        /* skip option */        } else {          LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("skipping option %"U16_F"\n", options[offset]));          /* skip option type */          offset++;          offset += 1 + options[offset];        }      }    }  }  return NULL;}/** * Return the byte of DHCP option data. * * @param client DHCP client. * @param ptr pointer obtained by dhcp_get_option_ptr(). * * @return byte value at the given address. */static u8_tdhcp_get_option_byte(u8_t *ptr){  LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%"U16_F"\n", (u16_t)(*ptr)));  return *ptr;}#if 0 /* currently unused *//** * Return the 16-bit value of DHCP option data. * * @param client DHCP client. * @param ptr pointer obtained by dhcp_get_option_ptr(). * * @return byte value at the given address. */static u16_tdhcp_get_option_short(u8_t *ptr){  u16_t value;  value = *ptr++ << 8;  value |= *ptr;  LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%"U16_F"\n", value));  return value;}#endif/** * Return the 32-bit value of DHCP option data. * * @param client DHCP client. * @param ptr pointer obtained by dhcp_get_option_ptr(). * * @return byte value at the given address. */static u32_t dhcp_get_option_long(u8_t *ptr){  u32_t value;  value = (u32_t)(*ptr++) << 24;  value |= (u32_t)(*ptr++) << 16;  value |= (u32_t)(*ptr++) << 8;  value |= (u32_t)(*ptr++);  LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%"U32_F"\n", value));  return value;}#endif /* LWIP_DHCP */

⌨️ 快捷键说明

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