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

📄 icmp.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/***********************************************************************
*                                                                       
*        Copyright (c) 1993 - 2001 Accelerated Technology, Inc.         
*                                                                       
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the      
* subject matter of this material.  All manufacturing, reproduction,    
* use, and sales rights pertaining to this subject matter are governed  
* by the license agreement.  The recipient of this software implicitly  
* accepts the terms of the license.                                     
*                                                                       
*************************************************************************/

/***********************************************************************
*                                                                       
* FILE NAME                                     VERSION                         
*                                                                               
*      ICMP.C                                     4.4                           
*                                                                               
* COMPONENT                                                             
*                                                                       
*      ICMP - Internet Control Message Protocol                         
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*                                                                       
* DATA STRUCTURES                                                       
*                                                                       
*      <Data Structure> - <Description>                                 
*                                                                       
* FUNCTIONS                                                             
*                                                                       
*      ICMP_Init                       Initialize the ICMP module.      
*      ICMP_Interpret                  Interprets an ICMP request.      
*      ICMP_Echo_Reply                 Echoes out a reply to the        
*                                      incoming ICMP request.           
*      ICMP_Reflect                    Send an ICMP echo response.      
*      ICMP_Send_Error                 Sends an ICMP packet.            
*      ICMP_Send_Echo_Request          Send an echo (ping) request.     
*                                                                       
* DEPENDENCIES                                                          
*                                                                       
*        ICMP.H                        Holds the defines for ICMP.      
*                                                                       
*************************************************************************/

#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/socketd.h"
#include "net/inc/nerrs.h"
#include "net/inc/netevent.h"
#include "net/inc/dev.h"
#include "net/inc/ip.h"
#include "net/inc/tcp.h"
#include "net/inc/net.h"
#include "net/inc/icmp.h"

#if (INCLUDE_SNMP == NU_TRUE)
#include SNMP_GLUE
#endif

/* This list will contain information needed to send pings. It is used
   to determine if reply is for a ping that we sent. */
ICMP_ECHO_LIST  ICMP_Echo_List;

/* This will be used for generating a sequence number when sending ICMP
   echo requests (pings). */
static UINT16 ICMP_Echo_Req_Seq_Num;

/***********************************************************************
*                                                                       
*                                                                       
*       ICMP_Init                                                        
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      Initialize the ICMP module. In this case is only consists of     
* nulling the ICMP_Echo_List.                                           
*                                                                       
* INPUTS                                                                
*                                                                       
*      none                                                             
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      none                                                             
*                                                                       
*************************************************************************/
VOID ICMP_Init (VOID)
{
    /* Null the head and tail pointers of the echo list. */
    ICMP_Echo_List.icmp_head = NU_NULL;
    ICMP_Echo_List.icmp_tail = NU_NULL;

    /* Start the sequence number at zero. */
    ICMP_Echo_Req_Seq_Num = 0;
}

/***********************************************************************
*                                                                       
*                                                                       
*      ICMP_Interpret                                                   
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      Process received ICMP datagrams.                                 
*                                                                       
* INPUTS                                                                
*                                                                       
*      buf_ptr                                                          
*      ip_source                                                        
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      0                               Success                          
*      -1                              Failure                          
*                                                                       
*************************************************************************/
STATUS ICMP_Interpret (NET_BUFFER *buf_ptr, UINT32 ip_source)
{
    ICMP_ECHO_LIST_ENTRY    *echo_entry;
    ICMP_LAYER              *icp;
    INT                     i;
    UINT32                  src, dst, gateway;

#if (INCLUDE_TCP == NU_TRUE)

    UINT8                   hlen;
    TCP_PORT                *prt;
    UINT16                  dest_port, src_port;

#endif /* INCLUDE_TCP == NU_TRUE */


    icp = (ICMP_LAYER *)(buf_ptr->data_ptr);

    /* Increment the total number of ICMP messages received. */
    SNMP_icmpInMsgs_Inc;

    i = GET8(icp, ICMP_TYPE_OFFSET);

    if (GET16(icp, ICMP_CKSUM_OFFSET))
    {        /* ignore if chksum=0 */
        if (TLS_IP_Check_Buffer_Chain (buf_ptr))
        {
            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 ICMP messages received with errors. */
            SNMP_icmpInErrors_Inc;

            return (-1);
        } /* end if */
    } /* end if */

    switch(i)
    {
        case ICMP_ECHO:                    /* ping request sent to me */

            /* Increment the number of Echo requests received. */
            SNMP_icmpInEchos_Inc;

            PUT8(icp, ICMP_TYPE_OFFSET, 0);           /* echo reply type */

            /* Remove the buffer from the buffer list. The buffer will be
               reused, it will be sent back as a echo reply. */
            MEM_Buffer_Dequeue (&MEM_Buffer_List);

            ICMP_Echo_Reply (buf_ptr);     /* send back */

            /* Increment the number of Echo replies sent. */
            SNMP_icmpOutEchoReps_Inc;


            break;

        case ICMP_ECHOREPLY:                /* ping reply requested by me */

            /* Increment the number of Echo Replies received. */
            SNMP_icmpInEchoReps_Inc;

            /* Search the list looking for a matcing ID and seq num. */
            for (echo_entry = ICMP_Echo_List.icmp_head;
                (echo_entry) && (!((GET16(icp, ICMP_ID_OFFSET) == ICMP_ECHO_REQ_ID)
                && (GET16(icp, ICMP_SEQ_OFFSET) == echo_entry->icmp_echo_seq_num)));
                echo_entry = echo_entry->icmp_next);

            /* If an entry was found mark the status as success, resume
               the requesting task, and unset the timeout timer. */
            if (echo_entry)
            {
                /* set status as success */
                echo_entry->icmp_echo_status = NU_SUCCESS;

                /* unset the timeout timer. */
                UTL_Timerunset (ICMP_ECHO_TIMEOUT, (UNSIGNED) echo_entry, 1);

                /* resume the task */
                NU_Resume_Task (echo_entry->icmp_requesting_task);
            }

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

            break;

        case ICMP_REDIRECT:

            dst = GET32(icp, ICMP_IP_OFFSET + IP_DEST_OFFSET);
            gateway = GET32(icp, ICMP_GWADDR_OFFSET);
            src = ip_source;

            RTAB_Redirect(dst, gateway, RT_GATEWAY | RT_HOST, src);

            /* 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 Redirect messages received. */
            SNMP_icmpInRedirects_Inc;

            break;

        case ICMP_SOURCEQUENCH:
            
            /* 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 Source Quench messages received. */
            SNMP_icmpInSrcQuenchs_Inc;

             break;

        case ICMP_UNREACH:

#if (INCLUDE_TCP == NU_TRUE)

            hlen = (UINT8)((GET8(&(icp->icmp_dun.id_ip), IP_VERSIONANDHDRLEN_OFFSET) 
                            & 0x0f) << 2);

            /* Get the destination and source port from the ICMP message */
            dest_port = GET16(&(icp->icmp_dun.id_ip) + hlen, TCP_DEST_OFFSET);
            src_port = GET16(&(icp->icmp_dun.id_ip) + hlen, TCP_SRC_OFFSET);

            src = GET32(&(icp->icmp_dun.id_ip), IP_SRC_OFFSET);
            dst = GET32(&(icp->icmp_dun.id_ip), IP_DEST_OFFSET);

            /* Seach through the TCP_Ports for the port matching our
             * source & destination port and ip address */
            for (i = 0; i < TCP_MAX_PORTS; i++)
            {
                prt = TCP_Ports[i];

⌨️ 快捷键说明

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