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

📄 dhcpclnt.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 3 页
字号:
   int   i;
#endif   /* DHC_MAXDNSRVS */

   /* first, clear the options */
   dhc_states[iface].snmask = 0; 
   dhc_states[iface].defgw = 0; 
   dhc_states[iface].lease = 0; 
#if defined(DHC_MAXDNSRVS) && (DHC_MAXDNSRVS > 0)
   MEMSET(dhc_states[iface].dnsrv, 0, sizeof(dhc_states[iface].dnsrv));
#endif   /* DHC_MAXDNSRVS */

   /* then fill them in from the DHCP data */
   while (opts <= end)
   {
      switch (*opts++)
      {
      case DHOP_PAD:
         break;
      case DHOP_END:
         return 0;   /* only good exit point */
      case DHOP_SNMASK:
         opts++;
         dhc_states[iface].snmask = dh_getlong(opts);
         opts += 4;
         break;
      case DHOP_ROUTER:
         optlen = *opts++;
         if (optlen >= 4)
            dhc_states[iface].defgw = dh_getlong(opts);
         opts += optlen;
         break;
      case DHOP_LEASE:
         opts++;
         dhc_states[iface].lease = htonl(dh_getlong(opts));
         opts += 4;
         break;
      case DHOP_DNSRV:
         optlen = *opts++;
#if defined(DHC_MAXDNSRVS) && (DHC_MAXDNSRVS > 0)
         i = 0;
         while ((optlen >= 4) && (i < DHC_MAXDNSRVS))
         {
            dhc_states[iface].dnsrv[i] = dh_getlong(opts);
            optlen -= 4;
            opts += 4;
            i++;
         }
#endif   /* DHC_MAXDNSRVS */
         opts += optlen;
         break;
      default:
         opts += ((*opts) + 1);
         break;
      }
   }
   dtrap("dhcpclnt 11\n");
   return -1;
}

/* dhc_stats() - print dhcp client statistics. Returns 0 if ok, else 
 * non-zero error. 
 */
#ifdef NET_STATS


/* FUNCTION: dhc_stats()
 * 
 * PARAM1: void *pio
 *
 * RETURNS: 
 */

int
dhc_stats(void *pio)
{
   int   i;
   ns_printf(pio ,"dhcp client stats:\n");
   ns_printf(pio ,"all errors:      %lu\n", dsc_errors);
   ns_printf(pio ,"discover sent:   %lu\n", dsc_discovers);
   ns_printf(pio ,"offers rcvd:     %lu\n", dsc_offers);
   ns_printf(pio ,"requests sent:   %lu\n", dsc_requests);
   ns_printf(pio ,"acks received:   %lu\n", dsc_acks);
   ns_printf(pio ,"bootp replys:    %lu\n", dsc_bpreplys);
   ns_printf(pio ,"declines sent:   %lu\n", dsc_declines);
   ns_printf(pio ,"releases sent:   %lu\n", dsc_releases);
   ns_printf(pio ,"naks received:   %lu\n", dsc_naks);
   ns_printf(pio ,"renew req sent:  %lu\n", dsc_renew);
   ns_printf(pio ,"rebind req sent: %lu\n", dsc_rebind);
   ns_printf(pio ,"relay agent errs:%lu\n", dsc_rlyerrs);

   for ( i=0 ; i < MAXNETS ; i++ )
   {
      ns_printf(pio ,"Interface %d state = %s\n",i+1,
       dhc_state_str[ dhc_states[i].state ] );
      if ( dhc_states[i].state == DHCS_UNUSED )
         continue;
      else
      {
         ns_printf(pio ,"   tries=%d, xid=%lu, secs=%d\n", 
          dhc_states[i].tries,dhc_states[i].xid,dhc_states[i].secs);
         ns_printf(pio ,"   lease=%lu, t1=%lu, t2=%lu\n", 
          dhc_states[i].lease,dhc_states[i].t1,dhc_states[i].t2);
         ns_printf(pio ,
          "   ip=%u.%u.%u.%u, snmask=%u.%u.%u.%u, gw=%u.%u.%u.%u\n", 
          PUSH_IPADDR(dhc_states[i].ipaddr),
          PUSH_IPADDR(dhc_states[i].snmask),
          PUSH_IPADDR(dhc_states[i].defgw)  );
         ns_printf(pio , "   serverip=%u.%u.%u.%u\n", 
          PUSH_IPADDR(dhc_states[i].srv_ipaddr) );
#if defined(DHC_MAXDNSRVS) && (DHC_MAXDNSRVS > 0)
         {
            int   dnsindex;
            for (dnsindex=0; dnsindex < DHC_MAXDNSRVS ; dnsindex++ )
            {
               ns_printf(pio , "   DNS%d=%u.%u.%u.%u\n", dnsindex+1,
                  PUSH_IPADDR(dhc_states[i].dnsrv[dnsindex]) );
            }
         }
#endif
      }
   }
   return 0;
}
#endif   /* NET_STATS */


