Leaked source code of windows server 2003
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.

2035 lines
67 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. // Transmit routines for Internet Protocol Version 6.
  14. //
  15. #include "oscfg.h"
  16. #include "ndis.h"
  17. #include "ip6imp.h"
  18. #include "ip6def.h"
  19. #include "route.h"
  20. #include "select.h"
  21. #include "icmp.h"
  22. #include "neighbor.h"
  23. #include "fragment.h"
  24. #include "security.h"
  25. #include "ipsec.h"
  26. #include "md5.h"
  27. #include "info.h"
  28. //
  29. // Structure of completion data for "Care Of" packets.
  30. //
  31. typedef struct CareOfCompletionInfo {
  32. void (*SavedCompletionHandler)(PNDIS_PACKET Packet, IP_STATUS Status);
  33. // Original handler.
  34. void *SavedCompletionData; // Original data.
  35. PNDIS_BUFFER SavedFirstBuffer;
  36. uint NumESPTrailers;
  37. } CareOfCompletionInfo;
  38. ulong FragmentId = 0;
  39. //* NewFragmentId - generate a unique fragment identifier.
  40. //
  41. // Returns a fragment id.
  42. //
  43. __inline
  44. ulong
  45. NewFragmentId(void)
  46. {
  47. return InterlockedIncrement((PLONG)&FragmentId);
  48. }
  49. //* IPv6AllocatePacket
  50. //
  51. // Allocates a single-buffer packet.
  52. //
  53. // The completion handler for the packet is set to IPv6PacketComplete,
  54. // although the caller can easily change that if desired.
  55. //
  56. NDIS_STATUS
  57. IPv6AllocatePacket(
  58. uint Length,
  59. PNDIS_PACKET *pPacket,
  60. void **pMemory)
  61. {
  62. PNDIS_PACKET Packet;
  63. PNDIS_BUFFER Buffer;
  64. void *Memory;
  65. NDIS_STATUS Status;
  66. NdisAllocatePacket(&Status, &Packet, IPv6PacketPool);
  67. if (Status != NDIS_STATUS_SUCCESS) {
  68. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  69. "IPv6AllocatePacket - couldn't allocate header!?!\n"));
  70. return Status;
  71. }
  72. Memory = ExAllocatePoolWithTagPriority(NonPagedPool, Length,
  73. IP6_TAG, LowPoolPriority);
  74. if (Memory == NULL) {
  75. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  76. "IPv6AllocatePacket - couldn't allocate pool!?!\n"));
  77. NdisFreePacket(Packet);
  78. return NDIS_STATUS_RESOURCES;
  79. }
  80. NdisAllocateBuffer(&Status, &Buffer, IPv6BufferPool,
  81. Memory, Length);
  82. if (Status != NDIS_STATUS_SUCCESS) {
  83. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  84. "IPv6AllocatePacket - couldn't allocate buffer!?!\n"));
  85. ExFreePool(Memory);
  86. NdisFreePacket(Packet);
  87. return Status;
  88. }
  89. InitializeNdisPacket(Packet);
  90. PC(Packet)->CompletionHandler = IPv6PacketComplete;
  91. NdisChainBufferAtFront(Packet, Buffer);
  92. *pPacket = Packet;
  93. *pMemory = Memory;
  94. return NDIS_STATUS_SUCCESS;
  95. }
  96. //* IPv6FreePacket - free an IPv6 packet.
  97. //
  98. // Frees a packet whose buffers were allocated from the IPv6BufferPool.
  99. //
  100. void
  101. IPv6FreePacket(PNDIS_PACKET Packet)
  102. {
  103. PNDIS_BUFFER Buffer, NextBuffer;
  104. //
  105. // Free all the buffers in the packet.
  106. // Start with the first buffer in the packet and follow the chain.
  107. //
  108. NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
  109. for (; Buffer != NULL; Buffer = NextBuffer) {
  110. VOID *Mem;
  111. UINT Unused;
  112. //
  113. // Free the buffer descriptor back to IPv6BufferPool and its
  114. // associated memory back to the heap. Not clear if it would be
  115. // safe to free the memory before the buffer (because the buffer
  116. // references the memory), but this order should definitely be safe.
  117. //
  118. NdisGetNextBuffer(Buffer, &NextBuffer);
  119. NdisQueryBuffer(Buffer, &Mem, &Unused);
  120. NdisFreeBuffer(Buffer);
  121. ExFreePool(Mem);
  122. }
  123. //
  124. // Free the packet back to IPv6PacketPool.
  125. //
  126. NdisFreePacket(Packet);
  127. }
  128. //* IPv6PacketComplete
  129. //
  130. // Generic packet completion handler.
  131. // Just frees the packet.
  132. //
  133. void
  134. IPv6PacketComplete(
  135. PNDIS_PACKET Packet,
  136. IP_STATUS Status)
  137. {
  138. UNREFERENCED_PARAMETER(Status);
  139. IPv6FreePacket(Packet);
  140. }
  141. //* IPv6CareOfComplete - Completion handler for "Care Of" packets.
  142. //
  143. // Completion handler for packets that had a routing header inserted
  144. // because of a Binding Cache Entry.
  145. //
  146. void // Returns: Nothing.
  147. IPv6CareOfComplete(
  148. PNDIS_PACKET Packet,
  149. IP_STATUS Status)
  150. {
  151. PNDIS_BUFFER Buffer;
  152. uchar *Memory;
  153. uint Length;
  154. CareOfCompletionInfo *CareOfInfo =
  155. (CareOfCompletionInfo *)PC(Packet)->CompletionData;
  156. ASSERT(CareOfInfo->SavedFirstBuffer != NULL);
  157. //
  158. // Remove the first buffer that IPv6Send created, re-chain
  159. // the original first buffer, and restore the original packet
  160. // completion info.
  161. //
  162. NdisUnchainBufferAtFront(Packet, &Buffer);
  163. NdisChainBufferAtFront(Packet, CareOfInfo->SavedFirstBuffer);
  164. PC(Packet)->CompletionHandler = CareOfInfo->SavedCompletionHandler;
  165. PC(Packet)->CompletionData = CareOfInfo->SavedCompletionData;
  166. //
  167. // Now free the removed buffer and its memory.
  168. //
  169. NdisQueryBuffer(Buffer, &Memory, &Length);
  170. NdisFreeBuffer(Buffer);
  171. ExFreePool(Memory);
  172. //
  173. // Check if there are any ESP trailers that need to be freed.
  174. //
  175. for ( ; CareOfInfo->NumESPTrailers > 0; CareOfInfo->NumESPTrailers--) {
  176. // Remove the ESP Trailer.
  177. NdisUnchainBufferAtBack(Packet, &Buffer);
  178. //
  179. // Free the removed buffer and its memory.
  180. //
  181. NdisQueryBuffer(Buffer, &Memory, &Length);
  182. NdisFreeBuffer(Buffer);
  183. ExFreePool(Memory);
  184. }
  185. //
  186. // Free care-of completion data.
  187. //
  188. ExFreePool(CareOfInfo);
  189. //
  190. // The packet should now have it's original completion handler
  191. // specified for us to call.
  192. //
  193. ASSERT(PC(Packet)->CompletionHandler != NULL);
  194. //
  195. // Call the packet's designated completion handler.
  196. //
  197. (*PC(Packet)->CompletionHandler)(Packet, Status);
  198. }
  199. //* IPv6SendComplete - IP send complete handler.
  200. //
  201. // Called by the link layer when a send completes. We're given a pointer to
  202. // a net structure, as well as the completing send packet and the final status
  203. // of the send.
  204. //
  205. // The Context argument is NULL if and only if the Packet has not
  206. // actually been handed via IPv6SendLL to a link.
  207. //
  208. // The Status argument is usually one of three values:
  209. // IP_SUCCESS
  210. // IP_PACKET_TOO_BIG
  211. // IP_GENERAL_FAILURE
  212. //
  213. // May be called in a DPC or thread context.
  214. //
  215. // To prevent recursion, send-completion routines should
  216. // avoid sending packets directly. Schedule a DPC instead.
  217. //
  218. void // Returns: Nothing.
  219. IPv6SendComplete(
  220. void *Context, // Context we gave to the link layer on registration.
  221. PNDIS_PACKET Packet, // Packet completing send.
  222. IP_STATUS Status) // Final status of send.
  223. {
  224. Interface *IF = PC(Packet)->IF;
  225. ASSERT(Context == IF);
  226. UNREFERENCED_PARAMETER(Context);
  227. if ((IF != NULL) && !(PC(Packet)->Flags & NDIS_FLAGS_DONT_LOOPBACK)) {
  228. //
  229. // Send the packet via loopback also.
  230. // The loopback code will call IPv6SendComplete again,
  231. // after setting NDIS_FLAGS_DONT_LOOPBACK.
  232. //
  233. LoopQueueTransmit(Packet);
  234. return;
  235. }
  236. //
  237. // The packet should have a completion handler specified for us to call.
  238. //
  239. ASSERT(PC(Packet)->CompletionHandler != NULL);
  240. //
  241. // Call the packet's designated completion handler.
  242. // This should free the packet.
  243. //
  244. (*PC(Packet)->CompletionHandler)(Packet, Status);
  245. //
  246. // Release the packet's reference for the sending interface,
  247. // if this packet has actually been sent.
  248. // If the packet is completed before transmission,
  249. // it does not hold a reference for the interface.
  250. //
  251. if (IF != NULL)
  252. ReleaseIF(IF);
  253. }
  254. //* IPv6SendLL
  255. //
  256. // Hands a packet down to the link-layer and/or the loopback module.
  257. //
  258. // Callable from thread or DPC context.
  259. // Must be called with no locks held.
  260. //
  261. void
  262. IPv6SendLL(
  263. Interface *IF,
  264. PNDIS_PACKET Packet,
  265. uint Offset,
  266. const void *LinkAddress)
  267. {
  268. //
  269. // The packet needs to hold a reference to the sending interface,
  270. // because the transmit is asynchronous.
  271. //
  272. AddRefIF(IF);
  273. ASSERT(PC(Packet)->IF == NULL);
  274. PC(Packet)->IF = IF;
  275. PC(Packet)->pc_offset = Offset;
  276. //
  277. // Are we sending the packet via loopback or via the link?
  278. // NDIS_FLAGS_LOOPBACK_ONLY means do NOT send via the link.
  279. // NDIS_FLAGS_DONT_LOOPBACK means do NOT send via loopback.
  280. // Finalize these flag bits here.
  281. // NB: One or both may already be set.
  282. //
  283. if (PC(Packet)->Flags & NDIS_FLAGS_MULTICAST_PACKET) {
  284. //
  285. // Multicast packets are sent both ways by default.
  286. // If the interface is not receiving this address,
  287. // then don't bother with loopback.
  288. //
  289. if (! CheckLinkLayerMulticastAddress(IF, LinkAddress))
  290. PC(Packet)->Flags |= NDIS_FLAGS_DONT_LOOPBACK;
  291. }
  292. else {
  293. //
  294. // Unicast packets are either sent via loopback
  295. // or via the link, but not both.
  296. //
  297. if (RtlCompareMemory(IF->LinkAddress, LinkAddress,
  298. IF->LinkAddressLength) == IF->LinkAddressLength)
  299. PC(Packet)->Flags |= NDIS_FLAGS_LOOPBACK_ONLY;
  300. else
  301. PC(Packet)->Flags |= NDIS_FLAGS_DONT_LOOPBACK;
  302. }
  303. //
  304. // If a packet is both looped-back and sent via the link,
  305. // we hand it to the link first and then IPv6SendComplete
  306. // handles the loopback.
  307. //
  308. if (!(PC(Packet)->Flags & NDIS_FLAGS_LOOPBACK_ONLY)) {
  309. //
  310. // Send it via the link.
  311. //
  312. (*IF->Transmit)(IF->LinkContext, Packet, Offset, LinkAddress);
  313. }
  314. else if (!(PC(Packet)->Flags & NDIS_FLAGS_DONT_LOOPBACK)) {
  315. //
  316. // Send it via loopback.
  317. //
  318. LoopQueueTransmit(Packet);
  319. }
  320. else {
  321. //
  322. // We do not send this packet.
  323. //
  324. IPv6SendComplete(IF, Packet, IP_SUCCESS);
  325. }
  326. }
  327. //
  328. // We store the Interface in our own field
  329. // instead of using PC(Packet)->IF to maintain
  330. // an invariant for IPv6SendLL and IPv6SendComplete:
  331. // PC(Packet)->IF is only set when the packet
  332. // is actually transmitted.
  333. //
  334. typedef struct IPv6SendLaterInfo {
  335. KDPC Dpc;
  336. KTIMER Timer;
  337. Interface *IF;
  338. PNDIS_PACKET Packet;
  339. uchar LinkAddress[];
  340. } IPv6SendLaterInfo;
  341. //* IPv6SendLaterWorker
  342. //
  343. // Finishes the work of IPv6SendLater by calling IPv6SendLL.
  344. //
  345. // Called in a DPC context.
  346. //
  347. void
  348. IPv6SendLaterWorker(
  349. PKDPC MyDpcObject, // The DPC object describing this routine.
  350. void *Context, // The argument we asked to be called with.
  351. void *Unused1,
  352. void *Unused2)
  353. {
  354. IPv6SendLaterInfo *Info = (IPv6SendLaterInfo *) Context;
  355. Interface *IF = Info->IF;
  356. NDIS_PACKET *Packet = Info->Packet;
  357. UNREFERENCED_PARAMETER(MyDpcObject);
  358. UNREFERENCED_PARAMETER(Unused1);
  359. UNREFERENCED_PARAMETER(Unused2);
  360. //
  361. // Finally, transmit the packet.
  362. //
  363. IPv6SendLL(IF, Packet, PC(Packet)->pc_offset, Info->LinkAddress);
  364. ReleaseIF(IF);
  365. ExFreePool(Info);
  366. }
  367. //* IPv6SendLater
  368. //
  369. // Like IPv6SendLL, but defers the actual transmit until later.
  370. // This is useful in two scenarios. First, the caller
  371. // may hold a spinlock (like an interface lock), preventing
  372. // direct use of IPv6SendLL. Second, our caller may wish
  373. // to delay the transmit for a small period of time.
  374. //
  375. // Because this function performs memory allocation, it can fail.
  376. // If it fails, the caller must dispose of the packet.
  377. //
  378. // Callable from thread or DPC context.
  379. // May be called with locks held.
  380. //
  381. NDIS_STATUS
  382. IPv6SendLater(
  383. LARGE_INTEGER Time, // Zero means immediately.
  384. Interface *IF,
  385. PNDIS_PACKET Packet,
  386. uint Offset,
  387. const void *LinkAddress)
  388. {
  389. IPv6SendLaterInfo *Info;
  390. Info = ExAllocatePoolWithTagPriority(
  391. NonPagedPool, sizeof *Info + IF->LinkAddressLength,
  392. IP6_TAG, LowPoolPriority);
  393. if (Info == NULL) {
  394. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  395. "IPv6SendLater: no pool\n"));
  396. return NDIS_STATUS_RESOURCES;
  397. }
  398. AddRefIF(IF);
  399. Info->IF = IF;
  400. PC(Packet)->pc_offset = Offset;
  401. Info->Packet = Packet;
  402. RtlCopyMemory(Info->LinkAddress, LinkAddress, IF->LinkAddressLength);
  403. KeInitializeDpc(&Info->Dpc, IPv6SendLaterWorker, Info);
  404. if (Time.QuadPart == 0) {
  405. //
  406. // Queue the DPC for immediate execution.
  407. //
  408. KeInsertQueueDpc(&Info->Dpc, NULL, NULL);
  409. }
  410. else {
  411. //
  412. // Initialize a timer that will queue the DPC later.
  413. //
  414. KeInitializeTimer(&Info->Timer);
  415. KeSetTimer(&Info->Timer, Time, &Info->Dpc);
  416. }
  417. return NDIS_STATUS_SUCCESS;
  418. }
  419. //* IPv6SendND
  420. //
  421. // IPv6 primitive for sending via Neighbor Discovery.
  422. // We already know the first-hop destination and have a completed
  423. // packet ready to send. All we really do here is check & update the
  424. // NCE's neighbor discovery state.
  425. //
  426. // Discovery Address is the source address to use in neighbor
  427. // discovery solicitations.
  428. //
  429. // If DiscoveryAddress is not NULL, it must NOT be the address
  430. // of the packet's source address, because that memory might
  431. // be gone might by the time we reference it in NeighborSolicitSend.
  432. // It must point to memory that will remain valid across
  433. // IPv6SendND's entire execution.
  434. //
  435. // If DiscoveryAddress is NULL, then the Packet must be well-formed.
  436. // It must have a valid IPv6 header. For example, the raw header-include
  437. // path can NOT pass in NULL.
  438. //
  439. // Whether the Packet is well-formed or not, the first 40 bytes
  440. // of data must be accessible in the kernel. This is because
  441. // an ND failure will lead to IPv6SendAbort, which uses GetIPv6Header,
  442. // which calls GetDataFromNdis, which calls NdisQueryBuffer,
  443. // which bugchecks when the buffer can not be mapped.
  444. //
  445. // REVIEW - Should IPv6SendND live in send.c or neighbor.c?
  446. //
  447. // Callable from thread or DPC context.
  448. //
  449. void
  450. IPv6SendND(
  451. PNDIS_PACKET Packet, // Packet to send.
  452. uint Offset, // Offset from start of Packet to IP header.
  453. NeighborCacheEntry *NCE, // First-hop neighbor information.
  454. const IPv6Addr *DiscoveryAddress) // Address to use for neighbor discovery.
  455. {
  456. NDIS_PACKET *PacketList;
  457. IPv6Addr DiscoveryAddressBuffer;
  458. KIRQL OldIrql; // For locking the interface's neighbor cache.
  459. Interface *IF; // Interface to send via.
  460. ASSERT(NCE != NULL);
  461. IF = NCE->IF;
  462. //
  463. // Are we sending to a multicast IPv6 destination?
  464. // Pass this information to IPv6SendLL.
  465. //
  466. if (IsMulticast(&NCE->NeighborAddress))
  467. PC(Packet)->Flags |= NDIS_FLAGS_MULTICAST_PACKET;
  468. RetryRequest:
  469. KeAcquireSpinLock(&IF->LockNC, &OldIrql);
  470. //
  471. // If the interface is disabled, we can't send packets.
  472. //
  473. if (IsDisabledIF(IF)) {
  474. KeReleaseSpinLock(&IF->LockNC, OldIrql);
  475. AbortRequest:
  476. IPSInfo.ipsi_outdiscards++;
  477. IPv6SendComplete(NULL, Packet, IP_GENERAL_FAILURE);
  478. return;
  479. }
  480. //
  481. // Check the Neighbor Discovery Protocol state of our Neighbor to
  482. // insure that we have current information to work with. We don't
  483. // have a timer going off to drive this in the common case, but
  484. // instead check the reachability timestamp directly here.
  485. //
  486. switch (NCE->NDState) {
  487. case ND_STATE_PERMANENT:
  488. //
  489. // This neighbor is always valid.
  490. //
  491. break;
  492. case ND_STATE_REACHABLE:
  493. //
  494. // Common case. We've verified neighbor reachability within
  495. // the last 'ReachableTime' ticks of the system interval timer.
  496. // If the time limit hasn't expired, we're free to go.
  497. //
  498. // Note that the following arithmetic will correctly handle wraps
  499. // of the IPv6 tick counter.
  500. //
  501. if ((uint)(IPv6TickCount - NCE->LastReachability) <=
  502. IF->ReachableTime) {
  503. //
  504. // Got here within the time limit. Just send it.
  505. //
  506. break;
  507. }
  508. //
  509. // Too long since last send. Entry went stale. Conceptually,
  510. // we've been in the STALE state since the above quantity went
  511. // positive. So just drop on into it now...
  512. //
  513. case ND_STATE_STALE:
  514. //
  515. // We have a stale entry in our neighbor cache. Go into DELAY
  516. // state, start the delay timer, and send the packet anyway.
  517. // NB: Internally we use PROBE state instead of DELAY.
  518. //
  519. NCE->NDState = ND_STATE_PROBE;
  520. NCE->NSTimer = DELAY_FIRST_PROBE_TIME;
  521. NCE->NSLimit = MAX_UNICAST_SOLICIT;
  522. NCE->NSCount = 0;
  523. break;
  524. case ND_STATE_PROBE:
  525. //
  526. // While in the PROBE state, we continue to send to our
  527. // cached address and hope for the best.
  528. //
  529. // First, check NSLimit. It might be MAX_UNREACH_SOLICIT or
  530. // MAX_UNICAST_SOLICIT. Ensure it's at least MAX_UNICAST_SOLICIT.
  531. //
  532. if (NCE->NSLimit < MAX_UNICAST_SOLICIT)
  533. NCE->NSLimit = MAX_UNICAST_SOLICIT;
  534. //
  535. // Second, if we have not started actively probing yet, ensure
  536. // we do not wait longer than DELAY_FIRST_PROBE_TIME to start.
  537. //
  538. if ((NCE->NSCount == 0) && (NCE->NSTimer > DELAY_FIRST_PROBE_TIME))
  539. NCE->NSTimer = DELAY_FIRST_PROBE_TIME;
  540. break;
  541. case ND_STATE_INCOMPLETE: {
  542. PNDIS_PACKET OldPacket;
  543. int SendSolicit;
  544. if (!(IF->Flags & IF_FLAG_NEIGHBOR_DISCOVERS)) {
  545. //
  546. // This interface does not support Neighbor Discovery.
  547. // We can not resolve the address.
  548. // Mark the neighbor unreachable and invalidate the route cache.
  549. // This gives FindNextHop an opportunity to round-robin.
  550. //
  551. NCE->IsUnreachable = TRUE;
  552. NCE->LastReachability = IPv6TickCount; // Timestamp it.
  553. NCE->DoRoundRobin = TRUE;
  554. InvalidateRouteCache();
  555. KeReleaseSpinLock(&IF->LockNC, OldIrql);
  556. IPSInfo.ipsi_outnoroutes++;
  557. IPv6SendAbort(CastFromIF(IF), Packet, Offset,
  558. ICMPv6_DESTINATION_UNREACHABLE,
  559. ICMPv6_ADDRESS_UNREACHABLE, 0, FALSE);
  560. return;
  561. }
  562. //
  563. // Get DiscoveryAddress from the packet
  564. // if we don't already have it.
  565. // We SHOULD use the packet's source address if possible.
  566. //
  567. if (DiscoveryAddress == NULL) {
  568. IPv6Header UNALIGNED *IP;
  569. IPv6Header HdrBuffer;
  570. NetTableEntry *NTE;
  571. int IsValid;
  572. KeReleaseSpinLock(&IF->LockNC, OldIrql);
  573. DiscoveryAddress = &DiscoveryAddressBuffer;
  574. //
  575. // Get the packet's source address.
  576. // Anyone sending possibly-malformed packets (eg RawSend)
  577. // must specify DiscoveryAddress, so GetIPv6Header
  578. // will always succeed.
  579. //
  580. IP = GetIPv6Header(Packet, Offset, &HdrBuffer);
  581. ASSERT(IP != NULL);
  582. DiscoveryAddressBuffer = IP->Source;
  583. //
  584. // Check that the address is a valid unicast address
  585. // assigned to the outgoing interface.
  586. //
  587. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  588. NTE = (NetTableEntry *) *FindADE(IF, DiscoveryAddress);
  589. IsValid = ((NTE != NULL) &&
  590. (NTE->Type == ADE_UNICAST) &&
  591. IsValidNTE(NTE));
  592. KeReleaseSpinLock(&IF->Lock, OldIrql);
  593. if (! IsValid) {
  594. //
  595. // Can't use the packet's source address.
  596. // Try the interface's link-local address.
  597. //
  598. if (! GetLinkLocalAddress(IF, &DiscoveryAddressBuffer)) {
  599. //
  600. // Without a valid link-local address, give up.
  601. //
  602. goto AbortRequest;
  603. }
  604. }
  605. //
  606. // Now that we have a valid DiscoveryAddress,
  607. // start over.
  608. //
  609. goto RetryRequest;
  610. }
  611. //
  612. // We do not have a valid link-layer address for the neighbor.
  613. // We must queue the packet, pending neighbor discovery.
  614. // Remember the packet's offset in the Packet6Context area.
  615. // REVIEW: For now, wait queue is just one packet deep.
  616. //
  617. OldPacket = NCE->WaitQueue;
  618. PC(Packet)->pc_offset = Offset;
  619. PC(Packet)->DiscoveryAddress = *DiscoveryAddress;
  620. NCE->WaitQueue = Packet;
  621. //
  622. // If we have not started neighbor discovery yet,
  623. // do so now by sending the first solicit.
  624. // It would be simpler to let NeighborCacheEntryTimeout
  625. // send the first solicit but that would introduce latency.
  626. //
  627. SendSolicit = (NCE->NSCount == 0);
  628. if (SendSolicit) {
  629. //
  630. // We send the first solicit below.
  631. //
  632. NCE->NSCount = 1;
  633. //
  634. // If NSTimer is zero, we need to initialize NSLimit.
  635. //
  636. if (NCE->NSTimer == 0)
  637. NCE->NSLimit = MAX_MULTICAST_SOLICIT;
  638. NCE->NSTimer = (ushort)IF->RetransTimer;
  639. }
  640. //
  641. // NSLimit might be MAX_MULTICAST_SOLICIT or MAX_UNREACH_SOLICIT.
  642. // Ensure that it is at least MAX_MULTICAST_SOLICIT.
  643. //
  644. if (NCE->NSLimit < MAX_MULTICAST_SOLICIT)
  645. NCE->NSLimit = MAX_MULTICAST_SOLICIT;
  646. //
  647. // If there are any packets waiting to be completed, take
  648. // this opportunity. With an active DoS attack, we want
  649. // to do this more frequently than NeighborCacheTimeout will.
  650. //
  651. PacketList = IF->PacketList;
  652. IF->PacketList = NULL;
  653. KeReleaseSpinLock(&IF->LockNC, OldIrql);
  654. NeighborCacheCompletePackets(IF, PacketList);
  655. if (SendSolicit)
  656. NeighborSolicitSend(NCE, DiscoveryAddress);
  657. if (OldPacket != NULL) {
  658. //
  659. // This queue overflow is congestion of a sort,
  660. // so we must not send an ICMPv6 error.
  661. //
  662. IPSInfo.ipsi_outdiscards++;
  663. IPv6SendComplete(NULL, OldPacket, IP_GENERAL_FAILURE);
  664. }
  665. return;
  666. }
  667. default:
  668. //
  669. // Should never happen.
  670. //
  671. ABORTMSG("IPv6SendND: Invalid Neighbor Cache NDState field!\n");
  672. }
  673. //
  674. // Move the NCE to the head of the LRU list,
  675. // because we are using it to send a packet.
  676. //
  677. if (NCE != IF->FirstNCE) {
  678. //
  679. // Remove NCE from the list.
  680. //
  681. NCE->Next->Prev = NCE->Prev;
  682. NCE->Prev->Next = NCE->Next;
  683. //
  684. // Add NCE to the head of the list.
  685. //
  686. NCE->Next = IF->FirstNCE;
  687. NCE->Next->Prev = NCE;
  688. NCE->Prev = SentinelNCE(IF);
  689. NCE->Prev->Next = NCE;
  690. ASSERT(IF->FirstNCE == NCE);
  691. }
  692. //
  693. // Unlock before transmitting the packet.
  694. // This means that there is a very small chance that NCE->LinkAddress
  695. // could change out from underneath us. (For example, if we process
  696. // an advertisement changing the link-layer address.)
  697. // In practice this won't happen, and if it does the worst that
  698. // will happen is that we'll send a packet somewhere strange.
  699. // The best alternative is copying the LinkAddress.
  700. //
  701. KeReleaseSpinLock(&IF->LockNC, OldIrql);
  702. IPv6SendLL(IF, Packet, Offset, NCE->LinkAddress);
  703. }
  704. //
  705. // Context information that is used for fragmentation.
  706. // This information is carried between calls to IPv6SendFragment.
  707. //
  708. typedef struct FragmentationInfo {
  709. PNDIS_PACKET Packet; // Unfragmented packet.
  710. long NumLeft; // Number of uncompleted fragments.
  711. IP_STATUS Status; // Current status.
  712. } FragmentationInfo;
  713. //* IPv6SendFragmentComplete
  714. //
  715. // Completion handler, called when a fragment has been sent.
  716. //
  717. void
  718. IPv6SendFragmentComplete(
  719. PNDIS_PACKET Packet,
  720. IP_STATUS Status)
  721. {
  722. FragmentationInfo *Info = PC(Packet)->CompletionData;
  723. //
  724. // Free the fragment packet.
  725. //
  726. IPv6FreePacket(Packet);
  727. //
  728. // Update the current cumulative status.
  729. //
  730. InterlockedCompareExchange((PLONG)&Info->Status, Status, IP_SUCCESS);
  731. if (InterlockedDecrement(&Info->NumLeft) == 0) {
  732. //
  733. // This is the last fragment to complete.
  734. //
  735. IPv6SendComplete(NULL, Info->Packet, Info->Status);
  736. ExFreePool(Info);
  737. }
  738. }
  739. //* IPv6SendFragments - Fragment an IPv6 datagram.
  740. //
  741. // Helper routine for creating and sending IPv6 fragments.
  742. // Called from IPv6Send when the datagram is bigger than the path MTU.
  743. //
  744. // The PathMTU is passed separately so that we use a consistent value.
  745. // The value in the RCE is subject to change.
  746. //
  747. // NB: We assume that the packet has well-formed, contiguous headers.
  748. //
  749. void
  750. IPv6SendFragments(
  751. PNDIS_PACKET Packet, // Packet to send.
  752. uint Offset, // Offset from start of Packet to IP header.
  753. IPv6Header UNALIGNED *IP, // Pointer to Packet's IPv6 header.
  754. uint PayloadLength, // Packet payload length.
  755. RouteCacheEntry *RCE, // First-hop neighbor information.
  756. uint PathMTU) // PathMTU to use when fragmenting.
  757. {
  758. FragmentationInfo *Info;
  759. NeighborCacheEntry *NCE = RCE->NCE;
  760. NDIS_STATUS NdisStatus;
  761. IP_STATUS IPStatus;
  762. PNDIS_PACKET FragPacket;
  763. FragmentHeader FragHdr;
  764. uchar *Mem;
  765. uint MemLen;
  766. uint PktOffset;
  767. uint UnfragBytes;
  768. uint BytesLeft;
  769. uint BytesSent;
  770. uchar HdrType;
  771. uchar *tbuf;
  772. PNDIS_BUFFER SrcBuffer;
  773. uint SrcOffset;
  774. uint NextHeaderOffset;
  775. uint FragPayloadLength;
  776. //
  777. // A PathMTU value of zero is special -
  778. // it means that we should use the minimum MTU
  779. // and always include a fragment header.
  780. //
  781. if (PathMTU == 0)
  782. PathMTU = IPv6_MINIMUM_MTU;
  783. else
  784. ASSERT(PathMTU >= IPv6_MINIMUM_MTU);
  785. //
  786. // Determine the 'unfragmentable' portion of this packet.
  787. // We do this by scanning through all extension headers,
  788. // and noting the last occurrence, if any, of
  789. // a routing or hop-by-hop header.
  790. // We do not assume the extension headers are in recommended order,
  791. // but otherwise we assume that the headers are well-formed.
  792. // We also assume that they are contiguous.
  793. //
  794. UnfragBytes = sizeof *IP;
  795. HdrType = IP->NextHeader;
  796. NextHeaderOffset = (uint)((uchar *)&IP->NextHeader - (uchar *)IP);
  797. tbuf = (uchar *)(IP + 1);
  798. while ((HdrType == IP_PROTOCOL_HOP_BY_HOP) ||
  799. (HdrType == IP_PROTOCOL_ROUTING) ||
  800. (HdrType == IP_PROTOCOL_DEST_OPTS)) {
  801. ExtensionHeader *EHdr = (ExtensionHeader *) tbuf;
  802. uint EHdrLen = (EHdr->HeaderExtLength + 1) * 8;
  803. tbuf += EHdrLen;
  804. if (HdrType != IP_PROTOCOL_DEST_OPTS) {
  805. UnfragBytes = (uint)(tbuf - (uchar *)IP);
  806. NextHeaderOffset = (uint)((uchar *)&EHdr->NextHeader - (uchar *)IP);
  807. }
  808. HdrType = EHdr->NextHeader;
  809. }
  810. //
  811. // Suppose we have a routing header followed by
  812. // a destination-options header. Then the routing header
  813. // is unfragmentable but the destination options are
  814. // fragmentable, so HdrType should be IP_PROTOCOL_DEST_OPTS.
  815. //
  816. HdrType = *((uchar *)IP + NextHeaderOffset);
  817. //
  818. // Check that we can actually fragment this packet.
  819. // If the unfragmentable part is too large, we can't.
  820. // We need to send at least 8 bytes of fragmentable data
  821. // in each fragment.
  822. //
  823. if (UnfragBytes + sizeof(FragmentHeader) + 8 > PathMTU) {
  824. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_USER_ERROR,
  825. "IPv6SendFragments: can't fragment\n"));
  826. IPStatus = IP_GENERAL_FAILURE;
  827. goto ErrorExit;
  828. }
  829. FragHdr.NextHeader = HdrType;
  830. FragHdr.Reserved = 0;
  831. FragHdr.Id = net_long(NewFragmentId());
  832. //
  833. // Initialize SrcBuffer and SrcOffset, which point
  834. // to the fragmentable data in the packet.
  835. // SrcOffset is the offset into SrcBuffer's data,
  836. // NOT an offset into the packet.
  837. //
  838. SrcBuffer = NdisFirstBuffer(Packet);
  839. SrcOffset = Offset + UnfragBytes;
  840. //
  841. // Create new packets of MTU size until all data is sent.
  842. //
  843. BytesLeft = sizeof *IP + PayloadLength - UnfragBytes;
  844. PktOffset = 0; // relative to fragmentable part of original packet
  845. //
  846. // We need a completion context for the fragments.
  847. //
  848. Info = ExAllocatePoolWithTagPriority(NonPagedPool, sizeof *Info,
  849. IP6_TAG, LowPoolPriority);
  850. if (Info == NULL) {
  851. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  852. "IPv6SendFragments: no pool\n"));
  853. IPStatus = IP_NO_RESOURCES;
  854. goto ErrorExit;
  855. }
  856. Info->Packet = Packet;
  857. Info->NumLeft = 1; // A reference for our own processing.
  858. Info->Status = IP_SUCCESS;
  859. while (BytesLeft != 0) {
  860. //
  861. // Determine new IP payload length (a multiple of 8) and
  862. // and set the Fragment Header offset.
  863. //
  864. if ((BytesLeft + UnfragBytes + sizeof(FragmentHeader)) > PathMTU) {
  865. BytesSent = (PathMTU - UnfragBytes - sizeof(FragmentHeader)) &~ 7;
  866. // Not the last fragment, so turn on the M bit.
  867. FragHdr.OffsetFlag = net_short((ushort)(PktOffset | 1));
  868. } else {
  869. BytesSent = BytesLeft;
  870. FragHdr.OffsetFlag = net_short((ushort)PktOffset);
  871. }
  872. //
  873. // Allocate packet (and a buffer) and Memory for new fragment
  874. //
  875. MemLen = Offset + UnfragBytes + sizeof(FragmentHeader) + BytesSent;
  876. NdisStatus = IPv6AllocatePacket(MemLen, &FragPacket, &Mem);
  877. if (NdisStatus != NDIS_STATUS_SUCCESS) {
  878. InterlockedCompareExchange((PLONG)&Info->Status,
  879. IP_NO_RESOURCES, IP_SUCCESS);
  880. break;
  881. }
  882. //
  883. // Copy IP header, Frag Header, and a portion of data to fragment.
  884. //
  885. RtlCopyMemory(Mem + Offset, IP, UnfragBytes);
  886. RtlCopyMemory(Mem + Offset + UnfragBytes, &FragHdr,
  887. sizeof FragHdr);
  888. if (! CopyNdisToFlat(Mem + Offset + UnfragBytes + sizeof FragHdr,
  889. SrcBuffer, SrcOffset, BytesSent,
  890. &SrcBuffer, &SrcOffset)) {
  891. IPv6FreePacket(FragPacket);
  892. InterlockedCompareExchange((PLONG)&Info->Status,
  893. IP_NO_RESOURCES, IP_SUCCESS);
  894. break;
  895. }
  896. //
  897. // Correct the PayloadLength and NextHeader fields.
  898. //
  899. FragPayloadLength = UnfragBytes + sizeof(FragmentHeader) +
  900. BytesSent - sizeof(IPv6Header);
  901. ASSERT(FragPayloadLength <= MAX_IPv6_PAYLOAD);
  902. ((IPv6Header UNALIGNED *)(Mem + Offset))->PayloadLength =
  903. net_short((ushort) FragPayloadLength);
  904. ASSERT(Mem[Offset + NextHeaderOffset] == HdrType);
  905. Mem[Offset + NextHeaderOffset] = IP_PROTOCOL_FRAGMENT;
  906. BytesLeft -= BytesSent;
  907. PktOffset += BytesSent;
  908. //
  909. // Pick up any flags (like loopback-only) from the original packet.
  910. //
  911. PC(FragPacket)->Flags = PC(Packet)->Flags;
  912. //
  913. // Setup our completion handler and increment
  914. // the number of outstanding users of the completion data.
  915. //
  916. PC(FragPacket)->CompletionHandler = IPv6SendFragmentComplete;
  917. PC(FragPacket)->CompletionData = Info;
  918. InterlockedIncrement(&Info->NumLeft);
  919. //
  920. // Send the fragment.
  921. //
  922. IPSInfo.ipsi_fragcreates++;
  923. IPv6SendND(FragPacket, Offset, NCE, NULL);
  924. }
  925. if (InterlockedDecrement(&Info->NumLeft) == 0) {
  926. //
  927. // Amazingly, the fragments have already completed.
  928. // Complete the original packet now.
  929. //
  930. IPv6SendComplete(NULL, Packet, Info->Status);
  931. ExFreePool(Info);
  932. }
  933. else {
  934. //
  935. // IPv6SendFragmentComplete will complete the original packet
  936. // when all the fragments are completed.
  937. //
  938. }
  939. IPSInfo.ipsi_fragoks++;
  940. return;
  941. ErrorExit:
  942. IPSInfo.ipsi_fragfails++;
  943. IPv6SendComplete(NULL, Packet, IPStatus);
  944. }
  945. //* IPv6Send
  946. //
  947. // High-level IPv6 send routine. We have a completed datagram and a
  948. // RCE indicating where to direct it to. Here we deal with any packetization
  949. // issues (inserting a Jumbo Payload option, fragmentation, etc.) that are
  950. // necessary, and pick a NCE for the first hop.
  951. //
  952. // We also add any additional extension headers to the packet that may be
  953. // required for mobility (routing header) or security (AH, ESP header).
  954. // TBD: This design may change to move those header inclusions elsewhere.
  955. //
  956. // Note that this routine expects a properly formatted IPv6 packet, and
  957. // also that all of the headers are contained within the first NDIS buffer.
  958. // It performs no checking of these requirements.
  959. //
  960. void
  961. IPv6Send(
  962. PNDIS_PACKET Packet, // Packet to send.
  963. uint Offset, // Offset from start of Packet to IP header.
  964. IPv6Header UNALIGNED *IP, // Pointer to Packet's IPv6 header.
  965. uint PayloadLength, // Packet payload length.
  966. RouteCacheEntry *RCE, // First-hop neighbor information.
  967. uint Flags, // Flags for special handling.
  968. ushort TransportProtocol,
  969. ushort SourcePort,
  970. ushort DestPort)
  971. {
  972. uint PacketLength; // Size of complete IP packet in bytes.
  973. NeighborCacheEntry *NCE; // First-hop neighbor information.
  974. uint PathMTU;
  975. PNDIS_BUFFER OrigBuffer1, NewBuffer1;
  976. uchar *OrigMemory, *NewMemory,
  977. *EndOrigMemory, *EndNewMemory, *InsertPoint;
  978. uint OrigBufSize, NewBufSize, TotalPacketSize, Size, RtHdrSize = 0;
  979. IPv6RoutingHeader *SavedRtHdr = NULL, *RtHdr = NULL;
  980. IPv6Header UNALIGNED *IPNew;
  981. uint BytesToInsert = 0;
  982. uchar *BufPtr, *PrevNextHdr;
  983. ExtensionHeader *EHdr;
  984. uint EHdrLen;
  985. uchar HdrType;
  986. NDIS_STATUS Status;
  987. RouteCacheEntry *CareOfRCE = NULL;
  988. RouteCacheEntry *TunnelRCE = NULL;
  989. CareOfCompletionInfo *CareOfInfo;
  990. KIRQL OldIrql;
  991. IPSecProc *IPSecToDo;
  992. uint Action;
  993. uint i;
  994. uint TunnelStart = NO_TUNNEL;
  995. uint JUST_ESP = FALSE;
  996. uint IPSEC_TUNNEL = FALSE;
  997. uint NumESPTrailers = 0;
  998. IPSIncrementOutRequestCount();
  999. //
  1000. // Find the Security Policy for this outbound traffic.
  1001. // Current Mobile IPv6 draft says to use a mobile node's home address
  1002. // and not its care-of address as the selector for security policy lookup.
  1003. //
  1004. IPSecToDo = OutboundSPLookup(AlignAddr(&IP->Source),
  1005. AlignAddr(&IP->Dest),
  1006. TransportProtocol,
  1007. SourcePort, DestPort,
  1008. RCE->NTE->IF, &Action);
  1009. if (IPSecToDo == NULL) {
  1010. //
  1011. // Check Action.
  1012. // Just fall through for LOOKUP_BYPASS.
  1013. //
  1014. if (Action == LOOKUP_DROP) {
  1015. // Drop packet.
  1016. goto AbortSend;
  1017. }
  1018. if (Action == LOOKUP_IKE_NEG) {
  1019. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1020. "IPv6Send: IKE not supported yet.\n"));
  1021. goto AbortSend;
  1022. }
  1023. } else {
  1024. //
  1025. // Calculate the space needed for the IPSec headers.
  1026. //
  1027. BytesToInsert = IPSecBytesToInsert(IPSecToDo, &TunnelStart, NULL);
  1028. if (TunnelStart != NO_TUNNEL) {
  1029. IPSEC_TUNNEL = TRUE;
  1030. }
  1031. }
  1032. //
  1033. // If this packet is being sent to a mobile node's care-of address,
  1034. // then we'll use the CareOfRCE instead of the one our caller gave us.
  1035. //
  1036. if ((RCE->BCE != NULL) &&
  1037. !(Flags & SEND_FLAG_BYPASS_BINDING_CACHE)) {
  1038. KeAcquireSpinLock(&RouteCacheLock, &OldIrql);
  1039. if (RCE->BCE != NULL) {
  1040. MoveToFrontBCE(RCE->BCE);
  1041. CareOfRCE = RCE->BCE->CareOfRCE;
  1042. AddRefRCE(CareOfRCE);
  1043. KeReleaseSpinLock(&RouteCacheLock, OldIrql);
  1044. RCE = CareOfRCE;
  1045. } else
  1046. KeReleaseSpinLock(&RouteCacheLock, OldIrql);
  1047. }
  1048. //
  1049. // Step through headers.
  1050. //
  1051. HdrType = IP->NextHeader;
  1052. PrevNextHdr = &IP->NextHeader;
  1053. BufPtr = (uchar *)(IP + 1);
  1054. //
  1055. // Skip the hop-by-hop header if it exists. Don't skip
  1056. // dest options, since dest options (e.g. BindAck) usually
  1057. // want IPsec and need to go after the RH/AH/ESP. As a result,
  1058. // the only current way to get intermediate destination options
  1059. // is to compose the packet before calling IPv6Send.
  1060. //
  1061. while (HdrType == IP_PROTOCOL_HOP_BY_HOP) {
  1062. EHdr = (ExtensionHeader *) BufPtr;
  1063. EHdrLen = (EHdr->HeaderExtLength + 1) * 8;
  1064. BufPtr += EHdrLen;
  1065. HdrType = EHdr->NextHeader;
  1066. PrevNextHdr = &EHdr->NextHeader;
  1067. }
  1068. //
  1069. // Check if there is a routing header. If this packet is being sent
  1070. // to a care-of address, then it must contain a routing extension header.
  1071. // If one already exists then add the destination address as the last
  1072. // entry. If no routing header exists insert one with the home address as
  1073. // the first (and only) address.
  1074. //
  1075. // This code assumes that the packet is contiguous at least up to the
  1076. // insertion point.
  1077. //
  1078. if (HdrType == IP_PROTOCOL_ROUTING) {
  1079. EHdr = (ExtensionHeader *) BufPtr;
  1080. EHdrLen = (EHdr->HeaderExtLength + 1) * 8;
  1081. RtHdrSize = EHdrLen;
  1082. PrevNextHdr = &EHdr->NextHeader;
  1083. //
  1084. // Check if this header will be modified due to mobility.
  1085. //
  1086. if (CareOfRCE) {
  1087. // Save Routing Header location for later use.
  1088. RtHdr = (IPv6RoutingHeader *)BufPtr;
  1089. //
  1090. // Check if there is room to store the Home Address.
  1091. // REVIEW: Is this necessary, what should happen
  1092. // REVIEW: if the routing header is full?
  1093. //
  1094. if (RtHdr->HeaderExtLength / 2 < 23) {
  1095. BytesToInsert += sizeof (IPv6Addr);
  1096. }
  1097. } else {
  1098. // Adjust BufPtr to end of routing header.
  1099. BufPtr += EHdrLen;
  1100. }
  1101. } else {
  1102. //
  1103. // No routing header present, but check if one needs to be
  1104. // inserted due to mobility.
  1105. //
  1106. if (CareOfRCE) {
  1107. BytesToInsert += (sizeof (IPv6RoutingHeader) + sizeof (IPv6Addr));
  1108. }
  1109. }
  1110. // Only will happen for IPSec bypass mode with no mobility.
  1111. if (BytesToInsert == 0) {
  1112. //
  1113. // Nothing to do.
  1114. //
  1115. Action = LOOKUP_CONT;
  1116. goto ContinueSend;
  1117. }
  1118. //
  1119. // We have something to insert. We will replace the packet's
  1120. // first NDIS_BUFFER with a new buffer that we allocate to hold the
  1121. // all data from the existing first buffer plus the inserted data.
  1122. //
  1123. //
  1124. // We get the first buffer and determine its size, then
  1125. // allocate memory for the new buffer.
  1126. //
  1127. NdisGetFirstBufferFromPacket(Packet, &OrigBuffer1, &OrigMemory,
  1128. &OrigBufSize, &TotalPacketSize);
  1129. TotalPacketSize -= Offset;
  1130. NewBufSize = (OrigBufSize - Offset) + MAX_LINK_HEADER_SIZE + BytesToInsert;
  1131. Offset = MAX_LINK_HEADER_SIZE;
  1132. NewMemory = ExAllocatePoolWithTagPriority(NonPagedPool, NewBufSize,
  1133. IP6_TAG, LowPoolPriority);
  1134. if (NewMemory == NULL) {
  1135. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1136. "IPv6Send: - couldn't allocate pool!?!\n"));
  1137. goto AbortSend;
  1138. }
  1139. NdisAllocateBuffer(&Status, &NewBuffer1, IPv6BufferPool, NewMemory,
  1140. NewBufSize);
  1141. if (Status != NDIS_STATUS_SUCCESS) {
  1142. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1143. "IPv6Send - couldn't allocate buffer!?!\n"));
  1144. ExFreePool(NewMemory);
  1145. goto AbortSend;
  1146. }
  1147. //
  1148. // We've sucessfully allocated a new buffer. Now copy the data from
  1149. // the existing buffer to the new one. First we copy all data after
  1150. // the insertion point. This is essentially the transport layer data
  1151. // (no Extension headers).
  1152. //
  1153. //
  1154. // Calculate Insertion Point for upper layer data.
  1155. //
  1156. EndOrigMemory = OrigMemory + OrigBufSize;
  1157. EndNewMemory = NewMemory + NewBufSize;
  1158. Size = (uint)(EndOrigMemory - BufPtr);
  1159. InsertPoint = EndNewMemory - Size;
  1160. // Copy upper layer data to end of new buffer.
  1161. RtlCopyMemory(InsertPoint, BufPtr, Size);
  1162. BytesToInsert = 0;
  1163. //
  1164. // Insert Transport IPSec headers.
  1165. //
  1166. if (IPSecToDo) {
  1167. Action = IPSecInsertHeaders(TRANSPORT, IPSecToDo, &InsertPoint,
  1168. NewMemory, Packet, &TotalPacketSize,
  1169. PrevNextHdr, TunnelStart, &BytesToInsert,
  1170. &NumESPTrailers, &JUST_ESP);
  1171. if (Action == LOOKUP_DROP) {
  1172. NdisFreeBuffer(NewBuffer1);
  1173. ExFreePool(NewMemory);
  1174. goto AbortSend;
  1175. }
  1176. } // end of if (IPSecToDo).
  1177. //
  1178. // Check if mobility needs to be done.
  1179. //
  1180. if (CareOfRCE) {
  1181. // Check if routing header is already present in original buffer..
  1182. if (RtHdr != NULL) {
  1183. //
  1184. // Need to insert the home address in the routing header.
  1185. //
  1186. RtHdrSize += sizeof (IPv6Addr);
  1187. // Move insert point up to start of routing header.
  1188. InsertPoint -= RtHdrSize;
  1189. BytesToInsert += sizeof(IPv6Addr);
  1190. // Insert the routing header.
  1191. RtlCopyMemory(InsertPoint, RtHdr, RtHdrSize - sizeof(IPv6Addr));
  1192. // Insert the Home address.
  1193. RtlCopyMemory(InsertPoint + RtHdrSize - sizeof (IPv6Addr),
  1194. &IP->Dest, sizeof (IPv6Addr));
  1195. RtHdr = (IPv6RoutingHeader *)InsertPoint;
  1196. // Adjust size of routing header.
  1197. RtHdr->HeaderExtLength += 2;
  1198. } else {
  1199. //
  1200. // No routing header present - need to create new Routing header.
  1201. //
  1202. RtHdrSize = sizeof (IPv6RoutingHeader) + sizeof(IPv6Addr);
  1203. // Move insert point up to start of routing header.
  1204. InsertPoint -= RtHdrSize;
  1205. BytesToInsert += RtHdrSize;
  1206. //
  1207. // Insert an entire routing header.
  1208. //
  1209. RtHdr = (IPv6RoutingHeader *)InsertPoint;
  1210. RtHdr->NextHeader = *PrevNextHdr;
  1211. RtHdr->HeaderExtLength = 2;
  1212. RtHdr->RoutingType = 0;
  1213. RtlZeroMemory(&RtHdr->Reserved, sizeof RtHdr->Reserved);
  1214. RtHdr->SegmentsLeft = 1;
  1215. // Insert the home address.
  1216. RtlCopyMemory(RtHdr + 1, &IP->Dest, sizeof (IPv6Addr));
  1217. //
  1218. // Fix the previous NextHeader field to indicate that it now points
  1219. // to a routing header.
  1220. //
  1221. *(PrevNextHdr) = IP_PROTOCOL_ROUTING;
  1222. }
  1223. // Change the destination IPv6 address to the care-of address.
  1224. RtlCopyMemory(&IP->Dest, &CareOfRCE->Destination, sizeof (IPv6Addr));
  1225. } // end of if (CareOfRCE)
  1226. //
  1227. // Copy original IP plus any extension headers.
  1228. // If a care-of address was added, the Routing header is not part
  1229. // of this copy because it has already been copied.
  1230. //
  1231. Size = (uint)(BufPtr - (uchar *)IP);
  1232. // Move insert point up to start of IP.
  1233. InsertPoint -= Size;
  1234. // Adjust length of payload.
  1235. PayloadLength += BytesToInsert;
  1236. // Set the new IP payload length.
  1237. IP->PayloadLength = net_short((ushort)PayloadLength);
  1238. RtlCopyMemory(InsertPoint, (uchar *)IP, Size);
  1239. IPNew = (IPv6Header UNALIGNED *)InsertPoint;
  1240. //
  1241. // Check if any Transport mode IPSec was performed and
  1242. // if mutable fields need to be adjusted.
  1243. //
  1244. if (TunnelStart != 0 && IPSecToDo && !JUST_ESP) {
  1245. if (RtHdr) {
  1246. //
  1247. // Save the new routing header so it can be restored after
  1248. // authenticating.
  1249. //
  1250. SavedRtHdr = ExAllocatePoolWithTagPriority(
  1251. NonPagedPool, RtHdrSize,
  1252. IP6_TAG, LowPoolPriority);
  1253. if (SavedRtHdr == NULL) {
  1254. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1255. "IPv6Send: - couldn't allocate SavedRtHdr!?!\n"));
  1256. NdisFreeBuffer(NewBuffer1);
  1257. ExFreePool(NewMemory);
  1258. goto AbortSend;
  1259. }
  1260. RtlCopyMemory(SavedRtHdr, RtHdr, RtHdrSize);
  1261. }
  1262. //
  1263. // Adjust mutable fields before doing Authentication.
  1264. //
  1265. Action = IPSecAdjustMutableFields(InsertPoint, SavedRtHdr);
  1266. if (Action == LOOKUP_DROP) {
  1267. NdisFreeBuffer(NewBuffer1);
  1268. ExFreePool(NewMemory);
  1269. goto AbortSend;
  1270. }
  1271. } // end of if(IPSecToDo && !JUST_ESP)
  1272. //
  1273. // We need to save the existing completion handler & data. We'll
  1274. // use these fields here, and restore them in IPv6CareOfComplete.
  1275. //
  1276. CareOfInfo = ExAllocatePoolWithTagPriority(
  1277. NonPagedPool, sizeof(*CareOfInfo),
  1278. IP6_TAG, LowPoolPriority);
  1279. if (CareOfInfo == NULL) {
  1280. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1281. "IPv6Send - couldn't allocate completion info!?!\n"));
  1282. NdisFreeBuffer(NewBuffer1);
  1283. ExFreePool(NewMemory);
  1284. goto AbortSend;
  1285. }
  1286. CareOfInfo->SavedCompletionHandler = PC(Packet)->CompletionHandler;
  1287. CareOfInfo->SavedCompletionData = PC(Packet)->CompletionData;
  1288. CareOfInfo->SavedFirstBuffer = OrigBuffer1;
  1289. CareOfInfo->NumESPTrailers = NumESPTrailers;
  1290. PC(Packet)->CompletionHandler = IPv6CareOfComplete;
  1291. PC(Packet)->CompletionData = CareOfInfo;
  1292. // Unchain the original first buffer from the packet.
  1293. NdisUnchainBufferAtFront(Packet, &OrigBuffer1);
  1294. // Chain the new buffer to the front of the packet.
  1295. NdisChainBufferAtFront(Packet, NewBuffer1);
  1296. //
  1297. // Do authentication for transport mode IPSec.
  1298. //
  1299. if (IPSecToDo) {
  1300. IPSecAuthenticatePacket(TRANSPORT, IPSecToDo, InsertPoint,
  1301. &TunnelStart, NewMemory, EndNewMemory,
  1302. NewBuffer1);
  1303. if (!JUST_ESP) {
  1304. //
  1305. // Reset the mutable fields to correct values.
  1306. // Just copy from old packet to new packet for IP and
  1307. // unmodified Ext. headers.
  1308. //
  1309. RtlCopyMemory(InsertPoint, (uchar *)IP, Size);
  1310. // Check if the Routing header needs to be restored.
  1311. if (CareOfRCE) {
  1312. // Copy the saved routing header to the new buffer.
  1313. RtlCopyMemory(RtHdr, SavedRtHdr, RtHdrSize);
  1314. }
  1315. }
  1316. } // end of if (IPSecToDo)
  1317. //
  1318. // We're done with the transport copy.
  1319. //
  1320. //
  1321. // Insert tunnel IPSec headers.
  1322. //
  1323. if (IPSEC_TUNNEL) {
  1324. i = 0;
  1325. // Loop through the different Tunnels.
  1326. while (TunnelStart < IPSecToDo->BundleSize) {
  1327. uchar NextHeader = IP_PROTOCOL_V6;
  1328. NumESPTrailers = 0;
  1329. i++;
  1330. // Reset byte count.
  1331. BytesToInsert = 0;
  1332. Action = IPSecInsertHeaders(TUNNEL, IPSecToDo, &InsertPoint,
  1333. NewMemory, Packet, &TotalPacketSize,
  1334. &NextHeader, TunnelStart,
  1335. &BytesToInsert, &NumESPTrailers,
  1336. &JUST_ESP);
  1337. if (Action == LOOKUP_DROP) {
  1338. goto AbortSend;
  1339. }
  1340. // Add the ESP trailer header number.
  1341. CareOfInfo->NumESPTrailers += NumESPTrailers;
  1342. // Move insert point up to start of IP.
  1343. InsertPoint -= sizeof(IPv6Header);
  1344. //
  1345. // Adjust length of payload.
  1346. //
  1347. PayloadLength = BytesToInsert + PayloadLength + sizeof(IPv6Header);
  1348. // Insert IP header fields.
  1349. IPNew = (IPv6Header UNALIGNED *)InsertPoint;
  1350. IPNew->PayloadLength = net_short((ushort)PayloadLength);
  1351. IPNew->NextHeader = NextHeader;
  1352. if (!JUST_ESP) {
  1353. // Adjust mutable fields.
  1354. IPNew->VersClassFlow = IP_VERSION;
  1355. IPNew->HopLimit = 0;
  1356. } else {
  1357. IPNew->VersClassFlow = IP->VersClassFlow;
  1358. IPNew->HopLimit = IP->HopLimit - i;
  1359. }
  1360. // Source address same as inner header.
  1361. RtlCopyMemory(&IPNew->Source, &IP->Source, sizeof (IPv6Addr));
  1362. // Dest address to the tunnel end point.
  1363. RtlCopyMemory(&IPNew->Dest, &IPSecToDo[TunnelStart].SA->SADestAddr,
  1364. sizeof (IPv6Addr));
  1365. //
  1366. // Do authentication for tunnel mode IPSec.
  1367. //
  1368. IPSecAuthenticatePacket(TUNNEL, IPSecToDo, InsertPoint,
  1369. &TunnelStart, NewMemory, EndNewMemory,
  1370. NewBuffer1);
  1371. if (!JUST_ESP) {
  1372. //
  1373. // Reset the mutable fields to correct values.
  1374. //
  1375. IPNew->VersClassFlow = IP->VersClassFlow;
  1376. IPNew->HopLimit = IP->HopLimit - i;
  1377. }
  1378. } // end of while (TunnelStart < IPSecToDo->BundleSize)
  1379. //
  1380. // Check if a new RCE is needed due to the tunnel.
  1381. //
  1382. if (!(IP6_ADDR_EQUAL(AlignAddr(&IPNew->Dest), AlignAddr(&IP->Dest)))) {
  1383. // Get a new route to the tunnel end point.
  1384. Status = RouteToDestination(AlignAddr(&IPNew->Dest), 0, NULL,
  1385. RTD_FLAG_NORMAL, &TunnelRCE);
  1386. if (Status != IP_SUCCESS) {
  1387. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  1388. "IPv6Send: No route to IPSec tunnel dest."));
  1389. IPv6SendAbort(CastFromNTE(RCE->NTE), Packet, Offset,
  1390. ICMPv6_DESTINATION_UNREACHABLE,
  1391. ICMPv6_NO_ROUTE_TO_DESTINATION, 0, FALSE);
  1392. goto AbortSend;
  1393. }
  1394. // Set new RCE;
  1395. RCE = TunnelRCE;
  1396. }
  1397. } // end of if (IPSEC_TUNNEL)
  1398. // Set the IP pointer to the new IP pointer.
  1399. IP = IPNew;
  1400. if (IPSecToDo) {
  1401. // Free IPSecToDo.
  1402. FreeIPSecToDo(IPSecToDo, IPSecToDo->BundleSize);
  1403. if (SavedRtHdr) {
  1404. // Free the saved routing header.
  1405. ExFreePool(SavedRtHdr);
  1406. }
  1407. }
  1408. ContinueSend:
  1409. if (Action == LOOKUP_DROP) {
  1410. AbortSend:
  1411. // Error occured.
  1412. IPSInfo.ipsi_outdiscards++;
  1413. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1414. "IPv6Send: Drop packet.\n"));
  1415. IPv6SendComplete(NULL, Packet, IP_GENERAL_FAILURE);
  1416. if (CareOfRCE) {
  1417. ReleaseRCE(CareOfRCE);
  1418. }
  1419. if (TunnelRCE)
  1420. ReleaseRCE(TunnelRCE);
  1421. if (IPSecToDo) {
  1422. // Free IPSecToDo.
  1423. FreeIPSecToDo(IPSecToDo, IPSecToDo->BundleSize);
  1424. if (SavedRtHdr) {
  1425. // Free the saved routing header.
  1426. ExFreePool(SavedRtHdr);
  1427. }
  1428. }
  1429. return;
  1430. }
  1431. //
  1432. // We only have one NCE per RCE for now,
  1433. // so picking one is really easy...
  1434. //
  1435. NCE = RCE->NCE;
  1436. //
  1437. // Prevent the packet from actually going out onto a link,
  1438. // in several situations. Also see IsLoopbackAddress.
  1439. //
  1440. if ((IP->HopLimit == 0) ||
  1441. IsLoopback(AlignAddr(&IP->Dest)) ||
  1442. IsInterfaceLocalMulticast(AlignAddr(&IP->Dest))) {
  1443. PC(Packet)->Flags |= NDIS_FLAGS_LOOPBACK_ONLY;
  1444. }
  1445. //
  1446. // See if we need to insert a Jumbo Payload option.
  1447. //
  1448. if (PayloadLength > MAX_IPv6_PAYLOAD) {
  1449. // Add code to insert a Jumbo Payload hop-by-hop option here.
  1450. IPSInfo.ipsi_outdiscards++;
  1451. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_USER_ERROR,
  1452. "IPv6Send: attempted to send a Jumbo Payload!\n"));
  1453. IPv6SendComplete(NULL, Packet, IP_PACKET_TOO_BIG);
  1454. return;
  1455. }
  1456. //
  1457. // Check the path's MTU. If we're larger, fragment.
  1458. //
  1459. PacketLength = PayloadLength + sizeof(IPv6Header);
  1460. PathMTU = GetPathMTUFromRCE(RCE);
  1461. if (PacketLength > PathMTU) {
  1462. IPv6SendFragments(Packet, Offset, IP, PayloadLength, RCE, PathMTU);
  1463. } else {
  1464. //
  1465. // Fill in packet's PayloadLength field.
  1466. // We already set the IP->PayloadLength if IPSec was done.
  1467. //
  1468. if (!IPSecToDo) {
  1469. IP->PayloadLength = net_short((ushort)PayloadLength);
  1470. }
  1471. IPv6SendND(Packet, Offset, NCE, NULL);
  1472. }
  1473. if (CareOfRCE)
  1474. ReleaseRCE(CareOfRCE);
  1475. if (TunnelRCE)
  1476. ReleaseRCE(TunnelRCE);
  1477. }
  1478. //* IPv6Forward - Forward a packet onto a new link.
  1479. //
  1480. // Somewhat like IPv6Send, but for forwarding packets
  1481. // instead of sending freshly-generated packets.
  1482. //
  1483. // We are given ownership of the packet. The packet data
  1484. // must be writable and the IP header must be contiguous.
  1485. //
  1486. // We can generate several possible ICMP errors:
  1487. // Time Limit Exceeded, Destination Unreachable, Packet Too Big.
  1488. // We decrement the hop limit.
  1489. // We do not fragment the packet.
  1490. //
  1491. // We assume that our caller has already sanity-checked
  1492. // the packet's destination address. Routing-header forwarding
  1493. // may allow some cases (like link-local or loopback destinations)
  1494. // that normal router forwarding does not permit.
  1495. // Our caller provides the NCE of the next hop for the packet.
  1496. //
  1497. void
  1498. IPv6Forward(
  1499. NetTableEntryOrInterface *RecvNTEorIF,
  1500. PNDIS_PACKET Packet,
  1501. uint Offset,
  1502. IPv6Header UNALIGNED *IP,
  1503. uint PayloadLength,
  1504. int Redirect,
  1505. IPSecProc *IPSecToDo,
  1506. RouteCacheEntry *RCE)
  1507. {
  1508. uint PacketLength;
  1509. uint LinkMTU, IPSecBytesInserted = 0;
  1510. IP_STATUS Status;
  1511. uint IPSecOffset = Offset;
  1512. NeighborCacheEntry *NCE = RCE->NCE;
  1513. RouteCacheEntry *TunnelRCE = NULL;
  1514. ushort SrcScope;
  1515. IPSIncrementForwDatagramCount();
  1516. ASSERT(IP == GetIPv6Header(Packet, Offset, NULL));
  1517. //
  1518. // Check for "scope" errors. We can't allow a packet with a scoped
  1519. // source address to leave its scope.
  1520. //
  1521. SrcScope = AddressScope(AlignAddr(&IP->Source));
  1522. if (NCE->IF->ZoneIndices[SrcScope] !=
  1523. RecvNTEorIF->IF->ZoneIndices[SrcScope]) {
  1524. IPv6SendAbort(RecvNTEorIF, Packet, Offset,
  1525. ICMPv6_DESTINATION_UNREACHABLE, ICMPv6_SCOPE_MISMATCH,
  1526. 0, FALSE);
  1527. return;
  1528. }
  1529. //
  1530. // Are we forwarding the packet out the link on which it arrived,
  1531. // and we should consider a Redirect? Redirect will be false
  1532. // if the forwarding is happening because of source-routing.
  1533. //
  1534. if ((NCE->IF == RecvNTEorIF->IF) && Redirect) {
  1535. Interface *IF = NCE->IF;
  1536. //
  1537. // We do not want to forward a packet back onto a p2p link,
  1538. // because it will very often lead to a loop.
  1539. // One example: a prefix is on-link to a p2p link between routers
  1540. // and someone sends a packet to an address in the prefix
  1541. // that is not assigned to either end of the link.
  1542. //
  1543. if (IF->Flags & IF_FLAG_P2P) {
  1544. IPv6SendAbort(RecvNTEorIF, Packet, Offset,
  1545. ICMPv6_DESTINATION_UNREACHABLE,
  1546. (IP6_ADDR_EQUAL(&NCE->NeighborAddress,
  1547. &RCE->Destination) ?
  1548. ICMPv6_ADDRESS_UNREACHABLE :
  1549. ICMPv6_NO_ROUTE_TO_DESTINATION),
  1550. 0, FALSE);
  1551. return;
  1552. }
  1553. //
  1554. // We SHOULD send a Redirect, whenever
  1555. // 1. The Source address of the packet specifies a neighbor, and
  1556. // 2. A better first-hop resides on the same link, and
  1557. // 3. The Destination address is not multicast.
  1558. // See Section 8.2 of the ND spec.
  1559. //
  1560. if ((IF->Flags & IF_FLAG_ROUTER_DISCOVERS) &&
  1561. !IsMulticast(AlignAddr(&IP->Dest))) {
  1562. RouteCacheEntry *SrcRCE;
  1563. NeighborCacheEntry *SrcNCE;
  1564. //
  1565. // Get an RCE for the Source of this packet.
  1566. //
  1567. Status = RouteToDestination(AlignAddr(&IP->Source), 0,
  1568. RecvNTEorIF, RTD_FLAG_STRICT,
  1569. &SrcRCE);
  1570. if (Status == IP_SUCCESS) {
  1571. //
  1572. // Because of RTD_FLAG_STRICT.
  1573. //
  1574. ASSERT(SrcRCE->NTE->IF == IF);
  1575. SrcNCE = SrcRCE->NCE;
  1576. if (IP6_ADDR_EQUAL(&SrcNCE->NeighborAddress,
  1577. AlignAddr(&IP->Source))) {
  1578. //
  1579. // The source of this packet is on-link,
  1580. // so send a Redirect to the source.
  1581. // Unless rate-limiting prevents it.
  1582. //
  1583. if (ICMPv6RateLimit(SrcRCE)) {
  1584. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1585. "RedirectSend - rate limit %s\n",
  1586. FormatV6Address(&SrcRCE->Destination)));
  1587. } else {
  1588. RedirectSend(SrcNCE, NCE,
  1589. AlignAddr(&IP->Dest), RecvNTEorIF,
  1590. Packet, Offset, PayloadLength);
  1591. }
  1592. }
  1593. ReleaseRCE(SrcRCE);
  1594. }
  1595. }
  1596. }
  1597. //
  1598. // Check that the hop limit allows the packet to be forwarded.
  1599. //
  1600. if (IP->HopLimit <= 1) {
  1601. //
  1602. // It seems to be customary in this case to have the hop limit
  1603. // in the ICMP error's payload be zero.
  1604. //
  1605. IP->HopLimit = 0;
  1606. IPv6SendAbort(RecvNTEorIF, Packet, Offset, ICMPv6_TIME_EXCEEDED,
  1607. ICMPv6_HOP_LIMIT_EXCEEDED, 0, FALSE);
  1608. return;
  1609. }
  1610. //
  1611. // Note that subsequent ICMP errors (Packet Too Big, Address Unreachable)
  1612. // will show the decremented hop limit. They are also generated
  1613. // from the perspective of the outgoing link. That is, the source address
  1614. // in the ICMP error is an address assigned to the outgoing link.
  1615. //
  1616. IP->HopLimit--;
  1617. // Check if there is IPSec to be done.
  1618. if (IPSecToDo) {
  1619. PNDIS_BUFFER Buffer;
  1620. uchar *Memory, *EndMemory, *InsertPoint;
  1621. uint BufSize, TotalPacketSize, BytesInserted;
  1622. IPv6Header UNALIGNED *IPNew = NULL;
  1623. uint JUST_ESP, Action, TunnelStart = 0, i = 0;
  1624. NetTableEntry *NTE;
  1625. uint NumESPTrailers = 0; // not used here.
  1626. // Set the insert point to the start of the IP header.
  1627. InsertPoint = (uchar *)IP;
  1628. // Get the first buffer.
  1629. NdisGetFirstBufferFromPacket(Packet, &Buffer, &Memory, &BufSize,
  1630. &TotalPacketSize);
  1631. TotalPacketSize -= Offset;
  1632. // End of this buffer.
  1633. EndMemory = Memory + BufSize;
  1634. // Loop through the different Tunnels.
  1635. while (TunnelStart < IPSecToDo->BundleSize) {
  1636. uchar NextHeader = IP_PROTOCOL_V6;
  1637. BytesInserted = 0;
  1638. i++;
  1639. //
  1640. // Insert Tunnel mode IPSec.
  1641. //
  1642. Action = IPSecInsertHeaders(TUNNEL, IPSecToDo, &InsertPoint,
  1643. Memory, Packet, &TotalPacketSize,
  1644. &NextHeader, TunnelStart,
  1645. &BytesInserted, &NumESPTrailers,
  1646. &JUST_ESP);
  1647. if (Action == LOOKUP_DROP) {
  1648. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1649. "IPv6Forward: IPSec drop packet.\n"));
  1650. return;
  1651. }
  1652. // Move insert point up to start of IP.
  1653. InsertPoint -= sizeof(IPv6Header);
  1654. // Reset the Offset value to the correct link-layer size.
  1655. IPSecOffset = (uint)(InsertPoint - Memory);
  1656. // Adjust length of payload.
  1657. PayloadLength = BytesInserted + PayloadLength + sizeof(IPv6Header);
  1658. // Insert IP header fields.
  1659. IPNew = (IPv6Header UNALIGNED *)InsertPoint;
  1660. IPNew->PayloadLength = net_short((ushort)PayloadLength);
  1661. IPNew->NextHeader = NextHeader;
  1662. if (!JUST_ESP) {
  1663. // Adjust mutable fields.
  1664. IPNew->VersClassFlow = IP_VERSION;
  1665. IPNew->HopLimit = 0;
  1666. } else {
  1667. IPNew->VersClassFlow = IP->VersClassFlow;
  1668. IPNew->HopLimit = IP->HopLimit - i;
  1669. }
  1670. // Dest address to the tunnel end point.
  1671. RtlCopyMemory(&IPNew->Dest, &IPSecToDo[TunnelStart].SA->SADestAddr,
  1672. sizeof (IPv6Addr));
  1673. // Figure out what source address to use.
  1674. NTE = FindBestSourceAddress(NCE->IF, AlignAddr(&IPNew->Dest));
  1675. if (NTE == NULL) {
  1676. //
  1677. // We have no valid source address to use!
  1678. //
  1679. return;
  1680. }
  1681. // Source address is the address of the forwarding interface.
  1682. RtlCopyMemory(&IPNew->Source, &NTE->Address, sizeof (IPv6Addr));
  1683. // Release NTE.
  1684. ReleaseNTE(NTE);
  1685. //
  1686. // Do authentication for tunnel mode IPSec.
  1687. //
  1688. IPSecAuthenticatePacket(TUNNEL, IPSecToDo, InsertPoint,
  1689. &TunnelStart, Memory, EndMemory, Buffer);
  1690. if (!JUST_ESP) {
  1691. //
  1692. // Reset the mutable fields to correct values.
  1693. //
  1694. IPNew->VersClassFlow = IP->VersClassFlow;
  1695. IPNew->HopLimit = IP->HopLimit - i;
  1696. }
  1697. IPSecBytesInserted += (BytesInserted + sizeof(IPv6Header));
  1698. } // end of while (TunnelStart < IPSecToDo->BundleSize)
  1699. //
  1700. // Check if a new RCE is needed.
  1701. //
  1702. if (!(IP6_ADDR_EQUAL(AlignAddr(&IPNew->Dest), AlignAddr(&IP->Dest)))) {
  1703. // Get a new route to the tunnel end point.
  1704. Status = RouteToDestination(AlignAddr(&IPNew->Dest), 0, NULL,
  1705. RTD_FLAG_NORMAL, &TunnelRCE);
  1706. if (Status != IP_SUCCESS) {
  1707. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  1708. "IPv6Forward: No route to IPSec tunnel dest."));
  1709. IPv6SendAbort(RecvNTEorIF, Packet, Offset,
  1710. ICMPv6_DESTINATION_UNREACHABLE,
  1711. ICMPv6_NO_ROUTE_TO_DESTINATION, 0, FALSE);
  1712. return;
  1713. }
  1714. // Set the new RCE.
  1715. RCE = TunnelRCE;
  1716. // Set new NCE;
  1717. NCE = RCE->NCE;
  1718. }
  1719. } // end of if (IPSecToDo)
  1720. //
  1721. // Check that the packet is not too big for the outgoing link.
  1722. // Note that IF->LinkMTU is volatile, so we capture
  1723. // it in a local variable for consistency.
  1724. //
  1725. PacketLength = PayloadLength + sizeof(IPv6Header);
  1726. LinkMTU = NCE->IF->LinkMTU;
  1727. if (PacketLength > LinkMTU) {
  1728. // Change the LinkMTU to account for the IPSec headers.
  1729. LinkMTU -= IPSecBytesInserted;
  1730. //
  1731. // Note that MulticastOverride is TRUE for Packet Too Big errors.
  1732. // This allows Path MTU Discovery to work for multicast.
  1733. //
  1734. IPv6SendAbort(RecvNTEorIF, Packet, Offset, ICMPv6_PACKET_TOO_BIG,
  1735. 0, LinkMTU, TRUE); // MulticastOverride.
  1736. } else {
  1737. IPv6SendND(Packet, IPSecOffset, NCE, NULL);
  1738. IPSInfo.ipsi_forwdatagrams++;
  1739. }
  1740. if (TunnelRCE)
  1741. ReleaseRCE(TunnelRCE);
  1742. }
  1743. //* IPv6SendAbort
  1744. //
  1745. // Abort an attempt to send a packet and instead
  1746. // generate an ICMP error. In most situations this function
  1747. // is called before the packet has been sent (so PC(Packet)->IF is NULL)
  1748. // but it can also be used after sending the packet, if the link layer
  1749. // reports failure.
  1750. //
  1751. // Disposes of the aborted packet.
  1752. //
  1753. // The caller can specify the source address of the ICMP error,
  1754. // by specifying an NTE, or the caller can provide an interface
  1755. // from which which the best source address is selected.
  1756. //
  1757. // Callable from thread or DPC context.
  1758. // Must be called with no locks held.
  1759. //
  1760. void
  1761. IPv6SendAbort(
  1762. NetTableEntryOrInterface *NTEorIF,
  1763. PNDIS_PACKET Packet, // Aborted packet.
  1764. uint Offset, // Offset of IPv6 header in aborted packet.
  1765. uchar ICMPType, // ICMP error type.
  1766. uchar ICMPCode, // ICMP error code pertaining to type.
  1767. ulong ErrorParameter, // Parameter included in the error.
  1768. int MulticastOverride) // Allow replies to multicast packets?
  1769. {
  1770. IPv6Header UNALIGNED *IP;
  1771. IPv6Packet DummyPacket;
  1772. IPv6Header HdrBuffer;
  1773. //
  1774. // It's possible for GetIPv6Header to fail
  1775. // when we are sending "raw" packets.
  1776. //
  1777. IP = GetIPv6Header(Packet, Offset, &HdrBuffer);
  1778. if (IP != NULL) {
  1779. InitializePacketFromNdis(&DummyPacket, Packet, Offset);
  1780. DummyPacket.IP = IP;
  1781. DummyPacket.SrcAddr = AlignAddr(&IP->Source);
  1782. DummyPacket.IPPosition = Offset;
  1783. AdjustPacketParams(&DummyPacket, sizeof *IP);
  1784. DummyPacket.NTEorIF = NTEorIF;
  1785. ICMPv6SendError(&DummyPacket, ICMPType, ICMPCode, ErrorParameter,
  1786. IP->NextHeader, MulticastOverride);
  1787. }
  1788. IPv6SendComplete(PC(Packet)->IF, Packet, IP_GENERAL_FAILURE);
  1789. }