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

📄 net_arp.c

📁 MIPS YAMON, a famous monitor inc. source, make file and PDF manuals.
💻 C
📖 第 1 页 / 共 2 页
字号:
 *  Return values : *  --------------- *  'OK'(=0) * ************************************************************************/UINT32 NET_ARP_poll(  void ){    int    i ;    UINT32 time_now ;    UINT32 rcode ;    UINT32 old_ie;    /* get time now (unit is seconds since 1.1.1970) */    rcode = NET_gettime( &time_now ) ;    if (time_now < next_poll_time)    {        return( rcode ) ;    }    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 ;    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 ) ;    /* Check, that this ARP-frame actually contains our IP-address */    if (dst_ip_addr != env_ipaddr)    {        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 * * ************************************************************************/staticUINT32 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: * * ************************************************************************/staticUINT32 NET_ARP_reply( UINT32     ip_addr,                      t_mac_addr *mac_addr ){    UINT8   frame[MAC_HEADER_SIZE + ARP_HEADER_SIZE] ;    UINT32  rcode = OK ;    UINT8   *p ;    /* build the ARP-reply header */    p = &frame[ ARP_HEADER_BASE ] ;    putbe2( ARP_HEADER_MEDIA_TYPE_ETHERNET , p )     putbe2( ARP_HEADER_PROTOCOL_TYPE_IP , p )         put1( ARP_HEADER_MEDIA_ADDRESS_SIZE_ETHERNET , p )     put1( ARP_HEADER_PROTOCOL_ADDRESS_SIZE_IP , p )     putbe2( ARP_HEADER_OPERATION_CODE_RESPONSE , p )         put6( mac_station_adr, p )    put4( env_ipaddr, 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: * * ************************************************************************/staticUINT32 NET_ARP_request( UINT32 ip_addr ){    UINT8   frame[MAC_HEADER_SIZE + ARP_HEADER_SIZE] ;    UINT32  rcode = OK ;    UINT8   *p ;    /* build the ARP-reply header */    p = &frame[ ARP_HEADER_BASE ] ;    putbe2( ARP_HEADER_MEDIA_TYPE_ETHERNET , p )    putbe2( ARP_HEADER_PROTOCOL_TYPE_IP , p )       put1( ARP_HEADER_MEDIA_ADDRESS_SIZE_ETHERNET , p )    put1( ARP_HEADER_PROTOCOL_ADDRESS_SIZE_IP , p )    putbe2( ARP_HEADER_OPERATION_CODE_REQUEST , p )    put6( mac_station_adr, p )    put4( env_ipaddr, 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 + -