// -*- 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 typedef struct ipv6_mreq { struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast address */ unsigned int ipv6mr_interface; /* Interface index */ } IPV6_MREQ; #include // // 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