Revisted the packet capture driver and updated with fixes in latest 3.0a4 release.

Seems I'll need to do some work on the SCM before this'll be running for me.

svn path=/trunk/; revision=3883
This commit is contained in:
Robert Dickenson 2002-12-21 04:46:09 +00:00
parent 5f09dd1402
commit 05a8cab618
24 changed files with 1948 additions and 1614 deletions

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.2 2002/09/24 15:16:46 robd Exp $
# $Id: Makefile,v 1.3 2002/12/21 04:46:09 robd Exp $
PATH_TO_TOP = ../../..
@ -7,7 +7,9 @@ TARGET_TYPE = driver
TARGET_NAME = packet
TARGET_CFLAGS = -DDBG -DWIN_NT_DRIVER -DKQPC_TS
#TARGET_CFLAGS = -DDBG -DWIN_NT_DRIVER -DKQPC_TS -I$(PATH_TO_TOP)/ntoskrnl/include
TARGET_CFLAGS = -DDBG -DWIN_NT_DRIVER -DKQPC_TS -DUSE_KLOCKS -I$(PATH_TO_TOP)/ntoskrnl/include
TARGET_OBJECTS = \
packet.o \

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2001
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -35,9 +35,9 @@
#endif
#define BUCKET_LOOKUP_INSERT 0x00000011
#define BUCKET_LOOKUP_INSERT 0x00000011
uint32 bucket_lookup_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref);
#define BUCKET_LOOKUP 0x00000010
#define BUCKET_LOOKUP 0x00000010
uint32 bucket_lookup(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref);
#endif

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2001
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -38,13 +38,13 @@
typedef struct __c_p_data
{
struct timeval timestamp;
uint64 packets;
uint64 bytes;
struct timeval timestamp;
uint64 packets;
uint64 bytes;
}
c_p_data;
c_p_data;
#define COUNT_PACKETS 0x00000000
#define COUNT_PACKETS 0x00000000
uint32 count_packets(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data);
#endif

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 1999, 2000
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 1999, 2000
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -27,6 +27,8 @@
#else
#include <ddk/ntddk.h>
#include <net/ndis.h>
//#define PsGetCurrentProcess() IoGetCurrentProcess()
#define PsGetCurrentThread() ((PETHREAD) (KeGetCurrentThread()))
#endif
#include "debug.h"
@ -38,232 +40,229 @@
NTSTATUS
NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN Append)
{
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatus;
OBJECT_ATTRIBUTES ObjectAttributes;
PWCHAR PathPrefix;
USHORT PathLen;
UNICODE_STRING FullFileName;
ULONG FullFileNameLength;
PDEVICE_OBJECT fsdDevice;
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatus;
OBJECT_ATTRIBUTES ObjectAttributes;
PWCHAR PathPrefix;
USHORT PathLen;
UNICODE_STRING FullFileName;
ULONG FullFileNameLength;
PDEVICE_OBJECT fsdDevice;
FILE_STANDARD_INFORMATION StandardInfo;
FILE_STANDARD_INFORMATION StandardInfo;
IF_LOUD(DbgPrint("NPF: OpenDumpFile.\n");)
if(fileName->Buffer[0] == L'\\' &&
fileName->Buffer[1] == L'?' &&
fileName->Buffer[2] == L'?' &&
fileName->Buffer[3] == L'\\'
){
PathLen = 0;
}
else{
PathPrefix = L"\\??\\";
PathLen = 8;
}
// Insert the correct path prefix.
FullFileNameLength = PathLen + fileName->MaximumLength;
FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
FullFileNameLength,
'0DWA');
if (FullFileName.Buffer == NULL) {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
return ntStatus;
}
FullFileName.Length = PathLen;
FullFileName.MaximumLength = (USHORT)FullFileNameLength;
if(PathLen)
RtlMoveMemory (FullFileName.Buffer, PathPrefix, PathLen);
RtlAppendUnicodeStringToString (&FullFileName, fileName);
IF_LOUD(DbgPrint( "Packet: Attempting to open %wZ\n", &FullFileName);)
InitializeObjectAttributes ( &ObjectAttributes,
&FullFileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
// Create the dump file
ntStatus = ZwCreateFile( &Open->DumpFileHandle,
SYNCHRONIZE | FILE_WRITE_DATA,
&ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
(Append)?FILE_OPEN_IF:FILE_SUPERSEDE,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
if(fileName->Buffer[0] == L'\\' &&
fileName->Buffer[1] == L'?' &&
fileName->Buffer[2] == L'?' &&
fileName->Buffer[3] == L'\\'
){
PathLen = 0;
}
else{
PathPrefix = L"\\??\\";
PathLen = 8;
}
// Insert the correct path prefix.
FullFileNameLength = PathLen + fileName->MaximumLength;
#define NPF_TAG_FILENAME TAG('0', 'D', 'W', 'A')
FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
FullFileNameLength,
NPF_TAG_FILENAME);
if (FullFileName.Buffer == NULL) {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
return ntStatus;
}
FullFileName.Length = PathLen;
FullFileName.MaximumLength = (USHORT)FullFileNameLength;
if(PathLen)
RtlMoveMemory (FullFileName.Buffer, PathPrefix, PathLen);
RtlAppendUnicodeStringToString (&FullFileName, fileName);
IF_LOUD(DbgPrint( "Packet: Attempting to open %wZ\n", &FullFileName);)
InitializeObjectAttributes ( &ObjectAttributes,
&FullFileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
// Create the dump file
ntStatus = ZwCreateFile( &Open->DumpFileHandle,
SYNCHRONIZE | FILE_WRITE_DATA,
&ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
(Append)?FILE_OPEN_IF:FILE_SUPERSEDE,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
if ( !NT_SUCCESS( ntStatus ) )
{
IF_LOUD(DbgPrint("NPF: Error opening file %x\n", ntStatus);)
ExFreePool(FullFileName.Buffer);
Open->DumpFileHandle=NULL;
Open->DumpFileHandle=NULL;
ntStatus = STATUS_NO_SUCH_FILE;
return ntStatus;
}
ExFreePool(FullFileName.Buffer);
ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle,
FILE_WRITE_ACCESS,
ExFreePool(FullFileName.Buffer);
ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle,
FILE_WRITE_ACCESS,
#ifndef __GNUC__
*IoFileObjectType,
*IoFileObjectType,
#else
IoFileObjectType,
IoFileObjectType,
#endif
KernelMode,
&Open->DumpFileObject,
0);
KernelMode,
(PVOID)&Open->DumpFileObject,
0);
if ( !NT_SUCCESS( ntStatus ) )
{
IF_LOUD(DbgPrint("NPF: Error creating file, status=%x\n", ntStatus);)
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
ntStatus = STATUS_NO_SUCH_FILE;
return ntStatus;
}
fsdDevice = IoGetRelatedDeviceObject(Open->DumpFileObject);
IF_LOUD(DbgPrint("NPF: Dump: write file created succesfully, status=%d \n",ntStatus);)
IF_LOUD(DbgPrint("NPF: Dump: write file created succesfully, status=%d \n",ntStatus);)
return ntStatus;
}
return ntStatus;
}
//-------------------------------------------------------------------
NTSTATUS
NPF_StartDump(POPEN_INSTANCE Open)
{
NTSTATUS ntStatus;
struct packet_file_header hdr;
IO_STATUS_BLOCK IoStatus;
NTSTATUS ntStatus;
struct packet_file_header hdr;
IO_STATUS_BLOCK IoStatus;
NDIS_REQUEST pRequest;
ULONG MediaType;
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG MediaType;
OBJECT_ATTRIBUTES ObjectAttributes;
IF_LOUD(DbgPrint("NPF: StartDump.\n");)
// Init the file header
hdr.magic = TCPDUMP_MAGIC;
hdr.version_major = PCAP_VERSION_MAJOR;
hdr.version_minor = PCAP_VERSION_MINOR;
hdr.thiszone = 0; /*Currently not set*/
hdr.snaplen = 1514;
hdr.sigfigs = 0;
// Init the file header
hdr.magic = TCPDUMP_MAGIC;
hdr.version_major = PCAP_VERSION_MAJOR;
hdr.version_minor = PCAP_VERSION_MINOR;
hdr.thiszone = 0; /*Currently not set*/
hdr.snaplen = 1514;
hdr.sigfigs = 0;
// Detect the medium type
switch (Open->Medium){
case NdisMediumWan:
hdr.linktype = DLT_EN10MB;
break;
case NdisMedium802_3:
hdr.linktype = DLT_EN10MB;
break;
case NdisMediumFddi:
hdr.linktype = DLT_FDDI;
break;
case NdisMedium802_5:
hdr.linktype = DLT_IEEE802;
break;
case NdisMediumArcnet878_2:
hdr.linktype = DLT_ARCNET;
break;
case NdisMediumAtm:
hdr.linktype = DLT_ATM_RFC1483;
break;
default:
hdr.linktype = DLT_EN10MB;
}
// Detect the medium type
switch (Open->Medium){
case NdisMediumWan:
hdr.linktype = DLT_EN10MB;
break;
case NdisMedium802_3:
hdr.linktype = DLT_EN10MB;
break;
case NdisMediumFddi:
hdr.linktype = DLT_FDDI;
break;
case NdisMedium802_5:
hdr.linktype = DLT_IEEE802;
break;
case NdisMediumArcnet878_2:
hdr.linktype = DLT_ARCNET;
break;
case NdisMediumAtm:
hdr.linktype = DLT_ATM_RFC1483;
break;
default:
hdr.linktype = DLT_EN10MB;
}
// Write the header.
// We can use ZwWriteFile because we are in the context of the application
ntStatus = ZwWriteFile(Open->DumpFileHandle,
NULL,
NULL,
NULL,
&IoStatus,
&hdr,
sizeof(hdr),
NULL,
NULL );
// Write the header.
// We can use ZwWriteFile because we are in the context of the application
ntStatus = ZwWriteFile(Open->DumpFileHandle,
NULL,
NULL,
NULL,
&IoStatus,
&hdr,
sizeof(hdr),
NULL,
NULL );
if ( !NT_SUCCESS( ntStatus ) )
{
IF_LOUD(DbgPrint("NPF: Error dumping file %x\n", ntStatus);)
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
ntStatus = STATUS_NO_SUCH_FILE;
return ntStatus;
}
Open->DumpOffset.QuadPart=24;
ntStatus = PsCreateSystemThread(&Open->DumpThreadHandle,
THREAD_ALL_ACCESS,
(ACCESS_MASK)0L,
0,
0,
NPF_DumpThread,
Open);
Open->DumpOffset.QuadPart=24;
ntStatus = PsCreateSystemThread(&Open->DumpThreadHandle,
THREAD_ALL_ACCESS,
(ACCESS_MASK)0L,
0,
0,
(PKSTART_ROUTINE)NPF_DumpThread,
Open);
if ( !NT_SUCCESS( ntStatus ) )
{
IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);)
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
return ntStatus;
}
#ifndef __GNUC__
ntStatus = ObReferenceObjectByHandle(Open->DumpThreadHandle,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&Open->DumpThreadObject,
0);
#else
#endif
ntStatus = ObReferenceObjectByHandle(Open->DumpThreadHandle,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&Open->DumpThreadObject,
0);
if ( !NT_SUCCESS( ntStatus ) )
{
IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);)
ObDereferenceObject(Open->DumpFileObject);
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
ObDereferenceObject(Open->DumpFileObject);
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
return ntStatus;
}
return ntStatus;
return ntStatus;
}
//-------------------------------------------------------------------
@ -272,245 +271,250 @@ NPF_StartDump(POPEN_INSTANCE Open)
VOID NPF_DumpThread(POPEN_INSTANCE Open)
{
ULONG FrozenNic;
ULONG FrozenNic;
IF_LOUD(DbgPrint("NPF: In the work routine. Parameter = 0x%0x\n",Open);)
while(TRUE){
while(TRUE){
// Wait until some packets arrive or the timeout expires
NdisWaitEvent(&Open->DumpEvent, 5000);
// Wait until some packets arrive or the timeout expires
NdisWaitEvent(&Open->DumpEvent, 5000);
IF_LOUD(DbgPrint("NPF: Worker Thread - event signalled\n");)
if(Open->DumpLimitReached ||
Open->BufSize==0){ // BufSize=0 means that this instance was closed, or that the buffer is too
// small for any capture. In both cases it is better to end the dump
IF_LOUD(DbgPrint("NPF: Worker Thread - event signalled\n");)
if(Open->DumpLimitReached ||
Open->BufSize==0){ // BufSize=0 means that this instance was closed, or that the buffer is too
// small for any capture. In both cases it is better to end the dump
IF_LOUD(DbgPrint("NPF: Worker Thread - Exiting happily\n");)
IF_LOUD(DbgPrint("Thread: Dumpoffset=%I64d\n",Open->DumpOffset.QuadPart);)
IF_LOUD(DbgPrint("NPF: Worker Thread - Exiting happily\n");)
IF_LOUD(DbgPrint("Thread: Dumpoffset=%I64d\n",Open->DumpOffset.QuadPart);)
PsTerminateSystemThread(STATUS_SUCCESS);
return;
}
NdisResetEvent(&Open->DumpEvent);
PsTerminateSystemThread(STATUS_SUCCESS);
return;
}
NdisResetEvent(&Open->DumpEvent);
// Write the content of the buffer to the file
if(NPF_SaveCurrentBuffer(Open) != STATUS_SUCCESS){
PsTerminateSystemThread(STATUS_SUCCESS);
return;
}
}
// Write the content of the buffer to the file
if(NPF_SaveCurrentBuffer(Open) != STATUS_SUCCESS){
PsTerminateSystemThread(STATUS_SUCCESS);
return;
}
}
}
//-------------------------------------------------------------------
NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open)
{
UINT Thead;
UINT Ttail;
UINT TLastByte;
PUCHAR CurrBuff;
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatus;
PMDL lMdl;
UINT SizeToDump;
UINT Thead;
UINT Ttail;
UINT TLastByte;
PUCHAR CurrBuff;
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatus;
PMDL lMdl;
UINT SizeToDump;
Thead=Open->Bhead;
Ttail=Open->Btail;
TLastByte=Open->BLastByte;
Thead=Open->Bhead;
Ttail=Open->Btail;
TLastByte=Open->BLastByte;
IF_LOUD(DbgPrint("NPF: NPF_SaveCurrentBuffer.\n");)
// Get the address of the buffer
CurrBuff=Open->Buffer;
//
// Fill the application buffer
//
if( Ttail < Thead )
{
if(Open->MaxDumpBytes &&
(UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes)
{
// Size limit reached
UINT PktLen;
SizeToDump = 0;
// Scan the buffer to detect the exact amount of data to save
while(TRUE){
PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr);
if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes)
break;
SizeToDump += PktLen;
}
}
else
SizeToDump = TLastByte-Thead;
lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL);
if (lMdl == NULL)
{
// No memory: stop dump
IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");)
return STATUS_UNSUCCESSFUL;
}
MmBuildMdlForNonPagedPool(lMdl);
// Write to disk
NPF_WriteDumpFile(Open->DumpFileObject,
&Open->DumpOffset,
SizeToDump,
lMdl,
&IoStatus);
IoFreeMdl(lMdl);
if(!NT_SUCCESS(IoStatus.Status)){
// Error
return STATUS_UNSUCCESSFUL;
}
if(SizeToDump != TLastByte-Thead){
// Size limit reached.
Open->DumpLimitReached = TRUE;
// Awake the application
KeSetEvent(Open->ReadEvent,0,FALSE);
// Get the address of the buffer
CurrBuff=Open->Buffer;
//
// Fill the application buffer
//
if( Ttail < Thead )
{
if(Open->MaxDumpBytes &&
(UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes)
{
// Size limit reached
UINT PktLen;
SizeToDump = 0;
// Scan the buffer to detect the exact amount of data to save
while(TRUE){
PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr);
if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes)
break;
SizeToDump += PktLen;
}
}
else
SizeToDump = TLastByte-Thead;
lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL);
if (lMdl == NULL)
{
// No memory: stop dump
IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");)
return STATUS_UNSUCCESSFUL;
}
MmBuildMdlForNonPagedPool(lMdl);
// Write to disk
NPF_WriteDumpFile(Open->DumpFileObject,
&Open->DumpOffset,
SizeToDump,
lMdl,
&IoStatus);
IoFreeMdl(lMdl);
if(!NT_SUCCESS(IoStatus.Status)){
// Error
return STATUS_UNSUCCESSFUL;
}
if(SizeToDump != TLastByte-Thead){
// Size limit reached.
Open->DumpLimitReached = TRUE;
// Awake the application
KeSetEvent(Open->ReadEvent,0,FALSE);
return STATUS_UNSUCCESSFUL;
}
// Update the packet buffer
Open->DumpOffset.QuadPart+=(TLastByte-Thead);
Open->BLastByte=Ttail;
Open->Bhead=0;
}
return STATUS_UNSUCCESSFUL;
}
// Update the packet buffer
Open->DumpOffset.QuadPart+=(TLastByte-Thead);
Open->BLastByte=Ttail;
Open->Bhead=0;
}
if( Ttail > Thead ){
if(Open->MaxDumpBytes &&
(UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes)
{
// Size limit reached
UINT PktLen;
SizeToDump = 0;
// Scan the buffer to detect the exact amount of data to save
while(Thead + SizeToDump < Ttail){
if( Ttail > Thead ){
if(Open->MaxDumpBytes &&
(UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes)
{
// Size limit reached
UINT PktLen;
SizeToDump = 0;
// Scan the buffer to detect the exact amount of data to save
while(Thead + SizeToDump < Ttail){
PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr);
if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes)
break;
SizeToDump += PktLen;
}
}
else
SizeToDump = Ttail-Thead;
lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL);
if (lMdl == NULL)
{
// No memory: stop dump
IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");)
return STATUS_UNSUCCESSFUL;
}
MmBuildMdlForNonPagedPool(lMdl);
// Write to disk
NPF_WriteDumpFile(Open->DumpFileObject,
&Open->DumpOffset,
SizeToDump,
lMdl,
&IoStatus);
IoFreeMdl(lMdl);
if(!NT_SUCCESS(IoStatus.Status)){
// Error
return STATUS_UNSUCCESSFUL;
}
if(SizeToDump != Ttail-Thead){
// Size limit reached.
Open->DumpLimitReached = TRUE;
PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr);
if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes)
break;
SizeToDump += PktLen;
}
}
else
SizeToDump = Ttail-Thead;
lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL);
if (lMdl == NULL)
{
// No memory: stop dump
IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");)
return STATUS_UNSUCCESSFUL;
}
MmBuildMdlForNonPagedPool(lMdl);
// Write to disk
NPF_WriteDumpFile(Open->DumpFileObject,
&Open->DumpOffset,
SizeToDump,
lMdl,
&IoStatus);
IoFreeMdl(lMdl);
if(!NT_SUCCESS(IoStatus.Status)){
// Error
return STATUS_UNSUCCESSFUL;
}
if(SizeToDump != Ttail-Thead){
// Size limit reached.
Open->DumpLimitReached = TRUE;
// Awake the application
KeSetEvent(Open->ReadEvent,0,FALSE);
return STATUS_UNSUCCESSFUL;
}
// Update the packet buffer
Open->DumpOffset.QuadPart+=(Ttail-Thead);
Open->Bhead=Ttail;
}
// Awake the application
KeSetEvent(Open->ReadEvent,0,FALSE);
return STATUS_UNSUCCESSFUL;
}
// Update the packet buffer
Open->DumpOffset.QuadPart+=(Ttail-Thead);
Open->Bhead=Ttail;
}
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
//-------------------------------------------------------------------
NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open){
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatus;
PMDL WriteMdl;
PUCHAR VMBuff;
UINT VMBufLen;
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatus;
PMDL WriteMdl;
PUCHAR VMBuff;
UINT VMBufLen;
IF_LOUD(DbgPrint("NPF: NPF_CloseDumpFile.\n");)
IF_LOUD(DbgPrint("Dumpoffset=%d\n",Open->DumpOffset.QuadPart);)
DbgPrint("1\n");
// Consistency check
if(Open->DumpFileHandle == NULL)
return STATUS_UNSUCCESSFUL;
// Consistency check
if(Open->DumpFileHandle == NULL)
return STATUS_UNSUCCESSFUL;
DbgPrint("2\n");
ZwClose( Open->DumpFileHandle );
ZwClose( Open->DumpFileHandle );
ObDereferenceObject(Open->DumpFileObject);
ObDereferenceObject(Open->DumpFileObject);
/*
if(Open->DumpLimitReached == TRUE)
// Limit already reached: don't save the rest of the buffer.
return STATUS_SUCCESS;
if(Open->DumpLimitReached == TRUE)
// Limit already reached: don't save the rest of the buffer.
return STATUS_SUCCESS;
*/
DbgPrint("3\n");
NPF_OpenDumpFile(Open,&Open->DumpFileName, TRUE);
NPF_OpenDumpFile(Open,&Open->DumpFileName, TRUE);
// Flush the buffer to file
NPF_SaveCurrentBuffer(Open);
// Flush the buffer to file
NPF_SaveCurrentBuffer(Open);
// Close The file
ObDereferenceObject(Open->DumpFileObject);
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle = NULL;
// Close The file
ObDereferenceObject(Open->DumpFileObject);
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle = NULL;
ObDereferenceObject(Open->DumpFileObject);
ObDereferenceObject(Open->DumpFileObject);
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
//-------------------------------------------------------------------
static NTSTATUS PacketDumpCompletion(PDEVICE_OBJECT DeviceObject,
#ifndef __GNUC__
static NTSTATUS
#else
NTSTATUS STDCALL
#endif
PacketDumpCompletion(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
@ -527,10 +531,10 @@ static NTSTATUS PacketDumpCompletion(PDEVICE_OBJECT DeviceObject,
//-------------------------------------------------------------------
VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
PLARGE_INTEGER Offset,
ULONG Length,
PMDL Mdl,
PIO_STATUS_BLOCK IoStatusBlock)
PLARGE_INTEGER Offset,
ULONG Length,
PMDL Mdl,
PIO_STATUS_BLOCK IoStatusBlock)
{
PIRP irp;
KEVENT event;
@ -549,33 +553,33 @@ VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
IoStatusBlock->Information = 0;
return;
return;
}
irp->MdlAddress = Mdl;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject= FileObject;
irp->Tail.Overlay.OriginalFileObject= FileObject;
irp->RequestorMode = KernelMode;
// Indicate that this is a WRITE operation
irp->Flags = IRP_WRITE_OPERATION;
irp->Flags = IRP_WRITE_OPERATION;
// Set up the next I/O stack location
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_WRITE;
ioStackLocation->MinorFunction = 0;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
IoSetCompletionRoutine(irp, PacketDumpCompletion, 0, TRUE, TRUE, TRUE);
ioStackLocation->Parameters.Write.Length = Length;
IoSetCompletionRoutine(irp, PacketDumpCompletion, 0, TRUE, TRUE, TRUE);
ioStackLocation->Parameters.Write.Length = Length;
ioStackLocation->Parameters.Write.ByteOffset = *Offset;
// Send it on. Ignore the return code
(void) IoCallDriver(fsdDevice, irp);
// Wait for the I/O to complete.
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
@ -583,5 +587,4 @@ VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
IoFreeIrp(irp);
return;
}

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2001
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -55,10 +55,10 @@
/*! \brief A stream of X86 binary code.*/
typedef struct binary_stream{
INT cur_ip; ///< Current X86 instruction pointer.
INT bpf_pc; ///< Current BPF instruction pointer, i.e. position in the BPF program reached by the jitter.
PCHAR ibuf; ///< Instruction buffer, contains the X86 generated code.
PUINT refs; ///< Jumps reference table.
INT cur_ip; ///< Current X86 instruction pointer.
INT bpf_pc; ///< Current BPF instruction pointer, i.e. position in the BPF program reached by the jitter.
PCHAR ibuf; ///< Instruction buffer, contains the X86 generated code.
PUINT refs; ///< Jumps reference table.
}binary_stream;
@ -81,8 +81,8 @@ typedef void (*emit_func)(binary_stream *stream, ULONG value, UINT n);
/*! \brief Structure describing a x86 filtering program created by the jitter.*/
typedef struct JIT_BPF_Filter{
BPF_filter_function Function; ///< The x86 filtering binary, in the form of a BPF_filter_function.
PINT mem;
BPF_filter_function Function; ///< The x86 filtering binary, in the form of a BPF_filter_function.
PINT mem;
}
JIT_BPF_Filter;
@ -373,7 +373,7 @@ JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins);
through the instruction macros defined in jitter.h it is able to create an function directly executable
by NPF.
*/
BPF_filter_function BPFtoX86(struct bpf_insn *prog, UINT nins, INT *mem);
BPF_filter_function BPFtoX86(struct bpf_insn *ins, UINT nins, INT *mem);
/*!
\brief Deletes a filtering function that was previously created by BPF_jitter().
\param Filter The filter to destroy.

View file

@ -22,6 +22,7 @@
#include "tme.h"
#include "memory_t.h"
#ifdef _USE_SW_FUNCS_
int32 SW_LONG_AT(void *b, uint32 c)
{
@ -62,4 +63,6 @@ VOID SW_ULONG_ASSIGN(void *dst, uint32 src)
}
#endif /*_USE_SW_FUNCS_*/
void assert(void* assert, const char* file, int line, void* msg) { };

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2001
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -22,20 +22,20 @@
#ifndef __memory_t
#define __memory_t
#define uint8 UCHAR
#define int8 CHAR
#define uint16 USHORT
#define int16 SHORT
#define uint32 ULONG
#define int32 LONG
#define uint64 ULONGLONG
#define int64 LONGLONG
#define uint8 UCHAR
#define int8 CHAR
#define uint16 USHORT
#define int16 SHORT
#define uint32 ULONG
#define int32 LONG
#define uint64 ULONGLONG
#define int64 LONGLONG
/*memory type*/
typedef struct __MEM_TYPE
{
uint8 *buffer;
uint32 size;
uint8 *buffer;
uint32 size;
} MEM_TYPE, *PMEM_TYPE;
#define LONG_AT(base,offset) (*(int32*)((uint8*)base+(uint32)offset))
@ -47,66 +47,71 @@ typedef struct __MEM_TYPE
#define USHORT_AT(base,offset) (*(uint16*)((uint8*)base+(uint32)offset))
#ifdef __GNUC__
#define __inline inline
#define _USE_SW_FUNCS_
#endif
int32 SW_LONG_AT(void *b, uint32 c);
uint32 SW_ULONG_AT(void *b, uint32 c);
int16 SW_SHORT_AT(void *b, uint32 os);
uint16 SW_USHORT_AT(void *b, uint32 os);
VOID SW_ULONG_ASSIGN(void *dst, uint32 src);
#ifdef _USE_SW_FUNCS_
#else /* __GNUC__ */
inline int32 SW_LONG_AT(void *b, uint32 c);
inline uint32 SW_ULONG_AT(void *b, uint32 c);
inline int16 SW_SHORT_AT(void *b, uint32 os);
inline uint16 SW_USHORT_AT(void *b, uint32 os);
inline VOID SW_ULONG_ASSIGN(void *dst, uint32 src);
#else /*_USE_SW_FUNCS_*/
__inline int32 SW_LONG_AT(void *b, uint32 c)
{
return ((int32)*((uint8 *)b+c)<<24|
(int32)*((uint8 *)b+c+1)<<16|
(int32)*((uint8 *)b+c+2)<<8|
(int32)*((uint8 *)b+c+3)<<0);
return ((int32)*((uint8 *)b+c)<<24|
(int32)*((uint8 *)b+c+1)<<16|
(int32)*((uint8 *)b+c+2)<<8|
(int32)*((uint8 *)b+c+3)<<0);
}
__inline uint32 SW_ULONG_AT(void *b, uint32 c)
{
return ((uint32)*((uint8 *)b+c)<<24|
(uint32)*((uint8 *)b+c+1)<<16|
(uint32)*((uint8 *)b+c+2)<<8|
(uint32)*((uint8 *)b+c+3)<<0);
return ((uint32)*((uint8 *)b+c)<<24|
(uint32)*((uint8 *)b+c+1)<<16|
(uint32)*((uint8 *)b+c+2)<<8|
(uint32)*((uint8 *)b+c+3)<<0);
}
__inline int16 SW_SHORT_AT(void *b, uint32 os)
{
return ((int16)
((int16)*((uint8 *)b+os+0)<<8|
(int16)*((uint8 *)b+os+1)<<0));
return ((int16)
((int16)*((uint8 *)b+os+0)<<8|
(int16)*((uint8 *)b+os+1)<<0));
}
__inline uint16 SW_USHORT_AT(void *b, uint32 os)
{
return ((uint16)
((uint16)*((uint8 *)b+os+0)<<8|
(uint16)*((uint8 *)b+os+1)<<0));
return ((uint16)
((uint16)*((uint8 *)b+os+0)<<8|
(uint16)*((uint8 *)b+os+1)<<0));
}
__inline VOID SW_ULONG_ASSIGN(void *dst, uint32 src)
{
*((uint8*)dst+0)=*((uint8*)&src+3);
*((uint8*)dst+1)=*((uint8*)&src+2);
*((uint8*)dst+2)=*((uint8*)&src+1);
*((uint8*)dst+3)=*((uint8*)&src+0);
*((uint8*)dst+0)=*((uint8*)&src+3);
*((uint8*)dst+1)=*((uint8*)&src+2);
*((uint8*)dst+2)=*((uint8*)&src+1);
*((uint8*)dst+3)=*((uint8*)&src+0);
}
#endif /* __GNUC__ */
#endif /*_USE_SW_FUNCS_*/
#ifdef WIN_NT_DRIVER
#define ALLOCATE_MEMORY(dest,type,amount) \
(dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount));
(dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount));
#define ALLOCATE_ZERO_MEMORY(dest,type,amount) \
{ \
(dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount)); \
if ((dest)!=NULL) \
RtlZeroMemory((dest),sizeof(type)*(amount)); \
}
{ \
(dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount)); \
if ((dest)!=NULL) \
RtlZeroMemory((dest),sizeof(type)*(amount)); \
}
#define FREE_MEMORY(dest) ExFreePool(dest);
#define ZERO_MEMORY(dest,amount) RtlZeroMemory(dest,amount);

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2001
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -36,10 +36,10 @@
#endif
#define NORMAL_LUT_W_INSERT 0x00000000
#define NORMAL_LUT_W_INSERT 0x00000000
uint32 normal_lut_w_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref);
#define NORMAL_LUT_WO_INSERT 0x00000001
#define NORMAL_LUT_WO_INSERT 0x00000001
uint32 normal_lut_wo_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref);
#define DUMMY_INSERT 1234
#define DUMMY_INSERT 1234
#endif

