windows-nt/Source/XPSP1/NT/net/tcpip/tpipv6/tcpip6/ip6/ntip.c

202 lines
5.3 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// Copyright (c) 1985-2000 Microsoft Corporation
//
// This file is part of the Microsoft Research IPv6 Network Protocol Stack.
// You should have received a copy of the Microsoft End-User License Agreement
// for this software along with this release; see the file "license.txt".
// If not, please see http://www.research.microsoft.com/msripv6/license.htm,
// or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
//
// Abstract:
//
// NT specific routines for loading and configuring the IP driver.
//
#define _CTYPE_DISABLE_MACROS // REVIEW: does this do anything?
#include <oscfg.h>
#include <ndis.h>
#include <ip6imp.h>
#include "ip6def.h"
#include <tdiinfo.h>
#include <tdikrnl.h>
#include <ntddip6.h>
#include <ip6.h>
#include <icmp6.h>
#include "neighbor.h"
#include "route.h"
//
// Global variables.
//
PDRIVER_OBJECT IPDriverObject;
PDEVICE_OBJECT IPDeviceObject;
HANDLE IPv6ProviderHandle;
int IPv6IndicatedProviderReady;
uint UseEtherSnap = FALSE;
//
// Local function prototypes
//
NTSTATUS
IPDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
uint
UseEtherSNAP(PNDIS_STRING Name);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, IPDriverEntry)
#pragma alloc_text(PAGE, UseEtherSNAP)
#endif // ALLOC_PRAGMA
//
// Function definitions
//
//* IPDriverEntry
//
// This is the IPv6 protocol initialization entry point, called from
// the common DriverEntry routine upon loading.
//
NTSTATUS // Status of initialization operation.
IPDriverEntry(
IN PDRIVER_OBJECT DriverObject, // Common TCP/IP driver object.
IN PUNICODE_STRING RegistryPath) // Path to our info in the registry.
{
NTSTATUS Status;
UNICODE_STRING DeviceName;
UNICODE_STRING WinDeviceName;
IPDriverObject = DriverObject;
//
// Create the device object. IoCreateDevice zeroes the memory
// occupied by the object.
//
RtlInitUnicodeString(&DeviceName, DD_IPV6_DEVICE_NAME);
Status = IoCreateDevice(DriverObject, 0, &DeviceName,
FILE_DEVICE_NETWORK,
FILE_DEVICE_SECURE_OPEN,
FALSE, &IPDeviceObject);
if (!NT_SUCCESS(Status)) {
KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
"IP init failed: "
"Unable to create device object %ws, Status %lx.",
DD_IPV6_DEVICE_NAME, Status));
return(Status);
}
//
// Create a Win32-accessible link for the device.
// This will allow Windows programs to make IOCTLs.
//
RtlInitUnicodeString(&WinDeviceName, L"\\??\\" WIN_IPV6_BASE_DEVICE_NAME);
Status = IoCreateSymbolicLink(&WinDeviceName, &DeviceName);
if (!NT_SUCCESS(Status)) {
KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
"IPv6: IoCreateSymbolicLink failed\n"));
IoDeleteDevice(IPDeviceObject);
return STATUS_UNSUCCESSFUL;
}
//
// Register as a TDI provider.
//
Status = TdiRegisterProvider(&DeviceName, &IPv6ProviderHandle);
if (!NT_SUCCESS(Status)) {
KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
"IPv6: TdiRegisterProvider failed\n"));
IoDeleteDevice(IPDeviceObject);
return STATUS_UNSUCCESSFUL;
}
//
// Initialize the device object.
//
IPDeviceObject->Flags |= DO_DIRECT_IO;
//
// Initialize the list of pending echo request IRPs.
//
InitializeListHead(&PendingEchoList);
//
// Read configuration parameters from the registry
// and then initialize.
//
ConfigureGlobalParameters();
if (!IPInit()) {
//
// REVIEW: Write an error log entry here?
//
KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
"IP initialization failed.\n"));
TdiDeregisterProvider(IPv6ProviderHandle);
IoDeleteDevice(IPDeviceObject);
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
//* IPv6ProviderReady
//
// Indicate that we are ready to operate as a TDI provider.
//
void
IPv6ProviderReady(void)
{
int DidIndicateProviderReady;
NTSTATUS Status;
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
//
// Ensure that we only indicate provider ready once.
//
DidIndicateProviderReady = InterlockedExchange(&IPv6IndicatedProviderReady,
TRUE);
if (! DidIndicateProviderReady) {
//
// Create persistent interfaces after any NDIS interfaces.
//
ConfigurePersistentInterfaces();
//
// Now indicate to TDI that we are ready.
//
Status = TdiProviderReady(IPv6ProviderHandle);
if (!NT_SUCCESS(Status))
KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
"IPv6: TdiProviderReady failed: %x\n", Status));
}
}
//* UseEtherSNAP
//
// Determines whether the EtherSNAP protocol should be used on an interface.
//
uint // Returns: Nonzero if SNAP is to be used on the I/F. Zero otherwise.
UseEtherSNAP(
PNDIS_STRING Name) // Device name of the interface in question.
{
UNREFERENCED_PARAMETER(Name);
//
// We currently set this on a global basis.
//
return(UseEtherSnap);
}