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

📄 dhcp.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 4 页
字号:
  /*-------------------------------------------------------------------*/  buf = sock->rq_head;  if (buf == NULL)    return;  /*-------------------------------------------------------------------*/  /* Extract buffer from receive queue.                                */  /*-------------------------------------------------------------------*/  sock->rq_head = buf->next;  --sock->q_count;  /*-------------------------------------------------------------------*/  /* Extract options from packet and then free buffer.                 */  /*-------------------------------------------------------------------*/  type = parse_response((DhcpMsg *)buf->app_data);  tcpRetBuf(&buf);  /*-------------------------------------------------------------------*/  /* If packet was error-free, process the packet received event.      */  /*-------------------------------------------------------------------*/  if (type != -1)    DhcpSwitch[dhcp.state](type);}/***********************************************************************//*   dhcp_free: DHCP state machine shutdown                            *//*                                                                     *//***********************************************************************/static void dhcp_free(int event){  switch (event)  {  case TRANSITION:    if (dhcp.state >= DHCP_BOUND)      send_msg(dhcp.ni, dhcp.reqAddr, DHCPRELEASE);    dhcp.state = DHCP_FREE;    NetTimerStop(&dhcp.msgTimer);    NetTimerStop(&dhcp.leaseTimer);    break;  }}/***********************************************************************//*   dhcp_init: DHCP state machine initialization                      *//*                                                                     *//***********************************************************************/static void dhcp_init(int event){  switch (event)  {  case TRANSITION:    /*-----------------------------------------------------------------*/    /* If interface was bound, have to remove all interface routes.    */    /*-----------------------------------------------------------------*/    if (dhcp.state >= DHCP_BOUND)      NiRtDel(dhcp.ni);    /*-----------------------------------------------------------------*/    /* Else if restarting, call event callback function if installed.  */    /*-----------------------------------------------------------------*/    else if ((dhcp.state > DHCP_FREE) && dhcp.ni->report)      dhcp.ni->report(dhcp.ni, NIE_RESTART);    /*-----------------------------------------------------------------*/    /* Assign state.                                                   */    /*-----------------------------------------------------------------*/    dhcp.state = DHCP_INIT;    /*-----------------------------------------------------------------*/    /* Stop the lease and retransmission timers.                       */    /*-----------------------------------------------------------------*/    NetTimerStop(&dhcp.msgTimer);    NetTimerStop(&dhcp.leaseTimer);    /*-----------------------------------------------------------------*/    /* Initially clear all values potentially read from DHCP server.   */    /*-----------------------------------------------------------------*/    dhcp.renewT1 = dhcp.rebindT2 = dhcp.leaseTime = 0;    dhcp.router = dhcp.serverID = dhcp.subnetMask = 0;    dhcp.ni->ip_addr = 0;    break;  case MSG_TIMEOUT:    /*-----------------------------------------------------------------*/    /* Transition to DHCP_SELECT state.                                */    /*-----------------------------------------------------------------*/    dhcp_select(TRANSITION);    break;  }}/***********************************************************************//*   dhcp_select: Broadcast DHCPDISCOVER, look for DHCPOFFER           *//*                                                                     *//***********************************************************************/static void dhcp_select(int event){  uint i;  switch (event)  {  case TRANSITION:    /*-----------------------------------------------------------------*/    /* Initialize state and retransmission delay.                      */    /*-----------------------------------------------------------------*/    dhcp.state = DHCP_SELECT;    dhcp.retransDelay = K4_SECONDS;    /*-----------------------------------------------------------------*/    /* Record tick count at beginning of lease attempt.                */    /*-----------------------------------------------------------------*/    dhcp.req_time = NetTickCount;    /*lint -fallthrough */  case MSG_TIMEOUT:    /*-----------------------------------------------------------------*/    /* If max retry period exceeded, reset state to DHCP_INIT.         */    /*-----------------------------------------------------------------*/    if (dhcp.retransDelay >= K64_SECONDS)    {      dhcp_init(TRANSITION);      dhcp_init(MSG_TIMEOUT);    }    /*-----------------------------------------------------------------*/    /* Otherwise, broadcast a DHCPDISCOVER message.                    */    /*-----------------------------------------------------------------*/    else    {      send_msg(dhcp.ni, 0, DHCPDISCOVER);      i = (dhcp.retransDelay - K1_SECOND) + (rand() % K2_SECONDS);      NetTimerStart(&dhcp.msgTimer, i);      dhcp.retransDelay <<= 1;    }    break;  case DHCPOFFER:    /*-----------------------------------------------------------------*/    /* Transition to DHCP_REQUEST state.                               */    /*-----------------------------------------------------------------*/    dhcp_request(TRANSITION);    break;  }}/***********************************************************************//*  dhcp_request: Broadcast DHCPREQUEST, look for DHCPACK              *//*                                                                     *//***********************************************************************/static void dhcp_request(int event){  uint i;  switch (event)  {  case TRANSITION:    dhcp.state = DHCP_REQUEST;    dhcp.retransDelay = K4_SECONDS;    /*lint -fallthrough */  case MSG_TIMEOUT:    /*-----------------------------------------------------------------*/    /* If max retry period exceeded, reset state to DHCP_INIT.         */    /*-----------------------------------------------------------------*/    if (dhcp.retransDelay >= K64_SECONDS)    {      dhcp_init(TRANSITION);      dhcp_init(MSG_TIMEOUT);    }    /*-----------------------------------------------------------------*/    /* Otherwise, send a DHCPREQUEST message.                          */    /*-----------------------------------------------------------------*/    else    {      send_msg(dhcp.ni, 0, DHCPREQUEST);      i = (dhcp.retransDelay - K1_SECOND) + (rand() % K2_SECONDS);      NetTimerStart(&dhcp.msgTimer, i);      dhcp.retransDelay <<= 1;    }    break;  case DHCPACK:    /*-----------------------------------------------------------------*/    /* Transition to either DHCP_BOUND or DHCP_ARP state.              */    /*-----------------------------------------------------------------*/    if (dhcp.ni->flags & NIF_P2P)    {      /*---------------------------------------------------------------*/      /* Assign the supplied IP address and mask.                      */      /*---------------------------------------------------------------*/      dhcp.ni->ip_addr = dhcp.reqAddr;      dhcp.ni->ip_mask = dhcp.subnetMask;      dhcp_bound(TRANSITION);    }    else      dhcp_arp(TRANSITION);    break;  case DHCPNAK:    /*-----------------------------------------------------------------*/    /* Reset to DHCP_INIT and change to DHCP_SELECT 10 seconds later.  */    /*-----------------------------------------------------------------*/    dhcp_init(TRANSITION);    NetTimerStart(&dhcp.msgTimer, K10_SECONDS);    break;  }}/***********************************************************************//*    dhcp_arp: Final check whether address is in use                  *//*                                                                     *//***********************************************************************/static void dhcp_arp(int event){  switch (event)  {  case TRANSITION:    /*-----------------------------------------------------------------*/    /* Initialize state.                                               */    /*-----------------------------------------------------------------*/    dhcp.state = DHCP_ARP;    /*-----------------------------------------------------------------*/    /* Send ARP request and use timer to wait one second.              */    /*-----------------------------------------------------------------*/    DhcpArpReq(dhcp.ni, dhcp.reqAddr);    NetTimerStart(&dhcp.msgTimer, TICKS_PER_SEC);    break;  case MSG_TIMEOUT:    /*-----------------------------------------------------------------*/    /* Check whether any host claimed IP address.                      */    /*-----------------------------------------------------------------*/    if (DhcpArpCached(dhcp.reqAddr))    {      /*---------------------------------------------------------------*/      /* Address is already in use! Must decline it.                   */      /*---------------------------------------------------------------*/      send_msg(dhcp.ni, 0, DHCPDECLINE);      /*---------------------------------------------------------------*/      /* Reset to DHCP_INIT and change to DHCP_SELECT 10 secs later.   */      /*---------------------------------------------------------------*/      dhcp_init(TRANSITION);      NetTimerStart(&dhcp.msgTimer, K10_SECONDS);    }    else    {      /*---------------------------------------------------------------*/      /* Assign the supplied IP address and mask.                      */      /*---------------------------------------------------------------*/      dhcp.ni->ip_addr = dhcp.reqAddr;      dhcp.ni->ip_mask = dhcp.subnetMask;      /*---------------------------------------------------------------*/      /* Clear outdated ARP entries and change to DHCP_BOUND state.    */      /*---------------------------------------------------------------*/      DhcpArpReply(dhcp.ni);      dhcp_bound(TRANSITION);    }    break;  }}/***********************************************************************//*  dhcp_bound: Bind address, move to DHCP_RENEW at 50% expiration     *//*                                                                     *//***********************************************************************/static void dhcp_bound(int event){  uint temp;  switch (event)  {  case TRANSITION:    /*-----------------------------------------------------------------*/    /* Check if this is first transition to DHCP_BOUND.                */    /*-----------------------------------------------------------------*/    if (dhcp.state < DHCP_BOUND)    {      /*---------------------------------------------------------------*/      /* Add interface routes.                                         */      /*---------------------------------------------------------------*/      if (NiRtAdd(dhcp.ni))        goto bound_err;      /*---------------------------------------------------------------*/      /* If new gateway, add DHCP-supplied router as default gateway.  */      /*---------------------------------------------------------------*/      if (dhcp.router)        RtAdd(dhcp.router, 0, INADDR_ANY, dhcp.ni, RT_GATEWAY);    }    /*-----------------------------------------------------------------*/    /* Initialize state and stop message retransmission timer.         */    /*-----------------------------------------------------------------*/    dhcp.state = DHCP_BOUND;    NetTimerStop(&dhcp.msgTimer);

⌨️ 快捷键说明

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