View file

@ -11,7 +11,7 @@ struct _PACKET_OID_DATA {
ULONG Oid;
ULONG Length;
UCHAR Data[1];
};
};
typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;

View file

@ -67,8 +67,7 @@ NDIS_SPIN_LOCK Opened_Instances_Lock;
//-------------------------------------------------------------------
NTSTATUS
NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
NTSTATUS NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PDEVICE_EXTENSION DeviceExtension;
@ -84,7 +83,6 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
PLIST_ENTRY PacketListEntry;
PCHAR EvName;
IF_LOUD(DbgPrint("NPF: OpenAdapter\n");)
DeviceExtension = DeviceObject->DeviceExtension;
@ -93,7 +91,8 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
IrpSp = IoGetCurrentIrpStackLocation(Irp);
// allocate some memory for the open structure
Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), '0OWA');
#define NPF_TAG_OPENSTRUCT TAG('0', 'O', 'W', 'A')
Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), NPF_TAG_OPENSTRUCT);
if (Open==NULL) {
@ -109,7 +108,8 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
);
EvName=ExAllocatePoolWithTag(NonPagedPool, sizeof(L"\\BaseNamedObjects\\NPF0000000000"), '1OWA');
#define NPF_TAG_EVNAME TAG('1', 'O', 'W', 'A')
EvName=ExAllocatePoolWithTag(NonPagedPool, sizeof(L"\\BaseNamedObjects\\NPF0000000000"), NPF_TAG_EVNAME);
if (EvName==NULL) {
// no memory
@ -187,7 +187,8 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
InitializeListHead(&Open->RequestList);
// Initializes the extended memory of the NPF machine
Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, '2OWA');
#define NPF_TAG_MACHINE TAG('2', 'O', 'W', 'A')
Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, NPF_TAG_MACHINE);
if((Open->mem_ex.buffer) == NULL)
{
// no memory
@ -208,7 +209,7 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Open->Buffer = NULL;
Open->Bhead = 0;
Open->Btail = 0;
Open->BLastByte = 0;
(INT)Open->BLastByte = -1;
Open->Dropped = 0; //reset the dropped packets counter
Open->Received = 0; //reset the received packets counter
Open->Accepted = 0; //reset the accepted packets counter
@ -225,6 +226,7 @@ NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Open->DumpFileHandle = NULL;
Open->tme.active = TME_NONE_ACTIVE;
Open->DumpLimitReached = FALSE;
Open->MaxFrameSize = 0;
//allocate the spinlock for the statistic counters
NdisAllocateSpinLock(&Open->CountersLock);
@ -282,8 +284,12 @@ VOID NPF_OpenAdapterComplete(
IN NDIS_STATUS OpenErrorStatus)
{
PIRP Irp;
POPEN_INSTANCE Open;
PIRP Irp;
POPEN_INSTANCE Open;
PLIST_ENTRY RequestListEntry;
PINTERNAL_REQUEST MaxSizeReq;
NDIS_STATUS ReqStatus;
IF_LOUD(DbgPrint("NPF: OpenAdapterComplete\n");)
@ -306,6 +312,9 @@ VOID NPF_OpenAdapterComplete(
ExFreePool(Open->ReadEventName.Buffer);
ZwClose(Open->ReadEventHandle);
ExFreePool(Open);
}
else {
@ -318,6 +327,47 @@ VOID NPF_OpenAdapterComplete(
// Get the absolute value of the system boot time.
// This is used for timestamp conversion.
TIME_SYNCHRONIZE(&G_Start_Time);
// Extract a request from the list of free ones
RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList, &Open->RequestSpinLock);
if (RequestListEntry == NULL)
{
Open->MaxFrameSize = 1514; // Assume Ethernet
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return;
}
MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement);
MaxSizeReq->Irp = Irp;
MaxSizeReq->Internal = TRUE;
MaxSizeReq->Request.RequestType = NdisRequestQueryInformation;
MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE;
MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = &Open->MaxFrameSize;
MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = 4;
// submit the request
NdisRequest(
&ReqStatus,
Open->AdapterHandle,
&MaxSizeReq->Request);
if (ReqStatus != NDIS_STATUS_PENDING) {
NPF_RequestComplete(Open, &MaxSizeReq->Request, ReqStatus);
}
return;
}
Irp->IoStatus.Status = Status;
@ -397,7 +447,6 @@ NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
// If this instance is in dump mode, complete the dump and close the file
if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL){
#ifndef __GNUC__
NTSTATUS wres;
ThreadDelay.QuadPart = -50000000;
@ -413,7 +462,6 @@ NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
// Flush and close the dump file
NPF_CloseDumpFile(Open);
#endif
}
// Destroy the read Event

