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

📄 ip.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    case IP_IGMP_PROT :


        /* Increment the number of IP packets successfully delivered. */
        SNMP_ipInDelivers_Inc;

        return (IGMP_Interpret(buf_ptr, (INT)hlen));
#endif

#if (INCLUDE_IP_RAW == NU_TRUE)

    case IP_RAW_PROT :
    case IP_HELLO_PROT :
    case IP_OSPF_PROT :
    /** Any additional Raw IP protocols that are supported in the
        future must have a case here ***/
        
        return (IPRaw_Interpret((NET_BUFFER *)buf_ptr, device));
        
        
#endif

        default:
        NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);

        /* Drop the packet by placing it back on the buffer_freelist. */
        MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);

        /* Increment the number of IP packets received with a invalid
           protocol field. */
        SNMP_ipInUnknownProtos_Inc;

        return (1);
    }  /* end switch */
} /* IP_Interpret */


/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      IP_Send                                                          
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      Send an IP packet.                                               
*                                                                       
* INPUTS                                                                
*                                                                       
*      buf_ptr                                                          
*      ro                                                               
*      dest_ip                                                          
*      src_ip                                                           
*      flags                                                            
*      ttl                                                              
*      protocol                                                         
*      tos                                                              
*      mopt                                                             
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      NU_HOST_UNREACHABLE                                              
*      NU_ACCESS                                                        
*      NU_MSGSIZE                                                       
*                                                                       
*************************************************************************/
STATUS IP_Send(NET_BUFFER *buf_ptr, RTAB_ROUTE *ro, UINT32 dest_ip, 
           UINT32 src_ip, INT32 flags, INT ttl, INT protocol, INT tos, 
           IP_MULTI_OPTIONS *mopt)
{
    IPLAYER         *ip_dgram;
    INT             hlen = sizeof (IPLAYER);
    DV_DEVICE_ENTRY *int_face;
    RTAB_ROUTE      iproute;
    SCK_SOCKADDR_IP *dest;
    STATUS          status;

#if (INCLUDE_IP_MULTICASTING == NU_FALSE)
    UNUSED_PARAMETER(mopt);
#endif

    /* Here use a macro to resolve get a pointer to the IP header. */
    ip_dgram = IP_BUFF_TO_IP(buf_ptr);

    /* If this is a forwarded packet or if it is a raw IP packet, then don't
       mess with the IP header. */
    

    if (flags & (IP_FORWARDING | IP_RAWOUTPUT))
    {
#if INCLUDE_IP_RAW
        if (flags & IP_RAWOUTPUT)
        {
            /* The RAWOUTPUT flag means that the application created
               the header. Therefore buffer size will include the size of the
               header. The code further down in this function assumes that
               the header is not included in the buffer size, thus we
               subtract the header size from the buffer size here as it will
               be added back further below. */

            /* Get a pointer to the user created IP header. */
            ip_dgram = (IPLAYER *)buf_ptr->data_ptr;

            /* Obtain the length of the user created IP header. */
            hlen = (GET8(ip_dgram, IP_VERSIONANDHDRLEN_OFFSET) & 0xf) << 2;

            /* Subtract it from the length of the buffer. */
            buf_ptr->mem_total_data_len -= hlen;
            buf_ptr->data_len -= hlen;

            /* One other thing that must be checked since the user created
               the IP header is the ID field of the header. If the application
               set this field to zero it means that we must generate the
               ID here. */
            if ( (GET16(ip_dgram, IP_IDENT_OFFSET)) == 0)

                /* Set the IP packet ID. */
                PUT16(ip_dgram, IP_IDENT_OFFSET, (UINT16)IP_Ident++);

            /* Increment the number of IP packets transmitted. NOTE: this does
               not include packets that are being forwarded. */
            SNMP_ipOutRequests_Inc;

        }
        else
#endif
        {
           hlen = (INT16)((GET8(ip_dgram, IP_VERSIONANDHDRLEN_OFFSET) & 0xf) << 2);
           buf_ptr->mem_total_data_len = GET16(ip_dgram, IP_TLEN_OFFSET) - hlen;
        }
    }
    else
    {
        /* Set the IP header length and the IP version. */
        PUT8(ip_dgram, IP_VERSIONANDHDRLEN_OFFSET, 
              (UINT8)((hlen >> 2) | (IP_VERSION << 4)) );
 
        /* Zero out the fragment field */
        PUT16(ip_dgram, IP_FRAGS_OFFSET, 0);

        /* Set the IP packet ID. */
        PUT16(ip_dgram, IP_IDENT_OFFSET, (UINT16)IP_Ident++);

        /* Set the type of service. */
        PUT8(ip_dgram, IP_SERVICE_OFFSET, (UINT8)tos);

        /* Set the total length (data and IP header) of this packet. */
        PUT16(ip_dgram, IP_TLEN_OFFSET, (INT16)(buf_ptr->mem_total_data_len + hlen));

        /* Set the time to live */
        PUT8(ip_dgram, IP_TTL_OFFSET, (UINT8)ttl);
        
        /* Set the protocol. */
        PUT8(ip_dgram, IP_PROTOCOL_OFFSET, (UINT8)protocol);
        
        /* Set the destination IP address. */
        PUT32(ip_dgram, IP_DEST_OFFSET, dest_ip);


        /* Increment the number of IP packets transmitted. NOTE: this does
           not include packets that are being forwarded. */
        SNMP_ipOutRequests_Inc;
    }

    /* Update the length and data ptr for the head buffer. */
    buf_ptr->data_len           += hlen;
    buf_ptr->mem_total_data_len += hlen;
    buf_ptr->data_ptr           =  (UINT8 *)ip_dgram;

    
    /* If a route was not provided then point to the temporary
       route structure. */
    if (ro == NU_NULL)
    {
        ro = &iproute;
        UTL_Zero((CHAR *)ro, sizeof(*ro));
    }

    /* Point to the destination. */
    dest = &ro->rt_ip_dest;

    /* Check to see if there is a cached route.  If so verify that it is too the
       same destination and that it is still up. If it not free it and try
       again.
    */

    if  (ro->rt_route && ( (((ro->rt_route->rt_flags & RT_UP) == 0) || 
        (dest->sck_addr != dest_ip)) || 
        ((!(ro->rt_route->rt_device->dev_flags & DV_RUNNING)) &&
        (!(ro->rt_route->rt_device->dev_flags & DV_UP)))))
    {
        RTAB_Free(ro->rt_route);        
        ro->rt_route = NU_NULL;
    }

    if (ro->rt_route == NU_NULL)
    {        
        dest->sck_family = SK_FAM_IP;
        dest->sck_len = sizeof (*dest);
        dest->sck_addr = dest_ip;
    }

    /* NOTE:  Bypassing routing is not necessary yet, but may be supported in 
       future releases. */
#ifdef NOT_SUPPORTED
    /* Check to see if the caller specified that routing should be bypassed. */
    if (flags & IP_ROUTETOIF)
    {

    }
    else
#endif /* NOT_SUPPORTED */
    {
        if (ro->rt_route == NU_NULL)            
            IP_Find_Route(ro);

        if (ro->rt_route == NU_NULL)
        {
            /* Return host unreachable error.  The only resource allocated in
               this function is a route, but we failed to find the route so it
               is safe to return here.
            */

            /* Increment the number of packets that could not be delivered
               because a route could not be found. */
            SNMP_ipOutNoRoutes_Inc;
            return (NU_HOST_UNREACHABLE);
        }

        int_face = ro->rt_route->rt_device;
        ro->rt_route->rt_use++;

        /* If the next hop is a gateway then set the destination ip address to
           the gateway. */
        if (ro->rt_route->rt_flags & RT_GATEWAY)
            dest = &ro->rt_route->rt_gateway;
    }

    /* Is this packet destined for a multicast address */
    if (IP_MULTICAST_ADDR(GET32(ip_dgram, IP_DEST_OFFSET)))
    {
#if INCLUDE_IP_MULTICASTING

        /* Mark this buffer as containing a multicast packet. */
        buf_ptr->mem_flags |= NET_MCAST;

        /* IP destination address is multicast. Make sure "dest" still points 
           to the address in "ro". It may have been changed to point to a 
           gateway address above
        */
        dest = &ro->rt_ip_dest;
    
        /* Did the caller provide any multicast options. */    
        if (mopt != NU_NULL)
        {
            /* Use the options provided by the caller. */
            PUT8(ip_dgram, IP_TTL_OFFSET, (UINT8)mopt->ipo_ttl);
            if (mopt->ipo_device != NU_NULL)
                int_face = mopt->ipo_device;
        }
        else
            PUT8(ip_dgram, IP_TTL_OFFSET, (UINT8)IP_DEFAULT_MULTICAST_TTL);

        /* Confirm that the outgoing interface supports multicast. */
        if ((int_face->dev_flags & DV_MULTICAST) == 0)
        {
            SNMP_ipOutNoRoutes_Inc;

            return (NU_HOST_UNREACHABLE);
        }

        /* If a source address has not been specified then use the source 
           address of the outgoing interface. */
        if (src_ip == IP_ADDR_ANY)
        {
            PUT32(ip_dgram, IP_SRC_OFFSET, int_face->dev_addr.dev_ip_addr);
        }
        else
        {
            /* Note: this was added because when calculating the UDP */
            /* checksum this is needed                               */
           PUT32(ip_dgram, IP_SRC_OFFSET, src_ip);
        }

        /* NOTE: When multicastLoop Back and/or multicast routing are supported 
           this is where it should be done. */
#else /* !INCLUDE_IP_MULTICASTING */
    
        /* If multicasting support was not desired then return an error. */
        SNMP_ipOutNoRoutes_Inc;

        return (NU_HOST_UNREACHABLE);

#endif /* INCLUDE_IP_MULTICASTING */

    }
    else
    {
        /* Has a source address been specified?  If not use the address of the
           outgoing interface.  In the current release the source address will
           probably always be known at this point.  */
        if (src_ip != IP_ADDR_ANY)
            PUT32(ip_dgram, IP_SRC_OFFSET, src_ip);
        else
            PUT32(ip_dgram, IP_SRC_OFFSET, int_face->dev_addr.dev_ip_addr);

        /* Check for broadcast destination address. If this is a broadcast make 
           sure the interface supports broadcasting and that the caller enabled 
           broadcasting.
        */
        if (IP_Broadcast_Addr(dest_ip, int_face))
        {
            /* Does the interface support broadcasting. */
            if ( (int_face->dev_flags & DV_BROADCAST) == 0)
                return (NU_ACCESS);
        
            /* Did the caller enable broadcasting. */
            if ( (flags  & IP_ALLOWBROADCAST) == 0)
                return (NU_ACCESS);

            /* Inform the MAC layer to send this as a link-level broadcast. */
            buf_ptr->mem_flags |= NET_BCAST;
        }
        else
            /* Make sure the broadcast flag is clear. */
            buf_ptr->mem_flags &= ~NET_BCAST;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -