⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net_icmp.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* 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 + -