View file

@ -82,6 +82,9 @@ extern NDIS_SPIN_LOCK Opened_Instances_Lock;
// Packet Driver's entry routine.
//
NTSTATUS
#ifdef __GNUC__
STDCALL
#endif
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
@ -111,7 +114,7 @@ DriverEntry(
return STATUS_IMAGE_MP_UP_MISMATCH;
}
IF_LOUD(DbgPrint("\n\nPacket: DriverEntry\n");)
IF_LOUD(DbgPrint("Packet: DriverEntry\n");)
RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
@ -123,17 +126,24 @@ DriverEntry(
ProtocolChar.MinorNdisVersion = 0;
#ifndef __GNUC__
ProtocolChar.Reserved = 0;
#else
ProtocolChar.u1.Reserved = 0;
#endif
ProtocolChar.OpenAdapterCompleteHandler = NPF_OpenAdapterComplete;
ProtocolChar.CloseAdapterCompleteHandler = NPF_CloseAdapterComplete;
#ifndef __GNUC__
ProtocolChar.SendCompleteHandler = NPF_SendComplete;
ProtocolChar.TransferDataCompleteHandler = NPF_TransferDataComplete;
#else
ProtocolChar.u2.SendCompleteHandler = NPF_SendComplete;
ProtocolChar.u3.TransferDataCompleteHandler = NPF_TransferDataComplete;
#endif
ProtocolChar.ResetCompleteHandler = NPF_ResetComplete;
ProtocolChar.RequestCompleteHandler = NPF_RequestComplete;
#ifndef __GNUC__
ProtocolChar.ReceiveHandler = NPF_tap;
#else
ProtocolChar.u4.ReceiveHandler = NPF_tap;
#endif
ProtocolChar.ReceiveCompleteHandler = NPF_ReceiveComplete;
ProtocolChar.StatusHandler = NPF_Status;
@ -170,6 +180,7 @@ DriverEntry(
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NPF_IoControl;
DriverObject->DriverUnload = NPF_Unload;
/*
// Get the name of the Packet driver and the name of the NIC driver
// to bind to from the registry
Status=NPF_ReadRegistry(
@ -181,7 +192,7 @@ DriverEntry(
if (Status != STATUS_SUCCESS) {
IF_LOUD(DbgPrint("Trying dynamic binding\n");)
*/
bindP = getAdaptersList();
if (bindP == NULL) {
@ -198,7 +209,6 @@ DriverEntry(
bindT = (WCHAR*)(tcpBindingsP->Data);
} else {
bindT = bindP;
}
for (; *bindT != UNICODE_NULL; bindT += (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)) {
@ -207,13 +217,10 @@ DriverEntry(
}
return STATUS_SUCCESS;
/*
}
BindStringSave = BindString;
ExportStringSave = ExportString;
//
// create a device object for each entry
//
@ -223,23 +230,16 @@ DriverEntry(
//
RtlInitUnicodeString(
&MacDriverName,
BindString
);
BindString);
RtlInitUnicodeString(
&UnicodeDeviceName,
ExportString
);
ExportString);
//
// Advance to the next string of the MULTI_SZ string
//
BindString += (MacDriverName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
ExportString += (UnicodeDeviceName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
IF_LOUD(DbgPrint("NPF: DeviceName=%ws MacName=%ws\n",UnicodeDeviceName.Buffer,MacDriverName.Buffer);)
//
// Create the device object
//
@ -250,40 +250,25 @@ DriverEntry(
FILE_DEVICE_PROTOCOL,
0,
FALSE,
&DeviceObject
);
&DeviceObject);
if (Status != STATUS_SUCCESS) {
IF_LOUD(DbgPrint("NPF: IoCreateDevice() failed:\n");)
break;
}
DevicesCreated++;
DeviceObject->Flags |= DO_DIRECT_IO;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
DeviceExtension->DeviceObject = DeviceObject;
//
// Save the the name of the MAC driver to open in the Device Extension
//
DeviceExtension->AdapterName=MacDriverName;
if (DevicesCreated == 1) {
DeviceExtension->BindString = NULL;
DeviceExtension->ExportString = NULL;
}
DeviceExtension->NdisProtocolHandle=NdisProtocolHandle;
}
if (DevicesCreated > 0) {
//
// Managed to create at least one device.
@ -291,11 +276,9 @@ DriverEntry(
IF_LOUD(DbgPrint("NPF: Managed to create at least one device.\n");)
return STATUS_SUCCESS;
}
ExFreePool(BindStringSave);
ExFreePool(ExportStringSave);
*/
RegistryError:
IF_LOUD(DbgPrint("NPF: RegistryError: calling NdisDeregisterProtocol()\n");)
@ -320,7 +303,8 @@ PWCHAR getAdaptersList(void)
HANDLE keyHandle;
UINT BufPos=0;
PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, 4096, '0PWA');
#define NPF_TAG_DEVICENAME TAG('0', 'P', 'W', 'A')
PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, 4096, NPF_TAG_DEVICENAME);
if (DeviceNames == NULL) {
IF_LOUD(DbgPrint("Unable the allocate the buffer for the list of the network adapters\n");)
@ -331,7 +315,10 @@ PWCHAR getAdaptersList(void)
OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);
if (!NT_SUCCESS(status)) {
IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);)
//IF_LOUD(DbgPrint("Status of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);)
IF_LOUD(DbgPrint("Status of %x opening %ws\n", status, AdapterListKey.Buffer);)
} else { //OK
ULONG resultLength;
KEY_VALUE_PARTIAL_INFORMATION valueInfo;
@ -389,7 +376,8 @@ PWCHAR getAdaptersList(void)
IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);)
} else { // We know how big it needs to be.
ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag(PagedPool, valueInfoLength, '1PWA');
#define NPF_TAG_KEYVALUE TAG('1', 'P', 'W', 'A')
PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag(PagedPool, valueInfoLength, NPF_TAG_KEYVALUE);
if (valueInfoP != NULL) {
status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey,
KeyValuePartialInformation,
@ -458,8 +446,9 @@ PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(void)
IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);)
} else { // We know how big it needs to be.
ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
#define NPF_TAG_KEYVALUE2 TAG('2', 'P', 'W', 'A')
PKEY_VALUE_PARTIAL_INFORMATION valueInfoP =
(PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, valueInfoLength, '2PWA');
(PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, valueInfoLength, NPF_TAG_KEYVALUE2);
if (valueInfoP != NULL) {
status = ZwQueryValueKey(keyHandle, &bindValueName,
@ -506,54 +495,100 @@ PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(void)
BOOLEAN createDevice(IN OUT PDRIVER_OBJECT adriverObjectP,
IN PUNICODE_STRING amacNameP, NDIS_HANDLE aProtoHandle)
{
NTSTATUS status;
PDEVICE_OBJECT devObjP;
UNICODE_STRING deviceName;
BOOLEAN result = FALSE;
NTSTATUS status;
PDEVICE_OBJECT devObjP;
UNICODE_STRING deviceName;
UNICODE_STRING deviceSymLink;
IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer);)
if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer,
IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer););
if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer,
devicePrefix.Length) < devicePrefix.Length) {
return result;
}
return FALSE;
}
deviceName.Length = 0;
deviceName.MaximumLength = (USHORT)(amacNameP->Length + NPF_Prefix.Length + sizeof(UNICODE_NULL));
deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, '3PWA');
deviceName.Length = 0;
deviceName.MaximumLength = (USHORT)(amacNameP->Length + NPF_Prefix.Length + sizeof(UNICODE_NULL));
#define NPF_TAG_DEVICENAMEBUF TAG('3', 'P', 'W', 'A')
deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, NPF_TAG_DEVICENAMEBUF);
if (deviceName.Buffer != NULL) {
if (deviceName.Buffer == NULL)
return FALSE;
deviceSymLink.Length = 0;
deviceSymLink.MaximumLength =(USHORT)(amacNameP->Length-devicePrefix.Length
+ symbolicLinkPrefix.Length
+ NPF_Prefix.Length
+ sizeof(UNICODE_NULL));
#define NPF_TAG_SYMLINKBUF TAG('3', 'P', 'W', 'A')
deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, NPF_TAG_SYMLINKBUF);
if (deviceSymLink.Buffer == NULL)
{
ExFreePool(deviceName.Buffer);
return FALSE;
}
RtlAppendUnicodeStringToString(&deviceName, &devicePrefix);
RtlAppendUnicodeStringToString(&deviceName, &NPF_Prefix);
RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer +
devicePrefix.Length / sizeof(WCHAR));
IF_LOUD(DbgPrint("\n\nDevice name: %ws\n", deviceName.Buffer);)
RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix);
RtlAppendUnicodeStringToString(&deviceSymLink, &NPF_Prefix);
RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer +
devicePrefix.Length / sizeof(WCHAR));
IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);)
status = IoCreateDevice(adriverObjectP, sizeof(PDEVICE_EXTENSION),
&deviceName, FILE_DEVICE_TRANSPORT, 0, FALSE,
&devObjP);
status = IoCreateDevice(adriverObjectP,
sizeof(PDEVICE_EXTENSION),
&deviceName,
FILE_DEVICE_TRANSPORT,
0,
FALSE,
&devObjP);
if (NT_SUCCESS(status)) {
PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension;
PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension;
IF_LOUD(DbgPrint("\n\nDevice created succesfully\n");)
IF_LOUD(DbgPrint("Device created successfully\n"););
devObjP->Flags |= DO_DIRECT_IO;
devExtP->DeviceObject = devObjP;
RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer);
devExtP->BindString = NULL;
devExtP->ExportString = NULL;
devExtP->NdisProtocolHandle=aProtoHandle;
devObjP->Flags |= DO_DIRECT_IO;
RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer);
devExtP->NdisProtocolHandle=aProtoHandle;
IF_LOUD(DbgPrint("Trying to create SymLink %ws\n",deviceSymLink.Buffer););
if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) != STATUS_SUCCESS) {
IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer););
ExFreePool(deviceName.Buffer);
ExFreePool(deviceSymLink.Buffer);
devExtP->ExportString = NULL;
return FALSE;
}
else IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status););
IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer););
ExFreePool(deviceName.Buffer);
}
devExtP->ExportString = deviceSymLink.Buffer;
ExFreePool(deviceName.Buffer);
return TRUE;
}
return result;
else
{
IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status););
ExFreePool(deviceName.Buffer);
ExFreePool(deviceSymLink.Buffer);
return FALSE;
}
}
//-------------------------------------------------------------------
@ -561,7 +596,6 @@ BOOLEAN createDevice(IN OUT PDRIVER_OBJECT adriverObjectP,
VOID
NPF_Unload(IN PDRIVER_OBJECT DriverObject)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT OldDeviceObject;
PDEVICE_EXTENSION DeviceExtension;
@ -569,27 +603,38 @@ NPF_Unload(IN PDRIVER_OBJECT DriverObject)
NDIS_HANDLE NdisProtocolHandle;
NDIS_STATUS Status;
IF_LOUD(DbgPrint("NPF: Unload\n");)
NDIS_STRING SymLink;
IF_LOUD(DbgPrint("NPF: Unload\n"););
DeviceObject = DriverObject->DeviceObject;
while (DeviceObject != NULL) {
DeviceExtension = DeviceObject->DeviceExtension;
NdisProtocolHandle=DeviceExtension->NdisProtocolHandle;
OldDeviceObject=DeviceObject;
DeviceObject=DeviceObject->NextDevice;
DeviceExtension = OldDeviceObject->DeviceExtension;
NdisProtocolHandle=DeviceExtension->NdisProtocolHandle;
IF_LOUD(DbgPrint("Deleting Adapter %ws, Protocol Handle=%x, Device Obj=%x (%x)\n",
DeviceExtension->AdapterName.Buffer,
NdisProtocolHandle,
DeviceObject,
OldDeviceObject);)
OldDeviceObject););
if (DeviceExtension->ExportString)
{
RtlInitUnicodeString(&SymLink , DeviceExtension->ExportString);
IF_LOUD(DbgPrint("Deleting SymLink at %p\n", SymLink.Buffer););
IoDeleteSymbolicLink(&SymLink);
ExFreePool(DeviceExtension->ExportString);
}
IoDeleteDevice(OldDeviceObject);
}
NdisDeregisterProtocol(
@ -599,7 +644,6 @@ NPF_Unload(IN PDRIVER_OBJECT DriverObject)
// Free the adapters names
ExFreePool( bindP );
}
//-------------------------------------------------------------------
@ -754,7 +798,8 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
// Allocate the memory to contain the new filter program
// We could need the original BPF binary if we are forced to use bpf_filter_with_2_buffers()
TmpBPFProgram=(PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), '4PWA');
#define NPF_TAG_BPFPROG TAG('4', 'P', 'W', 'A')
TmpBPFProgram=(PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), NPF_TAG_BPFPROG);
if (TmpBPFProgram==NULL){
IF_LOUD(DbgPrint("Error - No memory for filter");)
// no memory
@ -766,11 +811,8 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
Open->bpfprogram=TmpBPFProgram;
// Create the new JIT filter function
if(!IsExtendedFilter)
if((Open->Filter=BPF_jitter((struct bpf_insn*)Open->bpfprogram,cnt))
== NULL)
{
if((Open->Filter=BPF_jitter((struct bpf_insn*)Open->bpfprogram,cnt)) == NULL) {
IF_LOUD(DbgPrint("Error jittering filter");)
EXIT_FAILURE(0);
}
@ -778,9 +820,10 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
//return
Open->Bhead = 0;
Open->Btail = 0;
Open->BLastByte = 0;
(INT)Open->BLastByte = -1;
Open->Received = 0;
Open->Dropped = 0;
Open->Accepted = 0;
EXIT_SUCCESS(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
@ -839,7 +882,8 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
}
// Allocate the buffer that will contain the string
DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, '5PWA');
#define NPF_TAG_DUMPNAMEBUF TAG('5', 'P', 'W', 'A')
DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, NPF_TAG_DUMPNAMEBUF);
if(DumpNameBuff==NULL || Open->DumpFileName.Buffer!=NULL){
IF_LOUD(DbgPrint("NPF: unable to allocate the dump filename: not enough memory or name already set\n");)
EXIT_FAILURE(0);
@ -908,7 +952,8 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
}
// Allocate the new buffer
if(dim!=0){
tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, '6PWA');
#define NPF_TAG_TPOINTER TAG('6', 'P', 'W', 'A')
tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, NPF_TAG_TPOINTER);
if (tpointer==NULL) {
// no memory
Open->BufSize = 0;
@ -922,7 +967,7 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
Open->Buffer = tpointer;
Open->Bhead = 0;
Open->Btail = 0;
Open->BLastByte = 0;
(INT)Open->BLastByte = -1;
Open->BufSize = (UINT)dim;
EXIT_SUCCESS(dim);
@ -990,6 +1035,8 @@ NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement);
pRequest->Irp=Irp;
pRequest->Internal = FALSE;
//
// See if it is an Ndis request
@ -1094,11 +1141,18 @@ NPF_RequestComplete(
pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
Irp=pRequest->Irp;
if(Irp == NULL){
if(pRequest->Internal == TRUE){
// Put the request in the list of the free ones
ExInterlockedInsertTailList(&Open->RequestList, &pRequest->ListElement, &Open->RequestSpinLock);
if(Status != NDIS_STATUS_SUCCESS)
Open->MaxFrameSize = 1514; // Assume Ethernet
// We always return success, because the adapter has been already opened
Irp->IoStatus.Status = NDIS_STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return;
}
@ -1138,7 +1192,7 @@ NPF_RequestComplete(
IoCompleteRequest(Irp, IO_NO_INCREMENT);
// Unlock the IOCTL call
// Unlock the caller
NdisSetEvent(&Open->IOEvent);
return;
@ -1200,7 +1254,8 @@ NPF_ReadRegistry(
PWCHAR Path;
Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), '7PWA');
#define NPF_TAG_PATH TAG('7', 'P', 'W', 'A')
Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), NPF_TAG_PATH);
if (Path == NULL) {
IF_LOUD(DbgPrint("\nPacketReadRegistry: returing STATUS_INSUFFICIENT_RESOURCES\n");)
@ -1311,7 +1366,8 @@ NPF_QueryRegistryRoutine(
}
Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, '8PWA');
#define NPF_TAG_REGBUF TAG('8', 'P', 'W', 'A')
Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, NPF_TAG_REGBUF);
if (Buffer==NULL) {

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 1999, 2000
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -30,11 +30,15 @@
#ifndef __PACKET_INCLUDE______
#define __PACKET_INCLUDE______
#define NTKERNEL ///< Forces the compilation of the jitter with kernel calls
#define NTKERNEL ///< Forces the compilation of the jitter with kernel calls
#ifdef __GNUC__
#undef EXIT_SUCCESS
#undef EXIT_FAILURE
#define UNICODE_NULL ((WCHAR)0) // winnt
#include "win_bpf.h"
#include <internal/ps.h>
#endif
#include "jitter.h"
#include "tme.h"
@ -42,8 +46,10 @@
#define MAX_REQUESTS 32 ///< Maximum number of simultaneous IOCTL requests.
#define Packet_ALIGNMENT sizeof(int) ///< Alignment macro. Defines the alignment size.
#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) ///< Alignment macro. Rounds up to the next
///< even multiple of Packet_ALIGNMENT.
#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) ///< Alignment macro. Rounds up to the next
///< even multiple of Packet_ALIGNMENT.
/***************************/
/* IOCTLs */
/***************************/
@ -56,7 +62,7 @@
and resets all the parameters associated with the buffer in the OPEN_INSTANCE structure. The currently
buffered packets are lost.
*/
#define BIOCSETBUFFERSIZE 9592
#define BIOCSETBUFFERSIZE 9592
/*!
\brief IOCTL code: set packet filtering program.
@ -68,7 +74,7 @@
every incoming packet. This command also empties the circular buffer used by current instance
to store packets. This is done to avoid the presence in the buffer of packets that do not match the filter.
*/
#define BIOCSETF 9030
#define BIOCSETF 9030
/*!
\brief IOCTL code: get the capture stats
@ -83,7 +89,7 @@
This command sets the maximum timeout after which a read is released, also if no data packets were received.
*/
#define BIOCSRTIMEOUT 7416
#define BIOCSRTIMEOUT 7416
/*!
\brief IOCTL code: set working mode
@ -92,7 +98,7 @@
buffer associated with the IOCTL command, can be #MODE_CAPT for capture mode (the default), #MODE_STAT for
statistical mode or #MODE_DUMP for dump mode.
*/
#define BIOCSMODE 7412
#define BIOCSMODE 7412
/*!
\brief IOCTL code: set number of physical repetions of every packet written by the app
@ -100,28 +106,28 @@
Sets the number of times a single write call must be repeated. This command sets the OPEN_INSTANCE::Nwrites
member, and is used to implement the 'multiple write' feature of the driver.
*/
#define BIOCSWRITEREP 7413
#define BIOCSWRITEREP 7413
/*!
\brief IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call
This command sets the OPEN_INSTANCE::MinToCopy member.
*/
#define BIOCSMINTOCOPY 7414
#define BIOCSMINTOCOPY 7414
/*!
\brief IOCTL code: set an OID value
This IOCTL is used to perform an OID set operation on the NIC driver.
*/
#define BIOCSETOID 2147483648
#define BIOCSETOID 2147483648
/*!
\brief IOCTL code: get an OID value
This IOCTL is used to perform an OID get operation on the NIC driver.
*/
#define BIOCQUERYOID 2147483652
#define BIOCQUERYOID 2147483652
/*!
\brief IOCTL code: set the name of a the file used by kernel dump mode
@ -176,20 +182,20 @@
#define BIOCISDUMPENDED 7411
// Working modes
#define MODE_CAPT 0x0 ///< Capture working mode
#define MODE_STAT 0x1 ///< Statistical working mode
#define MODE_MON 0x2 ///< Kernel monitoring mode
#define MODE_DUMP 0x10 ///< Kernel dump working mode
#define MODE_CAPT 0x0 ///< Capture working mode
#define MODE_STAT 0x1 ///< Statistical working mode
#define MODE_MON 0x2 ///< Kernel monitoring mode
#define MODE_DUMP 0x10 ///< Kernel dump working mode
#define IMMEDIATE 1 ///< Immediate timeout. Forces a read call to return immediately.
#define IMMEDIATE 1 ///< Immediate timeout. Forces a read call to return immediately.
// The following definitions are used to provide compatibility
// of the dump files with the ones of libpcap
#define TCPDUMP_MAGIC 0xa1b2c3d4 ///< Libpcap magic number. Used by programs like tcpdump to recognize a driver's generated dump file.
#define PCAP_VERSION_MAJOR 2 ///< Major libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file.
#define PCAP_VERSION_MINOR 4 ///< Minor libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file.
#define TCPDUMP_MAGIC 0xa1b2c3d4 ///< Libpcap magic number. Used by programs like tcpdump to recognize a driver's generated dump file.
#define PCAP_VERSION_MAJOR 2 ///< Major libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file.
#define PCAP_VERSION_MINOR 4 ///< Minor libpcap version of the dump file. Used by programs like tcpdump to recognize a driver's generated dump file.
/*!
\brief Header of a libpcap dump file.
@ -198,13 +204,13 @@
*/
struct packet_file_header
{
UINT magic; ///< Libpcap magic number
USHORT version_major; ///< Libpcap major version
USHORT version_minor; ///< Libpcap minor version
UINT thiszone; ///< Gmt to local correction
UINT sigfigs; ///< Accuracy of timestamps
UINT snaplen; ///< Length of the max saved portion of each packet
UINT linktype; ///< Data link type (DLT_*). See win_bpf.h for details.
UINT magic; ///< Libpcap magic number
USHORT version_major; ///< Libpcap major version
USHORT version_minor; ///< Libpcap minor version
UINT thiszone; ///< Gmt to local correction
UINT sigfigs; ///< Accuracy of timestamps
UINT snaplen; ///< Length of the max saved portion of each packet
UINT linktype; ///< Data link type (DLT_*). See win_bpf.h for details.
};
/*!
@ -212,11 +218,11 @@ struct packet_file_header
Similar to the bpf_hdr structure, but simpler.
*/
struct sf_pkthdr {
struct timeval ts; ///< time stamp
UINT caplen; ///< Length of captured portion. The captured portion can be different from
///< the original packet, because it is possible (with a proper filter) to
///< instruct the driver to capture only a portion of the packets.
UINT len; ///< Length of the original packet (off wire).
struct timeval ts; ///< time stamp
UINT caplen; ///< Length of captured portion. The captured portion can be different from
///< the original packet, because it is possible (with a proper filter) to
///< instruct the driver to capture only a portion of the packets.
UINT len; ///< Length of the original packet (off wire).
};
/*!
@ -229,9 +235,10 @@ struct sf_pkthdr {
maintaining information about the IRPs to complete.
*/
typedef struct _INTERNAL_REQUEST {
LIST_ENTRY ListElement; ///< Used to handle lists of requests.
PIRP Irp; ///< Irp that performed the request
NDIS_REQUEST Request; ///< The structure with the actual request, that will be passed to NdisRequest().
LIST_ENTRY ListElement; ///< Used to handle lists of requests.
PIRP Irp; ///< Irp that performed the request
BOOLEAN Internal; ///< True if the request is for internal use of npf.sys. False if the request is performed by the user through an IOCTL.
NDIS_REQUEST Request; ///< The structure with the actual request, that will be passed to NdisRequest().
} INTERNAL_REQUEST, *PINTERNAL_REQUEST;
/*!
@ -242,11 +249,11 @@ typedef struct _INTERNAL_REQUEST {
maintaining information about the IRPs to complete.
*/
typedef struct _PACKET_RESERVED {
LIST_ENTRY ListElement; ///< Used to handle lists of packets.
PIRP Irp; ///< Irp that performed the request
PMDL pMdl; ///< MDL mapping the buffer of the packet.
BOOLEAN FreeBufAfterWrite; ///< True if the memory buffer associated with the packet must be freed
///< after a call to NdisSend().
LIST_ENTRY ListElement; ///< Used to handle lists of packets.
PIRP Irp; ///< Irp that performed the request
PMDL pMdl; ///< MDL mapping the buffer of the packet.
BOOLEAN FreeBufAfterWrite; ///< True if the memory buffer associated with the packet must be freed
///< after a call to NdisSend().
} PACKET_RESERVED, *PPACKET_RESERVED;
#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) ///< Macro to obtain a NDIS_PACKET from a PACKET_RESERVED
@ -257,12 +264,10 @@ typedef struct _PACKET_RESERVED {
Structure containing some data relative to every adapter on which NPF is bound.
*/
typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT DeviceObject; ///< Adapter's device.
NDIS_HANDLE NdisProtocolHandle; ///< NDIS handle of NPF.
NDIS_STRING AdapterName; ///< Name of the adapter.
PWSTR BindString; ///< Original device name of the adapter.
PWSTR ExportString; ///< Name of the exported device, i.e. name that the applications will use
///< to open this adapter through WinPcap.
NDIS_HANDLE NdisProtocolHandle; ///< NDIS handle of NPF.
NDIS_STRING AdapterName; ///< Name of the adapter.
PWSTR ExportString; ///< Name of the exported device, i.e. name that the applications will use
///< to open this adapter through WinPcap.
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
/*!
@ -274,106 +279,104 @@ typedef struct _DEVICE_EXTENSION {
*/
typedef struct _OPEN_INSTANCE
{
PDEVICE_EXTENSION DeviceExtension; ///< Pointer to the _DEVICE_EXTENSION structure of the device on which
///< the instance is bound.
NDIS_HANDLE AdapterHandle; ///< NDIS idetifier of the adapter used by this instance.
UINT Medium; ///< Type of physical medium the underlying NDIS driver uses. See the
///< documentation of NdisOpenAdapter in the MS DDK for details.
NDIS_HANDLE PacketPool; ///< Pool of NDIS_PACKET structures used to transfer the packets from and to the NIC driver.
PIRP OpenCloseIrp; ///< Pointer used to store the open/close IRP requests and provide them to the
///< callbacks of NDIS.
KSPIN_LOCK RequestSpinLock; ///< SpinLock used to synchronize the OID requests.
LIST_ENTRY RequestList; ///< List of pending OID requests.
LIST_ENTRY ResetIrpList; ///< List of pending adapter reset requests.
PDEVICE_EXTENSION DeviceExtension; ///< Pointer to the _DEVICE_EXTENSION structure of the device on which
///< the instance is bound.
NDIS_HANDLE AdapterHandle; ///< NDIS idetifier of the adapter used by this instance.
UINT Medium; ///< Type of physical medium the underlying NDIS driver uses. See the
///< documentation of NdisOpenAdapter in the MS DDK for details.
NDIS_HANDLE PacketPool; ///< Pool of NDIS_PACKET structures used to transfer the packets from and to the NIC driver.
PIRP OpenCloseIrp; ///< Pointer used to store the open/close IRP requests and provide them to the
///< callbacks of NDIS.
KSPIN_LOCK RequestSpinLock; ///< SpinLock used to synchronize the OID requests.
LIST_ENTRY RequestList; ///< List of pending OID requests.
LIST_ENTRY ResetIrpList; ///< List of pending adapter reset requests.
INTERNAL_REQUEST Requests[MAX_REQUESTS]; ///< Array of structures that wrap every single OID request.
PMDL BufferMdl; ///< Pointer to a Memory descriptor list (MDL) that maps the circular buffer's memory.
PKEVENT ReadEvent; ///< Pointer to the event on which the read calls on this instance must wait.
HANDLE ReadEventHandle; ///< Handle of the event on which the read calls on this instance must wait.
UNICODE_STRING ReadEventName; ///< Name of the event on which the read calls on this instance must wait.
///< The event is created with a name, so it can be used at user level to know when it
///< is possible to access the driver without being blocked. This fiels stores the name
///< that and is used by the BIOCGEVNAME IOCTL call.
INT Received; ///< Number of packets received by current instance from its opening, i.e. number of
///< packet received by the network adapter since the beginning of the
///< capture/monitoring/dump session.
INT Dropped; ///< Number of packet that current instance had to drop, from its opening. A packet
///< is dropped if there is no more space to store it in the circular buffer that the
///< driver associates to current instance.
INT Accepted; ///< Number of packet that current capture instance acepted, from its opening. A packet
///< is accepted if it passes the filter and fits in the buffer. Accepted packets are the
///< ones that reach the application.
PUCHAR bpfprogram; ///< Pointer to the filtering pseudo-code associated with current instance of the driver.
///< This code is used only in particular situations (for example when the packet received
///< from the NIC driver is stored in two non-consecutive buffers. In normal situations
///< the filtering routine created by the JIT compiler and pointed by the next field
///< is used. See \ref NPF for details on the filtering process.
JIT_BPF_Filter *Filter; ///< Pointer to the native filtering function created by the jitter.
///< See BPF_jitter() for details.
PUCHAR Buffer; ///< Pointer to the circular buffer associated with every driver instance. It contains the
///< data that will be passed to the application. See \ref NPF for details.
UINT Bhead; ///< Head of the circular buffer.
UINT Btail; ///< Tail of the circular buffer.
UINT BufSize; ///< Size of the circular buffer.
UINT BLastByte; ///< Position of the last valid byte in the circular buffer.
PMDL TransferMdl; ///< MDL used to map the portion of the buffer that will contain an incoming packet.
///< Used by NdisTransferData().
NDIS_SPIN_LOCK BufLock; ///< SpinLock that protects the access tho the circular buffer variables.
UINT MinToCopy; ///< Minimum amount of data in the circular buffer that unlocks a read. Set with the
///< BIOCSMINTOCOPY IOCTL.
LARGE_INTEGER TimeOut; ///< Timeout after which a read is released, also if the amount of data in the buffer is
///< less than MinToCopy. Set with the BIOCSRTIMEOUT IOCTL.
int mode; ///< Working mode of the driver. See PacketSetMode() for details.
LARGE_INTEGER Nbytes; ///< Amount of bytes accepted by the filter when this instance is in statistical mode.
LARGE_INTEGER Npackets; ///< Number of packets accepted by the filter when this instance is in statistical mode.
NDIS_SPIN_LOCK CountersLock; ///< SpinLock that protects the statistical mode counters.
UINT Nwrites; ///< Number of times a single write must be physically repeated. See \ref NPF for an
///< explanation
UINT Multiple_Write_Counter; ///< Counts the number of times a single write has already physically repeated.
NDIS_EVENT WriteEvent; ///< Event used to synchronize the multiple write process.
NDIS_EVENT IOEvent; ///< Event used to synchronize I/O requests with the callback structure of NDIS.
NDIS_STATUS IOStatus; ///< Maintains the status of and OID request call, that will be passed to the application.
BOOLEAN Bound; ///< Specifies if NPF is still bound to the adapter used by this instance. Bound can be
///< FALSE if a Plug and Play adapter has been removed or disabled by the user.
HANDLE DumpFileHandle; ///< Handle of the file used in dump mode.
PFILE_OBJECT DumpFileObject; ///< Pointer to the object of the file used in dump mode.
// PKTHREAD DumpThreadObject; ///< Pointer to the object of the thread used in dump mode.
HANDLE DumpThreadHandle; ///< Handle of the thread created by dump mode to asynchronously move the buffer to disk.
NDIS_EVENT DumpEvent; ///< Event used to synchronize the dump thread with the tap when the instance is in dump mode.
LARGE_INTEGER DumpOffset; ///< Current offset in the dump file.
UNICODE_STRING DumpFileName; ///< String containing the name of the dump file.
UINT MaxDumpBytes; ///< Maximum dimension in bytes of the dump file. If the dump file reaches this size it
///< will be closed. A value of 0 means unlimited size.
UINT MaxDumpPacks; ///< Maximum number of packets that will be saved in the dump file. If this number of
///< packets is reached the dump will be closed. A value of 0 means unlimited number of
///< packets.
BOOLEAN DumpLimitReached; ///< TRUE if the maximum dimension of the dump file (MaxDumpBytes or MaxDumpPacks) is
///< reached.
MEM_TYPE mem_ex; ///< Memory used by the TME virtual co-processor
TME_CORE tme; ///< Data structure containing the virtualization of the TME co-processor
NDIS_SPIN_LOCK machine_lock; ///< SpinLock that protects the mem_ex buffer
PMDL BufferMdl; ///< Pointer to a Memory descriptor list (MDL) that maps the circular buffer's memory.
PKEVENT ReadEvent; ///< Pointer to the event on which the read calls on this instance must wait.
HANDLE ReadEventHandle; ///< Handle of the event on which the read calls on this instance must wait.
UNICODE_STRING ReadEventName; ///< Name of the event on which the read calls on this instance must wait.
///< The event is created with a name, so it can be used at user level to know when it
///< is possible to access the driver without being blocked. This fiels stores the name
///< that and is used by the BIOCGEVNAME IOCTL call.
INT Received; ///< Number of packets received by current instance from its opening, i.e. number of
///< packet received by the network adapter since the beginning of the
///< capture/monitoring/dump session.
INT Dropped; ///< Number of packet that current instance had to drop, from its opening. A packet
///< is dropped if there is no more space to store it in the circular buffer that the
///< driver associates to current instance.
INT Accepted; ///< Number of packet that current capture instance acepted, from its opening. A packet
///< is accepted if it passes the filter and fits in the buffer. Accepted packets are the
///< ones that reach the application.
PUCHAR bpfprogram; ///< Pointer to the filtering pseudo-code associated with current instance of the driver.
///< This code is used only in particular situations (for example when the packet received
///< from the NIC driver is stored in two non-consecutive buffers. In normal situations
///< the filtering routine created by the JIT compiler and pointed by the next field
///< is used. See \ref NPF for details on the filtering process.
JIT_BPF_Filter *Filter; ///< Pointer to the native filtering function created by the jitter.
///< See BPF_jitter() for details.
PUCHAR Buffer; ///< Pointer to the circular buffer associated with every driver instance. It contains the
///< data that will be passed to the application. See \ref NPF for details.
UINT Bhead; ///< Head of the circular buffer.
UINT Btail; ///< Tail of the circular buffer.
UINT BufSize; ///< Size of the circular buffer.
UINT BLastByte; ///< Position of the last valid byte in the circular buffer.
PMDL TransferMdl; ///< MDL used to map the portion of the buffer that will contain an incoming packet.
///< Used by NdisTransferData().
NDIS_SPIN_LOCK BufLock; ///< SpinLock that protects the access tho the circular buffer variables.
UINT MinToCopy; ///< Minimum amount of data in the circular buffer that unlocks a read. Set with the
///< BIOCSMINTOCOPY IOCTL.
LARGE_INTEGER TimeOut; ///< Timeout after which a read is released, also if the amount of data in the buffer is
///< less than MinToCopy. Set with the BIOCSRTIMEOUT IOCTL.
int mode; ///< Working mode of the driver. See PacketSetMode() for details.
LARGE_INTEGER Nbytes; ///< Amount of bytes accepted by the filter when this instance is in statistical mode.
LARGE_INTEGER Npackets; ///< Number of packets accepted by the filter when this instance is in statistical mode.
NDIS_SPIN_LOCK CountersLock; ///< SpinLock that protects the statistical mode counters.
UINT Nwrites; ///< Number of times a single write must be physically repeated. See \ref NPF for an
///< explanation
UINT Multiple_Write_Counter; ///< Counts the number of times a single write has already physically repeated.
NDIS_EVENT WriteEvent; ///< Event used to synchronize the multiple write process.
NDIS_EVENT IOEvent; ///< Event used to synchronize I/O requests with the callback structure of NDIS.
NDIS_STATUS IOStatus; ///< Maintains the status of and OID request call, that will be passed to the application.
BOOLEAN Bound; ///< Specifies if NPF is still bound to the adapter used by this instance. Bound can be
///< FALSE if a Plug and Play adapter has been removed or disabled by the user.
HANDLE DumpFileHandle; ///< Handle of the file used in dump mode.
PFILE_OBJECT DumpFileObject; ///< Pointer to the object of the file used in dump mode.
PKTHREAD DumpThreadObject; ///< Pointer to the object of the thread used in dump mode.
HANDLE DumpThreadHandle; ///< Handle of the thread created by dump mode to asynchronously move the buffer to disk.
NDIS_EVENT DumpEvent; ///< Event used to synchronize the dump thread with the tap when the instance is in dump mode.
LARGE_INTEGER DumpOffset; ///< Current offset in the dump file.
UNICODE_STRING DumpFileName; ///< String containing the name of the dump file.
UINT MaxDumpBytes; ///< Maximum dimension in bytes of the dump file. If the dump file reaches this size it
///< will be closed. A value of 0 means unlimited size.
UINT MaxDumpPacks; ///< Maximum number of packets that will be saved in the dump file. If this number of
///< packets is reached the dump will be closed. A value of 0 means unlimited number of
///< packets.
BOOLEAN DumpLimitReached; ///< TRUE if the maximum dimension of the dump file (MaxDumpBytes or MaxDumpPacks) is
///< reached.
MEM_TYPE mem_ex; ///< Memory used by the TME virtual co-processor
TME_CORE tme; ///< Data structure containing the virtualization of the TME co-processor
NDIS_SPIN_LOCK machine_lock; ///< SpinLock that protects the mem_ex buffer
UINT MaxFrameSize; ///< Maximum frame size that the underlying MAC acceptes. Used to perform a check on the
///< size of the frames sent with NPF_Write() or NPF_BufferedWrite().
} OPEN_INSTANCE, *POPEN_INSTANCE;
#define TRANSMIT_PACKETS 256 ///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number
///< of packets that can be transmitted at the same time or with a single call to NdisSendPackets.
#define TRANSMIT_PACKETS 256 ///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number
///< of packets that can be transmitted at the same time or with a single call to NdisSendPackets.
#ifdef __GNUC__
#undef EXIT_SUCCESS
#undef EXIT_FAILURE
#endif
/// Macro used in the I/O routines to return the control to user-mode with a success status.
#define EXIT_SUCCESS(quantity) Irp->IoStatus.Information=quantity;\
Irp->IoStatus.Status = STATUS_SUCCESS;\
IoCompleteRequest(Irp, IO_NO_INCREMENT);\
return STATUS_SUCCESS;\
Irp->IoStatus.Status = STATUS_SUCCESS;\
IoCompleteRequest(Irp, IO_NO_INCREMENT);\
return STATUS_SUCCESS;\
/// Macro used in the I/O routines to return the control to user-mode with a failure status.
#define EXIT_FAILURE(quantity) Irp->IoStatus.Information=quantity;\
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\
IoCompleteRequest(Irp, IO_NO_INCREMENT);\
return STATUS_UNSUCCESSFUL;\
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\
IoCompleteRequest(Irp, IO_NO_INCREMENT);\
return STATUS_UNSUCCESSFUL;\
/**
* @}
@ -400,11 +403,11 @@ return STATUS_UNSUCCESSFUL;\
performing all the allocations and the setup. In particular, DriverEntry registers all the driver's I/O
callbacks, creates the devices, defines NPF as a protocol inside NDIS.
*/
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
//NTSTATUS
//DriverEntry(
// IN PDRIVER_OBJECT DriverObject,
// IN PUNICODE_STRING RegistryPath
// );
/*!
\brief Returns the list of the MACs available on the system.
@ -437,9 +440,9 @@ PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID);
determine the correct adapter to use.
*/
BOOLEAN createDevice(
IN OUT PDRIVER_OBJECT adriverObjectP,
IN PUNICODE_STRING amacNameP,
NDIS_HANDLE aProtoHandle);
IN OUT PDRIVER_OBJECT adriverObjectP,
IN PUNICODE_STRING amacNameP,
NDIS_HANDLE aProtoHandle);
/*!
\brief Opens a new instance of the driver.
@ -584,8 +587,8 @@ NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext);
- #BIOCQUERYOID
- #BIOCSETDUMPFILENAME
- #BIOCGEVNAME
- #BIOCSENDPACKETSSYNC
- #BIOCSENDPACKETSNOSYNC
- #BIOCSENDPACKETSSYNC
- #BIOCSENDPACKETSNOSYNC
*/
NTSTATUS
NPF_IoControl(
@ -624,9 +627,9 @@ NPF_RequestComplete(
*/
NTSTATUS
NPF_Write(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
/*!
@ -636,7 +639,7 @@ NPF_Write(
\param UserBuffSize Size of the buffer with the packets.
\return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an
error occurred during the send. The error can be caused by an adapter problem or by an
inconsistent/bogus user buffer.
inconsistent/bogus user buffer.
This function is called by the OS in consequence of a BIOCSENDPACKETSNOSYNC or a BIOCSENDPACKETSSYNC IOCTL.
The buffer received as input parameter contains an arbitrary number of packets, each of which preceded by a
@ -648,9 +651,9 @@ NPF_Write(
*/
INT NPF_BufferedWrite(IN PIRP Irp,
IN PCHAR UserBuff,
IN ULONG UserBuffSize,
BOOLEAN sync);
IN PCHAR UserBuff,
IN ULONG UserBuffSize,
BOOLEAN sync);
/*!
\brief Ends a send operation.
@ -827,12 +830,12 @@ int bpf_validate(struct bpf_insn *f,int len, uint32 mem_ex_size);
that is faster than the interpreter.
*/
UINT bpf_filter(register struct bpf_insn *pc,
register UCHAR *p,
UINT wirelen,
register UINT buflen,
PMEM_TYPE mem_ex,
PTME_CORE tme,
struct time_conv *time_ref);
register UCHAR *p,
UINT wirelen,
register UINT buflen,
PMEM_TYPE mem_ex,
PTME_CORE tme,
struct time_conv *time_ref);
/*!
\brief The filtering pseudo-machine interpreter with two buffers. This function is slower than bpf_filter(),
@ -852,14 +855,14 @@ UINT bpf_filter(register struct bpf_insn *pc,
This function is used when NDIS passes the packet to NPF_tap() in two buffers instaed than in a single one.
*/
UINT bpf_filter_with_2_buffers(register struct bpf_insn *pc,
register UCHAR *p,
register UCHAR *pd,
register int headersize,
UINT wirelen,
register UINT buflen,
PMEM_TYPE mem_ex,
PTME_CORE tme,
struct time_conv *time_ref);
register UCHAR *p,
register UCHAR *pd,
register int headersize,
UINT wirelen,
register UINT buflen,
PMEM_TYPE mem_ex,
PTME_CORE tme,
struct time_conv *time_ref);
/*!
\brief Creates the file that will receive the packets when the driver is in dump mode.
@ -910,10 +913,10 @@ NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open);
of the NPF circular buffer to disk. This function is used by NPF_DumpThread().
*/
VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
PLARGE_INTEGER Offset,
ULONG Length,
PMDL Mdl,
PIO_STATUS_BLOCK IoStatusBlock);
PLARGE_INTEGER Offset,
ULONG Length,
PMDL Mdl,
PIO_STATUS_BLOCK IoStatusBlock);
@ -954,4 +957,3 @@ NDIS_STATUS NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_E
*/
#endif /*main ifndef/define*/

