⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/*************************************************************************
*                                                                       
*     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/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.C                                            4.4                      
*                                                                                 
*   DESCRIPTION                                                           
*                                                                         
*       TCP level routines                                                
*                                                                         
*   DATA STRUCTURES                                                       
*
*       int                 TCP_Backoff[MAX_RETRANSMITS + 1]
*       struct _TCP_Port    *TCP_Ports[TCP_MAX_PORTS]
*       INT16               tasks_waiting_to_send
*       UINT32              TCP_Ack_Timeout
*                 
*   FUNCTIONS       
*                 
*       TCP_ACK_Check  
*       TCP_ACK_It  
*       TCP_Check_FIN
*       TCP_Check_MSS  
*       TCP_Check_OOO_List                                                 
*       TCP_Cleanup    
*       TCP_Do         
*       TCP_Estab1986  
*       TCP_Find_Empty_Port                                               
*       TCP_Get_Opt
*       TCP_Interpret  
*       TCP_Make_Port  
*       TCP_OOO_Packet 
*       TCP_Reset_FIN  
*       TCP_Retransmit 
*       TCP_Send       
*       TCP_Send_ACK       
*       TCP_Set_Opt
*       TCP_Update_Headers
*       TCP_Valid_Seq                                                     
*       TCP_Xmit       
*       TCP_Xmit_Timer       
*                 
*   DEPENDENCIES    
*                 
*       nucleus.h    
*       net_extr.h
*       tcpdefs.h
*       socketd.h
*       externs.h
*       target.h
*       netevent.h
*       nerrs.h
*       tcp.h
*       arp.h
*                 
*************************************************************************/
 
#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/ip.h"
#include "net/inc/net_extr.h"
#include "net/inc/tcpdefs.h"
#include "net/inc/socketd.h"
#include "net/inc/netevent.h"
#include "net/inc/nerrs.h"
#include "net/inc/tcp.h"

#if (INCLUDE_SNMP == NU_TRUE)
#include SNMP_GLUE
#endif

/* This back off arrary is used by more than just TCP, therefore it
   needs to be complied in even when TCP is not being used. */
int TCP_Backoff[TCP_MAX_BACKOFFS + 1];


/* Should this module even be built? */
#if (INCLUDE_TCP == NU_TRUE)


/* Local Prototypes */
static  void  TCP_Check_FIN (TCP_PORT *, TCPLAYER *);
static  void  TCP_Check_MSS (TCP_PORT *, TCPLAYER *, UINT16);
static  INT16 TCP_Estab1986 (TCP_PORT *, NET_BUFFER *, UINT16, UINT16);
static  INT16 TCP_ACK_Check (TCP_PORT *, TCPLAYER *);
static  INT16 TCP_Reset_FIN (TCPLAYER *, struct pseudotcp *, INT16);
static  INT16 TCP_Do(VOID *, NET_BUFFER *, UINT16, struct pseudotcp *, INT16);
static  INT16 TCP_Find_Empty_Port (struct TASK_TABLE_STRUCT *);
static  INT TCP_Valid_Seq(INT32 seq, UINT16 dlen, INT32 expected, INT32 wsize);
VOID    TCP_Check_OOO_List(TCP_PORT *);
VOID    TCP_Xmit_Timer(TCP_PORT *, UINT32);
INT16   TCP_OOO_Packet(TCP_PORT *, INT32);

extern NU_TASK           NU_EventsDispatcher_ptr;
extern NU_TASK           timer_task_ptr;

/*
 * Define the TCP_Ports table.  This is a critical structure in Nucleus NET
 * as it maintains information about all open connections.
 */
struct _TCP_Port    *TCP_Ports[TCP_MAX_PORTS];

/* A global counter of the number of tasks waiting for buffers to be freed
 * so that data can be sent via TCP.  Initialized in tcpinit. */
INT16 tasks_waiting_to_send;

/* This is the number of ticks to delay sending an ACK.  A value of
   approximately a 1/5 of a second (200ms) is recommended. This variable will
   be initialized by the TCP init routine in PROTINIT.C. */
UINT32 TCP_ACK_Timeout;

/*************************************************************************
*                                                                       
*   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          
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *buf_ptr                                                          
*       *tcp_chk                                                          
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       INT16                   0, 1, or 2                               
*                                                                       
*************************************************************************/
INT16 TCP_Interpret (NET_BUFFER *buf_ptr, struct pseudotcp *tcp_chk)
{
    TCP_PORT    *prt;
    UINT16      i, myport, hlen, hisport;
    TCPLAYER    *p;
    INT         socketd;

    /* Increment the number of TCP segments received. */
    SNMP_tcpInSegs_Inc;

    /* Grab a pointer to the tcp layer */
    p = (TCPLAYER *)buf_ptr->data_ptr;

    /*
    *  checksum
    *    First, fill the pseudo header with its fields, then run our
    *  checksum to confirm it.
    *
    */
    if(GET16(p, TCP_CHECK_OFFSET))
    {
        /* compute the checksum */
        if (TLS_TCP_Check( (UINT16 *) tcp_chk, 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 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 = GET16(p, TCP_DEST_OFFSET);
    hisport = GET16(p, TCP_SRC_OFFSET);

    /* bytes offset to data */
    hlen = (UINT16)(GET8(p, TCP_HLEN_OFFSET) >> 2);

    /* Set the option len for this packet. */
    buf_ptr->mem_option_len = (UINT16)(hlen - sizeof (TCPLAYER));

    for (i = 0; i < TCP_MAX_PORTS; i++)
    {
        prt=TCP_Ports[i];
        if((prt != NU_NULL) && (prt->in.port == myport) &&
           (prt->out.port == hisport) &&
             (prt->tcp_faddr == LONGSWAP(tcp_chk->source)) )
        {
            return (TCP_Do (prt, buf_ptr, hlen, tcp_chk, (INT16)prt->state));
        } /* end if, this is the port that we want */
    } /* end for, i < TCP_MAX_PORTS */

    /*
     *  If we got this far, then the current state is either SLISTEN or SCLOSED.
     *  First check for listeners.
     */
    if ((socketd = SCK_Check_Listeners(myport)) != -1) 
    {
        return( TCP_Do (SCK_Sockets[socketd], buf_ptr, hlen, tcp_chk, SLISTEN));
    }


    /*
    *  no matching port was found to handle this packet, reject it
    */

    /* Send a reset. */
    TCP_Reset_FIN (p, tcp_chk, (INT16)(buf_ptr->mem_total_data_len - 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. */
    MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);

    /* no error message if it is a SYN */
    if(!(GET8(p, TCP_FLAGS_OFFSET) & TSYN))
    {
        /* Increment the number of TCP packets received with errors. */
        SNMP_tcpInErrs_Inc;

        NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);
    } /* end if t.flags & TSYN */

    /* return on port matches */
    return (1);
}  /* TCP_Interpret() */

/*************************************************************************
*                                                                         
*   FUNCTION                                                              
*                                                                         
*       TCP_Do                                                            
*                                                                         
*   DESCRIPTION                                                           
*                                                                         
*       Deliver the incoming packet.                                      
*                                                                         
*   INPUTS                                                                
*                                                                         
*       *input
*       *buf_ptr                                                          
*       hlen                                                              
*       *tcp_chk                                                          
*       state                                                             
*                                                                         
*   OUTPUTS                                                               
*                                                                         
*       INT16                   0 or 1                                    
*                                                                         
*************************************************************************/
static INT16 TCP_Do(VOID *input, NET_BUFFER *buf_ptr, UINT16 hlen,
                   struct pseudotcp *tcp_chk, INT16 state)
{
    struct TASK_TABLE_STRUCT    *task_entry;
    UINT16                      myport;
    INT                         tasklist_num; 
    INT                         portlist_num;
    TCPLAYER                    *p;
    UINT16                      tlen;
    UINT8                       flags;
    NET_BUFFER                  *nxtPkt;
    TCP_PORT                    *prt;
    SOCKET                      *listen_socket;
    SOCKET                      *new_socket;

#if (INCLUDE_SNMP == NU_TRUE)
    UINT8                       tcp_laddr[4];
    UINT8                       tcp_faddr[4];
#endif

    if (state == SLISTEN)
    {
        prt = NU_NULL;
        listen_socket = input;
    }
    else
    {
        prt = input;
        listen_socket = NU_NULL;
    }

    /* Get the total length on the packet. Including the TCP header. */
    tlen = (INT16) buf_ptr->mem_total_data_len;

    /* Get a pointer to the TCP header. */
    p = (TCPLAYER *)buf_ptr->data_ptr;

    /* Strip off the TCP header from the data sizes and data ptr. */
    buf_ptr->data_ptr           += (sizeof (TCPLAYER) + buf_ptr->mem_option_len);
    buf_ptr->data_len           -= (sizeof (TCPLAYER) + buf_ptr->mem_option_len);
    buf_ptr->mem_total_data_len -= (sizeof (TCPLAYER) + buf_ptr->mem_option_len);
    
    /*  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.  */

    flags = GET8(p, TCP_FLAGS_OFFSET);

    switch (state)
    {
    case SLISTEN:  /*  Waiting for a remote connection.  */

        /*  If a reset is received, ignore it since we have not

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -