Source code of Windows XP (NT5)
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.8 KiB

// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// Copyright (c) 1998-2000 Microsoft Corporation
//
// This file is part of the Microsoft Research IPv6 Network Protocol Stack.
// You should have received a copy of the Microsoft End-User License Agreement
// for this software along with this release; see the file "license.txt".
// If not, please see http://www.research.microsoft.com/msripv6/license.htm,
// or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
//
// Abstract:
//
// IPv6 fragmentation/reassembly definitions.
//
#ifndef FRAGMENT_H_INCLUDED
#define FRAGMENT_H_INCLUDED 1
//
// Structure used to link fragments together.
//
// The fragment data follows the shim structure in memory.
//
typedef struct PacketShim {
struct PacketShim *Next; // Next packet on list.
ushort Len;
ushort Offset;
} PacketShim;
__inline uchar *
PacketShimData(PacketShim *shim)
{
return (uchar *)(shim + 1);
}
//
// Structure used to keep track of the fragments
// being reassembled into a single IPv6 datagram.
//
// REVIEW: Some of these fields are bigger than they need to be.
//
struct Reassembly {
struct Reassembly *Next, *Prev; // Protected by global reassembly lock.
KSPIN_LOCK Lock; // Protects reassembly fields below.
uint State; // See values below.
IPv6Header IPHdr; // Copy of original IP header.
Interface *IF; // Does not hold a reference.
ulong Id; // Unique (along w/ addrs) datagram identifier.
uchar *UnfragData; // Pointer to unfragmentable data.
ushort UnfragmentLength; // Length of the unfragmentable part.
ushort Timer; // Time to expiration in ticks (see IPv6Timeout).
uint DataLength; // Length of the fragmentable part.
PacketShim *ContigList; // Sorted, contiguous frags (from offset zero).
PacketShim *ContigEnd; // Last shim on ContigList (for quick access).
PacketShim *GapList; // Other fragments (sorted but non-contiguous).
uint Flags; // Packet flags.
uint Size; // Amount of memory consumed in this reassembly.
ushort Marker; // The current marker for contiguous data.
ushort MaxGap; // Largest data offset in the gap list.
ushort NextHeaderOffset; // Offset from IPHdr to pre-FH NextHeader field.
uchar NextHeader; // Header type following the fragment header.
};
//
// A reassembly starts in REASSEMBLY_STATE_NORMAL.
// If you want to remove it, then change the state
// to REASSEMBLY_STATE_DELETING. This prevents someone else
// from freeing it while you unlock the reassembly,
// get the global reassembly list lock, and relock the assembly.
// Someone else can remove the deleting reassembly
// from the global list, in which case the state becomes
// REASSEMBLY_STATE_REMOVED.
//
#define REASSEMBLY_STATE_NORMAL 0
#define REASSEMBLY_STATE_DELETING 1
#define REASSEMBLY_STATE_REMOVED 2
//
// There are denial-of-service issues with reassembly.
// We limit the total amount of memory in the reassembly list.
// If we get fragments that cause us to exceed the limit,
// we remove old reassemblies.
//
// The locking order is
// 1. Global reassembly list lock.
// 2. Individual reassembly record locks.
// 3. Reassembly list size lock.
//
extern struct ReassemblyList {
KSPIN_LOCK Lock; // Protects Reassembly List.
Reassembly *First; // List of packets being reassembled.
Reassembly *Last;
KSPIN_LOCK LockSize; // Protects the Size field.
uint Size; // Total size of the waiting fragments.
uint Limit; // Upper bound for Size.
} ReassemblyList;
#define SentinelReassembly ((Reassembly *)&ReassemblyList.First)
//
// Per-packet and per-fragment overhead sizes.
// These are in addition to the actual size of the buffered data.
// They should be at least as large as the Reassembly
// and PacketShim struct sizes.
//
#define REASSEMBLY_SIZE_PACKET 1024
#define REASSEMBLY_SIZE_FRAG 256
#define DEFAULT_REASSEMBLY_TIMEOUT IPv6TimerTicks(60) // 60 seconds.
extern Reassembly *
FragmentLookup(Interface *IF, ulong Id,
const IPv6Addr *Source, const IPv6Addr *Dest);
extern void
RemoveReassembly(Reassembly *Reass);
extern void
DeleteReassembly(Reassembly *Reass);
extern void
AddToReassemblyList(Reassembly *Reass);
extern void
DeleteFromReassemblyList(Reassembly *Reass);
extern void
IncreaseReassemblySize(Reassembly *Reass, uint Size);
extern void
CheckReassemblyQuota(Reassembly *Reass);
extern void
ReassemblyTimeout(void);
extern void
ReassembleDatagram(IPv6Packet *Packet, Reassembly *Reass);
extern IPv6Packet *
CreateFragmentPacket(Reassembly *Reass);
#endif // FRAGMENT_H_INCLUDED