View file

@ -27,6 +27,16 @@
#else
#include <ddk/ntddk.h>
#include <net/ndis.h>
#define NdisMoveMappedMemory(Destination,Source,Length) RtlCopyMemory(Destination,Source,Length)
#define NdisZeroMappedMemory(Destination,Length) RtlZeroMemory(Destination,Length)
#define NdisReinitializePacket(Packet) \
{ \
(Packet)->Private.Head = (PNDIS_BUFFER)NULL; \
(Packet)->Private.ValidCounts = FALSE; \
}
#endif
#include "debug.h"
@ -92,20 +102,19 @@ NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
POPEN_INSTANCE Open;
PIO_STACK_LOCATION IrpSp;
PUCHAR packp;
UINT i;
ULONG Input_Buffer_Length;
UINT Thead;
UINT Ttail;
UINT TLastByte;
PUCHAR CurrBuff;
UINT cplen;
UINT CpStart;
LARGE_INTEGER CapTime;
LARGE_INTEGER TimeFreq;
struct bpf_hdr *header;
KIRQL Irql;
PUCHAR UserPointer;
ULONG bytecopy;
UINT SizeToCopy;
UINT PktLen;
IF_LOUD(DbgPrint("NPF: Read\n");)
@ -255,7 +264,7 @@ NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
NdisReleaseSpinLock( &Open->BufLock );
Input_Buffer_Length=IrpSp->Parameters.Read.Length;
packp=(PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress);
packp=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress);
//
@ -283,47 +292,38 @@ NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
}
//the buffer must be scannned to determine the number of bytes to copy
CpStart=Thead;
i=0;
SizeToCopy = 0;
while(TRUE){
if(Thead == Ttail)break;
if(Thead + SizeToCopy == Ttail)
break;
if(Thead == TLastByte){
// Copy the portion between thead and TLastByte
PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead));
packp+=(Thead-CpStart);
if(Thead + SizeToCopy == TLastByte && TLastByte != Ttail){
PacketMoveMem(packp, CurrBuff+Thead, SizeToCopy, &(Open->Bhead));
// Reset the buffer
NdisAcquireSpinLock( &Open->BufLock );
Open->BLastByte = Open->Btail;
Open->Bhead = 0;
(INT)Open->BLastByte = -1;
Open->Bhead = 0;
NdisReleaseSpinLock( &Open->BufLock );
Thead=0;
CpStart=0;
EXIT_SUCCESS(SizeToCopy);
}
cplen=((struct bpf_hdr*)(CurrBuff+Thead))->bh_caplen+sizeof(struct bpf_hdr);
if((i+cplen > Input_Buffer_Length)){//no more space in the application's buffer
PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead));
// Get the size of the next packet in the buffer
PktLen = ((struct bpf_hdr*)(CurrBuff + Thead + SizeToCopy))->bh_caplen + sizeof(struct bpf_hdr);
EXIT_SUCCESS(i);
}
cplen=Packet_WORDALIGN(cplen);
i+=cplen;
Thead+=cplen;
// The length is aligned to 32-bit boundary
PktLen = Packet_WORDALIGN(PktLen);
if(SizeToCopy + PktLen > Input_Buffer_Length)
break;
SizeToCopy += PktLen;
}
KeResetEvent(Open->ReadEvent);
PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead));
Open->Bhead=Thead;
EXIT_SUCCESS(i);
PacketMoveMem(packp, CurrBuff+Thead, SizeToCopy, &(Open->Bhead));
EXIT_SUCCESS(SizeToCopy);
}
//-------------------------------------------------------------------
@ -350,8 +350,14 @@ NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacRec
UINT maxbufspace;
USHORT NPFHdrSize;
UINT BufOccupation;
BOOLEAN ResetBuff = FALSE;
IF_VERY_LOUD(DbgPrint("NPF: tap\n");)
IF_VERY_LOUD(DbgPrint("HeaderBufferSize=%d, LookAheadBuffer=%d, LookaheadBufferSize=%d, PacketSize=%d\n",
HeaderBufferSize,
LookAheadBuffer,
LookaheadBufferSize,
PacketSize);)
Open= (POPEN_INSTANCE)ProtocolBindingContext;
@ -401,6 +407,7 @@ NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacRec
#ifndef __GNUC__
_asm add esp,12
#else
asm("add $0x12,%esp;");
#endif
}
else
@ -489,9 +496,16 @@ NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacRec
}
else{
Ttail=0;
ResetBuff = TRUE;
}
}
if (Thead > Ttail && (Thead-Ttail) <= maxbufspace)
{
Open->Dropped++;
return NDIS_STATUS_NOT_ACCEPTED;
}
CurrBuff=Open->Buffer+Ttail;
if(LookaheadBufferSize != PacketSize || (UINT)LookAheadBuffer-(UINT)HeaderBuffer != HeaderBufferSize)
@ -568,15 +582,17 @@ NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacRec
HeaderBuffer,
HeaderBufferSize + LookaheadBufferSize);
BytesTransfered = 0;
Open->TransferMdl = NULL;
Status = NDIS_STATUS_SUCCESS;
}
Open->Accepted++; // Increase the accepted packets counter
if (Status != NDIS_STATUS_FAILURE)
{
Open->Accepted++; // Increase the accepted packets counter
if( fres > (BytesTransfered+HeaderBufferSize+LookaheadBufferSize) )
fres = BytesTransfered+HeaderBufferSize+LookaheadBufferSize;
@ -596,12 +612,12 @@ NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacRec
Ttail+=fres+NPFHdrSize;
//update the buffer
if(Ttail > Thead)TLastByte = Ttail;
NdisAcquireSpinLock( &Open->BufLock );
if(ResetBuff){
Open->BLastByte = Open->Btail;
}
Open->Btail=Ttail;
Open->BLastByte=TLastByte;
NdisReleaseSpinLock( &Open->BufLock );
}

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2001
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -36,50 +36,50 @@
#endif
#define UNKNOWN 0
#define SYN_RCV 1
#define SYN_ACK_RCV 2
#define ESTABLISHED 3
#define CLOSED_RST 4
#define FIN_CLN_RCV 5
#define FIN_SRV_RCV 6
#define CLOSED_FIN 7
#define ERROR_TCP 8
#define FIRST_IS_CLN 0
#define FIRST_IS_SRV 0xffffffff
#define FIN_CLN 1
#define FIN_SRV 2
#define UNKNOWN 0
#define SYN_RCV 1
#define SYN_ACK_RCV 2
#define ESTABLISHED 3
#define CLOSED_RST 4
#define FIN_CLN_RCV 5
#define FIN_SRV_RCV 6
#define CLOSED_FIN 7
#define ERROR_TCP 8
#define FIRST_IS_CLN 0
#define FIRST_IS_SRV 0xffffffff
#define FIN_CLN 1
#define FIN_SRV 2
#define MAX_WINDOW 65536
typedef struct __tcp_data
{
struct timeval timestamp_block; /*DO NOT MOVE THIS VALUE*/
struct timeval syn_timestamp;
struct timeval last_timestamp;
struct timeval syn_ack_timestamp;
uint32 direction;
uint32 seq_n_0_srv;
uint32 seq_n_0_cln;
uint32 ack_srv; /* acknowledge of (data sent by server) */
uint32 ack_cln; /* acknowledge of (data sent by client) */
uint32 status;
uint32 pkts_cln_to_srv;
uint32 pkts_srv_to_cln;
uint32 bytes_srv_to_cln;
uint32 bytes_cln_to_srv;
uint32 close_state;
struct timeval timestamp_block; /*DO NOT MOVE THIS VALUE*/
struct timeval syn_timestamp;
struct timeval last_timestamp;
struct timeval syn_ack_timestamp;
uint32 direction;
uint32 seq_n_0_srv;
uint32 seq_n_0_cln;
uint32 ack_srv; /* acknowledge of (data sent by server) */
uint32 ack_cln; /* acknowledge of (data sent by client) */
uint32 status;
uint32 pkts_cln_to_srv;
uint32 pkts_srv_to_cln;
uint32 bytes_srv_to_cln;
uint32 bytes_cln_to_srv;
uint32 close_state;
}
tcp_data;
tcp_data;
#define FIN 1
#define SYN 2
#define RST 4
#define PSH 8
#define ACK 16
#define URG 32
#define FIN 1
#define SYN 2
#define RST 4
#define PSH 8
#define ACK 16
#define URG 32
#define TCP_SESSION 0x00000800
#define TCP_SESSION 0x00000800
uint32 tcp_session(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data);
#endif

View file

@ -26,11 +26,9 @@
void TIME_DESYNCHRONIZE(struct time_conv *data)
{
#ifndef __GNUC__
data->reference = 0;
data->start.tv_sec = 0;
data->start.tv_usec = 0;
#endif
}
#ifdef KQPC_TS
@ -39,7 +37,6 @@ void TIME_DESYNCHRONIZE(struct time_conv *data)
VOID TIME_SYNCHRONIZE(struct time_conv *data)
{
#ifndef __GNUC__
struct timeval tmp;
LARGE_INTEGER SystemTime;
LARGE_INTEGER i;
@ -52,17 +49,20 @@ VOID TIME_SYNCHRONIZE(struct time_conv *data)
// get the absolute value of the system boot time.
PTime=KeQueryPerformanceCounter(&TimeFreq);
KeQuerySystemTime(&SystemTime);
#ifndef __GNUC__
tmp.tv_sec=(LONG)(SystemTime.QuadPart/10000000-11644473600);
tmp.tv_usec=(LONG)((SystemTime.QuadPart%10000000)/10);
tmp.tv_sec-=(ULONG)(PTime.QuadPart/TimeFreq.QuadPart);
tmp.tv_usec-=(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
#else
// TODO FIXME:
#endif
if (tmp.tv_usec<0) {
tmp.tv_sec--;
tmp.tv_usec+=1000000;
}
data->start=tmp;
data->reference=1;
#endif
}
void FORCE_TIME(struct timeval *src, struct time_conv *dest)
@ -72,29 +72,30 @@ void FORCE_TIME(struct timeval *src, struct time_conv *dest)
void GET_TIME(struct timeval *dst, struct time_conv *data)
{
#ifndef __GNUC__
LARGE_INTEGER PTime, TimeFreq;
LONG tmp;
PTime=KeQueryPerformanceCounter(&TimeFreq);
#ifndef __GNUC__
tmp=(LONG)(PTime.QuadPart/TimeFreq.QuadPart);
dst->tv_sec=data->start.tv_sec+tmp;
dst->tv_usec=data->start.tv_usec+(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
#else
// TODO FIXME:
#endif
if (dst->tv_usec>=1000000) {
dst->tv_sec++;
dst->tv_usec-=1000000;
}
#endif
}
#else
#else /*KQPC_TS*/
/*RDTSC timestamps*/
/* callers must be at IRQL=PASSIVE_LEVEL */
VOID TIME_SYNCHRONIZE(struct time_conv *data)
{
#ifndef __GNUC__
struct timeval tmp;
LARGE_INTEGER system_time;
ULONGLONG curr_ticks;
@ -128,6 +129,17 @@ VOID TIME_SYNCHRONIZE(struct time_conv *data)
pop eax
}
#else
asm("push %%eax;"
"push %%edx;"
"push %%ecx;"
"rdtsc;"
"lea %0,%%ecx;"
"mov %%edx,(%%ecx+4);"
"mov %%eax,(%%ecx);"
"pop %%ecx;"
"pop %%edx;"
"pop %%eax;"
:"=c"(start_ticks): );
#endif
KeLowerIrql(old);
KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i);
@ -148,6 +160,17 @@ VOID TIME_SYNCHRONIZE(struct time_conv *data)
pop eax
}
#else
asm("push %%eax;"
"push %%edx;"
"push %%ecx;"
"rdtsc;"
"lea %0,%%ecx;"
"mov %%edx,(%%ecx+4);"
"mov %%eax,(%%ecx);"
"pop %%ecx;"
"pop %%edx;"
"pop %%eax;"
:"=c"(stop_ticks): );
#endif
KeLowerIrql(old);
delta=stop_ticks-start_ticks;
@ -178,6 +201,17 @@ VOID TIME_SYNCHRONIZE(struct time_conv *data)
pop eax
}
#else
asm("push %%eax;"
"push %%edx;"
"push %%ecx;"
"rdtsc;"
"lea %0,%%ecx;"
"mov %%edx,(%%ecx+4);"
"mov %%eax,(%%ecx);"
"pop %%ecx;"
"pop %%edx;"
"pop %%eax;"
:"=c"(curr_ticks): );
#endif
tmp.tv_sec=-(LONG)(curr_ticks/reference);
tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference);
@ -190,8 +224,6 @@ VOID TIME_SYNCHRONIZE(struct time_conv *data)
}
data->start=tmp;
IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);)
#else
#endif
}
void FORCE_TIME(struct timeval *src, struct time_conv *dest)
@ -201,7 +233,6 @@ void FORCE_TIME(struct timeval *src, struct time_conv *dest)
void GET_TIME(struct timeval *dst, struct time_conv *data)
{
#ifndef __GNUC__
ULONGLONG tmp;
#ifndef __GNUC__
__asm
@ -218,6 +249,17 @@ void GET_TIME(struct timeval *dst, struct time_conv *data)
pop eax
}
#else
asm("push %%eax;"
"push %%edx;"
"push %%ecx;"
"rdtsc;"
"lea %0,%%ecx;"
"mov %%edx,(%%ecx+4);"
"mov %%eax,(%%ecx);"
"pop %%ecx;"
"pop %%edx;"
"pop %%eax;"
:"=c"(tmp): );
#endif
if (data->reference==0) {
return;
@ -230,7 +272,6 @@ void GET_TIME(struct timeval *dst, struct time_conv *data)
dst->tv_sec++;
dst->tv_usec-=1000000;
}
#endif
}
#endif /*KQPC_TS*/

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2001
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -40,8 +40,8 @@ struct timeval {
#endif /*WIN_NT_DRIVER*/
struct time_conv {
ULONGLONG reference;
struct timeval start;
ULONGLONG reference;
struct timeval start;
};
#ifdef __GNUC__
@ -57,9 +57,9 @@ void GET_TIME(struct timeval *dst, struct time_conv *data);
__inline void TIME_DESYNCHRONIZE(struct time_conv *data)
{
data->reference = 0;
data->start.tv_sec = 0;
data->start.tv_usec = 0;
data->reference = 0;
data->start.tv_sec = 0;
data->start.tv_usec = 0;
}
#ifdef KQPC_TS
@ -68,48 +68,48 @@ __inline void TIME_DESYNCHRONIZE(struct time_conv *data)
__inline VOID TIME_SYNCHRONIZE(struct time_conv *data)
{
struct timeval tmp;
LARGE_INTEGER SystemTime;
LARGE_INTEGER i;
ULONG tmp2;
LARGE_INTEGER TimeFreq,PTime;
struct timeval tmp;
LARGE_INTEGER SystemTime;
LARGE_INTEGER i;
ULONG tmp2;
LARGE_INTEGER TimeFreq,PTime;
if (data->reference!=0)
return;
// get the absolute value of the system boot time.
PTime=KeQueryPerformanceCounter(&TimeFreq);
KeQuerySystemTime(&SystemTime);
tmp.tv_sec=(LONG)(SystemTime.QuadPart/10000000-11644473600);
tmp.tv_usec=(LONG)((SystemTime.QuadPart%10000000)/10);
tmp.tv_sec-=(ULONG)(PTime.QuadPart/TimeFreq.QuadPart);
tmp.tv_usec-=(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
if (tmp.tv_usec<0) {
tmp.tv_sec--;
tmp.tv_usec+=1000000;
}
data->start=tmp;
data->reference=1;
}
__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest)
{
dest->start=*src;
if (data->reference!=0)
return;
// get the absolute value of the system boot time.
PTime=KeQueryPerformanceCounter(&TimeFreq);
KeQuerySystemTime(&SystemTime);
tmp.tv_sec=(LONG)(SystemTime.QuadPart/10000000-11644473600);
tmp.tv_usec=(LONG)((SystemTime.QuadPart%10000000)/10);
tmp.tv_sec-=(ULONG)(PTime.QuadPart/TimeFreq.QuadPart);
tmp.tv_usec-=(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
if (tmp.tv_usec<0) {
tmp.tv_sec--;
tmp.tv_usec+=1000000;
}
data->start=tmp;
data->reference=1;
}
__inline void GET_TIME(struct timeval *dst, struct time_conv *data)
{
LARGE_INTEGER PTime, TimeFreq;
LONG tmp;
LARGE_INTEGER PTime, TimeFreq;
LONG tmp;
PTime=KeQueryPerformanceCounter(&TimeFreq);
tmp=(LONG)(PTime.QuadPart/TimeFreq.QuadPart);
dst->tv_sec=data->start.tv_sec+tmp;
dst->tv_usec=data->start.tv_usec+(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
if (dst->tv_usec>=1000000) {
dst->tv_sec++;
dst->tv_usec-=1000000;
}
PTime=KeQueryPerformanceCounter(&TimeFreq);
tmp=(LONG)(PTime.QuadPart/TimeFreq.QuadPart);
dst->tv_sec=data->start.tv_sec+tmp;
dst->tv_usec=data->start.tv_usec+(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
if (dst->tv_usec>=1000000) {
dst->tv_sec++;
dst->tv_usec-=1000000;
}
}
__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest)
{
dest->start=*src;
}
#else
@ -119,138 +119,138 @@ __inline void GET_TIME(struct timeval *dst, struct time_conv *data)
/* callers must be at IRQL=PASSIVE_LEVEL */
__inline VOID TIME_SYNCHRONIZE(struct time_conv *data)
{
struct timeval tmp;
LARGE_INTEGER system_time;
ULONGLONG curr_ticks;
KIRQL old;
LARGE_INTEGER start_kqpc,stop_kqpc,start_freq,stop_freq;
ULONGLONG start_ticks,stop_ticks;
ULONGLONG delta,delta2;
KEVENT event;
LARGE_INTEGER i;
ULONGLONG reference;
struct timeval tmp;
LARGE_INTEGER system_time;
ULONGLONG curr_ticks;
KIRQL old;
LARGE_INTEGER start_kqpc,stop_kqpc,start_freq,stop_freq;
ULONGLONG start_ticks,stop_ticks;
ULONGLONG delta,delta2;
KEVENT event;
LARGE_INTEGER i;
ULONGLONG reference;
if (data->reference!=0)
return;
KeInitializeEvent(&event,NotificationEvent,FALSE);
i.QuadPart=-3500000;
KeRaiseIrql(HIGH_LEVEL,&old);
start_kqpc=KeQueryPerformanceCounter(&start_freq);
if (data->reference!=0)
return;
KeInitializeEvent(&event,NotificationEvent,FALSE);
i.QuadPart=-3500000;
KeRaiseIrql(HIGH_LEVEL,&old);
start_kqpc=KeQueryPerformanceCounter(&start_freq);
#ifndef __GNUC__
__asm
{
push eax
push edx
push ecx
rdtsc
lea ecx, start_ticks
mov [ecx+4], edx
mov [ecx], eax
pop ecx
pop edx
pop eax
}
__asm
{
push eax
push edx
push ecx
rdtsc
lea ecx, start_ticks
mov [ecx+4], edx
mov [ecx], eax
pop ecx
pop edx
pop eax
}
#else
#endif
KeLowerIrql(old);
KeLowerIrql(old);
KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i);
KeRaiseIrql(HIGH_LEVEL,&old);
stop_kqpc=KeQueryPerformanceCounter(&stop_freq);
KeRaiseIrql(HIGH_LEVEL,&old);
stop_kqpc=KeQueryPerformanceCounter(&stop_freq);
#ifndef __GNUC__
__asm
{
push eax
push edx
push ecx
rdtsc
lea ecx, stop_ticks
mov [ecx+4], edx
mov [ecx], eax
pop ecx
pop edx
pop eax
}
__asm
{
push eax
push edx
push ecx
rdtsc
lea ecx, stop_ticks
mov [ecx+4], edx
mov [ecx], eax
pop ecx
pop edx
pop eax
}
#else
#endif
KeLowerIrql(old);
delta=stop_ticks-start_ticks;
delta2=stop_kqpc.QuadPart-start_kqpc.QuadPart;
if (delta>10000000000) {
delta/=16;
delta2/=16;
}
reference=delta*(start_freq.QuadPart)/delta2;
data->reference=reference/1000;
if (reference%1000>500)
data->reference++;
data->reference*=1000;
reference=data->reference;
KeQuerySystemTime(&system_time);
KeLowerIrql(old);
delta=stop_ticks-start_ticks;
delta2=stop_kqpc.QuadPart-start_kqpc.QuadPart;
if (delta>10000000000) {
delta/=16;
delta2/=16;
}
reference=delta*(start_freq.QuadPart)/delta2;
data->reference=reference/1000;
if (reference%1000>500)
data->reference++;
data->reference*=1000;
reference=data->reference;
KeQuerySystemTime(&system_time);
#ifndef __GNUC__
__asm
{
push eax
push edx
push ecx
rdtsc
lea ecx, curr_ticks
mov [ecx+4], edx
mov [ecx], eax
pop ecx
pop edx
pop eax
}
__asm
{
push eax
push edx
push ecx
rdtsc
lea ecx, curr_ticks
mov [ecx+4], edx
mov [ecx], eax
pop ecx
pop edx
pop eax
}
#else
#endif
tmp.tv_sec=-(LONG)(curr_ticks/reference);
tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference);
system_time.QuadPart-=116444736000000000;
tmp.tv_sec+=(LONG)(system_time.QuadPart/10000000);
tmp.tv_usec+=(LONG)((system_time.QuadPart%10000000)/10);
if (tmp.tv_usec<0) {
tmp.tv_sec--;
tmp.tv_usec+=1000000;
}
data->start=tmp;
IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);)
tmp.tv_sec=-(LONG)(curr_ticks/reference);
tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference);
system_time.QuadPart-=116444736000000000;
tmp.tv_sec+=(LONG)(system_time.QuadPart/10000000);
tmp.tv_usec+=(LONG)((system_time.QuadPart%10000000)/10);
if (tmp.tv_usec<0) {
tmp.tv_sec--;
tmp.tv_usec+=1000000;
}
data->start=tmp;
IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);)
}
__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest)
{
dest->start=*src;
dest->start=*src;
}
__inline void GET_TIME(struct timeval *dst, struct time_conv *data)
{
ULONGLONG tmp;
ULONGLONG tmp;
#ifndef __GNUC__
__asm
{
push eax
push edx
push ecx
rdtsc
lea ecx, tmp
mov [ecx+4], edx
mov [ecx], eax
pop ecx
pop edx
pop eax
}
__asm
{
push eax
push edx
push ecx
rdtsc
lea ecx, tmp
mov [ecx+4], edx
mov [ecx], eax
pop ecx
pop edx
pop eax
}
#else
#endif
if (data->reference==0) {
return;
}
dst->tv_sec=(LONG)(tmp/data->reference);
dst->tv_usec=(LONG)((tmp-dst->tv_sec*data->reference)*1000000/data->reference);
dst->tv_sec+=data->start.tv_sec;
dst->tv_usec+=data->start.tv_usec;
if (dst->tv_usec>=1000000) {
dst->tv_sec++;
dst->tv_usec-=1000000;
}
if (data->reference==0) {
return;
}
dst->tv_sec=(LONG)(tmp/data->reference);
dst->tv_usec=(LONG)((tmp-dst->tv_sec*data->reference)*1000000/data->reference);
dst->tv_sec+=data->start.tv_sec;
dst->tv_usec+=data->start.tv_usec;
if (dst->tv_usec>=1000000) {
dst->tv_sec++;
dst->tv_usec-=1000000;
}
}
#endif /*KQPC_TS*/

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2001
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -47,44 +47,44 @@
#endif
/* error codes */
#define TME_ERROR 0
#define TME_SUCCESS 1
#define TME_TRUE 2
#define TME_FALSE 3
#define TME_ERROR 0
#define TME_SUCCESS 1
#define TME_TRUE 2
#define TME_FALSE 3
/* some constants */
#define DEFAULT_MEM_EX_SIZE 65536
#define MAX_TME_DATA_BLOCKS 4
#define TME_NONE_ACTIVE 0xffffffff
#define DELTA_READ 2 /* secs */
#define DEFAULT_MEM_EX_SIZE 65536
#define MAX_TME_DATA_BLOCKS 4
#define TME_NONE_ACTIVE 0xffffffff
#define DELTA_READ 2 /* secs */
#define TME_LUT_ENTRIES 0x00000000
#define TME_MAX_FILL_STATE 0x00000001 /*potrebbe servire per un thread a passive level!?!?! */
#define TME_REHASHING_VALUE 0x00000002
#define TME_KEY_LEN 0x00000003
#define TME_SHARED_MEMORY_BLOCKS 0x00000004
#define TME_FILLED_ENTRIES 0x00000005
#define TME_BLOCK_SIZE 0x00000006
#define TME_EXTRA_SEGMENT_SIZE 0x00000007
#define TME_LOOKUP_CODE 0x00000008
#define TME_OUT_LUT_EXEC 0x00000009
#define TME_FILLED_BLOCKS 0x0000000a
#define TME_DEFAULT_EXEC 0x0000000b
#define TME_LUT_BASE_ADDRESS 0x0000000c
#define TME_SHARED_MEMORY_BASE_ADDRESS 0x0000000d
#define TME_EXTRA_SEGMENT_BASE_ADDRESS 0x0000000e
#define TME_LAST_FOUND 0x0000000f /* contains the offset of the last found entry */
#define TME_LAST_FOUND_BLOCK 0x00000010
#define TME_LUT_ENTRIES 0x00000000
#define TME_MAX_FILL_STATE 0x00000001 /*potrebbe servire per un thread a passive level!?!?! */
#define TME_REHASHING_VALUE 0x00000002
#define TME_KEY_LEN 0x00000003
#define TME_SHARED_MEMORY_BLOCKS 0x00000004
#define TME_FILLED_ENTRIES 0x00000005
#define TME_BLOCK_SIZE 0x00000006
#define TME_EXTRA_SEGMENT_SIZE 0x00000007
#define TME_LOOKUP_CODE 0x00000008
#define TME_OUT_LUT_EXEC 0x00000009
#define TME_FILLED_BLOCKS 0x0000000a
#define TME_DEFAULT_EXEC 0x0000000b
#define TME_LUT_BASE_ADDRESS 0x0000000c
#define TME_SHARED_MEMORY_BASE_ADDRESS 0x0000000d
#define TME_EXTRA_SEGMENT_BASE_ADDRESS 0x0000000e
#define TME_LAST_FOUND 0x0000000f /* contains the offset of the last found entry */
#define TME_LAST_FOUND_BLOCK 0x00000010
/* TME default values */
#define TME_LUT_ENTRIES_DEFAULT 32007
#define TME_REHASHING_VALUE_DEFAULT 1
#define TME_SHARED_MEMORY_BLOCKS_DEFAULT 16000
#define TME_BLOCK_SIZE_DEFAULT 64
#define TME_EXTRA_SEGMENT_SIZE_DEFAULT 0
#define TME_LOOKUP_CODE_DEFAULT 0
#define TME_OUT_LUT_EXEC_DEFAULT 0
#define TME_DEFAULT_EXEC_DEFAULT 0
#define TME_MAX_FILL_STATE_DEFAULT 15000
#define TME_LUT_ENTRIES_DEFAULT 32007
#define TME_REHASHING_VALUE_DEFAULT 1
#define TME_SHARED_MEMORY_BLOCKS_DEFAULT 16000
#define TME_BLOCK_SIZE_DEFAULT 64
#define TME_EXTRA_SEGMENT_SIZE_DEFAULT 0
#define TME_LOOKUP_CODE_DEFAULT 0
#define TME_OUT_LUT_EXEC_DEFAULT 0
#define TME_DEFAULT_EXEC_DEFAULT 0
#define TME_MAX_FILL_STATE_DEFAULT 15000
#define IS_VALIDATED(src,index) (src&(1<<index))
@ -106,32 +106,32 @@ typedef uint32 (*exec_fcn)(uint8 *block, uint32 pkt_size, void *data, MEM_TYPE *
typedef struct __RECORD
{
uint32 block;
uint32 exec_fcn;
uint32 block;
uint32 exec_fcn;
}
RECORD, *PRECORD;
RECORD, *PRECORD;
/* TME data registers */
struct __TME_DATA
{
uint32 lut_entries;
uint32 max_fill_state;
uint32 rehashing_value;
uint32 key_len;
uint32 shared_memory_blocks;
uint32 filled_entries;
uint32 block_size;
uint32 extra_segment_size;
uint32 filled_blocks;
lut_fcn lookup_code;
uint32 default_exec;
uint32 out_lut_exec;
uint8 *lut_base_address;
uint8 *shared_memory_base_address;
uint8 *extra_segment_base_address;
struct timeval last_read;
uint32 enable_deletion;
uint8 *last_found;
uint32 lut_entries;
uint32 max_fill_state;
uint32 rehashing_value;
uint32 key_len;
uint32 shared_memory_blocks;
uint32 filled_entries;
uint32 block_size;
uint32 extra_segment_size;
uint32 filled_blocks;
lut_fcn lookup_code;
uint32 default_exec;
uint32 out_lut_exec;
uint8 *lut_base_address;
uint8 *shared_memory_base_address;
uint8 *extra_segment_base_address;
struct timeval last_read;
uint32 enable_deletion;
uint8 *last_found;
};
typedef struct __TME_DATA TME_DATA,*PTME_DATA;
@ -141,25 +141,25 @@ typedef struct __TME_DATA TME_DATA,*PTME_DATA;
/* TME core */
typedef struct __TME_CORE
{
uint32 working;
uint32 active;
uint32 validated_blocks;
TME_DATA block_data[MAX_TME_DATA_BLOCKS];
uint32 active_read;
uint32 working;
uint32 active;
uint32 validated_blocks;
TME_DATA block_data[MAX_TME_DATA_BLOCKS];
uint32 active_read;
} TME_CORE, *PTME_CORE;
static __inline int32 IS_DELETABLE(void *timestamp, TME_DATA *data)
{
struct timeval *ts=(struct timeval*)timestamp;
struct timeval *ts=(struct timeval*)timestamp;
if (data->enable_deletion==FALSE)
return FALSE;
if (data->filled_entries<data->max_fill_state)
return FALSE;
if ((ts->tv_sec+DELTA_READ)<data->last_read.tv_sec)
return TRUE;
return FALSE;
if (data->enable_deletion==FALSE)
return FALSE;
if (data->filled_entries<data->max_fill_state)
return FALSE;
if ((ts->tv_sec+DELTA_READ)<data->last_read.tv_sec)
return TRUE;
return FALSE;
}
/* functions to manage TME */

View file

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
@ -37,7 +37,7 @@
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/drivers/net/packet/win_bpf.h,v 1.2 2002/09/24 15:16:46 robd Exp $ (LBL)
* @(#) $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/drivers/net/packet/win_bpf.h,v 1.3 2002/12/21 04:46:09 robd Exp $ (LBL)
*/
#ifndef BPF_MAJOR_VERSION
@ -45,12 +45,12 @@
/* BSD style release date */
#define BPF_RELEASE 199606
typedef UCHAR u_char;
typedef USHORT u_short;
typedef ULONG u_int;
typedef LONG bpf_int32;
typedef ULONG bpf_u_int32;
typedef ULONG u_int32;
typedef UCHAR u_char;
typedef USHORT u_short;
typedef ULONG u_int;
typedef LONG bpf_int32;
typedef ULONG bpf_u_int32;
typedef ULONG u_int32;
#define BPF_MAXINSNS 512
#define BPF_MAXBUFSIZE 0x8000
@ -62,26 +62,26 @@ typedef ULONG u_int32;
* The instruction data structure.
*/
struct bpf_insn {
u_short code;
u_char jt;
u_char jf;
bpf_int32 k;
u_short code;
u_char jt;
u_char jf;
bpf_int32 k;
};
/*
* Structure for BIOCSETF.
*/
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
u_int bf_len;
struct bpf_insn *bf_insns;
};
/*
* Struct returned by BIOCGSTATS.
*/
struct bpf_stat {
u_int bs_recv; /* number of packets received */
u_int bs_drop; /* number of packets dropped */
u_int bs_recv; /* number of packets received */
u_int bs_drop; /* number of packets dropped */
};
/*
@ -96,8 +96,8 @@ struct bpf_stat {
* It has nothing to do with the source code version.
*/
struct bpf_version {
u_short bv_major;
u_short bv_minor;
u_short bv_major;
u_short bv_minor;
};
/* Current version number of filter architecture. */
#define BPF_MAJOR_VERSION 1
@ -108,11 +108,11 @@ struct bpf_version {
* Structure prepended to each packet.
*/
struct bpf_hdr {
struct timeval bh_tstamp; /* time stamp */
bpf_u_int32 bh_caplen; /* length of captured portion */
bpf_u_int32 bh_datalen; /* original length of packet */
u_short bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
struct timeval bh_tstamp; /* time stamp */
bpf_u_int32 bh_caplen; /* length of captured portion */
bpf_u_int32 bh_datalen; /* original length of packet */
u_short bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
};
/*
@ -129,17 +129,17 @@ struct bpf_hdr {
* differ from those here, they should use their values, not the ones
* here).
*/
#define DLT_NULL 0 /* no link-layer encapsulation */
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
#define DLT_AX25 3 /* Amateur Radio AX.25 */
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
#define DLT_CHAOS 5 /* Chaos */
#define DLT_IEEE802 6 /* IEEE 802 Networks */
#define DLT_ARCNET 7 /* ARCNET */
#define DLT_SLIP 8 /* Serial Line IP */
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
#define DLT_NULL 0 /* no link-layer encapsulation */
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
#define DLT_AX25 3 /* Amateur Radio AX.25 */
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
#define DLT_CHAOS 5 /* Chaos */
#define DLT_IEEE802 6 /* IEEE 802 Networks */
#define DLT_ARCNET 7 /* ARCNET */
#define DLT_SLIP 8 /* Serial Line IP */
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
/*
* These are values from the traditional libpcap "bpf.h".
@ -147,8 +147,8 @@ struct bpf_hdr {
* with the ones appropriate to that platform, if the values are
* different on that platform.
*/
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
#define DLT_RAW 12 /* raw IP */
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
#define DLT_RAW 12 /* raw IP */
/*
* These are values from BSD/OS's "bpf.h".
@ -163,17 +163,17 @@ struct bpf_hdr {
* continue to compile - even though they won't correctly read
* files of these types.
*/
#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
/*
* This value is defined by NetBSD; other platforms should refrain from
* using it for other purposes, so that NetBSD savefiles with a link
* type of 50 can be read as this type on all platforms.
*/
#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
/*
* This value was defined by libpcap 0.5; platforms that have defined
@ -189,8 +189,8 @@ struct bpf_hdr {
* libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
* for source compatibility with programs written for libpcap 0.5.
*/
#define DLT_C_HDLC 104 /* Cisco HDLC */
#define DLT_CHDLC DLT_C_HDLC
#define DLT_C_HDLC 104 /* Cisco HDLC */
#define DLT_CHDLC DLT_C_HDLC
/*
* Reserved for future use.
@ -202,7 +202,7 @@ struct bpf_hdr {
* on one platform to be read on other platforms, even if the two
* platforms don't use the same numerical values for all DLT_ types).
*/
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
/*
* Values between 106 and 107 are used in capture file headers as
@ -219,7 +219,7 @@ struct bpf_hdr {
* define DLT_LOOP as 12 in its version, as per the comment above -
* and should not use 108 for any purpose.
*/
#define DLT_LOOP 108
#define DLT_LOOP 108
/*
* Values between 109 and 112 are used in capture file headers as
@ -230,85 +230,85 @@ struct bpf_hdr {
/*
* This is for Linux cooked sockets.
*/
#define DLT_LINUX_SLL 113
#define DLT_LINUX_SLL 113
/*
* The instruction encodings.
*/
/* instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
#define BPF_TXA 0x80
#define BPF_TAX 0x00
#define BPF_TXA 0x80
/* TME instructions */
#define BPF_TME 0x08
#define BPF_TME 0x08
#define BPF_LOOKUP 0x90
#define BPF_EXECUTE 0xa0
#define BPF_INIT 0xb0
#define BPF_VALIDATE 0xc0
#define BPF_SET_ACTIVE 0xd0
#define BPF_RESET 0xe0
#define BPF_SET_MEMORY 0x80
#define BPF_GET_REGISTER_VALUE 0x70
#define BPF_SET_REGISTER_VALUE 0x60
#define BPF_SET_WORKING 0x50
#define BPF_SET_ACTIVE_READ 0x40
#define BPF_SET_AUTODELETION 0x30
#define BPF_SEPARATION 0xff
#define BPF_LOOKUP 0x90
#define BPF_EXECUTE 0xa0
#define BPF_INIT 0xb0
#define BPF_VALIDATE 0xc0
#define BPF_SET_ACTIVE 0xd0
#define BPF_RESET 0xe0
#define BPF_SET_MEMORY 0x80
#define BPF_GET_REGISTER_VALUE 0x70
#define BPF_SET_REGISTER_VALUE 0x60
#define BPF_SET_WORKING 0x50
#define BPF_SET_ACTIVE_READ 0x40
#define BPF_SET_AUTODELETION 0x30
#define BPF_SEPARATION 0xff
#define BPF_MEM_EX_IMM 0xc0
#define BPF_MEM_EX_IND 0xe0
#define BPF_MEM_EX_IMM 0xc0
#define BPF_MEM_EX_IND 0xe0
/*used for ST */
#define BPF_MEM_EX 0xc0
#define BPF_MEM_EX 0xc0
/*

View file

@ -135,6 +135,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(A),"=c"(tmp2): );
#endif
continue;
@ -154,6 +164,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(X),"=c"(tmp2): );
#endif
continue;
@ -172,6 +192,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(A),"=c"(tmp): );
#endif
continue;
@ -190,6 +220,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(X),"=c"(tmp): );
#endif
continue;
@ -221,6 +261,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(A),"=c"(tmp2): );
#endif
continue;
@ -243,6 +293,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(A),"=c"(tmp): );
#endif
continue;
/* END LD NO PACKET INSTRUCTIONS */
@ -279,6 +339,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(A),"=c"(tmp): );
#endif
continue;
@ -297,6 +367,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(X),"=c"(tmp): );
#endif
continue;
@ -315,6 +395,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(A),"=c"(tmp2): );
#endif
continue;
@ -333,6 +423,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(X),"=c"(tmp2): );
#endif
continue;
@ -354,6 +454,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(A),"=c"(tmp): );
#endif
continue;
@ -372,6 +482,16 @@ uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE
pop eax
}
#else
asm("push %%eax;"
"push %%ebx;"
"mov %1,%%ebx;"
"xor %%eax, %%eax;"
"mov (%%ebx), %%ax;"
"bswap %%eax;"
"mov %%eax, %0;"
"pop %%ebx;"
"pop %%eax;"
:"=a"(A),"=c"(tmp2): );
#endif
continue;
/* END STORE INSTRUCTIONS */

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2001
* Politecnico di Torino. All rights reserved.
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@ -23,8 +23,8 @@
#include "tme.h"
#define INIT_OK 1
#define INIT_ERROR 0
#define INIT_OK 1
#define INIT_ERROR 0
uint32 bpf_filter_init(register struct bpf_insn *pc,MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref);

