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

📄 ip.c

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

/************************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      IP_Option_Copy                                                   
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*                                                                       
*                                                                       
* INPUTS                                                                
*                                                                       
*      dip         destination IP packet header                         
*      sip         source IP packet header                              
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      INT         The length of the option data copied.                
*                                                                       
*************************************************************************/
INT IP_Option_Copy (IPLAYER *dip, IPLAYER *sip)
{
    UINT8       *src, *dest;
    INT         cnt, opt, optlen;

    /* Point to the first byte of option data in each of the IP packets. */
    src = (UINT8 *) (sip + 1);
    dest = (UINT8 *) (dip + 1);

    cnt = ((GET8(sip, IP_VERSIONANDHDRLEN_OFFSET) & 0x0f)  << 2) - sizeof(IPLAYER);

    for (; cnt > 0; cnt -= optlen, src += optlen)
    {
        opt = src[0];

        /* Stop when the EOL option is encountered. */
        if (opt == IP_OPT_EOL)
            break;
        
        /* Copy NOPs to preserve alignment constraints. */
        if (opt == IP_OPT_NOP)
        {
            *dest++ = IP_OPT_NOP;
            optlen = 1;
            continue;
        }
        else
            optlen = src[IP_OPT_OLEN];

        /* Truncate an option length that is too large. This should not occur. */
        if (optlen > cnt)
            optlen = cnt;

        /* If the copied bit is set then copy the option. */
        if (IP_OPT_COPIED(opt))
        {
            memcpy(dest, src, (unsigned int)optlen);
            dest += optlen;
        }
    }

    /* Pad the option list, if necessary, out to a 4-byte boundary. */
    for (optlen = (INT)(dest - (UINT8 *)(dip + 1)); optlen & 0x3; optlen++)
    *dest++ = IP_OPT_EOL;

    return (optlen);

} /* IP_Option_Copy */

#endif /* INCLUDE_IP_FRAGMENT */

/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      IP_Broadcast_Addr                                                
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      This function checks an IP address to see if it is a broadcast   
*      address.                                                         
*                                                                       
* INPUTS                                                                
*                                                                       
*      dest        The IP address to be checked.                        
*      int_face    Pointer to the interface the IP address is being     
*                     used on.                                          
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      1          This is a broadcast address.                          
*      0          This is not a broadcast address.                      
*                                                                       
*************************************************************************/
INT IP_Broadcast_Addr(UINT32 dest, DV_DEVICE_ENTRY *int_face)
{
    if ( (dest == IP_ADDR_ANY) || (dest == IP_ADDR_BROADCAST) )
    return 1;

    if ( (int_face->dev_flags & DV_BROADCAST) == 0)
        return 0;

    if ( (int_face->dev_addr.dev_net == dest) ||
     (int_face->dev_addr.dev_net_brdcast == dest) )
        return 1;

    return 0;
} /* IP_Broadcast_Addr */

/* Check to see if the route is still valid. */

/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      IP_Find_Route                                                    
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      This function checks to see if a route is still valid. If the    
*      route is not valid or if a route has never been allocated. A new 
*      route is found.                                                  
*                                                                       
* INPUTS                                                                
*                                                                       
*      ro                                                               
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      None.                                                            
*                                                                       
*************************************************************************/
VOID IP_Find_Route(RTAB_ROUTE *ro)
{
    if ( ro->rt_route && ro->rt_route->rt_device &&
     (ro->rt_route->rt_flags & RT_UP) )
        return;

    ro->rt_route = RTAB_Find_Route(&ro->rt_ip_dest);
} /* IP_Find_Route */

#if INCLUDE_IP_FORWARDING

