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

📄 arp.c

📁 mcf5307实验源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
}  /* end arp_reply */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      arp_request                                                      */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Put out an ARP request packet, doesn't wait for response            */
/*                                                                       */
/* CALLED BY                                                             */
/*      netarpme            Send an ARP to myself                        */
/*      cachelook           looks up information in the cache            */
/*      netsetgate          Assign an IP number to use as a gateway      */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*      arp_prepare_pkt                                                  */
/*      NET_Send                                                         */
/*                                                                       */
/*************************************************************************/
int16 arp_request(uint8 *tipnum)
{
    struct pqueue HUGE *buf_ptr;


    buf_ptr = arp_prepare_pkt(tipnum, broadaddr, ARPREQ);

    if(buf_ptr == NU_NULL)
        return (-1);

    NET_Send(buf_ptr, sizeof(ARPKT), OTHER_PKT);

    return(NU_SUCCESS);
} /* end arp_request */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      arpinterpret                                                     */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   interpret ARP packets                                               */
/*   Look at incoming ARP packet and make required assessment of         */
/*   usefulness, check to see if we requested this packet, clear         */
/*   all appropriate flags.                                              */
/*                                                                       */
/*  CALLED BY                                                            */
/*      demux                       Demux incoming packets               */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*      intswap                     Byte swap an integer                 */
/*      arp_reply                   Address resolution                   */
/*      cacheupdate                 Update the ARP cache                 */
/*                                                                       */
/*************************************************************************/
int16 arpinterpret(ARPKT *p)
{
    ARP_RESOLVE_ENTRY       *ar_entry;

    /*
    *  check packet's desired IP address translation to see if it wants
    *  me to answer.
    */
    if ( (p->op == intswap (ARPREQ)) &&
         (comparen (p->tpa, nnipnum, 4)))
    {
        cacheupdate (p->spa, p->sha);   /* keep her address for me */
        arp_reply(p->sha, p->spa);      /* proper reply */
        return (NU_SUCCESS);
    }
    /*
     *  Check for a RARP reply.  If present, call netsetip()
    */
    else if (p->op == intswap (RARPR)
             && (comparen (p->tha, nnmyaddr, DADDLEN)))
    {
        /* Search the ARP_Res_List for a match. */
        for(ar_entry = ARP_Res_List.ar_head;
            ar_entry != NU_NULL;
            ar_entry = ar_entry->ar_next)
        {
            /* A match is found when we find an entry for a RARP request. */
            if (ar_entry->ar_pkt_type == RARPQ)
                break;
        }

        /* Was a match found. */
        if (ar_entry)
        {
            /* Get the IP address. */
            netsetip(p->tpa);

            /* Clear the timer event. */
            Stimerunset(CONCLASS, RARP_REQUEST, ar_entry->ar_id, 1);

            /* Resume the task. */
            NU_Resume_Task(ar_entry->ar_task);
        }

        return (NU_SUCCESS);
    }
    /*
     *  Check for a reply that I probably asked for.
     */
    if (comparen (p->tpa, nnipnum, 4)
        && (p->op == intswap (ARPREP))
        && (p->hrd == intswap (HARDWARE_TYPE))
        && (p->hln == DADDLEN) && (p->pln == 4))
    {
        cacheupdate (p->spa, p->sha);
        return (NU_SUCCESS);
    }

    return (1);
} /* end arpinterpret */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      cacheupdate                                                      */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*  We just received an ARP, or reply to ARP and need to add the         */
/*  information to the cache.                                            */
/*  Reset arptime so that another machine may be ARPed.  This timer keeps*/
/*  ARPs from going out more than one a second unless we receive a reply.*/
/*                                                                       */
/* CALLED BY                                                             */
/*     arp_request                      Send out an arp request packet   */
/*     arpinterpret                     Interpret ARP Packets            */
/*                                                                       */
/* CALLS                                                                 */
/*     n_clicks                                                          */
/*                                                                       */
/* HISTORY                                                               */
/*         NAME            DATE                    REMARKS               */
/*                                                                       */
/*     MQ. Qian          12/05/95        Fixed a bug that prevented the  */
/*                                       correct entry in the arp cache  */
/*                                       from always being found.        */
/*                                                                       */
/*************************************************************************/
int16 cacheupdate(uint8 *ipn,uint8 *hrdn)
{
    int16 i, found=-1;
    int32 timer;

    /*
     * linear search to see if we already have this entry
     */
    for (i=0; i<CACHELEN; i++)
        if (comparen (ipn, arpc[i].ip, 4))
        {
            found = i;
            break;
        }
    /*
     *  if that IP number is not already here, take the oldest
     *  entry.
     *  If it is already here, update the info and reset the timer.
     *  These were pre-initialized to 0, so if any are blank, they
     *  will be
     *  taken first because they are faked to be oldest.
     */
    if (found<0)
    {
        timer = arpc[0].tm;
        found = 0;
        for (i=1; i<CACHELEN; i++)
        {
            if ((INT32_CMP(arpc[i].tm, timer) < 0) && (!arpc[i].gate))
            {  /* exclude gateways */
                found = i;
                timer = arpc[i].tm;
            }  /* end if arpc check */
        }  /* end for CACHELEN */
    }  /* end if found < 0 */

    /*
     *   do the update to the cache
     */
    memcpy ((void *)arpc[found].hrd, (const void *)hrdn, DADDLEN);
    memcpy ((void *)arpc[found].ip, (const void *)ipn, 4);
    arpc[found].tm = n_clicks();
    arpc[found].valid_entry = 1;
    arptime = 0L;                   /* reset, allow more arps */
    return (found);
} /* end cacheupdate */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      cachelook                                                        */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Look up information in the cache                                    */
/*   returns the cache entry number for the IP number given.             */
/*   Returns -1 on no valid entry, also if the entry present is too old. */
/*   doarp is a flag for non-gateway requests which determines whether an*/
/*   arp will be sent or not.                                            */
/*                                                                       */
/* CALLED BY                                                             */
/*     getdlayer                                                         */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*      n_clicks                                                         */
/*      arp_request                      Send out an arp request packet  */
/*                                                                       */
/*************************************************************************/
int16 cachelook(uint8 *ipn, int16 gate, int16 doarp)
{
     int16 i,haveg;

     /*
     *  First option, we are not looking for a gateway, but a host on our
     *  local network.
     */
     if (!gate)
     {
         for (i = 0; i < CACHELEN; i++)
         {
             if ((comparen (ipn, arpc[i].ip, 4))
                && (INT32_CMP((arpc[i].tm + CACHETO), n_clicks()) > 0)
                && arpc[i].valid_entry)
             {
                 return (i);
             }
         }  /* end for CACHELEN */

         /*
          *  no valid entry, send an ARP
          */
         if ((INT32_CMP(n_clicks(), arptime) >=  0) && doarp)
         {  /* check time limit */
             arp_request (ipn);              /* put out a broadcast request */
             arptime = n_clicks () + ARPTO;
         }
     }  /* if !gate */
     else
     {
         /*
          *  Second option, we need a gateway.

⌨️ 快捷键说明

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