ip.c
来自「mcf5307实验源代码」· C语言 代码 · 共 827 行 · 第 1/3 页
C
827 行
/*************************************************************************/
/* */
/* CopyrIght (c) 1993 - 1996 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 3.2 */
/* */
/* DESCRIPTION */
/* */
/* IP level routines, including ICMP */
/* also includes a basic version of UDP, not generalized yet */
/* */
/* AUTHOR */
/* */
/* */
/* DATA STRUCTURES */
/* */
/* global compenent data stuctures defined in this file */
/* */
/* FUNCTIONS */
/* */
/* ipinterpret */
/* icmpinterpret */
/* neticmpturn */
/* ipchecklen */
/* found_friend */
/* first_frag */
/* ip_reassembly */
/* */
/* DEPENDENCIES */
/* */
/* No other file dependencies */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Maiqi Qian 12/06/96 Fixed the time wrap around (spr0229) */
/* Maiqi Qian 04/10/97 Added SNMP control */
/* */
/******************************************************************************/
#include "protocol.h"
#include "socketd.h"
#include "externs.h"
#include "data.h"
#include "target.h"
#include "tcp.h"
#include "tcp_errs.h"
#include "netevent.h"
#include "ip.h"
#if SNMP_INCLUDED
#include "snmp_g.h"
#endif
extern sint SQwait;
extern sint OKpackets;
static int16 neticmpturn(ICMPKT *, uint16);
static int16 icmpinterpret(ICMPKT *, uint16);
uint16 ipchecklen (int8 *, uint16);
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* ipchecklen */
/* */
/* DESCRIPTION */
/* */
/* Return IP checksum */
/* */
/* CALLS */
/* */
/* ipcheck */
/* */
/*************************************************************************/
uint16 ipchecklen (int8 *s, uint16 len)
{
if((len == 0) || (len > 2048))
{
return (0xDEAD); /* bad checksum, trust me! */
} /* end if */
return ipcheck ((uint16 *)s, len);
} /* end ipchecklen() */
/****************************************************************************/
/* */
/* FUNCTION */
/* */
/* ipinterpret */
/* */
/* 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. */
/* */
/* CALLED BY */
/* demux */
/* */
/* CALLS */
/* */
/* intswap */
/* ipcheck */
/* udpinterpret */
/* TCP_Interpret */
/* icmpinterpret */
/* dll_update_lists */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 03/15/96 Fixed the check for broadcast addrs. */
/* */
/****************************************************************************/
int16 ipinterpret (IPKT *p)
{
uint16 iplen;
uint16 hlen;
uint16 our_net;
int16 i;
/* Increment SNMP ipInReceives. This value counts all packets received.
Even those that have errors. */
SNMP_ipInReceives_Inc;
/*
* Extract total length of packet
*/
iplen = intswap (p->i.tlen);
hlen = (p->i.versionandhdrlen & 0x0f) << 2;
if ((hlen < sizeof(p->i)) /* Header too small */
|| (iplen < hlen) /* Header inconsistent */
|| (iplen > 2048)) /* WAY too big */
{
NU_Tcp_Log_Error (TCP_BAD_IP_CKSUM, TCP_RECOVERABLE,
__FILE__, __LINE__);
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
/* Increment the number of IP packets received with header errors. */
SNMP_ipInHdrErrors_Inc;
return (1); /* drop packet */
} /* end if */
/* Check for a fragmented packet. The first test will detect the first and
middle fragments because the more flag is set. The second test will
detect the last and middle fragments because an offset is specified in
the frags field. */
/* The IP defragmentation code has never been verified to work. So for now
assume they can't be handled and drop any fragmented packets. */
#ifndef IP_FRAG
if ((intswap(p->i.frags) & 0x2000) || (intswap(p->i.frags) & 0x1fff) )
{
/* Drop the current buffer. */
dll_update_lists(&buffer_list, &buffer_freelist);
return(1);
}
#else /* IP_FRAG */
if ((intswap(p->i.frags) & 0x2000) || (intswap(p->i.frags) & 0x1fff) )
{
/* Process this fragment. */
p = ip_reassembly(p, iplen);
/* Has a complete packet been assembled. */
if(p == NU_NULL)
{
/* Drop the current buffer. */
dll_update_lists(&buffer_list, &buffer_freelist);
return(1);
}
}
#endif /* IP_FRAG */
/*
* checksum verification of IP header
*/
if (ipchecklen ((int8 *)&p->i.versionandhdrlen,
(uint16)((p->i.versionandhdrlen & 0x0f) << 1)))
{
NU_Tcp_Log_Error (TCP_BAD_IP_CKSUM, TCP_RECOVERABLE,
__FILE__, __LINE__);
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
/* Increment the number of IP packets received with header errors. */
SNMP_ipInHdrErrors_Inc;
return(1); /* drop packet */
}
/* silently toss this legal-but-useless packet */
if (iplen <= hlen)
{
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
/* Increment the number of IP packets received with header errors. */
SNMP_ipInHdrErrors_Inc;
return (1);
}
/*
* See if there are any IP options to be handled.
* We don't understand IP options, post a warning to the user and drop
* the packet.
*/
/* check for options in packet */
if (hlen > sizeof (p->i))
{
NU_Tcp_Log_Error (TCP_IP_WITH_OPTS, TCP_RECOVERABLE,
__FILE__, __LINE__);
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
/* Increment the number of IP packets received with header errors. */
SNMP_ipInHdrErrors_Inc;
return (1);
} /* end if */
iplen -= hlen;
/*
* check to make sure that the packet is for me.
* Throws out all packets which are not directed to my IP address.
*/
if (!comparen (nnipnum, p->i.ipdest, 4))
{ /* potential non-match */
/* If we have received a UDP message, then perform special processing
to determine if we want to process it. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?