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

📄 fragment.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
/***********************************************************************//*                                                                     *//*   Module:  tcp_ip/ip/fragment.c                                     *//*   Release: 2001.3                                                   *//*   Version: 2000.0                                                   *//*   Purpose: IP Fragment Processing                                   *//*                                                                     *//*---------------------------------------------------------------------*//*                                                                     *//*               Copyright 2000, 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 <string.h>#include <stdlib.h>#include "ip.h"/***********************************************************************//* Configuration                                                       *//***********************************************************************/#define IP_FQSIZE   10  /* max number of frag queues */#define IP_MAXNF    10  /* max number of frags in packet */#define IP_FTTL     (60 * TICKS_PER_SEC)    /* fragment lifetime *//***********************************************************************//* Symbol Definitions                                                  *//***********************************************************************//*** Queue entry state flags*/#define IPFF_VALID  1   /* contents are valid */#define IPFF_BOGUS  2   /* drop frags that match */#define IPFF_FREE   3   /* this queue is free to be allocated *//***********************************************************************//* Type Definitions                                                    *//***********************************************************************/typedef struct{  TcpTmr timer;         /* fragment timer */  ui32 src_ip;          /* IP address of the source */  ui16 ip_id;           /* datagram id */  int  count;           /* number of queued entries */  NetBuf *head;         /* queue head */  char state;           /* IPFF_VALID, IPFF_BOGUS, or IPFF_FREE */} IpFragQ;/***********************************************************************//* Global Variable Definitions                                         *//***********************************************************************/static IpFragQ FragQ[IP_FQSIZE]; /* IP frag queue table *//***********************************************************************//* Local Function Definitions                                          *//***********************************************************************//***********************************************************************//*  free_queue: Add buffer to a sorted IP fragment queue               *//*                                                                     *//*       Input: head = pointer to the head of a fragment queue         *//*                                                                     *//*        Note: Assumes queue contains atleast one buffer              *//*                                                                     *//***********************************************************************/static void free_queue(NetBuf *head){  NetBuf *buf;  do  {    buf = head;    head = head->next;    tcpRetBuf(&buf);    ++Stats.IpReasmFails;  } while (head);}/***********************************************************************//*    add_frag: Add buffer to a sorted IP fragment queue               *//*                                                                     *//*       Input: queue = pointer to a fragment queue                    *//*                                                                     *//*     Returns: FALSE iff unable to add fragment to queue              *//*                                                                     *//***********************************************************************/static int add_frag(IpFragQ *queue){  NetBuf *nextbuf = queue->head;  /*-------------------------------------------------------------------*/  /* If queue is full, release all fragments and set state to bogus.   */  /*-------------------------------------------------------------------*/  if (queue->count == IP_MAXNF)  {    free_queue(nextbuf);    queue->state = IPFF_BOGUS;    ++Stats.IpReasmFails;    return FALSE;  }  /*-------------------------------------------------------------------*/  /* Else insert buffer according to fragment offset order.            */  /*-------------------------------------------------------------------*/  else  {    int fragoff = Net.Ip->frag_off & IP_FRAGOFF;    Ip *nextip = (Ip *)nextbuf->ip_pkt;    int nextfragoff = nextip->frag_off & IP_FRAGOFF;    /*-----------------------------------------------------------------*/    /* If offset is less than first entry, fragment is new queue head. */    /*-----------------------------------------------------------------*/    if (fragoff < nextfragoff)    {      RxBuf->next = queue->head;      queue->head = RxBuf;    }    /*-----------------------------------------------------------------*/    /* Search queue for fragment offset greater than buffer's.         */    /*-----------------------------------------------------------------*/    else    {      NetBuf *prevbuf;      for (;;)      {        /*-------------------------------------------------------------*/        /* Save pointer to current buffer and advance to next.         */        /*-------------------------------------------------------------*/        prevbuf = nextbuf;        nextbuf = nextbuf->next;        /*-------------------------------------------------------------*/        /* If queue end reached, append buffer.                        */        /*-------------------------------------------------------------*/        if (nextbuf == NULL)        {          RxBuf->next = NULL;          prevbuf->next = RxBuf;          break;        }        /*-------------------------------------------------------------*/        /* If buffer fragment offset is less than this entry, insert.  */        /*-------------------------------------------------------------*/        nextip = (Ip *)nextbuf->ip_pkt;        nextfragoff = nextip->frag_off & IP_FRAGOFF;        if (fragoff < nextfragoff)        {          RxBuf->next = nextbuf;          prevbuf->next = RxBuf;          break;        }      }    }    ++queue->count;    NetTimerStart(&queue->timer, IP_FTTL);    return TRUE;  }}/***********************************************************************//* copy_ip_data: Copy IP data from buffer                              *//*                                                                     *//*      Inputs: dst = pointer to IP data destination                   *//*              buf = pointer to buffer to copy from                   *//*              length = number of bytes to copy                       *//*                                                                     *//***********************************************************************/static void copy_ip_data(ui8 *dst, NetBuf *buf, uint length){  /*-------------------------------------------------------------------*/  /* If request fits in first region, take from there and return.      */  /*-------------------------------------------------------------------*/  if (length <= buf->length)  {    memcpy(dst, buf->ip_data, length);    buf->length -= length;    buf->ip_data = (ui8 *)buf->ip_data + length;    return;  }  /*-------------------------------------------------------------------*/  /* Else, copy all of the first region if non-empty.                  */  /*-------------------------------------------------------------------*/  else if (buf->length)  {    memcpy(dst, buf->ip_data, buf->length);    dst += buf->length;    length -= buf->length;    buf->length = 0;  }  /*-------------------------------------------------------------------*/  /* If remainder fits in second region, take from there and return.   */  /*-------------------------------------------------------------------*/  if (length <= buf->app_len)  {    memcpy(dst, buf->app_data, length);    buf->app_len -= length;    buf->app_data += length;    return;  }  /*-------------------------------------------------------------------*/  /* Else, copy all of the second region if non-empty.                 */  /*-------------------------------------------------------------------*/  else if (buf->app_len)  {    memcpy(dst, buf->app_data, buf->app_len);    dst += buf->app_len;    length -= buf->app_len;    buf->app_len = 0;  }  /*-------------------------------------------------------------------*/  /* If remaining request, take from third region.                     */  /*-------------------------------------------------------------------*/  if (length)  {    memcpy(dst, buf->app_data2, length);    buf->app_len2 -= length;    buf->app_data2 += length;  }}/***********************************************************************//*   join_frag: Join fragments, if all collected                       *//*                                                                     *//*       Input: queue = pointer to a fragment queue                    *//*                                                                     *//*     Returns: TRUE iff packet is re-assembled                        *//*                                                                     *//***********************************************************************/static int join_frag(IpFragQ *queue){  NetBuf *fbuf, *buf = queue->head;  int packoff, offset = 0;  uint hlen, dlen;  Ip  *ip;  ui8 *dst;  /*-------------------------------------------------------------------*/  /* Look for continuous pattern of fragment offsets starting at zero. */  /*-------------------------------------------------------------------*/  do  {

⌨️ 快捷键说明

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