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

📄 net_arp.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    next_poll_time = time_now + ARP_POLL_TIMEOUT ;

    /* search the SAP table to detect any expired entries */
    for ( i = 0; i < ARP_SAP_COUNT; i++ )
    {
        if (sap_context[i].state  != ARP_SAP_STATE_CLOSED)
        {
            /* DISABLE INTERRUPT */
            old_ie = sys_disable_int() ;

            if (time_now >= sap_context[i].timeout)
            {
                sap_context[i].state   = ARP_SAP_STATE_CLOSED ;
                sap_context[i].ip_addr = IP_ADDR_UNDEFINED ;
                sap_context[i].timeout = 0 ;
                memcpy( sap_context[i].mac_addr, 
                        mac_undefined_adr,
                        SYS_MAC_ADDR_SIZE ) ;
            }

            /* Restore interrupt enable status */
            if(old_ie)
                sys_enable_int();
        }
    }

    return( rcode ) ;
}


/************************************************************************
 *      Implementation : Static functions
 ************************************************************************/


/************************************************************************
 *
 *                          NET_ARP_receive
 *  Description :
 *  -------------
 *  In "RX-frame receive int. mode", this function is called from 
 *  the LAN-driver ISR, whenever it receives an Ethernet frame. 
 *
 *  In "RX-frame receive polled mode", this function will still
 *  be called from the LAN-driver, but in this case, the call
 *  gets started when NET_ARP_poll() calls the LAN-driver 'read'
 *  entry.
 *
 *  It must check for any SAP's registered to handle the addressed
 *  SAP and if one found, the registered receive handler is called.
 *
 *
 *
 *  Parameters :
 *  ------------
 *  'src_adr': senders MAC-address
 *  'length':  length of received ethernet frame
 *  'data':    pointer for received ethernet frame (in driver's space)
 *
 *
 *  Return values :
 *  ---------------
 *  'OK' 
 *
 ************************************************************************/
static 
UINT32 NET_ARP_receive( t_mac_addr *src_adr,
                        UINT32     length,
                        UINT8      *data    )
{
    UINT32  rcode = OK ;
    UINT8   *p ;
    UINT16  op_code ;
    UINT32  src_ip_addr ;
    UINT32  dst_ip_addr ;
    UINT32  ip_station_adr ;
    int     i ;

    /* get 'ARP-op_code' and keep it in 'CPU'-format */
    p = (data + ARP_HEADER_BASE + ARP_HEADER_OPERATION_CODE) ;
    get2( p, op_code ) ;
    op_code = BE16_TO_CPU( op_code ) ;

    /* get 'ARP-sender-ip' and keep it in 'BE'-format */
    p = (data + ARP_HEADER_BASE + ARP_HEADER_SOURCE_PROTOCOL_ADDRESS) ;
    get4( p, src_ip_addr ) ;

    /* get 'ARP-destination-ip' and keep it in 'BE'-format */
    p = (data + ARP_HEADER_BASE + ARP_HEADER_DESTINATION_PROTOCOL_ADDRESS) ;
    get4( p, dst_ip_addr ) ;

    /* get our IP address in BE-format */
    IF_ERROR( (rcode),
              (SYSCON_read( SYSCON_COM_EN0_IP_ADDR_ID,
                            &(ip_station_adr),
                            sizeof(ip_station_adr)) ) )

    /* Check, that this ARP-frame actually contains our IP-address */
    if (dst_ip_addr != ip_station_adr)
    {
        return( ERROR_NET_ARP_INVALID_IP_ADDR ) ;
    }

    switch (op_code)
    {
        case ARP_HEADER_OPERATION_CODE_REQUEST:
                /* Return 'response' */
                p = (data + ARP_HEADER_BASE + ARP_HEADER_SOURCE_MEDIA_ADDRESS) ;
                rcode = NET_ARP_reply( src_ip_addr, (t_mac_addr*) p ) ;
            break;

        case ARP_HEADER_OPERATION_CODE_RESPONSE:
                /* search the cache to match any 'ip_addr' */
                for ( i = 0; i < ARP_SAP_COUNT; i++ )
                {
                    if ( (sap_context[i].state == ARP_SAP_STATE_ALLOCATED) &&
                         (src_ip_addr == sap_context[i].ip_addr) )
                    {
                        /* Match found, save the MAC-address of sender */
                        sap_context[i].state   = ARP_SAP_STATE_RESOLUTED ;
                        p = (data + ARP_HEADER_BASE + ARP_HEADER_SOURCE_MEDIA_ADDRESS) ;
                        memcpy( sap_context[i].mac_addr, 
                                p,
                                SYS_MAC_ADDR_SIZE ) ;
                    }
                }
            break;

        default:
                /* we should never arrive here */
                rcode = ERROR_NET_ARP_INVALID_OPCODE ;
            break;
    }
    return( rcode ) ;
}


