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.

3241 lines
108 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. // Receive 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 "icmp.h"
  20. #include "route.h"
  21. #include "fragment.h"
  22. #include "mobile.h"
  23. #include "security.h"
  24. #include "info.h"
  25. #include "ipsec.h"
  26. struct ReassemblyList ReassemblyList;
  27. typedef struct Options {
  28. uint JumboLength; // Length of packet excluding IPv6 header.
  29. IPv6RouterAlertOption UNALIGNED *Alert;
  30. IPv6HomeAddressOption UNALIGNED *HomeAddress;
  31. IPv6BindingUpdateOption UNALIGNED *BindingUpdate;
  32. } Options;
  33. int
  34. ParseOptions(
  35. IPv6Packet *Packet, // The packet handed to us by IPv6Receive.
  36. uchar HdrType, // Hop-by-hop or destination.
  37. IPv6OptionsHeader *Hdr, // Header with following data.
  38. uint HdrLength, // Length of the entire options area.
  39. Options *Opts); // Return option values to caller.
  40. extern void TCPRcvComplete(void);
  41. //* IPv6ReceiveComplete - Handle a receive complete.
  42. //
  43. // Called by the lower layer when receives are temporarily done.
  44. //
  45. void
  46. IPv6ReceiveComplete(void)
  47. {
  48. // REVIEW: Original IP implementation had code here to call every
  49. // REVIEW: UL protocol's receive complete routine (yes, all of them) here.
  50. TCPRcvComplete();
  51. }
  52. //
  53. // By default, test pullup in checked builds.
  54. //
  55. #ifndef PULLUP_TEST
  56. #define PULLUP_TEST DBG
  57. #endif
  58. #if PULLUP_TEST
  59. #define PULLUP_TEST_MAX_BUFFERS 8
  60. #define PULLUP_TEST_MAX_BUFFER_SIZE 32
  61. //* PullupTestChooseDistribution
  62. //
  63. // Choose a random distribution.
  64. // Divides Size bytes into NumBuffers pieces,
  65. // and returns the result in the Counts array.
  66. //
  67. void
  68. PullupTestChooseDistribution(
  69. uint Counts[],
  70. uint NumBuffers,
  71. uint Size)
  72. {
  73. uint i;
  74. uint ThisBuffer;
  75. //
  76. // We are somewhat biased towards cutting the packet
  77. // up into small pieces with a large remainder.
  78. // This puts the fragment boundaries at the beginning,
  79. // where the headers are.
  80. //
  81. for (i = 0; i < NumBuffers - 1; i++) {
  82. ThisBuffer = RandomNumber(1, PULLUP_TEST_MAX_BUFFER_SIZE);
  83. //
  84. // Make sure that each segment has non-zero length.
  85. //
  86. if (ThisBuffer > Size - (NumBuffers - 1 - i))
  87. ThisBuffer = Size - (NumBuffers - 1 - i);
  88. Counts[i] = ThisBuffer;
  89. Size -= ThisBuffer;
  90. }
  91. Counts[i] = Size;
  92. }
  93. //* PullupTestCreatePacket
  94. //
  95. // Given an IPv6 packet, creates a new IPv6 packet
  96. // that can be handed up the receive path.
  97. //
  98. // We randomly fragment the IPv6 packet into multiple buffers.
  99. // This tests pull-up processing in the receive path.
  100. //
  101. // Returns NULL if any memory allocation fails.
  102. //
  103. IPv6Packet *
  104. PullupTestCreatePacket(IPv6Packet *Packet)
  105. {
  106. IPv6Packet *TestPacket;
  107. //
  108. // We mostly want to test discontiguous packets.
  109. // But occasionally test a contiguous packet.
  110. //
  111. if (RandomNumber(0, 10) == 0) {
  112. //
  113. // We need to create a contiguous packet.
  114. //
  115. uint Padding;
  116. uint MemLen;
  117. void *Mem;
  118. //
  119. // We insert some padding to vary the alignment.
  120. //
  121. Padding = RandomNumber(0, 16);
  122. MemLen = sizeof *TestPacket + Padding + Packet->TotalSize;
  123. TestPacket = ExAllocatePool(NonPagedPool, MemLen);
  124. if (TestPacket == NULL)
  125. return NULL;
  126. Mem = (void *)((uchar *)(TestPacket + 1) + Padding);
  127. if (Packet->NdisPacket == NULL) {
  128. RtlCopyMemory(Mem, Packet->Data, Packet->TotalSize);
  129. }
  130. else {
  131. PNDIS_BUFFER NdisBuffer;
  132. uint Offset;
  133. int Ok;
  134. NdisBuffer = NdisFirstBuffer(Packet->NdisPacket);
  135. Offset = Packet->Position;
  136. Ok = CopyNdisToFlat(Mem, NdisBuffer, Offset, Packet->TotalSize,
  137. &NdisBuffer, &Offset);
  138. ASSERT(Ok);
  139. }
  140. RtlZeroMemory(TestPacket, sizeof *TestPacket);
  141. TestPacket->Data = TestPacket->FlatData = Mem;
  142. TestPacket->ContigSize = TestPacket->TotalSize = Packet->TotalSize;
  143. TestPacket->NTEorIF = Packet->NTEorIF;
  144. TestPacket->Flags = Packet->Flags;
  145. }
  146. else {
  147. //
  148. // Create a packet with multiple NDIS buffers.
  149. // Start with an over-estimate of the size of the MDLs we need.
  150. //
  151. uint NumPages = (Packet->TotalSize >> PAGE_SHIFT) + 2;
  152. uint MdlRawSize = sizeof(MDL) + (NumPages * sizeof(PFN_NUMBER));
  153. uint MdlAlign = __builtin_alignof(MDL) - 1;
  154. uint MdlSize = (MdlRawSize + MdlAlign) &~ MdlAlign;
  155. uint Padding;
  156. uint MemLen;
  157. uint Counts[PULLUP_TEST_MAX_BUFFERS];
  158. uint NumBuffers;
  159. void *Mem;
  160. PNDIS_PACKET NdisPacket;
  161. PNDIS_BUFFER NdisBuffer;
  162. uint Garbage = 0xdeadbeef;
  163. uint i;
  164. //
  165. // Choose the number of buffers/MDLs that we will use
  166. // and the distribution of bytes into those buffers.
  167. //
  168. NumBuffers = RandomNumber(1, PULLUP_TEST_MAX_BUFFERS);
  169. PullupTestChooseDistribution(Counts, NumBuffers, Packet->TotalSize);
  170. //
  171. // Allocate all the memory that we will need.
  172. // (Actually a bit of an over-estimate.)
  173. // We insert some padding to vary the initial alignment.
  174. //
  175. Padding = RandomNumber(0, 16);
  176. MemLen = (sizeof *TestPacket + sizeof(NDIS_PACKET) +
  177. NumBuffers * (MdlSize + sizeof Garbage) +
  178. Padding + Packet->TotalSize);
  179. TestPacket = ExAllocatePool(NonPagedPool, MemLen);
  180. if (TestPacket == NULL)
  181. return NULL;
  182. NdisPacket = (PNDIS_PACKET)(TestPacket + 1);
  183. NdisBuffer = (PNDIS_BUFFER)(NdisPacket + 1);
  184. Mem = (void *)((uchar *)NdisBuffer + NumBuffers * MdlSize + Padding);
  185. //
  186. // Initialize the NDIS packet and buffers.
  187. //
  188. RtlZeroMemory(NdisPacket, sizeof *NdisPacket);
  189. for (i = 0; i < NumBuffers; i++) {
  190. MmInitializeMdl(NdisBuffer, Mem, Counts[i]);
  191. MmBuildMdlForNonPagedPool(NdisBuffer);
  192. NdisChainBufferAtBack(NdisPacket, NdisBuffer);
  193. RtlCopyMemory((uchar *)Mem + Counts[i], &Garbage, sizeof Garbage);
  194. (uchar *)Mem += Counts[i] + sizeof Garbage;
  195. (uchar *)NdisBuffer += MdlSize;
  196. }
  197. //
  198. // Copy data to the new packet.
  199. //
  200. CopyToBufferChain((PNDIS_BUFFER)(NdisPacket + 1), 0,
  201. Packet->NdisPacket, Packet->Position,
  202. Packet->FlatData, Packet->TotalSize);
  203. //
  204. // Initialize the new packet.
  205. //
  206. InitializePacketFromNdis(TestPacket, NdisPacket, 0);
  207. TestPacket->NTEorIF = Packet->NTEorIF;
  208. TestPacket->Flags = Packet->Flags;
  209. }
  210. return TestPacket;
  211. }
  212. #endif // PULLUP_TEST
  213. //* IPv6Receive - Receive an incoming IPv6 datagram.
  214. //
  215. // This is the routine called by the link layer module when an incoming IPv6
  216. // datagram is to be processed. We validate the datagram and decide what to
  217. // do with it.
  218. //
  219. // The Packet->NTEorIF field holds the NTE or interface that is receiving
  220. // the packet. Typically this is an interface, but there are some tunnel
  221. // situations where the link layer has already found an NTE.
  222. //
  223. // Either the caller should hold a reference to the NTE or interface
  224. // across the call, or the caller can place a reference in the Packet
  225. // with PACKET_HOLDS_REF. If the caller specifies PACKET_HOLDS_REF,
  226. /// IPv6Receive will release the reference.
  227. //
  228. // There is one exception: the caller can supply an interface
  229. // with zero references (not using PACKET_HOLDS_REF),
  230. // if the interface is being destroyed but IF->Cleanup has not yet returned.
  231. //
  232. // NB: The datagram may either be held in a NDIS_PACKET allocated by the
  233. // link-layer or the interface driver (in which case 'Packet->NdisPacket'
  234. // is non-NULL and 'Data' points to the first data buffer in the buffer
  235. // chain), or the datagram may still be held by NDIS (in which case
  236. // 'Packet->NdisPacket' is NULL and 'Data' points to a buffer containing
  237. // the entire datagram).
  238. //
  239. // NB: We do NOT check for link-level multi/broadcasts to
  240. // IPv6 unicast destinations. In the IPv4 world, receivers dropped
  241. // such packets, but in the IPv6 world they are accepted.
  242. //
  243. // Returns count of references for the packet.
  244. // For now, this should always be zero.
  245. // Someday in the future this might be used to indicate
  246. // that the IPv6 layer has not finished its receive processing.
  247. //
  248. // Callable from DPC context, not from thread context.
  249. //
  250. int
  251. IPv6Receive(IPv6Packet *Packet)
  252. {
  253. uchar NextHeader; // Current header's NextHeader field.
  254. uchar (*Handler)();
  255. SALinkage *ThisSA, *NextSA;
  256. int PktRefs;
  257. ASSERT((Packet->FlatData == NULL) != (Packet->NdisPacket == NULL));
  258. ASSERT(Packet->NTEorIF != NULL);
  259. ASSERT(Packet->SAPerformed == NULL);
  260. IPSIncrementInReceiveCount();
  261. //
  262. // Ensure that the packet is accessible in the kernel address space.
  263. // If any mappings fail, just drop the packet.
  264. // In practice, the packet buffers are usually already mapped.
  265. // But they may not be, for example in loopback.
  266. //
  267. if (Packet->NdisPacket != NULL) {
  268. NDIS_BUFFER *Buffer;
  269. Buffer = NdisFirstBuffer(Packet->NdisPacket);
  270. if (! MapNdisBuffers(Buffer)) {
  271. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  272. "IPv6Receive(%p): buffer mapping failed\n",
  273. Packet));
  274. IPSInfo.ipsi_indiscards++;
  275. return 0; // Drop the packet.
  276. }
  277. }
  278. #if PULLUP_TEST
  279. Packet = PullupTestCreatePacket(Packet);
  280. if (Packet == NULL) {
  281. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  282. "IPv6Receive(%p): PullupTestCreatePacket failed\n",
  283. Packet));
  284. IPSInfo.ipsi_indiscards++;
  285. return 0; // Drop the packet.
  286. }
  287. #endif
  288. //
  289. // Iteratively switch out to the handler for each successive next header
  290. // until we reach a handler that reports no more headers follow it.
  291. //
  292. // NB: We do NOT check NTE->DADStatus here.
  293. // That is the responsibility of higher-level protocols.
  294. //
  295. NextHeader = IP_PROTOCOL_V6; // Always first header in packet.
  296. do {
  297. //
  298. // Current header indicates that another header follows.
  299. // See if we have a handler for it.
  300. //
  301. Handler = ProtocolSwitchTable[NextHeader].DataReceive;
  302. if (Handler == NULL) {
  303. //
  304. // We don't have a handler for this header type,
  305. // so see if there is a raw receiver for it.
  306. //
  307. if (!RawReceive(Packet, NextHeader)) {
  308. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  309. "IPv6 Receive: Next Header type %u not handled.\n",
  310. NextHeader));
  311. //
  312. // There isn't a raw receiver either.
  313. // Send an ICMP error message.
  314. // ICMP Pointer value is the offset from the start of the
  315. // incoming packet's IPv6 header to the offending field.
  316. //
  317. ICMPv6SendError(Packet,
  318. ICMPv6_PARAMETER_PROBLEM,
  319. ICMPv6_UNRECOGNIZED_NEXT_HEADER,
  320. Packet->NextHeaderPosition -
  321. Packet->IPPosition,
  322. NextHeader, FALSE);
  323. IPSInfo.ipsi_inunknownprotos++;
  324. } else {
  325. IPSIncrementInDeliverCount();
  326. }
  327. break; // We can't do anything more with this packet.
  328. }
  329. NextHeader = (*Handler)(Packet);
  330. } while (NextHeader != IP_PROTOCOL_NONE);
  331. //
  332. // If this packet holds a reference, free it now.
  333. //
  334. if (Packet->Flags & PACKET_HOLDS_REF) {
  335. if (IsNTE(Packet->NTEorIF))
  336. ReleaseNTE(CastToNTE(Packet->NTEorIF));
  337. else
  338. ReleaseIF(CastToIF(Packet->NTEorIF));
  339. }
  340. //
  341. // Clean up any contiguous regions left by PacketPullup.
  342. //
  343. PacketPullupCleanup(Packet);
  344. //
  345. // Clean up list of SA's performed.
  346. //
  347. for (ThisSA = Packet->SAPerformed; ThisSA != NULL; ThisSA = NextSA) {
  348. ReleaseSA(ThisSA->This);
  349. NextSA = ThisSA->Next;
  350. ExFreePool(ThisSA);
  351. }
  352. PktRefs = Packet->RefCnt;
  353. #if PULLUP_TEST
  354. ExFreePool(Packet);
  355. #endif
  356. return PktRefs;
  357. }
  358. //* IPv6HeaderReceive - Handle a IPv6 header.
  359. //
  360. // This is the routine called to process an IPv6 header, a next header
  361. // value of 41 (e.g. as would be encountered with v6 in v6 tunnels). To
  362. // avoid code duplication, it is also used to process the initial IPv6
  363. // header found in all IPv6 packets, in which mode it may be viewed as
  364. // a continuation of IPv6Receive.
  365. //
  366. uchar
  367. IPv6HeaderReceive(
  368. IPv6Packet *Packet) // Packet handed to us by IPv6Receive.
  369. {
  370. uint PayloadLength;
  371. uchar NextHeader;
  372. int Forwarding; // TRUE means Forwarding, FALSE means Receiving.
  373. //
  374. // Sanity-check ContigSize & TotalSize.
  375. // Higher-level code in the receive path relies on these conditions.
  376. //
  377. ASSERT(Packet->ContigSize <= Packet->TotalSize);
  378. //
  379. // If we are decapsulating a packet,
  380. // remember that this packet was originally tunneled.
  381. //
  382. // Some argue that decapsulating and receiving
  383. // the inner packet on the same interface as the outer packet
  384. // is incorrect: the inner packet should be received
  385. // on a tunnel interface distinct from the original interface.
  386. // (This approach introduces some issues with handling
  387. // IPsec encapsulation, especially tunnel-mode IPsec between peers
  388. // where you want the inner & outer source address to be the same.)
  389. //
  390. // In any case, for now we receive the inner packet on the original
  391. // interface. However, this introduces a potential security
  392. // problem. An off-link node can send an encapsulated packet
  393. // that when decapsulated, appears to have originated from
  394. // an on-link neighbor. This is a security problem for ND.
  395. // We can not conveniently decrement the HopLimit (to make ND's
  396. // check against 255 effective in this case), because the packet
  397. // is read-only. Instead, we remember that the packet is tunneled
  398. // and check this flag bit in the ND code.
  399. //
  400. if (Packet->IP != NULL) {
  401. Packet->Flags |= PACKET_TUNNELED;
  402. Packet->Flags &= ~PACKET_SAW_HA_OPT; // Forget if we saw one.
  403. Packet->SkippedHeaderLength = 0;
  404. //
  405. // If we've already done some IPSec processing on this packet,
  406. // then this is a tunnel header and the preceeding IPSec header
  407. // is operating in tunnel mode.
  408. //
  409. if (Packet->SAPerformed != NULL)
  410. Packet->SAPerformed->Mode = TUNNEL;
  411. } else {
  412. //
  413. // In the reassembly path, we remember if the fragments were
  414. // tunneled but we do not have a Packet->IP.
  415. //
  416. ASSERT((((Packet->Flags & PACKET_TUNNELED) == 0) ||
  417. (Packet->Flags & PACKET_REASSEMBLED)) &&
  418. ((Packet->Flags & PACKET_SAW_HA_OPT) == 0) &&
  419. (Packet->SAPerformed == NULL));
  420. }
  421. //
  422. // Make sure we have enough contiguous bytes for an IPv6 header, otherwise
  423. // attempt to pullup that amount. Then stash away a pointer to the header
  424. // and also remember the offset into the packet at which it begins (needed
  425. // to calculate an offset for certain ICMP error messages).
  426. //
  427. if (! PacketPullup(Packet, sizeof(IPv6Header),
  428. __builtin_alignof(IPv6Addr), 0)) {
  429. // Pullup failed.
  430. if (Packet->TotalSize < sizeof(IPv6Header))
  431. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  432. "IPv6HeaderReceive: "
  433. "Packet too small to contain IPv6 header\n"));
  434. IPSInfo.ipsi_inhdrerrors++;
  435. return IP_PROTOCOL_NONE;
  436. }
  437. Packet->IP = (IPv6Header UNALIGNED *)Packet->Data;
  438. Packet->IPPosition = Packet->Position;
  439. Packet->NextHeaderPosition = Packet->Position +
  440. FIELD_OFFSET(IPv6Header, NextHeader);
  441. //
  442. // Skip over IPv6 header (note we keep our pointer to it).
  443. //
  444. AdjustPacketParams(Packet, sizeof(IPv6Header));
  445. //
  446. // Check the IP version is correct.
  447. // We specifically do NOT check HopLimit.
  448. // HopLimit is only checked when forwarding.
  449. //
  450. if ((Packet->IP->VersClassFlow & IP_VER_MASK) != IP_VERSION) {
  451. // Silently discard the packet.
  452. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  453. "IPv6HeaderReceive: bad version\n"));
  454. IPSInfo.ipsi_inhdrerrors++;
  455. return IP_PROTOCOL_NONE;
  456. }
  457. //
  458. // We use a separate pointer to refer to the source address so that
  459. // later options can change it.
  460. //
  461. Packet->SrcAddr = AlignAddr(&Packet->IP->Source);
  462. //
  463. // Protect against attacks that use bogus source addresses.
  464. //
  465. if (IsInvalidSourceAddress(Packet->SrcAddr)) {
  466. // Silently discard the packet.
  467. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  468. "IPv6HeaderReceive: source address is invalid\n"));
  469. return IP_PROTOCOL_NONE;
  470. }
  471. if (IsLoopback(Packet->SrcAddr) &&
  472. ((Packet->Flags & PACKET_LOOPED_BACK) == 0)) {
  473. // Silently discard the packet.
  474. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  475. "IPv6HeaderReceive: loopback source addr from wire?\n"));
  476. return IP_PROTOCOL_NONE;
  477. }
  478. if (IsNTE(Packet->NTEorIF)) {
  479. NetTableEntry *NTE;
  480. //
  481. // We were called with an NTE.
  482. // Our caller (or the packet itself) should be holding a reference.
  483. // The NTE holds an interface reference.
  484. //
  485. NTE = CastToNTE(Packet->NTEorIF);
  486. //
  487. // Verify that the packet's destination address is
  488. // consistent with this NTE.
  489. //
  490. if (!IP6_ADDR_EQUAL(AlignAddr(&Packet->IP->Dest), &NTE->Address)) {
  491. Interface *IF = NTE->IF;
  492. //
  493. // We can't accept this new header on this NTE.
  494. // Convert to an Interface and punt to forwarding code below.
  495. //
  496. if (Packet->Flags & PACKET_HOLDS_REF) {
  497. AddRefIF(IF);
  498. ReleaseNTE(NTE);
  499. }
  500. else {
  501. //
  502. // Our caller holds a reference for the NTE,
  503. // which holds a reference for the interface.
  504. // So the packet does not need to hold a reference.
  505. //
  506. }
  507. Packet->NTEorIF = CastFromIF(IF);
  508. goto Forward;
  509. }
  510. //
  511. // We are Receiving the packet.
  512. //
  513. Forwarding = FALSE;
  514. } else {
  515. NetTableEntryOrInterface *NTEorIF;
  516. ushort Type;
  517. //
  518. // We were called with an Interface.
  519. // In some situations, there is no reference for this interface
  520. // and the interface is being destroyed. FindAddressOnInterface
  521. // will return NULL in that case. After this point, we must ensure
  522. // that the interface does have a reference, by having the packet
  523. // hold a reference for the interface or a reference for an NTE
  524. // on the interface.
  525. //
  526. NTEorIF = FindAddressOnInterface(CastToIF(Packet->NTEorIF),
  527. AlignAddr(&Packet->IP->Dest), &Type);
  528. if (NTEorIF == NULL) {
  529. //
  530. // The interface is being destroyed.
  531. //
  532. IPSInfo.ipsi_indiscards++;
  533. return IP_PROTOCOL_NONE;
  534. }
  535. //
  536. // FindAddressOnInterface returned a reference to NTEorIF
  537. // (which could be an interface or an NTE). We either need
  538. // to put this reference into the packet, or release it
  539. // if the packet already holds an appropriate reference.
  540. //
  541. if (Type == ADE_NONE) {
  542. //
  543. // If the packet does not hold a reference for the interface,
  544. // give it one now.
  545. //
  546. ASSERT(NTEorIF == Packet->NTEorIF);
  547. if (Packet->Flags & PACKET_HOLDS_REF) {
  548. //
  549. // The packet already holds an interface reference,
  550. // so our reference is not neeeded.
  551. //
  552. ReleaseIF(CastToIF(NTEorIF));
  553. }
  554. else {
  555. //
  556. // Give the packet our interface reference.
  557. //
  558. Packet->Flags |= PACKET_HOLDS_REF;
  559. }
  560. //
  561. // The address is not assigned to this interface. Check to see
  562. // if it is appropriate for us to forward this packet.
  563. // If not, drop it. At this point, we are fairly
  564. // conservative about what we will forward.
  565. //
  566. Forward:
  567. if (!(CastToIF(Packet->NTEorIF)->Flags & IF_FLAG_FORWARDS) ||
  568. (Packet->Flags & PACKET_NOT_LINK_UNICAST) ||
  569. IsUnspecified(AlignAddr(&Packet->IP->Source)) ||
  570. IsLoopback(AlignAddr(&Packet->IP->Source))) {
  571. //
  572. // Drop the packet with no ICMP error.
  573. //
  574. IPSInfo.ipsi_inaddrerrors++;
  575. return IP_PROTOCOL_NONE;
  576. }
  577. //
  578. // No support yet for forwarding multicast packets.
  579. //
  580. if (IsUnspecified(AlignAddr(&Packet->IP->Dest)) ||
  581. IsLoopback(AlignAddr(&Packet->IP->Dest)) ||
  582. IsMulticast(AlignAddr(&Packet->IP->Dest))) {
  583. //
  584. // Send an ICMP error.
  585. //
  586. ICMPv6SendError(Packet,
  587. ICMPv6_DESTINATION_UNREACHABLE,
  588. ICMPv6_COMMUNICATION_PROHIBITED,
  589. 0, Packet->IP->NextHeader, FALSE);
  590. IPSInfo.ipsi_inaddrerrors++;
  591. return IP_PROTOCOL_NONE;
  592. }
  593. //
  594. // We do the actual forwarding below...
  595. //
  596. Forwarding = TRUE;
  597. } else {
  598. //
  599. // If we found a unicast ADE, then remember the NTE.
  600. // Conceptually, we think of the packet as holding
  601. // the reference to the NTE. Normally for multicast/anycast
  602. // addresses, we delay our choice of an appropriate NTE
  603. // until it is time to reply to the packet.
  604. //
  605. if (IsNTE(NTEorIF)) {
  606. NetTableEntry *NTE = CastToNTE(NTEorIF);
  607. Interface *IF = NTE->IF;
  608. ASSERT(CastFromIF(IF) == Packet->NTEorIF);
  609. if (!IsValidNTE(NTE)) {
  610. //
  611. // The unicast address is not valid, so it can't
  612. // receive packets. The address may be assigned
  613. // to some other node, so forwarding is appropriate.
  614. //
  615. // Ensure that the packet holds an interface reference.
  616. //
  617. if (!(Packet->Flags & PACKET_HOLDS_REF)) {
  618. //
  619. // The packet does not already hold an interface ref,
  620. // so give it one.
  621. //
  622. AddRefIF(IF);
  623. Packet->Flags |= PACKET_HOLDS_REF;
  624. }
  625. //
  626. // Now our NTE reference is not needed.
  627. //
  628. ReleaseNTE(NTE);
  629. goto Forward;
  630. }
  631. //
  632. // Ensure that the packet holds a reference for the NTE,
  633. // which holds an interface reference.
  634. //
  635. if (Packet->Flags & PACKET_HOLDS_REF) {
  636. //
  637. // The packet already holds an interface reference.
  638. // Release that reference and give the packet
  639. // our NTE reference.
  640. //
  641. ReleaseIF(IF);
  642. }
  643. else {
  644. //
  645. // The packet does not hold a reference.
  646. // Give the packet our NTE reference.
  647. //
  648. Packet->Flags |= PACKET_HOLDS_REF;
  649. }
  650. Packet->NTEorIF = CastFromNTE(NTE);
  651. }
  652. else {
  653. //
  654. // Ensure that the packet holds an interface reference.
  655. //
  656. ASSERT(NTEorIF == Packet->NTEorIF);
  657. if (Packet->Flags & PACKET_HOLDS_REF) {
  658. //
  659. // The packet already holds an interface reference,
  660. // so our reference is not needed.
  661. //
  662. ReleaseIF(CastToIF(NTEorIF));
  663. }
  664. else {
  665. //
  666. // Give our interface reference to the packet.
  667. //
  668. Packet->Flags |= PACKET_HOLDS_REF;
  669. }
  670. }
  671. //
  672. // We found an ADE on this IF to accept the packet,
  673. // so we will be Receiving it.
  674. //
  675. Forwarding = FALSE;
  676. }
  677. }
  678. //
  679. // At this point, the Forwarding variable tells us
  680. // if we are forwarding or receiving the packet.
  681. //
  682. //
  683. // Before processing any headers, including Hop-by-Hop,
  684. // check that the amount of payload the IPv6 header thinks is present
  685. // can actually fit inside the packet data area that the link handed us.
  686. // Note that a Payload Length of zero *might* mean a Jumbo Payload option.
  687. //
  688. PayloadLength = net_short(Packet->IP->PayloadLength);
  689. if (PayloadLength > Packet->TotalSize) {
  690. // Silently discard the packet.
  691. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  692. "IPv6HeaderReceive: Header's PayloadLength is greater than "
  693. "the amount of data received\n"));
  694. IPSInfo.ipsi_inhdrerrors++;
  695. return IP_PROTOCOL_NONE;
  696. }
  697. //
  698. // Check for Hop-by-Hop Options.
  699. //
  700. if (Packet->IP->NextHeader == IP_PROTOCOL_HOP_BY_HOP) {
  701. int RetVal;
  702. //
  703. // If there is a Jumbo Payload option, HopByHopOptionsReceive
  704. // will adjust the packet size. Otherwise we take care of it
  705. // now, before reading the Hop-by-Hop header.
  706. //
  707. if (PayloadLength != 0) {
  708. Packet->TotalSize = PayloadLength;
  709. if (Packet->ContigSize > PayloadLength)
  710. Packet->ContigSize = PayloadLength;
  711. }
  712. //
  713. // Parse the Hop-by-Hop options.
  714. //
  715. RetVal = HopByHopOptionsReceive(Packet);
  716. if (RetVal < 0) {
  717. //
  718. // The packet had bad Hop-by-Hop Options.
  719. // Drop it.
  720. //
  721. IPSInfo.ipsi_inhdrerrors++;
  722. return IP_PROTOCOL_NONE;
  723. }
  724. NextHeader = (uchar)RetVal; // Truncate to 8 bits.
  725. } else {
  726. //
  727. // No Jumbo Payload option. Adjust the packet size.
  728. //
  729. Packet->TotalSize = PayloadLength;
  730. if (Packet->ContigSize > PayloadLength)
  731. Packet->ContigSize = PayloadLength;
  732. //
  733. // No Hop-by-Hop options.
  734. //
  735. NextHeader = Packet->IP->NextHeader;
  736. }
  737. //
  738. // Check if we are forwarding this packet.
  739. //
  740. if (Forwarding) {
  741. IPv6Header UNALIGNED *FwdIP;
  742. NDIS_PACKET *FwdPacket;
  743. NDIS_STATUS NdisStatus;
  744. uint Offset;
  745. uint MemLen;
  746. uchar *Mem;
  747. uint TunnelStart = NO_TUNNEL, IPSecBytes = 0;
  748. IPSecProc *IPSecToDo;
  749. uint Action;
  750. RouteCacheEntry *RCE;
  751. IP_STATUS Status;
  752. //
  753. // Verify IPSec was performed.
  754. //
  755. if (InboundSecurityCheck(Packet, 0, 0, 0,
  756. CastToIF(Packet->NTEorIF)) != TRUE) {
  757. //
  758. // No policy was found or the policy indicated to drop the packet.
  759. //
  760. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  761. "IPv6Receive: "
  762. "IPSec lookup failed or policy was to drop\n"));
  763. IPSInfo.ipsi_inaddrerrors++;
  764. return IP_PROTOCOL_NONE;
  765. }
  766. //
  767. // At this time, we need to copy the incoming packet,
  768. // for several reasons: We can't hold the Packet
  769. // once IPv6HeaderReceive returns, yet we need to queue
  770. // packet to forward it. We need to modify the packet
  771. // (in IPv6Forward) by decrementing the hop count,
  772. // yet our incoming packet is read-only. Finally,
  773. // we need space in the outgoing packet for the outgoing
  774. // interface's link-level header, which may differ in size
  775. // from that of the incoming interface. Someday, we can
  776. // implement support for returning a non-zero reference
  777. // count from IPv6Receive and only copy the incoming
  778. // packet's header to construct the outgoing packet.
  779. //
  780. //
  781. // Find a route to the new destination.
  782. //
  783. Status = RouteToDestination(AlignAddr(&Packet->IP->Dest),
  784. 0, Packet->NTEorIF,
  785. RTD_FLAG_LOOSE, &RCE);
  786. if (Status != IP_SUCCESS) {
  787. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  788. "IPv6HeaderReceive: "
  789. "No route to destination for forwarding.\n"));
  790. ICMPv6SendError(Packet,
  791. ICMPv6_DESTINATION_UNREACHABLE,
  792. ICMPv6_NO_ROUTE_TO_DESTINATION,
  793. 0, NextHeader, FALSE);
  794. IPSInfo.ipsi_outnoroutes++;
  795. return IP_PROTOCOL_NONE;
  796. }
  797. //
  798. // Find the Security Policy for this outbound traffic.
  799. //
  800. IPSecToDo = OutboundSPLookup(AlignAddr(&Packet->IP->Source),
  801. AlignAddr(&Packet->IP->Dest),
  802. 0, 0, 0, RCE->NCE->IF, &Action);
  803. if (IPSecToDo == NULL) {
  804. //
  805. // Check Action.
  806. //
  807. if (Action == LOOKUP_DROP) {
  808. // Drop packet.
  809. ReleaseRCE(RCE);
  810. IPSInfo.ipsi_inaddrerrors++;
  811. return IP_PROTOCOL_NONE;
  812. } else {
  813. if (Action == LOOKUP_IKE_NEG) {
  814. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  815. "IPv6HeaderReceive: IKE not supported yet.\n"));
  816. ReleaseRCE(RCE);
  817. IPSInfo.ipsi_inaddrerrors++;
  818. return IP_PROTOCOL_NONE;
  819. }
  820. }
  821. //
  822. // With no IPSec to perform, IPv6Forward won't be changing the
  823. // outgoing interface from what we currently think it will be.
  824. // So we can use the exact size of its link-level header.
  825. //
  826. Offset = RCE->NCE->IF->LinkHeaderSize;
  827. } else {
  828. //
  829. // Calculate the space needed for the IPSec headers.
  830. //
  831. IPSecBytes = IPSecBytesToInsert(IPSecToDo, &TunnelStart, NULL);
  832. if (TunnelStart != 0) {
  833. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  834. "IPv6HeaderReceive: IPSec Tunnel mode only.\n"));
  835. FreeIPSecToDo(IPSecToDo, IPSecToDo->BundleSize);
  836. ReleaseRCE(RCE);
  837. IPSInfo.ipsi_inaddrerrors++;
  838. return IP_PROTOCOL_NONE;
  839. }
  840. //
  841. // The IPSec code in IPv6Forward might change the outgoing
  842. // interface from what we currently think it will be.
  843. // Leave the max amount of space for its link-level header.
  844. //
  845. Offset = MAX_LINK_HEADER_SIZE;
  846. }
  847. PayloadLength = Packet->TotalSize;
  848. MemLen = Offset + sizeof(IPv6Header) + PayloadLength + IPSecBytes;
  849. NdisStatus = IPv6AllocatePacket(MemLen, &FwdPacket, &Mem);
  850. if (NdisStatus != NDIS_STATUS_SUCCESS) {
  851. if (IPSecToDo) {
  852. FreeIPSecToDo(IPSecToDo, IPSecToDo->BundleSize);
  853. }
  854. ReleaseRCE(RCE);
  855. IPSInfo.ipsi_indiscards++;
  856. return IP_PROTOCOL_NONE; // We can't forward.
  857. }
  858. FwdIP = (IPv6Header UNALIGNED *)(Mem + Offset + IPSecBytes);
  859. //
  860. // Copy from the incoming packet to the outgoing packet.
  861. //
  862. CopyPacketToBuffer((uchar *)FwdIP, Packet,
  863. sizeof(IPv6Header) + PayloadLength,
  864. Packet->IPPosition);
  865. //
  866. // Send the outgoing packet.
  867. //
  868. IPv6Forward(Packet->NTEorIF, FwdPacket, Offset + IPSecBytes, FwdIP,
  869. PayloadLength, TRUE, // OK to Redirect.
  870. IPSecToDo, RCE);
  871. if (IPSecToDo) {
  872. FreeIPSecToDo(IPSecToDo, IPSecToDo->BundleSize);
  873. }
  874. ReleaseRCE(RCE);
  875. return IP_PROTOCOL_NONE;
  876. } // end of if (Forwarding)
  877. //
  878. // Packet is for this node.
  879. // Note: We may only be an intermediate node and not the packet's final
  880. // destination, if there is a routing header.
  881. //
  882. return NextHeader;
  883. }
  884. //* ReassemblyInit
  885. //
  886. // Initialize data structures required for fragment reassembly.
  887. //
  888. void
  889. ReassemblyInit(void)
  890. {
  891. KeInitializeSpinLock(&ReassemblyList.Lock);
  892. ReassemblyList.First = ReassemblyList.Last = SentinelReassembly;
  893. KeInitializeSpinLock(&ReassemblyList.LockSize);
  894. }
  895. //* ReassemblyUnload
  896. //
  897. // Cleanup the fragment reassembly data structures and
  898. // prepare for stack unload.
  899. //
  900. void
  901. ReassemblyUnload(void)
  902. {
  903. //
  904. // We are called after all interfaces have been destroyed,
  905. // so the reassemblies should already be gone.
  906. //
  907. ASSERT(ReassemblyList.Last == SentinelReassembly);
  908. ASSERT(ReassemblyList.Size == 0);
  909. }
  910. //* ReassemblyRemove
  911. //
  912. // Cleanup the fragment reassembly data structures
  913. // when an interface becomes invalid.
  914. //
  915. // Callable from DPC or thread context.
  916. //
  917. void
  918. ReassemblyRemove(Interface *IF)
  919. {
  920. Reassembly *DeleteList = NULL;
  921. Reassembly *Reass, *NextReass;
  922. KIRQL OldIrql;
  923. KeAcquireSpinLock(&ReassemblyList.Lock, &OldIrql);
  924. for (Reass = ReassemblyList.First;
  925. Reass != SentinelReassembly;
  926. Reass = NextReass) {
  927. NextReass = Reass->Next;
  928. if (Reass->IF == IF) {
  929. //
  930. // Remove this reassembly.
  931. // If it is not already being deleted,
  932. // put it on our temporary list.
  933. //
  934. RemoveReassembly(Reass);
  935. KeAcquireSpinLockAtDpcLevel(&Reass->Lock);
  936. if (Reass->State == REASSEMBLY_STATE_DELETING) {
  937. //
  938. // Note that it has been removed from the list.
  939. //
  940. Reass->State = REASSEMBLY_STATE_REMOVED;
  941. }
  942. else {
  943. Reass->Next = DeleteList;
  944. DeleteList = Reass;
  945. }
  946. KeReleaseSpinLockFromDpcLevel(&Reass->Lock);
  947. }
  948. }
  949. KeReleaseSpinLock(&ReassemblyList.Lock, OldIrql);
  950. //
  951. // Actually free the reassemblies that we removed above.
  952. //
  953. while ((Reass = DeleteList) != NULL) {
  954. DeleteList = Reass->Next;
  955. DeleteReassembly(Reass);
  956. }
  957. }
  958. //* FragmentReceive - Handle a IPv6 datagram fragment.
  959. //
  960. // This is the routine called by IPv6 when it receives a fragment of an
  961. // IPv6 datagram, i.e. a next header value of 44. Here we attempt to
  962. // reassemble incoming fragments into complete IPv6 datagrams.
  963. //
  964. // If a later fragment provides data that conflicts with an earlier
  965. // fragment, then we use the first-arriving data.
  966. //
  967. // We silently drop the fragment and stop reassembly in several
  968. // cases that are not specified in the spec, to prevent DoS attacks.
  969. // These include partially overlapping fragments and fragments
  970. // that carry no data. Legitimate senders should never generate them.
  971. //
  972. uchar
  973. FragmentReceive(
  974. IPv6Packet *Packet) // Packet handed to us by IPv6Receive.
  975. {
  976. Interface *IF = Packet->NTEorIF->IF;
  977. FragmentHeader UNALIGNED *Frag;
  978. Reassembly *Reass;
  979. ushort FragOffset;
  980. PacketShim *Shim, *ThisShim, **MoveShim;
  981. uint NextHeaderPosition;
  982. IPSInfo.ipsi_reasmreqds++;
  983. //
  984. // We can not reassemble fragments that have had IPsec processing.
  985. // It can't work because the IPsec headers in the unfragmentable part
  986. // of the offset-zero fragment will authenticate/decrypt that fragment.
  987. // Then the same headers would be copied to the reassembled packet.
  988. // They couldn't possibly successfully authenticate/decrypt again.
  989. // Also see RFC 2401 B.2.
  990. //
  991. if (Packet->SAPerformed != NULL) {
  992. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  993. "FragmentReceive: IPsec on fragment\n"));
  994. //
  995. // The spec does not tell us what ICMP error to generate in this case,
  996. // but flagging the fragment header seems reasonable.
  997. //
  998. goto BadFragment;
  999. }
  1000. //
  1001. // If a jumbo payload option was seen, send an ICMP error.
  1002. // Set ICMP pointer to the offset of the fragment header.
  1003. //
  1004. if (Packet->Flags & PACKET_JUMBO_OPTION) {
  1005. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1006. "FragmentReceive: jumbo fragment\n"));
  1007. BadFragment:
  1008. //
  1009. // The NextHeader value passed to ICMPv6SendError
  1010. // is IP_PROTOCOL_FRAGMENT because we haven't moved
  1011. // past the fragment header yet.
  1012. //
  1013. ICMPv6SendError(Packet,
  1014. ICMPv6_PARAMETER_PROBLEM,
  1015. ICMPv6_ERRONEOUS_HEADER_FIELD,
  1016. Packet->Position - Packet->IPPosition,
  1017. IP_PROTOCOL_FRAGMENT, FALSE);
  1018. goto Failed; // Drop packet.
  1019. }
  1020. //
  1021. // Verify that we have enough contiguous data to overlay a FragmentHeader
  1022. // structure on the incoming packet. Then do so.
  1023. //
  1024. if (! PacketPullup(Packet, sizeof *Frag, 1, 0)) {
  1025. // Pullup failed.
  1026. if (Packet->TotalSize < sizeof *Frag)
  1027. ICMPv6SendError(Packet,
  1028. ICMPv6_PARAMETER_PROBLEM,
  1029. ICMPv6_ERRONEOUS_HEADER_FIELD,
  1030. FIELD_OFFSET(IPv6Header, PayloadLength),
  1031. IP_PROTOCOL_NONE, FALSE);
  1032. goto Failed; // Drop packet.
  1033. }
  1034. Frag = (FragmentHeader UNALIGNED *) Packet->Data;
  1035. //
  1036. // Remember offset to this header's NextHeader field.
  1037. // But don't overwrite offset to previous header's NextHeader just yet.
  1038. //
  1039. NextHeaderPosition = Packet->Position +
  1040. FIELD_OFFSET(FragmentHeader, NextHeader);
  1041. //
  1042. // Skip over fragment header.
  1043. //
  1044. AdjustPacketParams(Packet, sizeof *Frag);
  1045. //
  1046. // Lookup this fragment triple (Source Address, Destination
  1047. // Address, and Identification field) per-interface to see if
  1048. // we've already received other fragments of this packet.
  1049. //
  1050. Reass = FragmentLookup(IF, Frag->Id,
  1051. AlignAddr(&Packet->IP->Source),
  1052. AlignAddr(&Packet->IP->Dest));
  1053. if (Reass == NULL) {
  1054. //
  1055. // We hold the global reassembly list lock.
  1056. //
  1057. // Handle a special case first: if this is the first, last, and only
  1058. // fragment, then we can just continue parsing without reassembly.
  1059. // Test both paths in checked builds.
  1060. //
  1061. if ((Frag->OffsetFlag == 0)
  1062. #if DBG
  1063. && ((int)Random() < 0)
  1064. #endif
  1065. ) {
  1066. //
  1067. // Return next header value.
  1068. //
  1069. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.Lock);
  1070. Packet->NextHeaderPosition = NextHeaderPosition;
  1071. Packet->SkippedHeaderLength += sizeof(FragmentHeader);
  1072. IPSInfo.ipsi_reasmoks++;
  1073. return Frag->NextHeader;
  1074. }
  1075. //
  1076. // We must avoid creating new reassembly records
  1077. // if the interface is going away, to prevent races
  1078. // with DestroyIF/ReassemblyRemove.
  1079. //
  1080. if (IsDisabledIF(IF)) {
  1081. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.Lock);
  1082. goto Failed;
  1083. }
  1084. //
  1085. // This is the first fragment of this datagram we've received.
  1086. // Allocate a reassembly structure to keep track of the pieces.
  1087. //
  1088. Reass = ExAllocatePool(NonPagedPool, sizeof(struct Reassembly));
  1089. if (Reass == NULL) {
  1090. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.Lock);
  1091. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1092. "FragmentReceive: Couldn't allocate memory!?!\n"));
  1093. goto Failed;
  1094. }
  1095. KeInitializeSpinLock(&Reass->Lock);
  1096. Reass->State = REASSEMBLY_STATE_NORMAL;
  1097. RtlCopyMemory(&Reass->IPHdr, Packet->IP, sizeof(IPv6Header));
  1098. Reass->IF = IF;
  1099. Reass->Id = Frag->Id;
  1100. Reass->ContigList = NULL;
  1101. #if DBG
  1102. Reass->ContigEnd = NULL;
  1103. #endif
  1104. Reass->GapList = NULL;
  1105. Reass->Timer = DEFAULT_REASSEMBLY_TIMEOUT;
  1106. Reass->Marker = 0;
  1107. Reass->MaxGap = 0;
  1108. //
  1109. // We must initialize DataLength to an invalid value.
  1110. // Initializing to zero doesn't work.
  1111. //
  1112. Reass->DataLength = (uint)-1;
  1113. Reass->UnfragmentLength = 0;
  1114. Reass->UnfragData = NULL;
  1115. Reass->Flags = 0;
  1116. Reass->Size = REASSEMBLY_SIZE_PACKET;
  1117. //
  1118. // Add new Reassembly struct to front of the ReassemblyList.
  1119. // Acquires the reassembly record lock and
  1120. // releases the global reassembly list lock.
  1121. //
  1122. AddToReassemblyList(Reass);
  1123. }
  1124. else {
  1125. //
  1126. // We have found and locked an existing reassembly structure.
  1127. // Because we remove the reassembly structure in every
  1128. // error situation below, an existing reassembly structure
  1129. // must have a shim that has been successfully added to it.
  1130. //
  1131. ASSERT((Reass->ContigList != NULL) || (Reass->GapList != NULL));
  1132. }
  1133. //
  1134. // At this point, we have a locked reassembly record.
  1135. // We do not hold the global reassembly list lock
  1136. // while we perform the relatively expensive work
  1137. // of copying the fragment.
  1138. //
  1139. ASSERT(Reass->State == REASSEMBLY_STATE_NORMAL);
  1140. //
  1141. // Update the saved packet flags from this fragment packet.
  1142. // We are really only interested in PACKET_NOT_LINK_UNICAST.
  1143. //
  1144. Reass->Flags |= Packet->Flags;
  1145. FragOffset = net_short(Frag->OffsetFlag) & FRAGMENT_OFFSET_MASK;
  1146. //
  1147. // Send ICMP error if this fragment causes the total packet length
  1148. // to exceed 65,535 bytes. Set ICMP pointer equal to the offset to
  1149. // the Fragment Offset field.
  1150. //
  1151. if (FragOffset + Packet->TotalSize > MAX_IPv6_PAYLOAD) {
  1152. DeleteFromReassemblyList(Reass);
  1153. ICMPv6SendError(Packet,
  1154. ICMPv6_PARAMETER_PROBLEM,
  1155. ICMPv6_ERRONEOUS_HEADER_FIELD,
  1156. (Packet->Position - sizeof(FragmentHeader) +
  1157. (uint)FIELD_OFFSET(FragmentHeader, OffsetFlag) -
  1158. Packet->IPPosition),
  1159. ((FragOffset == 0) ?
  1160. Frag->NextHeader : IP_PROTOCOL_NONE),
  1161. FALSE);
  1162. goto Failed;
  1163. }
  1164. if ((Packet->TotalSize == 0) && (Frag->OffsetFlag != 0)) {
  1165. //
  1166. // We allow a moot fragment header (Frag->OffsetFlag == 0),
  1167. // because some test programs might generate them.
  1168. // (The first/last/only check above catches this in free builds.)
  1169. // But otherwise, we disallow fragments that do not actually
  1170. // carry any data for DoS protection.
  1171. //
  1172. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1173. "FragmentReceive: zero data fragment\n"));
  1174. DeleteFromReassemblyList(Reass);
  1175. return IP_PROTOCOL_NONE;
  1176. }
  1177. //
  1178. // If this is the last fragment (more fragments bit not set), then
  1179. // remember the total data length, else, check that the length
  1180. // is a multiple of 8 bytes.
  1181. //
  1182. if ((net_short(Frag->OffsetFlag) & FRAGMENT_FLAG_MASK) == 0) {
  1183. if (Reass->DataLength != (uint)-1) {
  1184. //
  1185. // We already received a last fragment.
  1186. // This can happen if a packet is duplicated.
  1187. //
  1188. if (FragOffset + Packet->TotalSize != Reass->DataLength) {
  1189. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1190. "FragmentReceive: second last fragment\n"));
  1191. DeleteFromReassemblyList(Reass);
  1192. return IP_PROTOCOL_NONE;
  1193. }
  1194. }
  1195. else {
  1196. //
  1197. // Set expected data length from this fragment.
  1198. //
  1199. Reass->DataLength = FragOffset + Packet->TotalSize;
  1200. //
  1201. // Do we have any fragments beyond this length?
  1202. //
  1203. if ((Reass->Marker > Reass->DataLength) ||
  1204. (Reass->MaxGap > Reass->DataLength))
  1205. goto BadFragmentBeyondData;
  1206. }
  1207. } else {
  1208. if ((Packet->TotalSize % 8) != 0) {
  1209. //
  1210. // Length is not multiple of 8, send ICMP error with a pointer
  1211. // value equal to offset of payload length field in IP header.
  1212. //
  1213. DeleteFromReassemblyList(Reass);
  1214. ICMPv6SendError(Packet,
  1215. ICMPv6_PARAMETER_PROBLEM,
  1216. ICMPv6_ERRONEOUS_HEADER_FIELD,
  1217. FIELD_OFFSET(IPv6Header, PayloadLength),
  1218. ((FragOffset == 0) ?
  1219. Frag->NextHeader : IP_PROTOCOL_NONE),
  1220. FALSE);
  1221. goto Failed; // Drop packet.
  1222. }
  1223. if ((Reass->DataLength != (uint)-1) &&
  1224. (FragOffset + Packet->TotalSize > Reass->DataLength)) {
  1225. //
  1226. // This fragment falls beyond the data length.
  1227. // As part of our DoS prevention, drop the reassembly.
  1228. //
  1229. BadFragmentBeyondData:
  1230. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1231. "FragmentReceive: fragment beyond data length\n"));
  1232. DeleteFromReassemblyList(Reass);
  1233. return IP_PROTOCOL_NONE;
  1234. }
  1235. }
  1236. //
  1237. // Allocate and initialize a shim structure to hold the fragment data.
  1238. //
  1239. Shim = ExAllocatePool(NonPagedPool, sizeof *Shim + Packet->TotalSize);
  1240. if (Shim == NULL) {
  1241. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1242. "FragmentReceive: Couldn't allocate memory!?!\n"));
  1243. DeleteFromReassemblyList(Reass);
  1244. goto Failed;
  1245. }
  1246. IncreaseReassemblySize(Reass, REASSEMBLY_SIZE_FRAG + Packet->TotalSize);
  1247. Shim->Len = (ushort)Packet->TotalSize;
  1248. Shim->Offset = FragOffset;
  1249. Shim->Next = NULL;
  1250. //
  1251. // Determine where this fragment fits among the previous ones.
  1252. //
  1253. // There is no good reason for senders to ever generate overlapping
  1254. // fragments. However, packets may sometimes be duplicated in the network.
  1255. // If we receive a fragment that duplicates previously received fragments,
  1256. // then we just discard it. If we receive a fragment that only partially
  1257. // overlaps previously received fragments, then we assume a malicious
  1258. // sender and just drop the reassembly. This gives us better behavior
  1259. // under some kinds of DoS attacks, although the upper bound on reassembly
  1260. // buffers (see CheckReassemblyQuota) is the ultimate protection.
  1261. //
  1262. if (FragOffset == Reass->Marker) {
  1263. //
  1264. // This fragment extends the contiguous list.
  1265. //
  1266. if (Reass->ContigList == NULL) {
  1267. //
  1268. // We're first on the list.
  1269. // We use info from the (first) offset zero fragment to recreate
  1270. // the original datagram. Info in a second offset zero fragment
  1271. // is ignored.
  1272. //
  1273. ASSERT(FragOffset == 0);
  1274. ASSERT(Reass->UnfragData == NULL);
  1275. Reass->ContigList = Shim;
  1276. // Save the next header value.
  1277. Reass->NextHeader = Frag->NextHeader;
  1278. //
  1279. // Grab the unfragmentable data, i.e. the extension headers that
  1280. // preceded the fragment header.
  1281. //
  1282. Reass->UnfragmentLength = (ushort)
  1283. (Packet->Position - sizeof(FragmentHeader)) -
  1284. (Packet->IPPosition + sizeof(IPv6Header));
  1285. if (Reass->UnfragmentLength != 0) {
  1286. Reass->UnfragData = ExAllocatePool(NonPagedPool,
  1287. Reass->UnfragmentLength);
  1288. if (Reass->UnfragData == NULL) {
  1289. // Out of memory!?! Clean up and drop packet.
  1290. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1291. "FragmentReceive: "
  1292. "Couldn't allocate memory?\n"));
  1293. // Will also free Shim because of Reass->ContigList.
  1294. DeleteFromReassemblyList(Reass);
  1295. goto Failed;
  1296. }
  1297. IncreaseReassemblySize(Reass, Reass->UnfragmentLength);
  1298. CopyPacketToBuffer(Reass->UnfragData, Packet,
  1299. Reass->UnfragmentLength,
  1300. Packet->IPPosition + sizeof(IPv6Header));
  1301. Reass->NextHeaderOffset = Packet->NextHeaderPosition -
  1302. Packet->IPPosition;
  1303. } else
  1304. Reass->NextHeaderOffset = FIELD_OFFSET(IPv6Header, NextHeader);
  1305. //
  1306. // We need to have the IP header of the offset-zero fragment.
  1307. // (Every fragment normally will have the same IP header,
  1308. // except for PayloadLength, and unfragmentable headers,
  1309. // but they might not.) ReassembleDatagram and
  1310. // CreateFragmentPacket both need it.
  1311. //
  1312. // Of the 40 bytes in the header, the 32 bytes in the source
  1313. // and destination addresses are already correct.
  1314. // So we just copy the other 8 bytes now.
  1315. //
  1316. RtlCopyMemory(&Reass->IPHdr, Packet->IP, 8);
  1317. } else {
  1318. //
  1319. // Add us to the end of the list.
  1320. //
  1321. Reass->ContigEnd->Next = Shim;
  1322. }
  1323. Reass->ContigEnd = Shim;
  1324. //
  1325. // Increment our contiguous extent marker.
  1326. //
  1327. Reass->Marker += (ushort)Packet->TotalSize;
  1328. //
  1329. // Now peruse the non-contiguous list here to see if we already
  1330. // have the next fragment to extend the contiguous list, and if so,
  1331. // move it on over. Repeat until we can't.
  1332. //
  1333. MoveShim = &Reass->GapList;
  1334. while ((ThisShim = *MoveShim) != NULL) {
  1335. if (ThisShim->Offset == Reass->Marker) {
  1336. //
  1337. // This fragment now extends the contiguous list.
  1338. // Add it to the end of the list.
  1339. //
  1340. Reass->ContigEnd->Next = ThisShim;
  1341. Reass->ContigEnd = ThisShim;
  1342. Reass->Marker += ThisShim->Len;
  1343. //
  1344. // Remove it from non-contiguous list.
  1345. //
  1346. *MoveShim = ThisShim->Next;
  1347. ThisShim->Next = NULL;
  1348. }
  1349. else if (ThisShim->Offset > Reass->Marker) {
  1350. //
  1351. // This fragment lies beyond the contiguous list.
  1352. // Because the gap list is sorted, we can stop now.
  1353. //
  1354. break;
  1355. }
  1356. else {
  1357. //
  1358. // This fragment overlaps the contiguous list.
  1359. // For DoS prevention, drop the reassembly.
  1360. //
  1361. BadFragmentOverlap:
  1362. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1363. "FragmentReceive: overlapping fragment\n"));
  1364. DeleteFromReassemblyList(Reass);
  1365. return IP_PROTOCOL_NONE;
  1366. }
  1367. }
  1368. } else {
  1369. //
  1370. // Exile this fragment to the non-contiguous (gap) list.
  1371. // The gap list is sorted by Offset.
  1372. //
  1373. MoveShim = &Reass->GapList;
  1374. for (;;) {
  1375. ThisShim = *MoveShim;
  1376. if (ThisShim == NULL) {
  1377. //
  1378. // Insert Shim at the end of the gap list.
  1379. //
  1380. Reass->MaxGap = Shim->Offset + Shim->Len;
  1381. break;
  1382. }
  1383. if (Shim->Offset < ThisShim->Offset) {
  1384. //
  1385. // Check for partial overlap.
  1386. //
  1387. if (Shim->Offset + Shim->Len > ThisShim->Offset) {
  1388. ExFreePool(Shim);
  1389. goto BadFragmentOverlap;
  1390. }
  1391. //
  1392. // OK, insert Shim before ThisShim.
  1393. //
  1394. break;
  1395. }
  1396. else if (ThisShim->Offset < Shim->Offset) {
  1397. //
  1398. // Check for partial overlap.
  1399. //
  1400. if (ThisShim->Offset + ThisShim->Len > Shim->Offset) {
  1401. ExFreePool(Shim);
  1402. goto BadFragmentOverlap;
  1403. }
  1404. //
  1405. // OK, insert Shim somewhere after ThisShim.
  1406. // Keep looking for the right spot.
  1407. //
  1408. MoveShim = &ThisShim->Next;
  1409. }
  1410. else {
  1411. //
  1412. // If the new fragment duplicates the old,
  1413. // then just ignore the new fragment.
  1414. //
  1415. if (Shim->Len == ThisShim->Len) {
  1416. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1417. "FragmentReceive: duplicate fragment\n"));
  1418. ExFreePool(Shim);
  1419. KeReleaseSpinLockFromDpcLevel(&Reass->Lock);
  1420. return IP_PROTOCOL_NONE;
  1421. }
  1422. else {
  1423. ExFreePool(Shim);
  1424. goto BadFragmentOverlap;
  1425. }
  1426. }
  1427. }
  1428. Shim->Next = *MoveShim;
  1429. *MoveShim = Shim;
  1430. }
  1431. //
  1432. // Now that we have added the shim to the reassembly record
  1433. // and passed various checks (particularly DoS checks),
  1434. // copy the actual fragment data to the shim.
  1435. //
  1436. CopyPacketToBuffer(PacketShimData(Shim), Packet,
  1437. Packet->TotalSize, Packet->Position);
  1438. if (Reass->Marker == Reass->DataLength) {
  1439. //
  1440. // We have received all the fragments.
  1441. // Because of the overlapping/data-length/zero-size sanity checks
  1442. // above, when this happens there should be no fragments
  1443. // left on the gap list. However, ReassembleDatagram does not
  1444. // rely on having an empty gap list.
  1445. //
  1446. ASSERT(Reass->GapList == NULL);
  1447. ReassembleDatagram(Packet, Reass);
  1448. }
  1449. else {
  1450. //
  1451. // Finally, check if we're too close to our limit for
  1452. // reassembly buffers. If so, drop this packet. Otherwise,
  1453. // wait for more fragments to arrive.
  1454. //
  1455. CheckReassemblyQuota(Reass);
  1456. }
  1457. return IP_PROTOCOL_NONE;
  1458. Failed:
  1459. IPSInfo.ipsi_reasmfails++;
  1460. return IP_PROTOCOL_NONE;
  1461. }
  1462. //* FragmentLookup - look for record of previous fragments from this datagram.
  1463. //
  1464. // A datagram on an interface is uniquely identified by its
  1465. // {source address, destination address, identification field} triple.
  1466. // This function checks our reassembly list for previously
  1467. // received fragments of a given datagram.
  1468. //
  1469. // If an existing reassembly record is found,
  1470. // it is returned locked.
  1471. //
  1472. // If there is no existing reassembly record, returns NULL
  1473. // and leaves the global reassembly list locked.
  1474. //
  1475. // Callable from DPC context, not from thread context.
  1476. //
  1477. Reassembly *
  1478. FragmentLookup(
  1479. Interface *IF, // Receiving interface.
  1480. ulong Id, // Fragment identification field to match.
  1481. const IPv6Addr *Src, // Source address to match.
  1482. const IPv6Addr *Dst) // Destination address to match.
  1483. {
  1484. Reassembly *Reass;
  1485. KeAcquireSpinLockAtDpcLevel(&ReassemblyList.Lock);
  1486. for (Reass = ReassemblyList.First;; Reass = Reass->Next) {
  1487. if (Reass == SentinelReassembly) {
  1488. //
  1489. // Return with the global reassembly list lock still held.
  1490. //
  1491. return NULL;
  1492. }
  1493. if ((Reass->IF == IF) &&
  1494. (Reass->Id == Id) &&
  1495. IP6_ADDR_EQUAL(&Reass->IPHdr.Source, Src) &&
  1496. IP6_ADDR_EQUAL(&Reass->IPHdr.Dest, Dst)) {
  1497. //
  1498. // Is this reassembly record being deleted?
  1499. // If so, ignore it.
  1500. //
  1501. KeAcquireSpinLockAtDpcLevel(&Reass->Lock);
  1502. ASSERT((Reass->State == REASSEMBLY_STATE_NORMAL) ||
  1503. (Reass->State == REASSEMBLY_STATE_DELETING));
  1504. if (Reass->State == REASSEMBLY_STATE_DELETING) {
  1505. KeReleaseSpinLockFromDpcLevel(&Reass->Lock);
  1506. continue;
  1507. }
  1508. //
  1509. // Return with the reassembly record lock still held.
  1510. //
  1511. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.Lock);
  1512. return Reass;
  1513. }
  1514. }
  1515. }
  1516. //* AddToReassemblyList
  1517. //
  1518. // Add the reassembly record to the list.
  1519. // It must NOT already be on the list.
  1520. //
  1521. // Called with the global reassembly list lock held.
  1522. // Returns with the reassembly record lock held.
  1523. //
  1524. // Callable from DPC context, not from thread context.
  1525. //
  1526. void
  1527. AddToReassemblyList(Reassembly *Reass)
  1528. {
  1529. Reassembly *AfterReass = SentinelReassembly;
  1530. Reass->Prev = AfterReass;
  1531. (Reass->Next = AfterReass->Next)->Prev = Reass;
  1532. AfterReass->Next = Reass;
  1533. KeAcquireSpinLockAtDpcLevel(&ReassemblyList.LockSize);
  1534. ReassemblyList.Size += Reass->Size;
  1535. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.LockSize);
  1536. //
  1537. // We must acquire the reassembly record lock
  1538. // *before* releasing the global reassembly list lock,
  1539. // to prevent the reassembly from diappearing underneath us.
  1540. //
  1541. KeAcquireSpinLockAtDpcLevel(&Reass->Lock);
  1542. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.Lock);
  1543. }
  1544. //* RemoveReassembly
  1545. //
  1546. // Remove a reassembly record from the list.
  1547. //
  1548. // Called with the global reassembly lock held.
  1549. // The reassembly record lock may be held.
  1550. //
  1551. void
  1552. RemoveReassembly(Reassembly *Reass)
  1553. {
  1554. Reass->Prev->Next = Reass->Next;
  1555. Reass->Next->Prev = Reass->Prev;
  1556. KeAcquireSpinLockAtDpcLevel(&ReassemblyList.LockSize);
  1557. ReassemblyList.Size -= Reass->Size;
  1558. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.LockSize);
  1559. }
  1560. //* IncreaseReassemblySize
  1561. //
  1562. // Increase the size of the reassembly record.
  1563. // Called with the reassembly record lock held.
  1564. //
  1565. // Callable from DPC context, not from thread context.
  1566. //
  1567. void
  1568. IncreaseReassemblySize(Reassembly *Reass, uint Size)
  1569. {
  1570. Reass->Size += Size;
  1571. KeAcquireSpinLockAtDpcLevel(&ReassemblyList.LockSize);
  1572. ReassemblyList.Size += Size;
  1573. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.LockSize);
  1574. }
  1575. //* DeleteReassembly
  1576. //
  1577. // Delete a reassembly record.
  1578. //
  1579. void
  1580. DeleteReassembly(Reassembly *Reass)
  1581. {
  1582. PacketShim *ThisShim, *PrevShim;
  1583. //
  1584. // Free ContigList if populated.
  1585. //
  1586. PrevShim = ThisShim = Reass->ContigList;
  1587. while (ThisShim != NULL) {
  1588. PrevShim = ThisShim;
  1589. ThisShim = ThisShim->Next;
  1590. ExFreePool(PrevShim);
  1591. }
  1592. //
  1593. // Free GapList if populated.
  1594. //
  1595. PrevShim = ThisShim = Reass->GapList;
  1596. while (ThisShim != NULL) {
  1597. PrevShim = ThisShim;
  1598. ThisShim = ThisShim->Next;
  1599. ExFreePool(PrevShim);
  1600. }
  1601. //
  1602. // Free unfragmentable data.
  1603. //
  1604. if (Reass->UnfragData != NULL)
  1605. ExFreePool(Reass->UnfragData);
  1606. ExFreePool(Reass);
  1607. }
  1608. //* DeleteFromReassemblyList
  1609. //
  1610. // Remove and delete the reassembly record.
  1611. // The reassembly record MUST be on the list.
  1612. //
  1613. // Callable from DPC context, not from thread context.
  1614. // Called with the reassembly record lock held,
  1615. // but not the global reassembly list lock.
  1616. //
  1617. void
  1618. DeleteFromReassemblyList(Reassembly *Reass)
  1619. {
  1620. //
  1621. // Mark the reassembly as being deleted.
  1622. // This will prevent someone else from freeing it.
  1623. //
  1624. ASSERT(Reass->State == REASSEMBLY_STATE_NORMAL);
  1625. Reass->State = REASSEMBLY_STATE_DELETING;
  1626. KeReleaseSpinLockFromDpcLevel(&Reass->Lock);
  1627. KeAcquireSpinLockAtDpcLevel(&ReassemblyList.Lock);
  1628. KeAcquireSpinLockAtDpcLevel(&Reass->Lock);
  1629. ASSERT((Reass->State == REASSEMBLY_STATE_DELETING) ||
  1630. (Reass->State == REASSEMBLY_STATE_REMOVED));
  1631. //
  1632. // Remove the reassembly record from the list,
  1633. // if someone else hasn't already removed it.
  1634. //
  1635. if (Reass->State != REASSEMBLY_STATE_REMOVED)
  1636. RemoveReassembly(Reass);
  1637. KeReleaseSpinLockFromDpcLevel(&Reass->Lock);
  1638. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.Lock);
  1639. //
  1640. // Delete the reassembly record.
  1641. //
  1642. DeleteReassembly(Reass);
  1643. }
  1644. //* CheckReassemblyQuota
  1645. //
  1646. // Delete reassembly record if necessary,
  1647. // to keep the reassembly buffering under quota.
  1648. //
  1649. // Callable from DPC context, not from thread context.
  1650. // Called with the reassembly record lock held,
  1651. // but not the global reassembly list lock.
  1652. //
  1653. void
  1654. CheckReassemblyQuota(Reassembly *Reass)
  1655. {
  1656. int Prune = FALSE;
  1657. uint Threshold = ReassemblyList.Limit / 2;
  1658. //
  1659. // Decide whether to drop the reassembly record based on a RED-like
  1660. // algorithm. If the total size is less than 50% of the max, never
  1661. // drop. If the total size is over the max, always drop. If between
  1662. // 50% and 100% full, drop based on a probability proportional to the
  1663. // amount over 50%. This is an O(1) algorithm which is proportionally
  1664. // biased against large packets, and against sources which send more
  1665. // packets. This should provide a decent level of protection against
  1666. // DoS attacks.
  1667. //
  1668. KeAcquireSpinLockAtDpcLevel(&ReassemblyList.LockSize);
  1669. if ((ReassemblyList.Size > Threshold) &&
  1670. (RandomNumber(0, Threshold) < ReassemblyList.Size - Threshold))
  1671. Prune = TRUE;
  1672. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.LockSize);
  1673. if (Prune) {
  1674. //
  1675. // Delete this reassembly record.
  1676. // We do not send ICMP errors in this situation.
  1677. // The reassembly timer has not expired.
  1678. // This is more analogous to a router dropping packets
  1679. // when a queue gets full, and no ICMP error is sent
  1680. // in that situation.
  1681. //
  1682. #if DBG
  1683. char Buffer1[INET6_ADDRSTRLEN], Buffer2[INET6_ADDRSTRLEN];
  1684. FormatV6AddressWorker(Buffer1, &Reass->IPHdr.Source);
  1685. FormatV6AddressWorker(Buffer2, &Reass->IPHdr.Dest);
  1686. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1687. "CheckReassemblyQuota: Src %s Dst %s Id %x\n",
  1688. Buffer1, Buffer2, Reass->Id));
  1689. #endif
  1690. DeleteFromReassemblyList(Reass);
  1691. }
  1692. else
  1693. KeReleaseSpinLockFromDpcLevel(&Reass->Lock);
  1694. }
  1695. typedef struct ReassembledReceiveContext {
  1696. WORK_QUEUE_ITEM WQItem;
  1697. IPv6Packet Packet;
  1698. uchar Data[];
  1699. } ReassembledReceiveContext;
  1700. //* ReassembledReceive
  1701. //
  1702. // Receive a reassembled packet.
  1703. // This function is called from a kernel worker thread context.
  1704. // It prevents "reassembly recursion".
  1705. //
  1706. void
  1707. ReassembledReceive(PVOID Context)
  1708. {
  1709. ReassembledReceiveContext *rrc = (ReassembledReceiveContext *) Context;
  1710. KIRQL Irql;
  1711. int PktRefs;
  1712. //
  1713. // All receive processing normally happens at DPC level,
  1714. // so we must pretend to be a DPC, so we raise IRQL.
  1715. // (System worker threads typically run at PASSIVE_LEVEL).
  1716. //
  1717. KeRaiseIrql(DISPATCH_LEVEL, &Irql);
  1718. PktRefs = IPv6Receive(&rrc->Packet);
  1719. ASSERT(PktRefs == 0);
  1720. KeLowerIrql(Irql);
  1721. ExFreePool(rrc);
  1722. }
  1723. //* ReassembleDatagram - put all the fragments together.
  1724. //
  1725. // Called when we have all the fragments to complete a datagram.
  1726. // Patch them together and pass the packet up.
  1727. //
  1728. // We allocate a single contiguous buffer and copy the fragments
  1729. // into this buffer.
  1730. // REVIEW: Instead use ndis buffers to chain the fragments?
  1731. //
  1732. // Callable from DPC context, not from thread context.
  1733. // Called with the reassembly record lock held,
  1734. // but not the global reassembly list lock.
  1735. //
  1736. // Deletes the reassembly record.
  1737. //
  1738. void
  1739. ReassembleDatagram(
  1740. IPv6Packet *Packet, // The packet being currently received.
  1741. Reassembly *Reass) // Reassembly record for fragmented datagram.
  1742. {
  1743. uint DataLen;
  1744. uint TotalLength;
  1745. uint memptr = sizeof(IPv6Header);
  1746. PacketShim *ThisShim, *PrevShim;
  1747. ReassembledReceiveContext *rrc;
  1748. IPv6Packet *ReassPacket;
  1749. uchar *ReassBuffer;
  1750. uchar *pNextHeader;
  1751. DataLen = Reass->DataLength + Reass->UnfragmentLength;
  1752. ASSERT(DataLen <= MAX_IPv6_PAYLOAD);
  1753. TotalLength = sizeof(IPv6Header) + DataLen;
  1754. //
  1755. // Allocate memory for buffer and copy fragment data into it.
  1756. // At the same time we allocate space for context information
  1757. // and an IPv6 packet structure.
  1758. //
  1759. rrc = ExAllocatePool(NonPagedPool, sizeof *rrc + TotalLength);
  1760. if (rrc == NULL) {
  1761. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1762. "ReassembleDatagram: Couldn't allocate memory!?!\n"));
  1763. DeleteFromReassemblyList(Reass);
  1764. IPSInfo.ipsi_reasmfails++;
  1765. return;
  1766. }
  1767. //
  1768. // We must take a reference on the interface before
  1769. // DeleteFromReassemblyList releases the record lock.
  1770. //
  1771. ReassPacket = &rrc->Packet;
  1772. ReassBuffer = rrc->Data;
  1773. //
  1774. // Generate the original IP hdr and copy it and any unfragmentable
  1775. // data into the new packet. Note we have to update the next header
  1776. // field in the last unfragmentable header (or the IP hdr, if none).
  1777. //
  1778. Reass->IPHdr.PayloadLength = net_short((ushort)DataLen);
  1779. RtlCopyMemory(ReassBuffer, (uchar *)&Reass->IPHdr, sizeof(IPv6Header));
  1780. RtlCopyMemory(ReassBuffer + memptr, Reass->UnfragData,
  1781. Reass->UnfragmentLength);
  1782. memptr += Reass->UnfragmentLength;
  1783. pNextHeader = ReassBuffer + Reass->NextHeaderOffset;
  1784. ASSERT(*pNextHeader == IP_PROTOCOL_FRAGMENT);
  1785. *pNextHeader = Reass->NextHeader;
  1786. //
  1787. // Run through the contiguous list, copying data over to our new packet.
  1788. //
  1789. PrevShim = ThisShim = Reass->ContigList;
  1790. while(ThisShim != NULL) {
  1791. RtlCopyMemory(ReassBuffer + memptr, PacketShimData(ThisShim),
  1792. ThisShim->Len);
  1793. memptr += ThisShim->Len;
  1794. if (memptr > TotalLength) {
  1795. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  1796. "ReassembleDatagram: packets don't add up\n"));
  1797. }
  1798. PrevShim = ThisShim;
  1799. ThisShim = ThisShim->Next;
  1800. ExFreePool(PrevShim);
  1801. }
  1802. //
  1803. // Initialize the reassembled packet structure.
  1804. //
  1805. RtlZeroMemory(ReassPacket, sizeof *ReassPacket);
  1806. AddRefIF(Reass->IF);
  1807. ReassPacket->NTEorIF = CastFromIF(Reass->IF);
  1808. ReassPacket->FlatData = ReassBuffer;
  1809. ReassPacket->Data = ReassBuffer;
  1810. ReassPacket->ContigSize = TotalLength;
  1811. ReassPacket->TotalSize = TotalLength;
  1812. ReassPacket->Flags = PACKET_HOLDS_REF | PACKET_REASSEMBLED |
  1813. (Reass->Flags & PACKET_INHERITED_FLAGS);
  1814. //
  1815. // Explicitly null out the ContigList which was freed above and
  1816. // clean up the reassembly struct. This also drops our lock
  1817. // on the reassembly struct.
  1818. //
  1819. Reass->ContigList = NULL;
  1820. DeleteFromReassemblyList(Reass);
  1821. IPSInfo.ipsi_reasmoks++;
  1822. //
  1823. // Receive the reassembled packet.
  1824. // If the current fragment was reassembled,
  1825. // then we should avoid another level of recursion.
  1826. // We must prevent "reassembly recursion".
  1827. // Test both paths in checked builds.
  1828. //
  1829. if ((Packet->Flags & PACKET_REASSEMBLED)
  1830. #if DBG
  1831. || ((int)Random() < 0)
  1832. #endif
  1833. ) {
  1834. ExInitializeWorkItem(&rrc->WQItem, ReassembledReceive, rrc);
  1835. ExQueueWorkItem(&rrc->WQItem, CriticalWorkQueue);
  1836. }
  1837. else {
  1838. int PktRefs = IPv6Receive(ReassPacket);
  1839. ASSERT(PktRefs == 0);
  1840. ExFreePool(rrc);
  1841. }
  1842. }
  1843. //* CreateFragmentPacket
  1844. //
  1845. // Recreates the first fragment packet for purposes of notifying a source
  1846. // of a 'fragment reassembly time exceeded'.
  1847. //
  1848. IPv6Packet *
  1849. CreateFragmentPacket(
  1850. Reassembly *Reass)
  1851. {
  1852. PacketShim *FirstFrag;
  1853. IPv6Packet *Packet;
  1854. FragmentHeader *FragHdr;
  1855. uint PayloadLength;
  1856. uint PacketLength;
  1857. uint MemLen;
  1858. uchar *Mem;
  1859. //
  1860. // There must be a first (offset-zero) fragment.
  1861. //
  1862. FirstFrag = Reass->ContigList;
  1863. ASSERT((FirstFrag != NULL) && (FirstFrag->Offset == 0));
  1864. //
  1865. // Allocate memory for creating the first fragment, i.e. the first
  1866. // buffer in our contig list. We include space for an IPv6Packet.
  1867. //
  1868. PayloadLength = (Reass->UnfragmentLength + sizeof(FragmentHeader) +
  1869. FirstFrag->Len);
  1870. PacketLength = sizeof(IPv6Header) + PayloadLength;
  1871. MemLen = sizeof(IPv6Packet) + PacketLength;
  1872. Mem = ExAllocatePool(NonPagedPool, MemLen);
  1873. if (Mem == NULL) {
  1874. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1875. "CreateFragmentPacket: Couldn't allocate memory!?!\n"));
  1876. return NULL;
  1877. }
  1878. Packet = (IPv6Packet *) Mem;
  1879. Mem += sizeof(IPv6Packet);
  1880. Packet->Next = NULL;
  1881. Packet->IP = (IPv6Header UNALIGNED *) Mem;
  1882. Packet->IPPosition = 0;
  1883. Packet->Data = Packet->FlatData = Mem;
  1884. Packet->Position = 0;
  1885. Packet->ContigSize = Packet->TotalSize = PacketLength;
  1886. Packet->NdisPacket = NULL;
  1887. Packet->AuxList = NULL;
  1888. Packet->Flags = 0;
  1889. Packet->SrcAddr = AlignAddr(&Packet->IP->Source);
  1890. Packet->SAPerformed = NULL;
  1891. // Our caller must initialize Packet->NTEorIF.
  1892. AdjustPacketParams(Packet, sizeof(IPv6Header));
  1893. //
  1894. // Copy the original IPv6 header into the packet.
  1895. // Note that FragmentReceive ensures that
  1896. // Reass->IPHdr, Reass->UnfragData, and FirstFrag
  1897. // are all consistent.
  1898. //
  1899. RtlCopyMemory(Mem, (uchar *)&Reass->IPHdr, sizeof(IPv6Header));
  1900. Mem += sizeof(IPv6Header);
  1901. ASSERT(Reass->IPHdr.PayloadLength == net_short((ushort)PayloadLength));
  1902. //
  1903. // Copy the unfragmentable data into the packet.
  1904. //
  1905. RtlCopyMemory(Mem, Reass->UnfragData, Reass->UnfragmentLength);
  1906. Mem += Reass->UnfragmentLength;
  1907. //
  1908. // Create a fragment header in the packet.
  1909. //
  1910. FragHdr = (FragmentHeader *) Mem;
  1911. Mem += sizeof(FragmentHeader);
  1912. //
  1913. // Note that if the original offset-zero fragment had
  1914. // a non-zero value in the Reserved field, then we will
  1915. // not recreate it properly. It shouldn't do that.
  1916. //
  1917. FragHdr->NextHeader = Reass->NextHeader;
  1918. FragHdr->Reserved = 0;
  1919. FragHdr->OffsetFlag = net_short(FRAGMENT_FLAG_MASK);
  1920. FragHdr->Id = Reass->Id;
  1921. //
  1922. // Copy the original fragment data into the packet.
  1923. //
  1924. RtlCopyMemory(Mem, PacketShimData(FirstFrag), FirstFrag->Len);
  1925. return Packet;
  1926. }
  1927. //* ReassemblyTimeout - Handle a reassembly timer event.
  1928. //
  1929. // This routine is called periodically by IPv6Timeout to check for
  1930. // timed out fragments.
  1931. //
  1932. void
  1933. ReassemblyTimeout(void)
  1934. {
  1935. Reassembly *ThisReass, *NextReass;
  1936. Reassembly *Expired = NULL;
  1937. //
  1938. // Scan the ReassemblyList checking for expired reassembly contexts.
  1939. //
  1940. KeAcquireSpinLockAtDpcLevel(&ReassemblyList.Lock);
  1941. for (ThisReass = ReassemblyList.First;
  1942. ThisReass != SentinelReassembly;
  1943. ThisReass = NextReass) {
  1944. NextReass = ThisReass->Next;
  1945. //
  1946. // First decrement the timer then check if it has expired. If so,
  1947. // remove the reassembly record. This is basically the same code
  1948. // as in DeleteFromReassemblyList().
  1949. //
  1950. ThisReass->Timer--;
  1951. if (ThisReass->Timer == 0) {
  1952. RemoveReassembly(ThisReass);
  1953. KeAcquireSpinLockAtDpcLevel(&ThisReass->Lock);
  1954. ASSERT((ThisReass->State == REASSEMBLY_STATE_NORMAL) ||
  1955. (ThisReass->State == REASSEMBLY_STATE_DELETING));
  1956. if (ThisReass->State == REASSEMBLY_STATE_DELETING) {
  1957. //
  1958. // Note that we've removed it from the list already.
  1959. //
  1960. ThisReass->State = REASSEMBLY_STATE_REMOVED;
  1961. }
  1962. else {
  1963. //
  1964. // Move this reassembly context to the expired list.
  1965. // We must take a reference on the interface
  1966. // before releasing the reassembly record lock.
  1967. //
  1968. AddRefIF(ThisReass->IF);
  1969. ThisReass->Next = Expired;
  1970. Expired = ThisReass;
  1971. }
  1972. KeReleaseSpinLockFromDpcLevel(&ThisReass->Lock);
  1973. }
  1974. }
  1975. KeReleaseSpinLockFromDpcLevel(&ReassemblyList.Lock);
  1976. //
  1977. // Now that we no longer need the reassembly list lock,
  1978. // we can send ICMP errors at our leisure.
  1979. //
  1980. while ((ThisReass = Expired) != NULL) {
  1981. Interface *IF = ThisReass->IF;
  1982. #if DBG
  1983. char Buffer1[INET6_ADDRSTRLEN], Buffer2[INET6_ADDRSTRLEN];
  1984. FormatV6AddressWorker(Buffer1, &ThisReass->IPHdr.Source);
  1985. FormatV6AddressWorker(Buffer2, &ThisReass->IPHdr.Dest);
  1986. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1987. "ReassemblyTimeout: Src %s Dst %s Id %x\n",
  1988. Buffer1, Buffer2, ThisReass->Id));
  1989. #endif
  1990. Expired = ThisReass->Next;
  1991. //
  1992. // Send ICMP error IF we have received the first fragment.
  1993. // NB: Checking Marker != 0 is wrong, because we might have
  1994. // received a zero-length first fragment.
  1995. //
  1996. if (ThisReass->ContigList != NULL) {
  1997. IPv6Packet *Packet;
  1998. Packet = CreateFragmentPacket(ThisReass);
  1999. if (Packet != NULL) {
  2000. NetTableEntryOrInterface *NTEorIF;
  2001. ushort Type;
  2002. NTEorIF = FindAddressOnInterface(IF,
  2003. &ThisReass->IPHdr.Dest,
  2004. &Type);
  2005. if (NTEorIF != NULL) {
  2006. Packet->NTEorIF = NTEorIF;
  2007. ICMPv6SendError(Packet,
  2008. ICMPv6_TIME_EXCEEDED,
  2009. ICMPv6_REASSEMBLY_TIME_EXCEEDED, 0,
  2010. Packet->IP->NextHeader, FALSE);
  2011. if (IsNTE(NTEorIF))
  2012. ReleaseNTE(CastToNTE(NTEorIF));
  2013. else
  2014. ReleaseIF(CastToIF(NTEorIF));
  2015. }
  2016. ExFreePool(Packet);
  2017. }
  2018. }
  2019. //
  2020. // Delete the reassembly record.
  2021. //
  2022. ReleaseIF(IF);
  2023. DeleteReassembly(ThisReass);
  2024. }
  2025. }
  2026. //* DestinationOptionsReceive - Handle IPv6 Destination options.
  2027. //
  2028. // This is the routine called to process a Destination Options Header,
  2029. // a next header value of 60.
  2030. //
  2031. uchar
  2032. DestinationOptionsReceive(
  2033. IPv6Packet *Packet) // Packet handed to us by IPv6Receive.
  2034. {
  2035. IPv6OptionsHeader *DestOpt;
  2036. uint ExtLen;
  2037. Options Opts;
  2038. //
  2039. // Verify that we have enough contiguous data to overlay a Destination
  2040. // Options Header structure on the incoming packet. Then do so.
  2041. //
  2042. if (! PacketPullup(Packet, sizeof *DestOpt,
  2043. __builtin_alignof(IPv6OptionsHeader), 0)) {
  2044. if (Packet->TotalSize < sizeof *DestOpt) {
  2045. BadPayloadLength:
  2046. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  2047. "DestinationOptionsReceive: Incoming packet too small"
  2048. " to contain destination options header\n"));
  2049. ICMPv6SendError(Packet,
  2050. ICMPv6_PARAMETER_PROBLEM,
  2051. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2052. FIELD_OFFSET(IPv6Header, PayloadLength),
  2053. IP_PROTOCOL_NONE, FALSE);
  2054. }
  2055. return IP_PROTOCOL_NONE; // Drop packet.
  2056. }
  2057. DestOpt = (IPv6OptionsHeader *) Packet->Data;
  2058. //
  2059. // Check that length of destination options also fit in remaining data.
  2060. // The options must also be aligned for any addresses in them.
  2061. //
  2062. ExtLen = (DestOpt->HeaderExtLength + 1) * EXT_LEN_UNIT;
  2063. if (! PacketPullup(Packet, ExtLen,
  2064. MAX(__builtin_alignof(IPv6OptionsHeader),
  2065. __builtin_alignof(IPv6Addr)), 0)) {
  2066. if (Packet->TotalSize < ExtLen)
  2067. goto BadPayloadLength;
  2068. return IP_PROTOCOL_NONE; // Drop packet.
  2069. }
  2070. DestOpt = (IPv6OptionsHeader *) Packet->Data;
  2071. //
  2072. // Remember offset to this header's NextHeader field.
  2073. //
  2074. Packet->NextHeaderPosition = Packet->Position +
  2075. FIELD_OFFSET(IPv6OptionsHeader, NextHeader);
  2076. //
  2077. // Skip over the extension header.
  2078. // We need to do this now so subsequent ICMP error generation works.
  2079. //
  2080. AdjustPacketParams(Packet, ExtLen);
  2081. //
  2082. // Parse options in this extension header. If an error occurs
  2083. // while parsing the options, discard packet.
  2084. //
  2085. if (!ParseOptions(Packet, IP_PROTOCOL_DEST_OPTS, DestOpt, ExtLen, &Opts)) {
  2086. return IP_PROTOCOL_NONE; // Drop packet.
  2087. }
  2088. //
  2089. // The processing of any additional options should be added here,
  2090. // before the home address option.
  2091. //
  2092. //
  2093. // Process the home address option.
  2094. //
  2095. if (Opts.HomeAddress) {
  2096. if (IPv6RecvHomeAddress(Packet, Opts.HomeAddress)) {
  2097. //
  2098. // Couldn't process the home address option. Drop the packet.
  2099. //
  2100. return IP_PROTOCOL_NONE;
  2101. }
  2102. }
  2103. //
  2104. // Process binding update option.
  2105. //
  2106. // Note that the Mobile IP spec says that the effects of processing the
  2107. // Home Address option should not be visible until all other options in
  2108. // the same Destination Options header have been processed. Although
  2109. // we process the Binding Update option after the Home Address option,
  2110. // we achieve the same effect by requiring IPv6RecvBindingUpdate to
  2111. // know that the Packet->SrcAddr has already been updated.
  2112. //
  2113. if (Opts.BindingUpdate) {
  2114. if (IPv6RecvBindingUpdate(Packet, Opts.BindingUpdate)) {
  2115. //
  2116. // Couldn't process the binding update. Drop the packet.
  2117. //
  2118. return IP_PROTOCOL_NONE;
  2119. }
  2120. }
  2121. //
  2122. // Return next header value.
  2123. //
  2124. return DestOpt->NextHeader;
  2125. }
  2126. //* HopByHopOptionsReceive - Handle a IPv6 Hop-by-Hop Options.
  2127. //
  2128. // This is the routine called to process a Hop-by-Hop Options Header,
  2129. // next header value of 0.
  2130. //
  2131. // Note that this routine is not a normal handler in the Protocol Switch
  2132. // Table. Instead, it receives special treatment in IPv6HeaderReceive.
  2133. // Because of this, it returns -1 instead of IP_PROTOCOL_NONE on error.
  2134. //
  2135. int
  2136. HopByHopOptionsReceive(
  2137. IPv6Packet *Packet) // Packet handed to us by IPv6Receive.
  2138. {
  2139. IPv6OptionsHeader *HopByHop;
  2140. uint ExtLen;
  2141. Options Opts;
  2142. //
  2143. // Verify that we have enough contiguous data to overlay a minimum
  2144. // length Hop-by-Hop Options Header. Then do so.
  2145. //
  2146. if (! PacketPullup(Packet, sizeof *HopByHop,
  2147. __builtin_alignof(IPv6OptionsHeader), 0)) {
  2148. if (Packet->TotalSize < sizeof *HopByHop) {
  2149. BadPayloadLength:
  2150. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  2151. "HopByHopOptionsReceive: Incoming packet too small"
  2152. " to contain Hop-by-Hop Options header\n"));
  2153. ICMPv6SendError(Packet,
  2154. ICMPv6_PARAMETER_PROBLEM,
  2155. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2156. FIELD_OFFSET(IPv6Header, PayloadLength),
  2157. IP_PROTOCOL_NONE, FALSE);
  2158. }
  2159. return -1; // Drop packet.
  2160. }
  2161. HopByHop = (IPv6OptionsHeader *) Packet->Data;
  2162. //
  2163. // Check that length of the Hop-by-Hop options also fits in remaining data.
  2164. // The options must also be aligned for any addresses in them.
  2165. //
  2166. ExtLen = (HopByHop->HeaderExtLength + 1) * EXT_LEN_UNIT;
  2167. if (! PacketPullup(Packet, ExtLen,
  2168. MAX(__builtin_alignof(IPv6OptionsHeader),
  2169. __builtin_alignof(IPv6Addr)), 0)) {
  2170. if (Packet->TotalSize < ExtLen)
  2171. goto BadPayloadLength;
  2172. return -1; // Drop packet.
  2173. }
  2174. HopByHop = (IPv6OptionsHeader *) Packet->Data;
  2175. //
  2176. // Remember offset to this header's NextHeader field.
  2177. //
  2178. Packet->NextHeaderPosition = Packet->Position +
  2179. FIELD_OFFSET(IPv6OptionsHeader, NextHeader);
  2180. //
  2181. // Skip over the extension header.
  2182. // We need to do this now so subsequent ICMP error generation works.
  2183. //
  2184. AdjustPacketParams(Packet, ExtLen);
  2185. //
  2186. // Parse options in this extension header. If an error occurs
  2187. // while parsing the options, discard packet.
  2188. //
  2189. if (!ParseOptions(Packet, IP_PROTOCOL_HOP_BY_HOP, HopByHop,
  2190. ExtLen, &Opts)) {
  2191. return -1; // Drop packet.
  2192. }
  2193. //
  2194. // If we have a valid Jumbo Payload Option, use its value as
  2195. // the packet PayloadLength.
  2196. //
  2197. if (Opts.JumboLength) {
  2198. uint PayloadLength = Opts.JumboLength;
  2199. ASSERT(Packet->IP->PayloadLength == 0);
  2200. //
  2201. // Check that the jumbo length is big enough to include
  2202. // the extension header length. This must be true because
  2203. // the extension-header length is at most 11 bits,
  2204. // while the jumbo length is at least 16 bits.
  2205. //
  2206. ASSERT(PayloadLength > ExtLen);
  2207. PayloadLength -= ExtLen;
  2208. //
  2209. // Check that the amount of payload specified in the Jumbo
  2210. // Payload value fits in the buffer handed to us.
  2211. //
  2212. if (PayloadLength > Packet->TotalSize) {
  2213. // Silently discard data.
  2214. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  2215. "HopByHopOptionsReceive: "
  2216. "Jumbo payload length too big\n"));
  2217. return -1;
  2218. }
  2219. //
  2220. // As in IPv6HeaderReceive, adjust the TotalSize to be exactly the
  2221. // IP payload size (assume excess is media padding).
  2222. //
  2223. Packet->TotalSize = PayloadLength;
  2224. if (Packet->ContigSize > PayloadLength)
  2225. Packet->ContigSize = PayloadLength;
  2226. //
  2227. // Set the jumbo option packet flag.
  2228. //
  2229. Packet->Flags |= PACKET_JUMBO_OPTION;
  2230. }
  2231. else if (Packet->IP->PayloadLength == 0) {
  2232. //
  2233. // We should have a Jumbo Payload option,
  2234. // but we didn't find it. Send an ICMP error.
  2235. //
  2236. ICMPv6SendError(Packet,
  2237. ICMPv6_PARAMETER_PROBLEM,
  2238. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2239. FIELD_OFFSET(IPv6Header, PayloadLength),
  2240. HopByHop->NextHeader, FALSE);
  2241. return -1;
  2242. }
  2243. //
  2244. // Return next header value.
  2245. //
  2246. return HopByHop->NextHeader;
  2247. }
  2248. //* ParseOptions - Routine for generic header options parsing.
  2249. //
  2250. // Returns TRUE if the options were successfully parsed.
  2251. // Returns FALSE if the packet should be discarded.
  2252. //
  2253. int
  2254. ParseOptions(
  2255. IPv6Packet *Packet, // The packet handed to us by IPv6Receive.
  2256. uchar HdrType, // Hop-by-hop or destination.
  2257. IPv6OptionsHeader *Hdr, // Header with following data.
  2258. uint HdrLength, // Length of the entire options area.
  2259. Options *Opts) // Return option values to caller.
  2260. {
  2261. uchar *OptPtr;
  2262. uint OptSizeLeft;
  2263. OptionHeader *OptHdr;
  2264. uint OptLen;
  2265. ASSERT((HdrType == IP_PROTOCOL_DEST_OPTS) ||
  2266. (HdrType == IP_PROTOCOL_HOP_BY_HOP));
  2267. //
  2268. // Zero out the Options struct that is returned.
  2269. //
  2270. RtlZeroMemory(Opts, sizeof *Opts);
  2271. //
  2272. // Skip over the extension header.
  2273. //
  2274. OptPtr = (uchar *)(Hdr + 1);
  2275. OptSizeLeft = HdrLength - sizeof *Hdr;
  2276. //
  2277. // Note that if there are multiple options
  2278. // of the same type, we just use the last one encountered
  2279. // unless the spec says specifically it is an error.
  2280. //
  2281. while (OptSizeLeft > 0) {
  2282. //
  2283. // First we check the option length and ensure that it fits.
  2284. // We move OptPtr past this option while leaving OptHdr
  2285. // for use by the option processing code below.
  2286. //
  2287. OptHdr = (OptionHeader *) OptPtr;
  2288. if (OptHdr->Type == OPT6_PAD_1) {
  2289. //
  2290. // This is a special pad option which is just a one byte field,
  2291. // i.e. it has no length or data field.
  2292. //
  2293. OptLen = 1;
  2294. }
  2295. else {
  2296. //
  2297. // This is a multi-byte option.
  2298. //
  2299. if ((sizeof *OptHdr > OptSizeLeft) ||
  2300. ((OptLen = sizeof *OptHdr + OptHdr->DataLength) >
  2301. OptSizeLeft)) {
  2302. //
  2303. // Bad length, generate error and discard packet.
  2304. //
  2305. ICMPv6SendError(Packet,
  2306. ICMPv6_PARAMETER_PROBLEM,
  2307. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2308. (GetPacketPositionFromPointer(Packet,
  2309. &Hdr->HeaderExtLength) -
  2310. Packet->IPPosition),
  2311. Hdr->NextHeader, FALSE);
  2312. return FALSE;
  2313. }
  2314. }
  2315. OptPtr += OptLen;
  2316. OptSizeLeft -= OptLen;
  2317. switch (OptHdr->Type) {
  2318. case OPT6_PAD_1:
  2319. case OPT6_PAD_N:
  2320. break;
  2321. case OPT6_JUMBO_PAYLOAD:
  2322. if (HdrType != IP_PROTOCOL_HOP_BY_HOP)
  2323. goto BadOptionType;
  2324. if (OptHdr->DataLength != sizeof Opts->JumboLength)
  2325. goto BadOptionLength;
  2326. if (Packet->IP->PayloadLength != 0) {
  2327. //
  2328. // Jumbo option encountered when IP payload is not zero.
  2329. // Send ICMP error, set pointer to offset of this option type.
  2330. //
  2331. goto BadOptionType;
  2332. }
  2333. Opts->JumboLength = net_long(*(ulong UNALIGNED *)(OptHdr + 1));
  2334. if (Opts->JumboLength <= MAX_IPv6_PAYLOAD) {
  2335. //
  2336. // Jumbo payload length is not jumbo, send ICMP error.
  2337. // ICMP pointer is set to offset of jumbo payload len field.
  2338. //
  2339. goto BadOptionData;
  2340. }
  2341. break;
  2342. case OPT6_ROUTER_ALERT:
  2343. if (HdrType != IP_PROTOCOL_HOP_BY_HOP)
  2344. goto BadOptionType;
  2345. if (OptLen != sizeof *Opts->Alert)
  2346. goto BadOptionLength;
  2347. if (Opts->Alert != NULL) {
  2348. //
  2349. // Can only have one router alert option.
  2350. //
  2351. goto BadOptionType;
  2352. }
  2353. //
  2354. // Return the pointer to the router alert struct.
  2355. //
  2356. Opts->Alert = (IPv6RouterAlertOption UNALIGNED *)(OptHdr + 1);
  2357. break;
  2358. case OPT6_HOME_ADDRESS:
  2359. if (HdrType != IP_PROTOCOL_DEST_OPTS)
  2360. goto BadOptionType;
  2361. if (OptLen < sizeof *Opts->HomeAddress)
  2362. goto BadOptionLength;
  2363. //
  2364. // Return the pointer to the home address option
  2365. // after checking to make sure the address is reasonable.
  2366. // The option must be aligned so that the home address
  2367. // is appropriately aligned.
  2368. //
  2369. Opts->HomeAddress = (IPv6HomeAddressOption UNALIGNED *)OptHdr;
  2370. if (((UINT_PTR)&Opts->HomeAddress->HomeAddress % __builtin_alignof(IPv6Addr)) != 0) {
  2371. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  2372. "ParseOptions: misaligned home address\n"));
  2373. goto BadOptionType;
  2374. }
  2375. if (IsInvalidSourceAddress(AlignAddr(&Opts->HomeAddress->HomeAddress)) ||
  2376. IsUnspecified(AlignAddr(&Opts->HomeAddress->HomeAddress)) ||
  2377. IsLoopback(AlignAddr(&Opts->HomeAddress->HomeAddress))) {
  2378. //
  2379. // Address contained in option is invalid.
  2380. // Send ICMP error, set pointer to offset of home address.
  2381. //
  2382. goto BadOptionData;
  2383. }
  2384. break;
  2385. case OPT6_BINDING_UPDATE:
  2386. if (HdrType != IP_PROTOCOL_DEST_OPTS)
  2387. goto BadOptionType;
  2388. //
  2389. // At a minimum, the binding update must include all of the
  2390. // base header fields.
  2391. //
  2392. if (OptLen < sizeof(IPv6BindingUpdateOption)) {
  2393. //
  2394. // draft-ietf-mobileip-ipv6-13 sec 8.2 says we must
  2395. // silently drop the packet. Normally we would
  2396. // goto BadOptionLength to send an ICMP error.
  2397. //
  2398. return FALSE;
  2399. }
  2400. //
  2401. // Save pointer to the binding update option. Note we still
  2402. // need to do further length checking.
  2403. //
  2404. Opts->BindingUpdate = (IPv6BindingUpdateOption UNALIGNED *)OptHdr;
  2405. break;
  2406. default:
  2407. if (OPT6_ACTION(OptHdr->Type) == OPT6_A_SKIP) {
  2408. //
  2409. // Ignore the unrecognized option.
  2410. //
  2411. break;
  2412. }
  2413. else if (OPT6_ACTION(OptHdr->Type) == OPT6_A_DISCARD) {
  2414. //
  2415. // Discard the packet.
  2416. //
  2417. return FALSE;
  2418. }
  2419. else {
  2420. //
  2421. // Send an ICMP error.
  2422. //
  2423. ICMPv6SendError(Packet,
  2424. ICMPv6_PARAMETER_PROBLEM,
  2425. ICMPv6_UNRECOGNIZED_OPTION,
  2426. (GetPacketPositionFromPointer(Packet,
  2427. &OptHdr->Type) -
  2428. Packet->IPPosition),
  2429. Hdr->NextHeader,
  2430. OPT6_ACTION(OptHdr->Type) ==
  2431. OPT6_A_SEND_ICMP_ALL);
  2432. return FALSE; // discard the packet.
  2433. }
  2434. }
  2435. }
  2436. return TRUE;
  2437. BadOptionType:
  2438. ICMPv6SendError(Packet,
  2439. ICMPv6_PARAMETER_PROBLEM,
  2440. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2441. (GetPacketPositionFromPointer(Packet,
  2442. &OptHdr->Type) -
  2443. Packet->IPPosition),
  2444. Hdr->NextHeader, FALSE);
  2445. return FALSE; // discard packet.
  2446. BadOptionLength:
  2447. ICMPv6SendError(Packet,
  2448. ICMPv6_PARAMETER_PROBLEM,
  2449. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2450. (GetPacketPositionFromPointer(Packet,
  2451. &OptHdr->DataLength) -
  2452. Packet->IPPosition),
  2453. Hdr->NextHeader, FALSE);
  2454. return FALSE; // discard packet.
  2455. BadOptionData:
  2456. ICMPv6SendError(Packet,
  2457. ICMPv6_PARAMETER_PROBLEM,
  2458. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2459. (GetPacketPositionFromPointer(Packet,
  2460. (uchar *)(OptHdr + 1)) -
  2461. Packet->IPPosition),
  2462. Hdr->NextHeader, FALSE);
  2463. return FALSE; // discard packet.
  2464. }
  2465. //* ExtHdrControlReceive - generic extension header skip-over routine.
  2466. //
  2467. // Routine for processing the extension headers in an ICMP error message
  2468. // before delivering the error message to the upper-layer protocol.
  2469. //
  2470. uchar
  2471. ExtHdrControlReceive(
  2472. IPv6Packet *Packet, // Packet handed to us by ICMPv6ErrorReceive.
  2473. StatusArg *StatArg) // ICMP Error code and offset pointer.
  2474. {
  2475. uchar NextHdr = StatArg->IP->NextHeader;
  2476. uint HdrLen;
  2477. for (;;) {
  2478. switch (NextHdr) {
  2479. case IP_PROTOCOL_HOP_BY_HOP:
  2480. case IP_PROTOCOL_DEST_OPTS:
  2481. case IP_PROTOCOL_ROUTING: {
  2482. ExtensionHeader *ExtHdr; // Generic exension header.
  2483. //
  2484. // Here we take advantage of the fact that all of these extension
  2485. // headers share the same first two fields (except as noted below).
  2486. // Since those two fields (Next Header and Header Extension Length)
  2487. // provide us with all the information we need to skip over the
  2488. // header, they're all we need to look at here.
  2489. //
  2490. if (! PacketPullup(Packet, sizeof *ExtHdr,
  2491. __builtin_alignof(ExtensionHeader), 0)) {
  2492. if (Packet->TotalSize < sizeof *ExtHdr) {
  2493. PacketTooSmall:
  2494. //
  2495. // Pullup failed. There isn't enough of the invoking
  2496. // packet included in the error message to figure out
  2497. // what upper layer protocol it originated with.
  2498. //
  2499. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  2500. "ExtHdrControlReceive: "
  2501. "Incoming ICMP error packet "
  2502. "doesn't contain enough of invoking packet\n"));
  2503. }
  2504. return IP_PROTOCOL_NONE; // Drop packet.
  2505. }
  2506. ExtHdr = (ExtensionHeader *) Packet->Data;
  2507. HdrLen = (ExtHdr->HeaderExtLength + 1) * EXT_LEN_UNIT;
  2508. //
  2509. // Now that we know the actual length of this extension header,
  2510. // skip over it.
  2511. //
  2512. // REVIEW: We could rework this to use PositionPacketAt
  2513. // REVIEW: here instead of PacketPullup as we don't need to
  2514. // REVIEW: look at the data we're skipping over. Better?
  2515. //
  2516. if (! PacketPullup(Packet, HdrLen, 1, 0)) {
  2517. if (Packet->TotalSize < HdrLen)
  2518. goto PacketTooSmall;
  2519. return IP_PROTOCOL_NONE; // Drop packet.
  2520. }
  2521. NextHdr = ExtHdr->NextHeader;
  2522. break;
  2523. }
  2524. case IP_PROTOCOL_FRAGMENT: {
  2525. FragmentHeader UNALIGNED *FragHdr;
  2526. if (! PacketPullup(Packet, sizeof *FragHdr, 1, 0)) {
  2527. if (Packet->TotalSize < sizeof *FragHdr)
  2528. goto PacketTooSmall;
  2529. return IP_PROTOCOL_NONE; // Drop packet.
  2530. }
  2531. FragHdr = (FragmentHeader UNALIGNED *) Packet->Data;
  2532. if ((net_short(FragHdr->OffsetFlag) & FRAGMENT_OFFSET_MASK) != 0) {
  2533. //
  2534. // We can only continue parsing if this
  2535. // fragment has offset zero.
  2536. //
  2537. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  2538. "ExtHdrControlReceive: "
  2539. "non-zero-offset fragment\n"));
  2540. return IP_PROTOCOL_NONE;
  2541. }
  2542. HdrLen = sizeof *FragHdr;
  2543. NextHdr = FragHdr->NextHeader;
  2544. break;
  2545. }
  2546. case IP_PROTOCOL_AH:
  2547. case IP_PROTOCOL_ESP:
  2548. //
  2549. // REVIEW - What is the correct thing here?
  2550. //
  2551. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  2552. "ExtHdrControlReceive: found AH/ESP\n"));
  2553. return IP_PROTOCOL_NONE;
  2554. default:
  2555. //
  2556. // We came to a header that we do not recognize,
  2557. // so we can not continue parsing here.
  2558. // But our caller might recognize this header type.
  2559. //
  2560. return NextHdr;
  2561. }
  2562. //
  2563. // Move past this extension header.
  2564. //
  2565. AdjustPacketParams(Packet, HdrLen);
  2566. }
  2567. }
  2568. //* RoutingReceive - Handle the IPv6 Routing Header.
  2569. //
  2570. // Called from IPv6Receive when we encounter a Routing Header,
  2571. // next header value of 43.
  2572. //
  2573. uchar
  2574. RoutingReceive(
  2575. IPv6Packet *Packet) // Packet handed to us by link layer.
  2576. {
  2577. IPv6RoutingHeader *RH;
  2578. uint HeaderLength;
  2579. uint SegmentsLeft;
  2580. uint NumAddresses, i;
  2581. IPv6Addr *Addresses;
  2582. IP_STATUS Status;
  2583. uchar *Mem;
  2584. uint MemLen, Offset;
  2585. NDIS_PACKET *FwdPacket;
  2586. NDIS_STATUS NdisStatus;
  2587. IPv6Header UNALIGNED *FwdIP;
  2588. IPv6RoutingHeader UNALIGNED *FwdRH;
  2589. IPv6Addr UNALIGNED *FwdAddresses;
  2590. IPv6Addr FwdDest;
  2591. int Delta;
  2592. uint PayloadLength;
  2593. uint TunnelStart = NO_TUNNEL, IPSecBytes = 0;
  2594. IPSecProc *IPSecToDo;
  2595. RouteCacheEntry *RCE;
  2596. uint Action;
  2597. //
  2598. // Verify that we have enough contiguous data,
  2599. // then get a pointer to the routing header.
  2600. //
  2601. if (! PacketPullup(Packet, sizeof *RH,
  2602. __builtin_alignof(IPv6RoutingHeader), 0)) {
  2603. if (Packet->TotalSize < sizeof *RH) {
  2604. BadPayloadLength:
  2605. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  2606. "RoutingReceive: Incoming packet too small"
  2607. " to contain routing header\n"));
  2608. ICMPv6SendError(Packet,
  2609. ICMPv6_PARAMETER_PROBLEM,
  2610. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2611. FIELD_OFFSET(IPv6Header, PayloadLength),
  2612. IP_PROTOCOL_NONE, FALSE);
  2613. }
  2614. return IP_PROTOCOL_NONE; // Drop packet.
  2615. }
  2616. RH = (IPv6RoutingHeader *) Packet->Data;
  2617. //
  2618. // Now get the entire routing header.
  2619. // Also align for the address array.
  2620. //
  2621. HeaderLength = (RH->HeaderExtLength + 1) * EXT_LEN_UNIT;
  2622. if (! PacketPullup(Packet, HeaderLength,
  2623. MAX(__builtin_alignof(IPv6RoutingHeader),
  2624. __builtin_alignof(IPv6Addr)), 0)) {
  2625. if (Packet->TotalSize < HeaderLength)
  2626. goto BadPayloadLength;
  2627. return IP_PROTOCOL_NONE; // Drop packet.
  2628. }
  2629. RH = (IPv6RoutingHeader *) Packet->Data;
  2630. //
  2631. // Remember offset to this header's NextHeader field.
  2632. //
  2633. Packet->NextHeaderPosition = Packet->Position +
  2634. FIELD_OFFSET(IPv6RoutingHeader, NextHeader);
  2635. //
  2636. // Move past the routing header.
  2637. // We need to do this now so subsequent ICMP error generation works.
  2638. //
  2639. AdjustPacketParams(Packet, HeaderLength);
  2640. //
  2641. // If SegmentsLeft is zero, we proceed directly to the next header.
  2642. // We must not check the Type value or HeaderLength.
  2643. //
  2644. SegmentsLeft = RH->SegmentsLeft;
  2645. if (SegmentsLeft == 0) {
  2646. //
  2647. // Return next header value.
  2648. //
  2649. return RH->NextHeader;
  2650. }
  2651. //
  2652. // If we do not recognize the Type value, generate an ICMP error.
  2653. //
  2654. if (RH->RoutingType != 0) {
  2655. ICMPv6SendError(Packet,
  2656. ICMPv6_PARAMETER_PROBLEM,
  2657. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2658. (GetPacketPositionFromPointer(Packet,
  2659. &RH->RoutingType) -
  2660. Packet->IPPosition),
  2661. RH->NextHeader, FALSE);
  2662. return IP_PROTOCOL_NONE; // No further processing of this packet.
  2663. }
  2664. //
  2665. // We must have an integral number of IPv6 addresses
  2666. // in the routing header.
  2667. //
  2668. if (RH->HeaderExtLength & 1) {
  2669. ICMPv6SendError(Packet,
  2670. ICMPv6_PARAMETER_PROBLEM,
  2671. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2672. (GetPacketPositionFromPointer(Packet,
  2673. &RH->HeaderExtLength) -
  2674. Packet->IPPosition),
  2675. RH->NextHeader, FALSE);
  2676. return IP_PROTOCOL_NONE; // No further processing of this packet.
  2677. }
  2678. NumAddresses = RH->HeaderExtLength / 2;
  2679. //
  2680. // Sanity check SegmentsLeft.
  2681. //
  2682. if (SegmentsLeft > NumAddresses) {
  2683. ICMPv6SendError(Packet,
  2684. ICMPv6_PARAMETER_PROBLEM,
  2685. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2686. (GetPacketPositionFromPointer(Packet,
  2687. &RH->SegmentsLeft) -
  2688. Packet->IPPosition),
  2689. RH->NextHeader, FALSE);
  2690. return IP_PROTOCOL_NONE; // No further processing of this packet.
  2691. }
  2692. //
  2693. // Sanity check the destination address.
  2694. // Packets carrying a Type 0 Routing Header must not
  2695. // be sent to a multicast destination.
  2696. //
  2697. if (IsMulticast(AlignAddr(&Packet->IP->Dest))) {
  2698. //
  2699. // Just drop the packet, no ICMP error in this case.
  2700. //
  2701. return IP_PROTOCOL_NONE; // No further processing of this packet.
  2702. }
  2703. i = NumAddresses - SegmentsLeft;
  2704. Addresses = AlignAddr((IPv6Addr UNALIGNED *) (RH + 1));
  2705. //
  2706. // Sanity check the new destination.
  2707. // RFC 2460 doesn't mention checking for an unspecified address,
  2708. // but I think it's a good idea. Similarly, for security reasons,
  2709. // we also check the scope of the destination. This allows
  2710. // applications to check the scope of the eventual destination address
  2711. // and know that the packet originated within that scope.
  2712. // RFC 2460 says to discard the packet without an ICMP error
  2713. // (at least when the new destination is multicast),
  2714. // but I think an ICMP error is helpful in this situation.
  2715. //
  2716. if (IsMulticast(&Addresses[i]) ||
  2717. IsUnspecified(&Addresses[i]) ||
  2718. (UnicastAddressScope(&Addresses[i]) <
  2719. UnicastAddressScope(AlignAddr(&Packet->IP->Dest)))) {
  2720. ICMPv6SendError(Packet,
  2721. ICMPv6_PARAMETER_PROBLEM,
  2722. ICMPv6_ERRONEOUS_HEADER_FIELD,
  2723. (GetPacketPositionFromPointer(Packet, (uchar *)
  2724. &Addresses[i]) -
  2725. Packet->IPPosition),
  2726. RH->NextHeader, FALSE);
  2727. return IP_PROTOCOL_NONE; // No further processing of this packet.
  2728. }
  2729. //
  2730. // Verify IPSec was performed.
  2731. //
  2732. if (InboundSecurityCheck(Packet, 0, 0, 0, Packet->NTEorIF->IF) != TRUE) {
  2733. //
  2734. // No policy was found or the policy indicated to drop the packet.
  2735. //
  2736. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  2737. "RoutingReceive: "
  2738. "IPSec lookup failed or policy was to drop\n"));
  2739. return IP_PROTOCOL_NONE; // Drop packet.
  2740. }
  2741. //
  2742. // Find a route to the new destination.
  2743. //
  2744. Status = RouteToDestination(&Addresses[i],
  2745. 0, Packet->NTEorIF,
  2746. RTD_FLAG_LOOSE, &RCE);
  2747. if (Status != IP_SUCCESS) {
  2748. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  2749. "RoutingReceive: "
  2750. "No route to destination for forwarding.\n"));
  2751. ICMPv6SendError(Packet,
  2752. ICMPv6_DESTINATION_UNREACHABLE,
  2753. ICMPv6_NO_ROUTE_TO_DESTINATION,
  2754. 0, RH->NextHeader, FALSE);
  2755. return IP_PROTOCOL_NONE;
  2756. }
  2757. //
  2758. // For security reasons, we prevent source routing
  2759. // in some situations. Check those now.
  2760. //
  2761. if (Packet->NTEorIF->IF->Flags & IF_FLAG_FORWARDS) {
  2762. //
  2763. // The interface is forwarding, so source-routing is allowed.
  2764. //
  2765. }
  2766. else if (Packet->NTEorIF->IF == RCE->NCE->IF) {
  2767. //
  2768. // Same-interface rule says source-routing is allowed,
  2769. // because the host is not acting as a conduit
  2770. // between two networks. See RFC 1122 section 3.3.5.
  2771. //
  2772. }
  2773. else if ((SegmentsLeft == 1) && RCE->NCE->IsLoopback) {
  2774. //
  2775. // The packet is locally destined, so source-routing is allowed.
  2776. // Mobile IPv6 uses the Routing Header in this way.
  2777. //
  2778. }
  2779. else {
  2780. //
  2781. // We can not allow this use of source-routing.
  2782. // Instead of reporting an error, we could
  2783. // redo RouteToDestination with RTD_FLAG_STRICT
  2784. // to constrain to the same interface.
  2785. // However, an ICMP error is more in keeping
  2786. // with the treatment of scoped source addresses,
  2787. // which can produce a destination-unreachable error.
  2788. //
  2789. ReleaseRCE(RCE);
  2790. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  2791. "RoutingReceive: Inappropriate route.\n"));
  2792. ICMPv6SendError(Packet,
  2793. ICMPv6_DESTINATION_UNREACHABLE,
  2794. ICMPv6_COMMUNICATION_PROHIBITED,
  2795. 0, RH->NextHeader, FALSE);
  2796. return IP_PROTOCOL_NONE;
  2797. }
  2798. //
  2799. // Find the Security Policy for this outbound traffic.
  2800. // The source address is the same but the destination address is the
  2801. // next hop from the routing header.
  2802. //
  2803. IPSecToDo = OutboundSPLookup(AlignAddr(&Packet->IP->Source),
  2804. &Addresses[i],
  2805. 0, 0, 0, RCE->NCE->IF, &Action);
  2806. if (IPSecToDo == NULL) {
  2807. //
  2808. // Check Action.
  2809. //
  2810. if (Action == LOOKUP_DROP) {
  2811. // Drop packet.
  2812. ReleaseRCE(RCE);
  2813. return IP_PROTOCOL_NONE;
  2814. } else {
  2815. if (Action == LOOKUP_IKE_NEG) {
  2816. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  2817. "RoutingReceive: IKE not supported yet.\n"));
  2818. ReleaseRCE(RCE);
  2819. return IP_PROTOCOL_NONE;
  2820. }
  2821. }
  2822. //
  2823. // With no IPSec to perform, IPv6Forward won't be changing the
  2824. // outgoing interface from what we currently think it will be.
  2825. // So we can use the exact size of its link-level header.
  2826. //
  2827. Offset = RCE->NCE->IF->LinkHeaderSize;
  2828. } else {
  2829. //
  2830. // Calculate the space needed for the IPSec headers.
  2831. //
  2832. IPSecBytes = IPSecBytesToInsert(IPSecToDo, &TunnelStart, NULL);
  2833. if (TunnelStart != 0) {
  2834. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  2835. "RoutingReceive: IPSec Tunnel mode only.\n"));
  2836. FreeIPSecToDo(IPSecToDo, IPSecToDo->BundleSize);
  2837. ReleaseRCE(RCE);
  2838. return IP_PROTOCOL_NONE;
  2839. }
  2840. //
  2841. // The IPSec code in IPv6Forward might change the outgoing
  2842. // interface from what we currently think it will be. Play it
  2843. // safe and leave the max amount of space for its link-level header.
  2844. //
  2845. Offset = MAX_LINK_HEADER_SIZE;
  2846. }
  2847. //
  2848. // The packet has passed all our checks.
  2849. // We can construct a revised packet for transmission.
  2850. // First we allocate a packet, buffer, and memory.
  2851. //
  2852. // NB: The original packet is read-only for us. Furthermore
  2853. // we can not keep a pointer to it beyond the return of this
  2854. // function. So we must copy the packet and then modify it.
  2855. //
  2856. // Packet->IP->PayloadLength might be zero with jumbograms.
  2857. Delta = Packet->Position - Packet->IPPosition;
  2858. PayloadLength = Packet->TotalSize + Delta - sizeof(IPv6Header);
  2859. MemLen = Offset + sizeof(IPv6Header) + PayloadLength + IPSecBytes;
  2860. NdisStatus = IPv6AllocatePacket(MemLen, &FwdPacket, &Mem);
  2861. if (NdisStatus != NDIS_STATUS_SUCCESS) {
  2862. if (IPSecToDo) {
  2863. FreeIPSecToDo(IPSecToDo, IPSecToDo->BundleSize);
  2864. }
  2865. ReleaseRCE(RCE);
  2866. return IP_PROTOCOL_NONE; // No further processing of this packet.
  2867. }
  2868. FwdIP = (IPv6Header UNALIGNED *)(Mem + Offset + IPSecBytes);
  2869. FwdRH = (IPv6RoutingHeader UNALIGNED *)
  2870. ((uchar *)FwdIP + Delta - HeaderLength);
  2871. FwdAddresses = (IPv6Addr UNALIGNED *) (FwdRH + 1);
  2872. //
  2873. // Now we copy from the original packet to the new packet.
  2874. //
  2875. CopyPacketToBuffer((uchar *)FwdIP, Packet,
  2876. sizeof(IPv6Header) + PayloadLength,
  2877. Packet->IPPosition);
  2878. //
  2879. // Fix up the new packet - put in the new destination address
  2880. // and decrement SegmentsLeft.
  2881. // NB: We pass the Reserved field through unmodified!
  2882. // This violates a strict reading of the spec,
  2883. // but Steve Deering has confirmed that this is his intent.
  2884. //
  2885. FwdDest = *AlignAddr(&FwdAddresses[i]);
  2886. *AlignAddr(&FwdAddresses[i]) = *AlignAddr(&FwdIP->Dest);
  2887. *AlignAddr(&FwdIP->Dest) = FwdDest;
  2888. FwdRH->SegmentsLeft--;
  2889. //
  2890. // Forward the packet. This decrements the Hop Limit and generates
  2891. // any applicable ICMP errors (Time Limit Exceeded, Destination
  2892. // Unreachable, Packet Too Big). Note that previous ICMP errors
  2893. // that we generated were based on the unmodified incoming packet,
  2894. // while from here on the ICMP errors are based on the new FwdPacket.
  2895. //
  2896. IPv6Forward(Packet->NTEorIF, FwdPacket, Offset + IPSecBytes, FwdIP,
  2897. PayloadLength, FALSE, // Don't Redirect.
  2898. IPSecToDo, RCE);
  2899. if (IPSecToDo) {
  2900. FreeIPSecToDo(IPSecToDo, IPSecToDo->BundleSize);
  2901. }
  2902. ReleaseRCE(RCE);
  2903. return IP_PROTOCOL_NONE; // No further processing of this packet.
  2904. }