Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
4.9 KiB

  1. // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
  2. //
  3. // Copyright (c) 1998-2000 Microsoft Corporation
  4. //
  5. // This file is part of the Microsoft Research IPv6 Network Protocol Stack.
  6. // You should have received a copy of the Microsoft End-User License Agreement
  7. // for this software along with this release; see the file "license.txt".
  8. // If not, please see http://www.research.microsoft.com/msripv6/license.htm,
  9. // or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
  10. //
  11. // Abstract:
  12. //
  13. // IPv6 fragmentation/reassembly definitions.
  14. //
  15. #ifndef FRAGMENT_H_INCLUDED
  16. #define FRAGMENT_H_INCLUDED 1
  17. //
  18. // Structure used to link fragments together.
  19. //
  20. // The fragment data follows the shim structure in memory.
  21. //
  22. typedef struct PacketShim {
  23. struct PacketShim *Next; // Next packet on list.
  24. ushort Len;
  25. ushort Offset;
  26. } PacketShim;
  27. __inline uchar *
  28. PacketShimData(PacketShim *shim)
  29. {
  30. return (uchar *)(shim + 1);
  31. }
  32. //
  33. // Structure used to keep track of the fragments
  34. // being reassembled into a single IPv6 datagram.
  35. //
  36. // REVIEW: Some of these fields are bigger than they need to be.
  37. //
  38. struct Reassembly {
  39. struct Reassembly *Next, *Prev; // Protected by global reassembly lock.
  40. KSPIN_LOCK Lock; // Protects reassembly fields below.
  41. uint State; // See values below.
  42. IPv6Header IPHdr; // Copy of original IP header.
  43. Interface *IF; // Does not hold a reference.
  44. ulong Id; // Unique (along w/ addrs) datagram identifier.
  45. uchar *UnfragData; // Pointer to unfragmentable data.
  46. ushort UnfragmentLength; // Length of the unfragmentable part.
  47. ushort Timer; // Time to expiration in ticks (see IPv6Timeout).
  48. uint DataLength; // Length of the fragmentable part.
  49. PacketShim *ContigList; // Sorted, contiguous frags (from offset zero).
  50. PacketShim *ContigEnd; // Last shim on ContigList (for quick access).
  51. PacketShim *GapList; // Other fragments (sorted but non-contiguous).
  52. uint Flags; // Packet flags.
  53. uint Size; // Amount of memory consumed in this reassembly.
  54. ushort Marker; // The current marker for contiguous data.
  55. ushort MaxGap; // Largest data offset in the gap list.
  56. ushort NextHeaderOffset; // Offset from IPHdr to pre-FH NextHeader field.
  57. uchar NextHeader; // Header type following the fragment header.
  58. };
  59. //
  60. // A reassembly starts in REASSEMBLY_STATE_NORMAL.
  61. // If you want to remove it, then change the state
  62. // to REASSEMBLY_STATE_DELETING. This prevents someone else
  63. // from freeing it while you unlock the reassembly,
  64. // get the global reassembly list lock, and relock the assembly.
  65. // Someone else can remove the deleting reassembly
  66. // from the global list, in which case the state becomes
  67. // REASSEMBLY_STATE_REMOVED.
  68. //
  69. #define REASSEMBLY_STATE_NORMAL 0
  70. #define REASSEMBLY_STATE_DELETING 1
  71. #define REASSEMBLY_STATE_REMOVED 2
  72. //
  73. // There are denial-of-service issues with reassembly.
  74. // We limit the total amount of memory in the reassembly list.
  75. // If we get fragments that cause us to exceed the limit,
  76. // we remove old reassemblies.
  77. //
  78. // The locking order is
  79. // 1. Global reassembly list lock.
  80. // 2. Individual reassembly record locks.
  81. // 3. Reassembly list size lock.
  82. //
  83. extern struct ReassemblyList {
  84. KSPIN_LOCK Lock; // Protects Reassembly List.
  85. Reassembly *First; // List of packets being reassembled.
  86. Reassembly *Last;
  87. KSPIN_LOCK LockSize; // Protects the Size field.
  88. uint Size; // Total size of the waiting fragments.
  89. uint Limit; // Upper bound for Size.
  90. } ReassemblyList;
  91. #define SentinelReassembly ((Reassembly *)&ReassemblyList.First)
  92. //
  93. // Per-packet and per-fragment overhead sizes.
  94. // These are in addition to the actual size of the buffered data.
  95. // They should be at least as large as the Reassembly
  96. // and PacketShim struct sizes.
  97. //
  98. #define REASSEMBLY_SIZE_PACKET 1024
  99. #define REASSEMBLY_SIZE_FRAG 256
  100. #define DEFAULT_REASSEMBLY_TIMEOUT IPv6TimerTicks(60) // 60 seconds.
  101. extern Reassembly *
  102. FragmentLookup(Interface *IF, ulong Id,
  103. const IPv6Addr *Source, const IPv6Addr *Dest);
  104. extern void
  105. RemoveReassembly(Reassembly *Reass);
  106. extern void
  107. DeleteReassembly(Reassembly *Reass);
  108. extern void
  109. AddToReassemblyList(Reassembly *Reass);
  110. extern void
  111. DeleteFromReassemblyList(Reassembly *Reass);
  112. extern void
  113. IncreaseReassemblySize(Reassembly *Reass, uint Size);
  114. extern void
  115. CheckReassemblyQuota(Reassembly *Reass);
  116. extern void
  117. ReassemblyTimeout(void);
  118. extern void
  119. ReassembleDatagram(IPv6Packet *Packet, Reassembly *Reass);
  120. extern IPv6Packet *
  121. CreateFragmentPacket(Reassembly *Reass);
  122. #endif // FRAGMENT_H_INCLUDED