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

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