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.

1408 lines
42 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. // IPv6 private definitions.
  14. //
  15. // This file contains all of the definitions for IPv6 that
  16. // are not visible to outside layers.
  17. //
  18. #ifndef IPv6DEF_INCLUDED
  19. #define IPv6DEF_INCLUDED 1
  20. typedef struct NeighborCacheEntry NeighborCacheEntry;
  21. typedef struct AddressEntry AddressEntry;
  22. typedef struct MulticastAddressEntry MulticastAddressEntry;
  23. typedef struct AnycastAddressEntry AnycastAddressEntry;
  24. typedef struct NetTableEntryOrInterface NetTableEntryOrInterface;
  25. typedef struct NetTableEntry NetTableEntry;
  26. typedef struct Interface Interface;
  27. typedef struct IPSecProc IPSecProc;
  28. // REVIEW: Added so the build will work.
  29. typedef unsigned long IPAddr;
  30. #define INADDR_ANY 0
  31. //
  32. // Override the default DDK definitions of ASSERT/ASSERTMSG.
  33. // The default definitions use RtlAssert, which does nothing
  34. // unless you are using a checked kernel.
  35. //
  36. #undef ASSERT
  37. #undef ASSERTMSG
  38. #if DBG
  39. #define ASSERT(exp) \
  40. if (!(exp)) { \
  41. DbgPrint("assert failed (%s, %d): %s\n", __FILE__, __LINE__, #exp); \
  42. DbgBreakPoint(); \
  43. } else
  44. #define ASSERTMSG(msg, exp) \
  45. if (!(exp)) { \
  46. DbgPrint("assert failed (%s, %d): %s\n", __FILE__, __LINE__, (msg)); \
  47. DbgBreakPoint(); \
  48. } else
  49. #else
  50. #define ASSERT(exp)
  51. #define ASSERTMSG(msg, exp)
  52. #endif // DBG
  53. //
  54. // Per-neighbor information. We keep address translation and unreachability
  55. // detection info for each of our neighbors that we're in communication with.
  56. //
  57. // A non-zero reference count prevents the NCE from being reclaimed.
  58. // An NCE with zero references may be kept cached.
  59. // A per-interface lock protects all NCEs for that interface.
  60. //
  61. // NCEs with a non-zero reference count hold a reference for their interface.
  62. // NCEs with a zero reference count do not hold a reference.
  63. // This means if you hold a reference for an NCE,
  64. // you can always safely access and dereference NCE->IF.
  65. //
  66. // The Next/Prev fields link NCEs into a circular doubly-linked list.
  67. // They must be first and must match the IF->FirstNCE/LastNCE fields
  68. // to make the casting work out.
  69. //
  70. // The list of NCEs is kept sorted, from most-recently-used to least.
  71. //
  72. struct NeighborCacheEntry { // a.k.a. NCE
  73. NeighborCacheEntry *Next; // Next entry on I/F neighbor list.
  74. NeighborCacheEntry *Prev; // Previous entry on I/F neighbor list.
  75. IPv6Addr NeighborAddress; // Address of I/F on neighboring node.
  76. void *LinkAddress; // Media address corresponding to above.
  77. // NB: LinkAddressLength field not needed - use IF->LinkAddressLength.
  78. ushort IsRouter:1, // Is the neighbor a router?
  79. IsUnreachable:1, // Does ND indicate unreachability?
  80. // DoRoundRobin is only meaningful if IsUnreachable is TRUE.
  81. DoRoundRobin:1, // Should FindRoute do round-robin?
  82. IsLoopback:1; // Do we loopback to this neighbor
  83. // in software?
  84. ushort NDState; // Neighbor Discovery Protocol state.
  85. uint LastReachability; // Timestamp (IPv6Timer ticks).
  86. ushort NSTimer; // In IPv6Timer ticks (see IPv6Timeout).
  87. uchar NSCount; // Number of solicits sent so far.
  88. uchar NSLimit; // Total number of solicits to send.
  89. Interface *IF; // Interface on media with neighbor.
  90. NDIS_PACKET *WaitQueue; // Queue of packets waiting on ND.
  91. long RefCnt; // Reference count - interlocked.
  92. };
  93. //
  94. // The caller must already have a reference for the NCE.
  95. // The interface need not be locked.
  96. //
  97. __inline void
  98. AddRefNCE(NeighborCacheEntry *NCE)
  99. {
  100. long RefCnt = InterlockedIncrement(&NCE->RefCnt);
  101. ASSERT(RefCnt != 1);
  102. }
  103. extern void
  104. AddRefNCEInCache(NeighborCacheEntry *NCE);
  105. extern void
  106. ReleaseNCE(NeighborCacheEntry *NCE);
  107. //
  108. // Values for "NDState" above. See RFC 1970, section 7.3.2 for details.
  109. // Note: only state names are documented, we chose the values used here.
  110. //
  111. // In the INCOMPLETE state, the LinkAddress is not valid.
  112. // In all other states, LinkAddress may be used to send packets.
  113. // WaitQueue is usually only non-NULL in the INCOMPLETE state,
  114. // but sometimes a packet is left queued for NeighborCacheTimeout.
  115. //
  116. // The INCOMPLETE state has two flavors, dormant and active. If
  117. // EventTimer and EventCount are both zero, then we are not actively
  118. // trying to solicit the link address. If someone tries to send to
  119. // this neighbor, then we start soliciting the link address. If the
  120. // solicitation fails (or if we enter the PROBE state and then fail to
  121. // confirm reachability), then any waiting packets are discarded and
  122. // we reset to INCOMPLETE with zero EventTimer/EventCount. (So with
  123. // the next use of this neighbor, we start soliciting again from scratch.)
  124. //
  125. // The DELAY state is not used internally. Instead we use the PROBE state
  126. // with zero NSCount and non-zero NSTimer to indicate that we are delaying
  127. // the start of probing. However link-layer lip_cvaddr functions can
  128. // return ND_STATE_DELAY and IoctlQueryNeighborCache returns ND_STATE_DELAY.
  129. //
  130. // The IsUnreachable flag tracks separately whether the neighbor is
  131. // *known* to be unreachable. For example, a new NCE will be in in the
  132. // INCOMPLETE state, but IsUnreachable is FALSE because we don't know
  133. // yet whether the neighbor is reachable. Because FindRoute uses
  134. // IsUnreachable, code paths that change this flag must call
  135. // InvalidateRouteCache.
  136. //
  137. // These definitions are also in llip6if.h and ntddip6.w.
  138. //
  139. #define ND_STATE_INCOMPLETE 0
  140. #define ND_STATE_PROBE 1
  141. #define ND_STATE_DELAY 2 // Not used internally.
  142. #define ND_STATE_STALE 3
  143. #define ND_STATE_REACHABLE 4
  144. #define ND_STATE_PERMANENT 5
  145. //
  146. // There are a few places in the implementation where we need
  147. // to pass a pointer which is either a NetTableEntry or an Interface.
  148. // NetTableEntries and Interfaces share this structure as their
  149. // first element. With Interfaces, the IF field points back
  150. // at the Interface itself.
  151. //
  152. struct NetTableEntryOrInterface { // a.k.a. NTEorIF
  153. Interface *IF;
  154. };
  155. __inline int
  156. IsNTE(NetTableEntryOrInterface *NTEorIF)
  157. {
  158. return (NetTableEntryOrInterface *)NTEorIF->IF != NTEorIF;
  159. }
  160. __inline NetTableEntry *
  161. CastToNTE(NetTableEntryOrInterface *NTEorIF)
  162. {
  163. ASSERT(IsNTE(NTEorIF));
  164. return (NetTableEntry *) NTEorIF;
  165. }
  166. __inline NetTableEntryOrInterface *
  167. CastFromNTE(NetTableEntry *NTE)
  168. {
  169. return (NetTableEntryOrInterface *) NTE;
  170. }
  171. __inline int
  172. IsIF(NetTableEntryOrInterface *NTEorIF)
  173. {
  174. return (NetTableEntryOrInterface *)NTEorIF->IF == NTEorIF;
  175. }
  176. __inline Interface *
  177. CastToIF(NetTableEntryOrInterface *NTEorIF)
  178. {
  179. ASSERT(IsIF(NTEorIF));
  180. return (Interface *) NTEorIF;
  181. }
  182. __inline NetTableEntryOrInterface *
  183. CastFromIF(Interface *IF)
  184. {
  185. return (NetTableEntryOrInterface *) IF;
  186. }
  187. //
  188. // Local address information. Each interface keeps track of the addresses
  189. // assigned to the interface. Depending on the type of address, each
  190. // ADE structure is the first element of a larger NTE, MAE, or AAE structure.
  191. // The address information is protected by the interface's lock.
  192. //
  193. // The NTEorIF field must be first. In NTEs, it points to the interface
  194. // and holds a reference for the interface. In MAEs and AAEs, it can
  195. // point to the interface or to one of the NTEs on the interface but in
  196. // either case it does NOT hold a reference.
  197. //
  198. struct AddressEntry { // a.k.a. ADE
  199. union {
  200. Interface *IF;
  201. NetTableEntry *NTE;
  202. NetTableEntryOrInterface *NTEorIF;
  203. };
  204. AddressEntry *Next; // Linkage on chain.
  205. IPv6Addr Address; // Address identifying this entry.
  206. ushort Type; // Address type (unicast, multicast, etc).
  207. ushort Scope; // Address scope (link, site, global, etc).
  208. };
  209. //
  210. // Values for address Type.
  211. //
  212. #define ADE_UNICAST 0x00
  213. #define ADE_ANYCAST 0x01
  214. #define ADE_MULTICAST 0x02
  215. #define ADE_NONE ((ushort)-1) // Indicates absence of an ADE.
  216. //
  217. // Values for address Scope.
  218. //
  219. #define ADE_SMALLEST_SCOPE 0x00
  220. #define ADE_INTERFACE_LOCAL 0x01
  221. #define ADE_LINK_LOCAL 0x02
  222. #define ADE_SUBNET_LOCAL 0x03
  223. #define ADE_ADMIN_LOCAL 0x04
  224. #define ADE_SITE_LOCAL 0x05
  225. #define ADE_ORG_LOCAL 0x08
  226. #define ADE_GLOBAL 0x0e
  227. #define ADE_LARGEST_SCOPE 0x0f
  228. #define ADE_NUM_SCOPES (ADE_LARGEST_SCOPE - ADE_SMALLEST_SCOPE + 1)
  229. //
  230. // Multicast ADEs are really MAEs.
  231. //
  232. // MAEs can be a separate global QueryList.
  233. // If an MAE on an Interface has a non-zero MCastTimer value,
  234. // then it is on the QueryList.
  235. //
  236. // An MAE can be on the QueryList with a zero MCastTimer value
  237. // only when it is not on any interface and it just needs
  238. // a Done message sent before it can be deleted.
  239. // When it is in this state (but not otherwise), MAE->IF
  240. // holds a reference for the interface.
  241. //
  242. struct MulticastAddressEntry { // a.k.a. MAE
  243. AddressEntry; // Inherit the ADE fields.
  244. uint MCastRefCount; // Sockets/etc receiving from this group.
  245. //
  246. // The fields below are protected by the QueryList lock.
  247. //
  248. ushort MCastFlags:4, // Necessary info about a group.
  249. MCastCount:4; // Count of initial reports left to send.
  250. ushort MCastTimer; // Ticks until a membership report is sent.
  251. MulticastAddressEntry *NextQL; // For the QueryList.
  252. };
  253. //
  254. // Bit values for MCastFlags.
  255. //
  256. #define MAE_REPORTABLE 0x01 // We should send Reports.
  257. #define MAE_LAST_REPORTER 0x02 // We should send Done.
  258. //
  259. // Anycast ADEs are really AAEs.
  260. // Currently an AAE has no additional fields.
  261. //
  262. struct AnycastAddressEntry { // a.k.a. AAE
  263. AddressEntry; // Inherit the ADE fields.
  264. };
  265. //
  266. // Unicast ADEs are really NTEs.
  267. // There is one NTE for each source (unicast) address
  268. // assigned to an interface.
  269. //
  270. // NTEs hold a reference for their interface,
  271. // so if you have a reference for an NTE
  272. // you can always safely access and dereference NTE->IF.
  273. //
  274. // Most NTE fields are either read-only or are protected
  275. // by the interface lock. The interface WorkerLock protects
  276. // the TdiRegistrationHandle field.
  277. //
  278. // Anonyous addresses (AddrConf == ADDR_CONF_ANONYMOUS)
  279. // have extra fields - see AnonNetTableEntry.
  280. //
  281. struct NetTableEntry { // a.k.a. NTE
  282. AddressEntry; // Inherit the ADE fields.
  283. NetTableEntry *NextOnNTL; // Next NTE on NetTableList.
  284. NetTableEntry **PrevOnNTL; // Previous Next pointer in NetTableList.
  285. HANDLE TdiRegistrationHandle; // Opaque token for TDI De/notification.
  286. long RefCnt; // Reference count - interlocked.
  287. uint ValidLifetime; // In IPv6Timer ticks (see IPv6Timeout).
  288. uint PreferredLifetime; // In IPv6Timer ticks (see IPv6Timeout).
  289. uchar AddrConf; // Address configuration status.
  290. uchar DADState; // Address configuration state.
  291. ushort DADCount; // How many DAD solicits left to send.
  292. ushort DADTimer; // In IPv6Timer ticks (see IPv6Timeout).
  293. };
  294. __inline void
  295. AddRefNTE(NetTableEntry *NTE)
  296. {
  297. InterlockedIncrement(&NTE->RefCnt);
  298. }
  299. __inline void
  300. ReleaseNTE(NetTableEntry *NTE)
  301. {
  302. InterlockedDecrement(&NTE->RefCnt);
  303. }
  304. struct AddrConfEntry {
  305. union {
  306. uchar Value; // Address configuration status.
  307. struct {
  308. uchar InterfaceIdConf : 4;
  309. uchar PrefixConf : 4;
  310. };
  311. };
  312. };
  313. //
  314. // Values for PrefixConf - must fit in 4 bits.
  315. // These must match the values in ntddip6.h, as well as the
  316. // IP_PREFIX_ORIGIN values in iptypes.h.
  317. //
  318. #define PREFIX_CONF_OTHER 0 // None of the ones below.
  319. #define PREFIX_CONF_MANUAL 1 // From a user or administrator.
  320. #define PREFIX_CONF_WELLKNOWN 2 // IANA-assigned.
  321. #define PREFIX_CONF_DHCP 3 // Configured via DHCP.
  322. #define PREFIX_CONF_RA 4 // From a Router Advertisement.
  323. //
  324. // Values for InterfaceIdConf - must fit in 4 bits.
  325. // These must match the values in ntddip6.h, as well as the
  326. // IP_SUFFIX_ORIGIN values in iptypes.h.
  327. //
  328. #define IID_CONF_OTHER 0 // None of the ones below.
  329. #define IID_CONF_MANUAL 1 // From a user or administrator.
  330. #define IID_CONF_WELLKNOWN 2 // IANA-assigned.
  331. #define IID_CONF_DHCP 3 // Configured via DHCP.
  332. #define IID_CONF_LL_ADDRESS 4 // Derived from the link-layer address.
  333. #define IID_CONF_RANDOM 5 // Random, e.g. anonymous address.
  334. //
  335. // Values for AddrConf - must fit in 8 bits.
  336. //
  337. #define ADDR_CONF_MANUAL ((PREFIX_CONF_MANUAL << 4) | IID_CONF_MANUAL)
  338. #define ADDR_CONF_PUBLIC ((PREFIX_CONF_RA << 4) | IID_CONF_LL_ADDRESS)
  339. #define ADDR_CONF_ANONYMOUS ((PREFIX_CONF_RA << 4) | IID_CONF_RANDOM)
  340. #define ADDR_CONF_DHCP ((PREFIX_CONF_DHCP << 4) | IID_CONF_DHCP)
  341. #define ADDR_CONF_WELLKNOWN ((PREFIX_CONF_WELLKNOWN << 4) | IID_CONF_WELLKNOWN)
  342. #define ADDR_CONF_LINK ((PREFIX_CONF_WELLKNOWN << 4) | IID_CONF_LL_ADDRESS)
  343. __inline int
  344. IsValidPrefixConfValue(uint PrefixConf)
  345. {
  346. return PrefixConf < (1 << 4);
  347. }
  348. __inline int
  349. IsValidInterfaceIdConfValue(uint InterfaceIdConf)
  350. {
  351. return InterfaceIdConf < (1 << 4);
  352. }
  353. __inline int
  354. IsStatelessAutoConfNTE(NetTableEntry *NTE)
  355. {
  356. return ((struct AddrConfEntry *)&NTE->AddrConf)->PrefixConf == PREFIX_CONF_RA;
  357. }
  358. //
  359. // Values for DADState.
  360. //
  361. // The "deprecated" and "preferred" states are valid,
  362. // meaning that addresses in those two states can be
  363. // used as a source address, can receive packets, etc.
  364. // The invalid states mean that the address is
  365. // not actually assigned to the interface,
  366. // using the terminology of RFC 2462.
  367. //
  368. // Valid<->invalid and deprecated<->preferred transitions
  369. // must call InvalidateRouteCache because they affect
  370. // source address selection.
  371. //
  372. // Among valid states, bigger is better
  373. // for source address selection.
  374. //
  375. #define DAD_STATE_INVALID 0
  376. #define DAD_STATE_TENTATIVE 1
  377. #define DAD_STATE_DUPLICATE 2
  378. #define DAD_STATE_DEPRECATED 3
  379. #define DAD_STATE_PREFERRED 4
  380. __inline int
  381. IsValidNTE(NetTableEntry *NTE)
  382. {
  383. return (NTE->DADState >= DAD_STATE_DEPRECATED);
  384. }
  385. __inline int
  386. IsTentativeNTE(NetTableEntry *NTE)
  387. {
  388. return (NTE->DADState == DAD_STATE_TENTATIVE);
  389. }
  390. //
  391. // We use this infinite lifetime value for prefix lifetimes,
  392. // router lifetimes, address lifetimes, etc.
  393. //
  394. #define INFINITE_LIFETIME 0xffffffff
  395. //
  396. // Anonymous addresses have extra fields.
  397. //
  398. typedef struct AnonNetTableEntry {
  399. NetTableEntry; // Inherit the NTE fields.
  400. NetTableEntry *Public; // Does not hold a reference.
  401. uint CreationTime; // In ticks (see IPv6TickCount).
  402. } AnonNetTableEntry;
  403. //
  404. // Each interface keeps track of which link-layer multicast addresses
  405. // are currently enabled for receive. A reference count is required because
  406. // multiple IPv6 multicast addresses can map to a single link-layer
  407. // multicast address. The low bit of RefCntAndFlags is a flag that, if set,
  408. // indicates the link-layer address has been registered with the link.
  409. //
  410. typedef struct LinkLayerMulticastAddress {
  411. uint RefCntAndFlags;
  412. uchar LinkAddress[]; // The link-layer address follows in memory.
  413. // Padded to provide alignment.
  414. } LinkLayerMulticastAddress;
  415. #define LLMA_FLAG_REGISTERED 0x1
  416. __inline void
  417. AddRefLLMA(LinkLayerMulticastAddress *LLMA)
  418. {
  419. LLMA->RefCntAndFlags += (LLMA_FLAG_REGISTERED << 1);
  420. }
  421. __inline void
  422. ReleaseLLMA(LinkLayerMulticastAddress *LLMA)
  423. {
  424. LLMA->RefCntAndFlags -= (LLMA_FLAG_REGISTERED << 1);
  425. }
  426. __inline int
  427. IsLLMAReferenced(LinkLayerMulticastAddress *LLMA)
  428. {
  429. return LLMA->RefCntAndFlags > LLMA_FLAG_REGISTERED;
  430. }
  431. //
  432. // Information about IPv6 interfaces. There can be multiple NTEs for each
  433. // interface, but there is exactly one interface per NTE.
  434. //
  435. struct Interface { // a.k.a. IF
  436. NetTableEntryOrInterface; // For NTEorIF. Points to self.
  437. Interface *Next; // Next interface on chain.
  438. long RefCnt; // Reference count - interlocked.
  439. //
  440. // Interface to the link layer. The functions all take
  441. // the LinkContext as their first argument. See comments
  442. // in llip6if.h.
  443. //
  444. void *LinkContext; // Link layer context.
  445. void (*CreateToken)(void *Context, IPv6Addr *Address);
  446. const void *(*ReadLLOpt)(void *Context, const uchar *OptionData);
  447. void (*WriteLLOpt)(void *Context, uchar *OptionData,
  448. const void *LinkAddress);
  449. ushort (*ConvertAddr)(void *Context,
  450. const IPv6Addr *Address, void *LinkAddress);
  451. NTSTATUS (*SetRouterLLAddress)(void *Context, const void *TokenLinkAddress,
  452. const void *RouterLinkAddress);
  453. void (*Transmit)(void *Context, PNDIS_PACKET Packet,
  454. uint Offset, const void *LinkAddress);
  455. NDIS_STATUS (*SetMCastAddrList)(void *Context, const void *LinkAddresses,
  456. uint NumKeep, uint NumAdd, uint NumDel);
  457. void (*Close)(void *Context);
  458. void (*Cleanup)(void *Context);
  459. uint Index; // Node unique index of this I/F.
  460. uint Type; // Values in ntddip6.h.
  461. uint Flags; // Changes require lock, reads don't.
  462. uint DefaultPreference; // Read-only.
  463. uint Preference; // For routing.
  464. //
  465. // ZoneIndices[0] (ADE_SMALLEST_SCOPE) and
  466. // ZoneIndices[1] (ADE_INTERFACE_LOCAL) must be Index.
  467. // ZoneIndices[14] (ADE_GLOBAL) and
  468. // ZoneIndices[15] (ADE_LARGEST_SCOPE) must be one.
  469. // ZoneIndices must respect zone containment:
  470. // If two interfaces have the same value for ZoneIndices[N],
  471. // then they must have the same value for ZoneIndices[N+1].
  472. // To ensure consistency, modifying ZoneIndices requires
  473. // the global ZoneUpdateLock.
  474. //
  475. uint ZoneIndices[ADE_NUM_SCOPES]; // Changes require lock, reads don't.
  476. AddressEntry *ADE; // List of ADEs on this I/F.
  477. NetTableEntry *LinkLocalNTE; // Primary link-local address.
  478. KSPIN_LOCK LockNC; // Neighbor cache lock.
  479. NeighborCacheEntry *FirstNCE; // List of active neighbors on I/F.
  480. NeighborCacheEntry *LastNCE; // Last NCE in the list.
  481. uint NCENumUnused; // Number of unused NCEs - interlocked.
  482. uint TrueLinkMTU; // Read-only, true maximum MTU.
  483. uint DefaultLinkMTU; // Read-only, default for LinkMTU.
  484. uint LinkMTU; // Manually configured or received from RAs.
  485. uint CurHopLimit; // Default Hop Limit for unicast.
  486. uint BaseReachableTime; // Base for random ReachableTime (in ms).
  487. uint ReachableTime; // Reachable timeout (in IPv6Timer ticks).
  488. uint RetransTimer; // NS timeout (in IPv6Timer ticks).
  489. uint DefaultDupAddrDetectTransmits; // Read-only.
  490. uint DupAddrDetectTransmits; // Number of solicits during DAD.
  491. uint DupAddrDetects; // Number of consecutive DAD detects.
  492. uint AnonStateAge; // Age of the anonymous state.
  493. IPv6Addr AnonState; // State for generating anonymous addresses.
  494. uint RSCount; // Number of Router Solicits sent.
  495. uint RSTimer; // RS timeout (in IPv6Timer ticks).
  496. uint RACount; // Number of "fast" RAs left to send.
  497. uint RATimer; // RA timeout (in IPv6Timer ticks).
  498. uint RALast; // Time of last RA (in IPv6Timer ticks).
  499. uint LinkAddressLength; // Length of I/F link-level address.
  500. uchar *LinkAddress; // Pointer to link-level address.
  501. uint LinkHeaderSize; // Length of link-level header.
  502. KSPIN_LOCK Lock; // Main interface lock.
  503. KMUTEX WorkerLock; // Serializes worker thread operations.
  504. LinkLayerMulticastAddress *MCastAddresses; // Current addresses.
  505. uint MCastAddrNum; // Number of link-layer mcast addresses.
  506. uint TcpInitialRTT; // InitialRTT that TCP connections should use
  507. // on this interface.
  508. HANDLE TdiRegistrationHandle; // Opaque token for TDI De/notification.
  509. GUID Guid;
  510. NDIS_STRING DeviceName; // IPV6_EXPORT_STRING_PREFIX + string Guid.
  511. };
  512. __inline NeighborCacheEntry *
  513. SentinelNCE(Interface *IF)
  514. {
  515. return (NeighborCacheEntry *) &IF->FirstNCE;
  516. }
  517. __inline uint
  518. SizeofLinkLayerMulticastAddress(Interface *IF)
  519. {
  520. uint RawSize = (sizeof(struct LinkLayerMulticastAddress) +
  521. IF->LinkAddressLength);
  522. uint Align = __builtin_alignof(struct LinkLayerMulticastAddress) - 1;
  523. return (RawSize + Align) &~ Align;
  524. }
  525. //
  526. // These values should agree with definitions also
  527. // found in llip6if.h and ntddip6.h.
  528. //
  529. #define IF_TYPE_LOOPBACK 0
  530. #define IF_TYPE_ETHERNET 1
  531. #define IF_TYPE_FDDI 2
  532. #define IF_TYPE_TUNNEL_AUTO 3
  533. #define IF_TYPE_TUNNEL_6OVER4 4
  534. #define IF_TYPE_TUNNEL_V6V4 5
  535. #define IF_TYPE_TUNNEL_6TO4 6
  536. #define IF_TYPE_TUNNEL_TEREDO 7
  537. __inline int
  538. IsIPv4TunnelIF(Interface *IF)
  539. {
  540. return ((IF_TYPE_TUNNEL_AUTO <= IF->Type) &&
  541. (IF->Type <= IF_TYPE_TUNNEL_6TO4));
  542. }
  543. //
  544. // These values should agree with definitions also
  545. // found in llip6if.h and ntddip6.h.
  546. //
  547. #define IF_FLAG_PSEUDO 0x00000001
  548. #define IF_FLAG_P2P 0x00000002
  549. #define IF_FLAG_NEIGHBOR_DISCOVERS 0x00000004
  550. #define IF_FLAG_FORWARDS 0x00000008
  551. #define IF_FLAG_ADVERTISES 0x00000010
  552. #define IF_FLAG_MULTICAST 0x00000020
  553. #define IF_FLAG_ROUTER_DISCOVERS 0x00000040
  554. #define IF_FLAG_PERIODICMLD 0x00000080
  555. #define IF_FLAG_MEDIA_DISCONNECTED 0x00001000
  556. #define IF_FLAGS_DISCOVERS \
  557. (IF_FLAG_NEIGHBOR_DISCOVERS|IF_FLAG_ROUTER_DISCOVERS)
  558. #define IF_FLAGS_BINDINFO 0x0000ffff
  559. #define IF_FLAG_DISABLED 0x00010000
  560. #define IF_FLAG_MCAST_SYNC 0x00020000
  561. #define IF_FLAG_OTHER_STATEFUL_CONFIG 0x00040000
  562. //
  563. // The DISCONNECTED and RECONNECTED flags should not both be set.
  564. // RECONNECTED indicates that the host interface was recently reconnected;
  565. // it is cleared upon receiving a Router Advertisement.
  566. //
  567. #define IF_FLAG_MEDIA_RECONNECTED 0x00080000
  568. //
  569. // This function should be used after taking the interface lock
  570. // or interface list lock, to check if the interface is disabled.
  571. //
  572. __inline int
  573. IsDisabledIF(Interface *IF)
  574. {
  575. return IF->Flags & IF_FLAG_DISABLED;
  576. }
  577. //
  578. // Called with the interface lock held.
  579. //
  580. __inline int
  581. IsMCastSyncNeeded(Interface *IF)
  582. {
  583. return IF->Flags & IF_FLAG_MCAST_SYNC;
  584. }
  585. //
  586. // Active interfaces hold a reference to themselves.
  587. // NTEs hold a reference to their interface.
  588. // NCEs that have a non-zero ref count hold a reference.
  589. // MAEs and AAEs do not hold a reference for their NTE or IF.
  590. //
  591. __inline void
  592. AddRefIF(Interface *IF)
  593. {
  594. //
  595. // A stronger assertion would be !IsDisabledIF(IF),
  596. // which is mostly true, but that assertion would
  597. // imply that AddRefIF could be used only while
  598. // holding the interface list lock or the interface lock,
  599. // which is an undesirable restriction.
  600. //
  601. ASSERT(IF->RefCnt > 0);
  602. InterlockedIncrement(&IF->RefCnt);
  603. }
  604. __inline void
  605. ReleaseIF(Interface *IF)
  606. {
  607. InterlockedDecrement(&IF->RefCnt);
  608. }
  609. //
  610. // We have a periodic timer (IPv6Timer) that causes our IPv6Timeout
  611. // routine to be called IPv6_TICKS_SECOND times per second. Most of the
  612. // timers and timeouts in this implementation are driven off this routine.
  613. //
  614. // There is a trade-off here between timer granularity/resolution
  615. // and overhead. The resolution should be subsecond because
  616. // RETRANS_TIMER is only one second.
  617. //
  618. extern uint IPv6TickCount;
  619. #define IPv6_TICKS_SECOND 2 // Two ticks per second.
  620. #define IPv6_TIMEOUT (1000 / IPv6_TICKS_SECOND) // In milliseconds.
  621. #define IPv6TimerTicks(seconds) ((seconds) * IPv6_TICKS_SECOND)
  622. //
  623. // ConvertSecondsToTicks and ConvertTicksToSeconds
  624. // both leave the value INFINITE_LIFETIME unchanged.
  625. //
  626. extern uint
  627. ConvertSecondsToTicks(uint Seconds);
  628. extern uint
  629. ConvertTicksToSeconds(uint Ticks);
  630. //
  631. // ConvertMillisToTicks and ConvertTicksToMillis
  632. // do not have an infinite value.
  633. //
  634. extern uint
  635. ConvertMillisToTicks(uint Millis);
  636. __inline uint
  637. ConvertTicksToMillis(uint Ticks)
  638. {
  639. return Ticks * IPv6_TIMEOUT;
  640. }
  641. //
  642. // REVIEW: Hack to handle those few remaining places where we still need
  643. // REVIEW: to allocate space for a link-level header before we know the
  644. // REVIEW: outgoing inteface (and thus know how big said header will be).
  645. // REVIEW: When these places have all been fixed, we won't need this.
  646. //
  647. #define MAX_LINK_HEADER_SIZE 32
  648. //
  649. // Various constants from the IPv6 RFCs...
  650. //
  651. // REVIEW: Some of these should be per link-layer type.
  652. // REVIEW: Put them in the Interface structure?
  653. //
  654. #define MAX_INITIAL_RTR_ADVERT_INTERVAL IPv6TimerTicks(16)
  655. #define MAX_INITIAL_RTR_ADVERTISEMENTS 3 // Produces 4 quick RAs.
  656. #define MAX_FINAL_RTR_ADVERTISEMENTS 3
  657. #define MIN_DELAY_BETWEEN_RAS IPv6TimerTicks(3)
  658. #define MAX_RA_DELAY_TIME 1 // 0.5 seconds
  659. #define MaxRtrAdvInterval IPv6TimerTicks(600)
  660. #define MinRtrAdvInterval IPv6TimerTicks(200)
  661. // MAX_RTR_SOLICITATION_DELAY IPv6_TIMEOUT is used instead.
  662. #define RTR_SOLICITATION_INTERVAL IPv6TimerTicks(4) // 4 seconds.
  663. #define SLOW_RTR_SOLICITATION_INTERVAL IPv6TimerTicks(15 * 60) // 15 minutes.
  664. #define MAX_RTR_SOLICITATIONS 3
  665. #define MAX_MULTICAST_SOLICIT 3 // Total transmissions before giving up.
  666. #define MAX_UNICAST_SOLICIT 3 // Total transmissions before giving up.
  667. #define MAX_UNREACH_SOLICIT 1 // Total transmissions before giving up.
  668. #define UNREACH_SOLICIT_INTERVAL IPv6TimerTicks(60) // 1 minute.
  669. #define MAX_ANYCAST_DELAY_TIME 1 // seconds.
  670. #define REACHABLE_TIME (30 * 1000) // 30 seconds in milliseconds.
  671. #define MAX_REACHABLE_TIME (60 * 60 * 1000) // 1 hour in milliseconds.
  672. #define ICMP_MIN_ERROR_INTERVAL 1 // Ticks - a half second.
  673. #define RETRANS_TIMER IPv6TimerTicks(1) // 1 second.
  674. #define DELAY_FIRST_PROBE_TIME IPv6TimerTicks(5) // 5 seconds.
  675. #define MIN_RANDOM_FACTOR 50 // Percentage of base value.
  676. #define MAX_RANDOM_FACTOR 150 // Percentage of base value.
  677. #define PREFIX_LIFETIME_SAFETY IPv6TimerTicks(2 * 60 * 60) // 2 hours.
  678. #define RECALC_REACHABLE_INTERVAL IPv6TimerTicks(3 * 60 * 60) // 3 hours.
  679. #define PATH_MTU_RETRY_TIME IPv6TimerTicks(10 * 60) // 10 minutes.
  680. #define MLD_UNSOLICITED_REPORT_INTERVAL IPv6TimerTicks(10) // 10 seconds.
  681. #define MLD_QUERY_INTERVAL IPv6TimerTicks(125) // 125 seconds.
  682. #define MLD_NUM_INITIAL_REPORTS 2
  683. #define MAX_ANON_DAD_ATTEMPTS 5
  684. #define MAX_ANON_PREFERRED_LIFETIME (24 * 60 * 60) // 1 day.
  685. #define MAX_ANON_VALID_LIFETIME (7 * MAX_ANON_PREFERRED_LIFETIME)
  686. #define ANON_REGENERATE_TIME 5 // 5 seconds.
  687. #define MAX_ANON_RANDOM_TIME (10 * 60) // 10 minutes.
  688. #define DEFAULT_CUR_HOP_LIMIT 0x80
  689. //
  690. // Various implementation constants.
  691. //
  692. #define NEIGHBOR_CACHE_LIMIT 8
  693. #define ROUTE_CACHE_LIMIT 32
  694. #define BINDING_CACHE_LIMIT 32
  695. #define SMALL_POOL 10000
  696. #define MEDIUM_POOL 30000
  697. #define LARGE_POOL 60000
  698. //
  699. // Under NT, we use the assembly language version of the common core checksum
  700. // routine instead of the C language version.
  701. //
  702. ULONG
  703. tcpxsum(IN ULONG Checksum, IN PUCHAR Source, IN ULONG Length);
  704. #define Cksum(Buffer, Length) ((ushort)tcpxsum(0, (PUCHAR)(Buffer), (Length)))
  705. //
  706. // Protocol Receive Procedures ("Next Header" handlers) have this prototype.
  707. //
  708. typedef uchar ProtoRecvProc(IPv6Packet *Packet);
  709. typedef struct StatusArg {
  710. IP_STATUS Status;
  711. unsigned long Arg;
  712. IPv6Header UNALIGNED *IP;
  713. } StatusArg;
  714. //
  715. // Protocol Control Receive Procedures have this prototype.
  716. // These receive handlers are called for ICMP errors.
  717. //
  718. typedef uchar ProtoControlRecvProc(IPv6Packet *Packet, StatusArg *Arg);
  719. typedef struct ProtocolSwitch {
  720. ProtoRecvProc *DataReceive;
  721. ProtoControlRecvProc *ControlReceive;
  722. } ProtocolSwitch;
  723. extern ProtoRecvProc IPv6HeaderReceive;
  724. extern ProtoRecvProc ICMPv6Receive;
  725. extern ProtoRecvProc FragmentReceive;
  726. extern ProtoRecvProc DestinationOptionsReceive;
  727. extern ProtoRecvProc RoutingReceive;
  728. extern ProtoRecvProc EncapsulatingSecurityPayloadReceive;
  729. extern ProtoRecvProc AuthenticationHeaderReceive;
  730. extern ProtoControlRecvProc ICMPv6ControlReceive;
  731. extern ProtoControlRecvProc ExtHdrControlReceive;
  732. //
  733. // Hop-by-Hop Options use a special receive handler.
  734. // This is because they are processed even when a
  735. // a packet is being forwarded instead of received.
  736. // Note that they are only processed when immediately
  737. // following an IPv6 header.
  738. //
  739. extern int
  740. HopByHopOptionsReceive(IPv6Packet *Packet);
  741. //
  742. // The Raw Receive handler supports external protocol handlers.
  743. //
  744. extern int RawReceive(IPv6Packet *Packet, uchar Protocol);
  745. //
  746. // The actual definition of a reassembly structure
  747. // can be found in fragment.h.
  748. //
  749. typedef struct Reassembly Reassembly;
  750. #define USE_ANON_NO 0 // Don't use anonymous addresses.
  751. #define USE_ANON_YES 1 // Use them.
  752. #define USE_ANON_ALWAYS 2 // Always generating random numbers.
  753. #define USE_ANON_COUNTER 3 // Use them with per-interface counter.
  754. //
  755. // Prototypes for global variables.
  756. //
  757. extern uint DefaultCurHopLimit;
  758. extern uint MaxAnonDADAttempts;
  759. extern uint MaxAnonPreferredLifetime; // Ticks.
  760. extern uint MaxAnonValidLifetime; // Ticks.
  761. extern uint AnonRegenerateTime; // Ticks.
  762. extern uint UseAnonymousAddresses; // See values above.
  763. extern uint MaxAnonRandomTime; // Ticks.
  764. extern uint AnonRandomTime; // Ticks.
  765. extern ProtocolSwitch ProtocolSwitchTable[];
  766. extern KSPIN_LOCK NetTableListLock;
  767. extern NetTableEntry *NetTableList; // Pointer to the net table.
  768. extern KSPIN_LOCK IFListLock;
  769. extern Interface *IFList; // List of all interfaces on the system.
  770. extern KSPIN_LOCK ZoneUpdateLock;
  771. extern struct EchoControl *ICMPv6OutstandingEchos;
  772. extern LIST_ENTRY PendingEchoList; // def needed for initialization.
  773. extern Interface *LoopInterface;
  774. extern IPv6Addr UnspecifiedAddr;
  775. extern IPv6Addr LoopbackAddr;
  776. extern IPv6Addr AllNodesOnNodeAddr;
  777. extern IPv6Addr AllNodesOnLinkAddr;
  778. extern IPv6Addr AllRoutersOnLinkAddr;
  779. extern IPv6Addr LinkLocalPrefix;
  780. extern IPv6Addr SiteLocalPrefix;
  781. extern IPv6Addr SixToFourPrefix;
  782. extern IPv6Addr V4MappedPrefix;
  783. extern PDEVICE_OBJECT IPDeviceObject;
  784. extern HANDLE IPv6ProviderHandle;
  785. //
  786. // Some handy functions for working with IPv6 addresses.
  787. //
  788. __inline IPv6Addr *
  789. AlignAddr(IPv6Addr UNALIGNED *Addr)
  790. {
  791. //
  792. // IPv6 addresses only have char & short members,
  793. // so they need 2-byte alignment.
  794. // In practice addresses in headers are always
  795. // appropriately aligned.
  796. //
  797. ASSERT(((UINT_PTR)Addr % __builtin_alignof(IPv6Addr)) == 0);
  798. return (IPv6Addr *) Addr;
  799. }
  800. __inline int
  801. IsUnspecified(const IPv6Addr *Addr)
  802. {
  803. return IP6_ADDR_EQUAL(Addr, &UnspecifiedAddr);
  804. }
  805. __inline int
  806. IsLoopback(const IPv6Addr *Addr)
  807. {
  808. return IP6_ADDR_EQUAL(Addr, &LoopbackAddr);
  809. }
  810. __inline int
  811. IsGlobal(const IPv6Addr *Addr)
  812. {
  813. //
  814. // Check the format prefix and exclude addresses
  815. // whose high 4 bits are all zero or all one.
  816. // This is a cheap way of excluding v4-compatible,
  817. // v4-mapped, loopback, multicast, link-local, site-local.
  818. //
  819. uint High = (Addr->s6_bytes[0] & 0xf0);
  820. return (High != 0) && (High != 0xf0);
  821. }
  822. __inline int
  823. IsMulticast(const IPv6Addr *Addr)
  824. {
  825. return Addr->s6_bytes[0] == 0xff;
  826. }
  827. __inline int
  828. IsLinkLocal(const IPv6Addr *Addr)
  829. {
  830. return ((Addr->s6_bytes[0] == 0xfe) &&
  831. ((Addr->s6_bytes[1] & 0xc0) == 0x80));
  832. }
  833. __inline int
  834. IsLinkLocalMulticast(const IPv6Addr *Addr)
  835. {
  836. return IsMulticast(Addr) && ((Addr->s6_bytes[1] & 0xf) == ADE_LINK_LOCAL);
  837. }
  838. __inline int
  839. IsInterfaceLocalMulticast(const IPv6Addr *Addr)
  840. {
  841. return (IsMulticast(Addr) &&
  842. ((Addr->s6_bytes[1] & 0xf) == ADE_INTERFACE_LOCAL));
  843. }
  844. extern int
  845. IsSolicitedNodeMulticast(const IPv6Addr *Addr);
  846. __inline int
  847. IsSiteLocal(const IPv6Addr *Addr)
  848. {
  849. return ((Addr->s6_bytes[0] == 0xfe) &&
  850. ((Addr->s6_bytes[1] & 0xc0) == 0xc0));
  851. }
  852. __inline int
  853. IsSiteLocalMulticast(const IPv6Addr *Addr)
  854. {
  855. return IsMulticast(Addr) && ((Addr->s6_bytes[1] & 0xf) == ADE_SITE_LOCAL);
  856. }
  857. extern int
  858. IP6_ADDR_LTEQ(const IPv6Addr *A, const IPv6Addr *B);
  859. extern int
  860. IsEUI64Address(const IPv6Addr *Addr);
  861. extern int
  862. IsKnownAnycast(const IPv6Addr *Addr);
  863. extern int
  864. IsSubnetRouterAnycast(const IPv6Addr *Addr);
  865. extern int
  866. IsSubnetReservedAnycast(const IPv6Addr *Addr);
  867. extern int
  868. IsInvalidSourceAddress(const IPv6Addr *Addr);
  869. extern int
  870. IsNotManualAddress(const IPv6Addr *Addr);
  871. extern int
  872. IsV4Compatible(const IPv6Addr *Addr);
  873. extern void
  874. CreateV4Compatible(IPv6Addr *Addr, IPAddr V4Addr);
  875. extern int
  876. IsV4Mapped(const IPv6Addr *Addr);
  877. extern void
  878. CreateV4Mapped(IPv6Addr *Addr, IPAddr V4Addr);
  879. __inline IPAddr
  880. ExtractV4Address(const IPv6Addr *Addr)
  881. {
  882. return * (IPAddr UNALIGNED *) &Addr->s6_bytes[12];
  883. }
  884. __inline int
  885. Is6to4(const IPv6Addr *Addr)
  886. {
  887. return Addr->s6_words[0] == 0x0220;
  888. }
  889. __inline IPAddr
  890. Extract6to4Address(const IPv6Addr *Addr)
  891. {
  892. return * (IPAddr UNALIGNED *) &Addr->s6_bytes[2];
  893. }
  894. __inline int
  895. IsISATAP(const IPv6Addr *Addr)
  896. {
  897. return (((Addr->s6_words[4] & 0xFFFD) == 0x0000) &&
  898. (Addr->s6_words[5] == 0xfe5e));
  899. }
  900. __inline int
  901. IsV4Multicast(IPAddr Addr)
  902. {
  903. return (Addr & 0x000000f0) == 0x000000e0;
  904. }
  905. __inline int
  906. IsV4Broadcast(IPAddr Addr)
  907. {
  908. return Addr == 0xffffffff;
  909. }
  910. __inline int
  911. IsV4Loopback(IPAddr Addr)
  912. {
  913. return (Addr & 0x000000ff) == 0x0000007f;
  914. }
  915. __inline int
  916. IsV4Unspecified(IPAddr Addr)
  917. {
  918. return (Addr & 0x000000ff) == 0x00000000;
  919. }
  920. __inline ushort
  921. MulticastAddressScope(const IPv6Addr *Addr)
  922. {
  923. return Addr->s6_bytes[1] & 0xf;
  924. }
  925. extern ushort
  926. UnicastAddressScope(const IPv6Addr *Addr);
  927. extern ushort
  928. AddressScope(const IPv6Addr *Addr);
  929. extern ushort
  930. V4AddressScope(IPAddr Addr);
  931. extern uint
  932. DetermineScopeId(const IPv6Addr *Addr, Interface *IF);
  933. extern void
  934. CreateSolicitedNodeMulticastAddress(const IPv6Addr *Addr, IPv6Addr *MCastAddr);
  935. extern int
  936. HasPrefix(const IPv6Addr *Addr, const IPv6Addr *Prefix, uint PrefixLength);
  937. extern void
  938. CopyPrefix(IPv6Addr *Addr, const IPv6Addr *Prefix, uint PrefixLength);
  939. extern uint
  940. CommonPrefixLength(const IPv6Addr *Addr, const IPv6Addr *Addr2);
  941. extern int
  942. IntersectPrefix(const IPv6Addr *Prefix1, uint Prefix1Length,
  943. const IPv6Addr *Prefix2, uint Prefix2Length);
  944. //
  945. // Function prototypes.
  946. //
  947. extern void
  948. SeedRandom(const uchar *Seed, uint Length);
  949. extern uint
  950. Random(void);
  951. extern uint
  952. RandomNumber(uint Min, uint Max);
  953. #define INET6_ADDRSTRLEN 46 // Max size of numeric form of IPv6 address
  954. #define INET_ADDRSTRLEN 16 // Max size of numeric form of IPv4 address
  955. __inline int
  956. ParseV6Address(const WCHAR *Sz, const WCHAR **Terminator, IPv6Addr *Addr)
  957. {
  958. return NT_SUCCESS(RtlIpv6StringToAddressW(Sz, Terminator, Addr));
  959. }
  960. __inline void
  961. FormatV6AddressWorker(char *Sz, const IPv6Addr *Addr)
  962. {
  963. (void) RtlIpv6AddressToStringA(Addr, Sz);
  964. }
  965. extern char *
  966. FormatV6Address(const IPv6Addr *Addr);
  967. __inline int
  968. ParseV4Address(const WCHAR *Sz, const WCHAR **Terminator, IPAddr *Addr)
  969. {
  970. return NT_SUCCESS(RtlIpv4StringToAddressW(Sz, TRUE, Terminator, (struct in_addr *)Addr));
  971. }
  972. __inline void
  973. FormatV4AddressWorker(char *Sz, IPAddr Addr)
  974. {
  975. (void) RtlIpv4AddressToStringA((struct in_addr *)&Addr, Sz);
  976. }
  977. extern char *
  978. FormatV4Address(IPAddr Addr);
  979. extern ushort
  980. ChecksumPacket(PNDIS_PACKET Packet, uint Offset, uchar *Data, uint Length,
  981. const IPv6Addr *Source, const IPv6Addr *Dest, uchar NextHeader);
  982. extern void
  983. LoopQueueTransmit(PNDIS_PACKET Packet);
  984. extern NDIS_STATUS
  985. IPv6SendLater(LARGE_INTEGER Time,
  986. Interface *IF, PNDIS_PACKET Packet,
  987. uint Offset, const void *LinkAddress);
  988. extern void
  989. IPv6SendLL(Interface *IF, PNDIS_PACKET Packet,
  990. uint Offset, const void *LinkAddress);
  991. extern void
  992. IPv6SendND(PNDIS_PACKET Packet, uint Offset, NeighborCacheEntry *NCE,
  993. const IPv6Addr *DiscoveryAddress);
  994. #define SEND_FLAG_BYPASS_BINDING_CACHE 0x00000001
  995. extern void
  996. IPv6Send(PNDIS_PACKET Packet, uint Offset, IPv6Header UNALIGNED *IP,
  997. uint PayloadLength, RouteCacheEntry *RCE, uint Flags,
  998. ushort TransportProtocol, ushort SourcePort, ushort DestPort);
  999. extern void
  1000. IPv6Forward(NetTableEntryOrInterface *RecvNTEorIF,
  1001. PNDIS_PACKET Packet, uint Offset, IPv6Header UNALIGNED *IP,
  1002. uint PayloadLength, int Redirect, IPSecProc *IPSecToDo,
  1003. RouteCacheEntry *RCE);
  1004. extern void
  1005. IPv6SendAbort(NetTableEntryOrInterface *NTEorIF,
  1006. PNDIS_PACKET Packet, uint Offset,
  1007. uchar ICMPType, uchar ICMPCode, ulong ErrorParameter,
  1008. int MulticastOverride);
  1009. extern void
  1010. ICMPv6EchoTimeout(void);
  1011. extern void
  1012. IPULUnloadNotify(void);
  1013. extern Interface *
  1014. FindInterfaceFromIndex(uint Index);
  1015. extern Interface *
  1016. FindInterfaceFromGuid(const GUID *Guid);
  1017. extern Interface *
  1018. FindNextInterface(Interface *IF);
  1019. extern Interface *
  1020. FindInterfaceFromZone(Interface *OrigIF, uint Scope, uint Index);
  1021. extern uint
  1022. FindNewZoneIndex(uint Scope);
  1023. extern void
  1024. InitZoneIndices(Interface *IF);
  1025. extern IP_STATUS
  1026. FindDefaultInterfaceForZone(uint Scope, uint ScopeId,
  1027. Interface **ScopeIF, ushort *ReturnConstrained);
  1028. extern void
  1029. IPv6Timeout(PKDPC MyDpcObject, void *Context, void *Unused1, void *Unused2);
  1030. extern int
  1031. MapNdisBuffers(NDIS_BUFFER *Buffer);
  1032. extern uchar *
  1033. GetDataFromNdis(PNDIS_BUFFER SrcBuffer, uint SrcOffset, uint Length,
  1034. uchar *DataBuffer);
  1035. extern IPv6Header UNALIGNED *
  1036. GetIPv6Header(PNDIS_PACKET Packet, uint Offset, IPv6Header *HdrBuffer);
  1037. extern int
  1038. CheckLinkLayerMulticastAddress(Interface *IF, const void *LinkAddress);
  1039. extern void
  1040. AddNTEToInterface(Interface *IF, NetTableEntry *NTE);
  1041. extern uint
  1042. InterfaceIndex(void);
  1043. extern void
  1044. AddInterface(Interface *IF);
  1045. extern void
  1046. UpdateLinkMTU(Interface *IF, uint MTU);
  1047. extern NetTableEntry *
  1048. CreateNTE(Interface *IF, const IPv6Addr *Address,
  1049. uint AddrConf,
  1050. uint ValidLifetime, uint PreferredLifetime);
  1051. extern MulticastAddressEntry *
  1052. FindOrCreateMAE(Interface *IF, const IPv6Addr *Addr, NetTableEntry *NTE);
  1053. extern MulticastAddressEntry *
  1054. FindAndReleaseMAE(Interface *IF, const IPv6Addr *Addr);
  1055. extern int
  1056. FindOrCreateAAE(Interface *IF, const IPv6Addr *Addr,
  1057. NetTableEntryOrInterface *NTEorIF);
  1058. extern int
  1059. FindAndDeleteAAE(Interface *IF, const IPv6Addr *Addr);
  1060. extern void
  1061. DestroyADEs(Interface *IF, NetTableEntry *NTE);
  1062. extern void
  1063. DestroyNTE(Interface *IF, NetTableEntry *NTE);
  1064. extern void
  1065. EnlivenNTE(Interface *IF, NetTableEntry *NTE);
  1066. extern void
  1067. DestroyIF(Interface *IF);
  1068. extern AddressEntry **
  1069. FindADE(Interface *IF, const IPv6Addr *Addr);
  1070. extern NetTableEntryOrInterface *
  1071. FindAddressOnInterface(Interface *IF, const IPv6Addr *Addr, ushort *AddrType);
  1072. extern NetTableEntry *
  1073. GetLinkLocalNTE(Interface *IF);
  1074. extern int
  1075. GetLinkLocalAddress(Interface *IF, IPv6Addr *Addr);
  1076. extern void
  1077. DeferRegisterNetAddress(NetTableEntry *NTE);
  1078. extern void
  1079. DeferSynchronizeMulticastAddresses(Interface *IF);
  1080. extern int
  1081. IPInit(void);
  1082. extern int Unloading;
  1083. extern void
  1084. IPUnload(void);
  1085. extern void
  1086. AddrConfUpdate(Interface *IF, const IPv6Addr *Prefix,
  1087. uint ValidLifetime, uint PreferredLifetime,
  1088. int Authenticated, NetTableEntry **pNTE);
  1089. extern int
  1090. FindOrCreateNTE(Interface *IF, const IPv6Addr *Addr,
  1091. uint AddrConf,
  1092. uint ValidLifetime, uint PreferredLifetime);
  1093. extern void
  1094. AddrConfDuplicate(Interface *IF, NetTableEntry *NTE);
  1095. extern void
  1096. AddrConfNotDuplicate(Interface *IF, NetTableEntry *NTE);
  1097. extern void
  1098. AddrConfResetAutoConfig(Interface *IF, uint MaxLifetime);
  1099. extern void
  1100. AddrConfTimeout(NetTableEntry *NTE);
  1101. extern void
  1102. NetTableTimeout(void);
  1103. extern void
  1104. NetTableCleanup(void);
  1105. extern void
  1106. InterfaceTimeout(void);
  1107. extern void
  1108. InterfaceCleanup(void);
  1109. extern void
  1110. InterfaceReset(void);
  1111. extern NTSTATUS
  1112. UpdateInterface(Interface *IF, int Advertises, int Forwards);
  1113. extern void
  1114. ReconnectInterface(Interface *IF);
  1115. extern void
  1116. InterfaceResetAutoConfig(Interface *IF);
  1117. extern int
  1118. LanInit(void);
  1119. extern void
  1120. LanUnload(void);
  1121. extern int
  1122. LoopbackInit(void);
  1123. extern void
  1124. ProtoTabInit(void);
  1125. extern void
  1126. ICMPv6Init(void);
  1127. extern int
  1128. IPSecInit(void);
  1129. extern void
  1130. IPSecUnload(void);
  1131. extern int
  1132. TunnelInit(void);
  1133. extern void
  1134. TunnelUnload(void);
  1135. extern NTSTATUS
  1136. TunnelCreateTunnel(IPAddr SrcAddr, IPAddr DstAddr,
  1137. uint Flags, Interface **ReturnIF);
  1138. extern int
  1139. TunnelGetSourceAddress(IPAddr Dest, IPAddr *Source);
  1140. extern ulong
  1141. NewFragmentId(void);
  1142. extern void
  1143. ReassemblyInit(void);
  1144. extern void
  1145. ReassemblyUnload(void);
  1146. extern void
  1147. ReassemblyRemove(Interface *IF);
  1148. extern void
  1149. CreateGUIDFromName(const char *Name, GUID *Guid);
  1150. extern void
  1151. ConfigureGlobalParameters(void);
  1152. extern void
  1153. ConfigureInterface(Interface *IF);
  1154. extern void
  1155. ConfigurePrefixPolicies(void);
  1156. extern void
  1157. ConfigurePersistentInterfaces(void);
  1158. #endif // IPv6DEF_INCLUDED