/* FUNCTION: dhc_second()
 *
 * dhc_second() - dhcp client timer. system should call this once a 
 * second for retries, lease renewal, etc. 
 *
 * 
 * PARAM1: void
 *
 * RETURNS: Returns 0 or ENP_ error code 
 */

int
dhc_second(void)
{
   int   iface;
   int   tries;
   int   e;
   u_long   half_time;

   for (iface = 0; iface < MAXNETS; iface++)
   {
      switch (dhc_states[iface].state)
      {
      case DHCS_INIT:         /* Send a discover packet */
         e = dhc_discover(iface);
         /* Error while sending a discover packet */
         if (e)
         {
            dtrap("dhcpclnt 12\n");
            return e;
         }
         dhc_set_state(iface,DHCS_SELECTING);
         break;
      case DHCS_INITREBOOT:   /* Send a request packet */
         e = dhc_reclaim(iface);
         if (e)
         {
            dtrap("dhcpclnt 13\n");
            return e;
         }
         dhc_set_state(iface,DHCS_REBOOTING);
         break;
      case DHCS_SELECTING:
         /* Send discover packet on timeout */
      case DHCS_REBOOTING:
      case DHCS_REQUESTING:
         /* Discovery timeout = DHC_RETRY_TMO secs * (2 ** retries), max 64 */

         tries = dhc_states[iface].tries ;

         /* Set the exponential count */
         if ( tries >= DHC_MAX_TRIES) 
            tries= DHC_MAX_TRIES;
         if ( cticks > (dhc_states[iface].last_tick + 
             (((u_long) (DHC_RETRY_TMO*TPS)) << tries ) ) )
         {
            /* Timeout while waiting for a OFFER/ACK/NAK. Retransmit */
            switch(dhc_states[iface].state)
            {
            case DHCS_SELECTING:
               dhc_discover(iface);
               break;
            case DHCS_REQUESTING:
               dhc_request(iface,FALSE);
               break;
            case DHCS_REBOOTING:
               dhc_reclaim(iface);
               break;
            default:
               dtrap("dhcpclnt 14\n"); /* bogus state */
               break;
            }
         }
         if ( tries == DHC_MAX_TRIES && 
             (dhc_states[iface].state !=DHCS_SELECTING) )
         {
            /* We have tried enough. Restart from INIT state */
            dhc_set_state(iface,DHCS_RESTARTING);
            dhc_resetip(iface);
            dhc_set_state(iface,DHCS_INIT);
         }
         break;
      case DHCS_REBINDING:
         /* Check for timeout. Retry if we didn't get a ACK/NAK response. */

         if ( (dhc_states[iface].lease*TPS+dhc_states[iface].lease_start) > cticks )
         {
            /* See if we need to retransmit. If we have waiting for 
             * half the time between last transmit and lease, then we 
             * need to retransmit. Also the minimum retransmit 
             * interval is 60 secs. 
             */
            half_time = (dhc_states[iface].lease_start + 
             dhc_states[iface].lease*TPS - 
             dhc_states[iface].last_tick)/2;

            if ( half_time < 60*TPS )
               half_time = 60*TPS;
            if ( dhc_states[iface].last_tick + half_time < cticks )
            {
               dhc_request(iface,FALSE);
            }
         }
         else
         {
            /* Lease has expired. We didn't receive a ACK/NAK. Hence restart*/
            dhc_set_state(iface,DHCS_RESTARTING);
            dhc_resetip(iface);
            dhc_set_state(iface,DHCS_INIT);
         }
         break;

      case DHCS_BOUND:
         /* Test for lease expiry. The RENEW timer. */
         if ( (dhc_states[iface].t1 != DHC_INFINITY) &&
             (((dhc_states[iface].t1*TPS)+dhc_states[iface].lease_start) < cticks ) )
         {
            /* Time to renew. Send a UNICAST to the DHCP server */
            dhc_set_state(iface,DHCS_RENEWING);
            e = dhc_reclaim(iface); /* unicast */ 
            if (e)
            {
               dtrap("dhcpclnt 15\n");
               return e;
            }
            dsc_renew++;
         }
         break;
      case DHCS_RENEWING:
         /* Test for lease expiry. The REBIND timer. */
         if ( (dhc_states[iface].t2*TPS+dhc_states[iface].lease_start) > cticks )
         {
            /* See if we need to retransmit. If we have waiting for 
             * half the time between last transmit and t2, then we 
             * need to retransmit. Also the minimum retransmit 
             * interval is 60 secs. 
             */
            half_time = (dhc_states[iface].lease_start +
             dhc_states[iface].t2*TPS - 
             dhc_states[iface].last_tick)/2;

            if ( half_time < 60*TPS )
               half_time = 60*TPS;
            if ( dhc_states[iface].last_tick + half_time < cticks )
            {
               dhc_request(iface,FALSE);
            }
         }
         else
         {
            /* No Response has come from the Server that assigned our 
             * IP. Hence send a broadcast packet to see if we can 
             * lease this IP from some other server 
             */
            dhc_set_state(iface,DHCS_REBINDING);
            e = dhc_request(iface,TRUE);  /* broadcast */
            if (e)
            {
               dtrap("dhcpclnt 16\n");
               return e;
            }
            dsc_rebind++;
         }
         break;
      case DHCS_UNUSED:
      default:
         continue;
      }
   }
   return 0;
}


