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

📄 net_ip.c

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