View file

@ -27,6 +27,12 @@
#else
#include <ddk/ntddk.h>
#include <net/ndis.h>
#define NdisReinitializePacket(Packet) \
{ \
(Packet)->Private.Head = (PNDIS_BUFFER)NULL; \
(Packet)->Private.ValidCounts = FALSE; \
}
#endif
#include "debug.h"
@ -34,8 +40,8 @@
//-------------------------------------------------------------------
NTSTATUS
//STDCALL
NPF_Write(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
@ -48,17 +54,22 @@ NPF_Write(
UINT i;
NDIS_STATUS Status;
IF_LOUD(DbgPrint("Packet: SendAdapter\n");)
IF_LOUD(DbgPrint("NPF_Write\n");)
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Open=IrpSp->FileObject->FsContext;
// Check the length of the packet to avoid to use an empty packet
if(IrpSp->Parameters.Write.Length==0)
IF_LOUD(DbgPrint("Max frame size = %d\n", Open->MaxFrameSize);)
if(IrpSp->Parameters.Write.Length == 0 || // Check that the buffer provided by the user is not empty
Open->MaxFrameSize == 0 || // Check that the MaxFrameSize is correctly initialized
IrpSp->Parameters.Write.Length > Open->MaxFrameSize) // Check that the fame size is smaller that the MTU
{
IF_LOUD(DbgPrint("frame size out of range, send aborted\n");)
Irp->IoStatus.Status = NDIS_STATUS_SUCCESS;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return NDIS_STATUS_SUCCESS;
@ -159,6 +170,15 @@ NPF_BufferedWrite(
return 0;
}
// Check that the MaxFrameSize is correctly initialized
if(Open->MaxFrameSize == 0)
{
IF_LOUD(DbgPrint("BufferedWrite: Open->MaxFrameSize not initialized, probably because of a problem in the OID query\n");)
return 0;
}
// Start from the first packet
winpcap_hdr = (struct sf_pkthdr*)UserBuff;
@ -181,10 +201,10 @@ NPF_BufferedWrite(
// Main loop: send the buffer to the wire
while( TRUE ){
if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > 65536)
if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > Open->MaxFrameSize)
{
// Malformed header
IF_LOUD(DbgPrint("NPF_BufferedWrite: malformed user buffer, aborting write.\n");)
IF_LOUD(DbgPrint("NPF_BufferedWrite: malformed or bogus user buffer, aborting write.\n");)
return -1;
}
@ -247,7 +267,6 @@ NPF_BufferedWrite(
if( Sync ){
#if 0
// Release the application if it has been blocked for approximately more than 1 seconds
if( winpcap_hdr->ts.tv_sec - BufStartTime.tv_sec > 1 )
{
@ -256,17 +275,18 @@ NPF_BufferedWrite(
return (PCHAR)winpcap_hdr - UserBuff;
}
#ifndef __GNUC__
// Calculate the time interval to wait before sending the next packet
TargetTicks.QuadPart = StartTicks.QuadPart +
TargetTicks.QuadPart = StartTicks.QuadPart +
(LONGLONG)((winpcap_hdr->ts.tv_sec - BufStartTime.tv_sec) * 1000000 +
winpcap_hdr->ts.tv_usec - BufStartTime.tv_usec) *
(TimeFreq.QuadPart) / 1000000;
// Wait until the time interval has elapsed
while( CurTicks.QuadPart <= TargetTicks.QuadPart )
CurTicks = KeQueryPerformanceCounter(NULL);
#else
#endif
}
}
@ -330,3 +350,17 @@ NPF_SendComplete(
return;
}
#ifdef __GNUC__
/*
__divdi3()
{
//_alldiv();
}
//_allmul();
//_allrem();
*/
#endif