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

201 lines
5.3 KiB

  1. // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
  2. //
  3. // Copyright (c) 1985-2000 Microsoft Corporation
  4. //
  5. // This file is part of the Microsoft Research IPv6 Network Protocol Stack.
  6. // You should have received a copy of the Microsoft End-User License Agreement
  7. // for this software along with this release; see the file "license.txt".
  8. // If not, please see http://www.research.microsoft.com/msripv6/license.htm,
  9. // or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
  10. //
  11. // Abstract:
  12. //
  13. // NT specific routines for loading and configuring the IP driver.
  14. //
  15. #define _CTYPE_DISABLE_MACROS // REVIEW: does this do anything?
  16. #include <oscfg.h>
  17. #include <ndis.h>
  18. #include <ip6imp.h>
  19. #include "ip6def.h"
  20. #include <tdiinfo.h>
  21. #include <tdikrnl.h>
  22. #include <ntddip6.h>
  23. #include <ip6.h>
  24. #include <icmp6.h>
  25. #include "neighbor.h"
  26. #include "route.h"
  27. //
  28. // Global variables.
  29. //
  30. PDRIVER_OBJECT IPDriverObject;
  31. PDEVICE_OBJECT IPDeviceObject;
  32. HANDLE IPv6ProviderHandle;
  33. int IPv6IndicatedProviderReady;
  34. uint UseEtherSnap = FALSE;
  35. //
  36. // Local function prototypes
  37. //
  38. NTSTATUS
  39. IPDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
  40. uint
  41. UseEtherSNAP(PNDIS_STRING Name);
  42. #ifdef ALLOC_PRAGMA
  43. #pragma alloc_text(INIT, IPDriverEntry)
  44. #pragma alloc_text(PAGE, UseEtherSNAP)
  45. #endif // ALLOC_PRAGMA
  46. //
  47. // Function definitions
  48. //
  49. //* IPDriverEntry
  50. //
  51. // This is the IPv6 protocol initialization entry point, called from
  52. // the common DriverEntry routine upon loading.
  53. //
  54. NTSTATUS // Status of initialization operation.
  55. IPDriverEntry(
  56. IN PDRIVER_OBJECT DriverObject, // Common TCP/IP driver object.
  57. IN PUNICODE_STRING RegistryPath) // Path to our info in the registry.
  58. {
  59. NTSTATUS Status;
  60. UNICODE_STRING DeviceName;
  61. UNICODE_STRING WinDeviceName;
  62. IPDriverObject = DriverObject;
  63. //
  64. // Create the device object. IoCreateDevice zeroes the memory
  65. // occupied by the object.
  66. //
  67. RtlInitUnicodeString(&DeviceName, DD_IPV6_DEVICE_NAME);
  68. Status = IoCreateDevice(DriverObject, 0, &DeviceName,
  69. FILE_DEVICE_NETWORK,
  70. FILE_DEVICE_SECURE_OPEN,
  71. FALSE, &IPDeviceObject);
  72. if (!NT_SUCCESS(Status)) {
  73. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  74. "IP init failed: "
  75. "Unable to create device object %ws, Status %lx.",
  76. DD_IPV6_DEVICE_NAME, Status));
  77. return(Status);
  78. }
  79. //
  80. // Create a Win32-accessible link for the device.
  81. // This will allow Windows programs to make IOCTLs.
  82. //
  83. RtlInitUnicodeString(&WinDeviceName, L"\\??\\" WIN_IPV6_BASE_DEVICE_NAME);
  84. Status = IoCreateSymbolicLink(&WinDeviceName, &DeviceName);
  85. if (!NT_SUCCESS(Status)) {
  86. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  87. "IPv6: IoCreateSymbolicLink failed\n"));
  88. IoDeleteDevice(IPDeviceObject);
  89. return STATUS_UNSUCCESSFUL;
  90. }
  91. //
  92. // Register as a TDI provider.
  93. //
  94. Status = TdiRegisterProvider(&DeviceName, &IPv6ProviderHandle);
  95. if (!NT_SUCCESS(Status)) {
  96. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  97. "IPv6: TdiRegisterProvider failed\n"));
  98. IoDeleteDevice(IPDeviceObject);
  99. return STATUS_UNSUCCESSFUL;
  100. }
  101. //
  102. // Initialize the device object.
  103. //
  104. IPDeviceObject->Flags |= DO_DIRECT_IO;
  105. //
  106. // Initialize the list of pending echo request IRPs.
  107. //
  108. InitializeListHead(&PendingEchoList);
  109. //
  110. // Read configuration parameters from the registry
  111. // and then initialize.
  112. //
  113. ConfigureGlobalParameters();
  114. if (!IPInit()) {
  115. //
  116. // REVIEW: Write an error log entry here?
  117. //
  118. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  119. "IP initialization failed.\n"));
  120. TdiDeregisterProvider(IPv6ProviderHandle);
  121. IoDeleteDevice(IPDeviceObject);
  122. return STATUS_UNSUCCESSFUL;
  123. }
  124. return STATUS_SUCCESS;
  125. }
  126. //* IPv6ProviderReady
  127. //
  128. // Indicate that we are ready to operate as a TDI provider.
  129. //
  130. void
  131. IPv6ProviderReady(void)
  132. {
  133. int DidIndicateProviderReady;
  134. NTSTATUS Status;
  135. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  136. //
  137. // Ensure that we only indicate provider ready once.
  138. //
  139. DidIndicateProviderReady = InterlockedExchange(&IPv6IndicatedProviderReady,
  140. TRUE);
  141. if (! DidIndicateProviderReady) {
  142. //
  143. // Create persistent interfaces after any NDIS interfaces.
  144. //
  145. ConfigurePersistentInterfaces();
  146. //
  147. // Now indicate to TDI that we are ready.
  148. //
  149. Status = TdiProviderReady(IPv6ProviderHandle);
  150. if (!NT_SUCCESS(Status))
  151. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  152. "IPv6: TdiProviderReady failed: %x\n", Status));
  153. }
  154. }
  155. //* UseEtherSNAP
  156. //
  157. // Determines whether the EtherSNAP protocol should be used on an interface.
  158. //
  159. uint // Returns: Nonzero if SNAP is to be used on the I/F. Zero otherwise.
  160. UseEtherSNAP(
  161. PNDIS_STRING Name) // Device name of the interface in question.
  162. {
  163. UNREFERENCED_PARAMETER(Name);
  164. //
  165. // We currently set this on a global basis.
  166. //
  167. return(UseEtherSnap);
  168. }