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

📄 arp.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (buf_ptr->mem_flags & NET_BCAST)
    {
        memcpy(mac_dest, NET_Ether_Broadaddr, DADDLEN);
        return (NU_SUCCESS);
    }

    PUT32(temp, 0, ip_dest->sck_addr);

    if (buf_ptr->mem_flags & NET_MCAST)
    {
        NET_MAP_IP_TO_ETHER_MULTI(temp, mac_dest);
        return (NU_SUCCESS);
    }

    /* Check the ARP cache for the destination.  If found, return. */
    if ( (a_entry = ARP_Find_Entry(ip_dest)) != NU_NULL)
    {
        memcpy(mac_dest, a_entry->arp_mac_addr, DADDLEN);
        return (NU_SUCCESS);
    }

    if ((stat = NU_Allocate_Memory(&System_Memory, (VOID **)&ar_entry,
                        sizeof(*ar_entry),
                        (UNSIGNED)NU_NO_SUSPEND)) != NU_SUCCESS)
    {
        return (stat);
    }

    ar_entry->ar_id         = ARP_Res_Count++;
    ar_entry->ar_device     = int_face;
    ar_entry->ar_dest       = ip_dest->sck_addr;
    ar_entry->ar_send_count = 0;
    ar_entry->ar_task       = 0;              /* ar_task used only for RARP. */
    ar_entry->ar_buf_ptr    = buf_ptr;
    ar_entry->ar_pkt_type   = ARPREQ;
  
    /* If there is already an ARP entry for this host then we do not want to
       set an event, ie. don't send an ARP if we have already done so. */
    for (current_ar_entry = ARP_Res_List.ar_head;
             current_ar_entry != NU_NULL;
             current_ar_entry = current_ar_entry->ar_next)
    {
        if (TLS_Comparen(&ar_entry->ar_dest, &current_ar_entry->ar_dest, 4))
            break;
    }

    /* Order is not important.  Simply add the new entry to the front of the
       list. */
    DLL_Enqueue((tqe_t *)&ARP_Res_List, (tqe_t *)ar_entry);

    /* Set the event if one was not found. */
    if (!current_ar_entry)
    {
        TLS_Put_Event (ARPRESOLVE, (UNSIGNED)ar_entry->ar_id);
    }

    return(NU_UNRESOLVED_ADDR);
}  /* end ARP_Resolve */

/*************************************************************************
*
*   FUNCTION                                                              
*                                                                         
*       ARP_Find_Entry                                                    
*                                                                         
*   DESCRIPTION                                                           
*                                                                         
*       This function searches the ARP cache for a matching entry.        
*                                                                         
*   INPUTS                                                                
*                                                                         
*       *dest           IP address for which an ethernet 
*                       address is desired.                               
*                                                                         
*   OUTPUTS                                                               
*                                                                         
*       *ARP_ENTRY      A pointer to an entry in the ARP cache. NULL  
*                       on failure.                                  
*
*************************************************************************/
ARP_ENTRY *ARP_Find_Entry(SCK_SOCKADDR_IP *dest)
{
    INT         i;
    ARP_ENTRY   *a_entry = NU_NULL;

    /* Search the cache for the target IP number. */
    for (i = 0; i < ARP_CACHE_LENGTH; i++)
    {
        if ( dest->sck_addr == ARP_Cache[i].arp_ip_addr)
        {
            /* We found the entry. */
            a_entry = &ARP_Cache[i];
            break;
        }
    }

    /* If an entry was found, it has not timed out or is permanent,
       and the entry is valid, the return a pointer to this entry.  Else return NULL
     */
    if ( a_entry && ((INT32_CMP((a_entry->arp_time + CACHETO), 
                      NU_Retrieve_Clock()) > 0)
                    || (a_entry->arp_flags & ARP_PERMANENT))
                    && (a_entry->arp_flags & ARP_UP) )
        return (a_entry);
    else
        return NU_NULL;

} /* ARP_Find_Entry */