/* FUNCTION: dhc_halt()
 *
 * dhc_halt() - stop dhcp all client activity for the passed iface.
 *
 * 
 * PARAM1: int iface
 *
 * RETURNS: void
 */

void
dhc_halt(int iface)
{
   if (iface < 0 || iface > MAXNETS)
   {
      dtrap("dhcpclnt 17\n");
      return;
   }
   /* clear dhc_states entry - (kills retrys) */
   MEMSET(&dhc_states[iface], 0, sizeof(struct dhc_state));
   dhc_states[iface].state = DHCS_UNUSED;
}


/* FUNCTION: dhc_reclaim()
 *
 * dhc_reclaim() - send a "request" for the address currently in the 
 * passed interface. This is an alternative to dhc_discover() for 
 * machines which have previously been assigned an address via DHCP, 
 * saved it in flash, been through a power cycle, and now want to try 
 * to reclaim previous address from the server. This works by setting 
 * parameters of dhc_states[] and calling dhc_request() 
 *
 * 
 * PARAM1: int iface
 *
 * RETURNS: Returns 0 if DHCP request was sent OK, else non-zero error. 
 */

int   
dhc_reclaim(int iface)
{
   /* punt if IP address is not set */
   if (nets[iface]->n_ipaddr == 0L)
   {
      dtrap("dhcpclnt 18\n");    /* programming bug? */
      return ENP_LOGIC;
   }

   dhc_states[iface].ipaddr = nets[iface]->n_ipaddr;
   dhc_states[iface].snmask = nets[iface]->snmask;
   dhc_states[iface].defgw  = nets[iface]->n_defgw;

#ifdef IP_ROUTING
   /* If the DHCP Server is on other network, route the request
    * from the same DHCP relay agent. To do that, add a route.
    */
   if (dhc_states[iface].rly_ipaddr)
   {
      if (dhc_states[iface].srv_ipaddr)
      {
         /* yes, earlier negotiation was done via a relay agent */
         if ( !add_route(dhc_states[iface].srv_ipaddr, 0xFFFFFFFF,
             dhc_states[iface].rly_ipaddr, iface, IPRP_LOCAL))
         {
            /* route was not added. check this case */
            dtrap("dhcpclnt 19\n"); 
         }
      }
      else
      {
         /* DHCP relay IP address is set, but DHCP Server IP address is
          * not set ! How can this happen ?
          */
         dtrap("dhcpclnt 20\n");
      }
   }
#else
   /* IP_ROUTING is disabled. Hence we can't add route. */
#endif

   /* send the request */
   return(dhc_request(iface,TRUE));  
}


