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.
354 lines
6.4 KiB
354 lines
6.4 KiB
/*++
|
|
|
|
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
|
|
|