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

📄 arp.c

📁 mcf5307实验源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
          *  if there is a gateway with a current ARP, use it.
          *  if not, arp all of the gateways and return an error.  Next call
          *  will
          *  probably catch the result of the ARP.
          */
         haveg = 0;
         for (i = CACHELEN-1; i >= 0; i--)
         {
              if (arpc[i].gate && arpc[i].valid_entry &&
                  INT32_CMP((arpc[i].tm + CACHETO), n_clicks()) > 0)
                   return(i);
         }

         if(INT32_CMP(n_clicks(), arptime) >= 0)
         {
             for (i = CACHELEN-1; i >= 0; i--)
             {
                 if (arpc[i].gate)
                 {
                     haveg = 1;
                     arp_request (arpc[i].ip); /* put out a broadcast request */
                 }
             }
             if (!haveg)            /* blind luck, try ARPing even for */
                 arp_request(ipn);  /* a node not on our net. (proxy ARP)*/
             arptime=n_clicks()+ARPTO;
         }  /* end if */
     }  /* end else gate */
     return (-1);
} /* end cachelook */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      netdlayer                                                        */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Get data layer address for insertion into outgoing packets.         */
/*   searches based on ip number.  If it finds the address, ok, else ... */
/*                                                                       */
/*   Checks to see if the address is on the same network.  If it is,     */
/*   then ARPs the machine to get address.  Forces pause between sending */
/*   arps to guarantee not saturating network.                           */
/*                                                                       */
/*   If not on the same network, it needs the ether address of a         */
/*   gateway.  Searches the list of machines for a gateway flag.         */
/*   Returns the first gateway found with an Ethernet address.           */
/*                                                                       */
/*   Returns NULL if not here, or pointer to ether address if here.      */
/*   If we don't have it, this also sends an ARP request so that the     */
/*   next time we are called, the ARP reply may be here by then.         */
/*                                                                       */
/* CALLED BY                                                             */
/*      netusend                    Send a packet                        */
/*      netxopen                    Open a network socket                */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*      n_clicks                                                         */
/*      netsleep                                                         */
/*      NU_Obtain_Semaphore         Grab an instance of a semaphore      */
/*      NU_Release_Semaphore        Release an instance of a semaphore   */
/*      NU_Relinquish               Allow other ready tasks to run       */
/*      getdlayer                   Check for the hardware address       */
/*                                                                       */
/*************************************************************************/
uint8 *netdlayer(uint8 *tipnum)
{
    int32 t;
    uint8 *pc;
      
    t=n_clicks()+CONNWAITTIME;         /* some seconds time out */
    pc=NU_NULL;
    do
    {

        pc =  getdlayer(tipnum);

        if (pc == NU_NULL)
        {
            #ifndef INTERRUPT
            netsleep(0);       /* can't have deadlock */
            #endif  /* !INTERRUPT */

            /*  Release the TCP_Resource so that other tasks can run while
             *  we are waiting for the ARP message to be received and
             *  processed. */
            #ifdef PLUS
            NU_Release_Semaphore(&TCP_Resource);
            #else   /* !PLUS */
            NU_Release_Resource(TCP_Resource);
            #endif  /* !PLUS */

            /*  Relinquish control to allow other tasks to run.  */
            NU_Sleep(1);

            /*  Get the resource back so that we can continue.  */
            #ifdef PLUS
            NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
            #else   /* !PLUS */
            NU_Request_Resource(TCP_Resource, NU_WAIT_FOREVER);
            #endif  /* !PLUS */
        }


        if(INT32_CMP(t, n_clicks()) <= 0)
            return(NU_NULL);
          
          
    } while(pc==NU_NULL);

    return(pc);
}  /* end netdlayer */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      getdlayer                                                        */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   check for the hardware address one time                             */
/*                                                                       */
/* CALLED BY                                                             */
/*      NU_EventsDispatcher                                              */
/*      netsleep                                                         */
/*      netdlayer                                                        */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*      n_clicks                                                         */
/*      netsleep                                                         */
/*      NU_Relinquish               Allow other ready tasks to run       */
/*                                                                       */
/*************************************************************************/
uint8 *getdlayer(uint8 *tipnum)
{
      int16 needgate,i;
      
      needgate=0;
      /*
      *  Check to see if we need to go through a gateway.
      *  If the machine is on our network, then assume that we can send an ARP
      *  to that machine, otherwise, send the ARP to the gateway.
      *
      *  Uses internet standard subnet mask method, RFC950
      *  if subnets are not in use, netmask has been pre-set to the 
      *  appropriate
      *  network addressing mask.
      */
      for(i=3; i>=0; i--)
           if((nnmask[i] & tipnum[i])!=(nnmask[i] & nnipnum[i]))
                needgate=1;
      if(needgate && (0<=(i=cachelook(tipnum,1,1)))) 
           return(arpc[i].hrd);
      if(!needgate && (0<=(i=cachelook(tipnum,0,1))))
           return(arpc[i].hrd);
      return(NU_NULL);
} /* end getdlayer */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      netsetgate                                                       */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Establish an IP number to use as a gateway.                         */
/*   They are added in the order that they arrive and there is a limit on*/
/*   the number of gateways equal to CACHELEN/2.                         */
/*   ARPs them as they are added so that the Cache will get pre-filled   */
/*   with gateways.                                                      */
/*                                                                       */
/*   returns 0 if ok, -1 on error(full)                                  */
/*                                                                       */
/* CALLED BY                                                             */
/*      Ssetgates                   Set up gateway mahines and subnet    */
/*                                  mask                                 */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*      arp_request                      Send out an arp request packet  */
/*                                                                       */
/*************************************************************************/
int16 netsetgate(uint8 *ipn)
{
      int16 i;
      
      for(i=CACHELEN-1 ; i>=CACHELEN/2 ; i--) {
          if(!arpc[i].gate) {
              arpc[i].gate=1;

              /* The hardware address has yet to be resolved. So this is not yet
                 a valid entry.
              */
              arpc[i].valid_entry = 0;
              memcpy ((void *)arpc[i].ip, (const void *)ipn, 4);
              arp_request(ipn);
              return(NU_SUCCESS);
          }
      } /* end for */
      return(-1);
} /* end netsetgate */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      ARP_Init                                                         */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*  Setup an arp packet -- also sets up an arp cache                     */
/*                                                                       */
/* CALLED BY                                                             */
/*      protinit                                                         */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*      intswap                                                          */
/*                                                                       */
/*************************************************************************/
VOID ARP_Init (VOID)
{
    int16 i;

    memcpy ((void *)&arp.d, (const void *)&blankd, sizeof(DLAYER));
    arp.d.type = intswap (EARP);           /* 0x0806 is ARP type */
    arp.hrd = intswap (HARDWARE_TYPE);     /*  Ether = 1 */
    arp.pro = intswap (ARPPRO);            /* IP protocol = 0x0800 */
    arp.hln = DADDLEN;                     /* Ethernet hardware length */
    arp.pln = 4;                           /* IP length = 4 */
    /* sender's hardware addr */
    memcpy ((void *)arp.sha, (const void *)nnmyaddr, DADDLEN);
    /* target hardware addr */
    memcpy ((void *)arp.tha, (const void *)broadaddr, DADDLEN);
    /* sender's IP addr */
    memcpy ((void *)arp.spa, (const void *)nnipnum, 4);

    /* Clear all entries as being invalid.    */
    for (i = 0; i < CACHELEN; i++)
        arpc[i].valid_entry = 0;

    arptime = 0L;

    /* The resolve list is initially empty. */
    ARP_Res_List.ar_head = NU_NULL;
    ARP_Res_List.ar_tail = NU_NULL;

⌨️ 快捷键说明

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