/* FUNCTION: dhc_state_init()
 * 
 * dhc_state_init() : Initiate the DHCP Client for a interface into a 
 * starting state. Either INIT or INITREBOOT. If the DHCP Client is 
 * in INIT state, it would start by sending a DISCOVER packet. If it 
 * is in INITREBOOT state, it would try to use the earlier IP address 
 * by sending a REQUEST packet. Returns nothing. 
 *
 * PARAM1: int iface
 * PARAM2: int init_flag
 *
 * RETURNS: void
 */

void 
dhc_state_init(int iface,int init_flag)
{
   if ( init_flag == TRUE )
      dhc_set_state(iface,DHCS_INIT);
   else
      dhc_set_state(iface,DHCS_INITREBOOT);
}


/* FUNCTION: dhc_alldone()
 * 
 * dhc_alldone() : Check if DHCP activities on all interfaces is done 
 * or not. 
 *
 * PARAM1: void
 *
 * RETURNS: Return TRUE if all valid interfaces are done. Return FALSE 
 * otherwise. 
 */

int 
dhc_alldone(void)
{
   int   i;
   for ( i=0 ; i < MAXNETS ; i++ )
   {
      if ( ( dhc_states[i].state == DHCS_UNUSED ) || 
          ( dhc_states[i].state == DHCS_BOUND  )  )
      {
         continue ;
      }
      else
      {
         return FALSE ;
      }
   }
   return TRUE ;
}


/* FUNCTION: dhc_ifacedone()
 *
 * dhc_ifacedone() : Check if DHCP activities on a interface is done 
 * or not. Return TRUE if done (or if DHCP Client is not used on the 
 * interface). Return FALSE otherwise. 
 *
 * 
 * PARAM1: int iface
 *
 * RETURNS: 
 */

int 
dhc_ifacedone(int iface)
{
   if ( ( dhc_states[iface].state == DHCS_UNUSED ) || 
       ( dhc_states[iface].state == DHCS_BOUND  )  )
   {
      return TRUE ;
   }
   else
   {
      return FALSE ;
   }
}


/* FUNCTION: dhc_set_state()
 *
 * dhc_set_state() : Set the new state for the interface and call the 
 * callback routine. That way applications can track about the state 
 * of DHCP Client 
 *
 * 
 * PARAM1: int iface
 * PARAM2: int state
 *
 * RETURNS: 
 */

void dhc_set_state(int iface, int state)
{
   dhc_states[iface].state = state; /* Set the new state */
   dhc_states[iface].tries = 0;     /* Reset the number of tries */

   /* If callback is set, call it */
   if (dhc_states[iface].callback)
      dhc_states[iface].callback(iface,state);
}

#endif   /* DHCP_CLIENT - ifdef out whole file */


⌨️ 快捷键说明

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