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

📄 icmp.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:

                /* If this is the port we want, assign an error code */
                if((prt != NU_NULL) && (prt->in.port == src_port) &&
                   (prt->out.port == dest_port) &&
                   (prt->tcp_faddr == dst) && 
                   (prt->tcp_laddr == src))
                {
                    if (prt->icmp_error == 0)
                    {
                        /* Set the icmp_error field in the port to 1 to indicate 
                         * "No Route to Host" */
                        if ( (icp->icmp_code == 0) || (icp->icmp_code == 1) || 
                             ((icp->icmp_code >= 5) && (icp->icmp_code <= 12)) )
                            prt->icmp_error = 1;

                        /* Set the icmp_error field in the port to 2 to indicate
                         * "Connection Refused" */
                        else if ( (icp->icmp_code == 2) || (icp->icmp_code == 3) )
                            prt->icmp_error = 2;
    
                        /* Set the icmp_error field in the port to 3 to indicate
                         * "Message Too Long" */
                        else if (icp->icmp_code == 4)
                            prt->icmp_error = 3;
                    }
                    break;
                }
            } /* end for, i < TCP_MAX_PORTS */

#endif /* INCLUDE_TCP == NU_TRUE */

            /* Return the buffer back to the free buffer pool. */
            MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);

            break;

        default:

            /* 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 ICMP messages received with errors. */
            SNMP_icmpInErrors_Inc;
            break;

    } /* end switch */

    return (0);
}   /* end icmpinterpret() */

/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      ICMP_Send_Error                                                  
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      Send an ICMP packet.                                             
*                                                                       
* INPUTS                                                                
*                                                                       
*      buf_ptr                                                          
*      type                                                             
*      code                                                             
*      dest                                                             
*      device                                                           
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      None.                                                            
*                                                                       
*************************************************************************/
VOID ICMP_Send_Error(NET_BUFFER *buf_ptr, INT type, INT code, UINT32 dest,
                     DV_DEVICE_ENTRY *device)
{

    NET_BUFFER      *send_buf;
    IPLAYER         *ip_pkt;
    ICMP_LAYER      *icmp_shdr;
    UINT8           temp_buf[sizeof(IPLAYER) + 8];


    ip_pkt = (IPLAYER *)buf_ptr->data_ptr;


    /* Do not generate an ICMP error message in response to an ICMP packet,
       except for the case where we are responding to an echo request. */
    if((GET8(ip_pkt, IP_PROTOCOL_OFFSET) == IP_ICMP_PROT) && 
       ((type != (ICMP_ECHOREPLY))))
    {
       if ( type != ICMP_REDIRECT)
         return;
    }
    /* Do not send an error in response to a broadcast packet. */
    if(buf_ptr->mem_flags & (NET_BCAST | NET_MCAST))
        return;

    /* Perform aditional verification on the packet.  We want to reject the ICMP
       error for the same reasons that we refuse to forward a packet. */
    if ( IP_Canforward(GET32(ip_pkt, IP_DEST_OFFSET)) != NU_SUCCESS)
        return;


    /* Allocate a buffer to build the ICMP packet in. */
    if ((send_buf = (NET_BUFFER *)MEM_Buffer_Dequeue(&MEM_Buffer_Freelist))== NU_NULL)
    {
        NERRS_Log_Error (NERR_SEVERE, __FILE__, __LINE__);

        SNMP_icmpOutErrors_Inc;

        return;
    }

    send_buf->mem_dlist = &MEM_Buffer_Freelist;

    /* Begin filling in ICMP header. */
    /* Fill in the type. */
    icmp_shdr = (ICMP_LAYER *)(send_buf->mem_parent_packet + 
                (NET_MAX_ICMP_HEADER_SIZE - sizeof (ICMP_LAYER)));
    PUT8(icmp_shdr, ICMP_TYPE_OFFSET, (UINT8)type);

    
    if (type == ICMP_REDIRECT)
    {
        PUT32(icmp_shdr, ICMP_GWADDR_OFFSET, dest);

        SNMP_icmpOutRedirects_Inc;
    }
    else
    {
        PUT32(icmp_shdr, ICMP_VOID_OFFSET, 0);

        if (type == ICMP_PARAPROB)
        {
            PUT8(icmp_shdr, ICMP_PPTR_OFFSET, (UINT8)code);
            code = 0;

            SNMP_icmpOutParmProbs_Inc;
        }
        else if ( (type == ICMP_UNREACH) &&
                  (code == ICMP_UNREACH_NEEDFRAG && device) )
        {
            PUT16(icmp_shdr, ICMP_NEXTMTU_OFFSET, (INT16)device->dev_mtu);

            SNMP_icmpOutDestUnreachs_Inc;
        }
    }

    PUT8(icmp_shdr, ICMP_CODE_OFFSET, (UINT8)code);

    /* Copy the old IP packet into the data portion of the ICMP packet. */
    /* It would be simpler and more efficient to copy yhe data straight from the
       original IP packet to the ICMP packet. However, that will not work on 
       DSPs. Hence the two copies below. */
    GET_STRING(ip_pkt, 0, temp_buf, sizeof(IPLAYER) + 8);
    PUT_STRING(icmp_shdr, ICMP_IP_OFFSET, temp_buf, sizeof(IPLAYER) + 8);


    /* Point to where the new IP header should begin. */
    send_buf->data_ptr = (UINT8 *)icmp_shdr - sizeof(IPLAYER);


    /* Copy the IP header. */
    memcpy(send_buf->data_ptr, ip_pkt, sizeof(IPLAYER));

    send_buf->data_ptr = (UINT8 *)icmp_shdr;
    send_buf->mem_buf_device = device;

    /* The size of the data so far is the sizof(ICMP_LAYER) + 8. At first
       it might seem that 20 bytes for the IP header that is part of the
       ICMP data needs to added as well. However, that 20 bytes is included
       in ICMP_LAYER. */
    send_buf->mem_total_data_len = sizeof(ICMP_LAYER) + 8;
    send_buf->data_len = sizeof(ICMP_LAYER) + 8;

    ICMP_Reflect(send_buf);

} /* ICMP_Send_Error */

