281 lines
9.2 KiB
C
281 lines
9.2 KiB
C
|
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
|
||
|
//
|
||
|
// Copyright (c) 1985-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:
|
||
|
//
|
||
|
// Implementation specific definitions for Internet Protocol Version 6.
|
||
|
//
|
||
|
// Things we want visible to other kernel modules, yet aren't part of the
|
||
|
// official specifications (i.e. are implementation specific) go here.
|
||
|
//
|
||
|
|
||
|
|
||
|
#ifndef IP6IMP_INCLUDED
|
||
|
#define IP6IMP_INCLUDED 1
|
||
|
|
||
|
//
|
||
|
// These first few definitions (before the include of ip6.h)
|
||
|
// replicate definitions from winsock2.h and ws2tcpip.h.
|
||
|
// Unfortunately, those header files are not usable in the kernel.
|
||
|
//
|
||
|
|
||
|
typedef unsigned char u_char;
|
||
|
typedef unsigned short u_short;
|
||
|
typedef unsigned int u_int;
|
||
|
typedef unsigned long u_long;
|
||
|
typedef unsigned __int64 u_int64;
|
||
|
|
||
|
/* Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP */
|
||
|
|
||
|
#include <ipexport.h>
|
||
|
|
||
|
typedef struct ipv6_mreq {
|
||
|
struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast address */
|
||
|
unsigned int ipv6mr_interface; /* Interface index */
|
||
|
} IPV6_MREQ;
|
||
|
|
||
|
#include <ip6.h>
|
||
|
|
||
|
//
|
||
|
// The actual definitions can be found in ip6def.h.
|
||
|
//
|
||
|
typedef struct NetTableEntryOrInterface NetTableEntryOrInterface;
|
||
|
typedef struct Interface Interface;
|
||
|
|
||
|
//
|
||
|
// The actual definition of a Security Association Linkage
|
||
|
// can be found in security.h.
|
||
|
//
|
||
|
typedef struct SALinkage SALinkage;
|
||
|
|
||
|
typedef struct IPv6Packet IPv6Packet;
|
||
|
typedef struct IPv6PacketAuxiliary IPv6PacketAuxiliary;
|
||
|
|
||
|
//
|
||
|
// Structure of packet data we pass around the stack.
|
||
|
// Exactly one of FlatData and NdisPacket should be non-NULL.
|
||
|
//
|
||
|
struct IPv6Packet {
|
||
|
IPv6Packet *Next; // Next entry on a list of packets.
|
||
|
uint Position; // Current logical offset into packet.
|
||
|
void *Data; // Current pointer into packet data.
|
||
|
uint ContigSize; // Amount of contiguous data remaining.
|
||
|
uint TotalSize; // Total amount of data remaining.
|
||
|
NetTableEntryOrInterface *NTEorIF; // NTE or IF we received packet on.
|
||
|
void *FlatData; // Original flat data pointer (if any).
|
||
|
PNDIS_PACKET NdisPacket; // Original NDIS Packet (if any).
|
||
|
long RefCnt; // References held to NdisPacket.
|
||
|
IPv6PacketAuxiliary *AuxList; // Extra memory allocated by our stack.
|
||
|
uint Flags; // Various, see below.
|
||
|
IPv6Header UNALIGNED *IP; // IP header for this packet.
|
||
|
uint IPPosition; // Offset at which IP header resides.
|
||
|
IPv6Addr *SrcAddr; // Source/home addr for mobile IP.
|
||
|
SALinkage *SAPerformed; // Security Associations performed.
|
||
|
uint NextHeaderPosition; // Offset of recent NextHeader field.
|
||
|
uint SkippedHeaderLength; // Headers skipped in AH validation.
|
||
|
};
|
||
|
|
||
|
// Flags for above.
|
||
|
#define PACKET_OURS 0x01 // We alloc'd IPv6Packet struct off heap.
|
||
|
#define PACKET_NOT_LINK_UNICAST 0x02 // Link-level broadcast or multicast.
|
||
|
#define PACKET_REASSEMBLED 0x04 // Arrived as a bunch of fragments.
|
||
|
#define PACKET_HOLDS_REF 0x08 // Packet holds an NTE or IF reference.
|
||
|
#define PACKET_JUMBO_OPTION 0x10 // Packet has a jumbo payload option.
|
||
|
#define PACKET_ICMP_ERROR 0x20 // Packet is an ICMP error message.
|
||
|
#define PACKET_SAW_HA_OPT 0x40 // Home Addr Opt modified current IP hdr.
|
||
|
#define PACKET_TUNNELED 0x80 // Arrived inside an outer IPv6 header.
|
||
|
#define PACKET_LOOPED_BACK 0x100 // Arrived via internal loopback.
|
||
|
|
||
|
//
|
||
|
// Flags that are inherited by a reassembled datagram from its fragments.
|
||
|
//
|
||
|
#define PACKET_INHERITED_FLAGS (PACKET_NOT_LINK_UNICAST | \
|
||
|
PACKET_TUNNELED | \
|
||
|
PACKET_LOOPED_BACK)
|
||
|
|
||
|
struct IPv6PacketAuxiliary {
|
||
|
IPv6PacketAuxiliary *Next; // Next entry on packet's aux list.
|
||
|
uint Position; // Packet position corresponding to region.
|
||
|
uint Length; // Length of region in bytes.
|
||
|
uchar *Data; // Data comprising region.
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// PacketPullup will sometimes copy more than the requested amount,
|
||
|
// up to this limit.
|
||
|
//
|
||
|
#define MAX_EXCESS_PULLUP 128
|
||
|
|
||
|
//
|
||
|
// For comparing IPv6 addresseses.
|
||
|
//
|
||
|
__inline int
|
||
|
IP6_ADDR_EQUAL(const IPv6Addr *x, const IPv6Addr *y)
|
||
|
{
|
||
|
__int64 UNALIGNED *a;
|
||
|
__int64 UNALIGNED *b;
|
||
|
|
||
|
a = (__int64 UNALIGNED *)x;
|
||
|
b = (__int64 UNALIGNED *)y;
|
||
|
|
||
|
return (a[1] == b[1]) && (a[0] == b[0]);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// The actual definition of a route cache entry
|
||
|
// can be found in route.h.
|
||
|
//
|
||
|
typedef struct RouteCacheEntry RouteCacheEntry;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Structure of a packet context.
|
||
|
//
|
||
|
// The IF field holds a reference if it is non-NULL.
|
||
|
// The packet holds a reference for the sending interface
|
||
|
// between IPv6SendLL and IPv6SendComplete.
|
||
|
//
|
||
|
// The Flags field uses NDIS Flag bits (notably NDIS_FLAGS_MULTICAST_PACKET,
|
||
|
// NDIS_FLAGS_LOOPBACK_ONLY, and NDIS_FLAGS_DONT_LOOPBACK)
|
||
|
// but it is NOT the same as the Private.Flags field,
|
||
|
// which NDIS uses.
|
||
|
//
|
||
|
typedef struct Packet6Context {
|
||
|
PNDIS_PACKET pc_link; // For lists of packets.
|
||
|
Interface *IF; // Interface sending the packet.
|
||
|
uint pc_offset; // Offset of IPv6 header.
|
||
|
// pc_adjust is used by link layers when sending packets.
|
||
|
// pc_nucast is used in link layers when receiving transfer-data packets.
|
||
|
// pc_drop is used in NeighborCacheTimeout.
|
||
|
union {
|
||
|
uint pc_adjust; // See AdjustPacketBuffer.
|
||
|
uint pc_nucast; // Used in lan.c transfer-data.
|
||
|
int pc_drop; // See NeighborCacheTimeout.
|
||
|
};
|
||
|
void (*CompletionHandler)( // Called on event completion.
|
||
|
PNDIS_PACKET Packet,
|
||
|
IP_STATUS Status);
|
||
|
void *CompletionData; // Data for completion handler.
|
||
|
uint Flags;
|
||
|
IPv6Addr DiscoveryAddress; // Source address for ND.
|
||
|
} Packet6Context;
|
||
|
|
||
|
|
||
|
//
|
||
|
// The ProtocolReserved field (extra bytes after normal NDIS Packet fields)
|
||
|
// is structured as a Packet6Context.
|
||
|
//
|
||
|
// NB: Only packets created by IPv6 have an IPv6 Packet6Context.
|
||
|
// Packets that NDIS hands up to us do NOT have a Packet6Context.
|
||
|
//
|
||
|
__inline Packet6Context *
|
||
|
PC(NDIS_PACKET *Packet)
|
||
|
{
|
||
|
return (Packet6Context *)Packet->ProtocolReserved;
|
||
|
}
|
||
|
|
||
|
__inline void
|
||
|
InitializeNdisPacket(NDIS_PACKET *Packet)
|
||
|
{
|
||
|
RtlZeroMemory(PC(Packet), sizeof *PC(Packet));
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Global variables exported by the IPv6 driver for use by other
|
||
|
// NT kernel modules.
|
||
|
//
|
||
|
extern NDIS_HANDLE IPv6PacketPool, IPv6BufferPool;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Functions exported by the IPv6 driver for use by other
|
||
|
// NT kernel modules.
|
||
|
//
|
||
|
|
||
|
void
|
||
|
IPv6RegisterULProtocol(uchar Protocol, void *RecvHandler, void *CtrlHandler);
|
||
|
|
||
|
extern void
|
||
|
IPv6SendComplete(void *, PNDIS_PACKET, IP_STATUS);
|
||
|
|
||
|
extern int
|
||
|
IPv6Receive(IPv6Packet *);
|
||
|
|
||
|
extern void
|
||
|
IPv6ReceiveComplete(void);
|
||
|
|
||
|
extern void
|
||
|
IPv6ProviderReady(void);
|
||
|
|
||
|
extern void
|
||
|
InitializePacketFromNdis(IPv6Packet *Packet,
|
||
|
PNDIS_PACKET NdisPacket, uint Offset);
|
||
|
|
||
|
extern uint
|
||
|
GetPacketPositionFromPointer(IPv6Packet *Packet, uchar *Pointer);
|
||
|
|
||
|
extern uint
|
||
|
PacketPullupSubr(IPv6Packet *Packet, uint Needed,
|
||
|
uint AlignMultiple, uint AlignOffset);
|
||
|
|
||
|
__inline int
|
||
|
PacketPullup(IPv6Packet *Packet, uint Needed,
|
||
|
uint AlignMultiple, uint AlignOffset)
|
||
|
{
|
||
|
return (((Needed <= Packet->ContigSize) &&
|
||
|
((PtrToUint(Packet->Data) & (AlignMultiple-1)) == AlignOffset)) ||
|
||
|
(PacketPullupSubr(Packet, Needed,
|
||
|
AlignMultiple, AlignOffset) != 0));
|
||
|
}
|
||
|
|
||
|
extern void
|
||
|
PacketPullupCleanup(IPv6Packet *Packet);
|
||
|
|
||
|
extern void
|
||
|
AdjustPacketParams(IPv6Packet *Packet, uint BytesToSkip);
|
||
|
|
||
|
extern void
|
||
|
PositionPacketAt(IPv6Packet *Packet, uint NewPosition);
|
||
|
|
||
|
extern uint
|
||
|
CopyToBufferChain(PNDIS_BUFFER DstBuffer, uint DstOffset,
|
||
|
PNDIS_PACKET SrcPacket, uint SrcOffset, uchar *SrcData,
|
||
|
uint Length);
|
||
|
|
||
|
extern uint
|
||
|
CopyPacketToNdis(PNDIS_BUFFER DestBuf, IPv6Packet *Packet, uint Size,
|
||
|
uint DestOffset, uint RcvOffset);
|
||
|
|
||
|
extern void
|
||
|
CopyPacketToBuffer(uchar *DestBuf, IPv6Packet *SrcPkt, uint Size, uint Offset);
|
||
|
|
||
|
extern int
|
||
|
CopyToNdisSafe(PNDIS_BUFFER DestBuf, PNDIS_BUFFER * ppNextBuf,
|
||
|
uchar * SrcBuf, uint Size, uint * StartOffset);
|
||
|
|
||
|
extern PNDIS_BUFFER
|
||
|
CopyFlatToNdis(PNDIS_BUFFER DestBuf, uchar *SrcBuf, uint Size, uint *Offset,
|
||
|
uint *BytesCopied);
|
||
|
|
||
|
extern int
|
||
|
CopyNdisToFlat(void *DstData, PNDIS_BUFFER SrcBuffer, uint SrcOffset,
|
||
|
uint Length, PNDIS_BUFFER *NextBuffer, uint *NextOffset);
|
||
|
|
||
|
extern NDIS_STATUS
|
||
|
IPv6AllocatePacket(uint Length, PNDIS_PACKET *pPacket, void **pMemory);
|
||
|
|
||
|
extern void
|
||
|
IPv6FreePacket(PNDIS_PACKET Packet);
|
||
|
|
||
|
extern void
|
||
|
IPv6PacketComplete(PNDIS_PACKET Packet, IP_STATUS Status);
|
||
|
|
||
|
#endif // IP6IMP_INCLUDED
|