mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2025-11-19 18:01:33 +03:00
v4.03-9408-rtm
This commit is contained in:
63
src/See/DEBUG.H
Normal file
63
src/See/DEBUG.H
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DEBUG_INCLUDE
|
||||
#define __DEBUG_INCLUDE
|
||||
|
||||
|
||||
#if DBG
|
||||
|
||||
#define IF_PACKETDEBUG(f) if (PacketDebugFlag & (f))
|
||||
extern ULONG PacketDebugFlag;
|
||||
|
||||
#define PACKET_DEBUG_LOUD 0x00000001 // debugging info
|
||||
#define PACKET_DEBUG_VERY_LOUD 0x00000002 // excessive debugging info
|
||||
|
||||
#define PACKET_DEBUG_INIT 0x00000100 // init debugging info
|
||||
|
||||
//
|
||||
// Macro for deciding whether to dump lots of debugging information.
|
||||
//
|
||||
|
||||
#define IF_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_LOUD ) { A }
|
||||
#define IF_VERY_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) { A }
|
||||
#define IF_INIT_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_INIT ) { A }
|
||||
|
||||
#else
|
||||
|
||||
#define IF_LOUD(A)
|
||||
#define IF_VERY_LOUD(A)
|
||||
#define IF_INIT_LOUD(A)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /*#define __DEBUG_INCLUDE*/
|
||||
90
src/See/Devioctl.h
Normal file
90
src/See/Devioctl.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*++ BUILD Version: 0004 // Increment this if a change has global effects
|
||||
Copyright (c) 1992-1993 Microsoft Corporation
|
||||
Module Name:
|
||||
devioctl.h
|
||||
Revision History:
|
||||
-- */
|
||||
// begin_winioctl
|
||||
#ifndef _DEVIOCTL_
|
||||
#define _DEVIOCTL_
|
||||
// begin_ntddk begin_nthal begin_ntifs
|
||||
//
|
||||
// Define the various device type values. Note that values used by Microsoft
|
||||
// Corporation are in the range 0-32767, and 32768-65535 are reserved for use
|
||||
// by customers.
|
||||
//
|
||||
#define DEVICE_TYPE ULONG
|
||||
#define FILE_DEVICE_BEEP 0x00000001
|
||||
#define FILE_DEVICE_CD_ROM 0x00000002
|
||||
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
|
||||
#define FILE_DEVICE_CONTROLLER 0x00000004
|
||||
#define FILE_DEVICE_DATALINK 0x00000005
|
||||
#define FILE_DEVICE_DFS 0x00000006
|
||||
#define FILE_DEVICE_DISK 0x00000007
|
||||
#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
|
||||
#define FILE_DEVICE_FILE_SYSTEM 0x00000009
|
||||
#define FILE_DEVICE_INPORT_PORT 0x0000000a
|
||||
#define FILE_DEVICE_KEYBOARD 0x0000000b
|
||||
#define FILE_DEVICE_MAILSLOT 0x0000000c
|
||||
#define FILE_DEVICE_MIDI_IN 0x0000000d
|
||||
#define FILE_DEVICE_MIDI_OUT 0x0000000e
|
||||
#define FILE_DEVICE_MOUSE 0x0000000f
|
||||
#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
|
||||
#define FILE_DEVICE_NAMED_PIPE 0x00000011
|
||||
#define FILE_DEVICE_NETWORK 0x00000012
|
||||
#define FILE_DEVICE_NETWORK_BROWSER 0x00000013
|
||||
#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
|
||||
#define FILE_DEVICE_NULL 0x00000015
|
||||
#define FILE_DEVICE_PARALLEL_PORT 0x00000016
|
||||
#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
|
||||
#define FILE_DEVICE_PRINTER 0x00000018
|
||||
#define FILE_DEVICE_SCANNER 0x00000019
|
||||
#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a
|
||||
#define FILE_DEVICE_SERIAL_PORT 0x0000001b
|
||||
#define FILE_DEVICE_SCREEN 0x0000001c
|
||||
#define FILE_DEVICE_SOUND 0x0000001d
|
||||
#define FILE_DEVICE_STREAMS 0x0000001e
|
||||
#define FILE_DEVICE_TAPE 0x0000001f
|
||||
#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
|
||||
#define FILE_DEVICE_TRANSPORT 0x00000021
|
||||
#define FILE_DEVICE_UNKNOWN 0x00000022
|
||||
#define FILE_DEVICE_VIDEO 0x00000023
|
||||
#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
|
||||
#define FILE_DEVICE_WAVE_IN 0x00000025
|
||||
#define FILE_DEVICE_WAVE_OUT 0x00000026
|
||||
#define FILE_DEVICE_8042_PORT 0x00000027
|
||||
#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
|
||||
#define FILE_DEVICE_BATTERY 0x00000029
|
||||
#define FILE_DEVICE_BUS_EXTENDER 0x0000002a
|
||||
#define FILE_DEVICE_MODEM 0x0000002b
|
||||
#define FILE_DEVICE_VDM 0x0000002c
|
||||
#define FILE_DEVICE_MASS_STORAGE 0x0000002d
|
||||
//
|
||||
// Macro definition for defining IOCTL and FSCTL function control codes. Note
|
||||
// that function codes 0-2047 are reserved for Microsoft Corporation, and
|
||||
// 2048-4095 are reserved for customers.
|
||||
//
|
||||
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
|
||||
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
|
||||
)
|
||||
//
|
||||
// Define the method codes for how buffers are passed for I/O and FS controls
|
||||
//
|
||||
#define METHOD_BUFFERED 0
|
||||
#define METHOD_IN_DIRECT 1
|
||||
#define METHOD_OUT_DIRECT 2
|
||||
#define METHOD_NEITHER 3
|
||||
//
|
||||
// Define the access check value for any access
|
||||
//
|
||||
//
|
||||
// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
|
||||
// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
|
||||
// constants *MUST* always be in sync.
|
||||
//
|
||||
#define FILE_ANY_ACCESS 0
|
||||
#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
|
||||
#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
|
||||
// end_ntddk end_nthal end_ntifs
|
||||
#endif // _DEVIOCTL_
|
||||
// end_winioctl
|
||||
1400
src/See/Ntddndis.h
Normal file
1400
src/See/Ntddndis.h
Normal file
File diff suppressed because it is too large
Load Diff
26
src/See/Ntddpack.h
Normal file
26
src/See/Ntddpack.h
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
#ifndef __NTDDPACKET
|
||||
#define __NTDDPACKET 1
|
||||
#include "devioctl.h"
|
||||
/*#include <packon.h> */
|
||||
struct _PACKET_OID_DATA {
|
||||
ULONG Oid;
|
||||
ULONG Length;
|
||||
UCHAR Data[1];
|
||||
};
|
||||
|
||||
typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;
|
||||
|
||||
/*#include <packoff.h> */
|
||||
#define FILE_DEVICE_PROTOCOL 0x8000
|
||||
#define IOCTL_PROTOCOL_QUERY_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 0 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PROTOCOL_SET_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 1 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PROTOCOL_STATISTICS CTL_CODE(FILE_DEVICE_PROTOCOL, 2 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PROTOCOL_RESET CTL_CODE(FILE_DEVICE_PROTOCOL, 3 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PROTOCOL_READ CTL_CODE(FILE_DEVICE_PROTOCOL, 4 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PROTOCOL_WRITE CTL_CODE(FILE_DEVICE_PROTOCOL, 5 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PROTOCOL_MACNAME CTL_CODE(FILE_DEVICE_PROTOCOL, 6 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_OPEN CTL_CODE(FILE_DEVICE_PROTOCOL, 7 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_CLOSE CTL_CODE(FILE_DEVICE_PROTOCOL, 8 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#endif
|
||||
707
src/See/Openclos.c
Normal file
707
src/See/Openclos.c
Normal file
@ -0,0 +1,707 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||
* Copyright (c) 2005 CACE Technologies, Davis (California)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#include "ntddk.h"
|
||||
#include "ntiologc.h"
|
||||
#include "ndis.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "packet.h"
|
||||
|
||||
static NDIS_MEDIUM MediumArray[] = {
|
||||
NdisMedium802_3,
|
||||
// NdisMediumWan,
|
||||
NdisMediumFddi,
|
||||
NdisMediumArcnet878_2,
|
||||
NdisMediumAtm,
|
||||
NdisMedium802_5
|
||||
};
|
||||
|
||||
#define NUM_NDIS_MEDIA (sizeof MediumArray / sizeof MediumArray[0])
|
||||
|
||||
ULONG NamedEventsCounter=0;
|
||||
|
||||
//Itoa. Replaces the buggy RtlIntegerToUnicodeString
|
||||
void PacketItoa(UINT n,PUCHAR buf){
|
||||
int i;
|
||||
|
||||
for(i=0;i<20;i+=2){
|
||||
buf[18-i]=(n%10)+48;
|
||||
buf[19-i]=0;
|
||||
n/=10;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Global start time. Used as an absolute reference for timestamp conversion.
|
||||
struct time_conv G_Start_Time = {
|
||||
0,
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
UINT n_Opened_Instances = 0;
|
||||
|
||||
NDIS_SPIN_LOCK Opened_Instances_Lock;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
NTSTATUS NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
||||
{
|
||||
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
POPEN_INSTANCE Open;
|
||||
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
|
||||
NDIS_STATUS Status;
|
||||
NDIS_STATUS ErrorStatus;
|
||||
UINT i;
|
||||
PCHAR EvName;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: OpenAdapter\n");)
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
// allocate some memory for the open structure
|
||||
Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), '0OWA');
|
||||
|
||||
if (Open==NULL) {
|
||||
// no memory
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlZeroMemory(
|
||||
Open,
|
||||
sizeof(OPEN_INSTANCE)
|
||||
);
|
||||
|
||||
|
||||
EvName=ExAllocatePoolWithTag(NonPagedPool, sizeof(L"\\BaseNamedObjects\\SEE0000000000"), '1OWA');
|
||||
|
||||
if (EvName==NULL) {
|
||||
// no memory
|
||||
ExFreePool(Open);
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
// Save or open here
|
||||
IrpSp->FileObject->FsContext=Open;
|
||||
|
||||
Open->DeviceExtension=DeviceExtension;
|
||||
|
||||
|
||||
// Save the Irp here for the completeion routine to retrieve
|
||||
Open->OpenCloseIrp=Irp;
|
||||
|
||||
// Allocate a packet pool for our xmit and receive packets
|
||||
NdisAllocatePacketPool(
|
||||
&Status,
|
||||
&Open->PacketPool,
|
||||
TRANSMIT_PACKETS,
|
||||
sizeof(PACKET_RESERVED));
|
||||
|
||||
|
||||
if (Status != NDIS_STATUS_SUCCESS) {
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: Failed to allocate packet pool\n");)
|
||||
|
||||
ExFreePool(Open);
|
||||
ExFreePool(EvName);
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
||||
RtlCopyBytes(EvName,L"\\BaseNamedObjects\\SEE0000000000",sizeof(L"\\BaseNamedObjects\\SEE0000000000"));
|
||||
|
||||
//Create the string containing the name of the read event
|
||||
RtlInitUnicodeString(&Open->ReadEventName,(PCWSTR) EvName);
|
||||
|
||||
PacketItoa(NamedEventsCounter,(PUCHAR)(Open->ReadEventName.Buffer+21));
|
||||
|
||||
InterlockedIncrement(&NamedEventsCounter);
|
||||
|
||||
IF_LOUD(DbgPrint("\nCreated the named event for the read; name=%ws, counter=%d\n", Open->ReadEventName.Buffer,NamedEventsCounter-1);)
|
||||
|
||||
//allocate the event objects
|
||||
Open->ReadEvent=IoCreateNotificationEvent(&Open->ReadEventName,&Open->ReadEventHandle);
|
||||
if(Open->ReadEvent==NULL){
|
||||
ExFreePool(Open);
|
||||
ExFreePool(EvName);
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
KeInitializeEvent(Open->ReadEvent, NotificationEvent, FALSE);
|
||||
KeClearEvent(Open->ReadEvent);
|
||||
NdisInitializeEvent(&Open->WriteEvent);
|
||||
NdisInitializeEvent(&Open->IOEvent);
|
||||
NdisInitializeEvent(&Open->DumpEvent);
|
||||
NdisAllocateSpinLock(&Open->MachineLock);
|
||||
NdisAllocateSpinLock(&Open->WriteLock);
|
||||
Open->WriteInProgress = FALSE;
|
||||
|
||||
// list to hold irp's want to reset the adapter
|
||||
InitializeListHead(&Open->ResetIrpList);
|
||||
|
||||
|
||||
// Initialize the request list
|
||||
KeInitializeSpinLock(&Open->RequestSpinLock);
|
||||
InitializeListHead(&Open->RequestList);
|
||||
|
||||
// Initializes the extended memory of the NPF machine
|
||||
Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, '2OWA');
|
||||
if((Open->mem_ex.buffer) == NULL)
|
||||
{
|
||||
// no memory
|
||||
ExFreePool(Open);
|
||||
ExFreePool(EvName);
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Open->mem_ex.size = DEFAULT_MEM_EX_SIZE;
|
||||
RtlZeroMemory(Open->mem_ex.buffer, DEFAULT_MEM_EX_SIZE);
|
||||
|
||||
//
|
||||
// Initialize the open instance
|
||||
//
|
||||
// Open->BufSize = 0;
|
||||
// Open->Buffer = NULL;
|
||||
// Open->Bhead = 0;
|
||||
// Open->Btail = 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
|
||||
Open->bpfprogram = NULL; //reset the filter
|
||||
Open->mode = MODE_CAPT;
|
||||
Open->Nbytes.QuadPart = 0;
|
||||
Open->Npackets.QuadPart = 0;
|
||||
Open->Nwrites = 1;
|
||||
Open->Multiple_Write_Counter = 0;
|
||||
Open->MinToCopy = 0;
|
||||
Open->TimeOut.QuadPart = (LONGLONG)1;
|
||||
Open->Bound = TRUE;
|
||||
Open->DumpFileName.Buffer = NULL;
|
||||
Open->DumpFileHandle = NULL;
|
||||
Open->tme.active = TME_NONE_ACTIVE;
|
||||
Open->DumpLimitReached = FALSE;
|
||||
Open->MaxFrameSize = 0;
|
||||
Open->WriterSN=0;
|
||||
Open->ReaderSN=0;
|
||||
Open->Size=0;
|
||||
|
||||
|
||||
|
||||
//allocate the spinlock for the statistic counters
|
||||
NdisAllocateSpinLock(&Open->CountersLock);
|
||||
|
||||
//allocate the spinlock for the buffer pointers
|
||||
// NdisAllocateSpinLock(&Open->BufLock);
|
||||
|
||||
//
|
||||
// link up the request stored in our open block
|
||||
//
|
||||
for (i=0;i<MAX_REQUESTS;i++) {
|
||||
ExInterlockedInsertTailList(
|
||||
&Open->RequestList,
|
||||
&Open->Requests[i].ListElement,
|
||||
&Open->RequestSpinLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
IoMarkIrpPending(Irp);
|
||||
|
||||
//
|
||||
// Try to open the MAC
|
||||
//
|
||||
IF_LOUD(DbgPrint("NPF: Openinig the device %ws, BindingContext=%d\n",DeviceExtension->AdapterName.Buffer, Open);)
|
||||
|
||||
NdisOpenAdapter(
|
||||
&Status,
|
||||
&ErrorStatus,
|
||||
&Open->AdapterHandle,
|
||||
&Open->Medium,
|
||||
MediumArray,
|
||||
NUM_NDIS_MEDIA,
|
||||
DeviceExtension->NdisProtocolHandle,
|
||||
Open,
|
||||
&DeviceExtension->AdapterName,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: Opened the device, Status=%x\n",Status);)
|
||||
|
||||
if (Status != NDIS_STATUS_PENDING)
|
||||
{
|
||||
NPF_OpenAdapterComplete(Open,Status,NDIS_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
return(STATUS_PENDING);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID NPF_OpenAdapterComplete(
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN NDIS_STATUS Status,
|
||||
IN NDIS_STATUS OpenErrorStatus)
|
||||
{
|
||||
|
||||
PIRP Irp;
|
||||
POPEN_INSTANCE Open;
|
||||
PLIST_ENTRY RequestListEntry;
|
||||
PINTERNAL_REQUEST MaxSizeReq;
|
||||
NDIS_STATUS ReqStatus;
|
||||
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: OpenAdapterComplete\n");)
|
||||
|
||||
Open= (POPEN_INSTANCE)ProtocolBindingContext;
|
||||
|
||||
//
|
||||
// get the open irp
|
||||
//
|
||||
Irp=Open->OpenCloseIrp;
|
||||
|
||||
if (Status != NDIS_STATUS_SUCCESS) {
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: OpenAdapterComplete-FAILURE\n");)
|
||||
|
||||
NdisFreePacketPool(Open->PacketPool);
|
||||
|
||||
//free mem_ex
|
||||
Open->mem_ex.size = 0;
|
||||
if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer);
|
||||
|
||||
ExFreePool(Open->ReadEventName.Buffer);
|
||||
|
||||
ZwClose(Open->ReadEventHandle);
|
||||
|
||||
|
||||
ExFreePool(Open);
|
||||
}
|
||||
else {
|
||||
NdisAcquireSpinLock(&Opened_Instances_Lock);
|
||||
n_Opened_Instances++;
|
||||
NdisReleaseSpinLock(&Opened_Instances_Lock);
|
||||
|
||||
IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);)
|
||||
|
||||
// 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 = 1560; // 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;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
NTSTATUS
|
||||
NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
|
||||
{
|
||||
|
||||
POPEN_INSTANCE Open;
|
||||
NDIS_STATUS Status;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
LARGE_INTEGER ThreadDelay;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: CloseAdapter\n");)
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Open=IrpSp->FileObject->FsContext;
|
||||
|
||||
// Reset the buffer size. This tells the dump thread to stop.
|
||||
// Open->BufSize = 0;
|
||||
|
||||
if( Open->Bound == FALSE){
|
||||
|
||||
NdisWaitEvent(&Open->IOEvent,10000);
|
||||
|
||||
// Free the filter if it's present
|
||||
if(Open->bpfprogram != NULL)
|
||||
ExFreePool(Open->bpfprogram);
|
||||
|
||||
//
|
||||
// Jitted filters are supported on x86 (32bit) only
|
||||
//
|
||||
#ifdef __NPF_x86__
|
||||
// Free the jitted filter if it's present
|
||||
if(Open->Filter != NULL)
|
||||
BPF_Destroy_JIT_Filter(Open->Filter);
|
||||
#endif
|
||||
|
||||
//free the buffer
|
||||
// Open->BufSize=0;
|
||||
// if(Open->Buffer != NULL)ExFreePool(Open->Buffer);
|
||||
|
||||
if (Open->Size > 0)
|
||||
ExFreePool(Open->CpuData[0].Buffer);
|
||||
|
||||
//free mem_ex
|
||||
Open->mem_ex.size = 0;
|
||||
if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer);
|
||||
|
||||
NdisFreePacketPool(Open->PacketPool);
|
||||
|
||||
// Free the string with the name of the dump file
|
||||
if(Open->DumpFileName.Buffer!=NULL)
|
||||
ExFreePool(Open->DumpFileName.Buffer);
|
||||
|
||||
ExFreePool(Open->ReadEventName.Buffer);
|
||||
ExFreePool(Open);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
// Unfreeze the consumer
|
||||
if(Open->mode & MODE_DUMP)
|
||||
NdisSetEvent(&Open->DumpEvent);
|
||||
else
|
||||
KeSetEvent(Open->ReadEvent,0,FALSE);
|
||||
|
||||
// Save the IRP
|
||||
Open->OpenCloseIrp = Irp;
|
||||
|
||||
IoMarkIrpPending(Irp);
|
||||
|
||||
// If this instance is in dump mode, complete the dump and close the file
|
||||
if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL){
|
||||
|
||||
NTSTATUS wres;
|
||||
|
||||
ThreadDelay.QuadPart = -50000000;
|
||||
// Wait the completion of the thread
|
||||
wres = KeWaitForSingleObject(Open->DumpThreadObject,
|
||||
UserRequest,
|
||||
KernelMode,
|
||||
TRUE,
|
||||
&ThreadDelay);
|
||||
|
||||
ObDereferenceObject(Open->DumpThreadObject);
|
||||
|
||||
|
||||
// Flush and close the dump file
|
||||
NPF_CloseDumpFile(Open);
|
||||
}
|
||||
|
||||
// Destroy the read Event
|
||||
ZwClose(Open->ReadEventHandle);
|
||||
|
||||
// Close the adapter
|
||||
NdisCloseAdapter(
|
||||
&Status,
|
||||
Open->AdapterHandle
|
||||
);
|
||||
|
||||
if (Status != NDIS_STATUS_PENDING) {
|
||||
|
||||
NPF_CloseAdapterComplete(
|
||||
Open,
|
||||
Status
|
||||
);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
return(STATUS_PENDING);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID
|
||||
NPF_CloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status)
|
||||
{
|
||||
POPEN_INSTANCE Open;
|
||||
PIRP Irp;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: CloseAdapterComplete\n");)
|
||||
|
||||
Open= (POPEN_INSTANCE)ProtocolBindingContext;
|
||||
|
||||
// free the allocated structures only if the instance is still bound to the adapter
|
||||
if(Open->Bound == TRUE){
|
||||
|
||||
// Free the filter if it's present
|
||||
if(Open->bpfprogram != NULL)
|
||||
ExFreePool(Open->bpfprogram);
|
||||
|
||||
//
|
||||
// Jitted filters are supported on x86 (32bit) only
|
||||
//
|
||||
#ifdef __NPF_x86__
|
||||
// Free the jitted filter if it's present
|
||||
if(Open->Filter != NULL)
|
||||
BPF_Destroy_JIT_Filter(Open->Filter);
|
||||
#endif // __NPF_x86__
|
||||
|
||||
//free the buffer
|
||||
// Open->BufSize = 0;
|
||||
// if(Open->Buffer!=NULL)ExFreePool(Open->Buffer);
|
||||
|
||||
if (Open->Size > 0)
|
||||
ExFreePool(Open->CpuData[0].Buffer);
|
||||
|
||||
//free mem_ex
|
||||
Open->mem_ex.size = 0;
|
||||
if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer);
|
||||
|
||||
NdisFreePacketPool(Open->PacketPool);
|
||||
|
||||
Irp=Open->OpenCloseIrp;
|
||||
|
||||
// Free the string with the name of the dump file
|
||||
if(Open->DumpFileName.Buffer!=NULL)
|
||||
ExFreePool(Open->DumpFileName.Buffer);
|
||||
|
||||
ExFreePool(Open->ReadEventName.Buffer);
|
||||
ExFreePool(Open);
|
||||
|
||||
// Complete the request only if the instance is still bound to the adapter
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
else
|
||||
NdisSetEvent(&Open->IOEvent);
|
||||
|
||||
// Decrease the counter of open instances
|
||||
NdisAcquireSpinLock(&Opened_Instances_Lock);
|
||||
n_Opened_Instances--;
|
||||
NdisReleaseSpinLock(&Opened_Instances_Lock);
|
||||
|
||||
IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);)
|
||||
|
||||
if(n_Opened_Instances == 0){
|
||||
// Force a synchronization at the next NPF_Open().
|
||||
// This hopefully avoids the synchronization issues caused by hibernation or standby.
|
||||
TIME_DESYNCHRONIZE(&G_Start_Time);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
#ifdef NDIS50
|
||||
NDIS_STATUS
|
||||
NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent)
|
||||
{
|
||||
IF_LOUD(DbgPrint("NPF: PowerChange\n");)
|
||||
|
||||
TIME_DESYNCHRONIZE(&G_Start_Time);
|
||||
|
||||
TIME_SYNCHRONIZE(&G_Start_Time);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID
|
||||
NPF_BindAdapter(
|
||||
OUT PNDIS_STATUS Status,
|
||||
IN NDIS_HANDLE BindContext,
|
||||
IN PNDIS_STRING DeviceName,
|
||||
IN PVOID SystemSpecific1,
|
||||
IN PVOID SystemSpecific2
|
||||
)
|
||||
{
|
||||
IF_LOUD(DbgPrint("NPF: NPF_BindAdapter\n");)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID
|
||||
NPF_UnbindAdapter(
|
||||
OUT PNDIS_STATUS Status,
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN NDIS_HANDLE UnbindContext
|
||||
)
|
||||
{
|
||||
POPEN_INSTANCE Open =(POPEN_INSTANCE)ProtocolBindingContext;
|
||||
NDIS_STATUS lStatus;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: NPF_UnbindAdapter\n");)
|
||||
|
||||
// Reset the buffer size. This tells the dump thread to stop.
|
||||
// Open->BufSize=0;
|
||||
|
||||
NdisResetEvent(&Open->IOEvent);
|
||||
|
||||
// This open instance is no more bound to the adapter, set Bound to False
|
||||
InterlockedExchange( (PLONG) &Open->Bound, FALSE );
|
||||
|
||||
// Awake a possible pending read on this instance
|
||||
if(Open->mode & MODE_DUMP)
|
||||
NdisSetEvent(&Open->DumpEvent);
|
||||
else
|
||||
KeSetEvent(Open->ReadEvent,0,FALSE);
|
||||
|
||||
// If this instance is in dump mode, complete the dump and close the file
|
||||
if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL)
|
||||
NPF_CloseDumpFile(Open);
|
||||
|
||||
// Destroy the read Event
|
||||
ZwClose(Open->ReadEventHandle);
|
||||
|
||||
// close the adapter
|
||||
NdisCloseAdapter(
|
||||
&lStatus,
|
||||
Open->AdapterHandle
|
||||
);
|
||||
|
||||
if (lStatus != NDIS_STATUS_PENDING) {
|
||||
|
||||
NPF_CloseAdapterComplete(
|
||||
Open,
|
||||
lStatus
|
||||
);
|
||||
|
||||
*Status = NDIS_STATUS_SUCCESS;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
*Status = NDIS_STATUS_SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID
|
||||
NPF_ResetComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status)
|
||||
|
||||
{
|
||||
POPEN_INSTANCE Open;
|
||||
PIRP Irp;
|
||||
|
||||
PLIST_ENTRY ResetListEntry;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: PacketResetComplte\n");)
|
||||
|
||||
Open= (POPEN_INSTANCE)ProtocolBindingContext;
|
||||
|
||||
|
||||
//
|
||||
// remove the reset IRP from the list
|
||||
//
|
||||
ResetListEntry=ExInterlockedRemoveHeadList(
|
||||
&Open->ResetIrpList,
|
||||
&Open->RequestSpinLock
|
||||
);
|
||||
|
||||
#if DBG
|
||||
if (ResetListEntry == NULL) {
|
||||
DbgBreakPoint();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Irp=CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: PacketResetComplte exit\n");)
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
1607
src/See/Packet.c
Normal file
1607
src/See/Packet.c
Normal file
File diff suppressed because it is too large
Load Diff
954
src/See/Packet.h
Normal file
954
src/See/Packet.h
Normal file
@ -0,0 +1,954 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||
* Copyright (c) 2005 CACE Technologies, Davis (California)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @ingroup NPF
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup NPF_include NPF structures and definitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __PACKET_INCLUDE______
|
||||
#define __PACKET_INCLUDE______
|
||||
|
||||
#ifdef __NPF_x86__
|
||||
#define NTKERNEL ///< Forces the compilation of the jitter with kernel calls
|
||||
#include "jitter.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "win_bpf.h"
|
||||
|
||||
#define MAX_REQUESTS 256 ///< 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.
|
||||
/***************************/
|
||||
/* IOCTLs */
|
||||
/***************************/
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: set kernel buffer size.
|
||||
|
||||
This IOCTL is used to set a new size of the circular buffer associated with an instance of NPF.
|
||||
When a BIOCSETBUFFERSIZE command is received, the driver frees the old buffer, allocates the new one
|
||||
and resets all the parameters associated with the buffer in the OPEN_INSTANCE structure. The currently
|
||||
buffered packets are lost.
|
||||
*/
|
||||
#define BIOCSETBUFFERSIZE 9592
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: set packet filtering program.
|
||||
|
||||
This IOCTL sets a new packet filter in the driver. Before allocating any memory for the new filter, the
|
||||
bpf_validate() function is called to check the correctness of the filter. If this function returns TRUE,
|
||||
the filter is copied to the driver's memory, its address is stored in the bpfprogram field of the
|
||||
OPEN_INSTANCE structure associated with current instance of the driver, and the filter will be applied to
|
||||
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
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: get the capture stats
|
||||
|
||||
This command returns to the application the number of packets received and the number of packets dropped by
|
||||
an instance of the driver.
|
||||
*/
|
||||
#define BIOCGSTATS 9031
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: set the read timeout
|
||||
|
||||
This command sets the maximum timeout after which a read is released, also if no data packets were received.
|
||||
*/
|
||||
#define BIOCSRTIMEOUT 7416
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: set working mode
|
||||
|
||||
This IOCTL can be used to set the working mode of a NPF instance. The new mode, received by the driver in the
|
||||
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
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: set number of physical repetions of every packet written by the app
|
||||
|
||||
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
|
||||
|
||||
/*!
|
||||
\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
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: set an OID value
|
||||
|
||||
This IOCTL is used to perform an OID set operation on the NIC driver.
|
||||
*/
|
||||
#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 BIOCISETLOBBEH 7410
|
||||
/*!
|
||||
\brief IOCTL code: set the name of a the file used by kernel dump mode
|
||||
|
||||
This command opens a file whose name is contained in the IOCTL buffer and associates it with current NPf instance.
|
||||
The dump thread uses it to copy the content of the circular buffer to file.
|
||||
If a file was already opened, the driver closes it before opening the new one.
|
||||
*/
|
||||
#define BIOCSETDUMPFILENAME 9029
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: get the name of the event that the driver signals when some data is present in the buffer
|
||||
|
||||
Command used by the application to retrieve the name of the global event associated with a NPF instance.
|
||||
The event is signaled by the driver when the kernel buffer contains enough data for a transfer.
|
||||
*/
|
||||
#define BIOCGEVNAME 7415
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: Send a buffer containing multiple packets to the network, ignoring the timestamps.
|
||||
|
||||
Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by
|
||||
a sf_pkthdr structure. The timestamps of the packets are ignored, i.e. the packets are sent as fast as
|
||||
possible. The NPF_BufferedWrite() function is invoked to send the packets.
|
||||
*/
|
||||
#define BIOCSENDPACKETSNOSYNC 9032
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: Send a buffer containing multiple packets to the network, considering the timestamps.
|
||||
|
||||
Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by
|
||||
a sf_pkthdr structure. The timestamps of the packets are used to synchronize the write, i.e. the packets
|
||||
are sent to the network respecting the intervals specified in the sf_pkthdr structure assiciated with each
|
||||
packet. NPF_BufferedWrite() function is invoked to send the packets.
|
||||
*/
|
||||
#define BIOCSENDPACKETSSYNC 9033
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: Set the dump file limits.
|
||||
|
||||
This IOCTL sets the limits (maximum size and maximum number of packets) of the dump file created when the
|
||||
driver works in dump mode.
|
||||
*/
|
||||
#define BIOCSETDUMPLIMITS 9034
|
||||
|
||||
/*!
|
||||
\brief IOCTL code: Get the status of the kernel dump process.
|
||||
|
||||
This command returns TRUE if the kernel dump is ended, i.e if one of the limits set with BIOCSETDUMPLIMITS
|
||||
(amount of bytes or number of packets) has been reached.
|
||||
*/
|
||||
#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 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.
|
||||
|
||||
/*!
|
||||
\brief Header of a libpcap dump file.
|
||||
|
||||
Used when a driver instance is set in dump mode to create a libpcap-compatible file.
|
||||
*/
|
||||
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.
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Header associated to a packet in the driver's buffer when the driver is in dump mode.
|
||||
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).
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Stores an OID request.
|
||||
|
||||
This structure is used by the driver to perform OID query or set operations on the underlying NIC driver.
|
||||
The OID operations be performed usually only by network drivers, but NPF exports this mechanism to user-level
|
||||
applications through an IOCTL interface. The driver uses this structure to wrap a NDIS_REQUEST structure.
|
||||
This allows to handle correctly the callback structure of NdisRequest(), handling multiple requests and
|
||||
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
|
||||
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;
|
||||
|
||||
/*!
|
||||
\brief Contains a NDIS packet.
|
||||
|
||||
The driver uses this structure to wrap a NDIS_PACKET structure.
|
||||
This allows to handle correctly the callback structure of NdisTransferData(), handling multiple requests and
|
||||
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().
|
||||
ULONG Cpu; ///< The CPU on which the packet was pulled out of the linked list of free packets
|
||||
} PACKET_RESERVED, *PPACKET_RESERVED;
|
||||
|
||||
#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) ///< Macro to obtain a NDIS_PACKET from a PACKET_RESERVED
|
||||
|
||||
/*!
|
||||
\brief Port device extension.
|
||||
|
||||
Structure containing some data relative to every adapter on which NPF is bound.
|
||||
*/
|
||||
typedef struct _DEVICE_EXTENSION {
|
||||
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;
|
||||
|
||||
/*!
|
||||
\brief Kernel buffer of each CPU.
|
||||
|
||||
Structure containing the kernel buffer (and other CPU related fields) used to capture packets.
|
||||
*/
|
||||
typedef struct __CPU_Private_Data
|
||||
{
|
||||
ULONG P; ///< Zero-based index of the producer in the buffer. It indicates the first free byte to be written.
|
||||
ULONG C; ///< Zero-based index of the consumer in the buffer. It indicates the first free byte to be read.
|
||||
ULONG Free; ///< Number of the free bytes in the buffer
|
||||
PUCHAR Buffer; ///< Pointer to the kernel buffer used to capture packets.
|
||||
ULONG 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.
|
||||
///< This number is related to the particular CPU this structure is referring to.
|
||||
ULONG 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.
|
||||
///< This number is related to the particular CPU this structure is referring to.
|
||||
ULONG 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.
|
||||
///< This number is related to the particular CPU this structure is referring to.
|
||||
ULONG Processing; ///< Flag. If set to 1, it indicates that the tap is processing a packet on the CPU this structure is referring to.
|
||||
PMDL TransferMdl1; ///< MDL used to map the portion of the buffer that will contain an incoming packet.
|
||||
PMDL TransferMdl2; ///< Second MDL used to map the portion of the buffer that will contain an incoming packet.
|
||||
ULONG NewP; ///< Used by NdisTransferData() (when we call NdisTransferData, p index must be updated only in the TransferDataComplete.
|
||||
}
|
||||
CpuPrivateData;
|
||||
|
||||
|
||||
/*!
|
||||
\brief Contains the state of a running instance of the NPF driver.
|
||||
|
||||
This is the most important structure of NPF: it is used by almost all the functions of the driver. An
|
||||
_OPEN_INSTANCE structure is associated with every user-level session, allowing concurrent access
|
||||
to the driver.
|
||||
*/
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
#ifdef __NPF_x86__
|
||||
JIT_BPF_Filter *Filter; ///< Pointer to the native filtering function created by the jitter.
|
||||
///< See BPF_jitter() for details.
|
||||
#endif
|
||||
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
|
||||
ULONG 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.
|
||||
BOOLEAN WriteInProgress; ///< True if a write is currently in progress. NPF currently allows a single wite on
|
||||
///< the same open instance.
|
||||
NDIS_SPIN_LOCK WriteLock; ///< SpinLock that protects the WriteInProgress variable.
|
||||
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 MachineLock; ///< 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().
|
||||
CpuPrivateData CpuData[1024]; ///< Pool of kernel buffer structures, one for each CPU.
|
||||
ULONG ReaderSN; ///< Sequence number of the next packet to be read from the pool of kernel buffers.
|
||||
ULONG WriterSN; ///< Sequence number of the next packet to be written in the pool of kernel buffers.
|
||||
///< These two sequence numbers are unique for each capture instance.
|
||||
ULONG Size; ///< Size of each kernel buffer contained in the CpuData field.
|
||||
ULONG SkipProcessing; ///< Flag. When set to 1, the tap discards each packet. It is set to 1 by the IOCTLs that modify
|
||||
///< some "sensible" fields of the Open structure (e.g. they reallocate the pool of kernel buffers,
|
||||
///< or change the filter program
|
||||
BOOLEAN SkipSentPackets;
|
||||
|
||||
}
|
||||
OPEN_INSTANCE, *POPEN_INSTANCE;
|
||||
|
||||
/*!
|
||||
\brief Structure prepended to each packet in the kernel buffer pool.
|
||||
|
||||
Each packet in one of the kernel buffers is prepended by this header. It encapsulates the bpf_header,
|
||||
which will be passed to user level programs, as well as the sequence number of the packet, set by the producer (the tap function),
|
||||
and used by the consumer (the read function) to "reorder" the packets contained in the various kernel buffers.
|
||||
*/
|
||||
struct PacketHeader
|
||||
{
|
||||
ULONG SN; ///< Sequence number of the packet.
|
||||
struct bpf_hdr header; ///< bpf header, created by the tap, and copied unmodified to user level programs.
|
||||
};
|
||||
|
||||
extern UINT g_SendPacketFlags;
|
||||
#define NDIS_FLAGS_SKIP_LOOPBACK_W2K 0x400 ///< This is an undocumented flag for NdisSetPacketFlags() that allows to disable loopback reception.
|
||||
|
||||
#define TRANSMIT_PACKETS 2048 ///< 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.
|
||||
|
||||
|
||||
/// 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;\
|
||||
|
||||
/// 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;\
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/***************************/
|
||||
/* Prototypes */
|
||||
/***************************/
|
||||
|
||||
/** @defgroup NPF_code NPF functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\brief The initialization routine of the driver.
|
||||
\param DriverObject The driver object of NPF created by the system.
|
||||
\param RegistryPath The registry path containing the keys related to the driver.
|
||||
\return A string containing a list of network adapters.
|
||||
|
||||
DriverEntry is a mandatory function in a device driver. Like the main() of a user level program, it is called
|
||||
by the system when the driver is loaded in memory and started. Its purpose is to initialize the driver,
|
||||
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
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Returns the list of the MACs available on the system.
|
||||
\return A string containing a list of network adapters.
|
||||
|
||||
The list of adapters is retrieved from the
|
||||
SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318} registry key.
|
||||
NPF tries to create its bindings from this list. In this way it is possible to be loaded
|
||||
and unloaded dynamically without passing from the control panel.
|
||||
*/
|
||||
PWCHAR getAdaptersList(VOID);
|
||||
|
||||
/*!
|
||||
\brief Returns the MACs that bind to TCP/IP.
|
||||
\return Pointer to the registry key containing the list of adapters on which TCP/IP is bound.
|
||||
|
||||
If getAdaptersList() fails, NPF tries to obtain the TCP/IP bindings through this function.
|
||||
*/
|
||||
PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID);
|
||||
|
||||
/*!
|
||||
\brief Creates a device for a given MAC.
|
||||
\param adriverObjectP The driver object that will be associated with the device, i.e. the one of NPF.
|
||||
\param amacNameP The name of the network interface that the device will point.
|
||||
\param aProtoHandle NDIS protocol handle of NPF.
|
||||
\return If the function succeeds, the return value is nonzero.
|
||||
|
||||
NPF creates a device for every valid network adapter. The new device points to the NPF driver, but contains
|
||||
information about the original device. In this way, when the user opens the new device, NPF will be able to
|
||||
determine the correct adapter to use.
|
||||
*/
|
||||
BOOLEAN createDevice(
|
||||
IN OUT PDRIVER_OBJECT adriverObjectP,
|
||||
IN PUNICODE_STRING amacNameP,
|
||||
NDIS_HANDLE aProtoHandle);
|
||||
|
||||
/*!
|
||||
\brief Opens a new instance of the driver.
|
||||
\param DeviceObject Pointer to the device object utilized by the user.
|
||||
\param Irp Pointer to the IRP containing the user request.
|
||||
\return The status of the operation. See ntstatus.h in the DDK.
|
||||
|
||||
This function is called by the OS when a new instance of the driver is opened, i.e. when a user application
|
||||
performs a CreateFile on a device created by NPF. NPF_Open allocates and initializes variables, objects
|
||||
and buffers needed by the new instance, fills the OPEN_INSTANCE structure associated with it and opens the
|
||||
adapter with a call to NdisOpenAdapter.
|
||||
*/
|
||||
NTSTATUS
|
||||
NPF_Open(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Ends the opening of an adapter.
|
||||
\param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
|
||||
\param Status Status of the opening operation performed by NDIS.
|
||||
\param OpenErrorStatus not used by NPF.
|
||||
|
||||
Callback function associated with the NdisOpenAdapter() NDIS function. It is invoked by NDIS when the NIC
|
||||
driver has finished an open operation that was previously started by NPF_Open().
|
||||
*/
|
||||
VOID
|
||||
NPF_OpenAdapterComplete(
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN NDIS_STATUS Status,
|
||||
IN NDIS_STATUS OpenErrorStatus
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Closes an instance of the driver.
|
||||
\param DeviceObject Pointer to the device object utilized by the user.
|
||||
\param Irp Pointer to the IRP containing the user request.
|
||||
\return The status of the operation. See ntstatus.h in the DDK.
|
||||
|
||||
This function is called when a running instance of the driver is closed by the user with a CloseHandle().
|
||||
It stops the capture/monitoring/dump process, deallocates the memory and the objects associated with the
|
||||
instance and closing the files. The network adapter is then closed with a call to NdisCloseAdapter.
|
||||
*/
|
||||
NTSTATUS
|
||||
NPF_Close(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Ends the closing of an adapter.
|
||||
\param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
|
||||
\param Status Status of the close operation performed by NDIS.
|
||||
|
||||
Callback function associated with the NdisCloseAdapter() NDIS function. It is invoked by NDIS when the NIC
|
||||
driver has finished a close operation that was previously started by NPF_Close().
|
||||
*/
|
||||
VOID
|
||||
NPF_CloseAdapterComplete(
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN NDIS_STATUS Status
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Callback invoked by NDIS when a packet arrives from the network.
|
||||
\param ProtocolBindingContext Context of the function. Points to a OPEN_INSTANCE structure that identifies
|
||||
the NPF instance to which the packets are destined.
|
||||
\param MacReceiveContext Handle that identifies the underlying NIC driver that generated the request.
|
||||
This value must be used when the packet is transferred from the NIC driver with NdisTransferData().
|
||||
\param HeaderBuffer Pointer to the buffer in the NIC driver memory that contains the header of the packet.
|
||||
\param HeaderBufferSize Size in bytes of the header.
|
||||
\param LookAheadBuffer Pointer to the buffer in the NIC driver's memory that contains the incoming packet's
|
||||
data <b>available to NPF</b>. This value does not necessarily coincide with the actual size of the packet,
|
||||
since only a portion can be available at this time. The remaining portion can be obtained with the
|
||||
NdisTransferData() NDIS function.
|
||||
\param LookaheadBufferSize Size in bytes of the lookahead buffer.
|
||||
\param PacketSize Total size of the incoming packet, excluded the header.
|
||||
\return The status of the operation. See ntstatus.h in the DDK.
|
||||
|
||||
NPF_tap() is called by the underlying NIC for every incoming packet. It is the most important and one of
|
||||
the most complex functions of NPF: it executes the filter, runs the statistical engine (if the instance is in
|
||||
statistical mode), gathers the timestamp, moves the packet in the buffer. NPF_tap() is the only function,
|
||||
along with the filtering ones, that is executed for every incoming packet, therefore it is carefully
|
||||
optimized.
|
||||
*/
|
||||
NDIS_STATUS
|
||||
NPF_tap(
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN NDIS_HANDLE MacReceiveContext,
|
||||
IN PVOID HeaderBuffer,
|
||||
IN UINT HeaderBufferSize,
|
||||
IN PVOID LookAheadBuffer,
|
||||
IN UINT LookaheadBufferSize,
|
||||
IN UINT PacketSize
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Ends the transfer of a packet.
|
||||
\param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
|
||||
\param Packet Pointer to the NDIS_PACKET structure that received the packet data.
|
||||
\param Status Status of the transfer operation.
|
||||
\param BytesTransferred Amount of bytes transferred.
|
||||
|
||||
Callback function associated with the NdisTransferData() NDIS function. It is invoked by NDIS when the NIC
|
||||
driver has finished the transfer of a packet from the NIC driver memory to the NPF circular buffer.
|
||||
*/
|
||||
VOID
|
||||
NPF_TransferDataComplete(
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN PNDIS_PACKET Packet,
|
||||
IN NDIS_STATUS Status,
|
||||
IN UINT BytesTransferred
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Callback function that signals the end of a packet reception.
|
||||
\param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
|
||||
|
||||
does nothing in NPF
|
||||
*/
|
||||
VOID
|
||||
NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext);
|
||||
|
||||
/*!
|
||||
\brief Handles the IOCTL calls.
|
||||
\param DeviceObject Pointer to the device object utilized by the user.
|
||||
\param Irp Pointer to the IRP containing the user request.
|
||||
\return The status of the operation. See ntstatus.h in the DDK.
|
||||
|
||||
Once the packet capture driver is opened it can be configured from user-level applications with IOCTL commands
|
||||
using the DeviceIoControl() system call. NPF_IoControl receives and serves all the IOCTL calls directed to NPF.
|
||||
The following commands are recognized:
|
||||
- #BIOCSETBUFFERSIZE
|
||||
- #BIOCSETF
|
||||
- #BIOCGSTATS
|
||||
- #BIOCSRTIMEOUT
|
||||
- #BIOCSMODE
|
||||
- #BIOCSWRITEREP
|
||||
- #BIOCSMINTOCOPY
|
||||
- #BIOCSETOID
|
||||
- #BIOCQUERYOID
|
||||
- #BIOCSETDUMPFILENAME
|
||||
- #BIOCGEVNAME
|
||||
- #BIOCSENDPACKETSSYNC
|
||||
- #BIOCSENDPACKETSNOSYNC
|
||||
*/
|
||||
NTSTATUS
|
||||
NPF_IoControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
);
|
||||
|
||||
VOID
|
||||
|
||||
/*!
|
||||
\brief Ends an OID request.
|
||||
\param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
|
||||
\param pRequest Pointer to the completed OID request.
|
||||
\param Status Status of the operation.
|
||||
|
||||
Callback function associated with the NdisRequest() NDIS function. It is invoked by NDIS when the NIC
|
||||
driver has finished an OID request operation that was previously started by NPF_IoControl().
|
||||
*/
|
||||
NPF_RequestComplete(
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN PNDIS_REQUEST pRequest,
|
||||
IN NDIS_STATUS Status
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Writes a raw packet to the network.
|
||||
\param DeviceObject Pointer to the device object on which the user wrote the packet.
|
||||
\param Irp Pointer to the IRP containing the user request.
|
||||
\return The status of the operation. See ntstatus.h in the DDK.
|
||||
|
||||
This function is called by the OS in consequence of user WriteFile() call, with the data of the packet that must
|
||||
be sent on the net. The data is contained in the buffer associated with Irp, NPF_Write takes it and
|
||||
delivers it to the NIC driver via the NdisSend() function. The Nwrites field of the OPEN_INSTANCE structure
|
||||
associated with Irp indicates the number of copies of the packet that will be sent: more than one copy of the
|
||||
packet can be sent for performance reasons.
|
||||
*/
|
||||
NTSTATUS
|
||||
NPF_Write(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
);
|
||||
|
||||
|
||||
/*!
|
||||
\brief Writes a buffer of raw packets to the network.
|
||||
\param Irp Pointer to the IRP containing the user request.
|
||||
\param UserBuff Pointer to the buffer containing the packets to send.
|
||||
\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.
|
||||
|
||||
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
|
||||
sf_pkthdr structure. NPF_BufferedWrite() scans the buffer and sends every packet via the NdisSend() function.
|
||||
When Sync is set to TRUE, the packets are synchronized with the KeQueryPerformanceCounter() function.
|
||||
This requires a remarkable amount of CPU, but allows to respect the timestamps associated with packets with a precision
|
||||
of some microseconds (depending on the precision of the performance counter of the machine).
|
||||
If Sync is false, the timestamps are ignored and the packets are sent as fat as possible.
|
||||
*/
|
||||
|
||||
INT NPF_BufferedWrite(IN PIRP Irp,
|
||||
IN PCHAR UserBuff,
|
||||
IN ULONG UserBuffSize,
|
||||
BOOLEAN sync);
|
||||
|
||||
/*!
|
||||
\brief Waits the completion of all the sends performed by NPF_BufferedWrite.
|
||||
|
||||
\param Open Pointer to open context structure
|
||||
|
||||
Used by NPF_BufferedWrite to wait the completion of all the sends before returning the control to the user.
|
||||
*/
|
||||
VOID NPF_WaitEndOfBufferedWrite(POPEN_INSTANCE Open);
|
||||
|
||||
/*!
|
||||
\brief Ends a send operation.
|
||||
\param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
|
||||
\param pRequest Pointer to the NDIS PACKET structure used by NPF_Write() to send the packet.
|
||||
\param Status Status of the operation.
|
||||
|
||||
Callback function associated with the NdisSend() NDIS function. It is invoked by NDIS when the NIC
|
||||
driver has finished an OID request operation that was previously started by NPF_Write().
|
||||
*/
|
||||
VOID
|
||||
NPF_SendComplete(
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN PNDIS_PACKET pPacket,
|
||||
IN NDIS_STATUS Status
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Ends a reset of the adapter.
|
||||
\param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.
|
||||
\param Status Status of the operation.
|
||||
|
||||
Callback function associated with the NdisReset() NDIS function. It is invoked by NDIS when the NIC
|
||||
driver has finished an OID request operation that was previously started by NPF_IoControl(), in an IOCTL_PROTOCOL_RESET
|
||||
command.
|
||||
*/
|
||||
VOID
|
||||
NPF_ResetComplete(
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN NDIS_STATUS Status
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Callback for NDIS StatusHandler. Not used by NPF
|
||||
*/
|
||||
VOID
|
||||
NPF_Status(
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN NDIS_STATUS Status,
|
||||
IN PVOID StatusBuffer,
|
||||
IN UINT StatusBufferSize
|
||||
);
|
||||
|
||||
|
||||
/*!
|
||||
\brief Callback for NDIS StatusCompleteHandler. Not used by NPF
|
||||
*/
|
||||
VOID
|
||||
NPF_StatusComplete(IN NDIS_HANDLE ProtocolBindingContext);
|
||||
|
||||
/*!
|
||||
\brief Function called by the OS when NPF is unloaded.
|
||||
\param DriverObject The driver object of NPF created by the system.
|
||||
|
||||
This is the last function executed when the driver is unloaded from the system. It frees global resources,
|
||||
delete the devices and deregisters the protocol. The driver can be unloaded by the user stopping the NPF
|
||||
service (from control panel or with a console 'net stop npf').
|
||||
*/
|
||||
VOID
|
||||
NPF_Unload(IN PDRIVER_OBJECT DriverObject);
|
||||
|
||||
|
||||
/*!
|
||||
\brief Function that serves the user's reads.
|
||||
\param DeviceObject Pointer to the device used by the user.
|
||||
\param Irp Pointer to the IRP containing the user request.
|
||||
\return The status of the operation. See ntstatus.h in the DDK.
|
||||
|
||||
This function is called by the OS in consequence of user ReadFile() call. It moves the data present in the
|
||||
kernel buffer to the user buffer associated with Irp.
|
||||
First of all, NPF_Read checks the amount of data in kernel buffer associated with current NPF instance.
|
||||
- If the instance is in capture mode and the buffer contains more than OPEN_INSTANCE::MinToCopy bytes,
|
||||
NPF_Read moves the data in the user buffer and returns immediatly. In this way, the read performed by the
|
||||
user is not blocking.
|
||||
- If the buffer contains less than MinToCopy bytes, the application's request isn't
|
||||
satisfied immediately, but it's blocked until at least MinToCopy bytes arrive from the net
|
||||
or the timeout on this read expires. The timeout is kept in the OPEN_INSTANCE::TimeOut field.
|
||||
- If the instance is in statistical mode or in dump mode, the application's request is blocked until the
|
||||
timeout kept in OPEN_INSTANCE::TimeOut expires.
|
||||
*/
|
||||
NTSTATUS
|
||||
NPF_Read(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Reads the registry keys associated woth NPF if the driver is manually installed via the control panel.
|
||||
|
||||
Normally not used in recent versions of NPF.
|
||||
*/
|
||||
NTSTATUS
|
||||
NPF_ReadRegistry(
|
||||
IN PWSTR *MacDriverName,
|
||||
IN PWSTR *PacketDriverName,
|
||||
IN PUNICODE_STRING RegistryPath
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Function used by NPF_ReadRegistry() to quesry the registry keys associated woth NPF if the driver
|
||||
is manually installed via the control panel.
|
||||
|
||||
Normally not used in recent versions of NPF.
|
||||
*/
|
||||
NTSTATUS
|
||||
NPF_QueryRegistryRoutine(
|
||||
IN PWSTR ValueName,
|
||||
IN ULONG ValueType,
|
||||
IN PVOID ValueData,
|
||||
IN ULONG ValueLength,
|
||||
IN PVOID Context,
|
||||
IN PVOID EntryContext
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Callback for NDIS BindAdapterHandler. Not used by NPF.
|
||||
|
||||
Function called by NDIS when a new adapter is installed on the machine With Plug and Play.
|
||||
*/
|
||||
VOID NPF_BindAdapter(
|
||||
OUT PNDIS_STATUS Status,
|
||||
IN NDIS_HANDLE BindContext,
|
||||
IN PNDIS_STRING DeviceName,
|
||||
IN PVOID SystemSpecific1,
|
||||
IN PVOID SystemSpecific2
|
||||
);
|
||||
|
||||
/*!
|
||||
\brief Callback for NDIS UnbindAdapterHandler.
|
||||
\param Status out variable filled by NPF_UnbindAdapter with the status of the unbind operation.
|
||||
\param ProtocolBindingContext Context of the function. Contains a pointer to the OPEN_INSTANCE structure associated with current instance.
|
||||
\param UnbindContext Specifies a handle, supplied by NDIS, that NPF can use to complete the opration.
|
||||
|
||||
Function called by NDIS when a new adapter is removed from the machine without shutting it down.
|
||||
NPF_UnbindAdapter closes the adapter calling NdisCloseAdapter() and frees the memory and the structures
|
||||
associated with it. It also releases the waiting user-level app and closes the dump thread if the instance
|
||||
is in dump mode.
|
||||
*/
|
||||
VOID
|
||||
NPF_UnbindAdapter(
|
||||
OUT PNDIS_STATUS Status,
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN NDIS_HANDLE UnbindContext
|
||||
);
|
||||
|
||||
|
||||
/*!
|
||||
\brief Creates the file that will receive the packets when the driver is in dump mode.
|
||||
\param Open The NPF instance that opens the file.
|
||||
\param fileName Pointer to a UNICODE string containing the name of the file.
|
||||
\param append Boolean value that specifies if the data must be appended to the file.
|
||||
\return The status of the operation. See ntstatus.h in the DDK.
|
||||
*/
|
||||
NTSTATUS NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN append);
|
||||
|
||||
/*!
|
||||
\brief Starts dump to file.
|
||||
\param Open The NPF instance that opens the file.
|
||||
\return The status of the operation. See ntstatus.h in the DDK.
|
||||
|
||||
This function performs two operations. First, it writes the libpcap header at the beginning of the file.
|
||||
Second, it starts the thread that asynchronously dumps the network data to the file.
|
||||
*/
|
||||
NTSTATUS NPF_StartDump(POPEN_INSTANCE Open);
|
||||
|
||||
/*!
|
||||
\brief The dump thread.
|
||||
\param Open The NPF instance that creates the thread.
|
||||
|
||||
This function moves the content of the NPF kernel buffer to file. It runs in the user context, so at lower
|
||||
priority than the TAP.
|
||||
*/
|
||||
VOID NPF_DumpThread(PVOID Open);
|
||||
|
||||
/*!
|
||||
\brief Saves the content of the packet buffer to the file associated with current instance.
|
||||
\param Open The NPF instance that creates the thread.
|
||||
|
||||
Used by NPF_DumpThread() and NPF_CloseDumpFile().
|
||||
*/
|
||||
NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open);
|
||||
|
||||
/*!
|
||||
\brief Writes a block of packets on the dump file.
|
||||
\param FileObject The file object that will receive the packets.
|
||||
\param Offset The offset in the file where the packets will be put.
|
||||
\param Length The amount of bytes to write.
|
||||
\param Mdl MDL mapping the memory buffer that will be written to disk.
|
||||
\param IoStatusBlock Used by the function to return the status of the operation.
|
||||
\return The status of the operation. See ntstatus.h in the DDK.
|
||||
|
||||
NPF_WriteDumpFile addresses directly the file system, creating a custom IRP and using it to send a portion
|
||||
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);
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Closes the dump file associated with an instance of the driver.
|
||||
\param Open The NPF instance that closes the file.
|
||||
\return The status of the operation. See ntstatus.h in the DDK.
|
||||
*/
|
||||
NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open);
|
||||
|
||||
/*!
|
||||
\brief Returns the amount of bytes present in the packet buffer.
|
||||
\param Open The NPF instance that closes the file.
|
||||
*/
|
||||
UINT GetBuffOccupation(POPEN_INSTANCE Open);
|
||||
|
||||
/*!
|
||||
\brief Called by NDIS to notify us of a PNP event. The most significant one for us is power state change.
|
||||
|
||||
\param ProtocolBindingContext Pointer to open context structure. This is NULL for global reconfig
|
||||
events.
|
||||
\param pNetPnPEvent Pointer to the PnP event
|
||||
|
||||
If there is a power state change, the driver is forced to resynchronize the global timer.
|
||||
This hopefully avoids the synchronization issues caused by hibernation or standby.
|
||||
This function is excluded from the NT4 driver, where PnP is not supported
|
||||
*/
|
||||
#ifdef NDIS50
|
||||
NDIS_STATUS NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /*main ifndef/define*/
|
||||
423
src/See/Packet32.h
Normal file
423
src/See/Packet32.h
Normal file
@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @ingroup packetapi
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup packet32h Packet.dll definitions and data structures
|
||||
* Packet32.h contains the data structures and the definitions used by packet.dll.
|
||||
* The file is used both by the Win9x and the WinNTx versions of packet.dll, and can be included
|
||||
* by the applications that use the functions of this library
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __PACKET32
|
||||
#define __PACKET32
|
||||
|
||||
#include <winsock2.h>
|
||||
#include "devioctl.h"
|
||||
#ifdef HAVE_DAG_API
|
||||
#include <dagc.h>
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
// Working modes
|
||||
#define PACKET_MODE_CAPT 0x0 ///< Capture mode
|
||||
#define PACKET_MODE_STAT 0x1 ///< Statistical mode
|
||||
#define PACKET_MODE_MON 0x2 ///< Monitoring mode
|
||||
#define PACKET_MODE_DUMP 0x10 ///< Dump mode
|
||||
#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode
|
||||
|
||||
// ioctls
|
||||
#define FILE_DEVICE_PROTOCOL 0x8000
|
||||
|
||||
#define IOCTL_PROTOCOL_STATISTICS CTL_CODE(FILE_DEVICE_PROTOCOL, 2 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PROTOCOL_RESET CTL_CODE(FILE_DEVICE_PROTOCOL, 3 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PROTOCOL_READ CTL_CODE(FILE_DEVICE_PROTOCOL, 4 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PROTOCOL_WRITE CTL_CODE(FILE_DEVICE_PROTOCOL, 5 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PROTOCOL_MACNAME CTL_CODE(FILE_DEVICE_PROTOCOL, 6 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_OPEN CTL_CODE(FILE_DEVICE_PROTOCOL, 7 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_CLOSE CTL_CODE(FILE_DEVICE_PROTOCOL, 8 , METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define pBIOCSETBUFFERSIZE 9592 ///< IOCTL code: set kernel buffer size.
|
||||
#define pBIOCSETF 9030 ///< IOCTL code: set packet filtering program.
|
||||
#define pBIOCGSTATS 9031 ///< IOCTL code: get the capture stats.
|
||||
#define pBIOCSRTIMEOUT 7416 ///< IOCTL code: set the read timeout.
|
||||
#define pBIOCSMODE 7412 ///< IOCTL code: set working mode.
|
||||
#define pBIOCSWRITEREP 7413 ///< IOCTL code: set number of physical repetions of every packet written by the app.
|
||||
#define pBIOCSMINTOCOPY 7414 ///< IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call.
|
||||
#define pBIOCSETOID 2147483648 ///< IOCTL code: set an OID value.
|
||||
#define pBIOCQUERYOID 2147483652 ///< IOCTL code: get an OID value.
|
||||
#define pATTACHPROCESS 7117 ///< IOCTL code: attach a process to the driver. Used in Win9x only.
|
||||
#define pDETACHPROCESS 7118 ///< IOCTL code: detach a process from the driver. Used in Win9x only.
|
||||
#define pBIOCSETDUMPFILENAME 9029 ///< IOCTL code: set the name of a the file used by kernel dump mode.
|
||||
#define pBIOCEVNAME 7415 ///< IOCTL code: get the name of the event that the driver signals when some data is present in the buffer.
|
||||
#define pBIOCSENDPACKETSNOSYNC 9032 ///< IOCTL code: Send a buffer containing multiple packets to the network, ignoring the timestamps associated with the packets.
|
||||
#define pBIOCSENDPACKETSSYNC 9033 ///< IOCTL code: Send a buffer containing multiple packets to the network, respecting the timestamps associated with the packets.
|
||||
#define pBIOCSETDUMPLIMITS 9034 ///< IOCTL code: Set the dump file limits. See the PacketSetDumpLimits() function.
|
||||
#define pBIOCISDUMPENDED 7411 ///< IOCTL code: Get the status of the kernel dump process. See the PacketIsDumpEnded() function.
|
||||
|
||||
#define pBIOCSTIMEZONE 7471 ///< IOCTL code: set time zone. Used in Win9x only.
|
||||
|
||||
|
||||
/// Alignment macro. Defines the alignment size.
|
||||
#define Packet_ALIGNMENT sizeof(int)
|
||||
/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT.
|
||||
#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1))
|
||||
|
||||
|
||||
#define NdisMediumNull -1 // Custom linktype: NDIS doesn't provide an equivalent
|
||||
#define NdisMediumCHDLC -2 // Custom linktype: NDIS doesn't provide an equivalent
|
||||
#define NdisMediumPPPSerial -3 // Custom linktype: NDIS doesn't provide an equivalent
|
||||
|
||||
/*!
|
||||
\brief Network type structure.
|
||||
|
||||
This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed.
|
||||
*/
|
||||
typedef struct NetType
|
||||
{
|
||||
UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information)
|
||||
ULONGLONG LinkSpeed; ///< The speed of the network in bits per second
|
||||
}NetType;
|
||||
|
||||
|
||||
//some definitions stolen from libpcap
|
||||
|
||||
#ifndef BPF_MAJOR_VERSION
|
||||
|
||||
/*!
|
||||
\brief A BPF pseudo-assembly program.
|
||||
|
||||
The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet.
|
||||
*/
|
||||
struct bpf_program
|
||||
{
|
||||
UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow.
|
||||
struct bpf_insn *bf_insns; ///< A pointer to the first instruction of the program.
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief A single BPF pseudo-instruction.
|
||||
|
||||
bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver.
|
||||
*/
|
||||
struct bpf_insn
|
||||
{
|
||||
USHORT code; ///< Instruction type and addressing mode.
|
||||
UCHAR jt; ///< Jump if true
|
||||
UCHAR jf; ///< Jump if false
|
||||
int k; ///< Generic field used for various purposes.
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Structure that contains a couple of statistics values on the current capture.
|
||||
|
||||
It is used by packet.dll to return statistics about a capture session.
|
||||
*/
|
||||
struct bpf_stat
|
||||
{
|
||||
UINT bs_recv; ///< Number of packets that the driver received from the network adapter
|
||||
///< from the beginning of the current capture. This value includes the packets
|
||||
///< lost by the driver.
|
||||
UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture.
|
||||
///< Basically, a packet is lost when the the buffer of the driver is full.
|
||||
///< In this situation the packet cannot be stored and the driver rejects it.
|
||||
UINT ps_ifdrop; ///< drops by interface. XXX not yet supported
|
||||
UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and
|
||||
///< thus reach the application.
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Packet header.
|
||||
|
||||
This structure defines the header associated with every packet delivered to the application.
|
||||
*/
|
||||
struct bpf_hdr
|
||||
{
|
||||
struct timeval bh_tstamp; ///< The timestamp associated with the captured packet.
|
||||
///< It is stored in a TimeVal structure.
|
||||
UINT bh_caplen; ///< Length of captured portion. The captured portion <b>can be different</b>
|
||||
///< 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 bh_datalen; ///< Original length of packet
|
||||
USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases,
|
||||
///< a padding could be added between the end of this structure and the packet
|
||||
///< data for performance reasons. This filed can be used to retrieve the actual data
|
||||
///< of the packet.
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Dump packet header.
|
||||
|
||||
This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets().
|
||||
It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a
|
||||
packet in a dump file. This makes straightforward sending WinPcap dump files to the network.
|
||||
*/
|
||||
struct dump_bpf_hdr{
|
||||
struct timeval ts; ///< Time stamp of the packet
|
||||
UINT caplen; ///< Length of captured portion. The captured portion can smaller than the
|
||||
///< 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).
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices
|
||||
#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links
|
||||
#define NMAX_PACKET 65535
|
||||
|
||||
/*!
|
||||
\brief Addresses of a network adapter.
|
||||
|
||||
This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with
|
||||
an adapter.
|
||||
*/
|
||||
typedef struct npf_if_addr {
|
||||
struct sockaddr_storage IPAddress; ///< IP address.
|
||||
struct sockaddr_storage SubnetMask; ///< Netmask for that address.
|
||||
struct sockaddr_storage Broadcast; ///< Broadcast address.
|
||||
}npf_if_addr;
|
||||
|
||||
|
||||
#define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API.
|
||||
#define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API.
|
||||
#define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API.
|
||||
#define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API.
|
||||
|
||||
|
||||
typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API
|
||||
typedef WAN_ADAPTER *PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API
|
||||
|
||||
#define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter
|
||||
#define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter
|
||||
#define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card
|
||||
#define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file
|
||||
#define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones.
|
||||
|
||||
/*!
|
||||
\brief Contains comprehensive information about a network adapter.
|
||||
|
||||
This structure is filled with all the accessory information that the user can need about an adapter installed
|
||||
on his system.
|
||||
*/
|
||||
typedef struct _ADAPTER_INFO
|
||||
{
|
||||
struct _ADAPTER_INFO *Next; ///< Pointer to the next adapter in the list.
|
||||
CHAR Name[ADAPTER_NAME_LENGTH + 1]; ///< Name of the device representing the adapter.
|
||||
CHAR Description[ADAPTER_DESC_LENGTH + 1]; ///< Human understandable description of the adapter
|
||||
UINT MacAddressLen; ///< Length of the link layer address.
|
||||
UCHAR MacAddress[MAX_MAC_ADDR_LENGTH]; ///< Link layer address.
|
||||
NetType LinkLayer; ///< Physical characteristics of this adapter. This NetType structure contains the link type and the speed of the adapter.
|
||||
INT NNetworkAddresses; ///< Number of network layer addresses of this adapter.
|
||||
npf_if_addr *NetworkAddresses; ///< Pointer to an array of npf_if_addr, each of which specifies a network address of this adapter.
|
||||
UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API.
|
||||
}
|
||||
ADAPTER_INFO, *PADAPTER_INFO;
|
||||
|
||||
/*!
|
||||
\brief Describes an opened network adapter.
|
||||
|
||||
This structure is the most important for the functioning of packet.dll, but the great part of its fields
|
||||
should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters
|
||||
*/
|
||||
typedef struct _ADAPTER {
|
||||
HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver.
|
||||
CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened.
|
||||
int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated
|
||||
///< on the wire.
|
||||
HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter.
|
||||
///< It can be passed to standard Win32 functions (like WaitForSingleObject
|
||||
///< or WaitForMultipleObjects) to wait until the driver's buffer contains some
|
||||
///< data. It is particularly useful in GUI applications that need to wait
|
||||
///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy()
|
||||
///< function can be used to define the minimum amount of data in the kernel buffer
|
||||
///< that will cause the event to be signalled.
|
||||
|
||||
UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and
|
||||
///< ReadEvent will be signaled, also if no packets were captured
|
||||
CHAR Name[ADAPTER_NAME_LENGTH];
|
||||
PWAN_ADAPTER pWanAdapter;
|
||||
UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API.
|
||||
#ifdef HAVE_DAG_API
|
||||
dagc_t *pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter
|
||||
PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card
|
||||
struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure
|
||||
unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry
|
||||
DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps).
|
||||
#endif // HAVE_DAG_API
|
||||
} ADAPTER, *LPADAPTER;
|
||||
|
||||
/*!
|
||||
\brief Structure that contains a group of packets coming from the driver.
|
||||
|
||||
This structure defines the header associated with every packet delivered to the application.
|
||||
*/
|
||||
typedef struct _PACKET {
|
||||
HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications.
|
||||
OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications.
|
||||
PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for
|
||||
///< details about the organization of the data in this buffer
|
||||
UINT Length; ///< Length of the buffer
|
||||
DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data
|
||||
///< received by the last call to PacketReceivePacket()
|
||||
BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications.
|
||||
} PACKET, *LPPACKET;
|
||||
|
||||
/*!
|
||||
\brief Structure containing an OID request.
|
||||
|
||||
It is used by the PacketRequest() function to send an OID to the interface card driver.
|
||||
It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address,
|
||||
the list of the multicast groups defined on it, and so on.
|
||||
*/
|
||||
struct _PACKET_OID_DATA {
|
||||
ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h
|
||||
///< for a complete list of valid codes.
|
||||
ULONG Length; ///< Length of the data field
|
||||
UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received
|
||||
///< from the adapter.
|
||||
};
|
||||
typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;
|
||||
|
||||
|
||||
#if _DBG
|
||||
#define ODS(_x) OutputDebugString(TEXT(_x))
|
||||
#define ODSEx(_x, _y)
|
||||
#else
|
||||
#ifdef _DEBUG_TO_FILE
|
||||
/*!
|
||||
\brief Macro to print a debug string. The behavior differs depending on the debug level
|
||||
*/
|
||||
#define ODS(_x) { \
|
||||
FILE *f; \
|
||||
f = fopen("winpcap_debug.txt", "a"); \
|
||||
fprintf(f, "%s", _x); \
|
||||
fclose(f); \
|
||||
}
|
||||
/*!
|
||||
\brief Macro to print debug data with the printf convention. The behavior differs depending on
|
||||
the debug level
|
||||
*/
|
||||
#define ODSEx(_x, _y) { \
|
||||
FILE *f; \
|
||||
f = fopen("winpcap_debug.txt", "a"); \
|
||||
fprintf(f, _x, _y); \
|
||||
fclose(f); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName);
|
||||
#else
|
||||
#define ODS(_x)
|
||||
#define ODSEx(_x, _y)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* We load dinamically the dag library in order link it only when it's present on the system */
|
||||
#ifdef HAVE_DAG_API
|
||||
typedef dagc_t* (*dagc_open_handler)(const char *source, unsigned flags, char *ebuf); ///< prototype used to dynamically load the dag dll
|
||||
typedef void (*dagc_close_handler)(dagc_t *dagcfd); ///< prototype used to dynamically load the dag dll
|
||||
typedef int (*dagc_getlinktype_handler)(dagc_t *dagcfd); ///< prototype used to dynamically load the dag dll
|
||||
typedef int (*dagc_getlinkspeed_handler)(dagc_t *dagcfd); ///< prototype used to dynamically load the dag dll
|
||||
typedef int (*dagc_setsnaplen_handler)(dagc_t *dagcfd, unsigned snaplen); ///< prototype used to dynamically load the dag dll
|
||||
typedef unsigned (*dagc_getfcslen_handler)(dagc_t *dagcfd); ///< prototype used to dynamically load the dag dll
|
||||
typedef int (*dagc_receive_handler)(dagc_t *dagcfd, u_char **buffer, u_int *bufsize); ///< prototype used to dynamically load the dag dll
|
||||
typedef int (*dagc_stats_handler)(dagc_t *dagcfd, dagc_stats_t *ps); ///< prototype used to dynamically load the dag dll
|
||||
typedef int (*dagc_wait_handler)(dagc_t *dagcfd, struct timeval *timeout); ///< prototype used to dynamically load the dag dll
|
||||
typedef int (*dagc_finddevs_handler)(dagc_if_t **alldevsp, char *ebuf); ///< prototype used to dynamically load the dag dll
|
||||
typedef int (*dagc_freedevs_handler)(dagc_if_t *alldevsp); ///< prototype used to dynamically load the dag dll
|
||||
#endif // HAVE_DAG_API
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
// The following is used to check the adapter name in PacketOpenAdapterNPF and prevent
|
||||
// opening of firewire adapters
|
||||
#define FIREWIRE_SUBSTR L"1394"
|
||||
|
||||
void PacketPopulateAdaptersInfoList();
|
||||
PWCHAR SChar2WChar(PCHAR string);
|
||||
PCHAR WChar2SChar(PWCHAR string);
|
||||
BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen);
|
||||
PADAPTER_INFO PacketFindAdInfo(PCHAR AdapterName);
|
||||
BOOLEAN PacketUpdateAdInfo(PCHAR AdapterName);
|
||||
BOOLEAN IsFireWire(TCHAR *AdapterDesc);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// EXPORTED FUNCTIONS
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
PCHAR PacketGetVersion();
|
||||
PCHAR PacketGetDriverVersion();
|
||||
BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes);
|
||||
BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites);
|
||||
BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode);
|
||||
BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout);
|
||||
BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp);
|
||||
INT PacketSetSnapLen(LPADAPTER AdapterObject,int snaplen);
|
||||
BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s);
|
||||
BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s);
|
||||
BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim);
|
||||
BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type);
|
||||
LPADAPTER PacketOpenAdapter(PCHAR AdapterName);
|
||||
BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET pPacket,BOOLEAN Sync);
|
||||
INT PacketSendPackets(LPADAPTER AdapterObject,PVOID PacketBuff,ULONG Size, BOOLEAN Sync);
|
||||
LPPACKET PacketAllocatePacket(void);
|
||||
VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length);
|
||||
VOID PacketFreePacket(LPPACKET lpPacket);
|
||||
BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync);
|
||||
BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter);
|
||||
BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize);
|
||||
BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries);
|
||||
BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData);
|
||||
HANDLE PacketGetReadEvent(LPADAPTER AdapterObject);
|
||||
BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len);
|
||||
BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks);
|
||||
BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync);
|
||||
BOOL PacketStopDriver();
|
||||
VOID PacketCloseAdapter(LPADAPTER lpAdapter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__PACKET32
|
||||
938
src/See/Read.c
Normal file
938
src/See/Read.c
Normal file
@ -0,0 +1,938 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||
* Copyright (c) 2005 CACE Technologies, Davis (California)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "ntddk.h"
|
||||
#include <ntiologc.h>
|
||||
#include <ndis.h>
|
||||
#include "debug.h"
|
||||
#include "packet.h"
|
||||
#include "win_bpf.h"
|
||||
|
||||
#include "tme.h"
|
||||
#include "time_calls.h"
|
||||
|
||||
extern struct time_conv G_Start_Time; // from openclos.c
|
||||
|
||||
extern ULONG NCpu; //from packet.c
|
||||
|
||||
NTSTATUS NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
|
||||
{
|
||||
POPEN_INSTANCE Open;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
PUCHAR packp;
|
||||
PUCHAR CurrBuff;
|
||||
struct bpf_hdr *header;
|
||||
// PUCHAR UserPointer;
|
||||
// ULONG bytecopy;
|
||||
ULONG copied,count,current_cpu,plen,increment,ToCopy,available;
|
||||
CpuPrivateData *LocalData;
|
||||
ULONG i;
|
||||
ULONG Occupation;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: Read\n");)
|
||||
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
Open=IrpSp->FileObject->FsContext;
|
||||
|
||||
if( Open->Bound == FALSE )
|
||||
{
|
||||
// The Network adapter has been removed or diasabled
|
||||
EXIT_FAILURE(0);
|
||||
}
|
||||
|
||||
if (Open->Size == 0)
|
||||
{
|
||||
EXIT_FAILURE(0);
|
||||
}
|
||||
|
||||
if( Open->mode & MODE_DUMP && Open->DumpFileHandle == NULL ){
|
||||
// this instance is in dump mode, but the dump file has still not been opened
|
||||
EXIT_FAILURE(0);
|
||||
}
|
||||
|
||||
Occupation=0;
|
||||
|
||||
for(i=0;i<NCpu;i++)
|
||||
Occupation += (Open->Size - Open->CpuData[i].Free);
|
||||
|
||||
//See if the buffer is full enough to be copied
|
||||
if( Occupation <= Open->MinToCopy*NCpu || Open->mode & MODE_DUMP )
|
||||
{
|
||||
//wait until some packets arrive or the timeout expires
|
||||
if(Open->TimeOut.QuadPart != (LONGLONG)IMMEDIATE)
|
||||
KeWaitForSingleObject(Open->ReadEvent,
|
||||
UserRequest,
|
||||
KernelMode,
|
||||
TRUE,
|
||||
(Open->TimeOut.QuadPart == (LONGLONG)0)? NULL: &(Open->TimeOut));
|
||||
|
||||
KeClearEvent(Open->ReadEvent);
|
||||
|
||||
if(Open->mode & MODE_STAT)
|
||||
{ //this capture instance is in statistics mode
|
||||
#ifdef NDIS50
|
||||
CurrBuff=(PUCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
#else
|
||||
CurrBuff=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
#endif
|
||||
|
||||
//fill the bpf header for this packet
|
||||
header=(struct bpf_hdr*)CurrBuff;
|
||||
GET_TIME(&header->bh_tstamp,&G_Start_Time);
|
||||
|
||||
if(Open->mode & MODE_DUMP){
|
||||
*(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr)+16)=Open->DumpOffset.QuadPart;
|
||||
header->bh_caplen=24;
|
||||
header->bh_datalen=24;
|
||||
Irp->IoStatus.Information = 24 + sizeof(struct bpf_hdr);
|
||||
}
|
||||
else{
|
||||
header->bh_caplen=16;
|
||||
header->bh_datalen=16;
|
||||
header->bh_hdrlen=sizeof(struct bpf_hdr);
|
||||
Irp->IoStatus.Information = 16 + sizeof(struct bpf_hdr);
|
||||
}
|
||||
|
||||
*(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr))=Open->Npackets.QuadPart;
|
||||
*(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr)+8)=Open->Nbytes.QuadPart;
|
||||
|
||||
//reset the countetrs
|
||||
NdisAcquireSpinLock( &Open->CountersLock );
|
||||
Open->Npackets.QuadPart=0;
|
||||
Open->Nbytes.QuadPart=0;
|
||||
NdisReleaseSpinLock( &Open->CountersLock );
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// The MONITOR_MODE (aka TME extensions) is not supported on
|
||||
// 64 bit architectures
|
||||
//
|
||||
#ifdef __NPF_x86__
|
||||
|
||||
if(Open->mode==MODE_MON) //this capture instance is in monitor mode
|
||||
{
|
||||
PTME_DATA data;
|
||||
ULONG cnt;
|
||||
ULONG block_size;
|
||||
PUCHAR tmp;
|
||||
|
||||
#ifdef NDIS50
|
||||
UserPointer=MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
#else
|
||||
UserPointer=MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
#endif
|
||||
|
||||
if ((!IS_VALIDATED(Open->tme.validated_blocks,Open->tme.active_read))||(IrpSp->Parameters.Read.Length<sizeof(struct bpf_hdr)))
|
||||
{
|
||||
EXIT_FAILURE(0);
|
||||
}
|
||||
|
||||
header=(struct bpf_hdr*)UserPointer;
|
||||
|
||||
GET_TIME(&header->bh_tstamp,&G_Start_Time);
|
||||
|
||||
|
||||
header->bh_hdrlen=sizeof(struct bpf_hdr);
|
||||
|
||||
|
||||
//moves user memory pointer
|
||||
UserPointer+=sizeof(struct bpf_hdr);
|
||||
|
||||
//calculus of data to be copied
|
||||
//if the user buffer is smaller than data to be copied,
|
||||
//only some data will be copied
|
||||
data=&Open->tme.block_data[Open->tme.active_read];
|
||||
|
||||
if (data->last_read.tv_sec!=0)
|
||||
data->last_read=header->bh_tstamp;
|
||||
|
||||
|
||||
bytecopy=data->block_size*data->filled_blocks;
|
||||
|
||||
if ((IrpSp->Parameters.Read.Length-sizeof(struct bpf_hdr))<bytecopy)
|
||||
bytecopy=(IrpSp->Parameters.Read.Length-sizeof(struct bpf_hdr))/ data->block_size;
|
||||
else
|
||||
bytecopy=data->filled_blocks;
|
||||
|
||||
tmp=data->shared_memory_base_address;
|
||||
block_size=data->block_size;
|
||||
|
||||
for (cnt=0;cnt<bytecopy;cnt++)
|
||||
{
|
||||
NdisAcquireSpinLock(&Open->MachineLock);
|
||||
RtlCopyMemory(UserPointer,tmp,block_size);
|
||||
NdisReleaseSpinLock(&Open->MachineLock);
|
||||
tmp+=block_size;
|
||||
UserPointer+=block_size;
|
||||
}
|
||||
|
||||
bytecopy*=block_size;
|
||||
|
||||
header->bh_caplen=bytecopy;
|
||||
header->bh_datalen=header->bh_caplen;
|
||||
|
||||
EXIT_SUCCESS(bytecopy+sizeof(struct bpf_hdr));
|
||||
}
|
||||
|
||||
Occupation=0;
|
||||
|
||||
for(i=0;i<NCpu;i++)
|
||||
Occupation += (Open->Size - Open->CpuData[i].Free);
|
||||
|
||||
|
||||
if ( Occupation == 0 || Open->mode & MODE_DUMP)
|
||||
// The timeout has expired, but the buffer is still empty (or the packets must be written to file).
|
||||
// We must awake the application, returning an empty buffer.
|
||||
{
|
||||
EXIT_SUCCESS(0);
|
||||
}
|
||||
|
||||
#else // not __NPF_x86__ , so x86-64 or IA64
|
||||
if(Open->mode==MODE_MON) //this capture instance is in monitor mode
|
||||
{
|
||||
EXIT_FAILURE(0);
|
||||
}
|
||||
#endif // __NPF_x86__
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
copied=0;
|
||||
count=0;
|
||||
current_cpu=0;
|
||||
available = IrpSp->Parameters.Read.Length;
|
||||
#ifdef NDIS50
|
||||
packp=(PUCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
#else
|
||||
packp=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
#endif
|
||||
|
||||
|
||||
KeClearEvent(Open->ReadEvent);
|
||||
|
||||
while (count < NCpu) //round robin on the CPUs, if count = NCpu there are no packets left to be copied
|
||||
{
|
||||
if (available == copied)
|
||||
{
|
||||
EXIT_SUCCESS(copied);
|
||||
}
|
||||
|
||||
LocalData = &Open->CpuData[current_cpu];
|
||||
|
||||
if (LocalData->Free < Open->Size)
|
||||
{ //there are some packets in the selected (aka LocalData) buffer
|
||||
struct PacketHeader *Header = (struct PacketHeader*)(LocalData->Buffer + LocalData->C);
|
||||
|
||||
if ( Header->SN == Open->ReaderSN)
|
||||
{ //check if it the next one to be copied
|
||||
plen = Header->header.bh_caplen;
|
||||
if (plen + sizeof (struct bpf_hdr) > available - copied)
|
||||
{ //if the packet does not fit into the user buffer, we've ended copying packets
|
||||
EXIT_SUCCESS(copied);
|
||||
}
|
||||
|
||||
// FIX_TIMESTAMPS(&Header->header.bh_tstamp);
|
||||
|
||||
*((struct bpf_hdr*)(&packp[copied]))=Header->header;
|
||||
|
||||
copied += sizeof(struct bpf_hdr);
|
||||
LocalData->C += sizeof(struct PacketHeader);
|
||||
|
||||
if (LocalData->C == Open->Size)
|
||||
LocalData->C = 0;
|
||||
|
||||
if (Open->Size - LocalData->C < plen)
|
||||
{
|
||||
//the packet is fragmented in the buffer (i.e. it skips the buffer boundary)
|
||||
ToCopy = Open->Size - LocalData->C;
|
||||
RtlCopyMemory(packp + copied,LocalData->Buffer + LocalData->C,ToCopy);
|
||||
RtlCopyMemory(packp + copied + ToCopy,LocalData->Buffer,plen-ToCopy);
|
||||
LocalData->C = plen-ToCopy;
|
||||
}
|
||||
else
|
||||
{
|
||||
//the packet is not fragmented
|
||||
RtlCopyMemory(packp + copied ,LocalData->Buffer + LocalData->C ,plen);
|
||||
LocalData->C += plen;
|
||||
// if (c==size) inutile, contemplato nell "header atomico"
|
||||
// c=0;
|
||||
}
|
||||
|
||||
Open->ReaderSN++;
|
||||
copied+=Packet_WORDALIGN(plen);
|
||||
|
||||
increment = plen + sizeof(struct PacketHeader);
|
||||
if ( Open->Size - LocalData->C < sizeof(struct PacketHeader))
|
||||
{ //the next packet would be saved at the end of the buffer, but the NewHeader struct would be fragmented
|
||||
//so the producer (--> the consumer) skips to the beginning of the buffer
|
||||
increment += Open->Size-LocalData->C;
|
||||
LocalData->C=0;
|
||||
}
|
||||
InterlockedExchangeAdd(&Open->CpuData[current_cpu].Free,increment);
|
||||
count=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_cpu=(current_cpu+1)%NCpu;
|
||||
count++;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
current_cpu=(current_cpu+1)%NCpu;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
{EXIT_SUCCESS(copied);}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
extern void *test_addr;
|
||||
|
||||
NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacReceiveContext,
|
||||
IN PVOID HeaderBuffer,IN UINT HeaderBufferSize,IN PVOID LookaheadBuffer,
|
||||
IN UINT LookaheadBufferSize,IN UINT PacketSize)
|
||||
{
|
||||
POPEN_INSTANCE Open;
|
||||
PNDIS_PACKET pPacket;
|
||||
NDIS_STATUS Status;
|
||||
UINT BytesTransfered;
|
||||
PMDL pMdl1,pMdl2;
|
||||
UINT fres;
|
||||
|
||||
CpuPrivateData *LocalData;
|
||||
ULONG Cpu;
|
||||
struct PacketHeader *Header;
|
||||
ULONG ToCopy;
|
||||
ULONG increment;
|
||||
ULONG i;
|
||||
// BOOLEAN ShouldReleaseMachineLock;
|
||||
|
||||
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;
|
||||
|
||||
if (Open->SkipProcessing == 1) //some IoCtl is modifying some shared structure, we must drop the packet.
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
|
||||
Cpu = KeGetCurrentProcessorNumber();
|
||||
LocalData = &Open->CpuData[Cpu];
|
||||
|
||||
LocalData->Processing = 1; //this tells the Ioctls that we are processing a packet, they cannot modify anything
|
||||
//until ALL the Cpu have terminated their processing (aka, set their LocalData->processing to 0)
|
||||
LocalData->Received++;
|
||||
IF_LOUD(DbgPrint("Received on CPU %d \t%d\n",Cpu,LocalData->Received);)
|
||||
// Open->Received++; // Number of packets received by filter ++
|
||||
|
||||
//
|
||||
// The MONITOR_MODE (aka TME extensions) is not supported on
|
||||
// 64 bit architectures
|
||||
//
|
||||
#ifdef __NPF_x86__
|
||||
if (Open->mode == MODE_MON)
|
||||
{
|
||||
ShouldReleaseMachineLock = TRUE;
|
||||
NdisAcquireSpinLock(&Open->MachineLock);
|
||||
}
|
||||
else
|
||||
ShouldReleaseMachineLock = FALSE;
|
||||
#endif
|
||||
|
||||
//
|
||||
//Check if the lookahead buffer follows the mac header.
|
||||
//If the data follow the header (i.e. there is only a buffer) a normal bpf_filter() is
|
||||
//executed on the packet.
|
||||
//Otherwise if there are 2 separate buffers (this could be the case of LAN emulation or
|
||||
//things like this) bpf_filter_with_2_buffers() is executed.
|
||||
//
|
||||
if((UINT)((PUCHAR)LookaheadBuffer-(PUCHAR)HeaderBuffer) != HeaderBufferSize)
|
||||
fres=bpf_filter_with_2_buffers((struct bpf_insn*)(Open->bpfprogram),
|
||||
HeaderBuffer,
|
||||
LookaheadBuffer,
|
||||
HeaderBufferSize,
|
||||
PacketSize+HeaderBufferSize,
|
||||
LookaheadBufferSize+HeaderBufferSize,
|
||||
&Open->mem_ex,
|
||||
&Open->tme,
|
||||
&G_Start_Time);
|
||||
|
||||
|
||||
else
|
||||
//
|
||||
// the jit filter is available on x86 (32 bit) only
|
||||
//
|
||||
#ifdef __NPF_x86__
|
||||
|
||||
if(Open->Filter != NULL)
|
||||
{
|
||||
if (Open->bpfprogram != NULL)
|
||||
{
|
||||
fres=Open->Filter->Function(HeaderBuffer,
|
||||
PacketSize+HeaderBufferSize,
|
||||
LookaheadBufferSize+HeaderBufferSize);
|
||||
}
|
||||
else
|
||||
fres = -1;
|
||||
}
|
||||
else
|
||||
#endif //__NPF_x86__
|
||||
fres=bpf_filter((struct bpf_insn*)(Open->bpfprogram),
|
||||
HeaderBuffer,
|
||||
PacketSize+HeaderBufferSize,
|
||||
LookaheadBufferSize+HeaderBufferSize,
|
||||
&Open->mem_ex,
|
||||
&Open->tme,
|
||||
&G_Start_Time);
|
||||
|
||||
//
|
||||
// The MONITOR_MODE (aka TME extensions) is not supported on
|
||||
// 64 bit architectures
|
||||
//
|
||||
#ifdef __NPF_x86__
|
||||
if (ShouldReleaseMachineLock)
|
||||
NdisReleaseSpinLock(&Open->MachineLock);
|
||||
#endif
|
||||
|
||||
//
|
||||
// The MONITOR_MODE (aka TME extensions) is not supported on
|
||||
// 64 bit architectures
|
||||
//
|
||||
#ifdef __NPF_x86__
|
||||
if(Open->mode==MODE_MON)
|
||||
// we are in monitor mode
|
||||
{
|
||||
if (fres==1)
|
||||
KeSetEvent(Open->ReadEvent,0,FALSE);
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
if(fres==0)
|
||||
{
|
||||
// Packet not accepted by the filter, ignore it.
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
//if the filter returns -1 the whole packet must be accepted
|
||||
if(fres==-1 || fres > PacketSize+HeaderBufferSize)
|
||||
fres = PacketSize+HeaderBufferSize;
|
||||
|
||||
if(Open->mode & MODE_STAT)
|
||||
{
|
||||
// we are in statistics mode
|
||||
NdisAcquireSpinLock( &Open->CountersLock );
|
||||
|
||||
Open->Npackets.QuadPart++;
|
||||
|
||||
if(PacketSize+HeaderBufferSize<60)
|
||||
Open->Nbytes.QuadPart+=60;
|
||||
else
|
||||
Open->Nbytes.QuadPart+=PacketSize+HeaderBufferSize;
|
||||
// add preamble+SFD+FCS to the packet
|
||||
// these values must be considered because are not part of the packet received from NDIS
|
||||
Open->Nbytes.QuadPart+=12;
|
||||
|
||||
NdisReleaseSpinLock( &Open->CountersLock );
|
||||
|
||||
if(!(Open->mode & MODE_DUMP))
|
||||
{
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
}
|
||||
|
||||
if(Open->Size == 0)
|
||||
{
|
||||
LocalData->Dropped++;
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
if(Open->mode & MODE_DUMP && Open->MaxDumpPacks)
|
||||
{
|
||||
ULONG Accepted=0;
|
||||
for(i=0;i<NCpu;i++)
|
||||
Accepted+=Open->CpuData[i].Accepted;
|
||||
|
||||
if( Accepted > Open->MaxDumpPacks)
|
||||
{
|
||||
// Reached the max number of packets to save in the dump file. Discard the packet and stop the dump thread.
|
||||
Open->DumpLimitReached = TRUE; // This stops the thread
|
||||
// Awake the dump thread
|
||||
NdisSetEvent(&Open->DumpEvent);
|
||||
|
||||
// Awake the application
|
||||
KeSetEvent(Open->ReadEvent,0,FALSE);
|
||||
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////COPIA.C//////////////////////////////////////////77
|
||||
|
||||
if (fres + sizeof(struct PacketHeader) > LocalData->Free)
|
||||
{
|
||||
LocalData->Dropped++;
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
if (LocalData->TransferMdl1 != NULL)
|
||||
{
|
||||
//if TransferMdl is not NULL, there is some TransferData pending (i.e. not having called TransferDataComplete, yet)
|
||||
//in order to avoid buffer corruption, we drop the packet
|
||||
LocalData->Dropped++;
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
|
||||
if (LookaheadBufferSize + HeaderBufferSize >= fres)
|
||||
{
|
||||
//we do not need to call NdisTransferData, either because we need only the HeaderBuffer, or because the LookaheadBuffer
|
||||
//contains what we need
|
||||
|
||||
|
||||
|
||||
Header = (struct PacketHeader*)(LocalData->Buffer + LocalData->P);
|
||||
LocalData->Accepted++;
|
||||
GET_TIME(&Header->header.bh_tstamp,&G_Start_Time);
|
||||
Header->SN = InterlockedIncrement(&Open->WriterSN) - 1;
|
||||
|
||||
Header->header.bh_caplen = fres;
|
||||
Header->header.bh_datalen = PacketSize + HeaderBufferSize;
|
||||
Header->header.bh_hdrlen=sizeof(struct bpf_hdr);
|
||||
|
||||
LocalData->P +=sizeof(struct PacketHeader);
|
||||
if (LocalData->P == Open->Size)
|
||||
LocalData->P = 0;
|
||||
|
||||
if ( fres <= HeaderBufferSize || (UINT)( (PUCHAR)LookaheadBuffer - (PUCHAR)HeaderBuffer ) == HeaderBufferSize )
|
||||
{
|
||||
//we can consider the buffer contiguous, either because we use only the data
|
||||
//present in the HeaderBuffer, or because HeaderBuffer and LookaheadBuffer are contiguous
|
||||
// ;-))))))
|
||||
|
||||
if (Open->Size - LocalData->P < fres)
|
||||
{
|
||||
//the packet will be fragmented in the buffer (aka, it will skip the buffer boundary)
|
||||
//two copies!!
|
||||
ToCopy = Open->Size - LocalData->P;
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->P,HeaderBuffer, ToCopy);
|
||||
NdisMoveMappedMemory(LocalData->Buffer + 0 , (PUCHAR)HeaderBuffer + ToCopy, fres - ToCopy);
|
||||
LocalData->P = fres-ToCopy;
|
||||
}
|
||||
else
|
||||
{
|
||||
//the packet does not need to be fragmented in the buffer (aka, it doesn't skip the buffer boundary)
|
||||
// ;-)))))) only ONE copy
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, HeaderBuffer, fres);
|
||||
LocalData->P += fres;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//HeaderBuffer and LookAhead buffer are NOT contiguous,
|
||||
//AND, we need some bytes from the LookaheadBuffer, too
|
||||
if (Open->Size - LocalData->P < fres)
|
||||
{
|
||||
//the packet will be fragmented in the buffer (aka, it will skip the buffer boundary)
|
||||
if (Open->Size - LocalData->P >= HeaderBufferSize)
|
||||
{
|
||||
//HeaderBuffer is NOT fragmented
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, HeaderBuffer, HeaderBufferSize);
|
||||
LocalData->P += HeaderBufferSize;
|
||||
|
||||
if (LocalData->P == Open->Size)
|
||||
{
|
||||
//the fragmentation of the packet in the buffer is the same fragmentation
|
||||
//in HeaderBuffer+LookaheadBuffer
|
||||
LocalData->P=0;
|
||||
NdisMoveMappedMemory(LocalData->Buffer + 0, LookaheadBuffer, fres - HeaderBufferSize);
|
||||
LocalData->P += (fres - HeaderBufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
//LookAheadBuffer is fragmented, two copies
|
||||
ToCopy = Open->Size - LocalData->P;
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, LookaheadBuffer, ToCopy);
|
||||
LocalData->P=0;
|
||||
NdisMoveMappedMemory(LocalData->Buffer + 0, (PUCHAR)LookaheadBuffer+ ToCopy, fres - HeaderBufferSize - ToCopy);
|
||||
LocalData->P = fres - HeaderBufferSize - ToCopy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//HeaderBuffer is fragmented in the buffer (aka, it will skip the buffer boundary)
|
||||
//two copies to copy the HeaderBuffer
|
||||
ToCopy = Open->Size - LocalData->P;
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, HeaderBuffer, ToCopy);
|
||||
LocalData->P = 0;
|
||||
NdisMoveMappedMemory(LocalData->Buffer + 0, (PUCHAR)HeaderBuffer + ToCopy, HeaderBufferSize - ToCopy);
|
||||
LocalData->P = HeaderBufferSize - ToCopy;
|
||||
|
||||
//only one copy to copy the LookaheadBuffer
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, LookaheadBuffer, fres- HeaderBufferSize);
|
||||
LocalData->P += (fres - HeaderBufferSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//the packet won't be fragmented in the destination buffer (aka, it won't skip the buffer boundary)
|
||||
//two copies, the former to copy the HeaderBuffer, the latter to copy the LookaheadBuffer
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, HeaderBuffer, HeaderBufferSize);
|
||||
LocalData->P += HeaderBufferSize;
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->P, LookaheadBuffer, fres - HeaderBufferSize);
|
||||
LocalData->P += (fres - HeaderBufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
increment = fres + sizeof(struct PacketHeader);
|
||||
if (Open->Size - LocalData->P < sizeof(struct PacketHeader)) //we check that the available, AND contiguous, space in the buffer will fit
|
||||
{ //the NewHeader structure, at least, otherwise we skip the producer
|
||||
increment += Open->Size-LocalData->P; //at the beginning of the buffer (p = 0), and decrement the free bytes appropriately
|
||||
LocalData->P = 0;
|
||||
}
|
||||
|
||||
InterlockedExchangeAdd(&LocalData->Free, (ULONG)(-(LONG)increment));
|
||||
if(Open->Size - LocalData->Free >= Open->MinToCopy)
|
||||
{
|
||||
if(Open->mode & MODE_DUMP)
|
||||
NdisSetEvent(&Open->DumpEvent);
|
||||
else
|
||||
KeSetEvent(Open->ReadEvent,0,FALSE);
|
||||
}
|
||||
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
IF_LOUD(DbgPrint("TransferData!!\n");)
|
||||
//ndisTransferData required
|
||||
LocalData->NewP = LocalData->P;
|
||||
|
||||
LocalData->NewP +=sizeof(struct PacketHeader);
|
||||
if (LocalData->NewP == Open->Size)
|
||||
LocalData->NewP = 0;
|
||||
|
||||
//first of all, surely the header must be copied
|
||||
if (Open->Size-LocalData->NewP >= HeaderBufferSize)
|
||||
{
|
||||
//1 copy!
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->NewP, HeaderBuffer, HeaderBufferSize);
|
||||
LocalData->NewP += HeaderBufferSize;
|
||||
if (LocalData->NewP == Open->Size)
|
||||
LocalData->NewP = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ToCopy = Open->Size - LocalData->NewP;
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->NewP, HeaderBuffer, ToCopy);
|
||||
NdisMoveMappedMemory(LocalData->Buffer + 0, (PUCHAR)HeaderBuffer + ToCopy, HeaderBufferSize - ToCopy);
|
||||
LocalData->NewP = HeaderBufferSize - ToCopy;
|
||||
}
|
||||
|
||||
//then we copy the Lookahead buffer
|
||||
|
||||
if (Open->Size-LocalData->NewP >= LookaheadBufferSize)
|
||||
{
|
||||
//1 copy!
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->NewP, LookaheadBuffer, LookaheadBufferSize);
|
||||
LocalData->NewP += LookaheadBufferSize;
|
||||
if (LocalData->NewP == Open->Size)
|
||||
LocalData->NewP = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ToCopy = Open->Size - LocalData->NewP;
|
||||
NdisMoveMappedMemory(LocalData->Buffer + LocalData->NewP, LookaheadBuffer, ToCopy);
|
||||
NdisMoveMappedMemory(LocalData->Buffer + 0, (PUCHAR)LookaheadBuffer + ToCopy, LookaheadBufferSize - ToCopy);
|
||||
LocalData->NewP = LookaheadBufferSize - ToCopy;
|
||||
}
|
||||
|
||||
//Now we must prepare the buffer(s) for the NdisTransferData
|
||||
if ((Open->Size - LocalData->NewP) >= (fres - HeaderBufferSize - LookaheadBufferSize))
|
||||
{
|
||||
//only 1 buffer
|
||||
pMdl1 = IoAllocateMdl(
|
||||
LocalData->Buffer + LocalData->NewP,
|
||||
fres - HeaderBufferSize - LookaheadBufferSize,
|
||||
FALSE,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
if (pMdl1 == NULL)
|
||||
{
|
||||
IF_LOUD(DbgPrint("Error allocating Mdl1\n");)
|
||||
LocalData->Dropped++;
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
MmBuildMdlForNonPagedPool(pMdl1);
|
||||
pMdl2=NULL;
|
||||
LocalData->NewP += fres - HeaderBufferSize - LookaheadBufferSize;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//2 buffers
|
||||
pMdl1 = IoAllocateMdl(
|
||||
LocalData->Buffer + LocalData->NewP,
|
||||
Open->Size - LocalData->NewP,
|
||||
FALSE,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
if (pMdl1 == NULL)
|
||||
{
|
||||
IF_LOUD(DbgPrint("Error allocating Mdl1\n");)
|
||||
LocalData->Dropped++;
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
pMdl2 = IoAllocateMdl(
|
||||
LocalData->Buffer + 0,
|
||||
fres - HeaderBufferSize - LookaheadBufferSize - (Open->Size - LocalData->NewP),
|
||||
FALSE,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
if (pMdl2 == NULL)
|
||||
{
|
||||
IF_LOUD(DbgPrint("Error allocating Mdl2\n");)
|
||||
IoFreeMdl(pMdl1);
|
||||
LocalData->Dropped++;
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
LocalData->NewP = fres - HeaderBufferSize - LookaheadBufferSize - (Open->Size - LocalData->NewP);
|
||||
|
||||
MmBuildMdlForNonPagedPool(pMdl1);
|
||||
MmBuildMdlForNonPagedPool(pMdl2);
|
||||
}
|
||||
|
||||
|
||||
NdisAllocatePacket(&Status, &pPacket, Open->PacketPool);
|
||||
|
||||
if (Status != NDIS_STATUS_SUCCESS)
|
||||
{
|
||||
IF_LOUD(DbgPrint("NPF: Tap - No free packets\n");)
|
||||
IoFreeMdl(pMdl1);
|
||||
if (pMdl2 != NULL)
|
||||
IoFreeMdl(pMdl2);
|
||||
LocalData->Dropped++;
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
if (pMdl2 != NULL)
|
||||
NdisChainBufferAtFront(pPacket,pMdl2);
|
||||
|
||||
NdisChainBufferAtFront(pPacket,pMdl1);
|
||||
|
||||
RESERVED(pPacket)->Cpu = Cpu;
|
||||
|
||||
LocalData->TransferMdl1 = pMdl1;
|
||||
LocalData->TransferMdl2 = pMdl2;
|
||||
|
||||
|
||||
Header = (struct PacketHeader*)(LocalData->Buffer + LocalData->P);
|
||||
Header->header.bh_caplen = fres;
|
||||
Header->header.bh_datalen = PacketSize + HeaderBufferSize;
|
||||
Header->header.bh_hdrlen=sizeof(struct bpf_hdr);
|
||||
|
||||
NdisTransferData(
|
||||
&Status,
|
||||
Open->AdapterHandle,
|
||||
MacReceiveContext,
|
||||
LookaheadBufferSize,
|
||||
fres - HeaderBufferSize - LookaheadBufferSize,
|
||||
pPacket,
|
||||
&BytesTransfered);
|
||||
|
||||
if (Status != NDIS_STATUS_PENDING)
|
||||
{
|
||||
IF_LOUD(DbgPrint("NdisTransferData, not pending!\n");)
|
||||
LocalData->TransferMdl1 = NULL;
|
||||
LocalData->TransferMdl2 = NULL;
|
||||
|
||||
IoFreeMdl(pMdl1);
|
||||
if ( pMdl2 != NULL )
|
||||
IoFreeMdl(pMdl2);
|
||||
|
||||
NdisReinitializePacket(pPacket);
|
||||
// Put the packet on the free queue
|
||||
NdisFreePacket(pPacket);
|
||||
|
||||
LocalData->P = LocalData->NewP;
|
||||
|
||||
LocalData->Accepted++;
|
||||
GET_TIME(&Header->header.bh_tstamp,&G_Start_Time);
|
||||
Header->SN = InterlockedIncrement(&Open->WriterSN) - 1;
|
||||
|
||||
increment = fres + sizeof(struct PacketHeader);
|
||||
if (Open->Size - LocalData->P < sizeof(struct PacketHeader))
|
||||
{
|
||||
increment += Open->Size-LocalData->P;
|
||||
LocalData->P = 0;
|
||||
}
|
||||
|
||||
InterlockedExchangeAdd(&LocalData->Free, (ULONG)(-(LONG)increment));
|
||||
|
||||
if(Open->Size - LocalData->Free >= Open->MinToCopy)
|
||||
{
|
||||
if(Open->mode & MODE_DUMP)
|
||||
NdisSetEvent(&Open->DumpEvent);
|
||||
else
|
||||
KeSetEvent(Open->ReadEvent,0,FALSE);
|
||||
}
|
||||
|
||||
LocalData->Processing = 0;
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint("NdisTransferData, pending!\n");
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
}
|
||||
|
||||
return NDIS_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID NPF_TransferDataComplete (IN NDIS_HANDLE ProtocolBindingContext,IN PNDIS_PACKET pPacket,
|
||||
IN NDIS_STATUS Status,IN UINT BytesTransfered)
|
||||
{
|
||||
POPEN_INSTANCE Open;
|
||||
ULONG Cpu;
|
||||
CpuPrivateData *LocalData;
|
||||
struct PacketHeader* Header;
|
||||
ULONG increment;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: TransferDataComplete\n");)
|
||||
|
||||
Open = (POPEN_INSTANCE)ProtocolBindingContext;
|
||||
|
||||
Cpu = RESERVED(pPacket)->Cpu;
|
||||
|
||||
LocalData = &Open->CpuData[Cpu];
|
||||
|
||||
IoFreeMdl(LocalData->TransferMdl1);
|
||||
if ( LocalData->TransferMdl2 != NULL )
|
||||
IoFreeMdl(LocalData->TransferMdl2);
|
||||
|
||||
NdisReinitializePacket(pPacket);
|
||||
// Put the packet on the free queue
|
||||
NdisFreePacket(pPacket);
|
||||
|
||||
//the packet has been successfully copied to the kernel buffer, we can prepend it with the PacketHeader,
|
||||
//and obtain the sequence number and the timestamp
|
||||
|
||||
LocalData->Accepted++;
|
||||
Header = (struct PacketHeader*)(LocalData->Buffer + LocalData->P);
|
||||
GET_TIME(&Header->header.bh_tstamp,&G_Start_Time);
|
||||
Header->SN = InterlockedIncrement(&Open->WriterSN) - 1;
|
||||
|
||||
LocalData->P = LocalData->NewP;
|
||||
|
||||
increment = Header->header.bh_caplen + sizeof(struct PacketHeader);
|
||||
if (Open->Size - LocalData->P < sizeof(struct PacketHeader))
|
||||
{
|
||||
increment += Open->Size-LocalData->P;
|
||||
LocalData->P = 0;
|
||||
}
|
||||
|
||||
InterlockedExchangeAdd(&LocalData->Free, (ULONG)(-(LONG)increment));
|
||||
|
||||
if(Open->Size - LocalData->Free >= Open->MinToCopy)
|
||||
{
|
||||
if(Open->mode & MODE_DUMP)
|
||||
NdisSetEvent(&Open->DumpEvent);
|
||||
else
|
||||
KeSetEvent(Open->ReadEvent,0,FALSE);
|
||||
}
|
||||
|
||||
LocalData->TransferMdl1 = NULL;
|
||||
LocalData->TransferMdl2 = NULL;
|
||||
LocalData->Processing = 0;
|
||||
|
||||
// Unfreeze the consumer
|
||||
if(Open->Size - LocalData->Free > Open->MinToCopy)
|
||||
{
|
||||
if(Open->mode & MODE_DUMP)
|
||||
NdisSetEvent(&Open->DumpEvent);
|
||||
else
|
||||
KeSetEvent(Open->ReadEvent,0,FALSE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext)
|
||||
{
|
||||
IF_VERY_LOUD(DbgPrint("NPF: NPF_ReceiveComplete\n");)
|
||||
return;
|
||||
}
|
||||
63
src/See/See.rc
Normal file
63
src/See/See.rc
Normal file
@ -0,0 +1,63 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource1.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Japanese resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
|
||||
#pragma code_page(932)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource1.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Japanese resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
462
src/See/See.vcproj
Normal file
462
src/See/See.vcproj
Normal file
@ -0,0 +1,462 @@
|
||||
<?xml version="1.0" encoding="shift_jis"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="See"
|
||||
ProjectGUID="{D817977C-481C-4575-B229-DD2896EDF6C9}"
|
||||
RootNamespace="See"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)bin"
|
||||
IntermediateDirectory="$(PlatformName)_$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
InlineFunctionExpansion="0"
|
||||
EnableIntrinsicFunctions="false"
|
||||
FavorSizeOrSpeed="0"
|
||||
AdditionalIncludeDirectories="$(SolutionDir)Mayaqua\win32_inc;C:\WINDDK\7600.16385.0\inc\ddk;C:\WinDDK\7600.16385.0\inc\api;C:\WinDDK\7600.16385.0\inc\crt;$(SolutionDir)"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;NEO_EXPORTS;VPN_SPEED;WIN_NT_DRIVER;_X86_=1;NDIS50;NTKERNEL"
|
||||
StringPooling="false"
|
||||
ExceptionHandling="0"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="4"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="2"
|
||||
CompileAs="1"
|
||||
DisableSpecificWarnings="4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:GenerateVersionResource "$(TargetPath)" /OUT:"$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/driver /subsystem:native,5.00 /FULLBUILD /align:0x80 /osversion:5.00 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB"
|
||||
AdditionalDependencies="ntoskrnl.lib hal.lib wmilib.lib ndis.lib "$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res""
|
||||
OutputFile="$(OutDir)\hamcore\not_signed\see.sys"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="C:\WINDDK\7600.16385.0\lib\wnet\i386"
|
||||
GenerateManifest="false"
|
||||
IgnoreAllDefaultLibraries="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(SolutionDir)DebugFiles\pdb\$(PlatformName)_$(ConfigurationName)\$(ProjectName).pdb"
|
||||
GenerateMapFile="true"
|
||||
MapFileName="$(SolutionDir)DebugFiles\map\$(PlatformName)_$(ConfigurationName)\$(ProjectName).map"
|
||||
SubSystem="0"
|
||||
StackReserveSize="262144"
|
||||
StackCommitSize="4096"
|
||||
OptimizeReferences="1"
|
||||
EnableCOMDATFolding="1"
|
||||
EntryPointSymbol="DriverEntry"
|
||||
BaseAddress="0x10000"
|
||||
RandomizedBaseAddress="0"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="$(SolutionDir)tmp\lib\$(PlatformName)_$(ConfigurationName)\$(ProjectName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode "$(TargetPath)" /COMMENT:"VPN Software" /KERNEL:yes"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)bin"
|
||||
IntermediateDirectory="$(PlatformName)_$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
InlineFunctionExpansion="0"
|
||||
EnableIntrinsicFunctions="false"
|
||||
FavorSizeOrSpeed="0"
|
||||
AdditionalIncludeDirectories="$(SolutionDir)Mayaqua\win32_inc;C:\WINDDK\7600.16385.0\inc\ddk;C:\WinDDK\7600.16385.0\inc\api;C:\WinDDK\7600.16385.0\inc\crt;$(SolutionDir)"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;NEO_EXPORTS;VPN_SPEED;WIN_NT_DRIVER;NDIS50;WIN32_EXT;__NPF_AMD64__;_AMD64_;AMD64;_WIN64;NTKERNEL;CPU_64"
|
||||
StringPooling="false"
|
||||
ExceptionHandling="0"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="4"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="2"
|
||||
CompileAs="1"
|
||||
DisableSpecificWarnings="4996;4334"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:GenerateVersionResource "$(TargetPath)" /OUT:"$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:5.00 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB"
|
||||
AdditionalDependencies="ntoskrnl.lib hal.lib wmilib.lib ndis.lib "$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res""
|
||||
OutputFile="$(OutDir)\hamcore\not_signed\see_x64.sys"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="C:\WINDDK\7600.16385.0\lib\wnet\amd64"
|
||||
GenerateManifest="false"
|
||||
IgnoreAllDefaultLibraries="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(SolutionDir)DebugFiles\pdb\$(PlatformName)_$(ConfigurationName)\$(ProjectName).pdb"
|
||||
GenerateMapFile="true"
|
||||
MapFileName="$(SolutionDir)DebugFiles\map\$(PlatformName)_$(ConfigurationName)\$(ProjectName).map"
|
||||
SubSystem="0"
|
||||
StackReserveSize="262144"
|
||||
StackCommitSize="4096"
|
||||
OptimizeReferences="1"
|
||||
EnableCOMDATFolding="1"
|
||||
EntryPointSymbol="DriverEntry"
|
||||
BaseAddress="0x10000"
|
||||
RandomizedBaseAddress="0"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="$(SolutionDir)tmp\lib\$(PlatformName)_$(ConfigurationName)\$(ProjectName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode "$(TargetPath)" /COMMENT:"VPN Software" /KERNEL:yes"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\bucket_lookup.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\count_packets.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dump.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\functions.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jitter.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\normal_lookup.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Openclos.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Packet.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Read.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tcp_session.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tme.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\win_bpf_filter.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\win_bpf_filter_init.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Write.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\bucket_lookup.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\count_packets.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dagc.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DEBUG.H"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Devioctl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\functions.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jitter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\memory_t.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\normal_lookup.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Ntddndis.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Ntddpack.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Packet.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Packet32.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tcp_session.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\time_calls.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tme.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\valid_insns.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\win_bpf.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\win_bpf_filter_init.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\See.rc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
426
src/See/Write.c
Normal file
426
src/See/Write.c
Normal file
@ -0,0 +1,426 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||
* Copyright (c) 2005 CACE Technologies, Davis (California)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#include "stdarg.h"
|
||||
#include "ntddk.h"
|
||||
#include "ntiologc.h"
|
||||
#include "ndis.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "packet.h"
|
||||
|
||||
|
||||
void *test_addr = NULL;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
NTSTATUS
|
||||
NPF_Write(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
)
|
||||
|
||||
{
|
||||
POPEN_INSTANCE Open;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
PNDIS_PACKET pPacket;
|
||||
UINT i;
|
||||
NDIS_STATUS Status;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF_Write\n");)
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
|
||||
Open=IrpSp->FileObject->FsContext;
|
||||
|
||||
if( Open->Bound == FALSE )
|
||||
{
|
||||
// The Network adapter was removed.
|
||||
EXIT_FAILURE(0);
|
||||
}
|
||||
|
||||
NdisAcquireSpinLock(&Open->WriteLock);
|
||||
if(Open->WriteInProgress)
|
||||
{
|
||||
// Another write operation is currently in progress
|
||||
NdisReleaseSpinLock(&Open->WriteLock);
|
||||
EXIT_FAILURE(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Open->WriteInProgress = TRUE;
|
||||
}
|
||||
|
||||
NdisReleaseSpinLock(&Open->WriteLock);
|
||||
|
||||
IF_LOUD(DbgPrint("Max frame size = %d, packet size = %d\n", Open->MaxFrameSize, IrpSp->Parameters.Write.Length);)
|
||||
|
||||
|
||||
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");)
|
||||
|
||||
EXIT_FAILURE(0);
|
||||
}
|
||||
|
||||
|
||||
IoMarkIrpPending(Irp);
|
||||
|
||||
Open->Multiple_Write_Counter=Open->Nwrites;
|
||||
|
||||
NdisResetEvent(&Open->WriteEvent);
|
||||
|
||||
|
||||
for(i=0;i<Open->Nwrites;i++){
|
||||
|
||||
// Try to get a packet from our list of free ones
|
||||
NdisAllocatePacket(
|
||||
&Status,
|
||||
&pPacket,
|
||||
Open->PacketPool
|
||||
);
|
||||
|
||||
if (Status != NDIS_STATUS_SUCCESS) {
|
||||
|
||||
// No free packets
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if(Open->SkipSentPackets)
|
||||
{
|
||||
NdisSetPacketFlags(
|
||||
pPacket,
|
||||
g_SendPacketFlags);
|
||||
}
|
||||
|
||||
// The packet hasn't a buffer that needs not to be freed after every single write
|
||||
RESERVED(pPacket)->FreeBufAfterWrite = FALSE;
|
||||
|
||||
// Save the IRP associated with the packet
|
||||
RESERVED(pPacket)->Irp=Irp;
|
||||
|
||||
// Attach the writes buffer to the packet
|
||||
NdisChainBufferAtFront(pPacket,Irp->MdlAddress);
|
||||
|
||||
test_addr = MmGetMdlVirtualAddress(Irp->MdlAddress);
|
||||
|
||||
// Call the MAC
|
||||
NdisSend(
|
||||
&Status,
|
||||
Open->AdapterHandle,
|
||||
pPacket);
|
||||
|
||||
if (Status != NDIS_STATUS_PENDING) {
|
||||
// The send didn't pend so call the completion handler now
|
||||
NPF_SendComplete(
|
||||
Open,
|
||||
pPacket,
|
||||
Status
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
if(i%100==99){
|
||||
NdisWaitEvent(&Open->WriteEvent,1000);
|
||||
NdisResetEvent(&Open->WriteEvent);
|
||||
}
|
||||
}
|
||||
|
||||
return(STATUS_PENDING);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
INT
|
||||
NPF_BufferedWrite(
|
||||
IN PIRP Irp,
|
||||
IN PCHAR UserBuff,
|
||||
IN ULONG UserBuffSize,
|
||||
BOOLEAN Sync)
|
||||
{
|
||||
POPEN_INSTANCE Open;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
PNDIS_PACKET pPacket;
|
||||
NDIS_STATUS Status;
|
||||
struct sf_pkthdr *winpcap_hdr;
|
||||
PMDL TmpMdl;
|
||||
PCHAR EndOfUserBuff = UserBuff + UserBuffSize;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: BufferedWrite, UserBuff=%x, Size=%u\n", UserBuff, UserBuffSize);)
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Open=IrpSp->FileObject->FsContext;
|
||||
|
||||
if( Open->Bound == FALSE ){
|
||||
// The Network adapter was removed.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sanity check on the user buffer
|
||||
if(UserBuff == NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// Reset the event used to synchronize packet allocation
|
||||
NdisResetEvent(&Open->WriteEvent);
|
||||
|
||||
// Reset the pending packets counter
|
||||
Open->Multiple_Write_Counter = 0;
|
||||
|
||||
// Start from the first packet
|
||||
winpcap_hdr = (struct sf_pkthdr*)UserBuff;
|
||||
|
||||
// Chech the consistency of the user buffer
|
||||
if( (PCHAR)winpcap_hdr + winpcap_hdr->caplen + sizeof(struct sf_pkthdr) > EndOfUserBuff )
|
||||
{
|
||||
IF_LOUD(DbgPrint("Buffered Write: bogus packet buffer\n");)
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Main loop: send the buffer to the wire
|
||||
//
|
||||
while(TRUE)
|
||||
{
|
||||
|
||||
if(winpcap_hdr->caplen ==0/* || winpcap_hdr->caplen > Open->MaxFrameSize*/)
|
||||
{
|
||||
// Malformed header
|
||||
IF_LOUD(DbgPrint("NPF_BufferedWrite: malformed or bogus user buffer, aborting write.\n");)
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allocate an MDL to map the packet data
|
||||
TmpMdl = IoAllocateMdl((PCHAR)winpcap_hdr + sizeof(struct sf_pkthdr),
|
||||
winpcap_hdr->caplen,
|
||||
FALSE,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
if (TmpMdl == NULL)
|
||||
{
|
||||
// Unable to map the memory: packet lost
|
||||
IF_LOUD(DbgPrint("NPF_BufferedWrite: unable to allocate the MDL.\n");)
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
MmBuildMdlForNonPagedPool(TmpMdl); // XXX can this line be removed?
|
||||
|
||||
// Allocate a packet from our free list
|
||||
NdisAllocatePacket( &Status, &pPacket, Open->PacketPool);
|
||||
|
||||
if (Status != NDIS_STATUS_SUCCESS) {
|
||||
// No more free packets
|
||||
IF_LOUD(DbgPrint("NPF_BufferedWrite: no more free packets, returning.\n");)
|
||||
|
||||
NdisResetEvent(&Open->WriteEvent);
|
||||
|
||||
NdisWaitEvent(&Open->WriteEvent, 1000);
|
||||
|
||||
// Try again to allocate a packet
|
||||
NdisAllocatePacket( &Status, &pPacket, Open->PacketPool);
|
||||
|
||||
if (Status != NDIS_STATUS_SUCCESS) {
|
||||
// Second failure, report an error
|
||||
IoFreeMdl(TmpMdl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// IoFreeMdl(TmpMdl);
|
||||
// return (PCHAR)winpcap_hdr - UserBuff;
|
||||
}
|
||||
|
||||
if(Open->SkipSentPackets)
|
||||
{
|
||||
NdisSetPacketFlags(
|
||||
pPacket,
|
||||
g_SendPacketFlags);
|
||||
}
|
||||
|
||||
// The packet has a buffer that needs to be freed after every single write
|
||||
RESERVED(pPacket)->FreeBufAfterWrite = TRUE;
|
||||
|
||||
TmpMdl->Next = NULL;
|
||||
|
||||
// Attach the MDL to the packet
|
||||
NdisChainBufferAtFront(pPacket, TmpMdl);
|
||||
|
||||
// Increment the number of pending sends
|
||||
InterlockedIncrement(&Open->Multiple_Write_Counter);
|
||||
|
||||
// Call the MAC
|
||||
NdisSend( &Status, Open->AdapterHandle, pPacket);
|
||||
|
||||
if (Status != NDIS_STATUS_PENDING) {
|
||||
// The send didn't pend so call the completion handler now
|
||||
NPF_SendComplete(
|
||||
Open,
|
||||
pPacket,
|
||||
Status
|
||||
);
|
||||
}
|
||||
|
||||
// Step to the next packet in the buffer
|
||||
(PCHAR)winpcap_hdr += winpcap_hdr->caplen + sizeof(struct sf_pkthdr);
|
||||
|
||||
// Check if the end of the user buffer has been reached
|
||||
if( (PCHAR)winpcap_hdr >= EndOfUserBuff )
|
||||
{
|
||||
IF_LOUD(DbgPrint("NPF_BufferedWrite: End of buffer.\n");)
|
||||
|
||||
// Wait the completion of pending sends
|
||||
NPF_WaitEndOfBufferedWrite(Open);
|
||||
|
||||
return (INT)((PCHAR)winpcap_hdr - UserBuff);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (INT)((PCHAR)winpcap_hdr - UserBuff);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID NPF_WaitEndOfBufferedWrite(POPEN_INSTANCE Open)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
NdisResetEvent(&Open->WriteEvent);
|
||||
|
||||
for(i=0; Open->Multiple_Write_Counter > 0 && i < TRANSMIT_PACKETS; i++)
|
||||
{
|
||||
NdisWaitEvent(&Open->WriteEvent, 100);
|
||||
NdisResetEvent(&Open->WriteEvent);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID
|
||||
NPF_SendComplete(
|
||||
IN NDIS_HANDLE ProtocolBindingContext,
|
||||
IN PNDIS_PACKET pPacket,
|
||||
IN NDIS_STATUS Status
|
||||
)
|
||||
|
||||
{
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION irpSp;
|
||||
POPEN_INSTANCE Open;
|
||||
PMDL TmpMdl;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: SendComplete, BindingContext=%d\n",ProtocolBindingContext);)
|
||||
|
||||
Open= (POPEN_INSTANCE)ProtocolBindingContext;
|
||||
|
||||
if( RESERVED(pPacket)->FreeBufAfterWrite )
|
||||
{
|
||||
//
|
||||
// Packet sent by NPF_BufferedWrite()
|
||||
//
|
||||
|
||||
|
||||
// Free the MDL associated with the packet
|
||||
NdisUnchainBufferAtFront(pPacket, &TmpMdl);
|
||||
|
||||
IoFreeMdl(TmpMdl);
|
||||
|
||||
// recyle the packet
|
||||
// NdisReinitializePacket(pPacket);
|
||||
|
||||
NdisFreePacket(pPacket);
|
||||
|
||||
// Increment the number of pending sends
|
||||
InterlockedDecrement(&Open->Multiple_Write_Counter);
|
||||
|
||||
NdisSetEvent(&Open->WriteEvent);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Packet sent by NPF_Write()
|
||||
//
|
||||
|
||||
if((Open->Nwrites - Open->Multiple_Write_Counter) %100 == 99)
|
||||
NdisSetEvent(&Open->WriteEvent);
|
||||
|
||||
Open->Multiple_Write_Counter--;
|
||||
|
||||
if(Open->Multiple_Write_Counter == 0){
|
||||
// Release the buffer and awake the application
|
||||
NdisUnchainBufferAtFront(pPacket, &TmpMdl);
|
||||
|
||||
// Complete the request
|
||||
Irp=RESERVED(pPacket)->Irp;
|
||||
irpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = irpSp->Parameters.Write.Length;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
NdisAcquireSpinLock(&Open->WriteLock);
|
||||
Open->WriteInProgress = FALSE;
|
||||
NdisReleaseSpinLock(&Open->WriteLock);
|
||||
}
|
||||
|
||||
// Put the packet back on the free list
|
||||
NdisFreePacket(pPacket);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
264
src/See/bucket_lookup.c
Normal file
264
src/See/bucket_lookup.c
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "tme.h"
|
||||
#include "bucket_lookup.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <net/tme/tme.h>
|
||||
#include <net/tme/bucket_lookup.h>
|
||||
#else
|
||||
#include <tme/tme.h>
|
||||
#include <tme/bucket_lookup.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* the key is represented by the initial and final value */
|
||||
/* of the bucket. At the moment bucket_lookup is able to */
|
||||
/* manage values of 16, 32 bits. */
|
||||
uint32 bucket_lookup(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref)
|
||||
{
|
||||
uint32 value;
|
||||
uint32 i,j;
|
||||
int found=-1;
|
||||
uint32 blocks;
|
||||
uint32 block_size;
|
||||
uint8 *temp;
|
||||
if ((data->key_len!=1)&& /*16 bit value*/
|
||||
(data->key_len!=2)) /*32 bit value*/
|
||||
return TME_ERROR;
|
||||
|
||||
/*32 bit values*/
|
||||
blocks=data->filled_blocks-1;
|
||||
block_size=data->block_size;
|
||||
i=blocks/2; /*relative shift*/
|
||||
j=i;
|
||||
temp=data->shared_memory_base_address+block_size;
|
||||
|
||||
if (data->key_len==2)
|
||||
{
|
||||
value=SW_ULONG_AT(key,0);
|
||||
|
||||
if((value<SW_ULONG_AT(temp,0))||(value>SW_ULONG_AT(temp+block_size*(blocks-1),4)))
|
||||
{
|
||||
uint32 *key32=(uint32*) key;
|
||||
key32[0]=key32[1]=0;
|
||||
|
||||
GET_TIME((struct timeval *)(data->shared_memory_base_address+8),time_ref);
|
||||
|
||||
data->last_found=NULL;
|
||||
return TME_FALSE;
|
||||
}
|
||||
|
||||
while(found==-1) /* search routine */
|
||||
{
|
||||
i=(i==1)? 1:i>>1;
|
||||
if (SW_ULONG_AT(temp+block_size*j,0)>value)
|
||||
if (SW_ULONG_AT(temp+block_size*(j-1),4)<value)
|
||||
found=-2;
|
||||
else
|
||||
j-=i;
|
||||
else
|
||||
if (SW_ULONG_AT(temp+block_size*j,4)<value)
|
||||
if (SW_ULONG_AT(temp+block_size*j,0)>value)
|
||||
found=-2;
|
||||
else
|
||||
j+=i;
|
||||
else found=j;
|
||||
}
|
||||
if (found<0)
|
||||
{
|
||||
uint32 *key32=(uint32*) key;
|
||||
key32[0]=key32[1]=0;
|
||||
|
||||
GET_TIME((struct timeval *)(data->shared_memory_base_address+8),time_ref);
|
||||
|
||||
data->last_found=NULL;
|
||||
return TME_FALSE;
|
||||
}
|
||||
|
||||
data->last_found=data->lut_base_address+found*sizeof(RECORD);
|
||||
|
||||
COPY_MEMORY(key,temp+block_size*found,8);
|
||||
|
||||
GET_TIME((struct timeval *)(temp+block_size*found+8),time_ref);
|
||||
|
||||
return TME_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
value=SW_USHORT_AT(key,0);
|
||||
|
||||
if((value<SW_USHORT_AT(temp,0))||(value>SW_USHORT_AT(temp+block_size*(blocks-1),2)))
|
||||
{
|
||||
uint16 *key16=(uint16*) key;
|
||||
key16[0]=key16[1]=0;
|
||||
|
||||
GET_TIME((struct timeval *)(data->shared_memory_base_address+4),time_ref);
|
||||
|
||||
data->last_found=NULL;
|
||||
return TME_FALSE;
|
||||
}
|
||||
|
||||
while(found==-1) /* search routine */
|
||||
{
|
||||
i=(i==1)? 1:i>>1;
|
||||
if (SW_USHORT_AT(temp+block_size*j,0)>value)
|
||||
if (SW_USHORT_AT(temp+block_size*(j-1),2)<value)
|
||||
found=-2;
|
||||
else
|
||||
j-=i;
|
||||
else
|
||||
if (SW_USHORT_AT(temp+block_size*j,2)<value)
|
||||
if (SW_USHORT_AT(temp+block_size*j,0)>value)
|
||||
found=-2;
|
||||
else
|
||||
j+=i;
|
||||
else found=j;
|
||||
}
|
||||
|
||||
if (found<0)
|
||||
{
|
||||
uint16 *key16=(uint16*) key;
|
||||
key16[0]=key16[1]=0;
|
||||
|
||||
GET_TIME((struct timeval *)(data->shared_memory_base_address+4),time_ref);
|
||||
|
||||
data->last_found=NULL;
|
||||
return TME_FALSE;
|
||||
}
|
||||
|
||||
data->last_found=data->lut_base_address+found*sizeof(RECORD);
|
||||
|
||||
GET_TIME((struct timeval *)(temp+block_size*found+4),time_ref);
|
||||
|
||||
COPY_MEMORY(key,temp+block_size*found,4);
|
||||
|
||||
return TME_TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 bucket_lookup_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref)
|
||||
{
|
||||
RECORD *records=(RECORD*)data->lut_base_address;
|
||||
|
||||
if ((data->key_len!=1)&& /*16 bit value*/
|
||||
(data->key_len!=2)) /*32 bit value*/
|
||||
return TME_ERROR;
|
||||
|
||||
if(data->key_len==2)
|
||||
{
|
||||
uint32 start,stop;
|
||||
uint8 *tmp;
|
||||
|
||||
start=SW_ULONG_AT(key,0);
|
||||
stop=SW_ULONG_AT(key,4);
|
||||
|
||||
if (start>stop)
|
||||
return TME_ERROR;
|
||||
if (data->filled_entries>0)
|
||||
{
|
||||
tmp=mem_ex->buffer+SW_ULONG_AT(&records[data->filled_entries-1].block,0);
|
||||
/*check if it is coherent with the previous block*/
|
||||
if (SW_ULONG_AT(tmp,4)>=start)
|
||||
return TME_ERROR;
|
||||
}
|
||||
|
||||
if (data->filled_blocks==data->shared_memory_blocks)
|
||||
return TME_ERROR;
|
||||
|
||||
if (data->filled_entries==data->lut_entries)
|
||||
return TME_ERROR;
|
||||
|
||||
tmp=data->shared_memory_base_address+data->block_size*data->filled_blocks;
|
||||
|
||||
COPY_MEMORY(tmp,key,8);
|
||||
|
||||
SW_ULONG_ASSIGN(&records[data->filled_entries].block,tmp-mem_ex->buffer);
|
||||
SW_ULONG_ASSIGN(&records[data->filled_entries].exec_fcn,data->default_exec);
|
||||
|
||||
GET_TIME((struct timeval *)(tmp+8),time_ref);
|
||||
|
||||
data->filled_blocks++;
|
||||
data->filled_entries++;
|
||||
|
||||
return TME_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16 start,stop;
|
||||
uint8 *tmp;
|
||||
|
||||
start=SW_USHORT_AT(key,0);
|
||||
stop=SW_USHORT_AT(key,2);
|
||||
|
||||
if (start>stop)
|
||||
return TME_ERROR;
|
||||
if (data->filled_entries>0)
|
||||
{
|
||||
tmp=mem_ex->buffer+SW_ULONG_AT(&records[data->filled_entries-1].block,0);
|
||||
/*check if it is coherent with the previous block*/
|
||||
if (SW_USHORT_AT(tmp,2)>=start)
|
||||
return TME_ERROR;
|
||||
}
|
||||
|
||||
if (data->filled_blocks==data->shared_memory_blocks)
|
||||
return TME_ERROR;
|
||||
|
||||
if (data->filled_entries==data->lut_entries)
|
||||
return TME_ERROR;
|
||||
|
||||
tmp=mem_ex->buffer+SW_ULONG_AT(&records[data->filled_entries].block,0);
|
||||
|
||||
COPY_MEMORY(tmp,key,4);
|
||||
|
||||
SW_ULONG_ASSIGN(&records[data->filled_entries].block,tmp-mem_ex->buffer);
|
||||
SW_ULONG_ASSIGN(&records[data->filled_entries].exec_fcn,data->default_exec);
|
||||
|
||||
GET_TIME((struct timeval *)(tmp+4),time_ref);
|
||||
|
||||
data->filled_blocks++;
|
||||
data->filled_entries++;
|
||||
|
||||
return TME_TRUE;
|
||||
}
|
||||
}
|
||||
54
src/See/bucket_lookup.h
Normal file
54
src/See/bucket_lookup.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __bucket_lookup
|
||||
#define __bucket_lookup
|
||||
#ifdef WIN32
|
||||
#include "tme.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <net/tme/tme.h>
|
||||
#else
|
||||
#include <tme/tme.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#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
|
||||
uint32 bucket_lookup(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref);
|
||||
|
||||
#endif
|
||||
64
src/See/count_packets.c
Normal file
64
src/See/count_packets.c
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "tme.h"
|
||||
#include "count_packets.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <net/tme/tme.h>
|
||||
#include <net/tme/count_packets.h>
|
||||
#else
|
||||
#include <tme/tme.h>
|
||||
#include <tme/count_packets.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
uint32 count_packets(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data)
|
||||
{
|
||||
|
||||
c_p_data *counters=(c_p_data*)(block+data->key_len*4);
|
||||
|
||||
counters->bytes+=pkt_size;
|
||||
counters->packets++;
|
||||
|
||||
return TME_SUCCESS;
|
||||
|
||||
}
|
||||
62
src/See/count_packets.h
Normal file
62
src/See/count_packets.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __count_packets
|
||||
#define __count_packets
|
||||
|
||||
#ifdef WIN32
|
||||
#include "tme.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <net/tme/tme.h>
|
||||
#else
|
||||
#include <tme/tme.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct __c_p_data
|
||||
{
|
||||
struct timeval timestamp;
|
||||
uint64 packets;
|
||||
uint64 bytes;
|
||||
}
|
||||
c_p_data;
|
||||
|
||||
#define COUNT_PACKETS 0x00000000
|
||||
uint32 count_packets(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data);
|
||||
|
||||
#endif
|
||||
|
||||
225
src/See/dagc.h
Normal file
225
src/See/dagc.h
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define DAGC_ERRBUF_SIZE 512
|
||||
#define FILEBUFSIZE 65536
|
||||
#define MAXDAGCARDS 32
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
typedef long long long_long;
|
||||
typedef long long ull_t;
|
||||
#define TRUE 1
|
||||
#define devicestring "/dev/dag%d"
|
||||
#define dagc_sleepms(_MS) usleep(_MS * 1000)
|
||||
#else /* _WIN32 */
|
||||
|
||||
typedef LONGLONG long_long;
|
||||
typedef ULONGLONG ull_t;
|
||||
#define dagc_sleepms(_MS) Sleep(_MS)
|
||||
#define devicestring "\\\\.\\dag%d"
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#define MIN_DAG_SNAPLEN 12
|
||||
#define MAX_DAG_SNAPLEN 2040
|
||||
|
||||
#define erffilestring "erffile://"
|
||||
|
||||
|
||||
#define ATM_SNAPLEN 48
|
||||
/* Size of ATM payload */
|
||||
#define ATM_WLEN(h) ATM_SNAPLEN
|
||||
#define ATM_SLEN(h) ATM_SNAPLEN
|
||||
|
||||
/* Size Ethernet payload */
|
||||
#define ETHERNET_WLEN(h, b) ((u_int)ntohs((h)->wlen) - ((b) >> 3))
|
||||
#define ETHERNET_SLEN(h, b) min(ETHERNET_WLEN(h, b), \
|
||||
(u_int)ntohs((h)->rlen) - dag_record_size - 2)
|
||||
|
||||
/* Size of HDLC payload */
|
||||
#define HDLC_WLEN(h, b) ((u_int)ntohs((h)->wlen) - ((b) >> 3))
|
||||
#define HDLC_SLEN(h, b) min(HDLC_WLEN(h, b), \
|
||||
(u_int)ntohs((h)->rlen) - dag_record_size)
|
||||
|
||||
/* Flags for dagc_open */
|
||||
#define DAGC_OPEN_SHARED 1
|
||||
#define DAGC_OPEN_EXCLUSIVE 2
|
||||
|
||||
#define TYPE_LEGACY 0
|
||||
#define TYPE_HDLC_POS 1
|
||||
#define TYPE_ETH 2
|
||||
#define TYPE_ATM 3
|
||||
#define TYPE_AAL5 4
|
||||
|
||||
/*
|
||||
* Card statistics.
|
||||
*/
|
||||
typedef struct dagc_stats_t
|
||||
{
|
||||
ull_t received; /* (NOT IMPLEMENTED) total number of frames received by the DAG */
|
||||
ull_t dropped; /* number of frames dropped for buffer full */
|
||||
ull_t captured; /* (NOT IMPLEMENTED) number of frames that actually reach the
|
||||
application, i.e that are not filtered or dropped */
|
||||
} dagc_stats_t;
|
||||
|
||||
/*
|
||||
* Descriptor of an open session.
|
||||
* Note: the dagc_t descriptor is completely opaque to the application. It can be compared
|
||||
* to a file descriptor.
|
||||
*/
|
||||
typedef struct dagc dagc_t;
|
||||
|
||||
/*
|
||||
* Card description.
|
||||
*/
|
||||
typedef struct dagc_if_t
|
||||
{
|
||||
struct dagc_if_t *next;
|
||||
char *name; /* pointer to a string to pass to dagc_open*/
|
||||
char *description; /* human-understandable description (e.g. Endace 3.5e Fast
|
||||
Ethernet Card) */
|
||||
} dagc_if_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* returns a string with last dagc lib error
|
||||
*/
|
||||
#define dagc_getlasterror(dagcfd) dagcfd->errbuf
|
||||
|
||||
/*
|
||||
* returns a linked list with the cards available on the systems. For every card, it scans the
|
||||
* card type and converts it to a human-understandable string, in order to provide a description
|
||||
* useful for example when a system has more than one card
|
||||
*/
|
||||
int dagc_finddevs (dagc_if_t **alldevsp, char *ebuf);
|
||||
|
||||
|
||||
/*
|
||||
* frees the card list.
|
||||
*/
|
||||
void dagc_freedevs (dagc_if_t *alldevsp);
|
||||
|
||||
|
||||
/*
|
||||
* Opens a card (or a file) for capture. Snaplen is the portion of packet delivered to the
|
||||
* application, flags can contain specific settings (for example promisc mode??), minbufsize
|
||||
* is the smallest buffer that the API can provide to the application (to limit CPU waste
|
||||
* with several small buffers under moderated network throughputs)
|
||||
*/
|
||||
dagc_t* dagc_open(const char *source, unsigned flags, char *ebuf);
|
||||
|
||||
/*
|
||||
* Sets the snaplen of a card
|
||||
* Returns -1 on failure. On success, the actual snaplen is returned (snap len has to be a multiple of 4
|
||||
* with DAG cards).
|
||||
*/
|
||||
int dagc_setsnaplen(dagc_t *dagcfd, unsigned snaplen);
|
||||
|
||||
/*
|
||||
* closes a capture instance
|
||||
*/
|
||||
void dagc_close(dagc_t *dagcfd);
|
||||
|
||||
|
||||
/*
|
||||
* returns the linktype of a card
|
||||
*/
|
||||
int dagc_getlinktype(dagc_t *dagcfd);
|
||||
|
||||
|
||||
/*
|
||||
* returns the link speed of the adapter, in MB/s.
|
||||
* If the link speed of the card is unknown, -1 is returned.
|
||||
* XXX NOTE: Currently, there is no consistent way to get linkspeed querying the card.
|
||||
* As a consequence, we determine this value statically from the card model. For cards that can run at
|
||||
* different speeds, we report only the *maximum* speed.
|
||||
*/
|
||||
int dagc_getlinkspeed(dagc_t *dagcfd);
|
||||
|
||||
|
||||
/*
|
||||
* Returns the length of the CRC checksum that the card associates with any packet in the hole. This
|
||||
* information will be used to understand the actual length of the packet on the wire.
|
||||
* Note: this information is not provided consistently by DAG cards, so we gather it from an environment
|
||||
* variable in Unix and from a registry key in Windows.
|
||||
*/
|
||||
unsigned dagc_getfcslen(dagc_t *dagcfd);
|
||||
|
||||
/*
|
||||
* provides a buffer with the new packets (from the board or from the file) and its size.
|
||||
* On success, the return value is 0. If an error has occurred, the return value is -1.
|
||||
* If EOF has reached, the return value is -2. Note that this function always returns
|
||||
* immediately, eventually with an empty buffer, so it is possible to have a success (0)
|
||||
* return value and bufsize = 0.
|
||||
*/
|
||||
int dagc_receive(dagc_t *dagcfd, u_char **buffer, u_int *bufsize);
|
||||
|
||||
|
||||
/*
|
||||
* returns nonzero if any data is available from dagcfd, -1 if an error occurred. Waits until almost the time
|
||||
* specified by timeout has past or any data is available. If timeout=0, returns immediately.
|
||||
* If timeout=NULL, blocks until a packet arrives.
|
||||
*/
|
||||
int dagc_wait(dagc_t *dagcfd, struct timeval *timeout);
|
||||
|
||||
|
||||
/*
|
||||
* returns statistics about current capture session
|
||||
*/
|
||||
int dagc_stats(dagc_t *dagcfd, dagc_stats_t *ps);
|
||||
|
||||
|
||||
/*
|
||||
* Opens a dump file to store the data of this capture.
|
||||
* Returns 0 on success.
|
||||
* NOTE: currently, dagc_dumpfile_open, dagc_dumpfile_close and dagc_dump are simply wrappers
|
||||
* for open, close and write. However, if the programmer uses these functions, he is more protected
|
||||
* against file format changes (for example if the file format will have an header in the future).
|
||||
* Moreover, assuming that the user knows the file format is a bad practice: providing
|
||||
* simple simple save functionality is more intutive and user-friendly.
|
||||
*/
|
||||
int dagc_dumpfile_open(dagc_t *dagcfd, char* name);
|
||||
|
||||
|
||||
/*
|
||||
* Closes a dump file
|
||||
*/
|
||||
int dagc_dumpfile_close(dagc_t *dagcfd);
|
||||
|
||||
|
||||
/*
|
||||
* Writes a buffer of packets to a dump file
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int dagc_dump(dagc_t *dagcfd, u_char *buffer, u_int bufsize);
|
||||
570
src/See/dump.c
Normal file
570
src/See/dump.c
Normal file
@ -0,0 +1,570 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <ntddk.h>
|
||||
#include <ntiologc.h>
|
||||
#include <ndis.h>
|
||||
#include "debug.h"
|
||||
#include "packet.h"
|
||||
|
||||
#include "win_bpf.h"
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
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;
|
||||
|
||||
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 ( !NT_SUCCESS( ntStatus ) )
|
||||
{
|
||||
IF_LOUD(DbgPrint("NPF: Error opening file %x\n", ntStatus);)
|
||||
|
||||
ExFreePool(FullFileName.Buffer);
|
||||
Open->DumpFileHandle=NULL;
|
||||
ntStatus = STATUS_NO_SUCH_FILE;
|
||||
return ntStatus;
|
||||
}
|
||||
|
||||
ExFreePool(FullFileName.Buffer);
|
||||
|
||||
ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle,
|
||||
FILE_WRITE_ACCESS,
|
||||
*IoFileObjectType,
|
||||
KernelMode,
|
||||
&Open->DumpFileObject,
|
||||
0);
|
||||
|
||||
if ( !NT_SUCCESS( ntStatus ) )
|
||||
{
|
||||
IF_LOUD(DbgPrint("NPF: Error creating file, status=%x\n", ntStatus);)
|
||||
|
||||
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);)
|
||||
|
||||
return ntStatus;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
NTSTATUS
|
||||
NPF_StartDump(POPEN_INSTANCE Open)
|
||||
{
|
||||
NTSTATUS ntStatus;
|
||||
struct packet_file_header hdr;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
|
||||
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;
|
||||
|
||||
// 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 );
|
||||
|
||||
|
||||
if ( !NT_SUCCESS( ntStatus ) )
|
||||
{
|
||||
IF_LOUD(DbgPrint("NPF: Error dumping file %x\n", ntStatus);)
|
||||
|
||||
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);
|
||||
|
||||
if ( !NT_SUCCESS( ntStatus ) )
|
||||
{
|
||||
IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);)
|
||||
|
||||
ZwClose( Open->DumpFileHandle );
|
||||
Open->DumpFileHandle=NULL;
|
||||
|
||||
return ntStatus;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return ntStatus;
|
||||
}
|
||||
|
||||
|
||||
return ntStatus;
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Dump Thread
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID NPF_DumpThread(POPEN_INSTANCE Open)
|
||||
{
|
||||
// ULONG FrozenNic;
|
||||
|
||||
IF_LOUD(DbgPrint("NPF: In the work routine. Parameter = 0x%0x\n",Open);)
|
||||
|
||||
while(TRUE){
|
||||
|
||||
// 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->Size==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);)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open)
|
||||
{
|
||||
#if 0
|
||||
|
||||
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);
|
||||
|
||||
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){
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
#endif
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open){
|
||||
#if 0
|
||||
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;
|
||||
|
||||
DbgPrint("2\n");
|
||||
ZwClose( Open->DumpFileHandle );
|
||||
|
||||
ObDereferenceObject(Open->DumpFileObject);
|
||||
/*
|
||||
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);
|
||||
|
||||
// Flush the buffer to file
|
||||
NPF_SaveCurrentBuffer(Open);
|
||||
|
||||
// Close The file
|
||||
ObDereferenceObject(Open->DumpFileObject);
|
||||
ZwClose( Open->DumpFileHandle );
|
||||
|
||||
Open->DumpFileHandle = NULL;
|
||||
|
||||
ObDereferenceObject(Open->DumpFileObject);
|
||||
#endif
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
static NTSTATUS PacketDumpCompletion(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp,
|
||||
PVOID Context)
|
||||
{
|
||||
|
||||
// Copy the status information back into the "user" IOSB
|
||||
*Irp->UserIosb = Irp->IoStatus;
|
||||
|
||||
// Wake up the mainline code
|
||||
KeSetEvent(Irp->UserEvent, 0, FALSE);
|
||||
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
|
||||
PLARGE_INTEGER Offset,
|
||||
ULONG Length,
|
||||
PMDL Mdl,
|
||||
PIO_STATUS_BLOCK IoStatusBlock)
|
||||
{
|
||||
PIRP irp;
|
||||
KEVENT event;
|
||||
PIO_STACK_LOCATION ioStackLocation;
|
||||
PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject);
|
||||
|
||||
// Set up the event we'll use
|
||||
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
|
||||
|
||||
// Allocate and build the IRP we'll be sending to the FSD
|
||||
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
|
||||
|
||||
if (!irp) {
|
||||
// Allocation failed, presumably due to memory allocation failure
|
||||
IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoStatusBlock->Information = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
irp->MdlAddress = Mdl;
|
||||
irp->UserEvent = &event;
|
||||
irp->UserIosb = IoStatusBlock;
|
||||
irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||
irp->Tail.Overlay.OriginalFileObject= FileObject;
|
||||
irp->RequestorMode = KernelMode;
|
||||
|
||||
// Indicate that this is a 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;
|
||||
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);
|
||||
|
||||
// Free the IRP now that we are done with it
|
||||
IoFreeIrp(irp);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
95
src/See/functions.c
Normal file
95
src/See/functions.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "tme.h"
|
||||
#include "functions.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <net/tme/tme.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/tme/functions.h>
|
||||
#else
|
||||
#include <tme/tme.h>
|
||||
#include <bpf.h>
|
||||
#include <tme/functions.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
lut_fcn lut_fcn_mapper(uint32 index)
|
||||
{
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case NORMAL_LUT_W_INSERT:
|
||||
return (lut_fcn) normal_lut_w_insert;
|
||||
|
||||
case NORMAL_LUT_WO_INSERT:
|
||||
return (lut_fcn) normal_lut_wo_insert;
|
||||
|
||||
case BUCKET_LOOKUP:
|
||||
return (lut_fcn) bucket_lookup;
|
||||
|
||||
case BUCKET_LOOKUP_INSERT:
|
||||
return (lut_fcn) bucket_lookup_insert;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
exec_fcn exec_fcn_mapper(uint32 index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case COUNT_PACKETS:
|
||||
return (exec_fcn) count_packets;
|
||||
|
||||
case TCP_SESSION:
|
||||
return (exec_fcn) tcp_session;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
78
src/See/functions.h
Normal file
78
src/See/functions.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FUNCTIONS
|
||||
#define __FUNCTIONS
|
||||
|
||||
#ifdef WIN32
|
||||
#include "tme.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <net/tme/tme.h>
|
||||
#else
|
||||
#include <tme/tme.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*function mappers */
|
||||
|
||||
lut_fcn lut_fcn_mapper(uint32 index);
|
||||
exec_fcn exec_fcn_mapper(uint32 index);
|
||||
|
||||
/* lookup functions */
|
||||
|
||||
#ifdef WIN32
|
||||
#include "bucket_lookup.h"
|
||||
#include "normal_lookup.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <net/tme/bucket_lookup.h>
|
||||
#include <net/tme/normal_lookup.h>
|
||||
#endif
|
||||
|
||||
/* execution functions */
|
||||
|
||||
#ifdef WIN32
|
||||
#include "count_packets.h"
|
||||
#include "tcp_session.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <net/tme/count_packets.h>
|
||||
#include <ne/tme/tcp_session.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
687
src/See/jitter.c
Normal file
687
src/See/jitter.c
Normal file
@ -0,0 +1,687 @@
|
||||
/*
|
||||
* Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||
* Copyright (c) 2005 CACE Technologies, Davis (California)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#include "stdarg.h"
|
||||
#include "ntddk.h"
|
||||
#include "ntiologc.h"
|
||||
#include "ndis.h"
|
||||
|
||||
#include "packet.h"
|
||||
#include "win_bpf.h"
|
||||
#include "jitter.h"
|
||||
|
||||
//
|
||||
// emit routine to update the jump table
|
||||
//
|
||||
void emit_lenght(binary_stream *stream, ULONG value, UINT len)
|
||||
{
|
||||
(stream->refs)[stream->bpf_pc]+=len;
|
||||
stream->cur_ip+=len;
|
||||
}
|
||||
|
||||
//
|
||||
// emit routine to output the actual binary code
|
||||
//
|
||||
void emit_code(binary_stream *stream, ULONG value, UINT len)
|
||||
{
|
||||
|
||||
switch (len){
|
||||
|
||||
case 1:
|
||||
stream->ibuf[stream->cur_ip]=(UCHAR)value;
|
||||
stream->cur_ip++;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*((USHORT*)(stream->ibuf+stream->cur_ip))=(USHORT)value;
|
||||
stream->cur_ip+=2;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*((ULONG*)(stream->ibuf+stream->cur_ip))=value;
|
||||
stream->cur_ip+=4;
|
||||
break;
|
||||
|
||||
default:;
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Function that does the real stuff
|
||||
//
|
||||
BPF_filter_function BPFtoX86(struct bpf_insn *prog, UINT nins, INT *mem)
|
||||
{
|
||||
struct bpf_insn *ins;
|
||||
UINT i, pass;
|
||||
binary_stream stream;
|
||||
|
||||
//NOTE: do not modify the name of this variable, as it's used by the macros to emit code.
|
||||
emit_func emitm;
|
||||
|
||||
|
||||
// Allocate the reference table for the jumps
|
||||
#ifdef NTKERNEL
|
||||
stream.refs=(UINT *)ExAllocatePoolWithTag(NonPagedPool, (nins + 1)*sizeof(UINT), '0JWA');
|
||||
#else
|
||||
stream.refs=(UINT *)malloc((nins + 1)*sizeof(UINT));
|
||||
#endif
|
||||
if(stream.refs==NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Reset the reference table
|
||||
for(i=0; i< nins + 1; i++)
|
||||
stream.refs[i]=0;
|
||||
|
||||
stream.cur_ip=0;
|
||||
stream.bpf_pc=0;
|
||||
|
||||
// the first pass will emit the lengths of the instructions
|
||||
// to create the reference table
|
||||
emitm=emit_lenght;
|
||||
|
||||
for(pass=0;;){
|
||||
|
||||
ins = prog;
|
||||
|
||||
/* create the procedure header */
|
||||
PUSH(EBP)
|
||||
MOVrd(EBP,ESP)
|
||||
PUSH(EBX)
|
||||
PUSH(ECX)
|
||||
PUSH(EDX)
|
||||
PUSH(ESI)
|
||||
PUSH(EDI)
|
||||
MOVodd(EBX, EBP, 8)
|
||||
|
||||
for(i=0;i<nins;i++){
|
||||
|
||||
stream.bpf_pc++;
|
||||
|
||||
switch (ins->code) {
|
||||
|
||||
default:
|
||||
|
||||
return NULL;
|
||||
|
||||
case BPF_RET|BPF_K:
|
||||
|
||||
MOVid(EAX,ins->k)
|
||||
POP(EDI)
|
||||
POP(ESI)
|
||||
POP(EDX)
|
||||
POP(ECX)
|
||||
POP(EBX)
|
||||
POP(EBP)
|
||||
RET()
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case BPF_RET|BPF_A:
|
||||
|
||||
POP(EDI)
|
||||
POP(ESI)
|
||||
POP(EDX)
|
||||
POP(ECX)
|
||||
POP(EBX)
|
||||
POP(EBP)
|
||||
RET()
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case BPF_LD|BPF_W|BPF_ABS:
|
||||
|
||||
MOVid(ECX,ins->k)
|
||||
MOVrd(ESI,ECX)
|
||||
ADDib(ECX,sizeof(INT))
|
||||
CMPodd(ECX, EBP, 0x10)
|
||||
JLEb(12)
|
||||
POP(EDI)
|
||||
POP(ESI)
|
||||
POP(EDX)
|
||||
POP(ECX)
|
||||
POP(EBX)
|
||||
POP(EBP)
|
||||
MOVid(EAX,0) //this can be optimized with xor eax,eax
|
||||
RET()
|
||||
MOVobd(EAX, EBX, ESI)
|
||||
BSWAP(EAX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LD|BPF_H|BPF_ABS:
|
||||
|
||||
MOVid(ECX,ins->k)
|
||||
MOVrd(ESI,ECX)
|
||||
ADDib(ECX,sizeof(SHORT))
|
||||
CMPodd(ECX, EBP, 0x10)
|
||||
JLEb(12)
|
||||
POP(EDI)
|
||||
POP(ESI)
|
||||
POP(EDX)
|
||||
POP(ECX)
|
||||
POP(EBX)
|
||||
POP(EBP)
|
||||
MOVid(EAX,0)
|
||||
RET()
|
||||
MOVid(EAX,0)
|
||||
MOVobw(AX, EBX, ESI)
|
||||
SWAP_AX()
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LD|BPF_B|BPF_ABS:
|
||||
|
||||
MOVid(ECX,ins->k)
|
||||
CMPodd(ECX, EBP, 0x10)
|
||||
JLEb(12)
|
||||
POP(EDI)
|
||||
POP(ESI)
|
||||
POP(EDX)
|
||||
POP(ECX)
|
||||
POP(EBX)
|
||||
POP(EBP)
|
||||
MOVid(EAX,0)
|
||||
RET()
|
||||
MOVid(EAX,0)
|
||||
MOVobb(AL,EBX,ECX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LD|BPF_W|BPF_LEN:
|
||||
|
||||
MOVodd(EAX, EBP, 0xc)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LDX|BPF_W|BPF_LEN:
|
||||
|
||||
MOVodd(EDX, EBP, 0xc)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LD|BPF_W|BPF_IND:
|
||||
|
||||
MOVid(ECX,ins->k)
|
||||
ADDrd(ECX,EDX)
|
||||
MOVrd(ESI,ECX)
|
||||
ADDib(ECX,sizeof(INT))
|
||||
CMPodd(ECX, EBP, 0x10)
|
||||
JLEb(12)
|
||||
POP(EDI)
|
||||
POP(ESI)
|
||||
POP(EDX)
|
||||
POP(ECX)
|
||||
POP(EBX)
|
||||
POP(EBP)
|
||||
MOVid(EAX,0)
|
||||
RET()
|
||||
MOVobd(EAX, EBX, ESI)
|
||||
BSWAP(EAX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LD|BPF_H|BPF_IND:
|
||||
|
||||
MOVid(ECX,ins->k)
|
||||
ADDrd(ECX,EDX)
|
||||
MOVrd(ESI,ECX)
|
||||
ADDib(ECX,sizeof(SHORT))
|
||||
CMPodd(ECX, EBP, 0x10)
|
||||
JLEb(12)
|
||||
POP(EDI)
|
||||
POP(ESI)
|
||||
POP(EDX)
|
||||
POP(ECX)
|
||||
POP(EBX)
|
||||
POP(EBP)
|
||||
MOVid(EAX,0)
|
||||
RET()
|
||||
MOVid(EAX,0)
|
||||
MOVobw(AX, EBX, ESI)
|
||||
SWAP_AX()
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LD|BPF_B|BPF_IND:
|
||||
|
||||
MOVid(ECX,ins->k)
|
||||
ADDrd(ECX,EDX)
|
||||
CMPodd(ECX, EBP, 0x10)
|
||||
JLEb(12)
|
||||
POP(EDI)
|
||||
POP(ESI)
|
||||
POP(EDX)
|
||||
POP(ECX)
|
||||
POP(EBX)
|
||||
POP(EBP)
|
||||
MOVid(EAX,0)
|
||||
RET()
|
||||
MOVid(EAX,0)
|
||||
MOVobb(AL,EBX,ECX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LDX|BPF_MSH|BPF_B:
|
||||
|
||||
MOVid(ECX,ins->k)
|
||||
CMPodd(ECX, EBP, 0x10)
|
||||
JLEb(12)
|
||||
POP(EDI)
|
||||
POP(ESI)
|
||||
POP(EDX)
|
||||
POP(ECX)
|
||||
POP(EBX)
|
||||
POP(EBP)
|
||||
MOVid(EAX,0)
|
||||
RET()
|
||||
MOVid(EDX,0)
|
||||
MOVobb(DL,EBX,ECX)
|
||||
ANDib(DL, 0xf)
|
||||
SHLib(EDX, 2)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LD|BPF_IMM:
|
||||
|
||||
MOVid(EAX,ins->k)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LDX|BPF_IMM:
|
||||
|
||||
MOVid(EDX,ins->k)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LD|BPF_MEM:
|
||||
|
||||
MOVid(ECX,(INT)mem)
|
||||
MOVid(ESI,ins->k*4)
|
||||
MOVobd(EAX, ECX, ESI)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_LDX|BPF_MEM:
|
||||
|
||||
MOVid(ECX,(INT)mem)
|
||||
MOVid(ESI,ins->k*4)
|
||||
MOVobd(EDX, ECX, ESI)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ST:
|
||||
|
||||
// XXX: this command and the following could be optimized if the previous
|
||||
// instruction was already of this type
|
||||
MOVid(ECX,(INT)mem)
|
||||
MOVid(ESI,ins->k*4)
|
||||
MOVomd(ECX, ESI, EAX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_STX:
|
||||
|
||||
MOVid(ECX,(INT)mem)
|
||||
MOVid(ESI,ins->k*4)
|
||||
MOVomd(ECX, ESI, EDX)
|
||||
break;
|
||||
|
||||
case BPF_JMP|BPF_JA:
|
||||
|
||||
JMP(stream.refs[stream.bpf_pc+ins->k]-stream.refs[stream.bpf_pc])
|
||||
|
||||
break;
|
||||
|
||||
case BPF_JMP|BPF_JGT|BPF_K:
|
||||
|
||||
CMPid(EAX, ins->k)
|
||||
JG(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5) // 5 is the size of the following JMP
|
||||
JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
|
||||
break;
|
||||
|
||||
case BPF_JMP|BPF_JGE|BPF_K:
|
||||
|
||||
CMPid(EAX, ins->k)
|
||||
JGE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
|
||||
JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
|
||||
|
||||
break;
|
||||
|
||||
case BPF_JMP|BPF_JEQ|BPF_K:
|
||||
|
||||
CMPid(EAX, ins->k)
|
||||
JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
|
||||
JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
|
||||
|
||||
break;
|
||||
|
||||
case BPF_JMP|BPF_JSET|BPF_K:
|
||||
|
||||
MOVrd(ECX,EAX)
|
||||
ANDid(ECX,ins->k)
|
||||
JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5)
|
||||
JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc])
|
||||
|
||||
break;
|
||||
|
||||
case BPF_JMP|BPF_JGT|BPF_X:
|
||||
|
||||
CMPrd(EAX, EDX)
|
||||
JA(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
|
||||
JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
|
||||
break;
|
||||
|
||||
case BPF_JMP|BPF_JGE|BPF_X:
|
||||
|
||||
CMPrd(EAX, EDX)
|
||||
JAE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
|
||||
JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
|
||||
|
||||
break;
|
||||
|
||||
case BPF_JMP|BPF_JEQ|BPF_X:
|
||||
|
||||
CMPrd(EAX, EDX)
|
||||
JE(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc]+5)
|
||||
JMP(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc])
|
||||
|
||||
break;
|
||||
|
||||
case BPF_JMP|BPF_JSET|BPF_X:
|
||||
|
||||
MOVrd(ECX,EAX)
|
||||
ANDrd(ECX,EDX)
|
||||
JE(stream.refs[stream.bpf_pc+ins->jf]-stream.refs[stream.bpf_pc]+5)
|
||||
JMP(stream.refs[stream.bpf_pc+ins->jt]-stream.refs[stream.bpf_pc])
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_ADD|BPF_X:
|
||||
|
||||
ADDrd(EAX,EDX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_SUB|BPF_X:
|
||||
|
||||
SUBrd(EAX,EDX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_MUL|BPF_X:
|
||||
|
||||
MOVrd(ECX,EDX)
|
||||
MULrd(EDX)
|
||||
MOVrd(EDX,ECX)
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_DIV|BPF_X:
|
||||
|
||||
CMPid(EDX, 0)
|
||||
JNEb(12)
|
||||
POP(EDI)
|
||||
POP(ESI)
|
||||
POP(EDX)
|
||||
POP(ECX)
|
||||
POP(EBX)
|
||||
POP(EBP)
|
||||
MOVid(EAX,0)
|
||||
RET()
|
||||
MOVrd(ECX,EDX)
|
||||
MOVid(EDX,0)
|
||||
DIVrd(ECX)
|
||||
MOVrd(EDX,ECX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_AND|BPF_X:
|
||||
|
||||
ANDrd(EAX,EDX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_OR|BPF_X:
|
||||
|
||||
ORrd(EAX,EDX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_LSH|BPF_X:
|
||||
|
||||
MOVrd(ECX,EDX)
|
||||
SHL_CLrb(EAX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_RSH|BPF_X:
|
||||
|
||||
MOVrd(ECX,EDX)
|
||||
SHR_CLrb(EAX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_ADD|BPF_K:
|
||||
|
||||
ADD_EAXi(ins->k)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_SUB|BPF_K:
|
||||
|
||||
SUB_EAXi(ins->k)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_MUL|BPF_K:
|
||||
|
||||
MOVrd(ECX,EDX)
|
||||
MOVid(EDX,ins->k)
|
||||
MULrd(EDX)
|
||||
MOVrd(EDX,ECX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_DIV|BPF_K:
|
||||
|
||||
MOVrd(ECX,EDX)
|
||||
MOVid(EDX,0)
|
||||
MOVid(ESI,ins->k)
|
||||
DIVrd(ESI)
|
||||
MOVrd(EDX,ECX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_AND|BPF_K:
|
||||
|
||||
ANDid(EAX, ins->k)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_OR|BPF_K:
|
||||
|
||||
ORid(EAX, ins->k)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_LSH|BPF_K:
|
||||
|
||||
SHLib(EAX, (ins->k) & 255)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_RSH|BPF_K:
|
||||
|
||||
SHRib(EAX, (ins->k) & 255)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_ALU|BPF_NEG:
|
||||
|
||||
NEGd(EAX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_MISC|BPF_TAX:
|
||||
|
||||
MOVrd(EDX,EAX)
|
||||
|
||||
break;
|
||||
|
||||
case BPF_MISC|BPF_TXA:
|
||||
|
||||
MOVrd(EAX,EDX)
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
ins++;
|
||||
}
|
||||
|
||||
pass++;
|
||||
if(pass == 2) break;
|
||||
|
||||
#ifdef NTKERNEL
|
||||
stream.ibuf=(CHAR*)ExAllocatePoolWithTag(NonPagedPool, stream.cur_ip, '1JWA');
|
||||
#else
|
||||
stream.ibuf=(CHAR*)malloc(stream.cur_ip);
|
||||
#endif
|
||||
if(stream.ibuf==NULL)
|
||||
{
|
||||
#ifdef NTKERNEL
|
||||
ExFreePool(stream.refs);
|
||||
#else
|
||||
free(stream.refs);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// modify the reference table to contain the offsets and not the lengths of the instructions
|
||||
for(i=1; i< nins + 1; i++)
|
||||
stream.refs[i]+=stream.refs[i-1];
|
||||
|
||||
// Reset the counters
|
||||
stream.cur_ip=0;
|
||||
stream.bpf_pc=0;
|
||||
// the second pass creates the actual code
|
||||
emitm=emit_code;
|
||||
|
||||
}
|
||||
|
||||
// the reference table is needed only during compilation, now we can free it
|
||||
#ifdef NTKERNEL
|
||||
ExFreePool(stream.refs);
|
||||
#else
|
||||
free(stream.refs);
|
||||
#endif
|
||||
return (BPF_filter_function)stream.ibuf;
|
||||
|
||||
}
|
||||
|
||||
|
||||
JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins)
|
||||
{
|
||||
JIT_BPF_Filter *Filter;
|
||||
|
||||
|
||||
// Allocate the filter structure
|
||||
#ifdef NTKERNEL
|
||||
Filter=(struct JIT_BPF_Filter*)ExAllocatePoolWithTag(NonPagedPool, sizeof(struct JIT_BPF_Filter), '2JWA');
|
||||
#else
|
||||
Filter=(struct JIT_BPF_Filter*)malloc(sizeof(struct JIT_BPF_Filter));
|
||||
#endif
|
||||
if(Filter==NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate the filter's memory
|
||||
#ifdef NTKERNEL
|
||||
Filter->mem=(INT*)ExAllocatePoolWithTag(NonPagedPool, BPF_MEMWORDS*sizeof(INT), '3JWA');
|
||||
#else
|
||||
Filter->mem=(INT*)malloc(BPF_MEMWORDS*sizeof(INT));
|
||||
#endif
|
||||
if(Filter->mem==NULL)
|
||||
{
|
||||
#ifdef NTKERNEL
|
||||
ExFreePool(Filter);
|
||||
#else
|
||||
free(Filter);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create the binary
|
||||
if((Filter->Function = BPFtoX86(fp, nins, Filter->mem))==NULL)
|
||||
{
|
||||
#ifdef NTKERNEL
|
||||
ExFreePool(Filter->mem);
|
||||
ExFreePool(Filter);
|
||||
#else
|
||||
free(Filter->mem);
|
||||
free(Filter);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Filter;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
void BPF_Destroy_JIT_Filter(JIT_BPF_Filter *Filter){
|
||||
|
||||
#ifdef NTKERNEL
|
||||
ExFreePool(Filter->mem);
|
||||
ExFreePool(Filter->Function);
|
||||
ExFreePool(Filter);
|
||||
#else
|
||||
free(Filter->mem);
|
||||
free(Filter->Function);
|
||||
free(Filter);
|
||||
#endif
|
||||
|
||||
}
|
||||
404
src/See/jitter.h
Normal file
404
src/See/jitter.h
Normal file
@ -0,0 +1,404 @@
|
||||
/*
|
||||
* Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||
* Copyright (c) 2005 CACE Technologies, Davis (California)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/** @ingroup NPF
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup NPF_include NPF structures and definitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
//
|
||||
// Registers
|
||||
//
|
||||
#define EAX 0
|
||||
#define ECX 1
|
||||
#define EDX 2
|
||||
#define EBX 3
|
||||
#define ESP 4
|
||||
#define EBP 5
|
||||
#define ESI 6
|
||||
#define EDI 7
|
||||
|
||||
#define AX 0
|
||||
#define CX 1
|
||||
#define DX 2
|
||||
#define BX 3
|
||||
#define SP 4
|
||||
#define BP 5
|
||||
#define SI 6
|
||||
#define DI 7
|
||||
|
||||
#define AL 0
|
||||
#define CL 1
|
||||
#define DL 2
|
||||
#define BL 3
|
||||
|
||||
/*! \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.
|
||||
}binary_stream;
|
||||
|
||||
|
||||
/*! \brief Prototype of a filtering function created by the jitter.
|
||||
|
||||
The syntax and the meaning of the parameters is analogous to the one of bpf_filter(). Notice that the filter
|
||||
is not among the parameters, because it is hardwired in the function.
|
||||
*/
|
||||
typedef UINT (__cdecl *BPF_filter_function)( PVOID *, ULONG, UINT);
|
||||
|
||||
/*! \brief Prototype of the emit functions.
|
||||
|
||||
Different emit functions are used to create the reference table and to generate the actual filtering code.
|
||||
This allows to have simpler instruction macros.
|
||||
The first parameter is the stream that will receive the data. The secon one is a variable containing
|
||||
the data, the third one is the length, that can be 1,2 or 4 since it is possible to emit a byte, a short
|
||||
or a work at a time.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
JIT_BPF_Filter;
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************/
|
||||
/* X86 INSTRUCTION MACROS */
|
||||
/**************************/
|
||||
|
||||
/// mov r32,i32
|
||||
#define MOVid(r32, i32) \
|
||||
emitm(&stream, 11 << 4 | 1 << 3 | r32 & 0x7, 1); emitm(&stream, i32, 4);
|
||||
|
||||
/// mov dr32,sr32
|
||||
#define MOVrd(dr32, sr32) \
|
||||
emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);
|
||||
|
||||
/// mov dr32,sr32[off]
|
||||
#define MOVodd(dr32, sr32, off) \
|
||||
emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \
|
||||
emitm(&stream, 1 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);\
|
||||
emitm(&stream, off, 1);
|
||||
|
||||
/// mov dr32,sr32[or32]
|
||||
#define MOVobd(dr32, sr32, or32) \
|
||||
emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \
|
||||
emitm(&stream, (dr32 & 0x7) << 3 | 4 , 1);\
|
||||
emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1);
|
||||
|
||||
/// mov dr16,sr32[or32]
|
||||
#define MOVobw(dr32, sr32, or32) \
|
||||
emitm(&stream, 0x66, 1); \
|
||||
emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \
|
||||
emitm(&stream, (dr32 & 0x7) << 3 | 4 , 1);\
|
||||
emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1);
|
||||
|
||||
/// mov dr8,sr32[or32]
|
||||
#define MOVobb(dr8, sr32, or32) \
|
||||
emitm(&stream, 0x8a, 1); \
|
||||
emitm(&stream, (dr8 & 0x7) << 3 | 4 , 1);\
|
||||
emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1);
|
||||
|
||||
/// mov [dr32][or32],sr32
|
||||
#define MOVomd(dr32, or32, sr32) \
|
||||
emitm(&stream, 0x89, 1); \
|
||||
emitm(&stream, (sr32 & 0x7) << 3 | 4 , 1);\
|
||||
emitm(&stream, (or32 & 0x7) << 3 | (dr32 & 0x7) , 1);
|
||||
|
||||
/// bswap dr32
|
||||
#define BSWAP(dr32) \
|
||||
emitm(&stream, 0xf, 1); \
|
||||
emitm(&stream, 0x19 << 3 | dr32 , 1);
|
||||
|
||||
/// xchg al,ah
|
||||
#define SWAP_AX() \
|
||||
emitm(&stream, 0x86, 1); \
|
||||
emitm(&stream, 0xc4 , 1);
|
||||
|
||||
/// push r32
|
||||
#define PUSH(r32) \
|
||||
emitm(&stream, 5 << 4 | 0 << 3 | r32 & 0x7, 1);
|
||||
|
||||
/// pop r32
|
||||
#define POP(r32) \
|
||||
emitm(&stream, 5 << 4 | 1 << 3 | r32 & 0x7, 1);
|
||||
|
||||
/// ret
|
||||
#define RET() \
|
||||
emitm(&stream, 12 << 4 | 0 << 3 | 3, 1);
|
||||
|
||||
/// add dr32,sr32
|
||||
#define ADDrd(dr32, sr32) \
|
||||
emitm(&stream, 0x03, 1);\
|
||||
emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | (sr32 & 0x7), 1);
|
||||
|
||||
/// add eax,i32
|
||||
#define ADD_EAXi(i32) \
|
||||
emitm(&stream, 0x05, 1);\
|
||||
emitm(&stream, i32, 4);
|
||||
|
||||
/// add r32,i32
|
||||
#define ADDid(r32, i32) \
|
||||
emitm(&stream, 0x81, 1);\
|
||||
emitm(&stream, 24 << 3 | r32, 1);\
|
||||
emitm(&stream, i32, 4);
|
||||
|
||||
/// add r32,i8
|
||||
#define ADDib(r32, i8) \
|
||||
emitm(&stream, 0x83, 1);\
|
||||
emitm(&stream, 24 << 3 | r32, 1);\
|
||||
emitm(&stream, i8, 1);
|
||||
|
||||
/// sub dr32,sr32
|
||||
#define SUBrd(dr32, sr32) \
|
||||
emitm(&stream, 0x2b, 1);\
|
||||
emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | (sr32 & 0x7), 1);
|
||||
|
||||
/// sub eax,i32
|
||||
#define SUB_EAXi(i32) \
|
||||
emitm(&stream, 0x2d, 1);\
|
||||
emitm(&stream, i32, 4);
|
||||
|
||||
/// mul r32
|
||||
#define MULrd(r32) \
|
||||
emitm(&stream, 0xf7, 1);\
|
||||
emitm(&stream, 7 << 5 | (r32 & 0x7), 1);
|
||||
|
||||
/// div r32
|
||||
#define DIVrd(r32) \
|
||||
emitm(&stream, 0xf7, 1);\
|
||||
emitm(&stream, 15 << 4 | (r32 & 0x7), 1);
|
||||
|
||||
/// and r8,i8
|
||||
#define ANDib(r8, i8) \
|
||||
emitm(&stream, 0x80, 1);\
|
||||
emitm(&stream, 7 << 5 | r8, 1);\
|
||||
emitm(&stream, i8, 1);
|
||||
|
||||
/// and r32,i32
|
||||
#define ANDid(r32, i32) \
|
||||
if (r32 == EAX){ \
|
||||
emitm(&stream, 0x25, 1);\
|
||||
emitm(&stream, i32, 4);}\
|
||||
else{ \
|
||||
emitm(&stream, 0x81, 1);\
|
||||
emitm(&stream, 7 << 5 | r32, 1);\
|
||||
emitm(&stream, i32, 4);}
|
||||
|
||||
/// and dr32,sr32
|
||||
#define ANDrd(dr32, sr32) \
|
||||
emitm(&stream, 0x23, 1);\
|
||||
emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);
|
||||
|
||||
/// or dr32,sr32
|
||||
#define ORrd(dr32, sr32) \
|
||||
emitm(&stream, 0x0b, 1);\
|
||||
emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);
|
||||
|
||||
/// or r32,i32
|
||||
#define ORid(r32, i32) \
|
||||
if (r32 == EAX){ \
|
||||
emitm(&stream, 0x0d, 1);\
|
||||
emitm(&stream, i32, 4);}\
|
||||
else{ \
|
||||
emitm(&stream, 0x81, 1);\
|
||||
emitm(&stream, 25 << 3 | r32, 1);\
|
||||
emitm(&stream, i32, 4);}
|
||||
|
||||
/// shl r32,i8
|
||||
#define SHLib(r32, i8) \
|
||||
emitm(&stream, 0xc1, 1);\
|
||||
emitm(&stream, 7 << 5 | r32 & 0x7, 1);\
|
||||
emitm(&stream, i8, 1);
|
||||
|
||||
/// shl dr32,cl
|
||||
#define SHL_CLrb(dr32) \
|
||||
emitm(&stream, 0xd3, 1);\
|
||||
emitm(&stream, 7 << 5 | dr32 & 0x7, 1);
|
||||
|
||||
/// shr r32,i8
|
||||
#define SHRib(r32, i8) \
|
||||
emitm(&stream, 0xc1, 1);\
|
||||
emitm(&stream, 29 << 3 | r32 & 0x7, 1);\
|
||||
emitm(&stream, i8, 1);
|
||||
|
||||
/// shr dr32,cl
|
||||
#define SHR_CLrb(dr32) \
|
||||
emitm(&stream, 0xd3, 1);\
|
||||
emitm(&stream, 29 << 3 | dr32 & 0x7, 1);
|
||||
|
||||
/// neg r32
|
||||
#define NEGd(r32) \
|
||||
emitm(&stream, 0xf7, 1);\
|
||||
emitm(&stream, 27 << 3 | r32 & 0x7, 1);
|
||||
|
||||
/// cmp dr32,sr32[off]
|
||||
#define CMPodd(dr32, sr32, off) \
|
||||
emitm(&stream, 3 << 4 | 3 | 1 << 3, 1); \
|
||||
emitm(&stream, 1 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);\
|
||||
emitm(&stream, off, 1);
|
||||
|
||||
/// cmp dr32,sr32
|
||||
#define CMPrd(dr32, sr32) \
|
||||
emitm(&stream, 0x3b, 1); \
|
||||
emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);
|
||||
|
||||
/// cmp dr32,i32
|
||||
#define CMPid(dr32, i32) \
|
||||
if (dr32 == EAX){ \
|
||||
emitm(&stream, 0x3d, 1); \
|
||||
emitm(&stream, i32, 4);} \
|
||||
else{ \
|
||||
emitm(&stream, 0x81, 1); \
|
||||
emitm(&stream, 0x1f << 3 | (dr32 & 0x7), 1);\
|
||||
emitm(&stream, i32, 4);}
|
||||
|
||||
/// jne off32
|
||||
#define JNEb(off8) \
|
||||
emitm(&stream, 0x75, 1);\
|
||||
emitm(&stream, off8, 1);
|
||||
|
||||
/// je off32
|
||||
#define JE(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x84, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jle off32
|
||||
#define JLE(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x8e, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jle off8
|
||||
#define JLEb(off8) \
|
||||
emitm(&stream, 0x7e, 1);\
|
||||
emitm(&stream, off8, 1);
|
||||
|
||||
/// ja off32
|
||||
#define JA(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x87, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jae off32
|
||||
#define JAE(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x83, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jg off32
|
||||
#define JG(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x8f, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jge off32
|
||||
#define JGE(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x8d, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jmp off32
|
||||
#define JMP(off32) \
|
||||
emitm(&stream, 0xe9, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**************************/
|
||||
/* Prototypes */
|
||||
/**************************/
|
||||
|
||||
/** @ingroup NPF
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup NPF_code NPF functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
\brief BPF jitter, builds an x86 function from a BPF program.
|
||||
\param fp The BPF pseudo-assembly filter that will be translated into x86 code.
|
||||
\param nins Number of instructions of the input filter.
|
||||
\return The JIT_BPF_Filter structure containing the x86 filtering binary.
|
||||
|
||||
BPF_jitter allocates the buffers for the new native filter and then translates the program pointed by fp
|
||||
calling BPFtoX86().
|
||||
*/
|
||||
JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins);
|
||||
|
||||
/*!
|
||||
\brief Translates a set of BPF instructions in a set of x86 ones.
|
||||
\param ins Pointer to the BPF instructions that will be translated into x86 code.
|
||||
\param nins Number of instructions to translate.
|
||||
\param mem Memory used by the x86 function to emulate the RAM of the BPF pseudo processor.
|
||||
\return The x86 filtering function.
|
||||
|
||||
This function does the hard work for the JIT compilation. It takes a group of BPF pseudo instructions and
|
||||
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 *ins, UINT nins, INT *mem);
|
||||
/*!
|
||||
\brief Deletes a filtering function that was previously created by BPF_jitter().
|
||||
\param Filter The filter to destroy.
|
||||
|
||||
This function frees the variuos buffers (code, memory, etc.) associated with a filtering function.
|
||||
*/
|
||||
void BPF_Destroy_JIT_Filter(JIT_BPF_Filter *Filter);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
132
src/See/memory_t.h
Normal file
132
src/See/memory_t.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
/*memory type*/
|
||||
typedef struct __MEM_TYPE
|
||||
{
|
||||
uint8 *buffer;
|
||||
uint32 size;
|
||||
} MEM_TYPE, *PMEM_TYPE;
|
||||
|
||||
#define LONG_AT(base,offset) (*(int32*)((uint8*)base+(uint32)offset))
|
||||
|
||||
#define ULONG_AT(base,offset) (*(uint32*)((uint8*)base+(uint32)offset))
|
||||
|
||||
#define SHORT_AT(base,offset) (*(int16*)((uint8*)base+(uint32)offset))
|
||||
|
||||
#define USHORT_AT(base,offset) (*(uint16*)((uint8*)base+(uint32)offset))
|
||||
|
||||
__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);
|
||||
}
|
||||
|
||||
|
||||
__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);
|
||||
}
|
||||
|
||||
__inline int16 SW_SHORT_AT(void *b, uint32 os)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
__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);
|
||||
|
||||
}
|
||||
|
||||
#ifdef WIN_NT_DRIVER
|
||||
|
||||
#define ALLOCATE_MEMORY(dest,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)); \
|
||||
}
|
||||
|
||||
#define FREE_MEMORY(dest) ExFreePool(dest);
|
||||
#define ZERO_MEMORY(dest,amount) RtlZeroMemory(dest,amount);
|
||||
#define COPY_MEMORY(dest,src,amount) RtlCopyMemory(dest,src,amount);
|
||||
|
||||
#else
|
||||
|
||||
#define ALLOCATE_MEMORY(dest,type,amount) \
|
||||
(dest)=(type*)GlobalAlloc(GPTR, sizeof(type)*(amount));
|
||||
#define ALLOCATE_ZERO_MEMORY(dest,type,amount) \
|
||||
(dest)=(type*)GlobalAlloc(GPTR, sizeof(type)*(amount));
|
||||
|
||||
#define FREE_MEMORY(dest) GlobalFree(dest);
|
||||
#define ZERO_MEMORY(dest,amount) RtlZeroMemory(dest,amount);
|
||||
#define COPY_MEMORY(dest,src,amount) RtlCopyMemory(dest,src,amount);
|
||||
|
||||
|
||||
#endif /*WIN_NT_DRIVER*/
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
204
src/See/normal_lookup.c
Normal file
204
src/See/normal_lookup.c
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "tme.h"
|
||||
#include "normal_lookup.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <net/tme/tme.h>
|
||||
#include <net/tme/normal_lookup.h>
|
||||
#else
|
||||
#include <tme/tme.h>
|
||||
#include <tme/normal_lookup.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* lookup in the table, seen as an hash */
|
||||
/* if not found, inserts an element */
|
||||
/* returns TME_TRUE if the entry is found or created, */
|
||||
/* returns TME_FALSE if no more blocks are available */
|
||||
uint32 normal_lut_w_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref)
|
||||
{
|
||||
uint32 i;
|
||||
uint32 tocs=0;
|
||||
uint32 *key32=(uint32*) key;
|
||||
uint32 shrinked_key=0;
|
||||
uint32 index;
|
||||
RECORD *records=(RECORD*)data->lut_base_address;
|
||||
uint8 *offset;
|
||||
uint32 key_len=data->key_len;
|
||||
/*the key is shrinked into a 32-bit value */
|
||||
for (i=0; i<key_len;i++)
|
||||
shrinked_key^=key32[i];
|
||||
/*the first index in the table is calculated*/
|
||||
index=shrinked_key % data->lut_entries;
|
||||
|
||||
while (tocs<=data->filled_entries)
|
||||
{
|
||||
|
||||
if (records[index].block==0)
|
||||
{ /*creation of a new entry*/
|
||||
|
||||
if (data->filled_blocks==data->shared_memory_blocks)
|
||||
{
|
||||
/*no more free blocks*/
|
||||
GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref);
|
||||
data->last_found=NULL;
|
||||
return TME_FALSE;
|
||||
}
|
||||
|
||||
/*offset=absolute pointer to the block associated*/
|
||||
/*with the newly created entry*/
|
||||
offset=data->shared_memory_base_address+
|
||||
data->block_size*data->filled_blocks;
|
||||
|
||||
/*copy the key in the block*/
|
||||
COPY_MEMORY(offset,key32,key_len*4);
|
||||
GET_TIME((struct timeval *)(offset+4*key_len),time_ref);
|
||||
/*assign the block relative offset to the entry, in NBO*/
|
||||
SW_ULONG_ASSIGN(&records[index].block,offset-mem_ex->buffer);
|
||||
|
||||
data->filled_blocks++;
|
||||
|
||||
/*assign the exec function ID to the entry, in NBO*/
|
||||
SW_ULONG_ASSIGN(&records[index].exec_fcn,data->default_exec);
|
||||
data->filled_entries++;
|
||||
|
||||
data->last_found=(uint8*)&records[index];
|
||||
|
||||
return TME_TRUE;
|
||||
}
|
||||
/*offset contains the absolute pointer to the block*/
|
||||
/*associated with the current entry */
|
||||
offset=mem_ex->buffer+SW_ULONG_AT(&records[index].block,0);
|
||||
|
||||
for (i=0; (i<key_len) && (key32[i]==ULONG_AT(offset,i*4)); i++);
|
||||
|
||||
if (i==key_len)
|
||||
{
|
||||
/*key in the block matches the one provided, right entry*/
|
||||
GET_TIME((struct timeval *)(offset+4*key_len),time_ref);
|
||||
data->last_found=(uint8*)&records[index];
|
||||
return TME_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wrong entry, rehashing */
|
||||
if (IS_DELETABLE(offset+key_len*4,data))
|
||||
{
|
||||
ZERO_MEMORY(offset,data->block_size);
|
||||
COPY_MEMORY(offset,key32,key_len*4);
|
||||
SW_ULONG_ASSIGN(&records[index].exec_fcn,data->default_exec);
|
||||
GET_TIME((struct timeval*)(offset+key_len*4),time_ref);
|
||||
data->last_found=(uint8*)&records[index];
|
||||
return TME_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
index=(index+data->rehashing_value) % data->lut_entries;
|
||||
tocs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* nothing found, last found= out of lut */
|
||||
GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref);
|
||||
data->last_found=NULL;
|
||||
return TME_FALSE;
|
||||
|
||||
}
|
||||
|
||||
/* lookup in the table, seen as an hash */
|
||||
/* if not found, returns out of count entry index */
|
||||
/* returns TME_TRUE if the entry is found */
|
||||
/* returns TME_FALSE if the entry is not found */
|
||||
uint32 normal_lut_wo_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref)
|
||||
{
|
||||
uint32 i;
|
||||
uint32 tocs=0;
|
||||
uint32 *key32=(uint32*) key;
|
||||
uint32 shrinked_key=0;
|
||||
uint32 index;
|
||||
RECORD *records=(RECORD*)data->lut_base_address;
|
||||
uint8 *offset;
|
||||
uint32 key_len=data->key_len;
|
||||
/*the key is shrinked into a 32-bit value */
|
||||
for (i=0; i<key_len;i++)
|
||||
shrinked_key^=key32[i];
|
||||
/*the first index in the table is calculated*/
|
||||
index=shrinked_key % data->lut_entries;
|
||||
|
||||
while (tocs<=data->filled_entries)
|
||||
{
|
||||
|
||||
if (records[index].block==0)
|
||||
{ /*out of table, insertion is not allowed*/
|
||||
GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref);
|
||||
data->last_found=NULL;
|
||||
return TME_FALSE;
|
||||
}
|
||||
/*offset contains the absolute pointer to the block*/
|
||||
/*associated with the current entry */
|
||||
|
||||
offset=mem_ex->buffer+SW_ULONG_AT(&records[index].block,0);
|
||||
|
||||
for (i=0; (i<key_len) && (key32[i]==ULONG_AT(offset,i*4)); i++);
|
||||
|
||||
if (i==key_len)
|
||||
{
|
||||
/*key in the block matches the one provided, right entry*/
|
||||
GET_TIME((struct timeval *)(offset+4*key_len),time_ref);
|
||||
data->last_found=(uint8*)&records[index];
|
||||
return TME_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*wrong entry, rehashing*/
|
||||
index=(index+data->rehashing_value) % data->lut_entries;
|
||||
tocs++;
|
||||
}
|
||||
}
|
||||
|
||||
/*nothing found, last found= out of lut*/
|
||||
GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref);
|
||||
data->last_found=NULL;
|
||||
return TME_FALSE;
|
||||
|
||||
}
|
||||
56
src/See/normal_lookup.h
Normal file
56
src/See/normal_lookup.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __normal_lookup
|
||||
#define __normal_lookup
|
||||
|
||||
#ifdef WIN32
|
||||
#include "tme.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <net/tme/tme.h>
|
||||
#else
|
||||
#include <tme/tme.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#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
|
||||
uint32 normal_lut_wo_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref);
|
||||
#define DUMMY_INSERT 1234
|
||||
|
||||
#endif
|
||||
84
src/See/resource.h
Normal file
84
src/See/resource.h
Normal file
@ -0,0 +1,84 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by NPF.RC
|
||||
//
|
||||
// Comments: Tetsuo Sugiyama, Ph.D.
|
||||
//
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// version 2 as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License version 2
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
|
||||
// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
|
||||
//
|
||||
//
|
||||
// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
|
||||
// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
|
||||
// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
|
||||
// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
|
||||
// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
|
||||
// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
|
||||
// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
|
||||
// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
|
||||
// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
|
||||
// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
|
||||
// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
|
||||
// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
|
||||
// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
|
||||
// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
|
||||
//
|
||||
// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
|
||||
// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
|
||||
// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
|
||||
// COUNTRIES MIGHT BE RESTRICTED.
|
||||
//
|
||||
//
|
||||
// DEAR SECURITY EXPERTS
|
||||
// ---------------------
|
||||
//
|
||||
// If you find a bug or a security vulnerability please kindly inform us
|
||||
// about the problem immediately so that we can fix the security problem
|
||||
// to protect a lot of users around the world as soon as possible.
|
||||
//
|
||||
// Our e-mail address for security reports is:
|
||||
// softether-vpn-security [at] softether.org
|
||||
//
|
||||
// Please note that the above e-mail address is not a technical support
|
||||
// inquiry address. If you need technical assistance, please visit
|
||||
// http://www.softether.org/ and ask your question on the users forum.
|
||||
//
|
||||
// Thank you for your cooperation.
|
||||
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
|
||||
// Department of Computer Science has dozens of overly-enthusiastic geeks.
|
||||
// Join us: http://www.tsukuba.ac.jp/english/admission/
|
||||
84
src/See/resource1.h
Normal file
84
src/See/resource1.h
Normal file
@ -0,0 +1,84 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by See.rc
|
||||
//
|
||||
// Comments: Tetsuo Sugiyama, Ph.D.
|
||||
//
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// version 2 as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License version 2
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
|
||||
// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
|
||||
//
|
||||
//
|
||||
// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
|
||||
// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
|
||||
// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
|
||||
// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
|
||||
// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
|
||||
// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
|
||||
// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
|
||||
// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
|
||||
// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
|
||||
// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
|
||||
// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
|
||||
// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
|
||||
// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
|
||||
// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
|
||||
//
|
||||
// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
|
||||
// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
|
||||
// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
|
||||
// COUNTRIES MIGHT BE RESTRICTED.
|
||||
//
|
||||
//
|
||||
// DEAR SECURITY EXPERTS
|
||||
// ---------------------
|
||||
//
|
||||
// If you find a bug or a security vulnerability please kindly inform us
|
||||
// about the problem immediately so that we can fix the security problem
|
||||
// to protect a lot of users around the world as soon as possible.
|
||||
//
|
||||
// Our e-mail address for security reports is:
|
||||
// softether-vpn-security [at] softether.org
|
||||
//
|
||||
// Please note that the above e-mail address is not a technical support
|
||||
// inquiry address. If you need technical assistance, please visit
|
||||
// http://www.softether.org/ and ask your question on the users forum.
|
||||
//
|
||||
// Thank you for your cooperation.
|
||||
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
|
||||
// Department of Computer Science has dozens of overly-enthusiastic geeks.
|
||||
// Join us: http://www.tsukuba.ac.jp/english/admission/
|
||||
296
src/See/tcp_session.c
Normal file
296
src/See/tcp_session.c
Normal file
@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "tme.h"
|
||||
#include "tcp_session.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <net/tme/tme.h>
|
||||
#include <net/tme/tcp_session.h>
|
||||
#else
|
||||
#include <tme/tme.h>
|
||||
#include <tme/tcp_session.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
uint32 tcp_session(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data)
|
||||
|
||||
{
|
||||
|
||||
uint32 next_status;
|
||||
uint32 direction=ULONG_AT(mem_data,12);
|
||||
uint8 flags=mem_ex->buffer[25];
|
||||
tcp_data *session=(tcp_data*)(block+data->key_len*4);
|
||||
|
||||
session->last_timestamp=session->timestamp_block;
|
||||
session->timestamp_block.tv_sec=0x7fffffff;
|
||||
|
||||
if (direction==session->direction)
|
||||
{
|
||||
session->pkts_cln_to_srv++;
|
||||
session->bytes_cln_to_srv+=pkt_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
session->pkts_srv_to_cln++;
|
||||
session->bytes_srv_to_cln+=pkt_size;
|
||||
}
|
||||
/* we use only thes four flags, we don't need PSH or URG */
|
||||
flags&=(ACK|FIN|SYN|RST);
|
||||
|
||||
switch (session->status)
|
||||
{
|
||||
case ERROR_TCP:
|
||||
next_status=ERROR_TCP;
|
||||
break;
|
||||
|
||||
case UNKNOWN:
|
||||
if (flags==SYN)
|
||||
{
|
||||
if (SW_ULONG_AT(mem_ex->buffer,20)!=0)
|
||||
{
|
||||
|
||||
next_status=ERROR_TCP;
|
||||
break;
|
||||
}
|
||||
next_status=SYN_RCV;
|
||||
session->syn_timestamp=session->last_timestamp;
|
||||
|
||||
session->direction=direction;
|
||||
session->seq_n_0_cln=SW_ULONG_AT(mem_ex->buffer,16);
|
||||
}
|
||||
else
|
||||
next_status=UNKNOWN;
|
||||
break;
|
||||
|
||||
case SYN_RCV:
|
||||
if ((flags&RST)&&(direction!=session->direction))
|
||||
{
|
||||
next_status=CLOSED_RST;
|
||||
break;
|
||||
}
|
||||
if ((flags==SYN)&&(direction==session->direction))
|
||||
{ /* two syns... */
|
||||
next_status=SYN_RCV;
|
||||
session->seq_n_0_cln=SW_ULONG_AT(mem_ex->buffer,16);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((flags==(SYN|ACK))&&(direction!=session->direction))
|
||||
{
|
||||
if (SW_ULONG_AT(mem_ex->buffer,20)!=session->seq_n_0_cln+1)
|
||||
{
|
||||
next_status=ERROR_TCP;
|
||||
break;
|
||||
}
|
||||
next_status=SYN_ACK_RCV;
|
||||
|
||||
session->syn_ack_timestamp=session->last_timestamp;
|
||||
|
||||
session->seq_n_0_srv=SW_ULONG_AT(mem_ex->buffer,16);
|
||||
session->ack_cln=session->seq_n_0_cln+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
next_status=ERROR_TCP;
|
||||
}
|
||||
break;
|
||||
|
||||
case SYN_ACK_RCV:
|
||||
if ((flags&ACK)&&(flags&RST)&&(direction==session->direction))
|
||||
{
|
||||
next_status=CLOSED_RST;
|
||||
session->ack_srv=SW_ULONG_AT(mem_ex->buffer,20);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((flags==ACK)&&(!(flags&(SYN|FIN|RST)))&&(direction==session->direction))
|
||||
{
|
||||
if (SW_ULONG_AT(mem_ex->buffer,20)!=session->seq_n_0_srv+1)
|
||||
{
|
||||
next_status=ERROR_TCP;
|
||||
break;
|
||||
}
|
||||
next_status=ESTABLISHED;
|
||||
session->ack_srv=session->seq_n_0_srv+1;
|
||||
break;
|
||||
}
|
||||
if ((flags&ACK)&&(flags&SYN)&&(direction!=session->direction))
|
||||
{
|
||||
next_status=SYN_ACK_RCV;
|
||||
break;
|
||||
}
|
||||
|
||||
next_status=ERROR_TCP;
|
||||
break;
|
||||
|
||||
case ESTABLISHED:
|
||||
if (flags&SYN)
|
||||
{
|
||||
if ((flags&ACK)&&
|
||||
(direction!=session->direction)&&
|
||||
((session->ack_cln-SW_ULONG_AT(mem_ex->buffer,20))<MAX_WINDOW)
|
||||
)
|
||||
{ /* SYN_ACK duplicato */
|
||||
next_status=ESTABLISHED;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((!(flags&ACK))&&
|
||||
(direction==session->direction)&&
|
||||
(SW_ULONG_AT(mem_ex->buffer,16)==session->seq_n_0_cln)&&
|
||||
(ULONG_AT(mem_ex->buffer,20)==0)
|
||||
)
|
||||
{ /* syn duplicato */
|
||||
next_status=ESTABLISHED;
|
||||
break;
|
||||
}
|
||||
|
||||
next_status=ERROR_TCP;
|
||||
break;
|
||||
}
|
||||
if (flags&ACK)
|
||||
if (direction==session->direction)
|
||||
{
|
||||
uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20);
|
||||
if (new_ack-session->ack_srv<MAX_WINDOW)
|
||||
session->ack_srv=new_ack;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20);
|
||||
if (new_ack-session->ack_cln<MAX_WINDOW)
|
||||
session->ack_cln=new_ack;
|
||||
}
|
||||
if (flags&RST)
|
||||
{
|
||||
next_status=CLOSED_RST;
|
||||
break;
|
||||
}
|
||||
if (flags&FIN)
|
||||
if (direction==session->direction)
|
||||
{ /* an hack to make all things work */
|
||||
session->ack_cln=SW_ULONG_AT(mem_ex->buffer,16);
|
||||
next_status=FIN_CLN_RCV;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
session->ack_srv=SW_ULONG_AT(mem_ex->buffer,16);
|
||||
next_status=FIN_SRV_RCV;
|
||||
break;
|
||||
}
|
||||
next_status=ESTABLISHED;
|
||||
break;
|
||||
|
||||
case CLOSED_RST:
|
||||
next_status=CLOSED_RST;
|
||||
break;
|
||||
|
||||
case FIN_SRV_RCV:
|
||||
if (flags&SYN)
|
||||
{
|
||||
next_status=ERROR_TCP;
|
||||
break;
|
||||
}
|
||||
|
||||
next_status=FIN_SRV_RCV;
|
||||
|
||||
if (flags&ACK)
|
||||
{
|
||||
uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20);
|
||||
if (direction!=session->direction)
|
||||
if ((new_ack-session->ack_cln)<MAX_WINDOW)
|
||||
session->ack_cln=new_ack;
|
||||
}
|
||||
|
||||
if (flags&RST)
|
||||
next_status=CLOSED_RST;
|
||||
else
|
||||
if ((flags&FIN)&&(direction==session->direction))
|
||||
{
|
||||
session->ack_cln=SW_ULONG_AT(mem_ex->buffer,16);
|
||||
next_status=CLOSED_FIN;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FIN_CLN_RCV:
|
||||
if (flags&SYN)
|
||||
{
|
||||
next_status=ERROR_TCP;
|
||||
break;
|
||||
}
|
||||
|
||||
next_status=FIN_CLN_RCV;
|
||||
|
||||
if (flags&ACK)
|
||||
{
|
||||
uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20);
|
||||
if (direction==session->direction)
|
||||
if (new_ack-session->ack_srv<MAX_WINDOW)
|
||||
session->ack_srv=new_ack;
|
||||
}
|
||||
|
||||
if (flags&RST)
|
||||
next_status=CLOSED_RST;
|
||||
else
|
||||
if ((flags&FIN)&&(direction!=session->direction))
|
||||
{
|
||||
session->ack_srv=SW_ULONG_AT(mem_ex->buffer,16);
|
||||
next_status=CLOSED_FIN;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CLOSED_FIN:
|
||||
next_status=CLOSED_FIN;
|
||||
break;
|
||||
default:
|
||||
next_status=ERROR_TCP;
|
||||
|
||||
}
|
||||
|
||||
session->status=next_status;
|
||||
|
||||
if ((next_status==CLOSED_FIN)||(next_status==UNKNOWN)||(next_status==CLOSED_RST)||(next_status==ERROR_TCP))
|
||||
session->timestamp_block=session->last_timestamp;
|
||||
|
||||
return TME_SUCCESS;
|
||||
}
|
||||
96
src/See/tcp_session.h
Normal file
96
src/See/tcp_session.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __tcp_session
|
||||
#define __tcp_session
|
||||
|
||||
#ifdef WIN32
|
||||
#include "tme.h"
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <net/tme/tme.h>
|
||||
#else
|
||||
#include <tme/tme.h>
|
||||
#endif
|
||||
|
||||
#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 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;
|
||||
}
|
||||
tcp_data;
|
||||
|
||||
#define FIN 1
|
||||
#define SYN 2
|
||||
#define RST 4
|
||||
#define PSH 8
|
||||
#define ACK 16
|
||||
#define URG 32
|
||||
|
||||
#define TCP_SESSION 0x00000800
|
||||
uint32 tcp_session(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data);
|
||||
|
||||
#endif
|
||||
486
src/See/time_calls.h
Normal file
486
src/See/time_calls.h
Normal file
@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||
* Copyright (c) 2005 CACE Technologies, Davis (California)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _time_calls
|
||||
#define _time_calls
|
||||
|
||||
#ifdef WIN_NT_DRIVER
|
||||
|
||||
#include "debug.h"
|
||||
#include "ndis.h"
|
||||
|
||||
#define DEFAULT_TIMESTAMPMODE 0
|
||||
|
||||
#define TIMESTAMPMODE_SINGLE_SYNCHRONIZATION 0
|
||||
#define TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP 1
|
||||
#define TIMESTAMPMODE_QUERYSYSTEMTIME 2
|
||||
#define TIMESTAMPMODE_RDTSC 3
|
||||
|
||||
#define TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP 99
|
||||
|
||||
#define TIMESTAMPMODE_REGKEY L"TimestampMode"
|
||||
|
||||
extern ULONG TimestampMode;
|
||||
extern ULONG NCpu;
|
||||
|
||||
/*!
|
||||
\brief A microsecond precise timestamp.
|
||||
|
||||
included in the sf_pkthdr or the bpf_hdr that NPF associates with every packet.
|
||||
*/
|
||||
|
||||
struct timeval {
|
||||
long tv_sec; ///< seconds
|
||||
long tv_usec; ///< microseconds
|
||||
};
|
||||
|
||||
#endif /*WIN_NT_DRIVER*/
|
||||
|
||||
struct time_conv
|
||||
{
|
||||
ULONGLONG reference;
|
||||
struct timeval start[32];
|
||||
};
|
||||
|
||||
#ifdef WIN_NT_DRIVER
|
||||
|
||||
__inline void TIME_DESYNCHRONIZE(struct time_conv *data)
|
||||
{
|
||||
data->reference = 0;
|
||||
// data->start.tv_sec = 0;
|
||||
// data->start.tv_usec = 0;
|
||||
}
|
||||
|
||||
|
||||
__inline void ReadTimeStampModeFromRegistry(PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
ULONG NewLength;
|
||||
PWSTR NullTerminatedString;
|
||||
RTL_QUERY_REGISTRY_TABLE Queries[2];
|
||||
ULONG DefaultTimestampMode = DEFAULT_TIMESTAMPMODE;
|
||||
|
||||
NewLength = RegistryPath->Length/2;
|
||||
|
||||
NullTerminatedString = ExAllocatePool(PagedPool, (NewLength+1) *sizeof(WCHAR));
|
||||
|
||||
if (NullTerminatedString != NULL)
|
||||
{
|
||||
RtlCopyMemory(NullTerminatedString, RegistryPath->Buffer, RegistryPath->Length);
|
||||
|
||||
NullTerminatedString[NewLength]=0;
|
||||
|
||||
RtlZeroMemory(Queries, sizeof(Queries));
|
||||
|
||||
Queries[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||||
Queries[0].Name = TIMESTAMPMODE_REGKEY;
|
||||
Queries[0].EntryContext = &TimestampMode;
|
||||
Queries[0].DefaultType = REG_DWORD;
|
||||
Queries[0].DefaultData = &DefaultTimestampMode;
|
||||
Queries[0].DefaultLength = sizeof(ULONG);
|
||||
|
||||
if (RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, NullTerminatedString, Queries, NULL, NULL) != STATUS_SUCCESS)
|
||||
{
|
||||
TimestampMode = DEFAULT_TIMESTAMPMODE;
|
||||
}
|
||||
|
||||
RtlWriteRegistryValue( RTL_REGISTRY_ABSOLUTE, NullTerminatedString, TIMESTAMPMODE_REGKEY, REG_DWORD, &TimestampMode,sizeof(ULONG));
|
||||
ExFreePool(NullTerminatedString);
|
||||
}
|
||||
else
|
||||
TimestampMode = DEFAULT_TIMESTAMPMODE;
|
||||
}
|
||||
|
||||
#pragma optimize ("g",off) //Due to some weird behaviour of the optimizer of DDK build 2600
|
||||
|
||||
/* KeQueryPerformanceCounter TimeStamps */
|
||||
__inline void SynchronizeOnCpu(struct timeval *start)
|
||||
{
|
||||
// struct timeval *start = (struct timeval*)Data;
|
||||
|
||||
LARGE_INTEGER SystemTime;
|
||||
LARGE_INTEGER TimeFreq,PTime;
|
||||
|
||||
// get the absolute value of the system boot time.
|
||||
|
||||
PTime = KeQueryPerformanceCounter(&TimeFreq);
|
||||
KeQuerySystemTime(&SystemTime);
|
||||
|
||||
start->tv_sec = (LONG)(SystemTime.QuadPart/10000000-11644473600);
|
||||
|
||||
start->tv_usec = (LONG)((SystemTime.QuadPart%10000000)/10);
|
||||
|
||||
start->tv_sec -= (ULONG)(PTime.QuadPart/TimeFreq.QuadPart);
|
||||
|
||||
start->tv_usec -= (LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
|
||||
|
||||
if (start->tv_usec < 0)
|
||||
{
|
||||
start->tv_sec --;
|
||||
start->tv_usec += 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// inline assembler is not supported with the current AMD64 compilers
|
||||
// At the moment we simply disable this timestamping mode on AMD64.
|
||||
// A solution would be to allocate a small memory from the non-paged
|
||||
// pool, dump the instructions on that buffer, and then execute them.
|
||||
// The non paged pool is needed since it's the only area of kernel
|
||||
// data memory that is not subject to the NX protection.
|
||||
// Or use some lower level trick, like using an assembler to assemble
|
||||
// a small function for this.
|
||||
//
|
||||
|
||||
#ifdef __NPF_x86__
|
||||
/*RDTSC timestamps */
|
||||
/* callers must be at IRQL=PASSIVE_LEVEL*/
|
||||
__inline VOID TimeSynchronizeRDTSC(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;
|
||||
|
||||
if (data->reference!=0)
|
||||
return;
|
||||
|
||||
KeInitializeEvent(&event,NotificationEvent,FALSE);
|
||||
|
||||
i.QuadPart=-3500000;
|
||||
|
||||
KeRaiseIrql(HIGH_LEVEL,&old);
|
||||
start_kqpc=KeQueryPerformanceCounter(&start_freq);
|
||||
__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
|
||||
}
|
||||
|
||||
KeLowerIrql(old);
|
||||
|
||||
KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i);
|
||||
|
||||
KeRaiseIrql(HIGH_LEVEL,&old);
|
||||
stop_kqpc=KeQueryPerformanceCounter(&stop_freq);
|
||||
__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
|
||||
}
|
||||
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);
|
||||
|
||||
__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
|
||||
}
|
||||
|
||||
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[0] = tmp;
|
||||
|
||||
IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);)
|
||||
}
|
||||
#endif //__NPF_x86__
|
||||
|
||||
#pragma optimize ("g",on) //Due to some weird behaviour of the optimizer of DDK build 2600
|
||||
|
||||
__inline VOID TIME_SYNCHRONIZE(struct time_conv *data)
|
||||
{
|
||||
ULONG NumberOfCpus, i;
|
||||
KAFFINITY AffinityMask;
|
||||
|
||||
if (data->reference != 0)
|
||||
return;
|
||||
|
||||
NumberOfCpus = NCpu;
|
||||
|
||||
if ( TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP || TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP)
|
||||
{
|
||||
for (i = 0 ; i < NumberOfCpus ; i++ )
|
||||
{
|
||||
AffinityMask = (1 << i);
|
||||
ZwSetInformationThread(NtCurrentThread(), ThreadAffinityMask, &AffinityMask, sizeof(KAFFINITY));
|
||||
SynchronizeOnCpu(&(data->start[i]));
|
||||
}
|
||||
AffinityMask = 0xFFFFFFFF;
|
||||
ZwSetInformationThread(NtCurrentThread(), ThreadAffinityMask, &AffinityMask, sizeof(KAFFINITY));
|
||||
data->reference = 1;
|
||||
}
|
||||
else
|
||||
if ( TimestampMode == TIMESTAMPMODE_QUERYSYSTEMTIME )
|
||||
{
|
||||
//do nothing
|
||||
data->reference = 1;
|
||||
}
|
||||
else
|
||||
//
|
||||
// This timestamp mode is supported on x86 (32 bit) only
|
||||
//
|
||||
#ifdef __NPF_x86__
|
||||
if ( TimestampMode == TIMESTAMPMODE_RDTSC )
|
||||
{
|
||||
TimeSynchronizeRDTSC(data);
|
||||
}
|
||||
else
|
||||
#endif // __NPF_x86__
|
||||
{ //it should be only the normal case i.e. TIMESTAMPMODE_SINGLESYNCHRONIZATION
|
||||
SynchronizeOnCpu(data->start);
|
||||
data->reference = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#pragma optimize ("g",off) //Due to some weird behaviour of the optimizer of DDK build 2600
|
||||
|
||||
__inline void GetTimeKQPC(struct timeval *dst, struct time_conv *data)
|
||||
{
|
||||
LARGE_INTEGER PTime, TimeFreq;
|
||||
LONG tmp;
|
||||
ULONG CurrentCpu;
|
||||
static struct timeval old_ts={0,0};
|
||||
|
||||
|
||||
PTime = KeQueryPerformanceCounter(&TimeFreq);
|
||||
tmp = (LONG)(PTime.QuadPart/TimeFreq.QuadPart);
|
||||
|
||||
if (TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP || TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP)
|
||||
{
|
||||
//actually this code is ok only if we are guaranteed that no thread scheduling will take place.
|
||||
CurrentCpu = KeGetCurrentProcessorNumber();
|
||||
|
||||
dst->tv_sec = data->start[CurrentCpu].tv_sec + tmp;
|
||||
dst->tv_usec = data->start[CurrentCpu].tv_usec + (LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
|
||||
|
||||
if (dst->tv_usec >= 1000000)
|
||||
{
|
||||
dst->tv_sec ++;
|
||||
dst->tv_usec -= 1000000;
|
||||
}
|
||||
|
||||
if (TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP)
|
||||
{
|
||||
if (old_ts.tv_sec > dst->tv_sec || (old_ts.tv_sec == dst->tv_sec && old_ts.tv_usec > dst->tv_usec) )
|
||||
*dst = old_ts;
|
||||
|
||||
else
|
||||
old_ts = *dst;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //it should be only the normal case i.e. TIMESTAMPMODE_SINGLESYNCHRONIZATION
|
||||
dst->tv_sec = data->start[0].tv_sec + tmp;
|
||||
dst->tv_usec = data->start[0].tv_usec + (LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
|
||||
|
||||
if (dst->tv_usec >= 1000000)
|
||||
{
|
||||
dst->tv_sec ++;
|
||||
dst->tv_usec -= 1000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// inline assembler is not supported with the current AMD64 compilers
|
||||
// At the moment we simply disable this timestamping mode on AMD64.
|
||||
// A solution would be to allocate a small memory from the non-paged
|
||||
// pool, dump the instructions on that buffer, and then execute them.
|
||||
// The non paged pool is needed since it's the only area of kernel
|
||||
// data memory that is not subject to the NX protection.
|
||||
// Or use some lower level trick, like using an assembler to assemble
|
||||
// a small function for this.
|
||||
//
|
||||
|
||||
#ifdef __NPF_x86__
|
||||
__inline void GetTimeRDTSC(struct timeval *dst, struct time_conv *data)
|
||||
{
|
||||
|
||||
ULONGLONG tmp;
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push edx
|
||||
push ecx
|
||||
rdtsc
|
||||
lea ecx, tmp
|
||||
mov [ecx+4], edx
|
||||
mov [ecx], eax
|
||||
pop ecx
|
||||
pop edx
|
||||
pop eax
|
||||
}
|
||||
|
||||
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[0].tv_sec;
|
||||
|
||||
dst->tv_usec+=data->start[0].tv_usec;
|
||||
|
||||
if (dst->tv_usec>=1000000)
|
||||
{
|
||||
dst->tv_sec++;
|
||||
dst->tv_usec-=1000000;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif //__NPF_x86__
|
||||
|
||||
__inline void GetTimeQST(struct timeval *dst, struct time_conv *data)
|
||||
{
|
||||
LARGE_INTEGER SystemTime;
|
||||
|
||||
KeQuerySystemTime(&SystemTime);
|
||||
|
||||
dst->tv_sec = (LONG)(SystemTime.QuadPart/10000000-11644473600);
|
||||
dst->tv_usec = (LONG)((SystemTime.QuadPart%10000000)/10);
|
||||
|
||||
}
|
||||
|
||||
#pragma optimize ("g",on) //Due to some weird behaviour of the optimizer of DDK build 2600
|
||||
|
||||
__inline void GET_TIME(struct timeval *dst, struct time_conv *data)
|
||||
{
|
||||
return;
|
||||
|
||||
#if 0
|
||||
//
|
||||
// This timestamp mode is supported on x86 (32 bit) only
|
||||
//
|
||||
#ifdef __NPF_x86__
|
||||
if ( TimestampMode == TIMESTAMPMODE_RDTSC )
|
||||
{
|
||||
GetTimeRDTSC(dst,data);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ( TimestampMode == TIMESTAMPMODE_QUERYSYSTEMTIME )
|
||||
{
|
||||
GetTimeQST(dst,data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetTimeKQPC(dst,data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#else /*WIN_NT_DRIVER*/
|
||||
|
||||
__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest)
|
||||
{
|
||||
dest->start[0]=*src;
|
||||
}
|
||||
|
||||
__inline void GET_TIME(struct timeval *dst, struct time_conv *data)
|
||||
{
|
||||
return;
|
||||
*dst=data->start[0];
|
||||
}
|
||||
|
||||
#endif /*WIN_NT_DRIVER*/
|
||||
|
||||
|
||||
#endif /*_time_calls*/
|
||||
385
src/See/tme.c
Normal file
385
src/See/tme.c
Normal file
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#include "tme.h"
|
||||
|
||||
/* resizes extended memory */
|
||||
uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex)
|
||||
{
|
||||
uint8 *tmp;
|
||||
|
||||
if ((mem_ex==NULL)||(mem_ex->buffer==NULL)||(size==0))
|
||||
return TME_ERROR; /* awfully never reached!!!! */
|
||||
|
||||
tmp=mem_ex->buffer;
|
||||
mem_ex->buffer=NULL;
|
||||
FREE_MEMORY(tmp);
|
||||
|
||||
ALLOCATE_MEMORY(tmp,uint8,size);
|
||||
if (tmp==NULL)
|
||||
return TME_ERROR; /* no memory */
|
||||
|
||||
mem_ex->size=size;
|
||||
mem_ex->buffer=tmp;
|
||||
return TME_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/* activates a block of the TME */
|
||||
uint32 set_active_tme_block(TME_CORE *tme, uint32 block)
|
||||
{
|
||||
|
||||
if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block)))
|
||||
return TME_ERROR;
|
||||
tme->active=block;
|
||||
tme->working=block;
|
||||
return TME_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/* simply inserts default values in a TME block */
|
||||
/* it DOESN'T initialize the block in the core!! */
|
||||
/* FIXME default values are defined at compile time, */
|
||||
/* it will be useful to store them in the registry */
|
||||
uint32 init_tme_block(TME_CORE *tme, uint32 block)
|
||||
{
|
||||
|
||||
TME_DATA *data;
|
||||
if (block>=MAX_TME_DATA_BLOCKS)
|
||||
return TME_ERROR;
|
||||
data=&(tme->block_data[block]);
|
||||
tme->working=block;
|
||||
|
||||
ZERO_MEMORY(data,sizeof(TME_DATA));
|
||||
|
||||
/* entries in LUT */
|
||||
data->lut_entries=TME_LUT_ENTRIES_DEFAULT;
|
||||
/* blocks */
|
||||
data->shared_memory_blocks=TME_SHARED_MEMORY_BLOCKS_DEFAULT;
|
||||
/* block size */
|
||||
data->block_size=TME_BLOCK_SIZE_DEFAULT;
|
||||
/* lookup function */
|
||||
data->lookup_code=lut_fcn_mapper(TME_LOOKUP_CODE_DEFAULT);
|
||||
/* rehashing value */
|
||||
data->rehashing_value=TME_REHASHING_VALUE_DEFAULT;
|
||||
/* out lut function */
|
||||
data->out_lut_exec=TME_OUT_LUT_EXEC_DEFAULT;
|
||||
/* default function */
|
||||
data->default_exec=TME_DEFAULT_EXEC_DEFAULT;
|
||||
/* extra segment size */
|
||||
data->extra_segment_size=TME_EXTRA_SEGMENT_SIZE_DEFAULT;
|
||||
|
||||
|
||||
data->enable_deletion=FALSE;
|
||||
data->last_read.tv_sec=0;
|
||||
data->last_read.tv_usec=0;
|
||||
return TME_SUCCESS;
|
||||
|
||||
}
|
||||
/* it validates a TME block and */
|
||||
/* (on OK) inserts the block in the core */
|
||||
uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset)
|
||||
{
|
||||
uint32 required_memory;
|
||||
uint8 *base=mem_ex_offset+mem_ex->buffer;
|
||||
TME_DATA *data;
|
||||
|
||||
/* FIXME soluzione un po' posticcia... */
|
||||
if (mem_ex_offset==0)
|
||||
return TME_ERROR;
|
||||
|
||||
if (block>=MAX_TME_DATA_BLOCKS)
|
||||
return TME_ERROR;
|
||||
data=&tme->block_data[block];
|
||||
|
||||
if (data->lut_entries==0)
|
||||
return TME_ERROR;
|
||||
|
||||
if (data->key_len==0)
|
||||
return TME_ERROR;
|
||||
|
||||
if (data->shared_memory_blocks==0)
|
||||
return TME_ERROR;
|
||||
|
||||
if (data->block_size==0)
|
||||
return TME_ERROR;
|
||||
|
||||
/* checks if the lookup function is valid */
|
||||
if (data->lookup_code==NULL)
|
||||
return TME_ERROR;
|
||||
|
||||
/* checks if the out lut exec function is valid */
|
||||
if (exec_fcn_mapper(data->out_lut_exec)==NULL)
|
||||
return TME_ERROR;
|
||||
|
||||
/* checks if the default exec function is valid */
|
||||
if (exec_fcn_mapper(data->default_exec)==NULL)
|
||||
return TME_ERROR;
|
||||
|
||||
/* let's calculate memory needed */
|
||||
required_memory=data->lut_entries*sizeof(RECORD); /*LUT*/
|
||||
required_memory+=data->block_size*data->shared_memory_blocks; /*shared segment*/
|
||||
required_memory+=data->extra_segment_size; /*extra segment*/
|
||||
|
||||
if (required_memory>(mem_ex->size-mem_ex_offset))
|
||||
return TME_ERROR; /*not enough memory*/
|
||||
|
||||
/* the TME block can be initialized */
|
||||
ZERO_MEMORY(base,required_memory);
|
||||
|
||||
data->lut_base_address=base;
|
||||
|
||||
data->shared_memory_base_address=
|
||||
data->lut_base_address+
|
||||
data->lut_entries*sizeof(RECORD);
|
||||
|
||||
data->extra_segment_base_address=
|
||||
data->shared_memory_base_address+
|
||||
data->block_size*data->shared_memory_blocks;
|
||||
data->filled_blocks=1;
|
||||
VALIDATE(tme->validated_blocks,block);
|
||||
tme->active=block;
|
||||
tme->working=block;
|
||||
return TME_SUCCESS;
|
||||
}
|
||||
|
||||
/* I/F between the bpf machine and the callbacks, just some checks */
|
||||
uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref)
|
||||
{
|
||||
if (tme->active==TME_NONE_ACTIVE)
|
||||
return TME_FALSE;
|
||||
|
||||
return (tme->block_data[tme->active].lookup_code)(mem_ex_offset+mem_ex->buffer,&tme->block_data[tme->active],mem_ex, time_ref);
|
||||
}
|
||||
|
||||
/* I/F between the bpf machine and the callbacks, just some checks */
|
||||
uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size, uint32 offset)
|
||||
{
|
||||
|
||||
exec_fcn tmp;
|
||||
TME_DATA *data;
|
||||
uint8 *block;
|
||||
uint8 *mem_data;
|
||||
|
||||
if (tme->active==TME_NONE_ACTIVE)
|
||||
return TME_ERROR;
|
||||
|
||||
data=&tme->block_data[tme->active];
|
||||
|
||||
if (data->last_found==NULL)
|
||||
{ /*out lut exec */
|
||||
tmp=exec_fcn_mapper(data->out_lut_exec);
|
||||
block=data->shared_memory_base_address;
|
||||
}
|
||||
else
|
||||
{ /*checks if last_found is valid */
|
||||
if ((data->last_found<data->lut_base_address)||(data->last_found>=data->shared_memory_base_address))
|
||||
return TME_ERROR;
|
||||
else
|
||||
{
|
||||
tmp=exec_fcn_mapper(SW_ULONG_AT(&((RECORD*)data->last_found)->exec_fcn,0));
|
||||
if (tmp==NULL)
|
||||
return TME_ERROR;
|
||||
block=SW_ULONG_AT(&((RECORD*)data->last_found)->block,0)+mem_ex->buffer;
|
||||
if ((block<data->shared_memory_base_address)||(block>=data->extra_segment_base_address))
|
||||
return TME_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset>=mem_ex->size)
|
||||
return TME_ERROR;
|
||||
|
||||
mem_data=mem_ex->buffer+offset;
|
||||
|
||||
return tmp(block,pkt_size,data,mem_ex,mem_data);
|
||||
}
|
||||
|
||||
/*resets all the TME core*/
|
||||
uint32 reset_tme(TME_CORE *tme)
|
||||
{
|
||||
if (tme==NULL)
|
||||
return TME_ERROR;
|
||||
ZERO_MEMORY(tme, sizeof(TME_CORE));
|
||||
return TME_SUCCESS;
|
||||
}
|
||||
|
||||
/* returns a register value of the active TME block */
|
||||
/* FIXME last found in maniera elegante e veloce ?!?! */
|
||||
uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval)
|
||||
{
|
||||
switch(rgstr)
|
||||
{
|
||||
case TME_LUT_ENTRIES:
|
||||
*rval=data->lut_entries;
|
||||
return TME_SUCCESS;
|
||||
case TME_MAX_FILL_STATE:
|
||||
*rval=data->max_fill_state;
|
||||
return TME_SUCCESS;
|
||||
case TME_REHASHING_VALUE:
|
||||
*rval=data->rehashing_value;
|
||||
return TME_SUCCESS;
|
||||
case TME_KEY_LEN:
|
||||
*rval=data->key_len;
|
||||
return TME_SUCCESS;
|
||||
case TME_SHARED_MEMORY_BLOCKS:
|
||||
*rval=data->shared_memory_blocks;
|
||||
return TME_SUCCESS;
|
||||
case TME_FILLED_ENTRIES:
|
||||
*rval=data->filled_entries;
|
||||
return TME_SUCCESS;
|
||||
case TME_BLOCK_SIZE:
|
||||
*rval=data->block_size;
|
||||
return TME_SUCCESS;
|
||||
case TME_EXTRA_SEGMENT_SIZE:
|
||||
*rval=data->extra_segment_size;
|
||||
return TME_SUCCESS;
|
||||
case TME_FILLED_BLOCKS:
|
||||
*rval=data->filled_blocks;
|
||||
return TME_SUCCESS;
|
||||
case TME_DEFAULT_EXEC:
|
||||
*rval=data->default_exec;
|
||||
return TME_SUCCESS;
|
||||
case TME_OUT_LUT_EXEC:
|
||||
*rval=data->out_lut_exec;
|
||||
return TME_SUCCESS;
|
||||
case TME_SHARED_MEMORY_BASE_ADDRESS:
|
||||
*rval=data->shared_memory_base_address-mem_ex->buffer;
|
||||
return TME_SUCCESS;
|
||||
case TME_LUT_BASE_ADDRESS:
|
||||
*rval=data->lut_base_address-mem_ex->buffer;
|
||||
return TME_SUCCESS;
|
||||
case TME_EXTRA_SEGMENT_BASE_ADDRESS:
|
||||
*rval=data->extra_segment_base_address-mem_ex->buffer;
|
||||
return TME_SUCCESS;
|
||||
case TME_LAST_FOUND_BLOCK:
|
||||
if (data->last_found==NULL)
|
||||
*rval=0;
|
||||
else
|
||||
*rval=data->last_found-mem_ex->buffer;
|
||||
return TME_SUCCESS;
|
||||
|
||||
default:
|
||||
return TME_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* sets a register value in the active block */
|
||||
/* FIXME last found in maniera elegante e veloce ?!?! */
|
||||
uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init)
|
||||
{ /* very very very dangerous!!!!!!!!!!! */
|
||||
lut_fcn tmp;
|
||||
switch(rgstr)
|
||||
{
|
||||
case TME_MAX_FILL_STATE:
|
||||
data->max_fill_state=value;
|
||||
return TME_SUCCESS;
|
||||
case TME_REHASHING_VALUE:
|
||||
data->rehashing_value=value;
|
||||
return TME_SUCCESS;
|
||||
case TME_FILLED_ENTRIES:
|
||||
data->filled_entries=value;
|
||||
return TME_SUCCESS;
|
||||
case TME_FILLED_BLOCKS:
|
||||
if (value<=data->shared_memory_blocks)
|
||||
{
|
||||
data->filled_blocks=value;
|
||||
return TME_SUCCESS;
|
||||
}
|
||||
else
|
||||
return TME_ERROR;
|
||||
case TME_DEFAULT_EXEC:
|
||||
data->default_exec=value;
|
||||
return TME_SUCCESS;
|
||||
case TME_OUT_LUT_EXEC:
|
||||
data->out_lut_exec=value;
|
||||
return TME_SUCCESS;
|
||||
case TME_LOOKUP_CODE:
|
||||
tmp=lut_fcn_mapper(value);
|
||||
if (tmp==NULL)
|
||||
return TME_ERROR;
|
||||
else
|
||||
data->lookup_code=tmp;
|
||||
return TME_SUCCESS;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (init)
|
||||
switch (rgstr)
|
||||
{
|
||||
|
||||
case TME_LUT_ENTRIES:
|
||||
data->lut_entries=value;
|
||||
return TME_SUCCESS;
|
||||
case TME_KEY_LEN:
|
||||
data->key_len=value;
|
||||
return TME_SUCCESS;
|
||||
case TME_SHARED_MEMORY_BLOCKS:
|
||||
data->shared_memory_blocks=value;
|
||||
return TME_SUCCESS;
|
||||
case TME_BLOCK_SIZE:
|
||||
data->block_size=value;
|
||||
return TME_SUCCESS;
|
||||
case TME_EXTRA_SEGMENT_SIZE:
|
||||
data->extra_segment_size=value;
|
||||
return TME_SUCCESS;
|
||||
default:
|
||||
return TME_ERROR;
|
||||
}
|
||||
else
|
||||
return TME_ERROR;
|
||||
|
||||
}
|
||||
|
||||
/* chooses the TME block for read */
|
||||
uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block)
|
||||
{
|
||||
|
||||
if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block)))
|
||||
return TME_ERROR;
|
||||
tme->active_read=block;
|
||||
return TME_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/* chooses if the autodeletion must be used */
|
||||
uint32 set_autodeletion(TME_DATA *data, uint32 value)
|
||||
{
|
||||
if (value==0) /* no autodeletion */
|
||||
data->enable_deletion=FALSE;
|
||||
else
|
||||
data->enable_deletion=TRUE;
|
||||
|
||||
return TME_SUCCESS;
|
||||
}
|
||||
174
src/See/tme.h
Normal file
174
src/See/tme.h
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __tme_include_
|
||||
#define __tme_include_
|
||||
|
||||
#ifdef WIN_NT_DRIVER
|
||||
#include "ndis.h"
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif /*WIN_NT_DRIVER*/
|
||||
|
||||
#include "memory_t.h"
|
||||
#include "time_calls.h"
|
||||
|
||||
|
||||
/* error codes */
|
||||
#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 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 IS_VALIDATED(src,index) (src&(1<<index))
|
||||
|
||||
#define VALIDATE(src,index) src|=(1<<index);
|
||||
|
||||
|
||||
#define FORCE_NO_DELETION(timestamp) (struct timeval*)(timestamp)->tv_sec=0x7fffffff;
|
||||
|
||||
/* TME callback prototypes */
|
||||
typedef uint32 (*lut_fcn)(uint8 *key, struct __TME_DATA *data,MEM_TYPE *mem_ex, struct time_conv *time_ref );
|
||||
typedef uint32 (*exec_fcn)(uint8 *block, uint32 pkt_size, struct __TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data);
|
||||
|
||||
/* DO NOT MODIFY THIS STRUCTURE!!!! GV */
|
||||
typedef struct __RECORD
|
||||
|
||||
{
|
||||
uint32 block;
|
||||
uint32 exec_fcn;
|
||||
}
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
} TME_CORE, *PTME_CORE;
|
||||
|
||||
static __inline int32 IS_DELETABLE(void *timestamp, TME_DATA *data)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* functions to manage TME */
|
||||
uint32 init_tme_block(TME_CORE *tme, uint32 block);
|
||||
uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset);
|
||||
uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref);
|
||||
uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size,uint32 offset);
|
||||
uint32 set_active_tme_block(TME_CORE *tme, uint32 block);
|
||||
uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex);
|
||||
uint32 reset_tme(TME_CORE *tme);
|
||||
uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval);
|
||||
uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init);
|
||||
uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block);
|
||||
uint32 set_autodeletion(TME_DATA *data, uint32 value);
|
||||
|
||||
/* function mappers */
|
||||
lut_fcn lut_fcn_mapper(uint32 index);
|
||||
exec_fcn exec_fcn_mapper(uint32 index);
|
||||
|
||||
#endif
|
||||
117
src/See/valid_insns.h
Normal file
117
src/See/valid_insns.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||
* Copyright (c) 2005 CACE Technologies, Davis (California)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
u_short valid_instructions[]=
|
||||
{
|
||||
BPF_RET|BPF_K,
|
||||
BPF_RET|BPF_A,
|
||||
BPF_LD|BPF_IMM,
|
||||
BPF_LDX|BPF_IMM,
|
||||
BPF_LD|BPF_MEM,
|
||||
BPF_LDX|BPF_MEM,
|
||||
|
||||
#ifdef __NPF_x86__
|
||||
BPF_LD|BPF_MEM_EX_IMM|BPF_B,
|
||||
BPF_LD|BPF_MEM_EX_IMM|BPF_H,
|
||||
BPF_LD|BPF_MEM_EX_IMM|BPF_W,
|
||||
BPF_LD|BPF_MEM_EX_IND|BPF_B,
|
||||
BPF_LD|BPF_MEM_EX_IND|BPF_H,
|
||||
BPF_LD|BPF_MEM_EX_IND|BPF_W,
|
||||
#endif
|
||||
BPF_LD|BPF_W|BPF_ABS,
|
||||
BPF_LD|BPF_H|BPF_ABS,
|
||||
BPF_LD|BPF_B|BPF_ABS,
|
||||
BPF_LDX|BPF_W|BPF_ABS,
|
||||
BPF_LDX|BPF_H|BPF_ABS,
|
||||
BPF_LDX|BPF_B|BPF_ABS,
|
||||
BPF_LD|BPF_W|BPF_LEN,
|
||||
BPF_LDX|BPF_W|BPF_LEN,
|
||||
BPF_LD|BPF_W|BPF_IND,
|
||||
BPF_LD|BPF_H|BPF_IND,
|
||||
BPF_LD|BPF_B|BPF_IND,
|
||||
BPF_LDX|BPF_MSH|BPF_B,
|
||||
BPF_ST,
|
||||
BPF_STX,
|
||||
|
||||
#ifdef __NPF_x86__
|
||||
BPF_ST|BPF_MEM_EX_IMM|BPF_B,
|
||||
BPF_STX|BPF_MEM_EX_IMM|BPF_B,
|
||||
BPF_ST|BPF_MEM_EX_IMM|BPF_W,
|
||||
BPF_STX|BPF_MEM_EX_IMM|BPF_W,
|
||||
BPF_ST|BPF_MEM_EX_IMM|BPF_H,
|
||||
BPF_STX|BPF_MEM_EX_IMM|BPF_H,
|
||||
BPF_ST|BPF_MEM_EX_IND|BPF_B,
|
||||
BPF_ST|BPF_MEM_EX_IND|BPF_W,
|
||||
BPF_ST|BPF_MEM_EX_IND|BPF_H,
|
||||
#endif
|
||||
|
||||
BPF_JMP|BPF_JA,
|
||||
BPF_JMP|BPF_JGT|BPF_K,
|
||||
BPF_JMP|BPF_JGE|BPF_K,
|
||||
BPF_JMP|BPF_JEQ|BPF_K,
|
||||
BPF_JMP|BPF_JSET|BPF_K,
|
||||
BPF_JMP|BPF_JGT|BPF_X,
|
||||
BPF_JMP|BPF_JGE|BPF_X,
|
||||
BPF_JMP|BPF_JEQ|BPF_X,
|
||||
BPF_JMP|BPF_JSET|BPF_X,
|
||||
BPF_ALU|BPF_ADD|BPF_X,
|
||||
BPF_ALU|BPF_SUB|BPF_X,
|
||||
BPF_ALU|BPF_MUL|BPF_X,
|
||||
BPF_ALU|BPF_DIV|BPF_X,
|
||||
BPF_ALU|BPF_AND|BPF_X,
|
||||
BPF_ALU|BPF_OR|BPF_X,
|
||||
BPF_ALU|BPF_LSH|BPF_X,
|
||||
BPF_ALU|BPF_RSH|BPF_X,
|
||||
BPF_ALU|BPF_ADD|BPF_K,
|
||||
BPF_ALU|BPF_SUB|BPF_K,
|
||||
BPF_ALU|BPF_MUL|BPF_K,
|
||||
BPF_ALU|BPF_DIV|BPF_K,
|
||||
BPF_ALU|BPF_AND|BPF_K,
|
||||
BPF_ALU|BPF_OR|BPF_K,
|
||||
BPF_ALU|BPF_LSH|BPF_K,
|
||||
BPF_ALU|BPF_RSH|BPF_K,
|
||||
BPF_ALU|BPF_NEG,
|
||||
BPF_MISC|BPF_TAX,
|
||||
BPF_MISC|BPF_TXA,
|
||||
|
||||
#ifdef __NPF_x86__
|
||||
BPF_MISC|BPF_TME|BPF_LOOKUP,
|
||||
BPF_MISC|BPF_TME|BPF_EXECUTE,
|
||||
BPF_MISC|BPF_TME|BPF_SET_ACTIVE,
|
||||
BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE,
|
||||
BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#define VALID_INSTRUCTIONS_LEN (sizeof(valid_instructions)/sizeof(u_short))
|
||||
417
src/See/win_bpf.h
Normal file
417
src/See/win_bpf.h
Normal file
@ -0,0 +1,417 @@
|
||||
/*-
|
||||
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
||||
* 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
|
||||
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
|
||||
* Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
|
||||
*
|
||||
* @(#) $Header: /usr/cvsroot_private/winpcap/packetNtx/driver/win_bpf.h,v 1.2.2.1 2005/12/02 22:12:58 gianlucav Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#ifndef BPF_MAJOR_VERSION
|
||||
|
||||
/* BSD style release date */
|
||||
#define BPF_RELEASE 199606
|
||||
|
||||
#ifdef WIN_NT_DRIVER
|
||||
#include <ndis.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "tme.h"
|
||||
#include "time_calls.h"
|
||||
|
||||
typedef UCHAR u_char;
|
||||
typedef USHORT u_short;
|
||||
|
||||
#ifdef WIN_NT_DRIVER
|
||||
typedef ULONG u_int;
|
||||
#endif
|
||||
|
||||
typedef LONG bpf_int32;
|
||||
typedef ULONG bpf_u_int32;
|
||||
typedef ULONG u_int32;
|
||||
|
||||
#define BPF_MAXINSNS 512
|
||||
#define BPF_MAXBUFSIZE 0x8000
|
||||
#define BPF_MINBUFSIZE 32
|
||||
|
||||
/*
|
||||
* The instruction data structure.
|
||||
*/
|
||||
struct bpf_insn {
|
||||
u_short code;
|
||||
u_char jt;
|
||||
u_char jf;
|
||||
bpf_u_int32 k;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for BIOCSETF.
|
||||
*/
|
||||
struct bpf_program {
|
||||
u_int bf_len;
|
||||
struct bpf_insn *bf_insns;
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct returned by BIOCGSTATS.
|
||||
*/
|
||||
struct bpf_stat {
|
||||
UINT bs_recv; ///< Number of packets that the driver received from the network adapter
|
||||
///< from the beginning of the current capture. This value includes the packets
|
||||
///< lost by the driver.
|
||||
UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture.
|
||||
///< Basically, a packet is lost when the the buffer of the driver is full.
|
||||
///< In this situation the packet cannot be stored and the driver rejects it.
|
||||
UINT ps_ifdrop; ///< drops by interface. XXX not yet supported
|
||||
UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and
|
||||
///< thus reach the application.
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct return by BIOCVERSION. This represents the version number of
|
||||
* the filter language described by the instruction encodings below.
|
||||
* bpf understands a program iff kernel_major == filter_major &&
|
||||
* kernel_minor >= filter_minor, that is, if the value returned by the
|
||||
* running kernel has the same major number and a minor number equal
|
||||
* equal to or less than the filter being downloaded. Otherwise, the
|
||||
* results are undefined, meaning an error may be returned or packets
|
||||
* may be accepted haphazardly.
|
||||
* It has nothing to do with the source code version.
|
||||
*/
|
||||
struct bpf_version {
|
||||
u_short bv_major;
|
||||
u_short bv_minor;
|
||||
};
|
||||
/* Current version number of filter architecture. */
|
||||
#define BPF_MAJOR_VERSION 1
|
||||
#define BPF_MINOR_VERSION 1
|
||||
|
||||
|
||||
/*
|
||||
* 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) */
|
||||
};
|
||||
|
||||
/*
|
||||
* Data-link level type codes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These are the types that are the same on all platforms; on other
|
||||
* platforms, a <net/bpf.h> should be supplied that defines the additional
|
||||
* DLT_* codes appropriately for that platform (the BSDs, for example,
|
||||
* should not just pick up this version of "bpf.h"; they should also define
|
||||
* the additional DLT_* codes used by their kernels, as well as the values
|
||||
* defined here - and, if the values they use for particular DLT_ types
|
||||
* 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 */
|
||||
|
||||
/*
|
||||
* These are values from the traditional libpcap "bpf.h".
|
||||
* Ports of this to particular platforms should replace these definitions
|
||||
* 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 */
|
||||
|
||||
/*
|
||||
* These are values from BSD/OS's "bpf.h".
|
||||
* These are not the same as the values from the traditional libpcap
|
||||
* "bpf.h"; however, these values shouldn't be generated by any
|
||||
* OS other than BSD/OS, so the correct values to use here are the
|
||||
* BSD/OS values.
|
||||
*
|
||||
* Platforms that have already assigned these values to other
|
||||
* DLT_ codes, however, should give these codes the values
|
||||
* from that platform, so that programs that use these codes will
|
||||
* 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_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 */
|
||||
|
||||
/*
|
||||
* This value was defined by libpcap 0.5; platforms that have defined
|
||||
* it with a different value should define it here with that value -
|
||||
* a link type of 104 in a save file will be mapped to DLT_C_HDLC,
|
||||
* whatever value that happens to be, so programs will correctly
|
||||
* handle files with that link type regardless of the value of
|
||||
* DLT_C_HDLC.
|
||||
*
|
||||
* The name DLT_C_HDLC was used by BSD/OS; we use that name for source
|
||||
* compatibility with programs written for BSD/OS.
|
||||
*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* Reserved for future use.
|
||||
* Do not pick other numerical value for these unless you have also
|
||||
* picked up the tcpdump.org top-of-CVS-tree version of "savefile.c",
|
||||
* which will arrange that capture files for these DLT_ types have
|
||||
* the same "network" value on all platforms, regardless of what
|
||||
* value is chosen for their DLT_ type (thus allowing captures made
|
||||
* 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 */
|
||||
|
||||
/*
|
||||
* Values between 106 and 107 are used in capture file headers as
|
||||
* link-layer types corresponding to DLT_ types that might differ
|
||||
* between platforms; don't use those values for new DLT_ new types.
|
||||
*/
|
||||
|
||||
/*
|
||||
* OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
|
||||
* that the AF_ type in the link-layer header is in network byte order.
|
||||
*
|
||||
* OpenBSD defines it as 12, but that collides with DLT_RAW, so we
|
||||
* define it as 108 here. If OpenBSD picks up this file, it should
|
||||
* 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
|
||||
|
||||
/*
|
||||
* Values between 109 and 112 are used in capture file headers as
|
||||
* link-layer types corresponding to DLT_ types that might differ
|
||||
* between platforms; don't use those values for new DLT_ new types.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is for Linux cooked sockets.
|
||||
*/
|
||||
#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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* ret - BPF_K and BPF_X also apply */
|
||||
#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
|
||||
|
||||
/* TME instructions */
|
||||
#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_MEM_EX_IMM 0xc0
|
||||
#define BPF_MEM_EX_IND 0xe0
|
||||
/*used for ST */
|
||||
#define BPF_MEM_EX 0xc0
|
||||
|
||||
|
||||
/*
|
||||
* Macros for insn array initializers.
|
||||
*/
|
||||
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
|
||||
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
|
||||
|
||||
/*
|
||||
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
|
||||
*/
|
||||
#define BPF_MEMWORDS 16
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\brief Validates a filtering program arriving from the user-level app.
|
||||
\param f The filter.
|
||||
\param len Its length, in pseudo instructions.
|
||||
\param mem_ex_size The length of the extended memory, used to validate LD/ST to that memory
|
||||
\return true if f is a valid filter program..
|
||||
|
||||
The kernel needs to be able to verify an application's filter code. Otherwise, a bogus program could easily
|
||||
crash the system.
|
||||
This function returns true if f is a valid filter program. The constraints are that each jump be forward and
|
||||
to a valid code. The code must terminate with either an accept or reject.
|
||||
*/
|
||||
int32 bpf_validate(struct bpf_insn *f,int32 len, uint32 mem_ex_size);
|
||||
|
||||
/*!
|
||||
\brief The filtering pseudo-machine interpreter.
|
||||
\param pc The filter.
|
||||
\param p Pointer to a memory buffer containing the packet on which the filter will be executed.
|
||||
\param wirelen Original length of the packet.
|
||||
\param buflen Current length of the packet. In some cases (for example when the transfer of the packet to the RAM
|
||||
has not yet finished), bpf_filter can be executed on a portion of the packet.
|
||||
\param mem_ex The extended memory.
|
||||
\param tme The virtualization of the TME co-processor
|
||||
\param time_ref Data structure needed by the TME co-processor to timestamp data
|
||||
\return The portion of the packet to keep, in bytes. 0 means that the packet must be rejected, -1 means that
|
||||
the whole packet must be kept.
|
||||
|
||||
\note this function is not used in normal situations, because the jitter creates a native filtering function
|
||||
that is faster than the interpreter.
|
||||
*/
|
||||
u_int bpf_filter(register struct bpf_insn *pc,
|
||||
register UCHAR *p,
|
||||
u_int wirelen,
|
||||
register u_int 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(),
|
||||
but works correctly also if the MAC header and the data of the packet are in two different buffers.
|
||||
\param pc The filter.
|
||||
\param p Pointer to a memory buffer containing the MAC header of the packet.
|
||||
\param pd Pointer to a memory buffer containing the data of the packet.
|
||||
\param wirelen Original length of the packet.
|
||||
\param buflen Current length of the packet. In some cases (for example when the transfer of the packet to the RAM
|
||||
has not yet finished), bpf_filter can be executed on a portion of the packet.
|
||||
\param mem_ex The extended memory.
|
||||
\param tme The virtualization of the TME co-processor
|
||||
\param time_ref Data structure needed by the TME co-processor to timestamp data
|
||||
\return The portion of the packet to keep, in bytes. 0 means that the packet must be rejected, -1 means that
|
||||
the whole packet must be kept.
|
||||
|
||||
This function is used when NDIS passes the packet to NPF_tap() in two buffers instaed than in a single one.
|
||||
*/
|
||||
u_int bpf_filter_with_2_buffers(register struct bpf_insn *pc,
|
||||
register u_char *p,
|
||||
register u_char *pd,
|
||||
register int headersize,
|
||||
u_int wirelen,
|
||||
register u_int buflen,
|
||||
PMEM_TYPE mem_ex,
|
||||
PTME_CORE tme,
|
||||
struct time_conv *time_ref);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
1086
src/See/win_bpf_filter.c
Normal file
1086
src/See/win_bpf_filter.c
Normal file
File diff suppressed because it is too large
Load Diff
509
src/See/win_bpf_filter_init.c
Normal file
509
src/See/win_bpf_filter_init.c
Normal file
@ -0,0 +1,509 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <GlobalConst.h>
|
||||
|
||||
#include "tme.h"
|
||||
#include "win_bpf.h"
|
||||
|
||||
/*
|
||||
* Initialize the filter machine
|
||||
*/
|
||||
uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref)
|
||||
{
|
||||
register uint32 A, X;
|
||||
int32 mem[BPF_MEMWORDS];
|
||||
register int32 k;
|
||||
uint32 *tmp;
|
||||
uint16 *tmp2;
|
||||
uint32 j;
|
||||
if (pc == 0)
|
||||
/*
|
||||
* No filter means accept all.
|
||||
*/
|
||||
return (uint32)-1;
|
||||
A = 0;
|
||||
X = 0;
|
||||
--pc;
|
||||
while (1) {
|
||||
++pc;
|
||||
switch (pc->code) {
|
||||
|
||||
default:
|
||||
return 0;
|
||||
|
||||
/* RET INSTRUCTIONS */
|
||||
case BPF_RET|BPF_K:
|
||||
return (uint32)pc->k;
|
||||
|
||||
case BPF_RET|BPF_A:
|
||||
return (uint32)A;
|
||||
/* END RET INSTRUCTIONS */
|
||||
|
||||
/* LD NO PACKET INSTRUCTIONS */
|
||||
case BPF_LD|BPF_IMM:
|
||||
A = pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_LDX|BPF_IMM:
|
||||
X = pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_LD|BPF_MEM:
|
||||
A = mem[pc->k];
|
||||
continue;
|
||||
|
||||
case BPF_LDX|BPF_MEM:
|
||||
X = mem[pc->k];
|
||||
continue;
|
||||
|
||||
case BPF_LD|BPF_MEM_EX_IMM|BPF_B:
|
||||
A= mem_ex->buffer[pc->k];
|
||||
continue;
|
||||
|
||||
case BPF_LDX|BPF_MEM_EX_IMM|BPF_B:
|
||||
X= mem_ex->buffer[pc->k];
|
||||
continue;
|
||||
|
||||
case BPF_LD|BPF_MEM_EX_IMM|BPF_H:
|
||||
tmp2=(uint16*)&mem_ex->buffer[pc->k];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx,tmp2
|
||||
xor eax, eax
|
||||
mov ax, [ebx]
|
||||
bswap eax
|
||||
mov A, eax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
|
||||
case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
|
||||
tmp2=(uint16*)&mem_ex->buffer[pc->k];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx,tmp2
|
||||
xor eax, eax
|
||||
mov ax, [ebx]
|
||||
bswap eax
|
||||
mov X, eax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
|
||||
case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
|
||||
tmp=(uint32*)&mem_ex->buffer[pc->k];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx,tmp
|
||||
mov eax, [ebx]
|
||||
bswap eax
|
||||
mov A, eax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
|
||||
case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
|
||||
tmp=(uint32*)&mem_ex->buffer[pc->k];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx,tmp
|
||||
mov eax, [ebx]
|
||||
bswap eax
|
||||
mov X, eax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
|
||||
case BPF_LD|BPF_MEM_EX_IND|BPF_B:
|
||||
k = X + pc->k;
|
||||
if ((int32)k>= (int32)mem_ex->size) {
|
||||
return 0;
|
||||
}
|
||||
A= mem_ex->buffer[k];
|
||||
continue;
|
||||
|
||||
case BPF_LD|BPF_MEM_EX_IND|BPF_H:
|
||||
k = X + pc->k;
|
||||
if ((int32)(k+1)>= (int32)mem_ex->size) {
|
||||
return 0;
|
||||
}
|
||||
tmp2=(uint16*)&mem_ex->buffer[k];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx,tmp2
|
||||
xor eax, eax
|
||||
mov ax, [ebx]
|
||||
bswap eax
|
||||
mov A, eax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
|
||||
case BPF_LD|BPF_MEM_EX_IND|BPF_W:
|
||||
k = X + pc->k;
|
||||
if ((int32)(k+3)>= (int32)mem_ex->size) {
|
||||
return 0;
|
||||
}
|
||||
tmp=(uint32*)&mem_ex->buffer[k];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx,tmp
|
||||
mov eax, [ebx]
|
||||
bswap eax
|
||||
mov A, eax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
/* END LD NO PACKET INSTRUCTIONS */
|
||||
|
||||
/* STORE INSTRUCTIONS */
|
||||
case BPF_ST:
|
||||
mem[pc->k] = A;
|
||||
continue;
|
||||
|
||||
case BPF_STX:
|
||||
mem[pc->k] = X;
|
||||
continue;
|
||||
|
||||
case BPF_ST|BPF_MEM_EX_IMM|BPF_B:
|
||||
mem_ex->buffer[pc->k]=(uint8)A;
|
||||
continue;
|
||||
|
||||
case BPF_STX|BPF_MEM_EX_IMM|BPF_B:
|
||||
mem_ex->buffer[pc->k]=(uint8)X;
|
||||
continue;
|
||||
|
||||
case BPF_ST|BPF_MEM_EX_IMM|BPF_W:
|
||||
tmp=(uint32*)&mem_ex->buffer[pc->k];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx, tmp
|
||||
mov eax, A
|
||||
bswap eax
|
||||
mov [ebx], eax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
|
||||
case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
|
||||
tmp=(uint32*)&mem_ex->buffer[pc->k];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx, tmp
|
||||
mov eax, X
|
||||
bswap eax
|
||||
mov [ebx], eax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
|
||||
case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
|
||||
tmp2=(uint16*)&mem_ex->buffer[pc->k];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx, tmp2
|
||||
mov eax, A
|
||||
xchg ah, al
|
||||
mov [ebx], ax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
|
||||
case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
|
||||
tmp2=(uint16*)&mem_ex->buffer[pc->k];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx, tmp2
|
||||
mov eax, X
|
||||
xchg ah, al
|
||||
mov [ebx], ax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
|
||||
case BPF_ST|BPF_MEM_EX_IND|BPF_B:
|
||||
mem_ex->buffer[pc->k+X]=(uint8)A;
|
||||
|
||||
case BPF_ST|BPF_MEM_EX_IND|BPF_W:
|
||||
tmp=(uint32*)&mem_ex->buffer[pc->k+X];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx, tmp
|
||||
mov eax, A
|
||||
bswap eax
|
||||
mov [ebx], eax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
case BPF_ST|BPF_MEM_EX_IND|BPF_H:
|
||||
tmp2=(uint16*)&mem_ex->buffer[pc->k+X];
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push ebx
|
||||
mov ebx, tmp2
|
||||
mov eax, A
|
||||
xchg ah, al
|
||||
mov [ebx], ax
|
||||
pop ebx
|
||||
pop eax
|
||||
}
|
||||
continue;
|
||||
/* END STORE INSTRUCTIONS */
|
||||
|
||||
/* JUMP INSTRUCTIONS */
|
||||
case BPF_JMP|BPF_JA:
|
||||
pc += pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_JMP|BPF_JGT|BPF_K:
|
||||
pc += ((int32)A > (int32)pc->k) ? pc->jt : pc->jf;
|
||||
continue;
|
||||
|
||||
case BPF_JMP|BPF_JGE|BPF_K:
|
||||
pc += ((int32)A >= (int32)pc->k) ? pc->jt : pc->jf;
|
||||
continue;
|
||||
|
||||
case BPF_JMP|BPF_JEQ|BPF_K:
|
||||
pc += ((int32)A == (int32)pc->k) ? pc->jt : pc->jf;
|
||||
continue;
|
||||
|
||||
case BPF_JMP|BPF_JSET|BPF_K:
|
||||
pc += (A & pc->k) ? pc->jt : pc->jf;
|
||||
continue;
|
||||
|
||||
case BPF_JMP|BPF_JGT|BPF_X:
|
||||
pc += (A > X) ? pc->jt : pc->jf;
|
||||
continue;
|
||||
|
||||
case BPF_JMP|BPF_JGE|BPF_X:
|
||||
pc += (A >= X) ? pc->jt : pc->jf;
|
||||
continue;
|
||||
|
||||
case BPF_JMP|BPF_JEQ|BPF_X:
|
||||
pc += (A == X) ? pc->jt : pc->jf;
|
||||
continue;
|
||||
|
||||
case BPF_JMP|BPF_JSET|BPF_X:
|
||||
pc += (A & X) ? pc->jt : pc->jf;
|
||||
continue;
|
||||
/* END JUMP INSTRUCTIONS */
|
||||
|
||||
/* ARITHMETIC INSTRUCTIONS */
|
||||
case BPF_ALU|BPF_ADD|BPF_X:
|
||||
A += X;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_SUB|BPF_X:
|
||||
A -= X;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_MUL|BPF_X:
|
||||
A *= X;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_DIV|BPF_X:
|
||||
if (X == 0)
|
||||
return 0;
|
||||
A /= X;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_AND|BPF_X:
|
||||
A &= X;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_OR|BPF_X:
|
||||
A |= X;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_LSH|BPF_X:
|
||||
A <<= X;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_RSH|BPF_X:
|
||||
A >>= X;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_ADD|BPF_K:
|
||||
A += pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_SUB|BPF_K:
|
||||
A -= pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_MUL|BPF_K:
|
||||
A *= pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_DIV|BPF_K:
|
||||
A /= pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_AND|BPF_K:
|
||||
A &= pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_OR|BPF_K:
|
||||
A |= pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_LSH|BPF_K:
|
||||
A <<= pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_RSH|BPF_K:
|
||||
A >>= pc->k;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_NEG:
|
||||
(int32)A = -((int32)A);
|
||||
continue;
|
||||
/* ARITHMETIC INSTRUCTIONS */
|
||||
|
||||
/* MISC INSTRUCTIONS */
|
||||
case BPF_MISC|BPF_TAX:
|
||||
X = A;
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TXA:
|
||||
A = X;
|
||||
continue;
|
||||
/* END MISC INSTRUCTIONS */
|
||||
|
||||
/* TME INSTRUCTIONS */
|
||||
case BPF_MISC|BPF_TME|BPF_LOOKUP:
|
||||
j=lookup_frontend(mem_ex,tme,pc->k,time_ref);
|
||||
if (j==TME_ERROR)
|
||||
return 0;
|
||||
pc += (j == TME_TRUE) ? pc->jt : pc->jf;
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TME|BPF_EXECUTE:
|
||||
if (execute_frontend(mem_ex,tme,0,pc->k)==TME_ERROR)
|
||||
return 0;
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TME|BPF_INIT:
|
||||
if (init_tme_block(tme,pc->k)==TME_ERROR)
|
||||
return 0;
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TME|BPF_VALIDATE:
|
||||
if (validate_tme_block(mem_ex,tme,A,pc->k)==TME_ERROR)
|
||||
return 0;
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TME|BPF_SET_MEMORY:
|
||||
if (init_extended_memory(pc->k,mem_ex)==TME_ERROR)
|
||||
return 0;
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TME|BPF_SET_ACTIVE:
|
||||
if (set_active_tme_block(tme,pc->k)==TME_ERROR)
|
||||
return 0;
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TME|BPF_SET_ACTIVE_READ:
|
||||
if (set_active_tme_block(tme,pc->k)==TME_ERROR)
|
||||
return 0;
|
||||
continue;
|
||||
case BPF_MISC|BPF_TME|BPF_SET_WORKING:
|
||||
if (pc->k>=MAX_TME_DATA_BLOCKS)
|
||||
return 0;
|
||||
tme->working=pc->k;
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
case BPF_MISC|BPF_TME|BPF_RESET:
|
||||
if (reset_tme(tme)==TME_ERROR)
|
||||
return 0;
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE:
|
||||
if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR)
|
||||
return 0;
|
||||
A=j;
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE:
|
||||
if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,TRUE)==TME_ERROR)
|
||||
return 0;
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TME|BPF_SET_AUTODELETION:
|
||||
set_autodeletion(&tme->block_data[tme->working],pc->k);
|
||||
continue;
|
||||
|
||||
/* END TME INSTRUCTIONS */
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
50
src/See/win_bpf_filter_init.h
Normal file
50
src/See/win_bpf_filter_init.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2001 - 2003
|
||||
* NetGroup, Politecnico di Torino (Italy)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FILTER_INIT
|
||||
#define __FILTER_INIT
|
||||
|
||||
#include "tme.h"
|
||||
|
||||
#define INIT_OK 1
|
||||
#define INIT_ERROR 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
uint32 bpf_filter_init(register struct bpf_insn *pc,MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user