📄 ip.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.
*
*************************************************************************/
/* Portions of this program were written by: */
/**************************************************************************
*
* part of:
* TCP/IP kernel for NCSA Telnet
* by Tim Krauskopf
*
* National Center for Supercomputing Applications
* 152 Computing Applications Building
* 605 E. Springfield Ave.
* Champaign, IL 61820
*
* Revision history:
*
* 10/87 Initial source release, Tim Krauskopf
* 2/88 typedefs of integer lengths, TK
* 5/88 clean up for 2.3 release, JKM
* 9/91 Add input sanity checking, reorder tests, Nelson B. Bolyard
*
*/
/****************************************************************************
*
* FILENAME VERSION
*
* IP.C 4.4
*
* DESCRIPTION
*
* IP level routines, including ICMP
* also includes a basic version of UDP, not generalized yet
*
* DATA STRUCTURES
*
*
* global component data stuctures defined in this file
*
* FUNCTIONS
* IP_Add_Multi
* IP_Broadcast_Addr
* IP_Canforward
* IP_Delete_Multi
* IP_Find_Route
* IP_Forward
* IP_Fragment
* IP_Free_Queue_Element
* IP_Get_Multi_Opt
* IP_Get_Net_Mask
* IP_Get_Opt
* IP_Initialize
* IP_Insert_Frag
* IP_Interpret
* IP_Lookup_Multi
* IP_Option_Copy
* IP_Reassembly
* IP_Reassembly_Event
* IP_Remove_Frag
* IP_Send
* IP_Set_Multi_Opt
* IP_Set_Opt
* IP_Set_Raw_Opt
* IP_Localaddr
*
* DEPENDENCIES
*
* No other file dependencies
*
******************************************************************************/
#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/rtab.h"
#include "net/inc/tcp.h"
#include "net/inc/nerrs.h"
#include "net/inc/netevent.h"
#include "net/inc/ip.h"
#include "net/inc/udp.h"
#include "net/inc/net.h"
#include "net/inc/icmp.h"
#include "net/inc/mem_defs.h"
#include "net/inc/igmp.h"
#include "net/inc/ipraw.h"
#if (INCLUDE_NAT == NU_TRUE)
#include "nat/inc/nat_extr.h"
#endif
#if (INCLUDE_SNMP == NU_TRUE)
#include SNMP_GLUE
#endif
/* This is the id field of outgoing IP packets. */
INT16 IP_Ident;
#if INCLUDE_IP_FORWARDING
/* This is a flag that controls the forwarding of IP packets. */
INT IP_Forwarding;
/* This flag is used to control the sending of ICMP redirect messages. */
INT IP_Sendredirects;
/* A cached IP forwarding route. */
RTAB_ROUTE IP_Forward_Rt;
#endif
#if INCLUDE_IP_REASSEMBLY
IP_QUEUE IP_Frag_Queue;
#endif
#if (INCLUDE_NAT == NU_TRUE)
INT IP_NAT_Initialize;
#endif
UINT8 IP_Brd_Cast[IP_ADDR_LEN];
UINT8 IP_Null[IP_ADDR_LEN];
/* class A mask */
const UINT8 IP_A_Mask[4] = {255,0,0,0};
/* class B mask */
const UINT8 IP_B_Mask[4] = {255,255,0,0};
/* class C mask */
const UINT8 IP_C_Mask[4] = {255,255,255,0};
/***********************************************************************
*
* FUNCTION
*
* IP_Initialize
*
* DESCRIPTION
*
* Initialize the global data associated with the IP layer.
*
* INPUTS
*
* None.
*
* OUTPUTS
*
* None.
*
*************************************************************************/
VOID IP_Initialize(VOID)
{
INT i;
/* Identification field of outgoing packets. */
IP_Ident = 1;
/* Initialize the following arrays */
for (i = 0; i < IP_ADDR_LEN; i++)
{
IP_Brd_Cast[i] = 0xff;
IP_Null[i] = 0;
}
#if INCLUDE_IP_FORWARDING
/* Enable IP Forwarding by default. */
IP_Forwarding = 1;
/* Enable the sending of ICMP redirects by default. */
IP_Sendredirects = 1;
UTL_Zero((CHAR *)&IP_Forward_Rt, sizeof(IP_Forward_Rt));
#if (INCLUDE_SNMP == NU_TRUE)
SNMP_ipForwarding(1);
#endif
#else
#if (INCLUDE_SNMP == NU_TRUE)
SNMP_ipForwarding(2);
#endif
#endif
#if INCLUDE_IP_REASSEMBLY
IP_Frag_Queue.ipq_head = NU_NULL;
IP_Frag_Queue.ipq_tail = NU_NULL;
/* Record the timeout value for ip reasembly. This is defined in Nucleus
PLUS clock ticks. So we divide by SCK_Ticks_Per_Second to get the number
of seconds. */
SNMP_ipReasmTimeout (IP_FRAG_TTL / SCK_Ticks_Per_Second);
#endif
#if (INCLUDE_NAT == NU_TRUE)
IP_NAT_Initialize = 0;
#endif
} /* end IP_Initialize */
/****************************************************************************
*
* FUNCTION
*
* IP_Interpret
*
* DESCRIPTION
*
* Called by the packet demuxer to interpret a new ip packet. Checks
* the validity of the packet (checksum, flags) and then passes it
* on to the appropriate protocol handler.
*
* INPUTS
*
* pkt
* device
* buf_ptr
*
* OUTPUTS
*
* NU_SUCCESS Successful completion.
* 1 Packet dropped.
*
****************************************************************************/
STATUS IP_Interpret (IPLAYER *pkt, DV_DEVICE_ENTRY *device, NET_BUFFER *buf_ptr)
{
UINT16 iplen;
UINT16 hlen;
UINT32 total;
DV_DEVICE_ENTRY *temp_dev;
struct pseudotcp tcp_chk;
NET_BUFFER *buf;
#if (INCLUDE_NAT == NU_TRUE)
STATUS status;
#endif
#if INCLUDE_IP_REASSEMBLY
IP_QUEUE_ELEMENT *fp;
IPLAYER *ip;
NET_BUFFER *a_buf;
#endif
#if INCLUDE_IP_MULTICASTING
IP_MULTI *ipm;
#endif
/* Increment SNMP ipInReceives. This value counts all packets received.
Even those that have errors. */
SNMP_ipInReceives_Inc;
#if ((INCLUDE_DHCP != NU_TRUE) && (INCLUDE_BOOTP != NU_TRUE))
/* If neither DHCP or BOOTP will be used to perform IP address discovery
then drop all packets until an IP address is attached to the device. */
if ( !(device->dev_flags & DV_UP) )
{
/* Drop the packet by placing it back on the buffer_freelist. */
MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
SNMP_ipInDiscards_Inc;
return (NU_SUCCESS);
}
#endif /* ((INCLUDE_DHCP == NU_TRUE) || (INCLUDE_BOOTP == NU_TRUE)) */
/* Extract total length of packet. */
buf_ptr->mem_total_data_len = iplen = GET16(pkt, IP_TLEN_OFFSET);
/* Check to see if the total data length is less than the sum of the data
lengths the buffers in the chain. This at first sounds impossible. However
data_len comes from the size reported by the driver. It is not unusual to
receive a packet that has been padded. The dirver does not distinguish
between real data and padded data. However, the IP header contains the
true data length. We want to use the smaller value.
*/
for ( buf = buf_ptr, total = buf->mem_total_data_len;
buf;
buf = buf->next_buffer)
{
if (buf->data_len > total)
buf->data_len = total;
total -= buf->data_len;
}
hlen = (UINT16)((GET8(pkt, IP_VERSIONANDHDRLEN_OFFSET) & 0x0f) << 2);
if ((hlen < sizeof(IPLAYER)) /* Header too small */
|| (iplen < hlen) /* Header inconsistent */
|| (iplen > 2048)) /* WAY too big */
{
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 IP packets received with header errors. */
SNMP_ipInHdrErrors_Inc;
return (1); /* drop packet */
} /* end if */
/* checksum verification of IP header */
if (TLS_IP_Check ((UINT16 *)pkt,
(UINT16)((GET8(pkt, IP_VERSIONANDHDRLEN_OFFSET) & 0x0f) << 1)))
{
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 IP packets received with header errors. */
SNMP_ipInHdrErrors_Inc;
return(1); /* drop packet */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -