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

📄 icmp.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* Increment the number of ICMP messages sent. */
    SNMP_icmpOutMsgs_Inc;

} /* ICMP_Reflect */

/****************************************************************************
*                                                                            
* FUNCTION                                                                   
*                                                                            
*      ICMP_Echo_Reply                                                       
*                                                                            
* DESCRIPTION                                                                
*                                                                            
*   send out an icmp packet, probably in response to a ping operation        
*   interchanges the source and destination addresses of the packet,         
*   puts in my addresses for the source and sends it                         
*                                                                            
*   does not change any of the ICMP fields, just the IP and dlayers          
*   returns 0 on okay send, nonzero on error                                 
*                                                                            
* INPUTS                                                                     
*                                                                            
*      buf_ptr                                                               
*                                                                            
* OUTPUTS                                                                    
*                                                                            
*      NU_SUCCESS              Reply sent                                    
*      -1                      Reply not sent.                               
*                                                                            
******************************************************************************/
STATUS ICMP_Echo_Reply (NET_BUFFER *buf_ptr)
{

    /* Set the deallocation list. */
    buf_ptr->mem_dlist = &MEM_Buffer_Freelist;

    /* Do not send an error in response to a broadcast packet. */
    if (buf_ptr->mem_flags & (NET_BCAST | NET_MCAST))
    {
        MEM_One_Buffer_Chain_Free (buf_ptr, buf_ptr->mem_dlist);
        return(-1);
    }

    ICMP_Reflect(buf_ptr);

    return (NU_SUCCESS);

}  /* end ICMP_Echo_Reply */

