Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3203 lines
92 KiB

  1. // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
  2. //
  3. // Copyright (c) 1998-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. // Generic support for running IPv6 over IPv4.
  14. //
  15. #include "oscfg.h"
  16. #include "ndis.h"
  17. #include "ip6imp.h"
  18. #include "ip6def.h"
  19. #include "llip6if.h"
  20. #include "tdi.h"
  21. #include "tdiinfo.h"
  22. #include "tdikrnl.h"
  23. #include "tdistat.h"
  24. #include "tunnel.h"
  25. #include "ntddtcp.h"
  26. #include "tcpinfo.h"
  27. #include "icmp.h"
  28. #include "neighbor.h"
  29. #include "route.h"
  30. #include "security.h"
  31. #include <stdio.h>
  32. #include "ntddip6.h"
  33. #include "icmp.h"
  34. //
  35. // Our globals are all in one structure.
  36. //
  37. TunnelGlobals Tunnel;
  38. //* TunnelSetAddressObjectInformation
  39. //
  40. // Set information on the TDI address object.
  41. //
  42. // Our caller should initialize the ID.toi_id, BufferSize, Buffer
  43. // fields of the SetInfo structure, but we initialize the rest.
  44. //
  45. NTSTATUS
  46. TunnelSetAddressObjectInformation(
  47. PFILE_OBJECT AO,
  48. PTCP_REQUEST_SET_INFORMATION_EX SetInfo,
  49. ULONG SetInfoSize)
  50. {
  51. IO_STATUS_BLOCK iosb;
  52. KEVENT event;
  53. NTSTATUS status;
  54. PIRP irp;
  55. PIO_STACK_LOCATION irpSp;
  56. //
  57. // Finish initialization of the request structure for this IOCTL.
  58. //
  59. SetInfo->ID.toi_entity.tei_entity = CL_TL_ENTITY;
  60. SetInfo->ID.toi_entity.tei_instance = 0;
  61. SetInfo->ID.toi_class = INFO_CLASS_PROTOCOL;
  62. SetInfo->ID.toi_type = INFO_TYPE_ADDRESS_OBJECT;
  63. //
  64. // Initialize the event that we use to wait.
  65. //
  66. KeInitializeEvent(&event, NotificationEvent, FALSE);
  67. //
  68. // Create and initialize the IRP for this operation.
  69. //
  70. irp = IoBuildDeviceIoControlRequest(IOCTL_TCP_SET_INFORMATION_EX,
  71. AO->DeviceObject,
  72. SetInfo,
  73. SetInfoSize,
  74. NULL, // output buffer
  75. 0, // output buffer length
  76. FALSE, // internal device control?
  77. &event,
  78. &iosb);
  79. if (irp == NULL)
  80. return STATUS_INSUFFICIENT_RESOURCES;
  81. iosb.Status = STATUS_UNSUCCESSFUL;
  82. iosb.Information = (ULONG)-1;
  83. irpSp = IoGetNextIrpStackLocation(irp);
  84. irpSp->FileObject = AO;
  85. //
  86. // Make the IOCTL, waiting for it to finish if necessary.
  87. //
  88. status = IoCallDriver(AO->DeviceObject, irp);
  89. if (status == STATUS_PENDING) {
  90. KeWaitForSingleObject(&event, Executive, KernelMode,
  91. FALSE, NULL);
  92. status = iosb.Status;
  93. }
  94. return status;
  95. }
  96. //* TunnelSetAddressObjectUCastIF
  97. //
  98. // Binds the TDI address object to a particular interface.
  99. //
  100. NTSTATUS
  101. TunnelSetAddressObjectUCastIF(PFILE_OBJECT AO, IPAddr Address)
  102. {
  103. PTCP_REQUEST_SET_INFORMATION_EX setInfo;
  104. union { // get correct alignment
  105. TCP_REQUEST_SET_INFORMATION_EX setInfo;
  106. char bytes[sizeof *setInfo - sizeof setInfo->Buffer + sizeof(IPAddr)];
  107. } buffer;
  108. setInfo = &buffer.setInfo;
  109. setInfo->ID.toi_id = AO_OPTION_IP_UCASTIF;
  110. setInfo->BufferSize = sizeof(IPAddr);
  111. * (IPAddr *) setInfo->Buffer = Address;
  112. return TunnelSetAddressObjectInformation(AO, setInfo, sizeof buffer);
  113. }
  114. //* TunnelSetAddressObjectTTL
  115. //
  116. // Set the unicast TTL on a TDI address object.
  117. // This sets the v4 header TTL that will be used
  118. // for unicast packets sent via this TDI address object.
  119. //
  120. NTSTATUS
  121. TunnelSetAddressObjectTTL(PFILE_OBJECT AO, uchar TTL)
  122. {
  123. TCP_REQUEST_SET_INFORMATION_EX setInfo;
  124. setInfo.ID.toi_id = AO_OPTION_TTL;
  125. setInfo.BufferSize = 1;
  126. setInfo.Buffer[0] = TTL;
  127. return TunnelSetAddressObjectInformation(AO, &setInfo, sizeof setInfo);
  128. }
  129. //* TunnelSetAddressObjectMCastTTL
  130. //
  131. // Set the multicast TTL on a TDI address object.
  132. // This sets the v4 header TTL that will be used
  133. // for multicast packets sent via this TDI address object.
  134. //
  135. NTSTATUS
  136. TunnelSetAddressObjectMCastTTL(PFILE_OBJECT AO, uchar TTL)
  137. {
  138. TCP_REQUEST_SET_INFORMATION_EX setInfo;
  139. setInfo.ID.toi_id = AO_OPTION_MCASTTTL;
  140. setInfo.BufferSize = 1;
  141. setInfo.Buffer[0] = TTL;
  142. return TunnelSetAddressObjectInformation(AO, &setInfo, sizeof setInfo);
  143. }
  144. //* TunnelSetAddressObjectMCastIF
  145. //
  146. // Set the multicast interface on a TDI address object.
  147. // This sets the v4 source address that will be used
  148. // for multicast packets sent via this TDI address object.
  149. //
  150. NTSTATUS
  151. TunnelSetAddressObjectMCastIF(PFILE_OBJECT AO, IPAddr Address)
  152. {
  153. PTCP_REQUEST_SET_INFORMATION_EX setInfo;
  154. UDPMCastIFReq *req;
  155. union { // get correct alignment
  156. TCP_REQUEST_SET_INFORMATION_EX setInfo;
  157. char bytes[sizeof *setInfo - sizeof setInfo->Buffer + sizeof *req];
  158. } buffer;
  159. setInfo = &buffer.setInfo;
  160. setInfo->ID.toi_id = AO_OPTION_MCASTIF;
  161. setInfo->BufferSize = sizeof *req;
  162. req = (UDPMCastIFReq *) setInfo->Buffer;
  163. req->umi_addr = Address;
  164. return TunnelSetAddressObjectInformation(AO, setInfo, sizeof buffer);
  165. }
  166. //* TunnelSetAddressObjectMCastLoop
  167. //
  168. // Controls multicast loopback on a TDI address object.
  169. // This controls whether looped-back multicast packets
  170. // can be received via this address object.
  171. // (IPv4 multicast loopback uses Winsock semantics, not BSD semantics.)
  172. //
  173. NTSTATUS
  174. TunnelSetAddressObjectMCastLoop(PFILE_OBJECT AO, int Loop)
  175. {
  176. TCP_REQUEST_SET_INFORMATION_EX setInfo;
  177. setInfo.ID.toi_id = AO_OPTION_MCASTLOOP;
  178. setInfo.BufferSize = 1;
  179. setInfo.Buffer[0] = (uchar)Loop;
  180. return TunnelSetAddressObjectInformation(AO, &setInfo, sizeof setInfo);
  181. }
  182. //* TunnelAddMulticastAddress
  183. //
  184. // Indicate to the v4 stack that we would like to receive
  185. // on a multicast address.
  186. //
  187. NTSTATUS
  188. TunnelAddMulticastAddress(
  189. PFILE_OBJECT AO,
  190. IPAddr IfAddress,
  191. IPAddr MCastAddress)
  192. {
  193. PTCP_REQUEST_SET_INFORMATION_EX setInfo;
  194. UDPMCastReq *req;
  195. union { // get correct alignment
  196. TCP_REQUEST_SET_INFORMATION_EX setInfo;
  197. char bytes[sizeof *setInfo - sizeof setInfo->Buffer + sizeof *req];
  198. } buffer;
  199. setInfo = &buffer.setInfo;
  200. setInfo->ID.toi_id = AO_OPTION_ADD_MCAST;
  201. setInfo->BufferSize = sizeof *req;
  202. req = (UDPMCastReq *) setInfo->Buffer;
  203. req->umr_if = IfAddress;
  204. req->umr_addr = MCastAddress;
  205. return TunnelSetAddressObjectInformation(AO, setInfo, sizeof buffer);
  206. }
  207. //* TunnelDelMulticastAddress
  208. //
  209. // Indicate to the v4 stack that we are no longer
  210. // interested in a multicast address.
  211. //
  212. NTSTATUS
  213. TunnelDelMulticastAddress(
  214. PFILE_OBJECT AO,
  215. IPAddr IfAddress,
  216. IPAddr MCastAddress)
  217. {
  218. PTCP_REQUEST_SET_INFORMATION_EX setInfo;
  219. UDPMCastReq *req;
  220. union { // get correct alignment
  221. TCP_REQUEST_SET_INFORMATION_EX setInfo;
  222. char bytes[sizeof *setInfo - sizeof setInfo->Buffer + sizeof *req];
  223. } buffer;
  224. setInfo = &buffer.setInfo;
  225. setInfo->ID.toi_id = AO_OPTION_DEL_MCAST;
  226. setInfo->BufferSize = sizeof *req;
  227. req = (UDPMCastReq *) setInfo->Buffer;
  228. req->umr_if = IfAddress;
  229. req->umr_addr = MCastAddress;
  230. return TunnelSetAddressObjectInformation(AO, setInfo, sizeof buffer);
  231. }
  232. //* TunnelGetAddressObjectInformation
  233. //
  234. // Get information from the TDI address object.
  235. //
  236. // Callable from thread context, not DPC context.
  237. //
  238. NTSTATUS
  239. TunnelGetAddressObjectInformation(
  240. PFILE_OBJECT AO,
  241. PTCP_REQUEST_QUERY_INFORMATION_EX GetInfo,
  242. ULONG GetInfoSize,
  243. PVOID Buffer,
  244. ULONG BufferSize)
  245. {
  246. IO_STATUS_BLOCK iosb;
  247. KEVENT event;
  248. NTSTATUS status;
  249. PIRP irp;
  250. PIO_STACK_LOCATION irpSp;
  251. //
  252. // Initialize the event that we use to wait.
  253. //
  254. KeInitializeEvent(&event, NotificationEvent, FALSE);
  255. //
  256. // Create and initialize the IRP for this operation.
  257. //
  258. irp = IoBuildDeviceIoControlRequest(IOCTL_TCP_QUERY_INFORMATION_EX,
  259. AO->DeviceObject,
  260. GetInfo,
  261. GetInfoSize,
  262. Buffer, // output buffer
  263. BufferSize, // output buffer length
  264. FALSE, // internal device control?
  265. &event,
  266. &iosb);
  267. if (irp == NULL)
  268. return STATUS_INSUFFICIENT_RESOURCES;
  269. iosb.Status = STATUS_UNSUCCESSFUL;
  270. iosb.Information = (ULONG)-1;
  271. irpSp = IoGetNextIrpStackLocation(irp);
  272. irpSp->FileObject = AO;
  273. //
  274. // Make the IOCTL, waiting for it to finish if necessary.
  275. //
  276. status = IoCallDriver(AO->DeviceObject, irp);
  277. if (status == STATUS_PENDING) {
  278. KeWaitForSingleObject(&event, Executive, KernelMode,
  279. FALSE, NULL);
  280. status = iosb.Status;
  281. }
  282. return status;
  283. }
  284. //* TunnelGetSourceAddress
  285. //
  286. // Finds the source address that the IPv4 stack
  287. // would use to send to the destination address.
  288. // Returns FALSE upon failure.
  289. //
  290. // Callable from thread context, not DPC context.
  291. //
  292. int
  293. TunnelGetSourceAddress(IPAddr Dest, IPAddr *Source)
  294. {
  295. PTCP_REQUEST_QUERY_INFORMATION_EX getInfo;
  296. IPAddr *req;
  297. union { // get correct alignment
  298. TCP_REQUEST_QUERY_INFORMATION_EX getInfo;
  299. char bytes[sizeof *getInfo - sizeof getInfo->Context + sizeof *req];
  300. } buffer;
  301. IPRouteEntry route;
  302. getInfo = &buffer.getInfo;
  303. getInfo->ID.toi_entity.tei_entity = CL_NL_ENTITY;
  304. getInfo->ID.toi_entity.tei_instance = 0;
  305. getInfo->ID.toi_class = INFO_CLASS_PROTOCOL;
  306. getInfo->ID.toi_type = INFO_TYPE_PROVIDER;
  307. getInfo->ID.toi_id = IP_GET_BEST_SOURCE;
  308. req = (IPAddr *) &getInfo->Context;
  309. *req = Dest;
  310. return (NT_SUCCESS(TunnelGetAddressObjectInformation(
  311. Tunnel.List.AOFile,
  312. getInfo, sizeof buffer,
  313. Source, sizeof *Source)) &&
  314. (*Source != INADDR_ANY));
  315. }
  316. //* TunnelOpenAddressObject
  317. //
  318. // Opens a raw IPv4 address object,
  319. // returning a handle (or NULL on error).
  320. //
  321. HANDLE
  322. TunnelOpenAddressObject(IPAddr Address, WCHAR *DeviceName)
  323. {
  324. UNICODE_STRING objectName;
  325. OBJECT_ATTRIBUTES objectAttributes;
  326. IO_STATUS_BLOCK iosb;
  327. PTRANSPORT_ADDRESS transportAddress;
  328. TA_IP_ADDRESS taIPAddress;
  329. union { // get correct alignment
  330. FILE_FULL_EA_INFORMATION ea;
  331. char bytes[sizeof(FILE_FULL_EA_INFORMATION) - 1 +
  332. TDI_TRANSPORT_ADDRESS_LENGTH + 1 +
  333. sizeof taIPAddress];
  334. } eaBuffer;
  335. PFILE_FULL_EA_INFORMATION ea = &eaBuffer.ea;
  336. HANDLE tdiHandle;
  337. NTSTATUS status;
  338. //
  339. // Initialize an IPv4 address.
  340. //
  341. taIPAddress.TAAddressCount = 1;
  342. taIPAddress.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
  343. taIPAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
  344. taIPAddress.Address[0].Address[0].sin_port = 0;
  345. taIPAddress.Address[0].Address[0].in_addr = Address;
  346. //
  347. // Initialize the extended-attributes information,
  348. // to indicate that we are opening an address object
  349. // with the specified IPv4 address.
  350. //
  351. ea->NextEntryOffset = 0;
  352. ea->Flags = 0;
  353. ea->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
  354. ea->EaValueLength = (USHORT)sizeof taIPAddress;
  355. RtlMoveMemory(ea->EaName, TdiTransportAddress, ea->EaNameLength + 1);
  356. transportAddress = (PTRANSPORT_ADDRESS)(&ea->EaName[ea->EaNameLength + 1]);
  357. RtlMoveMemory(transportAddress, &taIPAddress, sizeof taIPAddress);
  358. //
  359. // Open a raw IP address object.
  360. //
  361. RtlInitUnicodeString(&objectName, DeviceName);
  362. InitializeObjectAttributes(&objectAttributes,
  363. &objectName,
  364. OBJ_CASE_INSENSITIVE, // Attributes
  365. NULL, // RootDirectory
  366. NULL); // SecurityDescriptor
  367. status = ZwCreateFile(&tdiHandle,
  368. GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
  369. &objectAttributes,
  370. &iosb,
  371. NULL, // AllocationSize
  372. 0, // FileAttributes
  373. FILE_SHARE_READ | FILE_SHARE_WRITE,
  374. FILE_CREATE,
  375. 0, // CreateOptions
  376. ea,
  377. sizeof eaBuffer);
  378. if (!NT_SUCCESS(status))
  379. return NULL;
  380. return tdiHandle;
  381. }
  382. //* TunnelObjectAddRef
  383. //
  384. // Adds another reference to an existing file object.
  385. //
  386. // Callable from thread or DPC context.
  387. //
  388. void
  389. TunnelObjectAddRef(FILE_OBJECT *File)
  390. {
  391. NTSTATUS Status;
  392. Status = ObReferenceObjectByPointer(File,
  393. GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
  394. NULL, // object type
  395. KernelMode);
  396. ASSERT(NT_SUCCESS(Status));
  397. }
  398. //* TunnelObjectFromHandle
  399. //
  400. // Converts a handle to an object pointer.
  401. //
  402. FILE_OBJECT *
  403. TunnelObjectFromHandle(HANDLE Handle)
  404. {
  405. PVOID Object;
  406. NTSTATUS Status;
  407. Status = ObReferenceObjectByHandle(
  408. Handle,
  409. GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
  410. NULL, // object type
  411. KernelMode,
  412. &Object,
  413. NULL); // handle info
  414. ASSERT(NT_SUCCESS(Status));
  415. ASSERT(Object != NULL);
  416. return Object;
  417. }
  418. typedef struct TunnelOpenAddressContext {
  419. WORK_QUEUE_ITEM WQItem;
  420. IPAddr Addr;
  421. HANDLE AOHandle;
  422. FILE_OBJECT *AOFile;
  423. KEVENT Event;
  424. } TunnelOpenAddressContext;
  425. //* TunnelOpenAddressHelper
  426. //
  427. // Opens a tunnel address object.
  428. //
  429. // Callable from thread context, not DPC context.
  430. // Callable in kernel process context only.
  431. // Called with the tunnel mutex held.
  432. //
  433. void
  434. TunnelOpenAddressHelper(TunnelOpenAddressContext *oac)
  435. {
  436. oac->AOHandle = TunnelOpenAddressObject(oac->Addr,
  437. TUNNEL_DEVICE_NAME(IP_PROTOCOL_V6));
  438. if (oac->AOHandle != NULL)
  439. oac->AOFile = TunnelObjectFromHandle(oac->AOHandle);
  440. else
  441. oac->AOFile = NULL;
  442. }
  443. //* TunnelOpenAddressWorker
  444. //
  445. // Executes the open operations in a worker thread context.
  446. //
  447. void
  448. TunnelOpenAddressWorker(void *Context)
  449. {
  450. TunnelOpenAddressContext *oac =
  451. (TunnelOpenAddressContext *) Context;
  452. TunnelOpenAddressHelper(oac);
  453. KeSetEvent(&oac->Event, 0, FALSE);
  454. }
  455. //* TunnelOpenAddress
  456. //
  457. // Address objects must be opened in the kernel process context,
  458. // so they will not be tied to a particular user process.
  459. //
  460. // The main input is tc->SrcAddr, but also uses tc->DstAddr.
  461. // Initializes tc->AOHandle and tc->AOFile.
  462. // If there is an error opening the address object,
  463. // they are both initialized to NULL.
  464. //
  465. // Callable from thread context, not DPC context.
  466. //
  467. void
  468. TunnelOpenAddress(TunnelContext *tc)
  469. {
  470. TunnelOpenAddressContext oac;
  471. KIRQL OldIrql;
  472. NTSTATUS Status;
  473. oac.Addr = tc->SrcAddr;
  474. if (IoGetCurrentProcess() != Tunnel.KernelProcess) {
  475. //
  476. // We are in the wrong process context, so
  477. // punt this operation to a worker thread.
  478. // Initialize and queue the work item -
  479. // it will execute asynchronously.
  480. //
  481. ExInitializeWorkItem(&oac.WQItem, TunnelOpenAddressWorker, &oac);
  482. KeInitializeEvent(&oac.Event, SynchronizationEvent, FALSE);
  483. ExQueueWorkItem(&oac.WQItem, CriticalWorkQueue);
  484. //
  485. // Wait for the work item to finish.
  486. //
  487. (void) KeWaitForSingleObject(&oac.Event, UserRequest,
  488. KernelMode, FALSE, NULL);
  489. }
  490. else {
  491. //
  492. // It's safe for us to open the address object directly.
  493. //
  494. TunnelOpenAddressHelper(&oac);
  495. }
  496. if (oac.AOFile != NULL) {
  497. //
  498. // Tunnel.V4Device might be null if TunnelOpenV4 failed.
  499. // Which would be bizarre but conceivable.
  500. // It would mean we could send tunneled packets but not receive.
  501. //
  502. ASSERT((Tunnel.V4Device == NULL) ||
  503. (oac.AOFile->DeviceObject == Tunnel.V4Device));
  504. //
  505. // Finish initializing the new address object.
  506. //
  507. Status = TunnelSetAddressObjectUCastIF(oac.AOFile, oac.Addr);
  508. if (! NT_SUCCESS(Status)) {
  509. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  510. "TunnelOpenAddress(%s): "
  511. "TunnelSetAddressObjectUCastIF -> %x\n",
  512. FormatV4Address(oac.Addr), Status));
  513. }
  514. //
  515. // For 6over4 interfaces, set additional options.
  516. //
  517. if (tc->DstAddr == INADDR_ANY) {
  518. Status = TunnelSetAddressObjectTTL(oac.AOFile,
  519. TUNNEL_6OVER4_TTL);
  520. if (! NT_SUCCESS(Status)) {
  521. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  522. "TunnelOpenAddress(%s): "
  523. "TunnelSetAddressObjectTTL -> %x\n",
  524. FormatV4Address(oac.Addr), Status));
  525. }
  526. Status = TunnelSetAddressObjectMCastTTL(oac.AOFile,
  527. TUNNEL_6OVER4_TTL);
  528. if (! NT_SUCCESS(Status)) {
  529. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  530. "TunnelOpenAddress(%s): "
  531. "TunnelSetAddressObjectMCastTTL -> %x\n",
  532. FormatV4Address(oac.Addr), Status));
  533. }
  534. Status = TunnelSetAddressObjectMCastIF(oac.AOFile, oac.Addr);
  535. if (! NT_SUCCESS(Status)) {
  536. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  537. "TunnelOpenAddress(%s): "
  538. "TunnelSetAddressObjectMCastIF -> %x\n",
  539. FormatV4Address(oac.Addr), Status));
  540. }
  541. }
  542. }
  543. //
  544. // Now that the address object is initialized,
  545. // we can update the tunnel context.
  546. // We need both the mutex and spinlock for update.
  547. // NB: In some paths, the tunnel context is not yet
  548. // on a list and so the locks are not needed.
  549. //
  550. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  551. tc->AOHandle = oac.AOHandle;
  552. tc->AOFile = oac.AOFile;
  553. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  554. }
  555. typedef struct TunnelCloseAddressObjectContext {
  556. WORK_QUEUE_ITEM WQItem;
  557. HANDLE Handle;
  558. KEVENT Event;
  559. } TunnelCloseAddressObjectContext;
  560. //* TunnelCloseAddressObjectWorker
  561. //
  562. // Executes the close operation in a worker thread context.
  563. //
  564. void
  565. TunnelCloseAddressObjectWorker(void *Context)
  566. {
  567. TunnelCloseAddressObjectContext *chc =
  568. (TunnelCloseAddressObjectContext *) Context;
  569. ZwClose(chc->Handle);
  570. KeSetEvent(&chc->Event, 0, FALSE);
  571. }
  572. //* TunnelCloseAddressObject
  573. //
  574. // Because the address object handles are opened in the kernel process
  575. // context, we must always close them in the kernel process context.
  576. //
  577. // Callable from thread context, not DPC context.
  578. //
  579. void
  580. TunnelCloseAddressObject(HANDLE Handle)
  581. {
  582. if (IoGetCurrentProcess() != Tunnel.KernelProcess) {
  583. TunnelCloseAddressObjectContext chc;
  584. //
  585. // We are in the wrong process context, so
  586. // punt this operation to a worker thread.
  587. //
  588. //
  589. // Initialize and queue the work item -
  590. // it will execute asynchronously.
  591. //
  592. ExInitializeWorkItem(&chc.WQItem,
  593. TunnelCloseAddressObjectWorker, &chc);
  594. chc.Handle = Handle;
  595. KeInitializeEvent(&chc.Event, SynchronizationEvent, FALSE);
  596. ExQueueWorkItem(&chc.WQItem, CriticalWorkQueue);
  597. //
  598. // Wait for the work item to finish.
  599. //
  600. (void) KeWaitForSingleObject(&chc.Event, UserRequest,
  601. KernelMode, FALSE, NULL);
  602. }
  603. else {
  604. //
  605. // It's safe for us to close the handle directly.
  606. //
  607. ZwClose(Handle);
  608. }
  609. }
  610. //* TunnelInsertTunnel
  611. //
  612. // Insert a tunnel on the global list.
  613. // Called with both tunnel locks held.
  614. //
  615. void
  616. TunnelInsertTunnel(TunnelContext *tc, TunnelContext *List)
  617. {
  618. tc->Next = List->Next;
  619. tc->Prev = List;
  620. List->Next->Prev = tc;
  621. List->Next = tc;
  622. }
  623. //* TunnelRemoveTunnel
  624. //
  625. // Remove a tunnel from the global list.
  626. // Called with both tunnel locks held.
  627. //
  628. void
  629. TunnelRemoveTunnel(TunnelContext *tc)
  630. {
  631. tc->Next->Prev = tc->Prev;
  632. tc->Prev->Next = tc->Next;
  633. }
  634. //
  635. // Context information that we pass to the IPv4 stack
  636. // when transmitting.
  637. //
  638. typedef struct TunnelTransmitContext {
  639. PNDIS_PACKET Packet;
  640. TA_IP_ADDRESS taIPAddress;
  641. TDI_CONNECTION_INFORMATION tdiConnInfo;
  642. } TunnelTransmitContext;
  643. //* TunnelTransmitComplete
  644. //
  645. // Completion function for TunnelTransmit,
  646. // called when the IPv4 stack completes our IRP.
  647. //
  648. NTSTATUS
  649. TunnelTransmitComplete(
  650. PDEVICE_OBJECT DeviceObject,
  651. PIRP Irp,
  652. PVOID Context)
  653. {
  654. TunnelTransmitContext *ttc = (TunnelTransmitContext *) Context;
  655. PNDIS_PACKET Packet = ttc->Packet;
  656. TDI_STATUS TDIStatus = Irp->IoStatus.Status;
  657. IP_STATUS IPStatus;
  658. uchar ICMPCode;
  659. //
  660. // Free the state that we allocated in TunnelTransmit.
  661. //
  662. ExFreePool(ttc);
  663. IoFreeIrp(Irp);
  664. //
  665. // Undo our adjustment before letting upper-layer code
  666. // see the packet.
  667. //
  668. UndoAdjustPacketBuffer(Packet);
  669. //
  670. // Convert the error code.
  671. // For some errors, we send an ICMPv6 message so that the error
  672. // can be forwarded. For most errors we just complete the packet.
  673. //
  674. switch (TDIStatus) {
  675. case TDI_SUCCESS:
  676. IPStatus = IP_SUCCESS;
  677. goto CallSendComplete;
  678. case TDI_BUFFER_TOO_BIG:
  679. //
  680. // TODO: It would be preferable to generate an ICMPv6 Packet Too Big,
  681. // but TDI does not give us the MTU value. This needs to be solved
  682. // before we can set the dont-fragment bit and do PMTU discovery.
  683. //
  684. IPStatus = IP_PACKET_TOO_BIG;
  685. goto CallSendComplete;
  686. default:
  687. IPStatus = IP_GENERAL_FAILURE;
  688. CallSendComplete:
  689. //
  690. // Let IPv6 know that the send completed.
  691. //
  692. IPv6SendComplete(PC(Packet)->IF, Packet, IPStatus);
  693. break;
  694. case TDI_DEST_NET_UNREACH:
  695. case TDI_DEST_HOST_UNREACH:
  696. case TDI_DEST_PROT_UNREACH:
  697. case TDI_DEST_PORT_UNREACH:
  698. //
  699. // Generate an ICMPv6 error.
  700. // Because this is a link-specific error,
  701. // we use address-unreachable.
  702. // NB: At the moment, the IPv4 stack does
  703. // not return these errors to us.
  704. // This will call IPv6SendComplete for us.
  705. //
  706. IPv6SendAbort(CastFromIF(PC(Packet)->IF),
  707. Packet,
  708. PC(Packet)->pc_offset,
  709. ICMPv6_DESTINATION_UNREACHABLE,
  710. ICMPv6_ADDRESS_UNREACHABLE,
  711. 0, FALSE);
  712. break;
  713. }
  714. //
  715. // Tell IoCompleteRequest to stop working on the IRP.
  716. //
  717. return STATUS_MORE_PROCESSING_REQUIRED;
  718. }
  719. //* TunnelTransmitViaAO
  720. //
  721. // Encapsulate a v6 packet in a v4 packet and send it
  722. // to the specified v4 address, using the specified
  723. // TDI address object. The address object may be bound
  724. // to a v4 address, or else the v4 stack chooses
  725. // the v4 source address.
  726. //
  727. // Callable from thread or DPC context.
  728. //
  729. void
  730. TunnelTransmitViaAO(
  731. FILE_OBJECT *File, // Pointer to TDI address object.
  732. PNDIS_PACKET Packet, // Pointer to packet to be transmitted.
  733. uint Offset, // Offset from start of packet to IPv6 header.
  734. IPAddr Address) // Link-layer (IPv4) destination address.
  735. {
  736. TunnelTransmitContext *ttc;
  737. PIRP irp;
  738. PMDL mdl;
  739. ULONG SendLen;
  740. //
  741. // We do not need any space for a link-layer header,
  742. // because the IPv4 code takes care of that transparently.
  743. //
  744. (void) AdjustPacketBuffer(Packet, Offset, 0);
  745. //
  746. // TdiBuildSendDatagram needs an MDL and the total amount
  747. // of data that the MDL represents.
  748. //
  749. NdisQueryPacket(Packet, NULL, NULL, &mdl, &SendLen);
  750. //
  751. // Allocate the context that we will pass to the IPv4 stack.
  752. //
  753. ttc = ExAllocatePool(NonPagedPool, sizeof *ttc);
  754. if (ttc == NULL) {
  755. ErrorReturn:
  756. UndoAdjustPacketBuffer(Packet);
  757. IPv6SendComplete(PC(Packet)->IF, Packet, IP_GENERAL_FAILURE);
  758. return;
  759. }
  760. //
  761. // Allocate an IRP that we will pass to the IPv4 stack.
  762. //
  763. irp = IoAllocateIrp(File->DeviceObject->StackSize, FALSE);
  764. if (irp == NULL) {
  765. ExFreePool(ttc);
  766. goto ErrorReturn;
  767. }
  768. //
  769. // Initialize the context information.
  770. // Note that many fields of the "connection info" are unused.
  771. //
  772. ttc->Packet = Packet;
  773. ttc->taIPAddress.TAAddressCount = 1;
  774. ttc->taIPAddress.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
  775. ttc->taIPAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
  776. ttc->taIPAddress.Address[0].Address[0].sin_port = 0;
  777. ttc->taIPAddress.Address[0].Address[0].in_addr = Address;
  778. ttc->tdiConnInfo.RemoteAddressLength = sizeof ttc->taIPAddress;
  779. ttc->tdiConnInfo.RemoteAddress = &ttc->taIPAddress;
  780. //
  781. // Initialize the IRP.
  782. //
  783. TdiBuildSendDatagram(irp,
  784. File->DeviceObject, File,
  785. TunnelTransmitComplete, ttc,
  786. mdl, SendLen, &ttc->tdiConnInfo);
  787. //
  788. // Pass the IRP to the IPv4 stack.
  789. // Note that unlike NDIS's asynchronous operations,
  790. // our completion routine will always be called,
  791. // no matter what the return code from IoCallDriver.
  792. //
  793. (void) IoCallDriver(File->DeviceObject, irp);
  794. }
  795. //* TunnelTransmitViaTC
  796. //
  797. // Extracts a file object reference from a tunnel context
  798. // and calls TunnelTransmitViaAO.
  799. //
  800. void
  801. TunnelTransmitViaTC(
  802. TunnelContext *tc,
  803. PNDIS_PACKET Packet, // Pointer to packet to be transmitted.
  804. uint Offset, // Offset from start of packet to IPv6 header.
  805. IPAddr Address) // Link-layer (IPv4) destination address.
  806. {
  807. Interface *IF = tc->IF;
  808. PFILE_OBJECT File;
  809. KIRQL OldIrql;
  810. //
  811. // Get a reference to the TDI address object.
  812. //
  813. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  814. File = tc->AOFile;
  815. if (File == NULL) {
  816. ASSERT(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED);
  817. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  818. IPv6SendComplete(IF, Packet, IP_GENERAL_FAILURE);
  819. return;
  820. }
  821. TunnelObjectAddRef(File);
  822. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  823. TunnelTransmitViaAO(File, Packet, Offset, Address);
  824. ObDereferenceObject(File);
  825. }
  826. //* TunnelSearchAOList
  827. //
  828. // Search the list of TDI address objects
  829. // for one bound to the specified v4 address.
  830. // If successful, the TDI address object
  831. // is returned with a reference for the caller.
  832. //
  833. // REVIEW: This design is inefficient on
  834. // machines with thousands of v4 addresses.
  835. //
  836. FILE_OBJECT *
  837. TunnelSearchAOList(IPAddr Addr)
  838. {
  839. FILE_OBJECT *File;
  840. TunnelContext *tc;
  841. KIRQL OldIrql;
  842. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  843. for (tc = Tunnel.AOList.Next; ; tc = tc->Next) {
  844. if (tc == &Tunnel.AOList) {
  845. File = NULL;
  846. break;
  847. }
  848. if (tc->SrcAddr == Addr) {
  849. File = tc->AOFile;
  850. TunnelObjectAddRef(File);
  851. break;
  852. }
  853. }
  854. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  855. return File;
  856. }
  857. //* TunnelTransmit
  858. //
  859. // Translates the arguments of our link-layer transmit function
  860. // to the internal TunnelTransmitViaTC/AO.
  861. //
  862. void
  863. TunnelTransmit(
  864. void *Context, // Pointer to tunnel interface.
  865. PNDIS_PACKET Packet, // Pointer to packet to be transmitted.
  866. uint Offset, // Offset from start of packet to IPv6 header.
  867. const void *LinkAddress) // Link-layer address.
  868. {
  869. TunnelContext *tc = (TunnelContext *) Context;
  870. IPAddr Address = * (IPAddr *) LinkAddress;
  871. //
  872. // Suppress packets sent to various illegal destination types.
  873. // REVIEW - It would be good to suppress subnet broadcasts,
  874. // but we don't know the v4 net mask.
  875. //
  876. if ((Address == INADDR_ANY) ||
  877. IsV4Broadcast(Address) ||
  878. IsV4Multicast(Address)) {
  879. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_USER_ERROR,
  880. "TunnelTransmit: illegal destination %s\n",
  881. FormatV4Address(Address)));
  882. IPv6SendAbort(CastFromIF(tc->IF), Packet, Offset,
  883. ICMPv6_DESTINATION_UNREACHABLE,
  884. ICMPv6_COMMUNICATION_PROHIBITED,
  885. 0,
  886. FALSE);
  887. return;
  888. }
  889. //
  890. // It would be nice to suppress transmission of packets
  891. // that will result in v4 loopback, but we don't have a
  892. // convenient way of doing that here. We could check
  893. // if Address == tc->SrcAddr, but that won't catch most cases.
  894. // Instead TunnelReceivePacket checks for this.
  895. //
  896. if (tc->IF->Type == IF_TYPE_TUNNEL_AUTO) {
  897. IPv6Header Buffer;
  898. IPv6Header UNALIGNED *IP;
  899. IPAddr DesiredSrc;
  900. FILE_OBJECT *File;
  901. //
  902. // tc->AOFile is not bound to a particular v4 address,
  903. // so the v4 stack can choose a source address.
  904. // But it might choose a source address that is not
  905. // consistent with the v6 source address.
  906. // To prevent this, we keep a stash of TDI address
  907. // objects bound to v4 addresses and when appropriate,
  908. // use a bound TDI address object.
  909. //
  910. IP = GetIPv6Header(Packet, Offset, &Buffer);
  911. if ((IP != NULL) &&
  912. (IsV4Compatible(AlignAddr(&IP->Source)) ||
  913. IsISATAP(AlignAddr(&IP->Source)))) {
  914. //
  915. // Search for a TDI address object bound to
  916. // the desired v4 source address.
  917. //
  918. DesiredSrc = ExtractV4Address(AlignAddr(&IP->Source));
  919. File = TunnelSearchAOList(DesiredSrc);
  920. if (File != NULL) {
  921. //
  922. // Encapsulate and transmit the packet,
  923. // using the desired v4 source address.
  924. //
  925. TunnelTransmitViaAO(File, Packet, Offset, Address);
  926. ObDereferenceObject(File);
  927. return;
  928. }
  929. }
  930. }
  931. //
  932. // Encapsulate and transmit the packet.
  933. //
  934. TunnelTransmitViaTC(tc, Packet, Offset, Address);
  935. }
  936. //* TunnelTransmitND
  937. //
  938. // Translates the arguments of our link-layer transmit function
  939. // to the internal TunnelTransmitViaTC.
  940. //
  941. // This is just like TunnelTransmit, except it doesn't have
  942. // the checks for bad destination addresses. 6over4 destination
  943. // addresses are handled via Neighbor Discovery and
  944. // multicast is needed.
  945. //
  946. void
  947. TunnelTransmitND(
  948. void *Context, // Pointer to tunnel interface.
  949. PNDIS_PACKET Packet, // Pointer to packet to be transmitted.
  950. uint Offset, // Offset from start of packet to IPv6 header.
  951. const void *LinkAddress) // Link-layer address.
  952. {
  953. TunnelContext *tc = (TunnelContext *) Context;
  954. IPAddr Address = * (IPAddr *) LinkAddress;
  955. //
  956. // Encapsulate and transmit the packet.
  957. //
  958. TunnelTransmitViaTC(tc, Packet, Offset, Address);
  959. }
  960. //* TunnelCreateReceiveIrp
  961. //
  962. // Creates an IRP for TunnelReceive/TunnelReceiveComplete.
  963. //
  964. PIRP
  965. TunnelCreateReceiveIrp(DEVICE_OBJECT *Device)
  966. {
  967. PIRP irp;
  968. PMDL mdl;
  969. void *buffer;
  970. irp = IoAllocateIrp(Device->StackSize, FALSE);
  971. if (irp == NULL)
  972. goto ErrorReturn;
  973. buffer = ExAllocatePool(NonPagedPool, TUNNEL_RECEIVE_BUFFER);
  974. if (buffer == NULL)
  975. goto ErrorReturnFreeIrp;
  976. mdl = IoAllocateMdl(buffer, TUNNEL_RECEIVE_BUFFER,
  977. FALSE, // This is the irp's primary MDL.
  978. FALSE, // Do not charge quota.
  979. irp);
  980. if (mdl == NULL)
  981. goto ErrorReturnFreeBuffer;
  982. MmBuildMdlForNonPagedPool(mdl);
  983. return irp;
  984. ErrorReturnFreeBuffer:
  985. ExFreePool(buffer);
  986. ErrorReturnFreeIrp:
  987. IoFreeIrp(irp);
  988. ErrorReturn:
  989. return NULL;
  990. }
  991. //* TunnelSelectTunnel
  992. //
  993. // Try to choose a tunnel on which to deliver a packet.
  994. //
  995. // Called with the tunnel lock held.
  996. //
  997. NetTableEntryOrInterface *
  998. TunnelSelectTunnel(
  999. IPv6Addr *V6Dest, // May be NULL.
  1000. IPAddr V4Dest,
  1001. IPAddr V4Src,
  1002. uint Flags)
  1003. {
  1004. TunnelContext *tc;
  1005. Interface *IF;
  1006. //
  1007. // First try to receive the packet on a point-to-point interface.
  1008. //
  1009. for (tc = Tunnel.List.Next;
  1010. tc != &Tunnel.List;
  1011. tc = tc->Next) {
  1012. IF = tc->IF;
  1013. //
  1014. // Restrict the point-to-point tunnel to only receiving
  1015. // packets that are sent from & to the proper link-layer
  1016. // addresses. That is, make it really point-to-point.
  1017. //
  1018. if (((IF->Flags & Flags) == Flags) &&
  1019. (IF->Type == IF_TYPE_TUNNEL_V6V4) &&
  1020. (V4Src == tc->DstAddr) &&
  1021. (V4Dest == tc->SrcAddr)) {
  1022. AddRefIF(IF);
  1023. return CastFromIF(IF);
  1024. }
  1025. }
  1026. //
  1027. // Next try to receive the packet on a 6-over-4 interface.
  1028. //
  1029. for (tc = Tunnel.List.Next;
  1030. tc != &Tunnel.List;
  1031. tc = tc->Next) {
  1032. IF = tc->IF;
  1033. //
  1034. // Restrict the 6-over-4 interface to only receiving
  1035. // packets that are sent to proper link-layer addresses.
  1036. // This is our v4 address and multicast addresses
  1037. // from TunnelConvertAddress.
  1038. //
  1039. if (((Flags == 0) || (IF->Flags & Flags)) &&
  1040. (IF->Type == IF_TYPE_TUNNEL_6OVER4) &&
  1041. ((V4Dest == tc->SrcAddr) ||
  1042. ((((uchar *)&V4Dest)[0] == 239) &&
  1043. (((uchar *)&V4Dest)[1] == 192)))) {
  1044. AddRefIF(IF);
  1045. return CastFromIF(IF);
  1046. }
  1047. }
  1048. //
  1049. // Finally, try to receive the packet on a tunnel pseudo-interface.
  1050. // This is a fall-back for forwarding situations
  1051. // or when V6Dest is NULL. In the latter case,
  1052. // we only consider automatic tunneling interfaces
  1053. // because they usually have link-local addresses.
  1054. //
  1055. for (tc = Tunnel.List.Next;
  1056. tc != &Tunnel.List;
  1057. tc = tc->Next) {
  1058. IF = tc->IF;
  1059. if (((Flags == 0) || (IF->Flags & Flags)) &&
  1060. ((IF->Type == IF_TYPE_TUNNEL_AUTO) ||
  1061. ((V6Dest != NULL) && (IF->Type == IF_TYPE_TUNNEL_6TO4)))) {
  1062. AddRefIF(IF);
  1063. return CastFromIF(IF);
  1064. }
  1065. }
  1066. return NULL;
  1067. }
  1068. //* TunnelFindReceiver
  1069. //
  1070. // Finds the NTEorIF that should receive an encapsulated packet.
  1071. // Returns the NTEorIF with a reference, or NULL.
  1072. // Called at DPC level.
  1073. //
  1074. NetTableEntryOrInterface *
  1075. TunnelFindReceiver(
  1076. IPv6Addr *V6Dest, // May be NULL.
  1077. IPAddr V4Dest,
  1078. IPAddr V4Src)
  1079. {
  1080. NetTableEntryOrInterface *NTEorIF;
  1081. TunnelContext *tc;
  1082. //
  1083. // So we can access the global list of tunnels.
  1084. //
  1085. KeAcquireSpinLockAtDpcLevel(&Tunnel.Lock);
  1086. if (V6Dest != NULL) {
  1087. //
  1088. // First try to receive the packet directly (not forwarding)
  1089. // on a tunnel pseudo-interface.
  1090. //
  1091. for (tc = Tunnel.List.Next;
  1092. tc != &Tunnel.List;
  1093. tc = tc->Next) {
  1094. Interface *IF = tc->IF;
  1095. if ((IF->Type == IF_TYPE_TUNNEL_AUTO) ||
  1096. (IF->Type == IF_TYPE_TUNNEL_6TO4)) {
  1097. ushort Type;
  1098. NTEorIF = FindAddressOnInterface(IF, V6Dest, &Type);
  1099. if (NTEorIF != NULL) {
  1100. if (Type != ADE_NONE)
  1101. goto UnlockAndReturn;
  1102. ReleaseIF(CastToIF(NTEorIF));
  1103. }
  1104. }
  1105. }
  1106. }
  1107. //
  1108. // Next try to receive the packet on a tunnel interface which
  1109. // is marked as forwarding.
  1110. //
  1111. NTEorIF = TunnelSelectTunnel(V6Dest, V4Dest, V4Src, IF_FLAG_FORWARDS);
  1112. if (NTEorIF != NULL)
  1113. goto UnlockAndReturn;
  1114. //
  1115. // Finally try to receive the packet on any matching tunnel interface.
  1116. //
  1117. NTEorIF = TunnelSelectTunnel(V6Dest, V4Dest, V4Src, 0);
  1118. UnlockAndReturn:
  1119. KeReleaseSpinLockFromDpcLevel(&Tunnel.Lock);
  1120. return NTEorIF;
  1121. }
  1122. //* TunnelReceiveIPv6Helper
  1123. //
  1124. // Called when we receive an encapsulated IPv6 packet,
  1125. // when we have identified the IPv6 header and found
  1126. // the NTEorIF that will receive the packet.
  1127. //
  1128. // Called at DPC level.
  1129. //
  1130. void
  1131. TunnelReceiveIPv6Helper(
  1132. IPHeader UNALIGNED *IPv4H,
  1133. IPv6Header UNALIGNED *IPv6H,
  1134. NetTableEntryOrInterface *NTEorIF,
  1135. void *Data,
  1136. uint Length)
  1137. {
  1138. IPv6Packet IPPacket;
  1139. uint Flags;
  1140. //
  1141. // Check if the packet was received as a link-layer multicast/broadcast.
  1142. //
  1143. if (IsV4Broadcast(IPv4H->iph_dest) ||
  1144. IsV4Multicast(IPv4H->iph_dest))
  1145. Flags = PACKET_NOT_LINK_UNICAST;
  1146. else
  1147. Flags = 0;
  1148. RtlZeroMemory(&IPPacket, sizeof IPPacket);
  1149. IPPacket.FlatData = Data;
  1150. IPPacket.Data = Data;
  1151. IPPacket.ContigSize = Length;
  1152. IPPacket.TotalSize = Length;
  1153. IPPacket.Flags = Flags;
  1154. IPPacket.NTEorIF = NTEorIF;
  1155. //
  1156. // We want to prevent any loopback in the v4 stack.
  1157. // Loopback should be handled in our v6 routing table.
  1158. // For example, we want to prevent loops where 6to4
  1159. // addresses are routed around and around and around.
  1160. // Without this code, the hop count would eventually
  1161. // catch the loop and report a strange ICMP error.
  1162. //
  1163. if (IPv4H->iph_dest == IPv4H->iph_src) {
  1164. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1165. "TunnelReceiveIPv6Helper: suppressed loopback\n"));
  1166. //
  1167. // Send an ICMP error. This requires some setup.
  1168. //
  1169. IPPacket.IP = IPv6H;
  1170. IPPacket.SrcAddr = AlignAddr(&IPv6H->Source);
  1171. IPPacket.IPPosition = IPPacket.Position;
  1172. AdjustPacketParams(&IPPacket, sizeof(IPv6Header));
  1173. ICMPv6SendError(&IPPacket,
  1174. ICMPv6_DESTINATION_UNREACHABLE,
  1175. ICMPv6_NO_ROUTE_TO_DESTINATION,
  1176. 0, IPv6H->NextHeader, FALSE);
  1177. }
  1178. else {
  1179. int PktRefs;
  1180. PktRefs = IPv6Receive(&IPPacket);
  1181. ASSERT(PktRefs == 0);
  1182. }
  1183. }
  1184. //* TunnelReceiveIPv6
  1185. //
  1186. // Called when we receive an encapsulated IPv6 packet.
  1187. // Called at DPC level.
  1188. //
  1189. // We select a single tunnel interface to receive the packet.
  1190. // It's difficult to select the correct interface in all situations.
  1191. //
  1192. void
  1193. TunnelReceiveIPv6(
  1194. IPHeader UNALIGNED *IPv4H,
  1195. void *Data,
  1196. uint Length)
  1197. {
  1198. IPv6Header UNALIGNED *IPv6H;
  1199. NetTableEntryOrInterface *NTEorIF;
  1200. //
  1201. // If the packet does not contain a full IPv6 header,
  1202. // just ignore it. We need to look at the IPv6 header
  1203. // below to demultiplex the packet to the proper
  1204. // tunnel interface.
  1205. //
  1206. if (Length < sizeof *IPv6H) {
  1207. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1208. "TunnelReceiveIPv6: too small to contain IPv6 hdr\n"));
  1209. return;
  1210. }
  1211. IPv6H = (IPv6Header UNALIGNED *) Data;
  1212. //
  1213. // Find the NTEorIF that will receive the packet.
  1214. //
  1215. NTEorIF = TunnelFindReceiver(AlignAddr(&IPv6H->Dest),
  1216. IPv4H->iph_dest,
  1217. IPv4H->iph_src);
  1218. if (NTEorIF == NULL) {
  1219. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1220. "TunnelReceiveIPv6: no receiver\n"));
  1221. return;
  1222. }
  1223. TunnelReceiveIPv6Helper(IPv4H, IPv6H, NTEorIF, Data, Length);
  1224. if (IsNTE(NTEorIF))
  1225. ReleaseNTE(CastToNTE(NTEorIF));
  1226. else
  1227. ReleaseIF(CastToIF(NTEorIF));
  1228. }
  1229. //* TunnelFindPutativeSource
  1230. //
  1231. // Finds an address to use as the "source" of an error
  1232. // for completed echo requests.
  1233. // Returns FALSE if no address is available.
  1234. //
  1235. int
  1236. TunnelFindPutativeSource(
  1237. IPAddr V4Dest,
  1238. IPAddr V4Src,
  1239. IPv6Addr *Source,
  1240. uint *ScopeId)
  1241. {
  1242. NetTableEntryOrInterface *NTEorIF;
  1243. Interface *IF;
  1244. int rc;
  1245. //
  1246. // First find an interface that would receive
  1247. // a tunneled packet.
  1248. //
  1249. NTEorIF = TunnelFindReceiver(NULL, V4Dest, V4Src);
  1250. if (NTEorIF == NULL)
  1251. return FALSE;
  1252. IF = NTEorIF->IF;
  1253. //
  1254. // Then get a link-local address on the interface.
  1255. //
  1256. rc = GetLinkLocalAddress(IF, Source);
  1257. *ScopeId = IF->ZoneIndices[ADE_LINK_LOCAL];
  1258. if (IsNTE(NTEorIF))
  1259. ReleaseNTE(CastToNTE(NTEorIF));
  1260. else
  1261. ReleaseIF(IF);
  1262. return rc;
  1263. }
  1264. //* TunnelFindSourceAddress
  1265. //
  1266. // Finds a source address to use in a constructed ICMPv6 error,
  1267. // given the NTEorIF that is receiving the ICMPv6 error
  1268. // and the IPv6 destination of the error.
  1269. // Returns FALSE if no address is available.
  1270. //
  1271. int
  1272. TunnelFindSourceAddress(
  1273. NetTableEntryOrInterface *NTEorIF,
  1274. IPv6Addr *V6Dest,
  1275. IPv6Addr *V6Src)
  1276. {
  1277. RouteCacheEntry *RCE;
  1278. IP_STATUS Status;
  1279. //
  1280. // REVIEW: In the MIPV6 code base, eliminate this check.
  1281. //
  1282. if (IsNTE(NTEorIF)) {
  1283. *V6Src = CastToNTE(NTEorIF)->Address;
  1284. return TRUE;
  1285. }
  1286. Status = RouteToDestination(V6Dest, 0, NTEorIF, RTD_FLAG_NORMAL, &RCE);
  1287. if (Status != IP_SUCCESS)
  1288. return FALSE;
  1289. *V6Src = RCE->NTE->Address;
  1290. ReleaseRCE(RCE);
  1291. return TRUE;
  1292. }
  1293. //* TunnelReceiveICMPv4
  1294. //
  1295. // Called when we receive an ICMPv4 packet.
  1296. // Called at DPC level.
  1297. //
  1298. // If an encapsulated IPv6 packet triggered
  1299. // this ICMPv4 error, then we construct an ICMPv6 error
  1300. // based on the ICMPv4 error and process the constructed packet.
  1301. //
  1302. void
  1303. TunnelReceiveICMPv4(
  1304. IPHeader UNALIGNED *IPv4H,
  1305. void *Data,
  1306. uint Length)
  1307. {
  1308. ICMPHeader UNALIGNED *ICMPv4H;
  1309. IPHeader UNALIGNED *ErrorIPv4H;
  1310. uint ErrorHeaderLength;
  1311. IPv6Header UNALIGNED *ErrorIPv6H;
  1312. void *NewData;
  1313. uint NewLength;
  1314. uint NewPayloadLength;
  1315. IPv6Header *NewIPv6H;
  1316. ICMPv6Header *NewICMPv6H;
  1317. uint *NewICMPv6Param;
  1318. void *NewErrorData;
  1319. IPv6Addr V6Src;
  1320. NetTableEntryOrInterface *NTEorIF;
  1321. //
  1322. // If the packet does not contain a full ICMPv4 header,
  1323. // just ignore it.
  1324. //
  1325. if (Length < sizeof *ICMPv4H) {
  1326. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1327. "TunnelReceiveICMPv4: too small to contain ICMPv4 hdr\n"));
  1328. return;
  1329. }
  1330. ICMPv4H = (ICMPHeader UNALIGNED *) Data;
  1331. Length -= sizeof *ICMPv4H;
  1332. (char *)Data += sizeof *ICMPv4H;
  1333. //
  1334. // Ignore everything but selected ICMP errors.
  1335. //
  1336. if ((ICMPv4H->ich_type != ICMP_DEST_UNREACH) &&
  1337. (ICMPv4H->ich_type != ICMP_SOURCE_QUENCH) &&
  1338. (ICMPv4H->ich_type != ICMP_TIME_EXCEED) &&
  1339. (ICMPv4H->ich_type != ICMP_PARAM_PROBLEM))
  1340. return;
  1341. //
  1342. // We need sufficient data from the error packet:
  1343. // at least the IPv4 header.
  1344. //
  1345. if (Length < sizeof *ErrorIPv4H) {
  1346. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1347. "TunnelReceiveICMPv4: "
  1348. "too small to contain error IPv4 hdr\n"));
  1349. return;
  1350. }
  1351. ErrorIPv4H = (IPHeader UNALIGNED *) Data;
  1352. ErrorHeaderLength = ((ErrorIPv4H->iph_verlen & 0xf) << 2);
  1353. if ((ErrorHeaderLength < sizeof *ErrorIPv4H) ||
  1354. (ErrorIPv4H->iph_length < ErrorHeaderLength)) {
  1355. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1356. "TunnelReceiveICMPv4: "
  1357. "error IPv4 hdr length too small\n"));
  1358. return;
  1359. }
  1360. //
  1361. // We are only interested if this error is in response
  1362. // to an IPv6-in-IPv4 packet.
  1363. //
  1364. if (ErrorIPv4H->iph_protocol != IP_PROTOCOL_V6)
  1365. return;
  1366. //
  1367. // Ignore the packet if the ICMPv4 checksum fails.
  1368. // We do this check after the cheaper checks above,
  1369. // when we know that we really want to process the error.
  1370. //
  1371. if (Cksum(ICMPv4H, sizeof *ICMPv4H + Length) != 0xffff) {
  1372. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1373. "TunnelReceiveICMPv4: bad checksum\n"));
  1374. return;
  1375. }
  1376. //
  1377. // Ensure that we do not look at garbage bytes
  1378. // at the end of the ICMP packet.
  1379. // We must adjust Length after checking the checksum.
  1380. //
  1381. if (ErrorIPv4H->iph_length < Length)
  1382. Length = ErrorIPv4H->iph_length;
  1383. //
  1384. // Ideally we also have the encapsulated IPv6 header.
  1385. // But often IPv4 routers will return insufficient information.
  1386. // In that case, we make a best effort to identify
  1387. // and complete any outstanding echo requests.
  1388. // Yes, this is a hack.
  1389. //
  1390. if (Length < ErrorHeaderLength + sizeof *ErrorIPv6H) {
  1391. uint ScopeId;
  1392. IP_STATUS Status;
  1393. if (! TunnelFindPutativeSource(IPv4H->iph_dest,
  1394. ErrorIPv4H->iph_dest,
  1395. &V6Src,
  1396. &ScopeId)) {
  1397. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  1398. "TunnelReceiveICMPv4: no putative source\n"));
  1399. return;
  1400. }
  1401. //
  1402. // The status code here should be the same as if
  1403. // we constructed an ICMPv6 error below and then
  1404. // converted to a status code in ICMPv6ErrorReceive.
  1405. //
  1406. if ((ICMPv4H->ich_type == ICMP_DEST_UNREACH) &&
  1407. (ICMPv4H->ich_code == ICMP_FRAG_NEEDED) &&
  1408. (net_long(ICMPv4H->ich_param) >=
  1409. ErrorHeaderLength + IPv6_MINIMUM_MTU))
  1410. Status = IP_PACKET_TOO_BIG;
  1411. else
  1412. Status = IP_DEST_ADDR_UNREACHABLE;
  1413. ICMPv6ProcessTunnelError(ErrorIPv4H->iph_dest,
  1414. &V6Src, ScopeId,
  1415. Status);
  1416. return;
  1417. }
  1418. //
  1419. // Move past the IPv4 header in the error data.
  1420. // Everything past this point, including the error IPv6 header,
  1421. // will become data in the constructed ICMPv6 error.
  1422. //
  1423. Length -= ErrorHeaderLength;
  1424. (char *)Data += ErrorHeaderLength;
  1425. ErrorIPv6H = (IPv6Header UNALIGNED *) Data;
  1426. //
  1427. // Determine who will receive the constructed ICMPv6 error.
  1428. //
  1429. NTEorIF = TunnelFindReceiver(AlignAddr(&ErrorIPv6H->Source),
  1430. IPv4H->iph_dest,
  1431. ErrorIPv4H->iph_dest);
  1432. if (NTEorIF == NULL) {
  1433. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  1434. "TunnelReceiveICMPv4: no receiver\n"));
  1435. return;
  1436. }
  1437. //
  1438. // Find a source address for the constructed ICMPv6 error.
  1439. //
  1440. if (! TunnelFindSourceAddress(NTEorIF, AlignAddr(&ErrorIPv6H->Source),
  1441. &V6Src)) {
  1442. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  1443. "TunnelReceiveICMPv4: no source address\n"));
  1444. goto ReleaseAndReturn;
  1445. }
  1446. //
  1447. // Allocate memory for the constructed ICMPv6 error.
  1448. //
  1449. NewPayloadLength = sizeof *NewICMPv6H + sizeof *NewICMPv6Param + Length;
  1450. NewLength = sizeof *NewIPv6H + NewPayloadLength;
  1451. NewData = ExAllocatePool(NonPagedPool, NewLength);
  1452. if (NewData == NULL) {
  1453. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1454. "TunnelReceiveICMPv4: no pool\n"));
  1455. goto ReleaseAndReturn;
  1456. }
  1457. //
  1458. // Build the IPv6 header.
  1459. //
  1460. NewIPv6H = (IPv6Header *) NewData;
  1461. NewIPv6H->VersClassFlow = IP_VERSION;
  1462. NewIPv6H->PayloadLength = net_short((ushort)NewPayloadLength);
  1463. NewIPv6H->NextHeader = IP_PROTOCOL_ICMPv6;
  1464. NewIPv6H->HopLimit = DEFAULT_CUR_HOP_LIMIT;
  1465. NewIPv6H->Source = V6Src;
  1466. NewIPv6H->Dest = ErrorIPv6H->Source;
  1467. //
  1468. // Build the ICMPv6 header.
  1469. //
  1470. NewICMPv6H = (ICMPv6Header *) (NewIPv6H + 1);
  1471. NewICMPv6Param = (uint *) (NewICMPv6H + 1);
  1472. if ((ICMPv4H->ich_type == ICMP_DEST_UNREACH) &&
  1473. (ICMPv4H->ich_code == ICMP_FRAG_NEEDED)) {
  1474. uint MTU;
  1475. //
  1476. // Calculate the MTU as seen by the IPv6 packet.
  1477. // The MTU can not be smaller than IPv6_MINIMUM_MTU.
  1478. // NB: In old-style frag-needed errors,
  1479. // ich_param should be zero.
  1480. // NB: Actually, this code should not be exercised since
  1481. // we do not set the dont-fragment bit in our IPv4 packets.
  1482. //
  1483. MTU = net_long(ICMPv4H->ich_param);
  1484. if (MTU < ErrorHeaderLength + IPv6_MINIMUM_MTU) {
  1485. //
  1486. // If we were setting the dont-fragment bit,
  1487. // we should clear it in this case.
  1488. // We need to allow the IPv4 layer to fragment.
  1489. //
  1490. goto GenerateAddressUnreachable;
  1491. }
  1492. MTU -= ErrorHeaderLength;
  1493. NewICMPv6H->Type = ICMPv6_PACKET_TOO_BIG;
  1494. NewICMPv6H->Code = 0;
  1495. *NewICMPv6Param = net_long(MTU);
  1496. }
  1497. else {
  1498. //
  1499. // For everything else, we use address-unreachable.
  1500. // It is the appropriate code for a link-specific error.
  1501. //
  1502. GenerateAddressUnreachable:
  1503. NewICMPv6H->Type = ICMPv6_DESTINATION_UNREACHABLE;
  1504. NewICMPv6H->Code = ICMPv6_ADDRESS_UNREACHABLE;
  1505. *NewICMPv6Param = 0;
  1506. }
  1507. //
  1508. // Copy the error data to the new packet.
  1509. //
  1510. NewErrorData = (void *) (NewICMPv6Param + 1);
  1511. RtlCopyMemory(NewErrorData, Data, Length);
  1512. //
  1513. // Calculate the ICMPv6 checksum.
  1514. //
  1515. NewICMPv6H->Checksum = 0;
  1516. NewICMPv6H->Checksum = ChecksumPacket(NULL, 0,
  1517. (uchar *)NewICMPv6H, NewPayloadLength,
  1518. &NewIPv6H->Source, &NewIPv6H->Dest,
  1519. IP_PROTOCOL_ICMPv6);
  1520. //
  1521. // Receive the constructed packet.
  1522. //
  1523. TunnelReceiveIPv6Helper(IPv4H, NewIPv6H, NTEorIF, NewData, NewLength);
  1524. ExFreePool(NewData);
  1525. ReleaseAndReturn:
  1526. if (IsNTE(NTEorIF))
  1527. ReleaseNTE(CastToNTE(NTEorIF));
  1528. else
  1529. ReleaseIF(CastToIF(NTEorIF));
  1530. }
  1531. //* TunnelReceivePacket
  1532. //
  1533. // Called when we receive an encapsulated IPv6 packet OR
  1534. // we receive an ICMPv4 packet.
  1535. // Called at DPC level.
  1536. //
  1537. // We select a single tunnel interface to receive the packet.
  1538. // It's difficult to select the correct interface in all situations.
  1539. //
  1540. void
  1541. TunnelReceivePacket(void *Data, uint Length)
  1542. {
  1543. IPHeader UNALIGNED *IPv4H;
  1544. uint HeaderLength;
  1545. //
  1546. // The incoming data includes the IPv4 header.
  1547. // We should only get properly-formed IPv4 packets.
  1548. //
  1549. ASSERT(Length >= sizeof *IPv4H);
  1550. IPv4H = (IPHeader UNALIGNED *) Data;
  1551. HeaderLength = ((IPv4H->iph_verlen & 0xf) << 2);
  1552. ASSERT(Length >= HeaderLength);
  1553. Length -= HeaderLength;
  1554. (char *)Data += HeaderLength;
  1555. if (IPv4H->iph_src == INADDR_ANY) {
  1556. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1557. "TunnelReceivePacket: null v4 source\n"));
  1558. return;
  1559. }
  1560. if (IPv4H->iph_protocol == IP_PROTOCOL_V6) {
  1561. //
  1562. // Process the encapsulated IPv6 packet.
  1563. //
  1564. TunnelReceiveIPv6(IPv4H, Data, Length);
  1565. }
  1566. else if (IPv4H->iph_protocol == IP_PROTOCOL_ICMPv4) {
  1567. //
  1568. // Process the ICMPv4 packet.
  1569. //
  1570. TunnelReceiveICMPv4(IPv4H, Data, Length);
  1571. }
  1572. else {
  1573. //
  1574. // We should not receive stray packets.
  1575. //
  1576. ASSERT(! "bad iph_protocol");
  1577. }
  1578. }
  1579. //* TunnelReceiveComplete
  1580. //
  1581. // Completion function for TunnelReceive,
  1582. // called when the IPv4 stack completes our IRP.
  1583. //
  1584. NTSTATUS
  1585. TunnelReceiveComplete(
  1586. PDEVICE_OBJECT DeviceObject,
  1587. PIRP Irp,
  1588. PVOID Context)
  1589. {
  1590. TDI_STATUS status = Irp->IoStatus.Status;
  1591. void *Data;
  1592. ULONG BytesRead;
  1593. ASSERT(Context == NULL);
  1594. if (status == TDI_SUCCESS) {
  1595. //
  1596. // The incoming data includes the IPv4 header.
  1597. // We should only get properly-formed IPv4 packets.
  1598. //
  1599. BytesRead = (ULONG)Irp->IoStatus.Information;
  1600. Data = Irp->MdlAddress->MappedSystemVa;
  1601. TunnelReceivePacket(Data, BytesRead);
  1602. }
  1603. //
  1604. // Put the IRP back so that TunnelReceive can use it again.
  1605. //
  1606. KeAcquireSpinLockAtDpcLevel(&Tunnel.Lock);
  1607. ASSERT(Tunnel.ReceiveIrp == NULL);
  1608. Tunnel.ReceiveIrp = Irp;
  1609. KeReleaseSpinLockFromDpcLevel(&Tunnel.Lock);
  1610. //
  1611. // Tell IoCompleteRequest to stop working on the IRP.
  1612. //
  1613. return STATUS_MORE_PROCESSING_REQUIRED;
  1614. }
  1615. //* TunnelReceive
  1616. //
  1617. // Called from the IPv4 protocol stack, when it receives
  1618. // an encapsulated v6 packet.
  1619. //
  1620. NTSTATUS
  1621. TunnelReceive(
  1622. IN PVOID TdiEventContext, // The event context
  1623. IN LONG SourceAddressLength, // Length of SourceAddress field.
  1624. IN PVOID SourceAddress, // Describes the datagram's originator.
  1625. IN LONG OptionsLength, // Length of Options field.
  1626. IN PVOID Options, // Options for the receive.
  1627. IN ULONG ReceiveDatagramFlags, //
  1628. IN ULONG BytesIndicated, // Number of bytes this indication.
  1629. IN ULONG BytesAvailable, // Number of bytes in complete Tsdu.
  1630. OUT ULONG *BytesTaken, // Number of bytes used.
  1631. IN PVOID Tsdu, // Pointer describing this TSDU,
  1632. // typically a lump of bytes
  1633. OUT PIRP *IoRequestPacket) // TdiReceive IRP if
  1634. // MORE_PROCESSING_REQUIRED.
  1635. {
  1636. PIRP irp;
  1637. ASSERT(TdiEventContext == NULL);
  1638. ASSERT(BytesIndicated <= BytesAvailable);
  1639. //
  1640. // If the packet is too large, refuse to receive it.
  1641. //
  1642. if (BytesAvailable > TUNNEL_RECEIVE_BUFFER) {
  1643. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1644. "TunnelReceive - too big %x\n", BytesAvailable));
  1645. *BytesTaken = BytesAvailable;
  1646. return STATUS_SUCCESS;
  1647. }
  1648. //
  1649. // Check if we already have the entire packet to work with.
  1650. // If so, we can directly call TunnelReceivePacket.
  1651. //
  1652. if (BytesIndicated == BytesAvailable) {
  1653. TunnelReceivePacket(Tsdu, BytesIndicated);
  1654. //
  1655. // Tell our caller that we took the data
  1656. // and that we are done.
  1657. //
  1658. *BytesTaken = BytesAvailable;
  1659. return STATUS_SUCCESS;
  1660. }
  1661. //
  1662. // We need an IRP to receive the entire packet.
  1663. // The IRP has a pre-allocated MDL.
  1664. //
  1665. // NB: We may get here before TunnelOpenV4 has
  1666. // finished initializing. In that case,
  1667. // we will not find an IRP.
  1668. //
  1669. KeAcquireSpinLockAtDpcLevel(&Tunnel.Lock);
  1670. irp = Tunnel.ReceiveIrp;
  1671. Tunnel.ReceiveIrp = NULL;
  1672. KeReleaseSpinLockFromDpcLevel(&Tunnel.Lock);
  1673. //
  1674. // If we don't have an IRP available to us,
  1675. // just drop the packet. This doesn't happen in practice.
  1676. //
  1677. if (irp == NULL) {
  1678. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  1679. "TunnelReceive - no irp\n"));
  1680. *BytesTaken = BytesAvailable;
  1681. return STATUS_SUCCESS;
  1682. }
  1683. //
  1684. // Build the receive datagram request.
  1685. //
  1686. TdiBuildReceiveDatagram(irp,
  1687. Tunnel.V4Device,
  1688. Tunnel.List.AOFile,
  1689. TunnelReceiveComplete,
  1690. NULL, // Context
  1691. irp->MdlAddress,
  1692. BytesAvailable,
  1693. &Tunnel.ReceiveInputInfo,
  1694. &Tunnel.ReceiveOutputInfo,
  1695. 0); // ReceiveFlags
  1696. //
  1697. // Make the next stack location current. Normally IoCallDriver would
  1698. // do this, but since we're bypassing that, we do it directly.
  1699. //
  1700. IoSetNextIrpStackLocation(irp);
  1701. //
  1702. // Return the irp to our caller.
  1703. //
  1704. *IoRequestPacket = irp;
  1705. *BytesTaken = 0;
  1706. return STATUS_MORE_PROCESSING_REQUIRED;
  1707. }
  1708. //* TunnelSetReceiveHandler
  1709. //
  1710. // Request notification of received IPv4 datagrams
  1711. // using the specified TDI address object.
  1712. //
  1713. NTSTATUS
  1714. TunnelSetReceiveHandler(
  1715. FILE_OBJECT *File, // TDI address object.
  1716. PVOID EventHandler) // Receive handler.
  1717. {
  1718. IO_STATUS_BLOCK iosb;
  1719. KEVENT event;
  1720. NTSTATUS status;
  1721. PIRP irp;
  1722. //
  1723. // Initialize the event that we use to wait.
  1724. //
  1725. KeInitializeEvent(&event, NotificationEvent, FALSE);
  1726. //
  1727. // Create and initialize the IRP for this operation.
  1728. //
  1729. irp = IoBuildDeviceIoControlRequest(0, // dummy ioctl
  1730. File->DeviceObject,
  1731. NULL, // input buffer
  1732. 0, // input buffer length
  1733. NULL, // output buffer
  1734. 0, // output buffer length
  1735. TRUE, // internal device control?
  1736. &event,
  1737. &iosb);
  1738. if (irp == NULL)
  1739. return STATUS_INSUFFICIENT_RESOURCES;
  1740. iosb.Status = STATUS_UNSUCCESSFUL;
  1741. iosb.Information = (ULONG)-1;
  1742. TdiBuildSetEventHandler(irp,
  1743. File->DeviceObject, File,
  1744. NULL, NULL, // comp routine/context
  1745. TDI_EVENT_RECEIVE_DATAGRAM,
  1746. EventHandler, NULL);
  1747. //
  1748. // Make the IOCTL, waiting for it to finish if necessary.
  1749. //
  1750. status = IoCallDriver(File->DeviceObject, irp);
  1751. if (status == STATUS_PENDING) {
  1752. KeWaitForSingleObject(&event, Executive, KernelMode,
  1753. FALSE, NULL);
  1754. status = iosb.Status;
  1755. }
  1756. return status;
  1757. }
  1758. //* TunnelCreateToken
  1759. //
  1760. // Given a link-layer address, creates a 64-bit "interface token"
  1761. // in the low eight bytes of an IPv6 address.
  1762. // Does not modify the other bytes in the IPv6 address.
  1763. //
  1764. void
  1765. TunnelCreateToken(
  1766. void *Context,
  1767. IPv6Addr *Address)
  1768. {
  1769. TunnelContext *tc = (TunnelContext *)Context;
  1770. uchar *IPAddress = (uchar *)&tc->TokenAddr;
  1771. //
  1772. // Embed the link's interface index in the interface identifier.
  1773. // This makes the interface identifier unique.
  1774. // Otherwise point-to-point tunnel and 6-over-4 links
  1775. // could have the same link-layer address,
  1776. // which is awkward.
  1777. //
  1778. *(ULONG UNALIGNED *)&Address->s6_bytes[8] = net_long(tc->IF->Index);
  1779. *(IPAddr UNALIGNED *)&Address->s6_bytes[12] = tc->TokenAddr;
  1780. }
  1781. //* TunnelCreateIsatapToken
  1782. //
  1783. // Given a link-layer address, creates a 64-bit "interface token"
  1784. // in the low eight bytes of an IPv6 address.
  1785. // Does not modify the other bytes in the IPv6 address.
  1786. //
  1787. void
  1788. TunnelCreateIsatapToken(
  1789. void *Context,
  1790. IPv6Addr *Address)
  1791. {
  1792. TunnelContext *tc = (TunnelContext *)Context;
  1793. ASSERT(tc->IF->Type == IF_TYPE_TUNNEL_AUTO);
  1794. Address->s6_words[4] = 0;
  1795. Address->s6_words[5] = 0xfe5e;
  1796. * (IPAddr UNALIGNED *) &Address->s6_words[6] = tc->TokenAddr;
  1797. }
  1798. //* TunnelReadLinkLayerAddressOption
  1799. //
  1800. // Parses a Neighbor Discovery link-layer address option
  1801. // and if valid, returns a pointer to the link-layer address.
  1802. //
  1803. const void *
  1804. TunnelReadLinkLayerAddressOption(
  1805. void *Context,
  1806. const uchar *OptionData)
  1807. {
  1808. //
  1809. // Check that the option length is correct.
  1810. //
  1811. if (OptionData[1] != 1)
  1812. return NULL;
  1813. //
  1814. // Check the must-be-zero padding bytes.
  1815. //
  1816. if ((OptionData[2] != 0) || (OptionData[3] != 0))
  1817. return NULL;
  1818. //
  1819. // Return a pointer to the embedded IPv4 address.
  1820. //
  1821. return OptionData + 4;
  1822. }
  1823. //* TunnelWriteLinkLayerAddressOption
  1824. //
  1825. // Creates a Neighbor Discovery link-layer address option.
  1826. // Our caller takes care of the option type & length fields.
  1827. // We handle the padding/alignment/placement of the link address
  1828. // into the option data.
  1829. //
  1830. // (Our caller allocates space for the option by adding 2 to the
  1831. // link address length and rounding up to a multiple of 8.)
  1832. //
  1833. void
  1834. TunnelWriteLinkLayerAddressOption(
  1835. void *Context,
  1836. uchar *OptionData,
  1837. const void *LinkAddress)
  1838. {
  1839. const uchar *IPAddress = (uchar *)LinkAddress;
  1840. //
  1841. // Place the address after the option type/length bytes
  1842. // and two bytes of zero padding.
  1843. //
  1844. OptionData[2] = 0;
  1845. OptionData[3] = 0;
  1846. OptionData[4] = IPAddress[0];
  1847. OptionData[5] = IPAddress[1];
  1848. OptionData[6] = IPAddress[2];
  1849. OptionData[7] = IPAddress[3];
  1850. }
  1851. //* TunnelConvertAddress
  1852. //
  1853. // Converts an IPv6 address to a link-layer address.
  1854. //
  1855. ushort
  1856. TunnelConvertAddress(
  1857. void *Context,
  1858. const IPv6Addr *Address,
  1859. void *LinkAddress)
  1860. {
  1861. TunnelContext *tc = (TunnelContext *)Context;
  1862. Interface *IF = tc->IF;
  1863. IPAddr UNALIGNED *IPAddress = (IPAddr UNALIGNED *)LinkAddress;
  1864. switch (IF->Type) {
  1865. case IF_TYPE_TUNNEL_AUTO:
  1866. if (IsV4Compatible(Address) || IsISATAP(Address)) {
  1867. //
  1868. // Extract the IPv4 address from the interface identifier.
  1869. //
  1870. *IPAddress = ExtractV4Address(Address);
  1871. return ND_STATE_PERMANENT;
  1872. }
  1873. else if ((tc->DstAddr != INADDR_ANY) &&
  1874. IP6_ADDR_EQUAL(Address, &AllRoutersOnLinkAddr)) {
  1875. //
  1876. // Return the IPv4 address from TunnelSetRouterLLAddress.
  1877. //
  1878. *IPAddress = tc->DstAddr;
  1879. return ND_STATE_PERMANENT;
  1880. }
  1881. else {
  1882. //
  1883. // We can't guess at the correct link-layer address.
  1884. // This value will cause IPv6SendND to drop the packet.
  1885. //
  1886. return ND_STATE_INCOMPLETE;
  1887. }
  1888. case IF_TYPE_TUNNEL_6TO4:
  1889. if (Is6to4(Address)) {
  1890. //
  1891. // Extract the IPv4 address from the prefix.
  1892. //
  1893. *IPAddress = Extract6to4Address(Address);
  1894. return ND_STATE_PERMANENT;
  1895. }
  1896. else {
  1897. //
  1898. // We can't guess at the correct link-layer address.
  1899. // This value will cause IPv6SendND to drop the packet.
  1900. //
  1901. return ND_STATE_INCOMPLETE;
  1902. }
  1903. case IF_TYPE_TUNNEL_6OVER4:
  1904. //
  1905. // This is a 6-over-4 link, which uses IPv4 multicast.
  1906. //
  1907. if (IsMulticast(Address)) {
  1908. uchar *IPAddressBytes = (uchar *)LinkAddress;
  1909. IPAddressBytes[0] = 239;
  1910. IPAddressBytes[1] = 192; // REVIEW: or 128 or 64??
  1911. IPAddressBytes[2] = Address->s6_bytes[14];
  1912. IPAddressBytes[3] = Address->s6_bytes[15];
  1913. return ND_STATE_PERMANENT;
  1914. }
  1915. else {
  1916. //
  1917. // Let Neighbor Discovery do its thing for unicast.
  1918. //
  1919. return ND_STATE_INCOMPLETE;
  1920. }
  1921. case IF_TYPE_TUNNEL_V6V4:
  1922. //
  1923. // This is a point-to-point tunnel, so write in
  1924. // the address of the other side of the tunnel.
  1925. //
  1926. *IPAddress = tc->DstAddr;
  1927. if (!(IF->Flags & IF_FLAG_NEIGHBOR_DISCOVERS) || IsMulticast(Address))
  1928. return ND_STATE_PERMANENT;
  1929. else
  1930. return ND_STATE_STALE;
  1931. default:
  1932. ASSERT(!"TunnelConvertAddress: bad IF type");
  1933. return ND_STATE_INCOMPLETE;
  1934. }
  1935. }
  1936. //* TunnelSetMulticastAddressList
  1937. //
  1938. // Takes an array of link-layer multicast addresses
  1939. // (from TunnelConvertAddress) from which we should
  1940. // receive packets. Passes them to the IPv4 stack.
  1941. //
  1942. // Callable from thread context, not DPC context.
  1943. //
  1944. NDIS_STATUS
  1945. TunnelSetMulticastAddressList(
  1946. void *Context,
  1947. const void *LinkAddresses,
  1948. uint NumKeep,
  1949. uint NumAdd,
  1950. uint NumDel)
  1951. {
  1952. TunnelContext *tc = (TunnelContext *)Context;
  1953. IPAddr *Addresses = (IPAddr *)LinkAddresses;
  1954. NTSTATUS Status;
  1955. uint i;
  1956. //
  1957. // We only do something for 6-over-4 links.
  1958. //
  1959. ASSERT(tc->IF->Type == IF_TYPE_TUNNEL_6OVER4);
  1960. //
  1961. // The IPv6 layer serializes calls to TunnelSetMulticastAddressList
  1962. // and TunnelResetMulticastAddressListDone, so we can safely check
  1963. // SetMCListOK to handle races with TunnelOpenV4.
  1964. //
  1965. if (tc->SetMCListOK) {
  1966. //
  1967. // We add the multicast addresses to Tunnel.List.AOFile,
  1968. // instead of tc->AOFile, because we are only receiving
  1969. // from the first address object.
  1970. //
  1971. for (i = 0; i < NumAdd; i++) {
  1972. Status = TunnelAddMulticastAddress(
  1973. Tunnel.List.AOFile,
  1974. tc->SrcAddr,
  1975. Addresses[NumKeep + i]);
  1976. if (! NT_SUCCESS(Status))
  1977. goto Return;
  1978. }
  1979. for (i = 0; i < NumDel; i++) {
  1980. Status = TunnelDelMulticastAddress(
  1981. Tunnel.List.AOFile,
  1982. tc->SrcAddr,
  1983. Addresses[NumKeep + NumAdd + i]);
  1984. if (! NT_SUCCESS(Status))
  1985. goto Return;
  1986. }
  1987. }
  1988. Status = STATUS_SUCCESS;
  1989. Return:
  1990. return (NDIS_STATUS) Status;
  1991. }
  1992. //* TunnelResetMulticastAddressListDone
  1993. //
  1994. // Indicates that RestartLinkLayerMulticast has finished,
  1995. // and subsequent calls to TunnelSetMulticastAddressList
  1996. // will inform us of the link-layer multicast addresses.
  1997. //
  1998. // Callable from thread context, not DPC context.
  1999. //
  2000. void
  2001. TunnelResetMulticastAddressListDone(void *Context)
  2002. {
  2003. TunnelContext *tc = (TunnelContext *)Context;
  2004. tc->SetMCListOK = TRUE;
  2005. }
  2006. //* TunnelClose
  2007. //
  2008. // Shuts down a tunnel.
  2009. //
  2010. // Callable from thread context, not DPC context.
  2011. //
  2012. void
  2013. TunnelClose(void *Context)
  2014. {
  2015. TunnelContext *tc = (TunnelContext *)Context;
  2016. KIRQL OldIrql;
  2017. //
  2018. // Remove the tunnel from our data structures.
  2019. //
  2020. KeWaitForSingleObject(&Tunnel.Mutex, Executive, KernelMode, FALSE, NULL);
  2021. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  2022. TunnelRemoveTunnel(tc);
  2023. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  2024. KeReleaseMutex(&Tunnel.Mutex, FALSE);
  2025. ReleaseIF(tc->IF);
  2026. }
  2027. //* TunnelCleanup
  2028. //
  2029. // Performs final cleanup of the tunnel context.
  2030. //
  2031. void
  2032. TunnelCleanup(void *Context)
  2033. {
  2034. TunnelContext *tc = (TunnelContext *)Context;
  2035. if (tc->AOHandle == NULL) {
  2036. //
  2037. // No references to release.
  2038. //
  2039. ASSERT(tc->AOFile == NULL);
  2040. }
  2041. else if (tc->AOHandle == Tunnel.List.AOHandle) {
  2042. //
  2043. // No references to release.
  2044. //
  2045. ASSERT(tc->AOFile == Tunnel.List.AOFile);
  2046. }
  2047. else {
  2048. ObDereferenceObject(tc->AOFile);
  2049. TunnelCloseAddressObject(tc->AOHandle);
  2050. }
  2051. ExFreePool(tc);
  2052. }
  2053. //* TunnelSetRouterLLAddress
  2054. //
  2055. // Sets the ISATAP router's IPv4 address.
  2056. //
  2057. NTSTATUS
  2058. TunnelSetRouterLLAddress(
  2059. void *Context,
  2060. const void *TokenLinkAddress,
  2061. const void *RouterLinkAddress)
  2062. {
  2063. TunnelContext *tc = (TunnelContext *) Context;
  2064. IPv6Addr LinkLocalAddress;
  2065. KIRQL OldIrql;
  2066. NetTableEntry *NTE;
  2067. Interface *IF = tc->IF;
  2068. ASSERT(IF->Type == IF_TYPE_TUNNEL_AUTO);
  2069. //
  2070. // We should not set/reset one without the other.
  2071. //
  2072. if ((*((IPAddr *) RouterLinkAddress) == INADDR_ANY) !=
  2073. (*((IPAddr *) TokenLinkAddress) == INADDR_ANY))
  2074. return STATUS_INVALID_PARAMETER;
  2075. RtlCopyMemory(&tc->DstAddr, RouterLinkAddress, sizeof(IPAddr));
  2076. RtlCopyMemory(&tc->TokenAddr, TokenLinkAddress, sizeof(IPAddr));
  2077. KeAcquireSpinLock(&IF->Lock, &OldIrql);
  2078. if (tc->DstAddr != INADDR_ANY) {
  2079. //
  2080. // Look for a link-local NTE matching the TokenAddr.
  2081. // If we find one, set the preferred link-local NTE to that one,
  2082. // so that the IPv6 source address of RS's will match the IPv4
  2083. // source address of the outer header.
  2084. //
  2085. LinkLocalAddress = LinkLocalPrefix;
  2086. TunnelCreateIsatapToken(Context, &LinkLocalAddress);
  2087. NTE = (NetTableEntry *) *FindADE(IF, &LinkLocalAddress);
  2088. if ((NTE != NULL) && (NTE->Type == ADE_UNICAST))
  2089. IF->LinkLocalNTE = NTE;
  2090. //
  2091. // Enable address auto-configuration.
  2092. //
  2093. IF->CreateToken = TunnelCreateIsatapToken;
  2094. //
  2095. // Enable Router Discovery.
  2096. //
  2097. IF->Flags |= IF_FLAG_ROUTER_DISCOVERS;
  2098. //
  2099. // Trigger a Router Solicitation.
  2100. //
  2101. if (!(IF->Flags & IF_FLAG_ADVERTISES)) {
  2102. IF->RSCount = 0;
  2103. IF->RSTimer = 1;
  2104. }
  2105. }
  2106. else {
  2107. //
  2108. // Disable address auto-configuration.
  2109. //
  2110. IF->CreateToken = NULL;
  2111. //
  2112. // Disable Router Discovery.
  2113. //
  2114. IF->Flags &= ~IF_FLAG_ROUTER_DISCOVERS;
  2115. //
  2116. // Stop sending Router Solicitations.
  2117. //
  2118. if (!(IF->Flags & IF_FLAG_ADVERTISES)) {
  2119. IF->RSTimer = 0;
  2120. }
  2121. }
  2122. //
  2123. // Remove addresses & routes that were auto-configured from
  2124. // Router Advertisements.
  2125. //
  2126. AddrConfResetAutoConfig(IF, 0);
  2127. RouteTableResetAutoConfig(IF, 0);
  2128. InterfaceResetAutoConfig(IF);
  2129. KeReleaseSpinLock(&IF->Lock, OldIrql);
  2130. return STATUS_SUCCESS;
  2131. }
  2132. //* TunnelCreatePseudoInterface
  2133. //
  2134. // Creates a pseudo-interface. Type can either be
  2135. // IF_TYPE_TUNNEL_AUTO (v4-compatible/ISATAP) or
  2136. // IF_TYPE_TUNNEL_6TO4 (6to4 tunneling).
  2137. //
  2138. // Callable from thread context, not DPC context.
  2139. //
  2140. // Return codes:
  2141. // STATUS_INSUFFICIENT_RESOURCES
  2142. // STATUS_UNSUCCESSFUL
  2143. // STATUS_SUCCESS
  2144. //
  2145. NTSTATUS
  2146. TunnelCreatePseudoInterface(const char *InterfaceName, uint Type)
  2147. {
  2148. GUID Guid;
  2149. LLIPBindInfo BindInfo;
  2150. TunnelContext *tc;
  2151. NTSTATUS Status;
  2152. KIRQL OldIrql;
  2153. ASSERT((Type == IF_TYPE_TUNNEL_AUTO) ||
  2154. (Type == IF_TYPE_TUNNEL_6TO4));
  2155. //
  2156. // Allocate memory for the TunnelContext.
  2157. //
  2158. tc = ExAllocatePool(NonPagedPool, sizeof *tc);
  2159. if (tc == NULL) {
  2160. Status = STATUS_INSUFFICIENT_RESOURCES;
  2161. goto ErrorReturn;
  2162. }
  2163. //
  2164. // Tunnel pseudo-interfaces need a dummy link-layer address.
  2165. // It must be distinct from any address assigned to other nodes,
  2166. // so that the loopback check in IPv6SendLL works.
  2167. //
  2168. tc->SrcAddr = INADDR_LOOPBACK;
  2169. tc->TokenAddr = INADDR_ANY;
  2170. tc->DstAddr = INADDR_ANY;
  2171. tc->SetMCListOK = FALSE;
  2172. //
  2173. // Prepare the binding info for CreateInterface.
  2174. //
  2175. BindInfo.lip_context = tc;
  2176. BindInfo.lip_maxmtu = TUNNEL_MAX_MTU;
  2177. BindInfo.lip_defmtu = TUNNEL_DEFAULT_MTU;
  2178. BindInfo.lip_flags = IF_FLAG_PSEUDO;
  2179. BindInfo.lip_type = Type;
  2180. BindInfo.lip_hdrsize = 0;
  2181. BindInfo.lip_addrlen = sizeof(IPAddr);
  2182. BindInfo.lip_addr = (uchar *) &tc->SrcAddr;
  2183. BindInfo.lip_dadxmit = 0;
  2184. BindInfo.lip_pref = TUNNEL_DEFAULT_PREFERENCE;
  2185. BindInfo.lip_token = NULL;
  2186. BindInfo.lip_rdllopt = NULL;
  2187. BindInfo.lip_wrllopt = NULL;
  2188. BindInfo.lip_cvaddr = TunnelConvertAddress;
  2189. if (Type == IF_TYPE_TUNNEL_AUTO)
  2190. BindInfo.lip_setrtrlladdr = TunnelSetRouterLLAddress;
  2191. else
  2192. BindInfo.lip_setrtrlladdr = NULL;
  2193. BindInfo.lip_transmit = TunnelTransmit;
  2194. BindInfo.lip_mclist = NULL;
  2195. BindInfo.lip_close = TunnelClose;
  2196. BindInfo.lip_cleanup = TunnelCleanup;
  2197. CreateGUIDFromName(InterfaceName, &Guid);
  2198. //
  2199. // Prevent races with TunnelClose by taking the mutex
  2200. // before calling CreateInterface.
  2201. //
  2202. KeWaitForSingleObject(&Tunnel.Mutex, Executive, KernelMode, FALSE, NULL);
  2203. if (Tunnel.List.AOHandle == NULL) {
  2204. //
  2205. // TunnelOpenV4 has not yet happened.
  2206. // Create the interface in the disconnected state.
  2207. //
  2208. tc->AOHandle = NULL;
  2209. tc->AOFile = NULL;
  2210. BindInfo.lip_flags |= IF_FLAG_MEDIA_DISCONNECTED;
  2211. }
  2212. else {
  2213. //
  2214. // No need to open a new address object.
  2215. // Just reuse the global Tunnel.List address object.
  2216. //
  2217. tc->AOHandle = Tunnel.List.AOHandle;
  2218. tc->AOFile = Tunnel.List.AOFile;
  2219. }
  2220. //
  2221. // Create the IPv6 interface.
  2222. // We can hold the mutex across this call, but not a spinlock.
  2223. //
  2224. Status = CreateInterface(&Guid, &BindInfo, (void **)&tc->IF);
  2225. if (! NT_SUCCESS(Status))
  2226. goto ErrorReturnUnlock;
  2227. //
  2228. // Once we unlock, the interface could be gone.
  2229. //
  2230. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  2231. TunnelInsertTunnel(tc, &Tunnel.List);
  2232. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  2233. KeReleaseMutex(&Tunnel.Mutex, FALSE);
  2234. return STATUS_SUCCESS;
  2235. ErrorReturnUnlock:
  2236. KeReleaseMutex(&Tunnel.Mutex, FALSE);
  2237. ExFreePool(tc);
  2238. ErrorReturn:
  2239. return Status;
  2240. }
  2241. //* TunnelOpenV4
  2242. //
  2243. // Establishes our connection to the IPv4 stack,
  2244. // so we can send and receive tunnelled packets.
  2245. //
  2246. // Called with the tunnel mutex held.
  2247. //
  2248. void
  2249. TunnelOpenV4(void)
  2250. {
  2251. HANDLE Handle, IcmpHandle;
  2252. FILE_OBJECT *File, *IcmpFile;
  2253. DEVICE_OBJECT *Device;
  2254. IRP *ReceiveIrp;
  2255. TunnelContext *tc;
  2256. KIRQL OldIrql;
  2257. NTSTATUS Status;
  2258. //
  2259. // We use a single address object to receive all tunnelled packets.
  2260. //
  2261. Handle = TunnelOpenAddressObject(INADDR_ANY,
  2262. TUNNEL_DEVICE_NAME(IP_PROTOCOL_V6));
  2263. if (Handle == NULL) {
  2264. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2265. "TunnelOpenV4: TunnelOpenAddressObject(%u) failed\n",
  2266. IP_PROTOCOL_V6));
  2267. return;
  2268. }
  2269. File = TunnelObjectFromHandle(Handle);
  2270. //
  2271. // We use a second address object to receive ICMPv4 packets.
  2272. //
  2273. IcmpHandle = TunnelOpenAddressObject(INADDR_ANY,
  2274. TUNNEL_DEVICE_NAME(IP_PROTOCOL_ICMPv4));
  2275. if (IcmpHandle == NULL) {
  2276. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2277. "TunnelOpenV4: TunnelOpenAddressObject(%u) failed\n",
  2278. IP_PROTOCOL_ICMPv4));
  2279. goto ReturnReleaseHandle;
  2280. }
  2281. IcmpFile = TunnelObjectFromHandle(IcmpHandle);
  2282. //
  2283. // Disable reception of multicast loopback packets.
  2284. //
  2285. Status = TunnelSetAddressObjectMCastLoop(File, FALSE);
  2286. if (! NT_SUCCESS(Status)) {
  2287. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2288. "TunnelOpenV4: "
  2289. "TunnelSetAddressObjectMCastLoop: %x\n", Status));
  2290. goto ReturnReleaseBothHandles;
  2291. }
  2292. //
  2293. // After TunnelSetReceiveHandler, we will start receiving
  2294. // encapsulated v6 packets. However they will be dropped
  2295. // until we finish our initialization here.
  2296. //
  2297. Status = TunnelSetReceiveHandler(File, TunnelReceive);
  2298. if (! NT_SUCCESS(Status)) {
  2299. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2300. "TunnelOpenV4: "
  2301. "TunnelSetReceiveHandler: %x\n", Status));
  2302. goto ReturnReleaseBothHandles;
  2303. }
  2304. Status = TunnelSetReceiveHandler(IcmpFile, TunnelReceive);
  2305. if (! NT_SUCCESS(Status)) {
  2306. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2307. "TunnelOpenV4: "
  2308. "TunnelSetReceiveHandler(2): %x\n", Status));
  2309. goto ReturnReleaseBothHandles;
  2310. }
  2311. Device = File->DeviceObject;
  2312. ASSERT(Device == IcmpFile->DeviceObject);
  2313. ReceiveIrp = TunnelCreateReceiveIrp(Device);
  2314. if (ReceiveIrp == NULL) {
  2315. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2316. "TunnelOpenV4: TunnelCreateReceiveIrp failed\n"));
  2317. ReturnReleaseBothHandles:
  2318. ObDereferenceObject(IcmpFile);
  2319. TunnelCloseAddressObject(IcmpHandle);
  2320. ReturnReleaseHandle:
  2321. ObDereferenceObject(File);
  2322. TunnelCloseAddressObject(Handle);
  2323. return;
  2324. }
  2325. //
  2326. // We have successfully opened a connection to the IPv4 stack.
  2327. // Update our data structures.
  2328. //
  2329. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  2330. Tunnel.List.AOHandle = Handle;
  2331. Tunnel.List.AOFile = File;
  2332. Tunnel.V4Device = Device;
  2333. Tunnel.ReceiveIrp = ReceiveIrp;
  2334. Tunnel.IcmpHandle = IcmpHandle;
  2335. Tunnel.IcmpFile = IcmpFile;
  2336. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  2337. //
  2338. // Now search our list of interfaces and transition
  2339. // pseudo-interfaces to the connected state.
  2340. //
  2341. for (tc = Tunnel.List.Next;
  2342. tc != &Tunnel.List;
  2343. tc = tc->Next) {
  2344. Interface *IF = tc->IF;
  2345. if ((IF->Type == IF_TYPE_TUNNEL_AUTO) ||
  2346. (IF->Type == IF_TYPE_TUNNEL_6TO4)) {
  2347. //
  2348. // The pseudo-interface contexts do not hold
  2349. // separate references for the main TDI address object.
  2350. //
  2351. ASSERT(tc->AOHandle == NULL);
  2352. ASSERT(tc->AOFile == NULL);
  2353. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  2354. tc->AOHandle = Handle;
  2355. tc->AOFile = File;
  2356. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  2357. SetInterfaceLinkStatus(IF, TRUE);
  2358. }
  2359. else if (IF->Type == IF_TYPE_TUNNEL_6OVER4) {
  2360. //
  2361. // We must start listening to multicast addresses
  2362. // for this 6over4 interface.
  2363. //
  2364. RestartLinkLayerMulticast(IF, TunnelResetMulticastAddressListDone);
  2365. }
  2366. }
  2367. }
  2368. //* TunnelAddAddress
  2369. //
  2370. // Called by TDI when a transport registers an address.
  2371. //
  2372. void
  2373. TunnelAddAddress(
  2374. TA_ADDRESS *Address,
  2375. UNICODE_STRING *DeviceName,
  2376. TDI_PNP_CONTEXT *Context)
  2377. {
  2378. if (Address->AddressType == TDI_ADDRESS_TYPE_IP) {
  2379. TDI_ADDRESS_IP *TdiAddr = (TDI_ADDRESS_IP *) Address->Address;
  2380. IPAddr V4Addr = TdiAddr->in_addr;
  2381. TunnelContext *tc;
  2382. KIRQL OldIrql;
  2383. KeWaitForSingleObject(&Tunnel.Mutex, Executive, KernelMode,
  2384. FALSE, NULL);
  2385. //
  2386. // First, open a connection to the IPv4 stack if needed.
  2387. //
  2388. if (Tunnel.List.AOHandle == NULL)
  2389. TunnelOpenV4();
  2390. //
  2391. // Next, search for disconnected interfaces that should be connected.
  2392. //
  2393. for (tc = Tunnel.List.Next;
  2394. tc != &Tunnel.List;
  2395. tc = tc->Next) {
  2396. if (tc->SrcAddr == V4Addr) {
  2397. Interface *IF = tc->IF;
  2398. if (tc->AOHandle == NULL) {
  2399. ASSERT(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED);
  2400. TunnelOpenAddress(tc);
  2401. //
  2402. // Did TunnelOpenAddress succeed?
  2403. // If not, leave the interface disconnected.
  2404. //
  2405. if (tc->AOHandle == NULL) {
  2406. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2407. "TunnelAddAddress(%s): "
  2408. "TunnelOpenAddress failed\n",
  2409. FormatV4Address(V4Addr)));
  2410. }
  2411. else {
  2412. //
  2413. // Connect the interface.
  2414. //
  2415. SetInterfaceLinkStatus(IF, TRUE);
  2416. }
  2417. }
  2418. else {
  2419. //
  2420. // This is unusual... it indicates a race
  2421. // with TunnelCreateTunnel.
  2422. //
  2423. ASSERT(!(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED));
  2424. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  2425. "TunnelAddAddress(%s) IF %p connected?\n",
  2426. FormatV4Address(V4Addr), IF));
  2427. }
  2428. }
  2429. }
  2430. //
  2431. // Finally, add an address object to the list.
  2432. // Maintain the invariant that an address is present at most once.
  2433. //
  2434. for (tc = Tunnel.AOList.Next; ; tc = tc->Next) {
  2435. if (tc == &Tunnel.AOList) {
  2436. //
  2437. // Add a new address object.
  2438. //
  2439. tc = ExAllocatePool(NonPagedPool, sizeof *tc);
  2440. if (tc != NULL) {
  2441. //
  2442. // Open the address object.
  2443. //
  2444. tc->SrcAddr = V4Addr;
  2445. tc->DstAddr = V4Addr;
  2446. TunnelOpenAddress(tc);
  2447. if (tc->AOFile != NULL) {
  2448. //
  2449. // Put the address object on the list.
  2450. //
  2451. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  2452. TunnelInsertTunnel(tc, &Tunnel.AOList);
  2453. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  2454. }
  2455. else {
  2456. //
  2457. // Cleanup the context. We will not
  2458. // put an address object on the list.
  2459. //
  2460. ExFreePool(tc);
  2461. }
  2462. }
  2463. break;
  2464. }
  2465. if (tc->SrcAddr == V4Addr) {
  2466. //
  2467. // It already exists.
  2468. // REVIEW: Can this happen?
  2469. //
  2470. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  2471. "TunnelAddAddress(%s) already on AOList?\n",
  2472. FormatV4Address(V4Addr)));
  2473. break;
  2474. }
  2475. }
  2476. KeReleaseMutex(&Tunnel.Mutex, FALSE);
  2477. }
  2478. }
  2479. //* TunnelDelAddress
  2480. //
  2481. // Called by TDI when a transport unregisters an address.
  2482. //
  2483. void
  2484. TunnelDelAddress(
  2485. TA_ADDRESS *Address,
  2486. UNICODE_STRING *DeviceName,
  2487. TDI_PNP_CONTEXT *Context)
  2488. {
  2489. if (Address->AddressType == TDI_ADDRESS_TYPE_IP) {
  2490. TDI_ADDRESS_IP *TdiAddr = (TDI_ADDRESS_IP *) Address->Address;
  2491. IPAddr V4Addr = TdiAddr->in_addr;
  2492. TunnelContext *tc;
  2493. KIRQL OldIrql;
  2494. KeWaitForSingleObject(&Tunnel.Mutex, Executive, KernelMode,
  2495. FALSE, NULL);
  2496. //
  2497. // Search for connected interfaces that should be disconnected.
  2498. //
  2499. for (tc = Tunnel.List.Next;
  2500. tc != &Tunnel.List;
  2501. tc = tc->Next) {
  2502. if (tc->SrcAddr == V4Addr) {
  2503. Interface *IF = tc->IF;
  2504. if (tc->AOHandle == NULL) {
  2505. //
  2506. // The interface is already disconnected.
  2507. //
  2508. ASSERT(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED);
  2509. }
  2510. else {
  2511. HANDLE Handle;
  2512. FILE_OBJECT *File;
  2513. //
  2514. // The interface is connected.
  2515. //
  2516. ASSERT(!(IF->Flags & IF_FLAG_MEDIA_DISCONNECTED));
  2517. //
  2518. // Disconnect the interface.
  2519. //
  2520. SetInterfaceLinkStatus(IF, FALSE);
  2521. //
  2522. // Release the address object.
  2523. //
  2524. Handle = tc->AOHandle;
  2525. File = tc->AOFile;
  2526. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  2527. tc->AOHandle = NULL;
  2528. tc->AOFile = NULL;
  2529. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  2530. ObDereferenceObject(File);
  2531. TunnelCloseAddressObject(Handle);
  2532. }
  2533. }
  2534. }
  2535. //
  2536. // Remove an address object from the list.
  2537. // There can be at most one.
  2538. //
  2539. for (tc = Tunnel.AOList.Next;
  2540. tc != &Tunnel.AOList;
  2541. tc = tc->Next) {
  2542. if (tc->SrcAddr == V4Addr) {
  2543. //
  2544. // Remove this cache entry.
  2545. //
  2546. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  2547. TunnelRemoveTunnel(tc);
  2548. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  2549. ObDereferenceObject(tc->AOFile);
  2550. TunnelCloseAddressObject(tc->AOHandle);
  2551. ExFreePool(tc);
  2552. break;
  2553. }
  2554. }
  2555. KeReleaseMutex(&Tunnel.Mutex, FALSE);
  2556. }
  2557. }
  2558. //* TunnelInit - Initialize the tunnel module.
  2559. //
  2560. // This functions initializes the tunnel module.
  2561. //
  2562. // Returns FALSE if we fail to init.
  2563. // This should "never" happen, so we are not
  2564. // careful about cleanup in that case.
  2565. //
  2566. // Note we return TRUE if IPv4 is not available,
  2567. // but then tunnel functionality will not be available.
  2568. //
  2569. int
  2570. TunnelInit(void)
  2571. {
  2572. TDI_CLIENT_INTERFACE_INFO Handlers;
  2573. NTSTATUS status;
  2574. Tunnel.KernelProcess = IoGetCurrentProcess();
  2575. KeInitializeSpinLock(&Tunnel.Lock);
  2576. KeInitializeMutex(&Tunnel.Mutex, 0);
  2577. //
  2578. // Initialize the global list of tunnels.
  2579. //
  2580. Tunnel.List.Next = Tunnel.List.Prev = &Tunnel.List;
  2581. //
  2582. // Initialize the global list of address objects.
  2583. //
  2584. Tunnel.AOList.Next = Tunnel.AOList.Prev = &Tunnel.AOList;
  2585. //
  2586. // Initialize the pseudo-interfaces used
  2587. // for automatic/ISATAP tunneling
  2588. // and 6to4 tunneling.
  2589. //
  2590. status = TunnelCreatePseudoInterface("Auto Tunnel Pseudo-Interface",
  2591. IF_TYPE_TUNNEL_AUTO);
  2592. if (! NT_SUCCESS(status))
  2593. return FALSE;
  2594. ASSERT(IFList->Index == 2); // 6to4svc and scripts depend on this.
  2595. status = TunnelCreatePseudoInterface("6to4 Tunnel Pseudo-Interface",
  2596. IF_TYPE_TUNNEL_6TO4);
  2597. if (! NT_SUCCESS(status))
  2598. return FALSE;
  2599. ASSERT(IFList->Index == 3); // 6to4svc and scripts depend on this.
  2600. //
  2601. // Request address notifications from TDI.
  2602. // REVIEW - What should ClientName be? Does it matter?
  2603. //
  2604. memset(&Handlers, 0, sizeof Handlers);
  2605. Handlers.MajorTdiVersion = TDI_CURRENT_MAJOR_VERSION;
  2606. Handlers.MinorTdiVersion = TDI_CURRENT_MINOR_VERSION;
  2607. Handlers.ClientName = &Tunnel.List.Next->IF->DeviceName;
  2608. Handlers.AddAddressHandlerV2 = TunnelAddAddress;
  2609. Handlers.DelAddressHandlerV2 = TunnelDelAddress;
  2610. status = TdiRegisterPnPHandlers(&Handlers, sizeof Handlers,
  2611. &Tunnel.TdiHandle);
  2612. if (!NT_SUCCESS(status))
  2613. return FALSE;
  2614. return TRUE;
  2615. }
  2616. //* TunnelUnload
  2617. //
  2618. // Called to cleanup when the driver is unloading.
  2619. //
  2620. // Callable from thread context, not DPC context.
  2621. //
  2622. void
  2623. TunnelUnload(void)
  2624. {
  2625. TunnelContext *tc;
  2626. //
  2627. // All interfaces are already destroyed.
  2628. //
  2629. ASSERT(Tunnel.List.Next == &Tunnel.List);
  2630. ASSERT(Tunnel.List.Prev == &Tunnel.List);
  2631. //
  2632. // Stop TDI notifications.
  2633. // REVIEW: How to handle failure, esp. STATUS_NETWORK_BUSY?
  2634. //
  2635. (void) TdiDeregisterPnPHandlers(Tunnel.TdiHandle);
  2636. //
  2637. // Cleanup any remaining address objects.
  2638. //
  2639. while ((tc = Tunnel.AOList.Next) != &Tunnel.AOList) {
  2640. TunnelRemoveTunnel(tc);
  2641. ObDereferenceObject(tc->AOFile);
  2642. TunnelCloseAddressObject(tc->AOHandle);
  2643. ExFreePool(tc);
  2644. }
  2645. ASSERT(Tunnel.AOList.Prev == &Tunnel.AOList);
  2646. //
  2647. // Cleanup if TunnelOpenV4 has succeeded.
  2648. //
  2649. if (Tunnel.List.AOHandle != NULL) {
  2650. void *buffer;
  2651. TunnelContext *tc;
  2652. KIRQL OldIrql;
  2653. //
  2654. // Stop receiving encapsulated (v6 in v4) and ICMPv4 packets.
  2655. // This should block until any current TunnelReceive
  2656. // callbacks return, and prevent new callbacks.
  2657. // REVIEW: It is really legal to change a receive handler?
  2658. // Would just closing the address objects have the proper
  2659. // synchronization behavior?
  2660. //
  2661. (void) TunnelSetReceiveHandler(Tunnel.IcmpFile, NULL);
  2662. (void) TunnelSetReceiveHandler(Tunnel.List.AOFile, NULL);
  2663. ObDereferenceObject(Tunnel.IcmpFile);
  2664. TunnelCloseAddressObject(Tunnel.IcmpHandle);
  2665. ObDereferenceObject(Tunnel.List.AOFile);
  2666. TunnelCloseAddressObject(Tunnel.List.AOHandle);
  2667. buffer = Tunnel.ReceiveIrp->MdlAddress->MappedSystemVa;
  2668. IoFreeMdl(Tunnel.ReceiveIrp->MdlAddress);
  2669. IoFreeIrp(Tunnel.ReceiveIrp);
  2670. ExFreePool(buffer);
  2671. }
  2672. }
  2673. //* TunnelCreateTunnel
  2674. //
  2675. // Creates a tunnel. If DstAddr is INADDR_ANY,
  2676. // then it's a 6-over-4 tunnel. Otherwise it's point-to-point.
  2677. //
  2678. // Callable from thread context, not DPC context.
  2679. //
  2680. // Return codes:
  2681. // STATUS_ADDRESS_ALREADY_EXISTS The tunnel already exists.
  2682. // STATUS_INSUFFICIENT_RESOURCES
  2683. // STATUS_UNSUCCESSFUL
  2684. // STATUS_SUCCESS
  2685. //
  2686. NTSTATUS
  2687. TunnelCreateTunnel(IPAddr SrcAddr, IPAddr DstAddr,
  2688. uint Flags, Interface **ReturnIF)
  2689. {
  2690. char SrcAddrStr[16], DstAddrStr[16];
  2691. char InterfaceName[128];
  2692. GUID Guid;
  2693. LLIPBindInfo BindInfo;
  2694. TunnelContext *tc, *tcTmp;
  2695. KIRQL OldIrql;
  2696. NTSTATUS Status;
  2697. //
  2698. // 6over4 interfaces must use Neighbor Discovery
  2699. // and may use Router Discovery but should not have other flags set.
  2700. // p2p interfaces may use ND, RD, and/or periodic MLD.
  2701. //
  2702. ASSERT(SrcAddr != INADDR_ANY);
  2703. ASSERT((DstAddr == INADDR_ANY) ?
  2704. ((Flags & IF_FLAG_NEIGHBOR_DISCOVERS) &&
  2705. !(Flags &~ IF_FLAGS_DISCOVERS)) :
  2706. !(Flags &~ (IF_FLAGS_DISCOVERS|IF_FLAG_PERIODICMLD)));
  2707. FormatV4AddressWorker(SrcAddrStr, SrcAddr);
  2708. FormatV4AddressWorker(DstAddrStr, DstAddr);
  2709. tc = ExAllocatePool(NonPagedPool, sizeof *tc);
  2710. if (tc == NULL) {
  2711. Status = STATUS_INSUFFICIENT_RESOURCES;
  2712. goto ErrorReturn;
  2713. }
  2714. tc->DstAddr = DstAddr;
  2715. tc->TokenAddr = tc->SrcAddr = SrcAddr;
  2716. tc->SetMCListOK = FALSE;
  2717. //
  2718. // Prepare the binding info for CreateInterface.
  2719. //
  2720. BindInfo.lip_context = tc;
  2721. BindInfo.lip_maxmtu = TUNNEL_MAX_MTU;
  2722. BindInfo.lip_defmtu = TUNNEL_DEFAULT_MTU;
  2723. if (DstAddr == INADDR_ANY) {
  2724. BindInfo.lip_type = IF_TYPE_TUNNEL_6OVER4;
  2725. BindInfo.lip_flags = IF_FLAG_MULTICAST;
  2726. sprintf(InterfaceName, "6over4 %hs", SrcAddrStr);
  2727. } else {
  2728. BindInfo.lip_type = IF_TYPE_TUNNEL_V6V4;
  2729. BindInfo.lip_flags = IF_FLAG_P2P | IF_FLAG_MULTICAST;
  2730. sprintf(InterfaceName, "v6v4 %hs %hs", SrcAddrStr, DstAddrStr);
  2731. }
  2732. BindInfo.lip_flags |= Flags;
  2733. CreateGUIDFromName(InterfaceName, &Guid);
  2734. //
  2735. // We do not want IPv6 to reserve space for our link-layer header.
  2736. //
  2737. BindInfo.lip_hdrsize = 0;
  2738. //
  2739. // For point-to-point interfaces, the remote link-layer address
  2740. // must follow the local link-layer address in memory.
  2741. // So we rely on the TunnelContext layout of SrcAddr & DstAddr.
  2742. //
  2743. BindInfo.lip_addrlen = sizeof(IPAddr);
  2744. BindInfo.lip_addr = (uchar *) &tc->SrcAddr;
  2745. BindInfo.lip_dadxmit = 1; // Per RFC 2462.
  2746. BindInfo.lip_pref = TUNNEL_DEFAULT_PREFERENCE;
  2747. BindInfo.lip_token = TunnelCreateToken;
  2748. BindInfo.lip_cvaddr = TunnelConvertAddress;
  2749. BindInfo.lip_transmit = TunnelTransmitND;
  2750. if (DstAddr == INADDR_ANY) {
  2751. BindInfo.lip_mclist = TunnelSetMulticastAddressList;
  2752. BindInfo.lip_rdllopt = TunnelReadLinkLayerAddressOption;
  2753. BindInfo.lip_wrllopt = TunnelWriteLinkLayerAddressOption;
  2754. }
  2755. else {
  2756. BindInfo.lip_mclist = NULL;
  2757. BindInfo.lip_rdllopt = NULL;
  2758. BindInfo.lip_wrllopt = NULL;
  2759. }
  2760. BindInfo.lip_close = TunnelClose;
  2761. BindInfo.lip_cleanup = TunnelCleanup;
  2762. KeWaitForSingleObject(&Tunnel.Mutex, Executive, KernelMode, FALSE, NULL);
  2763. //
  2764. // Open an IPv4 TDI Address Object that is bound
  2765. // to this address. Packets sent with this AO
  2766. // will use this address as the v4 source.
  2767. // If the open fails, we create the interface disconnected.
  2768. //
  2769. TunnelOpenAddress(tc);
  2770. if (tc->AOHandle == NULL) {
  2771. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2772. "TunnelOpenAddress(%s) failed\n",
  2773. FormatV4Address(SrcAddr)));
  2774. BindInfo.lip_flags |= IF_FLAG_MEDIA_DISCONNECTED;
  2775. }
  2776. //
  2777. // Check that an equivalent tunnel doesn't already exist.
  2778. //
  2779. for (tcTmp = Tunnel.List.Next;
  2780. tcTmp != &Tunnel.List;
  2781. tcTmp = tcTmp->Next) {
  2782. if ((tcTmp->SrcAddr == SrcAddr) &&
  2783. (tcTmp->DstAddr == DstAddr)) {
  2784. Status = STATUS_ADDRESS_ALREADY_EXISTS;
  2785. goto ErrorReturnUnlock;
  2786. }
  2787. }
  2788. //
  2789. // For 6over4 interfaces, start receiving multicasts.
  2790. //
  2791. if (DstAddr == INADDR_ANY) {
  2792. //
  2793. // Synchronize with TunnelOpenV4.
  2794. //
  2795. if (Tunnel.List.AOHandle != NULL)
  2796. tc->SetMCListOK = TRUE;
  2797. }
  2798. //
  2799. // Create the IPv6 interface.
  2800. // We can hold the mutex across this call, but not a spinlock.
  2801. //
  2802. Status = CreateInterface(&Guid, &BindInfo, (void **)&tc->IF);
  2803. if (! NT_SUCCESS(Status))
  2804. goto ErrorReturnUnlock;
  2805. //
  2806. // Return a reference to the interface, if requested.
  2807. //
  2808. if (ReturnIF != NULL) {
  2809. Interface *IF = tc->IF;
  2810. AddRefIF(IF);
  2811. *ReturnIF = IF;
  2812. }
  2813. //
  2814. // Put this tunnel on our global list.
  2815. // Note that once we unlock, it could be immediately deleted.
  2816. //
  2817. KeAcquireSpinLock(&Tunnel.Lock, &OldIrql);
  2818. TunnelInsertTunnel(tc, &Tunnel.List);
  2819. KeReleaseSpinLock(&Tunnel.Lock, OldIrql);
  2820. KeReleaseMutex(&Tunnel.Mutex, FALSE);
  2821. return STATUS_SUCCESS;
  2822. ErrorReturnUnlock:
  2823. KeReleaseMutex(&Tunnel.Mutex, FALSE);
  2824. if (tc->AOFile != NULL)
  2825. ObDereferenceObject(tc->AOFile);
  2826. if (tc->AOHandle != NULL)
  2827. TunnelCloseAddressObject(tc->AOHandle);
  2828. ExFreePool(tc);
  2829. ErrorReturn:
  2830. return Status;
  2831. }