tcp.c
来自「mcf5307实验源代码」· C语言 代码 · 共 1,562 行 · 第 1/5 页
C
1,562 行
/*************************************************************************/
/* */
/* 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/UDP/ICMP/IP Network kernel for NCSA Telnet *
* by Tim Krauskopf *
* *
* National Center for Supercomputing Applications *
* 152 Computing Applications Building *
* 605 E. Springfield Ave. *
* Champaign, IL 61820 *
*
*/
/******************************************************************************/
/* */
/* FILENAME VERSION */
/* */
/* TCP 3.2 */
/* */
/* DESCRIPTION */
/* */
/* TCP level routines */
/* */
/* AUTHOR */
/* */
/* */
/* DATA STRUCTURES */
/* */
/* */
/* FUNCTIONS */
/* */
/* TCP_Interpret */
/* tcpdo */
/* checkmss */
/* tcpresetfin */
/* tcpsend */
/* ackcheck */
/* estab1986 */
/* checkfin */
/* tcp_xmit */
/* tcp_retransmit */
/* tcp_ooo_packet */
/* check_ooo_list */
/* NU_FindEmptyPort */
/* */
/* */
/* DEPENDENCIES */
/* */
/* No other file dependencies */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 04/30/96 Made some changes based on recommedations */
/* of K. Goto of Hitachi. */
/* Maiqi Qian 12/06/96 Fixed the time wrap up (spr0229) */
/* Maiqi Qian 12/11/96 Modified tcpsend() and tcp_retransmit(). */
/* */
/******************************************************************************/
#ifdef PLUS
#include "nucleus.h"
#endif
#include "protocol.h"
#include "tcpdefs.h"
#include "socketd.h"
#include "externs.h"
#include "data.h"
#include "target.h"
#include "sockext.h"
#include "netevent.h"
#include "tcp_errs.h"
#include "tcp.h"
#if SNMP_INCLUDED
#include "snmp_g.h"
#endif
/* Local Prototypes */
static void checkfin (struct port *, TCPKT *);
static int16 estab1986 (struct port *, TCPKT *, uint16, uint16);
static int16 ackcheck (struct port *, TCPKT *);
static void checkmss (struct port *, TCPKT *, uint16);
static int16 tcpresetfin (TCPKT *, uint16);
static int16 tcpdo (struct port *, TCPKT *, uint16 , uint16, int16);
static int16 NU_FindEmptyPort (struct TASK_TABLE_STRUCT *);
int16 checkListeners(int16);
/*
* Semi-Global Vars
*/
static uint16 pnum; /* port number */
// following for debug only.
extern unsigned short syntimes;
extern unsigned short syntimes_add;
char buffer[40];
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* TCP_Interpret */
/* */
/* DESCRIPTION */
/* */
/* Called when a packet comes in and passes the IP checksum and is */
/* of TCP protocol type. Check to see if we have an open connection */
/* on the appropriate port and stuff it in the right buffer */
/* */
/* CALLED BY */
/* ipinterpret */
/* */
/* CALLS */
/* */
/* intswap */
/* tcpcheck */
/* netlisten */
/* tcpresetfin */
/* dll_update_lists */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* G. Johnson 10-12-1995 Modified so hosts with different */
/* IP's but same port #'s could be */
/* distinguished. */
/* */
/*************************************************************************/
int16 TCP_Interpret (TCPKT *p, uint16 tlen)
{
struct port *prt;
uint16 *temp_tcp;
uint16 i, myport, hlen, hisport;
/* Increment the number of TCP segments received. */
SNMP_tcpInSegs_Inc;
/* NFH - We need to add the padding back in so that the TCP-Packet
will be interpreted properly. */
temp_tcp = (uint16 *) p;
temp_tcp--;
p = (TCPKT *) temp_tcp;
/*
* checksum
* First, fill the pseudo header with its fields, then run our
* checksum to confirm it.
*
*/
if(p->t.check)
{
/* move both addresses */
memcpy ((void *)tcps.source, (const void *)p->i.ipsource, 8);
tcps.z = 0;
tcps.proto = p->i.protocol;
/* byte-swapped length */
tcps.tcplen = intswap (tlen);
/* compute the checksum */
if(tcpcheck( (uint16 *) &tcps, (uint16 *) &p->t, tlen))
{
NU_Tcp_Log_Error (TCP_BAD_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 TCP packets received with errors. */
SNMP_tcpInErrs_Inc;
return (2);
} /* end if, for compute of the checksum */
} /* end if, we need to do the checksum */
/*
* find the port which is associated with the incoming packet
* First try open connections, then try listeners
*/
myport = intswap (p->t.dest);
hisport = intswap (p->t.source);
/* bytes offset to data */
hlen = p->t.hlen >> 2;
for (i = 0; i < NPORTS; i++)
{
prt=portlist[i];
if((prt != NU_NULL) && (prt->in.port == myport) &&
(prt->out.port == hisport) &&
comparen(prt->tcpout.i.ipdest, p->i.ipsource, 4))
{
pnum = i;
return (tcpdo (prt, p, tlen, hlen, prt->state));
} /* end if, this is the port that we want */
} /* end for, i < NPORTS */
/*
* If we got this far, then the current state is either SLISTEN or SCLOSED.
* First check for listeners.
*/
// modified by Ason. (1998.8.2.)
// no need to generate checkListeners in our application.
if (checkListeners(myport) == NU_TRUE)
{
return( tcpdo (prt, p, tlen, hlen, SLISTEN));
}
/*
* no matching port was found to handle this packet, reject it
*/
/* Send a reset. */
tcpresetfin (p, (uint16)(tlen - hlen));
/* If we have reached this point, nobody processed the packet. Therefore
we need to drop it by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
/* no error message if it is a SYN */
if(!(p->t.flags&TSYN))
{
/* Increment the number of TCP packets received with errors. */
SNMP_tcpInErrs_Inc;
NU_Tcp_Log_Error (TCP_BAD_PACKET_PORT, TCP_RECOVERABLE,
__FILE__, __LINE__);
} /* end if t.flags & TSYN */
/* return on port matches */
return (1);
} /* end TCP_Interpret() */
/******************************************************************************/
/* */
/* FUNCTION */
/* */
/* tcpdo */
/* */
/* DESCRIPTION */
/* */
/* Deliver the incoming packet. */
/* */
/* CALLED BY */
/* TCP_Interpret */
/* */
/* CALLS */
/* */
/* intswap */
/* longswap */
/* tcp_sendack */
/* netputevent */
/* checkmss */
/* ackcheck */
/* estab1986 */
/* Stimerunset */
/* dll_update_lists */
/* NU_SearchTaskList */
/* */
/* NAME DATE REMARKS */
/* */
/* G. Johnson 05-24-1996 Fixed a bug in state SSYNS. */
/* */
/******************************************************************************/
static int16 tcpdo(struct port *prt, TCPKT *p, uint16 tlen, uint16 hlen,
int16 state)
{
struct TASK_TABLE_STRUCT *Task_Entry;
uint16 myport;
int16 tasklist_num, portlist_num;
unsigned char ii;
STATUS check_suc;
/* Enter the state machine. Determine the current state and perform
the appropriate function. Completed I/O will invoke this
routine and consequently advance the state. */
switch (state)
{
case SLISTEN: /* Waiting for a remote connection. */
/* If a reset is received, ignore it since we have not
yet established a connection. */
if (p->t.flags & TRESET)
{
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?