/************************************************************************
 *
 *                          NET_ARP_alloc_sap
 *  Description :
 *  -------------
 *  Allocate an ARP SAP and register user context.
 * 
 *
 *  Parameters :
 *  ------------
 *  'ip_addr',          IN,    IP-address, which MAC-address is to be
 *                             resoluted
 *  'mac_addr',         INOUT, MAC-address, which may be defined
 *                             by the caller. At return, the MAC-address
 *                             may be defined, if the cache contains
 *                             an entry in state 'resoluted' of the
 *                             specified IP-address.
 *
 *
 *  Return values :
 *  ---------------
 * 'OK' = 0x00:  Entry found, MAC-address has been resoluted
 *
 *
 ************************************************************************/
static
UINT32 NET_ARP_alloc_sap( UINT32     ip_addr,
                          t_mac_addr *mac_addr )

{
    int i, j ;
    UINT32 rcode, oldest, time_now ;

#ifdef NET_DEBUG
    printf("NET_ARP_alloc_sap\n") ;
#endif

    /* search the cache to match any 'ip_addr' */
    for ( i = 0; i < ARP_SAP_COUNT; i++ )
    {
        if(ip_addr == sap_context[i].ip_addr)
        {
            /* Match found, check now the state to determine action */
            if (sap_context[i].state == ARP_SAP_STATE_RESOLUTED)
            {
                /* This entry contains the MAC-address */
                memcpy( mac_addr,
                        sap_context[i].mac_addr, 
                        SYS_MAC_ADDR_SIZE ) ;

                /* refresh timer */
                IF_ERROR( (rcode),
                          (NET_gettime( &time_now )) )
                sap_context[i].timeout = time_now + ARP_SAP_TIMEOUT ;
                return( OK ) ;
            }

            if (sap_context[i].state == ARP_SAP_STATE_ALLOCATED)
            {
                /* Broadcast ARP-request again */
                IF_ERROR( (rcode),
                          (NET_ARP_request( sap_context[i].ip_addr )) )

                /* refresh timer */
                IF_ERROR( (rcode),
                          (NET_gettime( &time_now )) )
                sap_context[i].timeout = time_now + ARP_SAP_TIMEOUT ;
                return( ERROR_NET_ARP_MAC_NOT_RESOLUTED ) ;
            }
        }
    }

    /* search the cache to create a new entry */
    j = 0 ;
    oldest = 0xffffffff ;
    for ( i = 0; i < ARP_SAP_COUNT; i++ )
    {
        if (sap_context[i].state == ARP_SAP_STATE_CLOSED)
        {
            j = i ;
            break ;
        }
        else
        {
            /* we must determine the oldest entry,
               in case the cache has no free entries */
            if (sap_context[i].timeout < oldest)
            {
                oldest = sap_context[i].timeout ;
                j = i ;
            }
        }
    }

    /* We have now determined where to put the new entry */
    i = j ;
    if ( memcmp(mac_addr, mac_undefined_adr, SYS_MAC_ADDR_SIZE) )
    {
        /* MAC is resoluted, create a new entry */

        /* Save (IP,MAC)-address */
        sap_context[i].ip_addr = ip_addr ;
        memcpy( sap_context[i].mac_addr, 
                mac_addr,
                SYS_MAC_ADDR_SIZE ) ;
        sap_context[i].state = ARP_SAP_STATE_RESOLUTED ;

        /* set timer */
        IF_ERROR( (rcode),
                  (NET_gettime( &time_now )) )
        sap_context[i].timeout = time_now + ARP_SAP_TIMEOUT ;
        return( OK ) ;
    }
    else
    {
        /* MAC must be resoluted, create a new entry */

        /* Save (IP)-address */
        sap_context[i].ip_addr = ip_addr ;
        memcpy( sap_context[i].mac_addr, 
                mac_undefined_adr,
                SYS_MAC_ADDR_SIZE ) ;
        sap_context[i].state = ARP_SAP_STATE_ALLOCATED ;

        /* Broadcast ARP-request */
        IF_ERROR( (rcode),
                  (NET_ARP_request( ip_addr )) )

        /* set timer */
        IF_ERROR( (rcode),
                  (NET_gettime( &time_now )) )
        sap_context[i].timeout = time_now + ARP_SAP_TIMEOUT ;
        return( ERROR_NET_ARP_MAC_NOT_RESOLUTED ) ;
    }
}