/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      IP_Forward                                                       
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      This function checks attempts to forward an IP packet out of     
*      one of the network interfaces.                                   
*                                                                       
* INPUTS                                                                
*                                                                       
*      buf_ptr     A buffer containing the datagram to forward.         
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      NU_SUCCESS                                                       
*      NU_INVALID_ADDRESS                                               
*      NU_HOST_UNREACHABLE                                              
*      -1                      Packet not forwarded.                    
*                                                                       
*************************************************************************/
STATUS IP_Forward(NET_BUFFER *buf_ptr)
{
    SCK_SOCKADDR_IP     *sin;
    ROUTE_NODE          *rt;
    DEV_IF_ADDRESS      *d_addr;
    UINT32              src, dest;
    INT                 type, code;
    STATUS              stat;
    IPLAYER             *ip_pkt;
    INT                 hlen;


    /* Initialize local variables. */
    dest = 0;
    ip_pkt = (IPLAYER *)buf_ptr->data_ptr;

    if ( (buf_ptr->mem_flags & NET_BCAST) ||
         IP_Canforward(GET32(ip_pkt, IP_DEST_OFFSET)) != NU_SUCCESS)
    {
        /* Deallocate the buffer. */
        MEM_One_Buffer_Chain_Free (buf_ptr,buf_ptr->mem_dlist);

        /* Increment the number of IP packets received with the wrong IP addr.*/
        SNMP_ipInAddrErrors_Inc;

        return (NU_INVALID_ADDRESS);
    }

    /* Check the time to live field. */
    if (GET8(ip_pkt, IP_TTL_OFFSET) <=  1)
    {
        ICMP_Send_Error(buf_ptr, ICMP_TIMXCEED, ICMP_TIMXCEED_TTL, 0,
                buf_ptr->mem_buf_device);

        /* Deallocate the buffer. */
        MEM_One_Buffer_Chain_Free (buf_ptr,buf_ptr->mem_dlist);

        return -1;
    }

    /* Decrement the time to live. */
    PUT8(ip_pkt, IP_TTL_OFFSET, (UINT8)(GET8(ip_pkt, IP_TTL_OFFSET) - 1));

    /* Increment the number of packets that we attempted to find a route
       and forward. */
    SNMP_ipForwDatagrams_Inc;

    sin = (SCK_SOCKADDR_IP *) &IP_Forward_Rt.rt_ip_dest;

    /* Check to see if the cached route is still valid. */
    if ( ((rt = IP_Forward_Rt.rt_route) == 0) ||
         (GET32(ip_pkt, IP_DEST_OFFSET) != sin->sck_addr) )
    {
        /* We can not used the cached route.  If there is one then free it. */
        if (IP_Forward_Rt.rt_route)
        {
            RTAB_Free(IP_Forward_Rt.rt_route);
            IP_Forward_Rt.rt_route = NU_NULL;
        }

        sin->sck_family = SK_FAM_IP;
        sin->sck_len = sizeof (*sin);
        sin->sck_addr = GET32(ip_pkt, IP_DEST_OFFSET);

        IP_Find_Route(&IP_Forward_Rt);

        /* Was a route found. */
        if (IP_Forward_Rt.rt_route == 0)
        {
            /* Send ICMP host unreachable message. */
            ICMP_Send_Error(buf_ptr, ICMP_UNREACH, ICMP_UNREACH_HOST, 0,
                    buf_ptr->mem_buf_device);

            /* Deallocate the buffer. */
            MEM_One_Buffer_Chain_Free (buf_ptr,buf_ptr->mem_dlist);

            /* Increment the number of packets that could not be delivered
               because a route could not be found. */
            SNMP_ipOutNoRoutes_Inc;

            return (NU_HOST_UNREACHABLE);
        }

        rt = IP_Forward_Rt.rt_route;
    }

    if ( (rt->rt_device == buf_ptr->mem_buf_device) &&
     ((rt->rt_flags & (RT_DYNAMIC | RT_MODIFIED)) == 00) &&
     (*(UINT32 *)rt->rt_rip2->ip_addr != 0) && IP_Sendredirects )
    {
        src = GET32(ip_pkt, IP_SRC_OFFSET);
        d_addr = &rt->rt_device->dev_addr;

        if ( (src & d_addr->dev_netmask) == d_addr->dev_net)
        {
            if (rt->rt_flags & RT_GATEWAY)
                dest = *(UINT32 *)rt->rt_gateway.sck_addr;
            else
                dest = GET32(ip_pkt, IP_DEST_OFFSET);

            type = ICMP_REDIRECT;
            code = ICMP_REDIRECT_HOST;
            /* Send ICMP host unreachable message. */
            ICMP_Send_Error(buf_ptr, type, code, dest, buf_ptr->mem_buf_device);

        }
    }

    /* IP send expects the data pointer to point at the IP data not at the IP
       header. So move the pointer forward. */
    hlen = (GET8(ip_pkt, IP_VERSIONANDHDRLEN_OFFSET) & 0x0f) << 2;
    buf_ptr->data_ptr += hlen;
    buf_ptr->data_len -= hlen;

    /* Forward the packet.  Because this is a forward many of the parameters are
       not required.  Specifically the length, the ttl, the protocol, and tos.
       NU_NULL is used for all of those parameters that will not be needed.
    */
    stat = IP_Send( buf_ptr, &IP_Forward_Rt, GET32(ip_pkt, IP_DEST_OFFSET), 
            GET32(ip_pkt, IP_SRC_OFFSET), IP_FORWARDING | IP_ALLOWBROADCAST, 
            NU_NULL, NU_NULL, NU_NULL, NU_NULL);

    if (stat != NU_SUCCESS)
    {
        if (stat == NU_HOST_UNREACHABLE)
        {
            type = ICMP_UNREACH;
            code = ICMP_UNREACH_HOST;
            
            /* Send ICMP host unreachable message. */
            ICMP_Send_Error(buf_ptr, type, code, dest, buf_ptr->mem_buf_device);
        }

        MEM_One_Buffer_Chain_Free (buf_ptr, buf_ptr->mem_dlist);

         /* Increment the number of IP packets received with the wrong IP addr.*/
        SNMP_ipInAddrErrors_Inc;
    }

    return (stat);

} /* IP_Forward */
#endif

/************************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      IP_Canforward                                                    
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      This function decides if an attempt should be made to forward    
*      an IP datagram.                                                  
*                                                                       
* INPUTS                                                                
*                                                                       
*      dest        

⌨️ 快捷键说明

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