/*************************************************************************
*
*   FUNCTION                                                              
*                                                                         
*       ARP_Request                                                       
*                                                                         
*   DESCRIPTION                                                           
*                                                                         
*       Send an ARP request.                                              
*                                                                         
*   INPUTS                                                                
*                                                                         
*       *device             Pointer to the device.                        
*       *tip                The target IP number                          
*       *thardware          The target hardware address.                  
*       protocol_type       Either EARP or ERARP.                        
*       arp_type            Either ARPREQ or RARPQ.              
*                                                                         
*   OUTPUTS                                                               
*                                                                         
*       NU_SUCCESS          If success.                                   
*       -1                  If error.                                     
*                                                                         
*************************************************************************/
STATUS ARP_Request(DV_DEVICE_ENTRY *device, UINT32 *tip, UINT8 *thardware,
                   UINT16 protocol_type, INT16 arp_type)
{
    NET_BUFFER      *buf_ptr;
    ARP_MAC_HEADER  mh;
    STATUS          stat;


    /* Build the ARP request packet.  The target hardware address is unknown at
       this point, so pass in a string of NULL characters as the target hardware
       address.
     */
    if ((buf_ptr = ARP_Build_Pkt(device, *tip, thardware, arp_type)) == NU_NULL)
    {
        return -1;
    }

    UTL_Zero(&mh, sizeof(mh));

    /* This is a psuedo MAC hedaer that is passed to the MAC layer send function. 
       The MAC layer information that is know is filled in. A family of 
       SK_FAM_UNSPEC lets the MAC layer know that this is not an IP datagram and 
       it should not try to resolve a hardware address. */
    memcpy (mh.ar_mac.ar_mac_ether.dest, NET_Ether_Broadaddr, DADDLEN);
    mh.ar_mac.ar_mac_ether.type = protocol_type;
    mh.ar_family = SK_FAM_UNSPEC;
    mh.ar_len = sizeof(mh);    

    /* Send the ARP Packet. */
    stat = (*device->dev_output)(buf_ptr, device, (SCK_SOCKADDR_IP *)&mh, NU_NULL);

    /* if the packet is not sent then free up the buffer space */
    if (stat != NU_SUCCESS)
        MEM_Buffer_Enqueue(&MEM_Buffer_Freelist, (NET_BUFFER *)buf_ptr);

    return (NU_SUCCESS);

} /* ARP_Request */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       ARP_Cache_Update                                                 
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Add an entry to the ARP cache.                                   
*                                                                       
*   INPUTS                                                                
*                                                                       
*       ipn                                                               
*       *hrdn                                                             
*       flags
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       INT             Index of entry made in ARP cache.        
*       -1              Entry was not found.                     
*                                                                       
*************************************************************************/
INT ARP_Cache_Update(UINT32 ipn, UINT8 *hrdn, INT flags)
{
    INT16 i, found = -1;
    INT32 timer;

    /*
     * linear search to see if we already have this entry
     */
    for (i=0; i < ARP_CACHE_LENGTH; i++)
        if (ipn == ARP_Cache[i].arp_ip_addr)
        {
            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 = ARP_Cache[0].arp_time;
        found = 0;
        for (i=1; i < ARP_CACHE_LENGTH; i++)
        {
            /* If this entry has timed-out and is not permanent then 
               reuse it. */
            if ( (INT32_CMP(ARP_Cache[i].arp_time, timer) < 0) &&
                ( (ARP_Cache[i].arp_flags & ARP_PERMANENT) == 0) )
            {  /* exclude gateways */
                found = i;
                timer = ARP_Cache[i].arp_time;
            }  /* end if ARP_Cache check */
        }  /* end for ARP_CACHE_LENGTH*/
    }  /* end if found < 0 */

    /*
     *   do the update to the cache
     */
    memcpy (ARP_Cache[found].arp_mac_addr, hrdn, DADDLEN);
    ARP_Cache[found].arp_ip_addr = ipn;
    ARP_Cache[found].arp_time = NU_Retrieve_Clock();
    ARP_Cache[found].arp_flags = (ARP_UP | flags);

    return (found);
} /* ARP_Cache_Update */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       ARP_Event                                                        
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Process an ARP timer event.                                      
*                                                                       
*   INPUTS                                                                
*                                                                       
*       id                                                                
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       None.                                                             
*                                                                       
*************************************************************************/
VOID ARP_Event(UINT16 id)
{
    ARP_RESOLVE_ENTRY               *ar_entry;
    UINT32                          arp_host_ip;

    for(ar_entry = ARP_Res_List.ar_head;
        ar_entry != NU_NULL;
        ar_entry = ar_entry->ar_next)
    {
        if (ar_entry->ar_id == id)
            break;
    }

⌨️ 快捷键说明

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