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

📄 net_ip.c

📁 MIPS YAMON, a famous monitor inc. source, make file and PDF manuals.
💻 C
📖 第 1 页 / 共 2 页
字号:
UINT32 NET_IP_send( UINT32      ip_sp_hd, /* service provider defined handle */                    UINT32      dst_adr,  /* destination ip address (BE)     */                    t_mac_addr *dst_mac_adr, /* destination MAC-address      */                    UINT32      length,   /* total length of frame to send   */                    UINT8       *data  )  /* pointer to start of frame       */{    UINT32     rcode ;    t_mac_addr mac_addr ;    UINT8      *p ;    UINT16     tmp2 ;    /* 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 (env_ipaddr == IP_ADDR_UNDEFINED)    {        /* Our IP address of this board is undefined ! */        sprintf( net_diag_msg,"Board IP-address: %d.%d.%d.%d",                        ((UINT8*)&env_ipaddr)[0],                        ((UINT8*)&env_ipaddr)[1],                        ((UINT8*)&env_ipaddr)[2],                        ((UINT8*)&env_ipaddr)[3] );        net_last_error = ERROR_NET_INVALID_BOARD_IP ;        return( ERROR_NET_INVALID_BOARD_IP ) ;    }    /* validate subnet mask */    if (env_subnetmask == 0)    {        /* Subnet mask is undefined ! */        sprintf( net_diag_msg,"subnetmask: %d.%d.%d.%d",                        ((UINT8*)&env_subnetmask)[0],                        ((UINT8*)&env_subnetmask)[1],                        ((UINT8*)&env_subnetmask)[2],                        ((UINT8*)&env_subnetmask)[3] );        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 ( (env_subnetmask & env_ipaddr) != (env_subnetmask & dst_adr) )        {            /* Not on same subnet, we need to use default gateway */            if (env_gateway == 0)            {                /* Gateway address is undefined ! */                sprintf( net_diag_msg,"Gateway IP-address: %d.%d.%d.%d",                                    ((UINT8*)&env_gateway)[0],                                    ((UINT8*)&env_gateway)[1],                                    ((UINT8*)&env_gateway)[2],                                    ((UINT8*)&env_gateway)[3] );                net_last_error = ERROR_NET_INVALID_GATEWAY_IP ;                return( ERROR_NET_INVALID_GATEWAY_IP ) ;            }            /* We must be on same subnet as gateway */            if ( (env_subnetmask & env_ipaddr) != (env_subnetmask & env_gateway) )            {                sprintf( net_diag_msg,"ip: %d.%d.%d.%d, gw: %d.%d.%d.%d, sub: %d.%d.%d.%d",                                    ((UINT8*)&env_ipaddr)[0],                                    ((UINT8*)&env_ipaddr)[1],                                    ((UINT8*)&env_ipaddr)[2],                                    ((UINT8*)&env_ipaddr)[3],                                    ((UINT8*)&env_gateway)[0],                                    ((UINT8*)&env_gateway)[1],                                    ((UINT8*)&env_gateway)[2],                                    ((UINT8*)&env_gateway)[3],                                    ((UINT8*)&env_subnetmask)[0],                                    ((UINT8*)&env_subnetmask)[1],                                    ((UINT8*)&env_subnetmask)[2],                                    ((UINT8*)&env_subnetmask)[3] );                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( env_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) ;    /* Fill-in version+header length  */    put1( IP_HEADER_VERSION_LENGTH_IPV4, p ) ;    /* Fill-in 'type-of-service'      */    put1( IP_HEADER_TYPE_OF_SERVICE_NORMAL, p ) ;    /* Fill-in 'total-length'         */    tmp2 = length - MAC_HEADER_SIZE ;    putbe2( tmp2, p ) ;    /* Fill-in 'identification'       */    putbe2( NET_IP_identification++, p ) ;    /* Fill-in 'fragment' (not used)  */    putbe2( IP_HEADER_FRAGMENT_NO, p ) ;    /* Fill-in 'time-to-live'         */    put1( IP_HEADER_TIME_TO_LIVE_NORMAL, p ) ;    /* Fill-in 'protocol'             */    put1( sap_context[ip_sp_hd].ip_sap, p ) ;    /* Fill-in 'checksum' (temp = 0)  */    put2( 0, p ) ;    /* Fill-in 'source-IP-adr'        */    put4( env_ipaddr, p ) ;    /* Fill-in 'destination-IP-adr'   */    put4( dst_adr, p ) ;    /* Fill-in calculated 'checksum'  */    tmp2 = NET_checksum( (UINT16*)((UINT32)data + IP_HEADER_BASE), IP_HEADER_SIZE/2 ) ;    p = (data + IP_HEADER_BASE + IP_HEADER_CHECKSUM) ;    put2( tmp2, p ) ;    /* 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' * ************************************************************************/staticUINT32 NET_IP_receive( t_mac_addr *src_mac_adr,                       UINT32     length,                       UINT8      *data    ){    UINT32            rcode, src_ip_addr, dst_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) ;    put2( 0, p ) ;    tmp2 = NET_checksum( (UINT16*)((UINT32)data + IP_HEADER_BASE), IP_HEADER_SIZE/2 ) ;    if ( tmp2 != checksum )    {        return( ERROR_NET_IP_INVALID_CHECKSUM ) ;    }    /* Having verified checksum, let this frame be untouched */    p = (data + IP_HEADER_BASE + IP_HEADER_CHECKSUM) ;    put2( checksum, p ) ;    /* 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) ;    get1( 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 (env_ipaddr != 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 ) ;            }        }    }    /* No SAP, reply 'PROTOCOL is UNREACHABLE' */    p = (data + IP_HEADER_BASE) ;    rcode = NET_ICMP_UNREACHABLE_send( src_ip_addr,                                       src_mac_adr,                                       p,                                       ICMP_UNREACHABLE_HEADER_CODE_PROT_UNREACHABLE ) ;    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: * * ************************************************************************/staticUINT32 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 + -