FRAGMENT.C
上传用户:better800
上传日期:2022-06-13
资源大小:1853k
文件大小:8k
源码类别:

TCP/IP协议栈

开发平台:

DOS

  1. /*
  2.  * Packet De-Fragmentaion code for WATTCP
  3.  * Written by and COPYRIGHT (c)1993 to Quentin Smart
  4.  *                               smart@actrix.gen.nz
  5.  * all rights reserved.
  6.  *
  7.  *   This software is distributed in the hope that it will be useful,
  8.  *   but without any warranty; without even the implied warranty of
  9.  *   merchantability or fitness for a particular purpose.
  10.  *
  11.  *   You may freely distribute this source code, but if distributed for
  12.  *   financial gain then only executables derived from the source may be
  13.  *   sold.
  14.  *
  15.  * Murf = Murf@perftech.com
  16.  * other fragfix = mdurkin@tsoft.net
  17.  *
  18.  * Based on RFC815
  19.  */
  20. #include <mem.h>
  21. #include <stdlib.h>
  22. #include "wattcp.h"
  23. /* Murf's code structuring macros */   /* add 94.09.16 */
  24. #define LOOP       for (;;)
  25. #define LOOPASSERT( c ) if (!(c)) break
  26. /* Murf's macro to get a structure address from a member address */
  27. #define structure(S,m,p) ((S *)( (byte *)(p) - (byte *) &((S *)0)->m ))
  28. /*
  29. #define ANIMATE
  30.  */
  31. #define MAXBUFS         5       /* maximum number of Ethernet buffers */
  32. #define MAXFRAGS        MAXBUFS-1
  33. #define FRAGHOLDTIME    15       /* 15 secs to hold before discarding */
  34. #define INFINITY        30000
  35. #define IP_HEADER_SIZE  20
  36. #define IP_MF           0x0020  // More fragment in INTEL form
  37. typedef struct {
  38. longword    source;
  39. //      longword destination;
  40.         byte        proto;         // use proto now
  41. word        identification;
  42. } fragkey;
  43. typedef struct hd {
  44. struct hd   * next;
  45. int           start;
  46. int           end;
  47. } hole_descr;
  48. typedef struct {
  49. byte         used;           // this position in table in use
  50. fragkey      key;
  51. hole_descr  *hole_first;
  52. longword     timer;
  53. in_Header   *ip;
  54. byte        *data_offset;
  55. } fraghdr;
  56. static fraghdr fraglist[MAXFRAGS] = {{0,{0,0},NULL,0,NULL},
  57.       {0,{0,0},NULL,0,NULL},
  58.       {0,{0,0},NULL,0,NULL},
  59.       {0,{0,0},NULL,0,NULL}};
  60. int active_frags = 0;
  61. extern word _pktipofs;  /* offset from header to start of pkt */
  62. /* Fragment is called if the frag section of the IP header is not zero and DF bit not set */
  63. byte *fragment( in_Header * ip )
  64. {
  65. //int        fc;
  66. fraghdr    *my_frag;
  67. hole_descr *hole = NULL;
  68. hole_descr *prev_hole = NULL;
  69. fragkey     key;
  70. int         found = 0;
  71. int         got_hole = 0;
  72. int         data_start;
  73. int         data_end;
  74. int         data_length;
  75. int         temp,i;
  76. int         more_frags;   // Set to true if this is the last frag
  77. /*byte     * buffer; */
  78. // Should check that the packet is actually valid and do a checksum on it.
  79. // Assemble key
  80. key.proto = ip->proto;     // use proto now
  81. key.source=ip->source;
  82. key.identification = ip->identification;
  83. // Check if we have a match
  84. for (i=0;i<MAXFRAGS && !found;i++)
  85.     if (fraglist[i].used && !memcmp(&key,&fraglist[i].key,sizeof(fragkey)))
  86.        {
  87.   found = TRUE;
  88.   my_frag = &fraglist[i];
  89.        }
  90. if (!found && active_frags == MAXFRAGS) {
  91. #ifdef ANIMATE
  92.    printf( "NO_BUFSn" );/*DEBUG STUFF*/
  93. #endif
  94.    // Can't handle any new frags, biff packet so that we can continue
  95.    // Could do direct!
  96.    pkt_buf_release((char*)ip);
  97.    return(NULL);  // We can't handle any new frags!
  98.    }
  99.  // Should biff packet?
  100. // Calc where data should go
  101. // fragfix - next line replaces... no more bitfields
  102.    data_start  = intel16(ip->frags) << 3; //* 8
  103.    data_length = intel16(ip->length)-in_GetHdrlenBytes(ip);
  104.    data_end    = data_start + data_length - 1;  // Murf 94.09.16
  105.    more_frags = ip->frags & IP_MF;
  106. #ifdef ANIMATE
  107.    printf( "Data=%d..%d", data_start, data_end );/*DEBUG STUFF*/
  108. #endif
  109. if (!found)
  110.  {
  111.    // Mark as used
  112.    *((byte *)ip - (2 + _pktipofs)) = 2;
  113.    // Find first empty slot
  114.    for (i=0;i < MAXFRAGS && fraglist[i].used;i++);
  115.    my_frag = &fraglist[i];
  116.    // mark as used
  117.    my_frag->used = 1;
  118.    // inc active frags counter
  119.    active_frags++;
  120.    // Setup frag header data, first packet
  121.    memcpy(&my_frag->key,&key,sizeof(key));
  122.    my_frag->timer  = set_timeout(max(FRAGHOLDTIME,ip->ttl));
  123.    my_frag->ip = ip;
  124.    // Set pointers to beinging of IP packet data
  125.    my_frag->data_offset = (byte *)my_frag->ip + in_GetHdrlenBytes(ip);
  126.    // Setup initial hole table
  127.    if (data_start) // i.e. not Zero
  128.     {
  129.       memcpy(my_frag->data_offset + data_start,(byte *)ip+in_GetHdrlenBytes(ip),data_length);
  130.       // Bracket beginning of data
  131.       hole = my_frag->hole_first = (hole_descr *)my_frag->data_offset;
  132.       hole->start = 0;
  133.       hole->end = data_start-1;
  134.       if (more_frags) {
  135.          // data_start was missing in next line - Murf 94.09.16
  136.          hole->next = (hole_descr *)(my_frag->data_offset + data_start + data_length + 1);
  137.  hole = hole->next;
  138.  }
  139.       else
  140. {
  141.  hole = my_frag->hole_first->next = NULL;
  142.  // Adjust length
  143.  ip->length = intel16(data_end + in_GetHdrlenBytes(ip));
  144. }
  145.     }
  146.    else
  147.     {
  148.      // Setup
  149.      hole = my_frag->hole_first = (hole_descr*)(my_frag->data_offset + data_length + 1);
  150.     }
  151.    // Bracket end
  152.    if (hole) {
  153.      // data_start was missing in next line - Murf 94.09.16
  154.      hole->start = data_start + data_length;// + 1;
  155.      hole->end = INFINITY;
  156.      hole->next = NULL;
  157.     }
  158. #ifdef ANIMATE
  159.    printf( " newn" );/*DEBUG STUFF*/
  160. #endif
  161.    return NULL; // Go back for more!
  162.  } // End !found
  163. // Adjust length
  164.    if (!more_frags)
  165.       my_frag->ip->length = intel16(data_end + 1 + in_GetHdrlenBytes(ip)); // Murf 94.09.16
  166. // Hole handling
  167.    hole = structure( hole_descr, next, &my_frag->hole_first ); // Murf 94.09.16
  168.    LOOP {                                                      // Murf 94.09.16
  169.       prev_hole = hole;                                        // Murf 94.09.16
  170.       hole = hole->next;                                       // Murf 94.09.16
  171.       LOOPASSERT (hole);                                       // Murf 94.09.16
  172. #ifdef ANIMATE
  173.       printf( " hole=%d..%d(%d)", hole->start, hole->end, hole->next );/*DEBUG STUFF*/
  174. #endif
  175.       if (!(data_start > hole->end) && !(data_end < hole->start)) {
  176.          // We've found the spot
  177.          // Mark as got.
  178.          got_hole =1;
  179.          // Find where to insert
  180.          // Check is there a hole before the new frag
  181.          temp = hole->end;   // Pick up old hole end for later;
  182.          if (data_start > hole->start) {
  183.             hole->end = data_start-1;
  184.             prev_hole = hole;  // We have a new prev
  185. #ifdef ANIMATE
  186.             printf( "->%d..%d(%d)", hole->start, hole->end, hole->next );/*DEBUG STUFF*/
  187. #endif
  188.             }
  189.           else {
  190.             // No, delete current hole
  191. #ifdef ANIMATE
  192.             printf( " del" );/* DEBUG STUFF*/
  193. #endif
  194.             prev_hole->next = hole->next;
  195.             hole = prev_hole;     // Leave hole valid - Murf 94.09.16
  196.             }
  197.          // Is there a hole after the current fragment
  198.          // Only if we're not last and more to come
  199.          if (data_end < temp && more_frags) {   // fragfix - Murf 94.09.14
  200.             hole = (hole_descr *)(data_end + 1 + my_frag->data_offset);
  201.             hole->start = data_end+1;
  202.             hole->end = temp;
  203.             hole->next = prev_hole->next;
  204.             prev_hole->next = hole;
  205. #ifdef ANIMATE
  206.             printf( ",%d..%d(%d)", hole->start, hole->end, hole->next );/*DEBUG STUFF*/
  207. #endif
  208.             }
  209.          }
  210.       }
  211.        // Thats all setup so copy in the data
  212.        if (got_hole)
  213.    memcpy(my_frag->data_offset + data_start,(byte *)ip+in_GetHdrlenBytes(ip),data_length);
  214.        // And release the buffer;
  215.        pkt_buf_release((char *)ip);
  216.        // Now do we have all the parts?
  217.        if (!my_frag->hole_first)
  218. {
  219. #ifdef ANIMATE
  220.       printf( " COMPLETEn" );/*DEBUG STUFF*/
  221. #endif
  222.   my_frag->used = 0;
  223.   active_frags--;
  224.   // Redo checksum as we've changed the length in the header
  225.   my_frag->ip->checksum = 0; // Zero
  226.   my_frag->ip->checksum = ~ checksum( my_frag->ip, sizeof( in_Header ));
  227.   return((byte *)my_frag->ip - _pktipofs);
  228. }
  229. #ifdef ANIMATE
  230.    printf( " MORE_TO_COMEn" );/*DEBUG STUFF*/
  231. #endif
  232. return NULL;
  233. }
  234. void timeout_frags( void )
  235. {
  236. int i;
  237. for (i=0;i<MAXFRAGS;i++)
  238.     if (fraglist[i].used)
  239.        if (chk_timeout(fraglist[i].timer))
  240.  {
  241. #ifdef ANIMATE
  242.   printf( "BUF timed outn" );/*DEBUG STUFF*/
  243. #endif
  244.   fraglist[i].used = 0;
  245.   active_frags--;
  246.   pkt_buf_release((char *)fraglist[i].ip);
  247.  }
  248. }