📄 net_icmp.c
字号:
* --------------- * '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 ; 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] ; /* Fill-in 'type'(=REQUEST) */ put1( ICMP_ECHO_HEADER_TYPE_ECHOREQUEST , p ) ; /* Fill-in 'code' */ put1( ICMP_ECHO_HEADER_CODE_ECHO , p ) ; /* Fill-in 'checksum' (temp = 0) */ put2( 0, p ) ; /* Fill-in 'identification' */ putbe2( ICMP_ECHO_HEADER_IDENTIFICATION_MIPS , p ) ; /* Fill-in 'sequence' */ putbe2( sequence , p ) ; /* Fill-in data */ for (i=0; i<length; i++) { put1( (UINT8)i , p ) ; } /* Check odd case */ tmp2 = ICMP_ECHO_HEADER_SIZE/2 + (length/2) ; if (length%2) { put1( 0, 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 ) ; /* 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' * ************************************************************************/staticUINT32 NET_ICMP_receive( UINT32 src_ip_adr, t_mac_addr *src_mac_adr, UINT32 length, UINT8 *data ){ UINT32 rcode ; UINT8 *p ; UINT8 type ; UINT16 tmp2, checksum, sequence, identification, words, usr_length ;#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) ; put2( 0, p ) ; /* odd case */ p = &data[length] ; words = (length - (ICMP_ECHO_HEADER_BASE))/2 ; if (length%2) { put1( 0, 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 */ p = (data + ICMP_ECHO_HEADER_BASE + ICMP_ECHO_HEADER_TYPE) ; put1( ICMP_ECHO_HEADER_TYPE_ECHOREPLY , 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 ) ; }/************************************************************************ * * NET_ICMP_UNREACHABLE_send * Description : * ------------- * Request the ICMP module to send a 'destination unreachable' datagram * to a specified destination IP-address with a specified * unreachable code along with the received IP-header. * * * Parameters : * ------------ * 'ip_adr', IN, destination ip address (BE-format) * 'mac_adr', IN, optional MAC address * 'ip_header', IN, ip-header of received datagram * 'code', IN, unreachable code * * * Return values : * --------------- * 'OK'(=0) * ************************************************************************/UINT32 NET_ICMP_UNREACHABLE_send( UINT32 ip_adr, /* destination ip address (BE) */ t_mac_addr *mac_adr,/* optional MAC destination */ UINT8 *ip_header, UINT8 code ){ UINT8 data[MAC_MAX_FRAME_SIZE] ; /* WARNING: This function needs stack */ UINT32 rcode ; UINT8 *p ; UINT32 tmp4 ; UINT16 tmp2 ; int i ; /* Fill-in ICMP header of frame */ p = &data[ICMP_UNREACHABLE_HEADER_BASE] ; /* Fill-in 'type'(=UNREACHABLE) */ put1( ICMP_UNREACHABLE_HEADER_TYPE_UNREACHABLE, p ) ; /* Fill-in 'code' */ put1( code, p ) ; /* Fill-in 'checksum' (temp = 0) */ put2( 0, p ) ; /* Fill-in 'reserved' (= 0) */ tmp4 = 0 ; put4( tmp4, p ) ; /* Fill-in received ip-header in data field */ for (i=0; i<ICMP_UNREACHABLE_DATA_SIZE; i++) { put1( *ip_header++ , p ) ; } /* complete UNREACHABLE-header with checksum */ p = &data[ICMP_UNREACHABLE_HEADER_BASE] ; tmp2 = (ICMP_UNREACHABLE_DATA_SIZE+ICMP_UNREACHABLE_HEADER_SIZE)/2 ; tmp2 = NET_checksum( (UINT16*)p, tmp2 ) ; p = (data + ICMP_UNREACHABLE_HEADER_BASE + ICMP_UNREACHABLE_HEADER_CHECKSUM) ; put2( tmp2, p ) ; /* request IP to send this frame */ rcode = NET_IP_send( ip_sp_hd, ip_adr, mac_adr, ICMP_UNREACHABLE_DATA_SIZE+ICMP_UNREACHABLE_HEADER_SIZE+IP_HEADER_SIZE+MAC_HEADER_SIZE, data ) ; /* return completion */ return( rcode ) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -