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

📄 tcp_in.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************//*                                                                     *//*   Module:  tcp_ip/tcp/tcp_in.c                                      *//*   Release: 2001.3                                                   *//*   Version: 2001.0                                                   *//*   Purpose: TCP Input Routines                                       *//*                                                                     *//*---------------------------------------------------------------------*//*                                                                     *//*               Copyright 2001, Blunk Microsystems                    *//*                      ALL RIGHTS RESERVED                            *//*                                                                     *//*   Licensees have the non-exclusive right to use, modify, or extract *//*   this computer program for software development at a single site.  *//*   This program may be resold or disseminated in executable format   *//*   only. The source code may not be redistributed or resold.         *//*                                                                     *//***********************************************************************/#include "../tcp_ipp.h"#include "tcp.h"#include "../ip/ip.h"#include <string.h>/***********************************************************************//* Function Prototypes                                                 *//***********************************************************************/static SOCKET sock_match(void);static void do_opts(void);static int  seq_ok(void);static void get_MSS(const ui16 *mssp);/***********************************************************************//* Global Data Definitions                                             *//***********************************************************************/SOCKET Sock;/***********************************************************************//* Global Function Definitions                                         *//***********************************************************************//***********************************************************************//*       TcpIn: Deliver an inbound TCP segment to TCP socket           *//*                                                                     *//***********************************************************************/void TcpIn(void){  int hlen;  void *aligned;  /*-------------------------------------------------------------------*/  /* Read and verify TCP header length.                                */  /*-------------------------------------------------------------------*/  hlen = TCP_HLEN(RxBuf->ip_data);  if ((hlen < TCPMHLEN) || (hlen > RxBuf->length))    return;  /*-------------------------------------------------------------------*/  /* If not already set by VJHC decompression, assign application data */  /* pointer and length.                                               */  /*-------------------------------------------------------------------*/  if (RxBuf->app_len == 0)  {    RxBuf->app_data = (ui8 *)RxBuf->ip_data + hlen;    RxBuf->app_len = RxBuf->length - hlen;  }  /*-------------------------------------------------------------------*/  /* Ensure TCP header is four-byte aligned.                           */  /*-------------------------------------------------------------------*/  aligned = (void *)((ui32)RxBuf->ip_data & ~3);  if (aligned != RxBuf->ip_data)  {    memmove(aligned, RxBuf->ip_data, hlen);    RxBuf->ip_data = aligned;  }  /*-------------------------------------------------------------------*/  /* Assign global TCP segment pointer.                                */  /*-------------------------------------------------------------------*/  Net.Tcp = aligned;  /*-------------------------------------------------------------------*/  /* Verify checksum validity (using length of entire segment).        */  /*-------------------------------------------------------------------*/  if (TcpCheckSum(RxBuf))    return;  /*-------------------------------------------------------------------*/  /* Set buffer length to length of application data.                  */  /*-------------------------------------------------------------------*/  RxBuf->length -= hlen;  /*-------------------------------------------------------------------*/  /* Convert header fields to host order.                              */  /*-------------------------------------------------------------------*/  Net.Tcp->seq_num = ntohl(Net.Tcp->seq_num);  Net.Tcp->ack_num = ntohl(Net.Tcp->ack_num);  Net.Tcp->window = ntohs(Net.Tcp->window);  Net.Tcp->urg_ptr = ntohs(Net.Tcp->urg_ptr);  /*-------------------------------------------------------------------*/  /* Match segment to a socket and reserve socket.                     */  /*-------------------------------------------------------------------*/  Sock = sock_match();  if (Sock == NULL)  {    TcpReset();    return;  }  ++Sock->reserve_cnt;  /*-------------------------------------------------------------------*/  /* Verify that sequence numbers are acceptable for current window.   */  /*-------------------------------------------------------------------*/  if (seq_ok())  {    /*-----------------------------------------------------------------*/    /* If segment contains options, process them.                      */    /*-----------------------------------------------------------------*/    if (hlen != TCPMHLEN)      do_opts();    /*-----------------------------------------------------------------*/    /* Process buffer according to socket state.                       */    /*-----------------------------------------------------------------*/    TcpSwitch[Sock->state]();    /*-----------------------------------------------------------------*/    /* Call output state machine if needed.                            */    /*-----------------------------------------------------------------*/    if (Net.TryOut || (Sock->flags & SF_SENDFLG))    {      Net.TryOut = FALSE;      ++Sock->reserve_cnt;      TcpOut(Sock);    }    TcpAssert(Sock->out_state == TCPO_IDLE || Sock->out_tmr.running);  }  else  {    /*-----------------------------------------------------------------*/    /* Not acceptable, just acknowledge successful reception.          */    /*-----------------------------------------------------------------*/    TcpJustAck(Sock);  }  /*-------------------------------------------------------------------*/  /* Release our socket reservation.                                   */  /*-------------------------------------------------------------------*/  SockRelease(Sock);}/***********************************************************************//*  TcpJustAck: Generate ACK for received segment that lies outside    *//*              current receive window                                 *//*                                                                     *//*       Input: sock = TCP socket for incoming segment                 *//*                                                                     *//***********************************************************************/void TcpJustAck(SOCKET sock){  NetBuf *rbuf;  Tcp *tcp_out;  Route *route;  Ip *ip;  /*-------------------------------------------------------------------*/  /* To prevent infinite loops, do not acknowledge RESET segments.     */  /*-------------------------------------------------------------------*/  if (Net.Tcp->flags & TCPF_RST)    return;  /*-------------------------------------------------------------------*/  /* If no data and no SYN or FIN, must be old duplicate ACK.          */  /*-------------------------------------------------------------------*/  if ((RxBuf->app_len == 0) && !(Net.Tcp->flags & (TCPF_SYN | TCPF_FIN)))    return;  /*-------------------------------------------------------------------*/  /* Get a buffer to use for the response.                             */  /*-------------------------------------------------------------------*/  rbuf = tcpGetBuf(NIMHLEN + IPMHLEN + TCPMHLEN);  if (rbuf == NULL)    return;  /*-------------------------------------------------------------------*/  /* Find route for this destination, using cached route if available. */  /*-------------------------------------------------------------------*/  if (sock->route)    route = sock->route;  else  {    route = RtSearch(sock->remote.sin_addr.s_addr);    if (route == NULL)    {      ++Stats.IpOutNoRoutes;      tcpRetBuf(&rbuf);      return;    }    sock->route = route;  }  /*-------------------------------------------------------------------*/  /* Begin IP header initialization.                                   */  /*-------------------------------------------------------------------*/  ip = (Ip *)rbuf->ip_pkt;  ip->protocol = IPT_TCP;  ip->src_ip = sock->local.sin_addr.s_addr;  ip->dst_ip = sock->remote.sin_addr.s_addr;  /*-------------------------------------------------------------------*/  /* Complete TCP header fields.                                       */  /*-------------------------------------------------------------------*/  tcp_out = rbuf->ip_data;  tcp_out->src_port = Net.Tcp->dst_port;  tcp_out->dst_port = Net.Tcp->src_port;  tcp_out->seq_num = htonl(sock->snd_nxt);  tcp_out->ack_num = htonl(sock->rcv_nxt);  tcp_out->flags = TCPF_ACK;  tcp_out->offset = TCPHOFFSET;  tcp_out->window = TcpRcvWin(sock);  tcp_out->urg_ptr = 0;  /*-------------------------------------------------------------------*/  /* Calculate checksum.                                               */  /*-------------------------------------------------------------------*/  rbuf->length = TCPMHLEN;  tcp_out->cksum = 0;  tcp_out->cksum = TcpCheckSum(rbuf);  /*-------------------------------------------------------------------*/  /* Pass to IP for delivery and track how many TCP segments are sent. */  /*-------------------------------------------------------------------*/  IpSend(route, rbuf, rbuf->length, sock->ip_tos);  ++Stats.TcpOutSegs;}

⌨️ 快捷键说明

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