📄 net_ip.c
字号:
UINT8 sap ;
int i ;
/* validate handle */
IF_UPPER( ERROR_NET_IP_INVALID_HANDLE, ip_sp_hd, IP_SAP_COUNT)
/* validate state */
if ( sap_context[ip_sp_hd].ip_sap_state != IP_SAP_STATE_OPEN )
{
return( ERROR_NET_IP_SAP_CLOSED ) ;
}
/* validate destination IP-address */
if (dst_adr == IP_ADDR_UNDEFINED)
{
/* Destination host is undefined ! */
sprintf( net_diag_msg,"Destination host: %d.%d.%d.%d", ((dst_adr>>24)&0xff),
((dst_adr>>16)&0xff),
((dst_adr>> 8)&0xff),
((dst_adr>> 0)&0xff) );
net_last_error = ERROR_NET_INVALID_HOST_IP ;
return( ERROR_NET_INVALID_HOST_IP ) ;
}
/* get our IP address, and validate */
IF_ERROR( (rcode),
(SYSCON_read( SYSCON_COM_EN0_IP_ADDR_ID,
&(our_ip_adr),
sizeof(our_ip_adr)) ) )
if (our_ip_adr == IP_ADDR_UNDEFINED)
{
/* Our IP address of this board is undefined ! */
sprintf( net_diag_msg,"Board IP-address: %d.%d.%d.%d",
((our_ip_adr>>24)&0xff),
((our_ip_adr>>16)&0xff),
((our_ip_adr>> 8)&0xff),
((our_ip_adr>> 0)&0xff) );
net_last_error = ERROR_NET_INVALID_BOARD_IP ;
return( ERROR_NET_INVALID_BOARD_IP ) ;
}
/* get subnet mask, and validate */
IF_ERROR( (rcode),
(SYSCON_read( SYSCON_COM_EN0_IP_SUBNETMASK_ID,
&(subnet),
sizeof(subnet)) ) )
if (subnet == 0)
{
/* Subnet mask is undefined ! */
sprintf( net_diag_msg,"subnetmask: %d.%d.%d.%d",
((subnet>>24)&0xff),
((subnet>>16)&0xff),
((subnet>> 8)&0xff),
((subnet>> 0)&0xff) );
net_last_error = ERROR_NET_INVALID_SUBNET_MASK ;
return( ERROR_NET_INVALID_SUBNET_MASK ) ;
}
/* check, if we have any MAC to use */
if (dst_mac_adr == NULL)
{
/* clear mac */
memcpy(mac_addr, mac_undefined_adr, SYS_MAC_ADDR_SIZE) ;
/* Check for use of default gateway */
if ( (subnet & our_ip_adr) != (subnet & dst_adr) )
{
/* Not on same subnet, we need to use default gateway */
IF_ERROR( (rcode),
(SYSCON_read( SYSCON_COM_EN0_IP_GATEWAYADDR_ID,
&(gateway),
sizeof(gateway)) ) )
if (gateway == 0)
{
/* Gateway address is undefined ! */
sprintf( net_diag_msg,"Gateway IP-address: %d.%d.%d.%d",
((gateway >>24)&0xff),
((gateway >>16)&0xff),
((gateway >> 8)&0xff),
((gateway >> 0)&0xff) );
net_last_error = ERROR_NET_INVALID_GATEWAY_IP ;
return( ERROR_NET_INVALID_GATEWAY_IP ) ;
}
/* We must be on same subnet as gateway */
if ( (subnet & our_ip_adr) != (subnet & gateway) )
{
our_ip_adr = BE32_TO_CPU(our_ip_adr) ;
subnet = BE32_TO_CPU(subnet) ;
gateway = BE32_TO_CPU(gateway) ;
sprintf( net_diag_msg,"ip: %d.%d.%d.%d, gw: %d.%d.%d.%d, sub: %d.%d.%d.%d",
((our_ip_adr>>24)&0xff),
((our_ip_adr>>16)&0xff),
((our_ip_adr>> 8)&0xff),
((our_ip_adr>> 0)&0xff),
((gateway >>24)&0xff),
((gateway >>16)&0xff),
((gateway >> 8)&0xff),
((gateway >> 0)&0xff),
((subnet >>24)&0xff),
((subnet >>16)&0xff),
((subnet >> 8)&0xff),
((subnet >> 0)&0xff) ) ;
net_last_error = ERROR_NET_NOT_ON_SAME_SUBNET_IP ;
return( ERROR_NET_NOT_ON_SAME_SUBNET_IP ) ;
}
/* We need to resolute the MAC-address of gateway */
IF_ERROR( (rcode),
(NET_ARP_open( gateway,
&mac_addr) ) )
}
else
{
/* On same subnet, we need to resolute the MAC-address of destination */
IF_ERROR( (rcode),
(NET_ARP_open( dst_adr,
&mac_addr) ) )
}
}
/* Fill-in IP header of frame */
p = (data + IP_HEADER_BASE) ;
tmp1 = IP_HEADER_VERSION_LENGTH_IPV4 ;
put1( tmp1, p ) ; /* Fill-in version+header length */
tmp1 = IP_HEADER_TYPE_OF_SERVICE_NORMAL ;
put1( tmp1, p ) ; /* Fill-in 'type-of-service' */
tmp2 = CPU_TO_BE16( length - MAC_HEADER_SIZE ) ;
put2( tmp2, p ) ; /* Fill-in 'total-length' */
tmp2 = CPU_TO_BE16( NET_IP_identification++ ) ;
put2( tmp2, p ) ; /* Fill-in 'identification' */
tmp2 = CPU_TO_BE16(IP_HEADER_FRAGMENT_NO) ;
put2( tmp2, p ) ; /* Fill-in 'fragment' (not used) */
tmp1 = IP_HEADER_TIME_TO_LIVE_NORMAL ;
put1( tmp1, p ) ; /* Fill-in 'time-to-live' */
sap = sap_context[ip_sp_hd].ip_sap ;
put1( sap, p ) ; /* Fill-in 'protocol' */
tmp2 = 0 ;
put2( tmp2, p ) ; /* Fill-in 'checksum' (temp = 0) */
tmp4 = our_ip_adr ;
put4( tmp4, p ) ; /* Fill-in 'source-IP-adr' */
tmp4 = dst_adr ;
put4( tmp4, p ) ; /* Fill-in 'destination-IP-adr' */
tmp2 = NET_checksum( (UINT16*)((UINT32)data + IP_HEADER_BASE), IP_HEADER_SIZE/2 ) ;
p = (data + IP_HEADER_BASE + IP_HEADER_CHECKSUM) ;
put2( tmp2, p ) ; /* Fill-in calculated 'checksum' */
/* request MAC to send this frame */
if (dst_mac_adr == NULL)
{
/* use resoluted MAC-address */
rcode = NET_MAC_send( mac_sp_hd,
&mac_addr,
length,
data ) ;
}
else
{
/* use callers supplied MAC-address */
rcode = NET_MAC_send( mac_sp_hd,
dst_mac_adr,
length,
data ) ;
}
/* return completion */
return( rcode ) ;
}
/************************************************************************
* Implementation : Static functions
************************************************************************/
/************************************************************************
*
* NET_IP_receive
* Description :
* -------------
* This function is registered in the MAC-module and linked with the
* MAC-type = '0x800', to let the MAC call us back with an reference
* to the received frame, containing an IP-frame.
* In this function the IP-header will be validated and the IP-SAP
* table will be searched for any match between the actual value
* of the IP-protocol field and a registered user to handle upper
* protocol layer.
*
*
*
* Parameters :
* ------------
* 'src_mac_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_IP_receive( t_mac_addr *src_mac_adr,
UINT32 length,
UINT8 *data )
{
UINT32 rcode, src_ip_addr, dst_ip_addr, our_ip_addr ;
t_ip_usr_receive receive ;
UINT8 *p ;
UINT8 sap ;
UINT16 checksum, totlen ;
UINT16 tmp2 ;
int i ;
#ifdef NET_DEBUG
printf("NET_IP_receive\n") ;
#endif
/* validate checksum */
p = (data + IP_HEADER_BASE + IP_HEADER_CHECKSUM) ;
get2( p, checksum) ;
p = (data + IP_HEADER_BASE + IP_HEADER_CHECKSUM) ;
tmp2 = 0 ;
put2( tmp2, p ) ;
tmp2 = NET_checksum( (UINT16*)((UINT32)data + IP_HEADER_BASE), IP_HEADER_SIZE/2 ) ;
if ( tmp2 != checksum )
{
return( ERROR_NET_IP_INVALID_CHECKSUM ) ;
}
/* get IP-'total_length'-field of this received frame and adjust length */
p = (data + IP_HEADER_BASE + IP_HEADER_TOTAL_LENGTH) ;
get2( p, totlen) ;
length = BE16_TO_CPU(totlen) + MAC_HEADER_SIZE ;
/* validate length */
if (length > MAC_MAX_FRAME_SIZE)
{
return( ERROR_NET_IP_INVALID_LENGTH ) ;
}
/* get IP-'protocol'-field of this received frame */
p = (data + IP_HEADER_BASE + IP_HEADER_PROTOCOL) ;
get2( p, sap) ;
/* get source IP address of this received frame */
p = (data + IP_HEADER_BASE + IP_HEADER_SOURCE_IP_ADDRESS) ;
get4( p, src_ip_addr) ;
/* get destination IP address of this received frame, and validate
destination is our address */
get4( p, dst_ip_addr) ;
IF_ERROR( (rcode),
(SYSCON_read( SYSCON_COM_EN0_IP_ADDR_ID,
&(our_ip_addr),
sizeof(our_ip_addr)) ) )
if (our_ip_addr != dst_ip_addr)
{
return( ERROR_NET_IP_INVALID_DST_IP_ADDR ) ;
}
/* search the SAP table to match this 'sap' */
for ( i = 0; i <IP_SAP_COUNT ; i++ )
{
if ( sap_context[i].ip_sap == sap )
{
if ( sap_context[i].ip_sap_state == IP_SAP_STATE_OPEN )
{
/* we have a registered SAP context, call user */
receive = sap_context[i].ip_usr_receive ;
rcode = (*receive)( src_ip_addr,
src_mac_adr,
length,
data ) ;
return( rcode ) ;
}
}
}
return( ERROR_NET_IP_NO_SAP ) ;
}
/************************************************************************
*
* NET_IP_alloc_sap
* Description :
* -------------
* Allocate a IP SAP, register user context and return a sp-handle.
*
*
* Parameters :
* ------------
*
* 'sap_id', IN, value of IP-'protocol' to bind for
* 'ip_usr_receive', IN, user-receive function to be registered
* 'ip_sp_hd', OUT, handle of IP to be used by user by call
* of 'send' or 'close'
*
*
* Return values :
* ---------------
* 'ERROR_NET_IP_NO_FREE_SAP', No SAP entry could be allocated
* 'OK' = 0x00:
*
*
************************************************************************/
static
UINT32 NET_IP_alloc_sap( UINT8 sap_id,
t_ip_usr_receive ip_usr_receive,
UINT32 *ip_sp_hd )
{
int i ;
/* allocate a free IP SAP table entry */
for ( i = 0; i <IP_SAP_COUNT ; i++)
{
if ( sap_context[i].ip_sap_state == IP_SAP_STATE_CLOSED )
{
/* save SAP context in allocated entry */
sap_context[i].ip_sap_state = IP_SAP_STATE_OPEN ;
sap_context[i].ip_sap = sap_id ;
sap_context[i].ip_usr_receive = ip_usr_receive ;
*ip_sp_hd = i ;
return( OK ) ;
}
}
/* we should not arrive here */
return( ERROR_NET_IP_NO_FREE_SAP ) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -