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 + -
显示快捷键?