355 lines
6 KiB
C
355 lines
6 KiB
C
/*++
|
||
|
||
Copyright (c) 1999 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
pfd.c
|
||
|
||
Abstract:
|
||
|
||
This module contains code for a simple packet-filter driver
|
||
|
||
Author:
|
||
|
||
Abolade Gbadegesin (aboladeg) 15-Aug-1999
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "precomp.h"
|
||
#pragma hdrstop
|
||
|
||
|
||
//
|
||
// Device- and file-object for the IP driver
|
||
//
|
||
|
||
extern PDEVICE_OBJECT IpDeviceObject = NULL;
|
||
extern PFILE_OBJECT IpFileObject = NULL;
|
||
|
||
//
|
||
// Device-object for the filter driver
|
||
//
|
||
|
||
extern PDEVICE_OBJECT PfdDeviceObject = NULL;
|
||
|
||
|
||
//
|
||
// FUNCTION PROTOTYPES (alphabetically)
|
||
//
|
||
|
||
NTSTATUS
|
||
DriverEntry(
|
||
IN PDRIVER_OBJECT DriverObject,
|
||
IN PUNICODE_STRING RegistryPath
|
||
);
|
||
|
||
FORWARD_ACTION
|
||
PfdFilterPacket(
|
||
struct IPHeader UNALIGNED* Header,
|
||
PUCHAR Packet,
|
||
UINT PacketLength,
|
||
UINT ReceivingInterfaceIndex,
|
||
UINT SendingInterfaceIndex,
|
||
IPAddr ReceivingLinkNextHop,
|
||
IPAddr SendingLinkNextHop
|
||
);
|
||
|
||
NTSTATUS
|
||
PfdInitializeDriver(
|
||
VOID
|
||
);
|
||
|
||
NTSTATUS
|
||
PfdSetFilterHook(
|
||
BOOLEAN Install
|
||
);
|
||
|
||
VOID
|
||
PfdUnloadDriver(
|
||
IN PDRIVER_OBJECT DriverObject
|
||
);
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(INIT, DriverEntry)
|
||
#endif
|
||
|
||
|
||
NTSTATUS
|
||
DriverEntry(
|
||
IN PDRIVER_OBJECT DriverObject,
|
||
IN PUNICODE_STRING RegistryPath
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Performs driver-initialization for the filter driver.
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
STATUS_SUCCESS if initialization succeeded, error code otherwise.
|
||
|
||
--*/
|
||
|
||
{
|
||
WCHAR DeviceName[] = DD_IP_PFD_DEVICE_NAME;
|
||
UNICODE_STRING DeviceString;
|
||
LONG i;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
HANDLE ParametersKey;
|
||
HANDLE ServiceKey;
|
||
NTSTATUS status;
|
||
UNICODE_STRING String;
|
||
|
||
PAGED_CODE();
|
||
|
||
KdPrint(("DriverEntry\n"));
|
||
|
||
//
|
||
// Create the device's object.
|
||
//
|
||
|
||
RtlInitUnicodeString(&DeviceString, DeviceName);
|
||
|
||
status =
|
||
IoCreateDevice(
|
||
DriverObject,
|
||
0,
|
||
&DeviceString,
|
||
FILE_DEVICE_NETWORK,
|
||
FILE_DEVICE_SECURE_OPEN,
|
||
FALSE,
|
||
&PfdDeviceObject
|
||
);
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
KdPrint(("IoCreateDevice failed (0x%08X)\n", status));
|
||
return status;
|
||
}
|
||
|
||
DriverObject->DriverUnload = PfdUnloadDriver;
|
||
DriverObject->DriverStartIo = NULL;
|
||
|
||
//
|
||
// Initialize the driver's structures
|
||
//
|
||
|
||
status = PfdInitializeDriver();
|
||
|
||
return status;
|
||
|
||
} // DriverEntry
|
||
|
||
|
||
FORWARD_ACTION
|
||
PfdFilterPacket(
|
||
struct IPHeader UNALIGNED* Header,
|
||
PUCHAR Packet,
|
||
UINT PacketLength,
|
||
UINT ReceivingInterfaceIndex,
|
||
UINT SendingInterfaceIndex,
|
||
IPAddr ReceivingLinkNextHop,
|
||
IPAddr SendingLinkNextHop
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Invoked to determine the fate of each received packet.
|
||
|
||
Arguments:
|
||
|
||
none used.
|
||
|
||
Return Value:
|
||
|
||
FORWARD_ACTION - indicates whether to forward or drop the given packet.
|
||
|
||
Environment:
|
||
|
||
Invoked within the context of reception or transmission.
|
||
|
||
--*/
|
||
|
||
{
|
||
KdPrint(("PfdFilterPacket\n"));
|
||
return FORWARD;
|
||
} // PfdFilterPacket
|
||
|
||
|
||
NTSTATUS
|
||
PfdInitializeDriver(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Performs initialization of the driver's structures.
|
||
|
||
Arguments:
|
||
|
||
none.
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - success/error code.
|
||
|
||
--*/
|
||
|
||
{
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
NTSTATUS status;
|
||
UNICODE_STRING UnicodeString;
|
||
|
||
KdPrint(("PfdInitializeDriver\n"));
|
||
|
||
//
|
||
// Obtain the IP driver device-object
|
||
//
|
||
|
||
RtlInitUnicodeString(&UnicodeString, DD_IP_DEVICE_NAME);
|
||
status =
|
||
IoGetDeviceObjectPointer(
|
||
&UnicodeString,
|
||
SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE,
|
||
&IpFileObject,
|
||
&IpDeviceObject
|
||
);
|
||
if (!NT_SUCCESS(status)) {
|
||
KdPrint(("PfdInitializeDriver: error %X getting IP object\n", status));
|
||
return status;
|
||
}
|
||
|
||
ObReferenceObject(IpDeviceObject);
|
||
|
||
//
|
||
// Install the filter-hook routine
|
||
//
|
||
|
||
return PfdSetFilterHook(TRUE);
|
||
|
||
} // PfdInitializeDriver
|
||
|
||
|
||
NTSTATUS
|
||
PfdSetFilterHook(
|
||
BOOLEAN Install
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called to set (Install==TRUE) or clear (Install==FALSE) the
|
||
value of the filter-callout function pointer in the IP driver.
|
||
|
||
Arguments:
|
||
|
||
Install - indicates whether to install or remove the hook.
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - indicates success/failure
|
||
|
||
Environment:
|
||
|
||
The routine assumes the caller is executing at PASSIVE_LEVEL.
|
||
|
||
--*/
|
||
|
||
{
|
||
IP_SET_FILTER_HOOK_INFO HookInfo;
|
||
IO_STATUS_BLOCK IoStatus;
|
||
PIRP Irp;
|
||
KEVENT LocalEvent;
|
||
NTSTATUS status;
|
||
|
||
KdPrint(("PfdSetFilterHook\n"));
|
||
|
||
//
|
||
// Register (or deregister) as a filter driver
|
||
//
|
||
|
||
HookInfo.FilterPtr = Install ? PfdFilterPacket : NULL;
|
||
|
||
KeInitializeEvent(&LocalEvent, SynchronizationEvent, FALSE);
|
||
Irp =
|
||
IoBuildDeviceIoControlRequest(
|
||
IOCTL_IP_SET_FILTER_POINTER,
|
||
IpDeviceObject,
|
||
(PVOID)&HookInfo,
|
||
sizeof(HookInfo),
|
||
NULL,
|
||
0,
|
||
FALSE,
|
||
&LocalEvent,
|
||
&IoStatus
|
||
);
|
||
|
||
if (!Irp) {
|
||
KdPrint(("PfdSetFilterHook: IoBuildDeviceIoControlRequest=0\n"));
|
||
return STATUS_UNSUCCESSFUL;
|
||
}
|
||
|
||
status = IoCallDriver(IpDeviceObject, Irp);
|
||
if (status == STATUS_PENDING) {
|
||
KeWaitForSingleObject(&LocalEvent, Executive, KernelMode, FALSE, NULL);
|
||
status = IoStatus.Status;
|
||
}
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
KdPrint(("PfdSetFilterHook: SetFilterPointer=%x\n", status));
|
||
}
|
||
|
||
return status;
|
||
|
||
} // PfdSetFilterHook
|
||
|
||
|
||
VOID
|
||
PfdUnloadDriver(
|
||
IN PDRIVER_OBJECT DriverObject
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Performs cleanup for the filter-driver.
|
||
|
||
Arguments:
|
||
|
||
DriverObject - reference to the module's driver-object
|
||
|
||
Return Value:
|
||
|
||
--*/
|
||
|
||
{
|
||
KdPrint(("PfdUnloadDriver\n"));
|
||
|
||
//
|
||
// Stop translation and clear the periodic timer
|
||
//
|
||
|
||
PfdSetFilterHook(FALSE);
|
||
IoDeleteDevice(DriverObject->DeviceObject);
|
||
|
||
//
|
||
// Release references to the IP device object
|
||
//
|
||
|
||
ObDereferenceObject((PVOID)IpFileObject);
|
||
ObDereferenceObject(IpDeviceObject);
|
||
|
||
} // PfdUnloadDriver
|
||
|