/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      ICMP_Send_Echo_Request                                           
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      Send an ICMP echo request.                                       
*                                                                       
* INPUTS                                                                
*                                                                       
*      dest_ip                                                          
*      timeout                                                          
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      NU_SUCCESS                                                       
*      NU_NO_ACTION                                                     
*      NU_MEM_ALLOC                                                     
*      NU_NO_BUFFERS                                                    
*                                                                       
*************************************************************************/
STATUS ICMP_Send_Echo_Request(UINT8 *dest_ip, UINT32 timeout)
{
    ICMP_ECHO_LIST_ENTRY        *echo_entry;
    STATUS                       ret_status;
    OPTION                       old_preempt;
    NET_BUFFER                  *buf_ptr;
    ICMP_LAYER                  *icmp_ptr;
    UINT16                       len;
    UINT8                        x, y;
    NU_SUPERV_USER_VARIABLES

    /* Grab the stack semaphore */
    NU_Obtain_Semaphore (&TCP_Resource, NU_SUSPEND);

    /* Switch to supervisor mode. */
    NU_SUPERVISOR_MODE();

    /* Allocate a buffer for the echo request (ping) */
    buf_ptr = MEM_Buffer_Dequeue (&MEM_Buffer_Freelist);

    /* Make sure we got one. */
    if (buf_ptr != NU_NULL)
    {
        /* If the timeout is zero then used the default value. */
        if (!timeout)
            timeout = ICMP_DEFAULT_ECHO_TIMEOUT;

        /* Bump the sequence number. */
        ICMP_Echo_Req_Seq_Num++;

        /* Set the data pointer to the correct location. */
        buf_ptr->data_ptr = (buf_ptr->mem_parent_packet +
                (NET_MAX_ICMP_HEADER_SIZE - sizeof (ICMP_LAYER)));

        /* Get the length of the ICMP header. */
        len = ICMP_ECHO_REQ_HEADER_SIZE;

        /* Point to the ICMP layer */
        icmp_ptr = (ICMP_LAYER *)buf_ptr->data_ptr;

        /* Set the ICMP type to echo */
        PUT8(icmp_ptr, ICMP_TYPE_OFFSET, ICMP_ECHO);

        /* Set the code to zero, always zero for echo packets */
        PUT8(icmp_ptr, ICMP_CODE_OFFSET, 0);

        /* Set the ID and sequence number fields. */
        PUT16(icmp_ptr, ICMP_ID_OFFSET, ICMP_ECHO_REQ_ID);
        PUT16(icmp_ptr, ICMP_SEQ_OFFSET, ICMP_Echo_Req_Seq_Num);

        /* Fill in the standard 32 bytes of data. */
        for (x = 0, y = 'a'; x <= 31; x++)
        {
            /* Start back at A if we get to the end of the alphabet */
            if (y > 'w')
                y = 'a';

            /* store the byte of data */
            PUT8(icmp_ptr, ICMP_DATA_OFFSET + x, y++);

            /* Bump the length */
            len++;
        }

        /* Set the length for this buffer. */
        buf_ptr->data_len = buf_ptr->mem_total_data_len = len;

        /* Set the deallocation list */
        buf_ptr->mem_dlist = &MEM_Buffer_Freelist;

        /* Compute the checksum */
        PUT16(icmp_ptr, ICMP_CKSUM_OFFSET, 0);
        PUT16(icmp_ptr, ICMP_CKSUM_OFFSET, TLS_IP_Check_Buffer_Chain (buf_ptr) );

        /* Send this packet. */
        ret_status = IP_Send(buf_ptr, NU_NULL, IP_ADDR (dest_ip),
                        NU_NULL, NU_NULL, IP_TIME_TO_LIVE, IP_ICMP_PROT,
                        0, NU_NULL);

        if (ret_status != NU_SUCCESS)
        {
            /* Release the stack semaphore */
            NU_Release_Semaphore (&TCP_Resource);
            
            /* 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);

            /* Increment the number of send errors. */
            SNMP_icmpOutErrors_Inc;

            /* Set the status to an error. */
            ret_status = NU_NO_ACTION;
        }
        else
        {
            /* Increment the number of ICMP messages sent. */
            SNMP_icmpOutMsgs_Inc;

            /* Increment the number of ICMP echos (pings) sent. */
            SNMP_icmpOutEchos_Inc;

            /* Allocate memory for the ICMP echo entry */
            ret_status = NU_Allocate_Memory (&System_Memory, (VOID **)&echo_entry,
                          sizeof (ICMP_ECHO_LIST_ENTRY), NU_NO_SUSPEND);

            /* Make sure that we got some memory */
            if (ret_status == NU_SUCCESS)
            {
                /* Fill in the echo entry structure. */
                echo_entry->icmp_requesting_task = NU_Current_Task_Pointer();
                echo_entry->icmp_echo_seq_num    = ICMP_Echo_Req_Seq_Num;

                /* Place it on the echo entry list. */
                DLL_Enqueue (&ICMP_Echo_List, echo_entry);

                /* Set an event to wake this task up if an echo reply
                   not not RX. */
                UTL_Timerset (ICMP_ECHO_TIMEOUT, (UNSIGNED) echo_entry,
                                                    timeout, NU_NULL);

                /* Change to no preemtion so that no other task can get in between the
                   time that we release the semaphore and self-suspend. */
                old_preempt = NU_Change_Preemption (NU_NO_PREEMPT);

                /* Release the stack semaphore */
                NU_Release_Semaphore (&TCP_Resource);

                /* Self-suspend waiting on the ping reply or a timeout. */
                NU_Suspend_Task (echo_entry->icmp_requesting_task);

                /* Restore the previous preemption state. */
                NU_Change_Preemption (old_preempt);

                /* Assign the status to that in the ICMP entry. It was
                   set by either the timeout or by the reception of
                   the reply. */
                ret_status = echo_entry->icmp_echo_status;

                /* Remove this entry from the echo entry list. */
                DLL_Remove (&ICMP_Echo_List, echo_entry);

                /* Deallocate the memory. */
                NU_Deallocate_Memory (echo_entry);
            }
            else
            {
                /* Release the stack semaphore */
                NU_Release_Semaphore (&TCP_Resource);
                
                /* Increment the number of send errors due to the
                   lack of memory. */
                SNMP_icmpOutErrors_Inc;

                /* Set the status to an error. */
                ret_status = NU_MEM_ALLOC;
            }
        }
    }
    else
    {
        /* Release the stack semaphore */
        NU_Release_Semaphore (&TCP_Resource);

        /* Increment the number of send errors due to the lack of buffers. */
        SNMP_icmpOutErrors_Inc;

        ret_status = NU_NO_BUFFERS;
    }

    /* Switch back to user mode. */
    NU_USER_MODE();

    return (ret_status);

} /* ICMP_Send_Echo_Reuest */

⌨️ 快捷键说明

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