📄 net_arp.c
字号:
* 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 + -