Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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