📄 net_icmp.c
字号:
/* un-register receive handler */
icmp_echo_sap = NULL ;
return(OK) ;
}
/************************************************************************
*
* NET_ICMP_ECHO_send
* Description :
* -------------
* Request the ICMP ECHO module to send a 'ECHO' datagram
* to a specified destination IP-address with a specified
* sequence number and length of ECHO user data.
* Optionally a MAC-address for destination may be supplied.
*
*
* Parameters :
* ------------
* 'ip_adr', IN, destination ip address (BE-format)
* 'mac_adr', IN, optional MAC address
* 'sequence', IN, sequence number to assign datagram
* 'length', IN, length of ECHO-data to send
*
*
* Return values :
* ---------------
* 'OK'(=0)
*
************************************************************************/
UINT32 NET_ICMP_ECHO_send( UINT32 ip_adr, /* destination ip address (BE) */
t_mac_addr *mac_adr,/* optional MAC destination */
UINT16 sequence,
UINT16 length )
{
UINT8 data[MAC_MAX_FRAME_SIZE] ; /* WARNING: This function needs stack */
UINT32 rcode ;
UINT8 *p ;
UINT8 tmp1 ;
UINT16 tmp2 ;
int i ;
/* Length validation */
if ( length > ICMP_ECHO_HEADER_DATA_MAX_SIZE )
{
return( ERROR_NET_ICMP_INVALID_DATA_SIZE ) ;
}
/* Fill-in ICMP header of frame */
p = &data[ICMP_ECHO_HEADER_BASE] ;
tmp1 = ICMP_ECHO_HEADER_TYPE_ECHOREQUEST ;
put1( tmp1, p ) ; /* Fill-in 'type'(=REQUEST) */
tmp1 = ICMP_ECHO_HEADER_CODE_ECHO ;
put1( tmp1, p ) ; /* Fill-in 'code' */
tmp2 = 0 ;
put2( tmp2, p ) ; /* Fill-in 'checksum' (temp = 0) */
tmp2 = CPU_TO_BE16( ICMP_ECHO_HEADER_IDENTIFICATION_MIPS ) ;
put2( tmp2, p ) ; /* Fill-in 'identification' */
tmp2 = CPU_TO_BE16( sequence ) ;
put2( tmp2, p ) ; /* Fill-in 'sequence' */
/* Fill-in data */
for (i=0; i<length; i++)
{
tmp1 = (i & 0xff) ;
put1( tmp1, p ) ;
}
/* Check odd case */
tmp2 = ICMP_ECHO_HEADER_SIZE/2 + (length/2) ;
if (length%2)
{
tmp1 = 0 ;
put1( tmp1, p ) ;
tmp2 = tmp2 + 1 ;
}
/* complete ECHO-header with checksum */
p = &data[ICMP_ECHO_HEADER_BASE] ;
tmp2 = NET_checksum( (UINT16*)p, tmp2 ) ;
p = (data + ICMP_ECHO_HEADER_BASE + ICMP_ECHO_HEADER_CHECKSUM) ;
put2( tmp2, p ) ; /* Fill-in calculated 'checksum' */
/* request IP to send this frame */
rcode = NET_IP_send( ip_sp_hd,
ip_adr,
mac_adr,
length+ICMP_ECHO_HEADER_SIZE+IP_HEADER_SIZE+MAC_HEADER_SIZE,
data ) ;
/* return completion */
return( rcode ) ;
}
/************************************************************************
* Implementation : Static functions
************************************************************************/
/************************************************************************
*
* NET_ICMP_receive
* Description :
* -------------
* This function is registered in the IP-module and linked with the
* IP-protocol = '1', to let the IP call us back with a reference
* to the received frame, containing an ICMP-frame.
* In this function the ICMP-header will be validated and
* the ICMP-ECHO-SAP will be checked to call a user registered
* ECHO-reply handler, which may check sender-IP-address, sequence
* number and length of user data received.
*
*
*
* Parameters :
* ------------
* 'src_ip_adr': sender's IP-address (BE-format)
* 'src_mac_adr': sender's MAC-address
* 'length': length of received ethernet frame
* 'data': pointer for received ethernet frame (in driver's space)
*
*
* Return values :
* ---------------
* 'OK'
*
************************************************************************/
static
UINT32 NET_ICMP_receive( UINT32 src_ip_adr,
t_mac_addr *src_mac_adr,
UINT32 length,
UINT8 *data )
{
UINT32 rcode ;
UINT8 *p ;
UINT8 tmp1, type ;
UINT16 tmp2, checksum, sequence, identification, words, usr_length ;
int i ;
#ifdef NET_DEBUG
printf("NET_ICMP_receive:\n") ;
#endif
/* validate ICMP checksum */
p = (data + ICMP_ECHO_HEADER_BASE + ICMP_ECHO_HEADER_CHECKSUM) ;
get2( p, checksum) ;
p = (data + ICMP_ECHO_HEADER_BASE + ICMP_ECHO_HEADER_CHECKSUM) ;
tmp2 = 0 ;
put2( tmp2, p ) ;
/* odd case */
p = &data[length] ;
words = (length - (ICMP_ECHO_HEADER_BASE))/2 ;
if (length%2)
{
tmp1 = 0 ;
put1( tmp1, p ) ;
words = words + 1 ;
}
p = &data[ICMP_ECHO_HEADER_BASE] ;
tmp2 = NET_checksum( (UINT16*)p, words ) ;
if ( tmp2 != checksum )
{
return( ERROR_NET_ICMP_INVALID_CHECKSUM ) ;
}
/* get ICMP-'type'-field of this received frame */
p = (data + ICMP_ECHO_HEADER_BASE + ICMP_ECHO_HEADER_TYPE) ;
get1( p, type) ;
switch(type)
{
case ICMP_ECHO_HEADER_TYPE_ECHOREQUEST:
/* make a reply */
/* Put-in reply */
tmp1 = ICMP_ECHO_HEADER_TYPE_ECHOREPLY ;
p = (data + ICMP_ECHO_HEADER_BASE + ICMP_ECHO_HEADER_TYPE) ;
put1( tmp1, p) ;
/* Calculate checksum */
p = &data[ICMP_ECHO_HEADER_BASE] ;
tmp2 = NET_checksum( (UINT16*)p, words ) ;
/* Put in checksum */
p = (data + ICMP_ECHO_HEADER_BASE + ICMP_ECHO_HEADER_CHECKSUM) ;
put2( tmp2, p) ;
/* request IP to send this frame */
rcode = NET_IP_send( ip_sp_hd,
src_ip_adr,
src_mac_adr,
length,
data ) ;
break ;
case ICMP_ECHO_HEADER_TYPE_ECHOREPLY:
if (icmp_echo_sap != NULL)
{
/* validate reply and call user */
p = (data + ICMP_ECHO_HEADER_BASE + ICMP_ECHO_HEADER_IDENTIFICATION) ;
get2( p, identification ) ;
tmp2 = BE16_TO_CPU( identification ) ;
if (tmp2 != ICMP_ECHO_HEADER_IDENTIFICATION_MIPS)
{
rcode = ERROR_NET_ICMP_INVALID_ID ;
}
else
{
get2( p, tmp2 ) ;
sequence = BE16_TO_CPU( tmp2 ) ;
usr_length = length - (ICMP_ECHO_HEADER_BASE + ICMP_ECHO_HEADER_SIZE) ;
rcode = (*icmp_echo_sap)( src_ip_adr, src_mac_adr, sequence, usr_length ) ;
}
}
else
{
rcode = ERROR_NET_ICMP_NO_USER ;
}
break ;
default:
rcode = ERROR_NET_ICMP_INVALID_TYPE ;
break ;
}
return( rcode ) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -