📄 icmp.c
字号:
/***********************************************************************
*
* 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 + -