#include <string.h>
#include <stdio.h>
#include <ntddk.h>
#include <ntddndis.h>
#include <pfhook.h>
#include "DrvFltIp.h"
#if DBG
#define dprintf DbgPrint
#else
#define dprintf(x)
#endif
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DrvUnload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS SetFilterFunction(PacketFilterExtensionPtr filterFunction);
NTSTATUS AddFilterToList(IPFilter *pf);
void ClearFilterList(void);
PF_FORWARD_ACTION cbFilterFunction(IN unsigned char *PacketHeader,IN unsigned char *Packet, IN unsigned int PacketLength, IN unsigned int RecvInterfaceIndex, IN unsigned int SendInterfaceIndex, IN unsigned long RecvLinkNextHop, IN unsigned long SendLinkNextHop);
#define NT_DEVICE_NAME L"\\Device\\DrvFltIp"
#define DOS_DEVICE_NAME L"\\DosDevices\\DrvFltIp"
struct filterList *first = NULL;
struct filterList *last = NULL;
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT deviceObject = NULL;
NTSTATUS ntStatus;
UNICODE_STRING deviceNameUnicodeString;
UNICODE_STRING deviceLinkUnicodeString;
dprintf("DrvFltIp.SYS: entering DriverEntry\n");
//we have to create the device
RtlInitUnicodeString(&deviceNameUnicodeString, NT_DEVICE_NAME);
ntStatus = IoCreateDevice(DriverObject,
0,
&deviceNameUnicodeString,
FILE_DEVICE_DRVFLTIP,
0,
FALSE,
&deviceObject);
if ( NT_SUCCESS(ntStatus) )
{
RtlInitUnicodeString(&deviceLinkUnicodeString, DOS_DEVICE_NAME);
ntStatus = IoCreateSymbolicLink(&deviceLinkUnicodeString, &deviceNameUnicodeString);
if ( !NT_SUCCESS(ntStatus) )
{
dprintf("JAH-NDIS: IoCreateSymbolicLink failed\n");
}
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DrvDispatch;
DriverObject->DriverUnload = DrvUnload;
}
if ( !NT_SUCCESS(ntStatus) )
{
dprintf("JAH-NDIS : Error in initialization. Unloading...");
DrvUnload(DriverObject);
}
return ntStatus;
}
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
PVOID ioBuffer;
ULONG inputBufferLength;
ULONG outputBufferLength;
ULONG ioControlCode;
NTSTATUS ntStatus;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
irpStack = IoGetCurrentIrpStackLocation(Irp);
ioBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch (irpStack->MajorFunction)
{
case IRP_MJ_CREATE:
dprintf("JAH-NDIS: IRP_MJ_CREATE\n");
break;
case IRP_MJ_CLOSE:
dprintf("JAH-NDIS: IRP_MJ_CLOSE\n");
break;
case IRP_MJ_DEVICE_CONTROL:
dprintf("JAH-NDIS: IRP_MJ_DEVICE_CONTROL\n");
ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
switch (ioControlCode)
{
case START_IP_HOOK:
{
SetFilterFunction(cbFilterFunction);
break;
}
case STOP_IP_HOOK:
{
SetFilterFunction(NULL);
break;
}
// ioctl to add a filter rule
case ADD_FILTER:
{
if(inputBufferLength == sizeof(IPFilter))
{
IPFilter *nf;
nf = (IPFilter *)ioBuffer;
AddFilterToList(nf);
}
break;
}
case CLEAR_FILTER:
{
ClearFilterList();
break;
}
default:
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
dprintf("JAH-NDIS: unknown IRP_MJ_DEVICE_CONTROL\n");
break;
}
break;
}
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;
}
VOID DrvUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING deviceLinkUnicodeString;
dprintf("JAH-NDIS: Unloading\n");
SetFilterFunction(NULL);
ClearFilterList();
RtlInitUnicodeString(&deviceLinkUnicodeString, DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&deviceLinkUnicodeString);
IoDeleteDevice(DriverObject->DeviceObject);
}
NTSTATUS SetFilterFunction(PacketFilterExtensionPtr filterFunction)
{
NTSTATUS status = STATUS_SUCCESS, waitStatus=STATUS_SUCCESS;
UNICODE_STRING filterName;
PDEVICE_OBJECT ipDeviceObject=NULL;
PFILE_OBJECT ipFileObject=NULL;
PF_SET_EXTENSION_HOOK_INFO filterData;
KEVENT event;
IO_STATUS_BLOCK ioStatus;
PIRP irp;
dprintf("JAH-NDIS:Getting pointer to IpFilterDriver\n");
RtlInitUnicodeString(&filterName, DD_IPFLTRDRVR_DEVICE_NAME);
status = IoGetDeviceObjectPointer(&filterName,STANDARD_RIGHTS_ALL, &ipFileObject, &ipDeviceObject);
if(NT_SUCCESS(status))
{
filterData.ExtensionPointer = filterFunction;
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER,
ipDeviceObject,
(PVOID) &filterData,
sizeof(PF_SET_EXTENSION_HOOK_INFO),
NULL,
0,
FALSE,
&event,
&ioStatus);
if(irp != NULL)
{
status = IoCallDriver(ipDeviceObject, irp);
if (status == STATUS_PENDING)
{
waitStatus = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
if (waitStatus != STATUS_SUCCESS )
dprintf("JAH-NDIS:Error waiting for IpFilterDriver response.");
}
status = ioStatus.Status;
if(!NT_SUCCESS(status))
dprintf("JAH-NDIS:Error, IO error with ipFilterDriver\n");
}
else
{
status = STATUS_INSUFFICIENT_RESOURCES;
dprintf("JAH-NDIS:Error building IpFilterDriver IRP\n");
}
if(ipFileObject != NULL)
ObDereferenceObject(ipFileObject);
ipFileObject = NULL;
ipDeviceObject = NULL;
}
else
dprintf("JAH-NDIS:Error while getting the pointer\n");
return status;
}
NTSTATUS AddFilterToList(IPFilter *pf)
{
struct filterList *aux=NULL;
aux=(struct filterList *) ExAllocatePool(NonPagedPool, sizeof(struct filterList));
if(aux == NULL)
{
dprintf("JAH-NDIS:Problem reserving memory\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
memcpy( &(aux->ipf) , pf , sizeof(IPFilter) );
if(first == NULL)
{
first = last = aux;
first->next = NULL;
}
else
{
last->next = aux;
last = aux;
last->next = NULL;
}
return STATUS_SUCCESS;
}
void ClearFilterList(void)
{
struct filterList *aux = NULL;
dprintf("JAH-NDIS:Removing the filter List...");
while(first != NULL)
{
aux = first;
first = first->next;
ExFreePool(aux);
dprintf("JAH-NDIS:One Rule removed");
}
first = last = NULL;
dprintf("JAH-NDIS:Removed is complete.");
}
USHORT ntohs(USHORT port)
{
CHAR hostshort[4] = { 0 };
PCHAR pnetshort = (PCHAR)&port;
hostshort[0] = pnetshort[1];
hostshort[1] = pnetshort[0];
return *(USHORT*)hostshort;
}
ULONG ntohl(ULONG netlong)
{
CHAR hostlong[4];
PCHAR pnetlong = (PCHAR)&netlong;
hostlong[0] = pnetlong[3];
hostlong[1] = pnetlong[2];
hostlong[2] = pnetlong[1];
hostlong[3] = pnetlong[0];
return *(ULONG*)hostlong;
}
BOOLEAN CheckIp(ULONG ip,ULONG ip1,ULONG ip2)
{
BOOLEAN ret = FALSE;
if (( ip1 ==0 ) && ( ip2 ==0 ))
ret = TRUE;
else
{
if (( ntohl(ip) >= ntohl(ip1))
&&( ntohl(ip) <= ntohl(ip2)))
ret = TRUE;
}
return ret;
}
BOOLEAN CheckPort(USHORT port , USHORT port1 ,USHORT port2)
{
BOOLEAN ret = FALSE;
if (( port1 == 0)&&(port2 ==0 ))
ret = TRUE;
else
{
if (( (port) >= ntohs(port1))
&&( (p
评论0