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.

280 lines
9.2 KiB

  1. // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
  2. //
  3. // Copyright (c) 1985-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. // Implementation specific definitions for Internet Protocol Version 6.
  14. //
  15. // Things we want visible to other kernel modules, yet aren't part of the
  16. // official specifications (i.e. are implementation specific) go here.
  17. //
  18. #ifndef IP6IMP_INCLUDED
  19. #define IP6IMP_INCLUDED 1
  20. //
  21. // These first few definitions (before the include of ip6.h)
  22. // replicate definitions from winsock2.h and ws2tcpip.h.
  23. // Unfortunately, those header files are not usable in the kernel.
  24. //
  25. typedef unsigned char u_char;
  26. typedef unsigned short u_short;
  27. typedef unsigned int u_int;
  28. typedef unsigned long u_long;
  29. typedef unsigned __int64 u_int64;
  30. /* Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP */
  31. #include <ipexport.h>
  32. typedef struct ipv6_mreq {
  33. struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast address */
  34. unsigned int ipv6mr_interface; /* Interface index */
  35. } IPV6_MREQ;
  36. #include <ip6.h>
  37. //
  38. // The actual definitions can be found in ip6def.h.
  39. //
  40. typedef struct NetTableEntryOrInterface NetTableEntryOrInterface;
  41. typedef struct Interface Interface;
  42. //
  43. // The actual definition of a Security Association Linkage
  44. // can be found in security.h.
  45. //
  46. typedef struct SALinkage SALinkage;
  47. typedef struct IPv6Packet IPv6Packet;
  48. typedef struct IPv6PacketAuxiliary IPv6PacketAuxiliary;
  49. //
  50. // Structure of packet data we pass around the stack.
  51. // Exactly one of FlatData and NdisPacket should be non-NULL.
  52. //
  53. struct IPv6Packet {
  54. IPv6Packet *Next; // Next entry on a list of packets.
  55. uint Position; // Current logical offset into packet.
  56. void *Data; // Current pointer into packet data.
  57. uint ContigSize; // Amount of contiguous data remaining.
  58. uint TotalSize; // Total amount of data remaining.
  59. NetTableEntryOrInterface *NTEorIF; // NTE or IF we received packet on.
  60. void *FlatData; // Original flat data pointer (if any).
  61. PNDIS_PACKET NdisPacket; // Original NDIS Packet (if any).
  62. long RefCnt; // References held to NdisPacket.
  63. IPv6PacketAuxiliary *AuxList; // Extra memory allocated by our stack.
  64. uint Flags; // Various, see below.
  65. IPv6Header UNALIGNED *IP; // IP header for this packet.
  66. uint IPPosition; // Offset at which IP header resides.
  67. IPv6Addr *SrcAddr; // Source/home addr for mobile IP.
  68. SALinkage *SAPerformed; // Security Associations performed.
  69. uint NextHeaderPosition; // Offset of recent NextHeader field.
  70. uint SkippedHeaderLength; // Headers skipped in AH validation.
  71. };
  72. // Flags for above.
  73. #define PACKET_OURS 0x01 // We alloc'd IPv6Packet struct off heap.
  74. #define PACKET_NOT_LINK_UNICAST 0x02 // Link-level broadcast or multicast.
  75. #define PACKET_REASSEMBLED 0x04 // Arrived as a bunch of fragments.
  76. #define PACKET_HOLDS_REF 0x08 // Packet holds an NTE or IF reference.
  77. #define PACKET_JUMBO_OPTION 0x10 // Packet has a jumbo payload option.
  78. #define PACKET_ICMP_ERROR 0x20 // Packet is an ICMP error message.
  79. #define PACKET_SAW_HA_OPT 0x40 // Home Addr Opt modified current IP hdr.
  80. #define PACKET_TUNNELED 0x80 // Arrived inside an outer IPv6 header.
  81. #define PACKET_LOOPED_BACK 0x100 // Arrived via internal loopback.
  82. //
  83. // Flags that are inherited by a reassembled datagram from its fragments.
  84. //
  85. #define PACKET_INHERITED_FLAGS (PACKET_NOT_LINK_UNICAST | \
  86. PACKET_TUNNELED | \
  87. PACKET_LOOPED_BACK)
  88. struct IPv6PacketAuxiliary {
  89. IPv6PacketAuxiliary *Next; // Next entry on packet's aux list.
  90. uint Position; // Packet position corresponding to region.
  91. uint Length; // Length of region in bytes.
  92. uchar *Data; // Data comprising region.
  93. };
  94. //
  95. // PacketPullup will sometimes copy more than the requested amount,
  96. // up to this limit.
  97. //
  98. #define MAX_EXCESS_PULLUP 128
  99. //
  100. // For comparing IPv6 addresseses.
  101. //
  102. __inline int
  103. IP6_ADDR_EQUAL(const IPv6Addr *x, const IPv6Addr *y)
  104. {
  105. __int64 UNALIGNED *a;
  106. __int64 UNALIGNED *b;
  107. a = (__int64 UNALIGNED *)x;
  108. b = (__int64 UNALIGNED *)y;
  109. return (a[1] == b[1]) && (a[0] == b[0]);
  110. }
  111. //
  112. // The actual definition of a route cache entry
  113. // can be found in route.h.
  114. //
  115. typedef struct RouteCacheEntry RouteCacheEntry;
  116. //
  117. // Structure of a packet context.
  118. //
  119. // The IF field holds a reference if it is non-NULL.
  120. // The packet holds a reference for the sending interface
  121. // between IPv6SendLL and IPv6SendComplete.
  122. //
  123. // The Flags field uses NDIS Flag bits (notably NDIS_FLAGS_MULTICAST_PACKET,
  124. // NDIS_FLAGS_LOOPBACK_ONLY, and NDIS_FLAGS_DONT_LOOPBACK)
  125. // but it is NOT the same as the Private.Flags field,
  126. // which NDIS uses.
  127. //
  128. typedef struct Packet6Context {
  129. PNDIS_PACKET pc_link; // For lists of packets.
  130. Interface *IF; // Interface sending the packet.
  131. uint pc_offset; // Offset of IPv6 header.
  132. // pc_adjust is used by link layers when sending packets.
  133. // pc_nucast is used in link layers when receiving transfer-data packets.
  134. // pc_drop is used in NeighborCacheTimeout.
  135. union {
  136. uint pc_adjust; // See AdjustPacketBuffer.
  137. uint pc_nucast; // Used in lan.c transfer-data.
  138. int pc_drop; // See NeighborCacheTimeout.
  139. };
  140. void (*CompletionHandler)( // Called on event completion.
  141. PNDIS_PACKET Packet,
  142. IP_STATUS Status);
  143. void *CompletionData; // Data for completion handler.
  144. uint Flags;
  145. IPv6Addr DiscoveryAddress; // Source address for ND.
  146. } Packet6Context;
  147. //
  148. // The ProtocolReserved field (extra bytes after normal NDIS Packet fields)
  149. // is structured as a Packet6Context.
  150. //
  151. // NB: Only packets created by IPv6 have an IPv6 Packet6Context.
  152. // Packets that NDIS hands up to us do NOT have a Packet6Context.
  153. //
  154. __inline Packet6Context *
  155. PC(NDIS_PACKET *Packet)
  156. {
  157. return (Packet6Context *)Packet->ProtocolReserved;
  158. }
  159. __inline void
  160. InitializeNdisPacket(NDIS_PACKET *Packet)
  161. {
  162. RtlZeroMemory(PC(Packet), sizeof *PC(Packet));
  163. }
  164. //
  165. // Global variables exported by the IPv6 driver for use by other
  166. // NT kernel modules.
  167. //
  168. extern NDIS_HANDLE IPv6PacketPool, IPv6BufferPool;
  169. //
  170. // Functions exported by the IPv6 driver for use by other
  171. // NT kernel modules.
  172. //
  173. void
  174. IPv6RegisterULProtocol(uchar Protocol, void *RecvHandler, void *CtrlHandler);
  175. extern void
  176. IPv6SendComplete(void *, PNDIS_PACKET, IP_STATUS);
  177. extern int
  178. IPv6Receive(IPv6Packet *);
  179. extern void
  180. IPv6ReceiveComplete(void);
  181. extern void
  182. IPv6ProviderReady(void);
  183. extern void
  184. InitializePacketFromNdis(IPv6Packet *Packet,
  185. PNDIS_PACKET NdisPacket, uint Offset);
  186. extern uint
  187. GetPacketPositionFromPointer(IPv6Packet *Packet, uchar *Pointer);
  188. extern uint
  189. PacketPullupSubr(IPv6Packet *Packet, uint Needed,
  190. uint AlignMultiple, uint AlignOffset);
  191. __inline int
  192. PacketPullup(IPv6Packet *Packet, uint Needed,
  193. uint AlignMultiple, uint AlignOffset)
  194. {
  195. return (((Needed <= Packet->ContigSize) &&
  196. ((PtrToUint(Packet->Data) & (AlignMultiple-1)) == AlignOffset)) ||
  197. (PacketPullupSubr(Packet, Needed,
  198. AlignMultiple, AlignOffset) != 0));
  199. }
  200. extern void
  201. PacketPullupCleanup(IPv6Packet *Packet);
  202. extern void
  203. AdjustPacketParams(IPv6Packet *Packet, uint BytesToSkip);
  204. extern void
  205. PositionPacketAt(IPv6Packet *Packet, uint NewPosition);
  206. extern uint
  207. CopyToBufferChain(PNDIS_BUFFER DstBuffer, uint DstOffset,
  208. PNDIS_PACKET SrcPacket, uint SrcOffset, uchar *SrcData,
  209. uint Length);
  210. extern uint
  211. CopyPacketToNdis(PNDIS_BUFFER DestBuf, IPv6Packet *Packet, uint Size,
  212. uint DestOffset, uint RcvOffset);
  213. extern void
  214. CopyPacketToBuffer(uchar *DestBuf, IPv6Packet *SrcPkt, uint Size, uint Offset);
  215. extern int
  216. CopyToNdisSafe(PNDIS_BUFFER DestBuf, PNDIS_BUFFER * ppNextBuf,
  217. uchar * SrcBuf, uint Size, uint * StartOffset);
  218. extern PNDIS_BUFFER
  219. CopyFlatToNdis(PNDIS_BUFFER DestBuf, uchar *SrcBuf, uint Size, uint *Offset,
  220. uint *BytesCopied);
  221. extern int
  222. CopyNdisToFlat(void *DstData, PNDIS_BUFFER SrcBuffer, uint SrcOffset,
  223. uint Length, PNDIS_BUFFER *NextBuffer, uint *NextOffset);
  224. extern NDIS_STATUS
  225. IPv6AllocatePacket(uint Length, PNDIS_PACKET *pPacket, void **pMemory);
  226. extern void
  227. IPv6FreePacket(PNDIS_PACKET Packet);
  228. extern void
  229. IPv6PacketComplete(PNDIS_PACKET Packet, IP_STATUS Status);
  230. #endif // IP6IMP_INCLUDED