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.

213 lines
5.7 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. #ifdef DEBUG_OBJECTS
  36. extern LIST_ENTRY FileObjectList;
  37. extern KSPIN_LOCK FileObjectLock;
  38. #endif
  39. //
  40. // Local function prototypes
  41. //
  42. NTSTATUS
  43. IPDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
  44. uint
  45. UseEtherSNAP(PNDIS_STRING Name);
  46. #ifdef ALLOC_PRAGMA
  47. #pragma alloc_text(INIT, IPDriverEntry)
  48. #pragma alloc_text(PAGE, UseEtherSNAP)
  49. #endif // ALLOC_PRAGMA
  50. //
  51. // Function definitions
  52. //
  53. //* IPDriverEntry
  54. //
  55. // This is the IPv6 protocol initialization entry point, called from
  56. // the common DriverEntry routine upon loading.
  57. //
  58. NTSTATUS // Status of initialization operation.
  59. IPDriverEntry(
  60. IN PDRIVER_OBJECT DriverObject, // Common TCP/IP driver object.
  61. IN PUNICODE_STRING RegistryPath) // Path to our info in the registry.
  62. {
  63. NTSTATUS Status;
  64. UNICODE_STRING DeviceName;
  65. UNICODE_STRING WinDeviceName;
  66. UNREFERENCED_PARAMETER(RegistryPath);
  67. IPDriverObject = DriverObject;
  68. #ifdef DEBUG_OBJECTS
  69. InitializeListHead(&FileObjectList);
  70. KeInitializeSpinLock(&FileObjectLock);
  71. #endif
  72. //
  73. // Create the device object. IoCreateDevice zeroes the memory
  74. // occupied by the object.
  75. //
  76. RtlInitUnicodeString(&DeviceName, DD_IPV6_DEVICE_NAME);
  77. Status = IoCreateDevice(DriverObject, 0, &DeviceName,
  78. FILE_DEVICE_NETWORK,
  79. FILE_DEVICE_SECURE_OPEN,
  80. FALSE, &IPDeviceObject);
  81. if (!NT_SUCCESS(Status)) {
  82. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  83. "IP init failed: "
  84. "Unable to create device object %ws, Status %lx.",
  85. DD_IPV6_DEVICE_NAME, Status));
  86. return(Status);
  87. }
  88. //
  89. // Create a Win32-accessible link for the device.
  90. // This will allow Windows programs to make IOCTLs.
  91. //
  92. RtlInitUnicodeString(&WinDeviceName, L"\\??\\" WIN_IPV6_BASE_DEVICE_NAME);
  93. Status = IoCreateSymbolicLink(&WinDeviceName, &DeviceName);
  94. if (!NT_SUCCESS(Status)) {
  95. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  96. "IPv6: IoCreateSymbolicLink failed\n"));
  97. IoDeleteDevice(IPDeviceObject);
  98. return STATUS_UNSUCCESSFUL;
  99. }
  100. //
  101. // Register as a TDI provider.
  102. //
  103. Status = TdiRegisterProvider(&DeviceName, &IPv6ProviderHandle);
  104. if (!NT_SUCCESS(Status)) {
  105. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  106. "IPv6: TdiRegisterProvider failed\n"));
  107. IoDeleteDevice(IPDeviceObject);
  108. return STATUS_UNSUCCESSFUL;
  109. }
  110. //
  111. // Initialize the device object.
  112. //
  113. IPDeviceObject->Flags |= DO_DIRECT_IO;
  114. //
  115. // Initialize the list of pending echo request IRPs.
  116. //
  117. InitializeListHead(&PendingEchoList);
  118. //
  119. // Read configuration parameters from the registry
  120. // and then initialize.
  121. //
  122. ConfigureGlobalParameters();
  123. if (!IPInit()) {
  124. //
  125. // REVIEW: Write an error log entry here?
  126. //
  127. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  128. "IP initialization failed.\n"));
  129. TdiDeregisterProvider(IPv6ProviderHandle);
  130. IoDeleteDevice(IPDeviceObject);
  131. return STATUS_UNSUCCESSFUL;
  132. }
  133. return STATUS_SUCCESS;
  134. }
  135. //* IPv6ProviderReady
  136. //
  137. // Indicate that we are ready to operate as a TDI provider.
  138. //
  139. void
  140. IPv6ProviderReady(void)
  141. {
  142. int DidIndicateProviderReady;
  143. NTSTATUS Status;
  144. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  145. //
  146. // Ensure that we only indicate provider ready once.
  147. //
  148. DidIndicateProviderReady = InterlockedExchange(
  149. (PLONG)&IPv6IndicatedProviderReady, TRUE);
  150. if (! DidIndicateProviderReady) {
  151. //
  152. // Create persistent interfaces after any NDIS interfaces.
  153. //
  154. ConfigurePersistentInterfaces();
  155. //
  156. // Now indicate to TDI that we are ready.
  157. //
  158. Status = TdiProviderReady(IPv6ProviderHandle);
  159. if (!NT_SUCCESS(Status))
  160. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  161. "IPv6: TdiProviderReady failed: %x\n", Status));
  162. }
  163. }
  164. //* UseEtherSNAP
  165. //
  166. // Determines whether the EtherSNAP protocol should be used on an interface.
  167. //
  168. uint // Returns: Nonzero if SNAP is to be used on the I/F. Zero otherwise.
  169. UseEtherSNAP(
  170. PNDIS_STRING Name) // Device name of the interface in question.
  171. {
  172. UNREFERENCED_PARAMETER(Name);
  173. //
  174. // We currently set this on a global basis.
  175. //
  176. return(UseEtherSnap);
  177. }