/************************************************************************
 *
 *                          NET_ARP_reply
 *  Description :
 *  -------------
 *  Send a 'reply' with this stations IP-and MAC-addresses to 'requester'.
 *
 *
 *  Parameters :
 *  ------------
 *  'ip_addr',          IN,    IP-address of 'requester' (BE-format)
 *  'mac_addr',         IN,    MAC-address of 'requester'
 *
 *
 *  Return values :
 *  ---------------
 * 'OK' = 0x00:
 *
 *
 ************************************************************************/
static
UINT32 NET_ARP_reply( UINT32     ip_addr,
                      t_mac_addr *mac_addr )
{
    UINT8   frame[MAC_HEADER_SIZE + ARP_HEADER_SIZE] ;
    UINT32  rcode = OK ;
    UINT8   *p ;
    UINT8   tmp1 ;
    UINT16  tmp2 ;
    UINT32  ip_station_adr ;

    /* get our IP address in BE-format */
    IF_ERROR( (rcode),
              (SYSCON_read( SYSCON_COM_EN0_IP_ADDR_ID,
                            &(ip_station_adr),
                            sizeof(ip_station_adr)) ) )

    /* build the ARP-reply header */
    p = &frame[ ARP_HEADER_BASE ] ;
    tmp2 = CPU_TO_BE16( ARP_HEADER_MEDIA_TYPE_ETHERNET ) ;
    put2( tmp2, p ) 

    tmp2 = CPU_TO_BE16( ARP_HEADER_PROTOCOL_TYPE_IP ) ;
    put2( tmp2, p ) 
    
    tmp1 = ARP_HEADER_MEDIA_ADDRESS_SIZE_ETHERNET ;
    put1( tmp1, p ) 

    tmp1 = ARP_HEADER_PROTOCOL_ADDRESS_SIZE_IP ;
    put1( tmp1, p ) 

    tmp2 = CPU_TO_BE16( ARP_HEADER_OPERATION_CODE_RESPONSE ) ;
    put2( tmp2, p ) 
    
    put6( mac_station_adr, p )
    put4( ip_station_adr, p )

    put6( *mac_addr, p )
    put4( ip_addr, p )

    /* request MAC to send the reply */
    rcode = NET_MAC_send( mac_sp_hd,
                          mac_addr,
                          MAC_HEADER_SIZE + ARP_HEADER_SIZE,
                          frame ) ;

    return( rcode ) ;
}


/************************************************************************
 *
 *                          NET_ARP_request
 *  Description :
 *  -------------
 *  Broadcast a 'request' to resolute the MAC-address of the specified
 *  'ip_addr'.
 *
 *
 *  Parameters :
 *  ------------
 *  'ip_addr',          IN,    IP-address (BE-format), 
 *                             which is going to be MAC-address resoluted.
 *
 *
 *  Return values :
 *  ---------------
 * 'OK' = 0x00:
 *
 *
 ************************************************************************/
static
UINT32 NET_ARP_request( UINT32 ip_addr )
{
    UINT8   frame[MAC_HEADER_SIZE + ARP_HEADER_SIZE] ;
    UINT32  rcode = OK ;
    UINT8   *p ;
    UINT8   tmp1 ;
    UINT16  tmp2 ;
    UINT32  ip_station_adr ;

    /* get our IP address in BE-format */
    IF_ERROR( (rcode),
              (SYSCON_read( SYSCON_COM_EN0_IP_ADDR_ID,
                            &(ip_station_adr),
                            sizeof(ip_station_adr)) ) )

    /* build the ARP-reply header */
    p = &frame[ ARP_HEADER_BASE ] ;
    tmp2 = CPU_TO_BE16( ARP_HEADER_MEDIA_TYPE_ETHERNET ) ;
    put2( tmp2, p )

    tmp2 = CPU_TO_BE16( ARP_HEADER_PROTOCOL_TYPE_IP ) ;
    put2( tmp2, p )
   
    tmp1 = ARP_HEADER_MEDIA_ADDRESS_SIZE_ETHERNET ;
    put1( tmp1, p )

    tmp1 = ARP_HEADER_PROTOCOL_ADDRESS_SIZE_IP ;
    put1( tmp1, p )

    tmp2 = CPU_TO_BE16( ARP_HEADER_OPERATION_CODE_REQUEST ) ;
    put2( tmp2, p )

    put6( mac_station_adr, p )
    put4( ip_station_adr, p )

    put6( mac_undefined_adr, p )
    put4( ip_addr, p )

    /* Request MAC to broadcast the request */
    rcode = NET_MAC_send( mac_sp_hd,
                          &mac_broadcast_adr,
                          MAC_HEADER_SIZE + ARP_HEADER_SIZE,
                          frame ) ;

    return( rcode ) ;
}

⌨️ 快捷键说明

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