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

📄 dhcp.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 4 页
字号:
  /*-------------------------------------------------------------------*/  dest.sin_family = AF_INET;  if ((dhcp.state == DHCP_RENEW) || (type == DHCPRELEASE))  {    route.gw = dest.sin_addr.s_addr = dhcp.serverID;  }  else  {    dest.sin_addr.s_addr = 0xFFFFFFFF;    route.gw = 0;  }  dest.sin_port = htons(DHCP_SERV);  sock->local.sin_addr.s_addr = ip_addr;  route.ni = ni;  route.flags = RT_GATEWAY;  /*-------------------------------------------------------------------*/  /* Send datagram to server.                                          */  /*-------------------------------------------------------------------*/  UdpSend(sock, &dest, buf, opts - &msg->op, &route);}/***********************************************************************//* parse_response: Parse response from DHCP server                     *//*                                                                     *//*     Returns: -1 if error found, otherwise DHCP message type         *//*                                                                     *//***********************************************************************/static int parse_response(DhcpMsg *msg){  ui8 *opt = &msg->options[0] + 4;  ui8 overload = 0;  int len, type = -1;  uint xid;  /*-------------------------------------------------------------------*/  /* Ensure message op code/type is BOOTREPLY.                         */  /*-------------------------------------------------------------------*/  if (msg->op != BOOTREPLY)    return -1;  /*-------------------------------------------------------------------*/  /* Ensure transaction ID matches that sent to server.                */  /*-------------------------------------------------------------------*/  memcpy(&xid, &msg->xid, sizeof(xid));  if (xid != htonl(TransactionId))    return -1;  /*-------------------------------------------------------------------*/  /* Verify presence of magic cookie value.                            */  /*-------------------------------------------------------------------*/  if ((msg->options[0] != 99) || (msg->options[1] != 130) ||      (msg->options[2] != 83) || (msg->options[3] != 99))    return -1;  /*-------------------------------------------------------------------*/  /* Read "yiaddr" and save it as the address to be requested.         */  /*-------------------------------------------------------------------*/  memcpy(&dhcp.reqAddr, &msg->yiaddr, IP_ALEN);  /*-------------------------------------------------------------------*/  /* Loop until all options have been read.                            */  /*-------------------------------------------------------------------*/  for (;;)  {    /*-----------------------------------------------------------------*/    /* Parse each individual option.                                   */    /*-----------------------------------------------------------------*/    switch (*opt++)    {      /*---------------------------------------------------------------*/      /* Adjust option pointer with padding option.                    */      /*---------------------------------------------------------------*/      case PADDING:        ++opt;        break;      /*---------------------------------------------------------------*/      /* Read subnetwork's subnet mask.                                */      /*---------------------------------------------------------------*/      case SUBNET_MASK:        /*-------------------------------------------------------------*/        /* Verify option length equals 4.                              */        /*-------------------------------------------------------------*/        if (*opt++ != 4)          return -1;        /*-------------------------------------------------------------*/        /* Read subnet mask, advance option pointer, and break.        */        /*-------------------------------------------------------------*/        memcpy(&dhcp.subnetMask, opt, 4);        opt += 4;        break;      case DNS_SERVER:        /*-------------------------------------------------------------*/        /* Verify option length is >= 4 and is a multiple of 4.        */        /*-------------------------------------------------------------*/        len = *opt++;        if ((len < 4) || (len & 3))          return -1;        /*-------------------------------------------------------------*/        /* If either DNS address is unconfigured, use this address.    */        /*-------------------------------------------------------------*/        if (PriDnsServer == 0)          memcpy(&PriDnsServer, opt, 4);        else if (SecDnsServer == 0)          memcpy(&SecDnsServer, opt, 4);        if (PriDnsServer == SecDnsServer)          SecDnsServer = 0;        /*-------------------------------------------------------------*/        /* Advance option pointer and break.                           */        /*-------------------------------------------------------------*/        opt += len;        break;      /*---------------------------------------------------------------*/      /* Read IP address lease time granted by DHCP server.            */      /*---------------------------------------------------------------*/      case LEASE_TIME:        /*-------------------------------------------------------------*/        /* Verify option length equals 4.                              */        /*-------------------------------------------------------------*/        if (*opt++ != 4)          return -1;        /*-------------------------------------------------------------*/        /* Read lease time and advance option pointer.                 */        /*-------------------------------------------------------------*/        memcpy(&dhcp.leaseTime, opt, 4);        opt += 4;        /*-------------------------------------------------------------*/        /* Convert to host order, then break.                          */        /*-------------------------------------------------------------*/        dhcp.leaseTime = ntohl(dhcp.leaseTime);        break;      /*---------------------------------------------------------------*/      /* Flag locations of overloaded options.                         */      /*---------------------------------------------------------------*/      case OVERLOAD:        /*-------------------------------------------------------------*/        /* Verify option length equals 1.                              */        /*-------------------------------------------------------------*/        if (*opt++ != 1)          return -1;        /*-------------------------------------------------------------*/        /* Read overload option value, advance pointer, and break.     */        /*-------------------------------------------------------------*/        overload = *opt++;        break;      /*---------------------------------------------------------------*/      /* Unsupported option.                                           */      /*---------------------------------------------------------------*/      default:        opt = opt + 1 + *opt;        break;      /*---------------------------------------------------------------*/      /* Determine DHCP message type.                                  */      /*---------------------------------------------------------------*/      case MSG_TYPE:        /*-------------------------------------------------------------*/        /* Verify option length equals 1.                              */        /*-------------------------------------------------------------*/        if (*opt++ != 1)          return -1;        /*-------------------------------------------------------------*/        /* Read message type and verify it's value is legal.           */        /*-------------------------------------------------------------*/        type = *opt++;        if ((type < 1) || (type > 7))          return -1;        break;      /*---------------------------------------------------------------*/      /* Read ID of DHCP server.                                       */      /*---------------------------------------------------------------*/      case SERVER_ID:        /*-------------------------------------------------------------*/        /* Verify option length equals 4.                              */        /*-------------------------------------------------------------*/        if (*opt++ != 4)          return -1;        /*-------------------------------------------------------------*/        /* Read server identifier, advance option pointer, and break.  */        /*-------------------------------------------------------------*/        memcpy(&dhcp.serverID, opt, 4);        opt += 4;        break;      /*---------------------------------------------------------------*/      /* Read renewal timer value.                                     */      /*---------------------------------------------------------------*/      case RENEWAL_T1:        /*-------------------------------------------------------------*/        /* Verify option length equals 4.                              */        /*-------------------------------------------------------------*/        if (*opt++ != 4)          return -1;        /*-------------------------------------------------------------*/        /* Read renewal timer value and advance option pointer.        */        /*-------------------------------------------------------------*/        memcpy(&dhcp.renewT1, opt, 4);        opt += 4;        /*-------------------------------------------------------------*/        /* Convert to host order, then break.                          */        /*-------------------------------------------------------------*/        dhcp.renewT1 = ntohl(dhcp.renewT1);        break;      /*---------------------------------------------------------------*/      /* Read rebind timer value.                                      */      /*---------------------------------------------------------------*/      case REBINDING_T2:        /*-------------------------------------------------------------*/        /* Verify option length equals 4.                              */        /*-------------------------------------------------------------*/        if (*opt++ != 4)          return -1;        /*-------------------------------------------------------------*/        /* Read rebind timer value and advance option pointer.         */        /*-------------------------------------------------------------*/        memcpy(&dhcp.rebindT2, opt, 4);        opt += 4;        /*-------------------------------------------------------------*/        /* Convert to host order, then break.                          */        /*-------------------------------------------------------------*/        dhcp.rebindT2 = ntohl(dhcp.rebindT2);        break;      case ROUTER_IP:        /*-------------------------------------------------------------*/        /* Verify option length is >= 4 and is a multiple of 4.        */        /*-------------------------------------------------------------*/        len = *opt++;        if ((len < 4) || (len & 3))          return -1;        /*-------------------------------------------------------------*/        /* Read address of first router, advance pointer, and break.   */        /*-------------------------------------------------------------*/        memcpy(&dhcp.router, opt, 4);        opt += len;        break;      /*---------------------------------------------------------------*/      /* Finished reading options, sname, or file field.               */      /*---------------------------------------------------------------*/      case OPTION_END:        /*-------------------------------------------------------------*/        /* Exit if overloading finished or was never requested.        */        /*-------------------------------------------------------------*/        if (overload == 0)          return type;        /*-------------------------------------------------------------*/        /* If file field overloaded, clear selection and set pointer.  */        /*-------------------------------------------------------------*/        else if (overload & USE_FILE_FIELD)        {          overload &= ~USE_FILE_FIELD;          opt = &msg->file[0];        }        /*-------------------------------------------------------------*/        /* If sname field overloaded, clear selection and set pointer. */        /*-------------------------------------------------------------*/        else if (overload & USE_SNAME_FIELD)        {          overload &= ~USE_SNAME_FIELD;          opt = &msg->sname[0];        }        break;    }  }}/***********************************************************************//* get_response: UDP mode socket callback function                     *//*                                                                     *//***********************************************************************/static void get_response(int sock_id, ui32 events){  SOCKET sock = &Socks[sock_id - 1];  NetBuf *buf;  int type;  /*-------------------------------------------------------------------*/  /* Return if no receive buffers are waiting.                         */

⌨️ 快捷键说明

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