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