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.

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