/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      ICMP_Reflect                                                     
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      Send an ICMP echo response.                                      
*                                                                       
* INPUTS                                                                
*                                                                       
*      buf_ptr                                                          
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      None.                                                            
*                                                                       
*************************************************************************/
VOID ICMP_Reflect(NET_BUFFER *buf_ptr)
{
    IPLAYER         *ip_pkt;
    UINT32          t, icmpsrc;
    DV_DEVICE_ENTRY *temp_dev;
    ICMP_LAYER      *icmp_l;
    STATUS          stat;

    /*  Point to the ICMP packet.  */
    ip_pkt = (IPLAYER *)(buf_ptr->data_ptr - sizeof (IPLAYER)); 

    /* Keep a copy of the original destination. */
    t = GET32(ip_pkt, IP_DEST_OFFSET);
    
    /* Make the source the new destination. */
    PUT32(ip_pkt, IP_DEST_OFFSET, GET32(ip_pkt, IP_SRC_OFFSET) );

    /* Set the new source address.  If an exact math can not be found then use
       the source address for the receiving interface. */
    for(temp_dev = DEV_Table.dv_head;
        temp_dev;
        temp_dev = temp_dev->dev_next)
    {
        /* Is there an exact match on the IP address. */
        if ( temp_dev->dev_addr.dev_ip_addr == t)
            break;
    }

    /* If a match was found use the IP address for that device, else use the IP
       address for the receiving device. */
    if (temp_dev)
        icmpsrc = temp_dev->dev_addr.dev_ip_addr;
    else
        icmpsrc = buf_ptr->mem_buf_device->dev_addr.dev_ip_addr;


    /* Compute the ICMP checksum. */
    icmp_l = (ICMP_LAYER *)(buf_ptr->data_ptr);

    PUT16(icmp_l, ICMP_CKSUM_OFFSET, 0);
    PUT16(icmp_l, ICMP_CKSUM_OFFSET, TLS_IP_Check_Buffer_Chain (buf_ptr));

    /* Send this packet. */
    stat = IP_Send(buf_ptr, NU_NULL, GET32(ip_pkt, IP_DEST_OFFSET),
                icmpsrc, NU_NULL, IP_TIME_TO_LIVE, IP_ICMP_PROT, 0, NU_NULL);

    if (stat != NU_SUCCESS)
    {
        /* The packet was not sent.  Dealocate the buffer.  If the packet was
           transmitted it will be deallocated when the transmit complete
           interrupt occurs. */
        MEM_One_Buffer_Chain_Free (buf_ptr, buf_ptr->mem_dlist);
    }

⌨️ 快捷键说明

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