<directory name="ndis">
<xi:include href="ndis/ndis.xml" />
</directory>
-<directory name="npf">
- <xi:include href="npf/npf.xml" />
-</directory>
<directory name="tcpip">
<xi:include href="tcpip/tcpip.xml" />
</directory>
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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;
- }
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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
-
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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;
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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
-
+++ /dev/null
-/*
- * Copyright (c) 1999, 2000
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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*/
+++ /dev/null
-/*
- * Copyright (c) 1999, 2000
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifdef _MSC_VER
-#include "stdarg.h"
-#include "ntddk.h"
-#include "ntiologc.h"
-#include "ndis.h"
-#else
-#include <ntddk.h>
-#include <ndis.h>
-//#define PsGetCurrentProcess() IoGetCurrentProcess()
-#ifndef PsGetCurrentThread
-#define PsGetCurrentThread() ((PETHREAD) (KeGetCurrentThread()))
-#endif
-#endif
-
-#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
-
-#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 = NULL;
- 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;
-
-#define NPF_TAG_FILENAME TAG('0', 'D', 'W', 'A')
- FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
- FullFileNameLength,
- NPF_TAG_FILENAME);
-
- if (FullFileName.Buffer == NULL) {
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- return ntStatus;
- }
-
- FullFileName.Length = PathLen;
- FullFileName.MaximumLength = (USHORT)FullFileNameLength;
-
- if(PathLen)
- RtlMoveMemory (FullFileName.Buffer, PathPrefix, PathLen);
-
- RtlAppendUnicodeStringToString (&FullFileName, fileName);
-
- IF_LOUD(DbgPrint( "Packet: Attempting to open %wZ\n", &FullFileName);)
-
- InitializeObjectAttributes ( &ObjectAttributes,
- &FullFileName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL );
-
- // Create the dump file
- ntStatus = ZwCreateFile( &Open->DumpFileHandle,
- SYNCHRONIZE | FILE_WRITE_DATA,
- &ObjectAttributes,
- &IoStatus,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ,
- (Append)?FILE_OPEN_IF:FILE_SUPERSEDE,
- FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0 );
-
- if ( !NT_SUCCESS( ntStatus ) )
- {
- IF_LOUD(DbgPrint("NPF: Error opening file %x\n", ntStatus);)
-
- ExFreePool(FullFileName.Buffer);
- Open->DumpFileHandle=NULL;
- ntStatus = STATUS_NO_SUCH_FILE;
- return ntStatus;
- }
-
- ExFreePool(FullFileName.Buffer);
-
- ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle,
- FILE_WRITE_ACCESS,
-#ifndef __GNUC__
- *IoFileObjectType,
-#else
- IoFileObjectType,
-#endif
- KernelMode,
- (PVOID)&Open->DumpFileObject,
- 0);
-
- if ( !NT_SUCCESS( ntStatus ) )
- {
- IF_LOUD(DbgPrint("NPF: Error creating file, status=%x\n", ntStatus);)
-
- ZwClose( Open->DumpFileHandle );
- Open->DumpFileHandle=NULL;
-
- 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,
- (PKSTART_ROUTINE)NPF_DumpThread,
- Open);
-
- if ( !NT_SUCCESS( ntStatus ) )
- {
- IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);)
-
- ZwClose( Open->DumpFileHandle );
- Open->DumpFileHandle=NULL;
-
- return ntStatus;
- }
- ntStatus = ObReferenceObjectByHandle(Open->DumpThreadHandle,
- THREAD_ALL_ACCESS,
- NULL,
- KernelMode,
- (PVOID*)&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)
-{
-
- 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->BufSize==0){ // BufSize=0 means that this instance was closed, or that the buffer is too
- // small for any capture. In both cases it is better to end the dump
-
- IF_LOUD(DbgPrint("NPF: Worker Thread - Exiting happily\n");)
- IF_LOUD(DbgPrint("Thread: Dumpoffset=%I64d\n",Open->DumpOffset.QuadPart);)
-
- 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)
-{
- UINT Thead;
- UINT Ttail;
- UINT TLastByte;
- PUCHAR CurrBuff;
- IO_STATUS_BLOCK IoStatus;
- PMDL lMdl;
- UINT SizeToDump;
-
-
- 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;
-
- }
-
- return STATUS_SUCCESS;
-}
-
-//-------------------------------------------------------------------
-
-NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open){
-
- 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);
-
- return STATUS_SUCCESS;
-}
-
-//-------------------------------------------------------------------
-
-#ifndef __GNUC__
-static NTSTATUS
-#else
-NTSTATUS STDCALL
-#endif
-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;
-}
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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;
-}
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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
-
+++ /dev/null
-/*
- * Copyright (c) 2002
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifdef _MSC_VER
-#include "stdarg.h"
-#include "ntddk.h"
-#include "ntiologc.h"
-#include "ndis.h"
-#else
-#include <ntddk.h>
-#include <ndis.h>
-#endif
-
-#include "packet.h"
-#include "win_bpf.h"
-
-#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
-
-emit_func emitm;
-
-//
-// 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;
-
-
- // Allocate the reference table for the jumps
-#ifdef NTKERNEL
-#define NPF_TAG_REFTABLE TAG('0', 'J', 'W', 'A')
- stream.refs=(UINT *)ExAllocatePoolWithTag(NonPagedPool, (nins + 1)*sizeof(UINT), NPF_TAG_REFTABLE);
-#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
-#define NPF_TAG_STREAMBUF TAG('1', 'J', 'W', 'A')
- stream.ibuf=(CHAR*)ExAllocatePoolWithTag(NonPagedPool, stream.cur_ip, NPF_TAG_STREAMBUF);
-#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
-#define NPF_TAG_FILTSTRUCT TAG('2', 'J', 'W', 'A')
- Filter=(struct JIT_BPF_Filter*)ExAllocatePoolWithTag(NonPagedPool, sizeof(struct JIT_BPF_Filter), NPF_TAG_FILTSTRUCT);
-#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
-#define NPF_TAG_FILTMEM TAG('3', 'J', 'W', 'A')
- Filter->mem=(INT*)ExAllocatePoolWithTag(NonPagedPool, BPF_MEMWORDS*sizeof(INT), NPF_TAG_FILTMEM);
-#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);
-
- return NULL;
-#endif
- }
-
- 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
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2002
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/** @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 (*BPF_filter_function)( binary_stream *, 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);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "tme.h"
-#include "memory_t.h"
-
-#ifdef _USE_SW_FUNCS_
-
-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);
-}
-
-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);
-}
-
-int16 SW_SHORT_AT(void *b, uint32 os)
-{
- return ((int16)
- ((int16)*((uint8 *)b+os+0)<<8|
- (int16)*((uint8 *)b+os+1)<<0));
-}
-
-uint16 SW_USHORT_AT(void *b, uint32 os)
-{
- return ((uint16)
- ((uint16)*((uint8 *)b+os+0)<<8|
- (uint16)*((uint8 *)b+os+1)<<0));
-}
-
-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);
-
-}
-
-#endif /*_USE_SW_FUNCS_*/
-
-void assert(void* assert, const char* file, int line, void* msg) { };
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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))
-
-#ifdef __GNUC__
-#define __inline inline
-#define _USE_SW_FUNCS_
-#endif
-
-#ifdef _USE_SW_FUNCS_
-
-inline int32 SW_LONG_AT(void *b, uint32 c);
-inline uint32 SW_ULONG_AT(void *b, uint32 c);
-inline int16 SW_SHORT_AT(void *b, uint32 os);
-inline uint16 SW_USHORT_AT(void *b, uint32 os);
-inline VOID SW_ULONG_ASSIGN(void *dst, uint32 src);
-
-#else /*_USE_SW_FUNCS_*/
-
-__inline int32 SW_LONG_AT(void *b, uint32 c)
-{
- return ((int32)*((uint8 *)b+c)<<24|
- (int32)*((uint8 *)b+c+1)<<16|
- (int32)*((uint8 *)b+c+2)<<8|
- (int32)*((uint8 *)b+c+3)<<0);
-}
-
-__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);
-
-}
-
-#endif /*_USE_SW_FUNCS_*/
-
-#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);
-
-#endif /*WIN_NT_DRIVER*/
-
-
-#endif
-
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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;
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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
-
+++ /dev/null
-; packet capture driver - ReactOS Operating System
-
-LIBRARY PACKET.SYS
-
-EXPORTS
-DriverEntry@8
-
-; EOF
+++ /dev/null
-//#include "resource.h"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,0,0,13
- PRODUCTVERSION 3,0,0,13
- FILEFLAGSMASK 0x3fL
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x40004L
- FILETYPE 0x3L
- FILESUBTYPE 0x7L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "000004b0"
- BEGIN
- VALUE "Comments", "Netgroup Packet Filter Driver\0"
- VALUE "CompanyName", "Politecnico di Torino\0"
- VALUE "FileDescription", "NPF Driver - TME extensions\0"
- VALUE "FileVersion", "3, 0, 0, 13\0"
- VALUE "InternalName", "NPF + TME \0"
- VALUE "LegalCopyright", "Copyright © 2002\0"
- VALUE "LegalTrademarks", "\0"
- VALUE "OriginalFilename", "NPF.RC\0"
- VALUE "PrivateBuild", "REACTOS PRIVATE BUILD\0"
- VALUE "ProductName", "NPF Driver\0"
- VALUE "ProductVersion", "3, 0, 0, 13\0"
- VALUE "SpecialBuild", "Beta testing use only\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x0, 1200
- END
-END
-
-/////////////////////////////////////////////////////////////////////////////
-
-
+++ /dev/null
-<module name="npf" type="kernelmodedriver" installbase="system32/drivers" installname="npf.sys">
- <include base="npf">include</include>
- <include base="ntoskrnl">include</include>
- <define name="__USE_W32API" />
- <define name="_TIMEVAL_DEFINED" />
- <define name="WIN_NT_DRIVER" />
- <define name="KQPC_TS" />
- <define name="USE_KLOCKS" />
- <define name="BINARY_COMPATIBLE" />
- <library>ndis</library>
- <library>ntoskrnl</library>
- <library>hal</library>
- <file>bucket_lookup.c</file>
- <file>count_packets.c</file>
- <file>dump.c</file>
- <file>functions.c</file>
- <file>jitter.c</file>
- <file>memory_t.c</file>
- <file>normal_lookup.c</file>
- <file>openclos.c</file>
- <file>packet.c</file>
- <file>read.c</file>
- <file>tcp_session.c</file>
- <file>time_calls.c</file>
- <file>tme.c</file>
- <file>win_bpf_filter.c</file>
- <file>win_bpf_filter_init.c</file>
- <file>write.c</file>
- <file>npf.rc</file>
-</module>
+++ /dev/null
-#ifndef __NTDDPACKET
-#define __NTDDPACKET 1
-
-#ifdef _MSC_VER
-#include "devioctl.h"
-/*#include <packon.h> */
-#else
-#endif
-
-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
+++ /dev/null
-/*
- * Copyright (c) 1999, 2000
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifdef _MSC_VER
-#include "ntddk.h"
-#include "ntiologc.h"
-#include "ndis.h"
-#else
-#include <ntddk.h>
-#include <ndis.h>
-#endif
-#include "debug.h"
-#include "packet.h"
-
-#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
-
-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 STDCALL
-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
-#define NPF_TAG_OPENSTRUCT TAG('0', 'O', 'W', 'A')
- Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), NPF_TAG_OPENSTRUCT);
-
-
- 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)
- );
-
-
-#define NPF_TAG_EVNAME TAG('1', 'O', 'W', 'A')
- EvName=ExAllocatePoolWithTag(NonPagedPool, sizeof(L"\\BaseNamedObjects\\NPF0000000000"), NPF_TAG_EVNAME);
-
- 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\\NPF0000000000",sizeof(L"\\BaseNamedObjects\\NPF0000000000"));
-
- //Create the string containing the name of the read event
- RtlInitUnicodeString(&Open->ReadEventName,(PCWSTR) EvName);
-
- PacketItoa(NamedEventsCounter,(PUCHAR)(Open->ReadEventName.Buffer+21));
-
- InterlockedIncrement((PLONG)&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);
- NdisInitializeEvent(&Open->IOEvent);
- NdisAllocateSpinLock(&Open->machine_lock);
-
-
- // 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
-#define NPF_TAG_MACHINE TAG('2', 'O', 'W', 'A')
- Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, NPF_TAG_MACHINE);
- if((Open->mem_ex.buffer) == NULL)
- {
- // no memory
- 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;
- Open->BLastByte = (UINT) -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;
-
- //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 STDCALL 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 = 1514; // Assume Ethernet
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return;
- }
-
- MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement);
- MaxSizeReq->Irp = Irp;
- MaxSizeReq->Internal = TRUE;
-
-
- MaxSizeReq->Request.RequestType = NdisRequestQueryInformation;
- MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE;
-
-
- MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = &Open->MaxFrameSize;
- MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = 4;
-
- // submit the request
- NdisRequest(
- &ReqStatus,
- Open->AdapterHandle,
- &MaxSizeReq->Request);
-
-
- if (ReqStatus != NDIS_STATUS_PENDING) {
- NPF_RequestComplete(Open, &MaxSizeReq->Request, ReqStatus);
- }
-
- return;
-
- }
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return;
-
-}
-
-//-------------------------------------------------------------------
-
-NTSTATUS STDCALL
-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);
-
- // Free the jitted filter if it's present
- if(Open->Filter != NULL)
- BPF_Destroy_JIT_Filter(Open->Filter);
-
- //free the buffer
- Open->BufSize=0;
- if(Open->Buffer != NULL)ExFreePool(Open->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 STDCALL
-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);
-
- // Free the jitted filter if it's present
- if(Open->Filter != NULL)
- BPF_Destroy_JIT_Filter(Open->Filter);
-
- //free the buffer
- Open->BufSize = 0;
- if(Open->Buffer!=NULL)ExFreePool(Open->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 STDCALL
-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;
-
-}
+++ /dev/null
-/*
- * Copyright (c) 1999, 2000
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifdef _MSC_VER
-#include "stdarg.h"
-#include "ntddk.h"
-#include "ntiologc.h"
-#include "ndis.h"
-#else
-#include <ntddk.h>
-#include <ndis.h>
-#endif
-
-#include "ntddpack.h"
-
-#include "debug.h"
-#include "packet.h"
-#include "win_bpf.h"
-#include "win_bpf_filter_init.h"
-
-#include "tme.h"
-
-#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
-
-#if DBG
-// Declare the global debug flag for this driver.
-//ULONG PacketDebugFlag = PACKET_DEBUG_LOUD;
-ULONG PacketDebugFlag = PACKET_DEBUG_LOUD + PACKET_DEBUG_VERY_LOUD + PACKET_DEBUG_INIT;
-
-#endif
-
-PDEVICE_EXTENSION GlobalDeviceExtension;
-
-////////////////////////////////////////////////////////////////////////////////
-#define ROBERTS_PATCH
-#ifdef ROBERTS_PATCH
-
-#define NDIS_STRING_CONST(x) {sizeof(L##x)-2, sizeof(L##x), L##x}
-
-//void __moddi3(void) {}
-//void __divdi3(void) {}
-
-#endif // ROBERTS_PATCH
-////////////////////////////////////////////////////////////////////////////////
-//
-// Global strings
-//
-NDIS_STRING NPF_Prefix = NDIS_STRING_CONST("NPF_");
-NDIS_STRING devicePrefix = NDIS_STRING_CONST("\\Device\\");
-NDIS_STRING symbolicLinkPrefix = NDIS_STRING_CONST("\\DosDevices\\");
-NDIS_STRING tcpLinkageKeyName = NDIS_STRING_CONST("\\Registry\\Machine\\System"
- L"\\CurrentControlSet\\Services\\Tcpip\\Linkage");
-NDIS_STRING AdapterListKey = NDIS_STRING_CONST("\\Registry\\Machine\\System"
- L"\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
-NDIS_STRING bindValueName = NDIS_STRING_CONST("Bind");
-
-
-/// Global variable that points to the names of the bound adapters
-WCHAR* bindP = NULL;
-
-extern struct time_conv G_Start_Time; // from openclos.c
-
-extern NDIS_SPIN_LOCK Opened_Instances_Lock;
-
-//
-// Packet Driver's entry routine.
-//
-NTSTATUS
-#ifdef __GNUC__
-STDCALL
-#endif
-DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
-{
-
- NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar;
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
- NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver");
- NDIS_HANDLE NdisProtocolHandle;
- WCHAR* bindT;
- PKEY_VALUE_PARTIAL_INFORMATION tcpBindingsP;
- UNICODE_STRING macName;
-
- // This driver at the moment works only on single processor machines
- if(NdisSystemProcessorCount() != 1){
- return STATUS_IMAGE_MP_UP_MISMATCH;
- }
-
- IF_LOUD(DbgPrint("Packet: DriverEntry\n");)
-
- RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
-
-#ifdef NDIS50
- ProtocolChar.MajorNdisVersion = 5;
-#else
- ProtocolChar.MajorNdisVersion = 3;
-#endif
- ProtocolChar.MinorNdisVersion = 0;
- ProtocolChar.Reserved = 0;
- ProtocolChar.OpenAdapterCompleteHandler = NPF_OpenAdapterComplete;
- ProtocolChar.CloseAdapterCompleteHandler = NPF_CloseAdapterComplete;
- ProtocolChar.SendCompleteHandler = NPF_SendComplete;
- ProtocolChar.TransferDataCompleteHandler = NPF_TransferDataComplete;
- ProtocolChar.ResetCompleteHandler = NPF_ResetComplete;
- ProtocolChar.RequestCompleteHandler = NPF_RequestComplete;
- ProtocolChar.ReceiveHandler = NPF_tap;
- ProtocolChar.ReceiveCompleteHandler = NPF_ReceiveComplete;
- ProtocolChar.StatusHandler = NPF_Status;
- ProtocolChar.StatusCompleteHandler = NPF_StatusComplete;
-#ifdef NDIS50
- ProtocolChar.BindAdapterHandler = NPF_BindAdapter;
- ProtocolChar.UnbindAdapterHandler = NPF_UnbindAdapter;
- ProtocolChar.PnPEventHandler = NPF_PowerChange;
- ProtocolChar.ReceivePacketHandler = NULL;
-#endif
- ProtocolChar.Name = ProtoName;
-
- NdisRegisterProtocol(
- &Status,
- &NdisProtocolHandle,
- &ProtocolChar,
- sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
-
- if (Status != NDIS_STATUS_SUCCESS) {
-
- IF_LOUD(DbgPrint("NPF: Failed to register protocol with NDIS\n");)
-
- return Status;
-
- }
-
- NdisAllocateSpinLock(&Opened_Instances_Lock);
-
- // Set up the device driver entry points.
- DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)NPF_Open;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)NPF_Close;
- DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)NPF_Read;
- DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)NPF_Write;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)NPF_IoControl;
- DriverObject->DriverUnload = NPF_Unload;
-
-/*
- // Get the name of the Packet driver and the name of the NIC driver
- // to bind to from the registry
- Status=NPF_ReadRegistry(
- &BindString,
- &ExportString,
- RegistryPath
- );
-
- if (Status != STATUS_SUCCESS) {
-
- IF_LOUD(DbgPrint("Trying dynamic binding\n");)
- */
- bindP = getAdaptersList();
-
- if (bindP == NULL) {
- IF_LOUD(DbgPrint("Adapters not found in the registry, try to copy the bindings of TCP-IP.\n");)
-
- tcpBindingsP = getTcpBindings();
-
- if (tcpBindingsP == NULL){
- IF_LOUD(DbgPrint("TCP-IP not found, quitting.\n");)
- goto RegistryError;
- }
-
- bindP = (WCHAR*)tcpBindingsP;
- bindT = (WCHAR*)(tcpBindingsP->Data);
- } else {
- bindT = bindP;
- }
-
- for (; *bindT != UNICODE_NULL; bindT += (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)) {
- RtlInitUnicodeString(&macName, bindT);
- createDevice(DriverObject, &macName, NdisProtocolHandle);
- }
-
- return STATUS_SUCCESS;
-/*
- }
- BindStringSave = BindString;
- ExportStringSave = ExportString;
- //
- // create a device object for each entry
- //
- while (*BindString!= UNICODE_NULL && *ExportString!= UNICODE_NULL) {
- //
- // Create a counted unicode string for both null terminated strings
- //
- RtlInitUnicodeString(
- &MacDriverName,
- BindString);
- RtlInitUnicodeString(
- &UnicodeDeviceName,
- ExportString);
- //
- // Advance to the next string of the MULTI_SZ string
- //
- BindString += (MacDriverName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
- ExportString += (UnicodeDeviceName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
- IF_LOUD(DbgPrint("NPF: DeviceName=%ws MacName=%ws\n",UnicodeDeviceName.Buffer,MacDriverName.Buffer);)
- //
- // Create the device object
- //
- Status = IoCreateDevice(
- DriverObject,
- sizeof(DEVICE_EXTENSION),
- &UnicodeDeviceName,
- FILE_DEVICE_PROTOCOL,
- 0,
- FALSE,
- &DeviceObject);
- if (Status != STATUS_SUCCESS) {
- IF_LOUD(DbgPrint("NPF: IoCreateDevice() failed:\n");)
- break;
- }
- DevicesCreated++;
- DeviceObject->Flags |= DO_DIRECT_IO;
- DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
- DeviceExtension->DeviceObject = DeviceObject;
- //
- // Save the the name of the MAC driver to open in the Device Extension
- //
- DeviceExtension->AdapterName=MacDriverName;
- if (DevicesCreated == 1) {
- DeviceExtension->BindString = NULL;
- DeviceExtension->ExportString = NULL;
- }
- DeviceExtension->NdisProtocolHandle=NdisProtocolHandle;
- }
- if (DevicesCreated > 0) {
- //
- // Managed to create at least one device.
- //
- IF_LOUD(DbgPrint("NPF: Managed to create at least one device.\n");)
- return STATUS_SUCCESS;
- }
- ExFreePool(BindStringSave);
- ExFreePool(ExportStringSave);
- */
-
-RegistryError:
- IF_LOUD(DbgPrint("NPF: RegistryError: calling NdisDeregisterProtocol()\n");)
- NdisDeregisterProtocol(
- &Status,
- NdisProtocolHandle
- );
-
- Status=STATUS_UNSUCCESSFUL;
-
- return(Status);
-
-}
-
-//-------------------------------------------------------------------
-
-PWCHAR getAdaptersList(void)
-{
- OBJECT_ATTRIBUTES objAttrs;
- NTSTATUS status;
- HANDLE keyHandle;
- UINT BufPos=0;
-
-#define NPF_TAG_DEVICENAME TAG('0', 'P', 'W', 'A')
- PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, 4096, NPF_TAG_DEVICENAME);
-
- if (DeviceNames == NULL) {
- IF_LOUD(DbgPrint("Unable the allocate the buffer for the list of the network adapters\n");)
- return NULL;
- }
-
- InitializeObjectAttributes(&objAttrs, &AdapterListKey,
- OBJ_CASE_INSENSITIVE, NULL, NULL);
- status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);
- if (!NT_SUCCESS(status)) {
-
- //IF_LOUD(DbgPrint("Status of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);)
- IF_LOUD(DbgPrint("Status of %x opening %ws\n", status, AdapterListKey.Buffer);)
-
- } else { //OK
- ULONG resultLength;
- CHAR AdapInfo[1024];
- UINT i=0;
-
- IF_LOUD(DbgPrint("getAdaptersList: scanning the list of the adapters in the registry, DeviceNames=%x\n",DeviceNames);)
-
- // Scan the list of the devices
- while((status=ZwEnumerateKey(keyHandle,i,KeyBasicInformation,AdapInfo,sizeof(AdapInfo),&resultLength))==STATUS_SUCCESS) {
- WCHAR ExportKeyName [512];
- PWCHAR ExportKeyPrefix = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
- UINT ExportKeyPrefixSize = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
- PWCHAR LinkageKeyPrefix = L"\\Linkage";
- UINT LinkageKeyPrefixSize = sizeof(L"\\Linkage");
- NDIS_STRING FinalExportKey = NDIS_STRING_CONST("Export");
- PKEY_BASIC_INFORMATION tInfo= (PKEY_BASIC_INFORMATION)AdapInfo;
- UNICODE_STRING AdapterKeyName;
- HANDLE ExportKeyHandle;
- KEY_VALUE_PARTIAL_INFORMATION valueInfo;
- ULONG resultLength;
-
- RtlCopyMemory(ExportKeyName,
- ExportKeyPrefix,
- ExportKeyPrefixSize);
-
- RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize,
- tInfo->Name,
- tInfo->NameLength+2);
-
- RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize+tInfo->NameLength,
- LinkageKeyPrefix,
- LinkageKeyPrefixSize);
-
- IF_LOUD(DbgPrint("Key name=%ws\n", ExportKeyName);)
-
- RtlInitUnicodeString(&AdapterKeyName, ExportKeyName);
-
- InitializeObjectAttributes(&objAttrs, &AdapterKeyName,
- OBJ_CASE_INSENSITIVE, NULL, NULL);
-
- status=ZwOpenKey(&ExportKeyHandle,KEY_READ,&objAttrs);
-
- if (!NT_SUCCESS(status)) {
- DbgPrint("OpenKey Failed, %d!\n",status);
- i++;
- continue;
- }
-
- status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey,
- KeyValuePartialInformation, &valueInfo,
- sizeof(valueInfo), &resultLength);
-
- if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) {
- IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);)
- } else { // We know how big it needs to be.
- ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
-#define NPF_TAG_KEYVALUE TAG('1', 'P', 'W', 'A')
- PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag(PagedPool, valueInfoLength, NPF_TAG_KEYVALUE);
- if (valueInfoP != NULL) {
- status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey,
- KeyValuePartialInformation,
- valueInfoP,
- valueInfoLength, &resultLength);
- if (!NT_SUCCESS(status)) {
- IF_LOUD(DbgPrint("Status of %x querying key value\n", status);)
- } else {
- IF_LOUD(DbgPrint("Device %d = %ws\n", i, valueInfoP->Data);)
- RtlCopyMemory((PCHAR)DeviceNames+BufPos,
- valueInfoP->Data,
- valueInfoP->DataLength);
- BufPos+=valueInfoP->DataLength-2;
- }
-
- ExFreePool(valueInfoP);
- } else {
- IF_LOUD(DbgPrint("Error Allocating the buffer for the device name\n");)
- }
-
- }
-
- // terminate the buffer
- DeviceNames[BufPos/2]=0;
- DeviceNames[BufPos/2+1]=0;
-
- ZwClose (ExportKeyHandle);
- i++;
-
- }
-
- ZwClose (keyHandle);
-
- }
- if(BufPos==0){
- ExFreePool(DeviceNames);
- return NULL;
- }
- return DeviceNames;
-}
-
-//-------------------------------------------------------------------
-
-PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(void)
-{
- PKEY_VALUE_PARTIAL_INFORMATION result = NULL;
- OBJECT_ATTRIBUTES objAttrs;
- NTSTATUS status;
- HANDLE keyHandle;
-
- InitializeObjectAttributes(&objAttrs, &tcpLinkageKeyName,
- OBJ_CASE_INSENSITIVE, NULL, NULL);
- status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);
- if (!NT_SUCCESS(status)) {
- IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);)
- } else {
- ULONG resultLength;
- KEY_VALUE_PARTIAL_INFORMATION valueInfo;
-
- IF_LOUD(DbgPrint("\n\nOpened %ws\n", tcpLinkageKeyName.Buffer);)
-
- status = ZwQueryValueKey(keyHandle, &bindValueName,
- KeyValuePartialInformation, &valueInfo,
- sizeof(valueInfo), &resultLength);
- if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) {
- IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);)
- } else { // We know how big it needs to be.
- ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
-#define NPF_TAG_KEYVALUE2 TAG('2', 'P', 'W', 'A')
- PKEY_VALUE_PARTIAL_INFORMATION valueInfoP =
- (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, valueInfoLength, NPF_TAG_KEYVALUE2);
-
- if (valueInfoP != NULL) {
- status = ZwQueryValueKey(keyHandle, &bindValueName,
- KeyValuePartialInformation,
- valueInfoP,
- valueInfoLength, &resultLength);
-
- if (!NT_SUCCESS(status)) {
- IF_LOUD(DbgPrint("\n\nStatus of %x querying key value\n", status);)
- }
- else if (valueInfoLength != resultLength) {
- IF_LOUD(DbgPrint("\n\nQuerying key value result len = %u "
- "but previous len = %u\n",
- resultLength, valueInfoLength);)
- }
- else if (valueInfoP->Type != REG_MULTI_SZ) {
- IF_LOUD(DbgPrint("\n\nTcpip bind value not REG_MULTI_SZ but %u\n",
- valueInfoP->Type);)
- }
- else { // It's OK
-#if DBG
- ULONG i;
- WCHAR* dataP = (WCHAR*)(&valueInfoP->Data[0]);
- IF_LOUD(DbgPrint("\n\nBind value:\n");)
- for (i = 0; *dataP != UNICODE_NULL; i++) {
- UNICODE_STRING macName;
- RtlInitUnicodeString(&macName, dataP);
- IF_LOUD(DbgPrint("\n\nMac %u = %ws\n", i, macName.Buffer);)
- dataP +=
- (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
- }
-#endif // DBG
- result = valueInfoP;
- }
- }
- }
- ZwClose(keyHandle);
- }
- return result;
-}
-
-//-------------------------------------------------------------------
-
-BOOLEAN createDevice(IN OUT PDRIVER_OBJECT adriverObjectP,
- IN PUNICODE_STRING amacNameP, NDIS_HANDLE aProtoHandle)
-{
- NTSTATUS status;
- PDEVICE_OBJECT devObjP;
- UNICODE_STRING deviceName;
- UNICODE_STRING deviceSymLink;
-
- IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer););
- if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer,
- devicePrefix.Length) < devicePrefix.Length) {
- return FALSE;
- }
-
- deviceName.Length = 0;
- deviceName.MaximumLength = (USHORT)(amacNameP->Length + NPF_Prefix.Length + sizeof(UNICODE_NULL));
-#define NPF_TAG_DEVICENAMEBUF TAG('3', 'P', 'W', 'A')
- deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, NPF_TAG_DEVICENAMEBUF);
-
- if (deviceName.Buffer == NULL)
- return FALSE;
-
- deviceSymLink.Length = 0;
- deviceSymLink.MaximumLength =(USHORT)(amacNameP->Length-devicePrefix.Length
- + symbolicLinkPrefix.Length
- + NPF_Prefix.Length
- + sizeof(UNICODE_NULL));
-
-#define NPF_TAG_SYMLINKBUF TAG('3', 'P', 'W', 'A')
- deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, NPF_TAG_SYMLINKBUF);
-
- if (deviceSymLink.Buffer == NULL)
- {
- ExFreePool(deviceName.Buffer);
- return FALSE;
- }
-
- RtlAppendUnicodeStringToString(&deviceName, &devicePrefix);
- RtlAppendUnicodeStringToString(&deviceName, &NPF_Prefix);
- RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer +
- devicePrefix.Length / sizeof(WCHAR));
-
- RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix);
- RtlAppendUnicodeStringToString(&deviceSymLink, &NPF_Prefix);
- RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer +
- devicePrefix.Length / sizeof(WCHAR));
-
- IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);)
-
- status = IoCreateDevice(adriverObjectP,
- sizeof(PDEVICE_EXTENSION),
- &deviceName,
- FILE_DEVICE_TRANSPORT,
- 0,
- FALSE,
- &devObjP);
-
- if (NT_SUCCESS(status)) {
- PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension;
-
- IF_LOUD(DbgPrint("Device created successfully\n"););
-
- devObjP->Flags |= DO_DIRECT_IO;
- RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer);
- devExtP->NdisProtocolHandle=aProtoHandle;
-
- IF_LOUD(DbgPrint("Trying to create SymLink %ws\n",deviceSymLink.Buffer););
-
- if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) != STATUS_SUCCESS) {
- IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer););
-
- ExFreePool(deviceName.Buffer);
- ExFreePool(deviceSymLink.Buffer);
-
- devExtP->ExportString = NULL;
-
- return FALSE;
- }
-
- IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer););
-
- devExtP->ExportString = deviceSymLink.Buffer;
-
- ExFreePool(deviceName.Buffer);
-
- return TRUE;
- }
-
- else
- {
- IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status););
-
- ExFreePool(deviceName.Buffer);
- ExFreePool(deviceSymLink.Buffer);
-
- return FALSE;
- }
-}
-
-//-------------------------------------------------------------------
-
-VOID STDCALL
-NPF_Unload(IN PDRIVER_OBJECT DriverObject)
-{
- PDEVICE_OBJECT DeviceObject;
- PDEVICE_OBJECT OldDeviceObject;
- PDEVICE_EXTENSION DeviceExtension;
-
- NDIS_HANDLE NdisProtocolHandle;
- NDIS_STATUS Status;
-
- NDIS_STRING SymLink;
-
- IF_LOUD(DbgPrint("NPF: Unload\n"););
-
- DeviceObject = DriverObject->DeviceObject;
-
- while (DeviceObject != NULL) {
- OldDeviceObject=DeviceObject;
-
- DeviceObject=DeviceObject->NextDevice;
-
- DeviceExtension = OldDeviceObject->DeviceExtension;
-
- NdisProtocolHandle=DeviceExtension->NdisProtocolHandle;
-
- IF_LOUD(DbgPrint("Deleting Adapter %ws, Protocol Handle=%x, Device Obj=%x (%x)\n",
- DeviceExtension->AdapterName.Buffer,
- NdisProtocolHandle,
- DeviceObject,
- OldDeviceObject););
-
- if (DeviceExtension->ExportString)
- {
- RtlInitUnicodeString(&SymLink , DeviceExtension->ExportString);
-
- IF_LOUD(DbgPrint("Deleting SymLink at %p\n", SymLink.Buffer););
-
- IoDeleteSymbolicLink(&SymLink);
- ExFreePool(DeviceExtension->ExportString);
- }
-
- IoDeleteDevice(OldDeviceObject);
-
- NdisDeregisterProtocol(
- &Status,
- NdisProtocolHandle
- );
- }
-
- // Free the adapters names
- ExFreePool( bindP );
-}
-
-//-------------------------------------------------------------------
-
-NTSTATUS STDCALL
-NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
-{
- POPEN_INSTANCE Open;
- PIO_STACK_LOCATION IrpSp;
- PLIST_ENTRY RequestListEntry;
- PINTERNAL_REQUEST pRequest;
- ULONG FunctionCode;
- NDIS_STATUS Status;
- PUCHAR tpointer;
- ULONG dim,timeout;
- PUCHAR prog;
- PPACKET_OID_DATA OidData;
- ULONG mode;
- PWSTR DumpNameBuff;
- PUCHAR TmpBPFProgram;
- INT WriteRes;
- BOOLEAN SyncWrite = FALSE;
- struct bpf_insn *initprogram;
- ULONG insns;
- ULONG cnt;
- BOOLEAN IsExtendedFilter=FALSE;
-
- IF_LOUD(DbgPrint("NPF: IoControl\n");)
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
- Open=IrpSp->FileObject->FsContext;
-
- Irp->IoStatus.Status = STATUS_SUCCESS;
-
- IF_LOUD(DbgPrint("NPF: Function code is %08lx buff size=%08lx %08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength,IrpSp->Parameters.DeviceIoControl.OutputBufferLength);)
-
-
- switch (FunctionCode){
-
- case BIOCGSTATS: //function to get the capture stats
-
- if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4*sizeof(INT)){
- EXIT_FAILURE(0);
- }
-
- *(((PUINT)Irp->UserBuffer)+3) = Open->Accepted;
- *(((PUINT)Irp->UserBuffer)) = Open->Received;
- *(((PUINT)Irp->UserBuffer)+1) = Open->Dropped;
- *(((PUINT)Irp->UserBuffer)+2) = 0; // Not yet supported
-
- EXIT_SUCCESS(4*sizeof(INT));
-
- break;
-
- case BIOCGEVNAME: //function to get the name of the event associated with the current instance
-
- if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength<26){
- EXIT_FAILURE(0);
- }
-
- RtlCopyMemory(Irp->UserBuffer,(Open->ReadEventName.Buffer)+18,26);
-
- EXIT_SUCCESS(26);
-
- break;
-
- case BIOCSENDPACKETSSYNC:
-
- SyncWrite = TRUE;
-
- case BIOCSENDPACKETSNOSYNC:
-
- WriteRes = NPF_BufferedWrite(Irp,
- (PCHAR)Irp->AssociatedIrp.SystemBuffer,
- IrpSp->Parameters.DeviceIoControl.InputBufferLength,
- SyncWrite);
-
- if( WriteRes != -1)
- {
- EXIT_SUCCESS(WriteRes);
- }
-
- EXIT_FAILURE(WriteRes);
-
- break;
-
- case BIOCSETF:
-
- // Free the previous buffer if it was present
- if(Open->bpfprogram!=NULL){
- TmpBPFProgram=Open->bpfprogram;
- Open->bpfprogram = NULL;
- ExFreePool(TmpBPFProgram);
- }
-
- if (Open->Filter!=NULL)
- {
- JIT_BPF_Filter *OldFilter=Open->Filter;
- Open->Filter=NULL;
- BPF_Destroy_JIT_Filter(OldFilter);
- }
-
- // Get the pointer to the new program
- prog=(PUCHAR)Irp->AssociatedIrp.SystemBuffer;
-
- if(prog==NULL){
- IF_LOUD(DbgPrint("0001");)
-
- EXIT_FAILURE(0);
- }
-
- insns=(IrpSp->Parameters.DeviceIoControl.InputBufferLength)/sizeof(struct bpf_insn);
-
- //count the number of operative instructions
- for (cnt=0;(cnt<insns) &&(((struct bpf_insn*)prog)[cnt].code!=BPF_SEPARATION); cnt++);
-
- IF_LOUD(DbgPrint("Operative instructions=%u\n",cnt);)
-
- if (((struct bpf_insn*)prog)[cnt].code==BPF_SEPARATION && (insns-cnt-1)!=0)
- {
- IF_LOUD(DbgPrint("Initialization instructions=%u\n",insns-cnt-1);)
-
- IsExtendedFilter=TRUE;
-
- initprogram=&((struct bpf_insn*)prog)[cnt+1];
-
- if(bpf_filter_init(initprogram,&(Open->mem_ex),&(Open->tme), &G_Start_Time)!=INIT_OK)
- {
-
- IF_LOUD(DbgPrint("Error initializing NPF machine (bpf_filter_init)\n");)
-
- EXIT_FAILURE(0);
- }
- }
-
- //the NPF processor has been initialized, we have to validate the operative instructions
- insns=cnt;
-
- if(bpf_validate((struct bpf_insn*)prog,cnt,Open->mem_ex.size)==0)
- {
- IF_LOUD(DbgPrint("Error validating program");)
- //FIXME: the machine has been initialized(?), but the operative code is wrong.
- //we have to reset the machine!
- //something like: reallocate the mem_ex, and reset the tme_core
- EXIT_FAILURE(0);
- }
-
- // Allocate the memory to contain the new filter program
- // We could need the original BPF binary if we are forced to use bpf_filter_with_2_buffers()
-#define NPF_TAG_BPFPROG TAG('4', 'P', 'W', 'A')
- TmpBPFProgram=(PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), NPF_TAG_BPFPROG);
- if (TmpBPFProgram==NULL){
- IF_LOUD(DbgPrint("Error - No memory for filter");)
- // no memory
- EXIT_FAILURE(0);
- }
-
- //copy the program in the new buffer
- RtlCopyMemory(TmpBPFProgram,prog,cnt*sizeof(struct bpf_insn));
- Open->bpfprogram=TmpBPFProgram;
-
- // Create the new JIT filter function
- if(!IsExtendedFilter)
- if((Open->Filter=BPF_jitter((struct bpf_insn*)Open->bpfprogram,cnt)) == NULL) {
- IF_LOUD(DbgPrint("Error jittering filter");)
- EXIT_FAILURE(0);
- }
-
- //return
- Open->Bhead = 0;
- Open->Btail = 0;
- Open->BLastByte = (UINT) -1;
- Open->Received = 0;
- Open->Dropped = 0;
- Open->Accepted = 0;
-
- EXIT_SUCCESS(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
-
- break;
-
- case BIOCSMODE: //set the capture mode
-
- mode=*((PULONG)Irp->AssociatedIrp.SystemBuffer);
-
- if(mode == MODE_CAPT){
- Open->mode=MODE_CAPT;
-
- EXIT_SUCCESS(0);
- }
- else if (mode==MODE_MON){
- Open->mode=MODE_MON;
-
- EXIT_SUCCESS(0);
- }
- else{
- if(mode & MODE_STAT){
- Open->mode = MODE_STAT;
- Open->Nbytes.QuadPart=0;
- Open->Npackets.QuadPart=0;
-
- if(Open->TimeOut.QuadPart==0)Open->TimeOut.QuadPart=-10000000;
-
- }
-
- if(mode & MODE_DUMP){
-
- Open->mode |= MODE_DUMP;
- Open->MinToCopy=(Open->BufSize<2000000)?Open->BufSize/2:1000000;
-
- }
- EXIT_SUCCESS(0);
- }
-
- EXIT_FAILURE(0);
-
- break;
-
- case BIOCSETDUMPFILENAME:
-
- if(Open->mode & MODE_DUMP)
- {
-
- // Close current dump file
- if(Open->DumpFileHandle != NULL){
- NPF_CloseDumpFile(Open);
- Open->DumpFileHandle = NULL;
- }
-
- if(IrpSp->Parameters.DeviceIoControl.InputBufferLength == 0){
- EXIT_FAILURE(0);
- }
-
- // Allocate the buffer that will contain the string
-#define NPF_TAG_DUMPNAMEBUF TAG('5', 'P', 'W', 'A')
- DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, NPF_TAG_DUMPNAMEBUF);
- if(DumpNameBuff==NULL || Open->DumpFileName.Buffer!=NULL){
- IF_LOUD(DbgPrint("NPF: unable to allocate the dump filename: not enough memory or name already set\n");)
- EXIT_FAILURE(0);
- }
-
- // Copy the buffer
- RtlCopyBytes((PVOID)DumpNameBuff,
- Irp->AssociatedIrp.SystemBuffer,
- IrpSp->Parameters.DeviceIoControl.InputBufferLength);
-
- // Force a \0 at the end of the filename to avoid that malformed strings cause RtlInitUnicodeString to crash the system
- ((SHORT*)DumpNameBuff)[IrpSp->Parameters.DeviceIoControl.InputBufferLength/2-1]=0;
-
- // Create the unicode string
- RtlInitUnicodeString(&Open->DumpFileName, DumpNameBuff);
-
- IF_LOUD(DbgPrint("NPF: dump file name set to %ws, len=%d\n",
- Open->DumpFileName.Buffer,
- IrpSp->Parameters.DeviceIoControl.InputBufferLength);)
-
- // Try to create the file
- if ( NT_SUCCESS( NPF_OpenDumpFile(Open,&Open->DumpFileName,FALSE)) &&
- NT_SUCCESS( NPF_StartDump(Open))){
-
- EXIT_SUCCESS(0);
- }
- }
-
- EXIT_FAILURE(0);
-
- break;
-
- case BIOCSETDUMPLIMITS:
-
- Open->MaxDumpBytes = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
- Open->MaxDumpPacks = *((PULONG)Irp->AssociatedIrp.SystemBuffer + 1);
-
- IF_LOUD(DbgPrint("NPF: Set dump limits to %u bytes, %u packs\n", Open->MaxDumpBytes, Open->MaxDumpPacks);)
-
- EXIT_SUCCESS(0);
-
- break;
-
- case BIOCISDUMPENDED:
- if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4){
- EXIT_FAILURE(0);
- }
-
- *((UINT*)Irp->UserBuffer) = (Open->DumpLimitReached)?1:0;
-
- EXIT_SUCCESS(4);
-
- break;
-
- case BIOCSETBUFFERSIZE:
-
- // Get the number of bytes to allocate
- dim = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
-
- // Free the old buffer
- tpointer = Open->Buffer;
- if(tpointer != NULL){
- Open->BufSize = 0;
- Open->Buffer = NULL;
- ExFreePool(tpointer);
- }
- // Allocate the new buffer
- if(dim!=0){
-#define NPF_TAG_TPOINTER TAG('6', 'P', 'W', 'A')
- tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, NPF_TAG_TPOINTER);
- if (tpointer==NULL) {
- // no memory
- Open->BufSize = 0;
- Open->Buffer = NULL;
- EXIT_FAILURE(0);
- }
- }
- else
- tpointer = NULL;
-
- Open->Buffer = tpointer;
- Open->Bhead = 0;
- Open->Btail = 0;
- Open->BLastByte = (UINT) -1;
-
- Open->BufSize = (UINT)dim;
- EXIT_SUCCESS(dim);
-
- break;
-
- case BIOCSRTIMEOUT: //set the timeout on the read calls
-
- timeout = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
- if((int)timeout==-1)
- Open->TimeOut.QuadPart=(LONGLONG)IMMEDIATE;
- else {
- Open->TimeOut.QuadPart=(LONGLONG)timeout;
- Open->TimeOut.QuadPart*=10000;
- Open->TimeOut.QuadPart=-Open->TimeOut.QuadPart;
- }
-
- //IF_LOUD(DbgPrint("NPF: read timeout set to %d:%d\n",Open->TimeOut.HighPart,Open->TimeOut.LowPart);)
- EXIT_SUCCESS(timeout);
-
- break;
-
- case BIOCSWRITEREP: //set the writes repetition number
-
- Open->Nwrites = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
-
- EXIT_SUCCESS(Open->Nwrites);
-
- break;
-
- case BIOCSMINTOCOPY: //set the minimum buffer's size to copy to the application
-
- Open->MinToCopy = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
-
- EXIT_SUCCESS(Open->MinToCopy);
-
- break;
-
- case IOCTL_PROTOCOL_RESET:
-
- IF_LOUD(DbgPrint("NPF: IoControl - Reset request\n");)
-
- IoMarkIrpPending(Irp);
- Irp->IoStatus.Status = STATUS_SUCCESS;
-
- ExInterlockedInsertTailList(&Open->ResetIrpList,&Irp->Tail.Overlay.ListEntry,&Open->RequestSpinLock);
- NdisReset(&Status,Open->AdapterHandle);
- if (Status != NDIS_STATUS_PENDING) {
- IF_LOUD(DbgPrint("NPF: IoControl - ResetComplete being called\n");)
- NPF_ResetComplete(Open,Status);
- }
-
- break;
-
-
- case BIOCSETOID:
- case BIOCQUERYOID:
-
- // Extract a request from the list of free ones
- RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,&Open->RequestSpinLock);
- if (RequestListEntry == NULL)
- {
- EXIT_FAILURE(0);
- }
-
- pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement);
- pRequest->Irp=Irp;
- pRequest->Internal = FALSE;
-
-
- //
- // See if it is an Ndis request
- //
- OidData=Irp->AssociatedIrp.SystemBuffer;
-
- if (((FunctionCode == BIOCSETOID) || (FunctionCode == BIOCQUERYOID))
- &&
- (IrpSp->Parameters.DeviceIoControl.InputBufferLength == IrpSp->Parameters.DeviceIoControl.OutputBufferLength)
- &&
- (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA))
- &&
- (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)-1+OidData->Length)) {
-
- IF_LOUD(DbgPrint("NPF: IoControl: Request: Oid=%08lx, Length=%08lx\n",OidData->Oid,OidData->Length);)
-
- //
- // The buffer is valid
- //
- if (FunctionCode == BIOCSETOID){
-
- pRequest->Request.RequestType=NdisRequestSetInformation;
- pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid;
-
- pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=OidData->Data;
- pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=OidData->Length;
- } else{
- pRequest->Request.RequestType=NdisRequestQueryInformation;
- pRequest->Request.DATA.QUERY_INFORMATION.Oid=OidData->Oid;
-
- pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=OidData->Data;
- pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=OidData->Length;
-
- }
-
- NdisResetEvent(&Open->IOEvent);
- //
- // submit the request
- //
- NdisRequest(
- &Status,
- Open->AdapterHandle,
- &pRequest->Request
- );
-
- } else {
- //
- // buffer too small
- //
- Status=NDIS_STATUS_FAILURE;
- pRequest->Request.DATA.SET_INFORMATION.BytesRead=0;
- pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0;
-
- }
-
- if (Status != NDIS_STATUS_PENDING) {
- IF_LOUD(DbgPrint("NPF: Calling RequestCompleteHandler\n");)
-
- NPF_RequestComplete(Open, &pRequest->Request, Status);
- return Status;
-
- }
-
- NdisWaitEvent(&Open->IOEvent, 5000);
-
- return(Open->IOStatus);
-
- break;
-
-
- default:
-
- EXIT_FAILURE(0);
- }
-
- return Status;
-}
-
-//-------------------------------------------------------------------
-
-VOID STDCALL
-NPF_RequestComplete(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN PNDIS_REQUEST NdisRequest,
- IN NDIS_STATUS Status
- )
-
-{
- POPEN_INSTANCE Open;
- PIO_STACK_LOCATION IrpSp;
- PIRP Irp;
- PINTERNAL_REQUEST pRequest;
- UINT FunctionCode;
-
- PPACKET_OID_DATA OidData;
-
- IF_LOUD(DbgPrint("NPF: RequestComplete\n");)
-
- Open= (POPEN_INSTANCE)ProtocolBindingContext;
-
- pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
- Irp=pRequest->Irp;
-
- if(pRequest->Internal == TRUE){
-
- // Put the request in the list of the free ones
- ExInterlockedInsertTailList(&Open->RequestList, &pRequest->ListElement, &Open->RequestSpinLock);
-
- if(Status != NDIS_STATUS_SUCCESS)
- Open->MaxFrameSize = 1514; // Assume Ethernet
-
- // We always return success, because the adapter has been already opened
- Irp->IoStatus.Status = NDIS_STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return;
- }
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
-
- OidData=Irp->AssociatedIrp.SystemBuffer;
-
- if (FunctionCode == BIOCSETOID) {
-
- OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead;
-
- } else {
-
- if (FunctionCode == BIOCQUERYOID) {
-
- OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten;
-
- IF_LOUD(DbgPrint("RequestComplete: BytesWritten=%d\n",pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten);)
- }
-
- }
-
- Irp->IoStatus.Information=IrpSp->Parameters.DeviceIoControl.InputBufferLength;
-
- IF_LOUD(DbgPrint("RequestComplete: BytesReturned=%d\n",IrpSp->Parameters.DeviceIoControl.InputBufferLength);)
-
- ExInterlockedInsertTailList(
- &Open->RequestList,
- &pRequest->ListElement,
- &Open->RequestSpinLock);
-
- Irp->IoStatus.Status = Status;
-
- Open->IOStatus = Status;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- // Unlock the caller
- NdisSetEvent(&Open->IOEvent);
-
- return;
-
-
-}
-
-//-------------------------------------------------------------------
-
-VOID STDCALL
-NPF_Status(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN NDIS_STATUS Status,
- IN PVOID StatusBuffer,
- IN UINT StatusBufferSize
- )
-
-{
-
- IF_LOUD(DbgPrint("NPF: Status Indication\n");)
-
- return;
-
-}
-
-//-------------------------------------------------------------------
-
-VOID STDCALL
-NPF_StatusComplete(
- IN NDIS_HANDLE ProtocolBindingContext
- )
-
-{
-
- IF_LOUD(DbgPrint("NPF: StatusIndicationComplete\n");)
-
- return;
-
-}
-
-//-------------------------------------------------------------------
-
-NTSTATUS
-NPF_ReadRegistry(
- IN PWSTR *MacDriverName,
- IN PWSTR *PacketDriverName,
- IN PUNICODE_STRING RegistryPath
- )
-
-{
- NTSTATUS Status;
-
- RTL_QUERY_REGISTRY_TABLE ParamTable[4];
-
- PWSTR Bind = L"Bind";
- PWSTR Export = L"Export";
- PWSTR Linkage = L"Linkage";
-
- PWCHAR Path;
-
-#define NPF_TAG_PATH TAG('7', 'P', 'W', 'A')
- Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), NPF_TAG_PATH);
-
- if (Path == NULL) {
- IF_LOUD(DbgPrint("\nPacketReadRegistry: returing STATUS_INSUFFICIENT_RESOURCES\n");)
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlZeroMemory(
- Path,
- RegistryPath->Length+sizeof(WCHAR)
- );
-
- RtlCopyMemory(
- Path,
- RegistryPath->Buffer,
- RegistryPath->Length
- );
-
- IF_LOUD(DbgPrint("NPF: Reg path is %ws\n",RegistryPath->Buffer);)
-
- RtlZeroMemory(
- ParamTable,
- sizeof(ParamTable)
- );
-
-
-
- //
- // change to the linkage key
- //
- //ParamTable[0].QueryRoutine = NULL;
- ParamTable[0].QueryRoutine = NPF_QueryRegistryRoutine;
- ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
- ParamTable[0].Name = Linkage;
-
-
- //
- // Get the name of the mac driver we should bind to
- //
-
- ParamTable[1].QueryRoutine = NPF_QueryRegistryRoutine;
- ParamTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED |
- RTL_QUERY_REGISTRY_NOEXPAND;
-
- ParamTable[1].Name = Bind;
- ParamTable[1].EntryContext = (PVOID)MacDriverName;
- ParamTable[1].DefaultType = REG_MULTI_SZ;
-
- //
- // Get the name that we should use for the driver object
- //
-
- ParamTable[2].QueryRoutine = NPF_QueryRegistryRoutine;
- ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED |
- RTL_QUERY_REGISTRY_NOEXPAND;
-
- ParamTable[2].Name = Export;
- ParamTable[2].EntryContext = (PVOID)PacketDriverName;
- ParamTable[2].DefaultType = REG_MULTI_SZ;
-
-
- Status=RtlQueryRegistryValues(
- RTL_REGISTRY_ABSOLUTE,
- Path,
- ParamTable,
- NULL,
- NULL
- );
-
- if (Status != STATUS_SUCCESS) {
- // insert hard coded parameters here while registry on ROS is not working...
- IF_LOUD(DbgPrint("PacketReadRegistry() RtlQueryRegistryValues failed - returing fixed parameters\n");)
-
- *MacDriverName = ExAllocatePool(PagedPool, 50 * sizeof(WCHAR));
- //memcpy(*MacDriverName, L"\\Device\\ne2000", 15 * sizeof(WCHAR));
- memcpy(*MacDriverName, L"\\Device\\ne2000", 15 * sizeof(WCHAR));
-
- *PacketDriverName = ExAllocatePool(PagedPool, 50 * sizeof(WCHAR));
- memcpy(*PacketDriverName, L"\\Device\\NPF_ne2000", 19 * sizeof(WCHAR));
- Status = STATUS_SUCCESS;
-
- }
-
- ExFreePool(Path);
- return Status;
-}
-
-//-------------------------------------------------------------------
-
-NTSTATUS STDCALL
-NPF_QueryRegistryRoutine(
- IN PWSTR ValueName,
- IN ULONG ValueType,
- IN PVOID ValueData,
- IN ULONG ValueLength,
- IN PVOID Context,
- IN PVOID EntryContext
- )
-
-{
-
- PUCHAR Buffer;
-
- IF_LOUD(DbgPrint("Perf: QueryRegistryRoutine\n");)
-
- if (ValueType != REG_MULTI_SZ) {
-
- return STATUS_OBJECT_NAME_NOT_FOUND;
-
- }
-
-#define NPF_TAG_REGBUF TAG('8', 'P', 'W', 'A')
- Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, NPF_TAG_REGBUF);
-
- if (Buffer==NULL) {
-
- return STATUS_INSUFFICIENT_RESOURCES;
-
- }
-
- RtlCopyMemory(
- Buffer,
- ValueData,
- ValueLength
- );
-
- *((PUCHAR *)EntryContext)=Buffer;
-
- return STATUS_SUCCESS;
-
-}
+++ /dev/null
-/*
- * Copyright (c) 1999, 2000
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/** @ingroup NPF
- * @{
- */
-
-/** @defgroup NPF_include NPF structures and definitions
- * @{
- */
-
-#ifndef __PACKET_INCLUDE______
-#define __PACKET_INCLUDE______
-
-#define NTKERNEL ///< Forces the compilation of the jitter with kernel calls
-
-struct bpf_insn;
-#undef EXIT_SUCCESS
-#undef EXIT_FAILURE
-
-#include "jitter.h"
-#include "tme.h"
-
-#define MAX_REQUESTS 32 ///< Maximum number of simultaneous IOCTL requests.
-
-#define Packet_ALIGNMENT sizeof(int) ///< Alignment macro. Defines the alignment size.
-#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) ///< Alignment macro. Rounds up to the next
- ///< even multiple of Packet_ALIGNMENT.
-
-
-/***************************/
-/* 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 2147483648UL
-
-/*!
- \brief IOCTL code: get an OID value
-
- This IOCTL is used to perform an OID get operation on the NIC driver.
-*/
-#define BIOCQUERYOID 2147483652UL
-
-/*!
- \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().
-} 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 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.
- INT Received; ///< Number of packets received by current instance from its opening, i.e. number of
- ///< packet received by the network adapter since the beginning of the
- ///< capture/monitoring/dump session.
- INT Dropped; ///< Number of packet that current instance had to drop, from its opening. A packet
- ///< is dropped if there is no more space to store it in the circular buffer that the
- ///< driver associates to current instance.
- INT Accepted; ///< Number of packet that current capture instance acepted, from its opening. A packet
- ///< is accepted if it passes the filter and fits in the buffer. Accepted packets are the
- ///< ones that reach the application.
- PUCHAR bpfprogram; ///< Pointer to the filtering pseudo-code associated with current instance of the driver.
- ///< This code is used only in particular situations (for example when the packet received
- ///< from the NIC driver is stored in two non-consecutive buffers. In normal situations
- ///< the filtering routine created by the JIT compiler and pointed by the next field
- ///< is used. See \ref NPF for details on the filtering process.
- JIT_BPF_Filter *Filter; ///< Pointer to the native filtering function created by the jitter.
- ///< See BPF_jitter() for details.
- PUCHAR Buffer; ///< Pointer to the circular buffer associated with every driver instance. It contains the
- ///< data that will be passed to the application. See \ref NPF for details.
- UINT Bhead; ///< Head of the circular buffer.
- UINT Btail; ///< Tail of the circular buffer.
- UINT BufSize; ///< Size of the circular buffer.
- UINT BLastByte; ///< Position of the last valid byte in the circular buffer.
- PMDL TransferMdl; ///< MDL used to map the portion of the buffer that will contain an incoming packet.
- ///< Used by NdisTransferData().
- NDIS_SPIN_LOCK BufLock; ///< SpinLock that protects the access tho the circular buffer variables.
- UINT MinToCopy; ///< Minimum amount of data in the circular buffer that unlocks a read. Set with the
- ///< BIOCSMINTOCOPY IOCTL.
- LARGE_INTEGER TimeOut; ///< Timeout after which a read is released, also if the amount of data in the buffer is
- ///< less than MinToCopy. Set with the BIOCSRTIMEOUT IOCTL.
-
- int mode; ///< Working mode of the driver. See PacketSetMode() for details.
- LARGE_INTEGER Nbytes; ///< Amount of bytes accepted by the filter when this instance is in statistical mode.
- LARGE_INTEGER Npackets; ///< Number of packets accepted by the filter when this instance is in statistical mode.
- NDIS_SPIN_LOCK CountersLock; ///< SpinLock that protects the statistical mode counters.
- UINT Nwrites; ///< Number of times a single write must be physically repeated. See \ref NPF for an
- ///< explanation
- UINT Multiple_Write_Counter; ///< Counts the number of times a single write has already physically repeated.
- NDIS_EVENT WriteEvent; ///< Event used to synchronize the multiple write process.
- NDIS_EVENT IOEvent; ///< Event used to synchronize I/O requests with the callback structure of NDIS.
- NDIS_STATUS IOStatus; ///< Maintains the status of and OID request call, that will be passed to the application.
- BOOLEAN Bound; ///< Specifies if NPF is still bound to the adapter used by this instance. Bound can be
- ///< FALSE if a Plug and Play adapter has been removed or disabled by the user.
- HANDLE DumpFileHandle; ///< Handle of the file used in dump mode.
- PFILE_OBJECT DumpFileObject; ///< Pointer to the object of the file used in dump mode.
- PKTHREAD DumpThreadObject; ///< Pointer to the object of the thread used in dump mode.
- HANDLE DumpThreadHandle; ///< Handle of the thread created by dump mode to asynchronously move the buffer to disk.
- NDIS_EVENT DumpEvent; ///< Event used to synchronize the dump thread with the tap when the instance is in dump mode.
- LARGE_INTEGER DumpOffset; ///< Current offset in the dump file.
- UNICODE_STRING DumpFileName; ///< String containing the name of the dump file.
- UINT MaxDumpBytes; ///< Maximum dimension in bytes of the dump file. If the dump file reaches this size it
- ///< will be closed. A value of 0 means unlimited size.
- UINT MaxDumpPacks; ///< Maximum number of packets that will be saved in the dump file. If this number of
- ///< packets is reached the dump will be closed. A value of 0 means unlimited number of
- ///< packets.
- BOOLEAN DumpLimitReached; ///< TRUE if the maximum dimension of the dump file (MaxDumpBytes or MaxDumpPacks) is
- ///< reached.
- MEM_TYPE mem_ex; ///< Memory used by the TME virtual co-processor
- TME_CORE tme; ///< Data structure containing the virtualization of the TME co-processor
- NDIS_SPIN_LOCK machine_lock; ///< SpinLock that protects the mem_ex buffer
- UINT MaxFrameSize; ///< Maximum frame size that the underlying MAC acceptes. Used to perform a check on the
- ///< size of the frames sent with NPF_Write() or NPF_BufferedWrite().
-} OPEN_INSTANCE, *POPEN_INSTANCE;
-
-
-#define TRANSMIT_PACKETS 256 ///< Maximum number of packets in the transmit packet pool. This value is an upper bound to the number
- ///< of packets that can be transmitted at the same time or with a single call to NdisSendPackets.
-
-
-/// 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 STDCALL
-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 STDCALL
-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 STDCALL
-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 STDCALL
-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 STDCALL
-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 STDCALL
-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 STDCALL
-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 STDCALL
-NPF_IoControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- );
-
-
-/*!
- \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().
-*/
-VOID STDCALL
-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 STDCALL
-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 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 STDCALL
-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 STDCALL
-NPF_ResetComplete(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN NDIS_STATUS Status
- );
-
-/*!
- \brief Callback for NDIS StatusHandler. Not used by NPF
-*/
-VOID STDCALL
-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 STDCALL
-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 STDCALL
-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 STDCALL
-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 STDCALL
-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 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.
-*/
-int bpf_validate(struct bpf_insn *f,int 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.
-*/
-UINT bpf_filter(register struct bpf_insn *pc,
- register UCHAR *p,
- UINT wirelen,
- register UINT buflen,
- PMEM_TYPE mem_ex,
- PTME_CORE tme,
- struct time_conv *time_ref);
-
-/*!
- \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.
-*/
-UINT bpf_filter_with_2_buffers(register struct bpf_insn *pc,
- register UCHAR *p,
- register UCHAR *pd,
- register int headersize,
- UINT wirelen,
- register UINT buflen,
- PMEM_TYPE mem_ex,
- PTME_CORE tme,
- struct time_conv *time_ref);
-
-/*!
- \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(POPEN_INSTANCE 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*/
+++ /dev/null
-/*
- * Copyright (c) 1999, 2000
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifdef _MSC_VER
-#include <stdarg.h>
-#include <ntddk.h>
-#include <ntiologc.h>
-#include <ndis.h>
-#else
-#include <ntddk.h>
-#include <ndis.h>
-
-#define NdisReinitializePacket(Packet) \
-{ \
- (Packet)->Private.Head = (PNDIS_BUFFER)NULL; \
- (Packet)->Private.ValidCounts = FALSE; \
-}
-
-
-#endif
-
-#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
-
-//-------------------------------------------------------------------
-
-UINT GetBuffOccupation(POPEN_INSTANCE Open)
-{
- UINT Occupation;
-
- NdisAcquireSpinLock( &Open->BufLock );
-
- if(Open->Btail >= Open->Bhead) Occupation = Open->Btail-Open->Bhead;
- else Occupation = Open->BLastByte-Open->Bhead+Open->Btail;
-
- NdisReleaseSpinLock( &Open->BufLock );
-
- return Occupation;
-}
-
-//-------------------------------------------------------------------
-
-void PacketMoveMem(PVOID Destination, PVOID Source, ULONG Length, UINT *Bhead)
-{
-ULONG WordLength;
-UINT n,i,NBlocks;
-PULONG ULSrc, ULDest;
-PUCHAR UCSrc, UCDest;
-
- WordLength=Length>>2;
- NBlocks=WordLength>>8;
-
- ULSrc = (PULONG) Source;
- ULDest = (PULONG) Destination;
- for(n=0;n<NBlocks;n++){
- for(i=0;i<256;i++){
- *ULDest++ = *ULSrc++;
- }
- *Bhead+=1024;
- }
-
- n=WordLength-(NBlocks<<8);
- for(i=0;i<n;i++){
- *ULDest++ = *ULSrc++;
- }
- *Bhead+=n<<2;
-
- UCDest = (PUCHAR) ULDest;
- UCSrc = (PUCHAR) ULSrc;
- n=Length-(WordLength<<2);
- for(i=0;i<n;i++){
- *UCDest++ = *UCSrc++;
- }
- *Bhead+=n;
-}
-
-//-------------------------------------------------------------------
-
-NTSTATUS STDCALL
-NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
-{
- POPEN_INSTANCE Open;
- PIO_STACK_LOCATION IrpSp;
- PUCHAR packp;
- ULONG Input_Buffer_Length;
- UINT Thead;
- UINT Ttail;
- UINT TLastByte;
- PUCHAR CurrBuff;
- struct bpf_hdr *header;
- PUCHAR UserPointer;
- ULONG bytecopy;
- UINT SizeToCopy;
- UINT PktLen;
-
- IF_LOUD(DbgPrint("NPF: Read\n");)
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- Open=IrpSp->FileObject->FsContext;
-
- if( Open->Bound == FALSE ){
- // The Network adapter was removed.
- 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);
- }
-
- //See if the buffer is full enough to be copied
- if( GetBuffOccupation(Open) <= Open->MinToCopy || 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
- CurrBuff=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress);
-
- //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;
- }
-
- if(Open->mode==MODE_MON) //this capture instance is in monitor mode
- {
- PTME_DATA data;
- ULONG cnt;
- ULONG block_size;
- PUCHAR tmp;
-
- UserPointer=MmGetSystemAddressForMdl(Irp->MdlAddress);
-
- 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->machine_lock);
- RtlCopyMemory(UserPointer,tmp,block_size);
- NdisReleaseSpinLock(&Open->machine_lock);
- 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));
- }
-
- if (Open->Bhead == Open->Btail || 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);
- }
-
- }
-
- //
- // The buffer if full enough to be copied,
- //
- NdisAcquireSpinLock( &Open->BufLock );
-
- Thead = Open->Bhead;
- Ttail = Open->Btail;
- TLastByte = Open->BLastByte;
-
- //get the address of the buffer
- CurrBuff=Open->Buffer;
-
- NdisReleaseSpinLock( &Open->BufLock );
-
- Input_Buffer_Length=IrpSp->Parameters.Read.Length;
- packp=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress);
-
-
- //
- //fill the application buffer
- //
- if(Ttail > Thead){ //first of all see if it we can copy all the buffer in one time
- if((Ttail-Thead)<Input_Buffer_Length){
- KeResetEvent(Open->ReadEvent);
-
- PacketMoveMem(packp,CurrBuff+Thead,Ttail-Thead,&(Open->Bhead));
- EXIT_SUCCESS(Ttail-Thead);
- }
- }
- else if((TLastByte - Thead) < Input_Buffer_Length){
- PacketMoveMem(packp, CurrBuff+Thead, TLastByte - Thead, &(Open->Bhead));
-
- NdisAcquireSpinLock( &Open->BufLock );
-
- Open->BLastByte = Open->Btail;
- Open->Bhead = 0;
-
- NdisReleaseSpinLock( &Open->BufLock );
-
- EXIT_SUCCESS(TLastByte-Thead);
- }
-
- //the buffer must be scannned to determine the number of bytes to copy
- SizeToCopy = 0;
- while(TRUE){
- if(Thead + SizeToCopy == Ttail)
- break;
-
- if(Thead + SizeToCopy == TLastByte && TLastByte != Ttail){
-
- PacketMoveMem(packp, CurrBuff+Thead, SizeToCopy, &(Open->Bhead));
- // Reset the buffer
- NdisAcquireSpinLock( &Open->BufLock );
- Open->BLastByte = (UINT) -1;
- Open->Bhead = 0;
- NdisReleaseSpinLock( &Open->BufLock );
-
- EXIT_SUCCESS(SizeToCopy);
- }
-
- // Get the size of the next packet in the buffer
- PktLen = ((struct bpf_hdr*)(CurrBuff + Thead + SizeToCopy))->bh_caplen + sizeof(struct bpf_hdr);
-
- // The length is aligned to 32-bit boundary
- PktLen = Packet_WORDALIGN(PktLen);
-
- if(SizeToCopy + PktLen > Input_Buffer_Length)
- break;
-
- SizeToCopy += PktLen;
- }
-
- PacketMoveMem(packp, CurrBuff+Thead, SizeToCopy, &(Open->Bhead));
- EXIT_SUCCESS(SizeToCopy);
-
-}
-
-//-------------------------------------------------------------------
-
-NDIS_STATUS STDCALL 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 pPacketb;
- ULONG SizeToTransfer;
- NDIS_STATUS Status;
- UINT BytesTransfered;
- ULONG BufferLength;
- PMDL pMdl;
- struct bpf_hdr *header;
- PUCHAR CurrBuff;
- UINT Thead;
- UINT Ttail;
- UINT TLastByte;
- UINT fres;
- UINT maxbufspace;
- USHORT NPFHdrSize;
- UINT BufOccupation;
- BOOLEAN ResetBuff = FALSE;
-
- IF_VERY_LOUD(DbgPrint("NPF: tap\n");)
- IF_VERY_LOUD(DbgPrint("HeaderBufferSize=%d, LookAheadBuffer=%d, LookaheadBufferSize=%d, PacketSize=%d\n",
- HeaderBufferSize,
- LookAheadBuffer,
- LookaheadBufferSize,
- PacketSize);)
-
- Open= (POPEN_INSTANCE)ProtocolBindingContext;
-
- Open->Received++; // Number of packets received by filter ++
-
- BufOccupation = GetBuffOccupation(Open); // Get the full buffer space
-
- if(((Open->mode&MODE_CAPT)||(Open->mode&MODE_DUMP)) && Open->BufSize - BufOccupation < PacketSize+HeaderBufferSize+sizeof(struct bpf_hdr)){
- // Heuristic that drops the packet also if it possibly fits in the buffer.
- // It allows to avoid filtering in critical situations when CPU is very important.
- Open->Dropped++;
- return NDIS_STATUS_NOT_ACCEPTED;
- }
-
- NdisAcquireSpinLock(&Open->machine_lock);
-
- //
- //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)LookAheadBuffer-(UINT)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
- if(Open->Filter != NULL)
- {
- if (Open->bpfprogram != NULL)
- {
- fres=Open->Filter->Function(HeaderBuffer,
- PacketSize+HeaderBufferSize,
- LookaheadBufferSize+HeaderBufferSize);
-
- // Restore the stack.
- // I ignore the reason, but this instruction is needed only at kernel level
-#ifndef __GNUC__
- _asm add esp,12
-#else
- asm("add $0x12,%esp;");
-#endif
- }
- else
- fres = -1;
- }
- else
- fres=bpf_filter((struct bpf_insn*)(Open->bpfprogram),
- HeaderBuffer,
- PacketSize+HeaderBufferSize,
- LookaheadBufferSize+HeaderBufferSize,
- &Open->mem_ex,
- &Open->tme,
- &G_Start_Time);
-
- NdisReleaseSpinLock(&Open->machine_lock);
-
- if(Open->mode==MODE_MON)
- // we are in monitor mode
- {
- if (fres==1)
- KeSetEvent(Open->ReadEvent,0,FALSE);
- return NDIS_STATUS_NOT_ACCEPTED;
-
- }
-
- if(fres==0)
- // Packet not accepted by the filter, ignore it.
- return NDIS_STATUS_NOT_ACCEPTED;
-
- //if the filter returns -1 the whole packet must be accepted
- if(fres==(UINT)-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)){
- return NDIS_STATUS_NOT_ACCEPTED;
- }
- }
-
- if(Open->BufSize==0)return NDIS_STATUS_NOT_ACCEPTED;
-
- if(Open->mode & MODE_DUMP && Open->MaxDumpPacks && (UINT)Open->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);
-
- return NDIS_STATUS_NOT_ACCEPTED;
- }
-
- // Calculate the correct size for the header associated with the packet
- NPFHdrSize=(Open->mode==MODE_CAPT)? sizeof(struct bpf_hdr): sizeof(struct sf_pkthdr);
-
- NdisAcquireSpinLock( &Open->BufLock );
-
- Thead=Open->Bhead;
- Ttail=Open->Btail;
- TLastByte = Open->BLastByte;
-
- NdisReleaseSpinLock( &Open->BufLock );
-
- maxbufspace=Packet_WORDALIGN(fres+NPFHdrSize);
-
- if(Ttail+maxbufspace >= Open->BufSize){
- if(Thead <= maxbufspace)
- {
- Open->Dropped++;
- return NDIS_STATUS_NOT_ACCEPTED;
- }
- else{
- Ttail=0;
- ResetBuff = TRUE;
- }
- }
-
- if (Thead > Ttail && (Thead-Ttail) <= maxbufspace)
- {
- Open->Dropped++;
- return NDIS_STATUS_NOT_ACCEPTED;
- }
-
- CurrBuff=Open->Buffer+Ttail;
-
- if(LookaheadBufferSize != PacketSize || (UINT)LookAheadBuffer-(UINT)HeaderBuffer != HeaderBufferSize)
- {
- // Allocate an MDL to map the portion of the buffer following the header
- pMdl=IoAllocateMdl(CurrBuff+HeaderBufferSize+LookaheadBufferSize+NPFHdrSize,
- maxbufspace,
- FALSE,
- FALSE,
- NULL);
-
- if (pMdl == NULL)
- {
- // Unable to map the memory: packet lost
- IF_LOUD(DbgPrint("NPF: Read-Failed to allocate Mdl\n");)
- Open->Dropped++;
- return NDIS_STATUS_NOT_ACCEPTED;
- }
- MmBuildMdlForNonPagedPool(pMdl);
-
- //allocate the packet from NDIS
- NdisAllocatePacket(&Status, &pPacketb, Open->PacketPool);
- if (Status != NDIS_STATUS_SUCCESS)
- {
- IF_LOUD(DbgPrint("NPF: Tap - No free packets\n");)
- IoFreeMdl(pMdl);
- Open->Dropped++;
- return NDIS_STATUS_NOT_ACCEPTED;
- }
- //link the buffer to the packet
- NdisChainBufferAtFront(pPacketb,pMdl);
-
- BufferLength=fres-HeaderBufferSize;
- //Find out how much to transfer
- SizeToTransfer = (PacketSize < BufferLength) ? PacketSize : BufferLength;
-
- //copy the ethernet header into buffer
- NdisMoveMappedMemory((CurrBuff)+NPFHdrSize,HeaderBuffer,HeaderBufferSize);
-
- //Copy the look ahead buffer
- if(LookaheadBufferSize)
- {
- NdisMoveMappedMemory((CurrBuff) + NPFHdrSize + HeaderBufferSize,
- LookAheadBuffer,
- (SizeToTransfer < LookaheadBufferSize)? SizeToTransfer : LookaheadBufferSize );
-
- SizeToTransfer = (SizeToTransfer > LookaheadBufferSize)?
- SizeToTransfer - LookaheadBufferSize : 0;
- }
-
- Open->TransferMdl=pMdl;
-
- if(SizeToTransfer)
- {
- //Call the Mac to transfer the packet
- NdisTransferData(&Status,
- Open->AdapterHandle,
- MacReceiveContext,
- LookaheadBufferSize,
- SizeToTransfer,
- pPacketb,
- &BytesTransfered);
- }
- else{
- BytesTransfered = 0;
- }
-
- }
- else
- {
- // The whole packet is in the lookahead buffer, we can avoid the call to NdisTransferData.
- // This allows us to avoid the allocation of the MDL and the NDIS packet as well
- RtlCopyMemory((CurrBuff) + NPFHdrSize,
- HeaderBuffer,
- HeaderBufferSize + LookaheadBufferSize);
-
- BytesTransfered = 0;
-
- Open->TransferMdl = NULL;
- Status = NDIS_STATUS_SUCCESS;
- }
-
- if (Status != NDIS_STATUS_FAILURE)
- {
-
- Open->Accepted++; // Increase the accepted packets counter
-
- if( fres > (BytesTransfered+HeaderBufferSize+LookaheadBufferSize) )
- fres = BytesTransfered+HeaderBufferSize+LookaheadBufferSize;
-
- //
- // Build the header
- //
- header=(struct bpf_hdr*)CurrBuff;
- GET_TIME(&header->bh_tstamp,&G_Start_Time);
- header->bh_caplen=fres;
- header->bh_datalen=PacketSize+HeaderBufferSize;
- if(Open->mode==MODE_CAPT){
- header->bh_hdrlen=NPFHdrSize;
- // Don't align if the packet goes to disk
- Ttail+=Packet_WORDALIGN(fres + NPFHdrSize);
- }
- else
- Ttail+=fres+NPFHdrSize;
-
- //update the buffer
- NdisAcquireSpinLock( &Open->BufLock );
-
- if(ResetBuff){
- Open->BLastByte = Open->Btail;
- }
- Open->Btail=Ttail;
-
- NdisReleaseSpinLock( &Open->BufLock );
- }
-
- if (Status != NDIS_STATUS_PENDING){
-
- if( Open->TransferMdl != NULL)
- // Complete the request and free the buffers
- NPF_TransferDataComplete(Open,pPacketb,Status,fres);
- else{
- // Unfreeze the consumer
- if(GetBuffOccupation(Open)>Open->MinToCopy){
- if(Open->mode & MODE_DUMP){
- NdisSetEvent(&Open->DumpEvent);
- }
- else
- KeSetEvent(Open->ReadEvent,0,FALSE);
- }
-
- }
- }
-
- return NDIS_STATUS_SUCCESS;
-
-}
-
-//-------------------------------------------------------------------
-
-VOID STDCALL NPF_TransferDataComplete (IN NDIS_HANDLE ProtocolBindingContext,IN PNDIS_PACKET pPacket,
- IN NDIS_STATUS Status,IN UINT BytesTransfered)
-{
- POPEN_INSTANCE Open;
-
- IF_LOUD(DbgPrint("NPF: TransferDataComplete\n");)
-
- Open= (POPEN_INSTANCE)ProtocolBindingContext;
-
- IoFreeMdl(Open->TransferMdl);
- //recylcle the packet
- NdisReinitializePacket(pPacket);
- //Put the packet on the free queue
- NdisFreePacket(pPacket);
- // Unfreeze the consumer
- if(GetBuffOccupation(Open)>Open->MinToCopy){
- if(Open->mode & MODE_DUMP){
- NdisSetEvent(&Open->DumpEvent);
- }
- else
- KeSetEvent(Open->ReadEvent,0,FALSE);
- }
- return;
-}
-
-//-------------------------------------------------------------------
-
-VOID STDCALL NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext)
-{
- IF_VERY_LOUD(DbgPrint("NPF: NPF_ReceiveComplete\n");)
- return;
-}
+++ /dev/null
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by NPF.RC
-//
-
-// 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
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#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
-
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "tme.h"
-#include "win_bpf.h"
-#include "time_calls.h"
-
-
-void TIME_DESYNCHRONIZE(struct time_conv *data)
-{
- data->reference = 0;
- data->start.tv_sec = 0;
- data->start.tv_usec = 0;
-}
-
-#ifdef KQPC_TS
-
-/* KeQueryPerformanceCounter TimeStamps */
-
-VOID TIME_SYNCHRONIZE(struct time_conv *data)
-{
- struct timeval tmp;
- LARGE_INTEGER SystemTime;
- LARGE_INTEGER TimeFreq,PTime;
-
- if (data->reference!=0)
- return;
-
- // get the absolute value of the system boot time.
- PTime=KeQueryPerformanceCounter(&TimeFreq);
- KeQuerySystemTime(&SystemTime);
-#ifndef __GNUC__
- tmp.tv_sec=(LONG)(SystemTime.QuadPart/10000000-11644473600);
- tmp.tv_usec=(LONG)((SystemTime.QuadPart%10000000)/10);
- tmp.tv_sec-=(ULONG)(PTime.QuadPart/TimeFreq.QuadPart);
- tmp.tv_usec-=(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
-#else
- // TODO FIXME:
- tmp.tv_sec = 0;
- tmp.tv_usec = 0;
-#endif
- if (tmp.tv_usec<0) {
- tmp.tv_sec--;
- tmp.tv_usec+=1000000;
- }
- data->start=tmp;
- data->reference=1;
-}
-
-void FORCE_TIME(struct timeval *src, struct time_conv *dest)
-{
- dest->start=*src;
-}
-
-void GET_TIME(struct timeval *dst, struct time_conv *data)
-{
- LARGE_INTEGER PTime, TimeFreq;
-
- PTime=KeQueryPerformanceCounter(&TimeFreq);
-#ifndef __GNUC__
- tmp=(LONG)(PTime.QuadPart/TimeFreq.QuadPart);
- dst->tv_sec=data->start.tv_sec+tmp;
- dst->tv_usec=data->start.tv_usec+(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
-#else
- // TODO FIXME:
-#endif
- if (dst->tv_usec>=1000000) {
- dst->tv_sec++;
- dst->tv_usec-=1000000;
- }
-}
-
-#else /*KQPC_TS*/
-
-/*RDTSC timestamps*/
-
-/* callers must be at IRQL=PASSIVE_LEVEL */
-VOID TIME_SYNCHRONIZE(struct time_conv *data)
-{
- 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);
-#ifndef __GNUC__
- __asm
- {
- push eax
- push edx
- push ecx
- rdtsc
- lea ecx, start_ticks
- mov [ecx+4], edx
- mov [ecx], eax
- pop ecx
- pop edx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%edx;"
- "push %%ecx;"
- "rdtsc;"
- "lea %0,%%ecx;"
- "mov %%edx,(%%ecx+4);"
- "mov %%eax,(%%ecx);"
- "pop %%ecx;"
- "pop %%edx;"
- "pop %%eax;"
- :"=c"(start_ticks): );
-#endif
- KeLowerIrql(old);
- KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i);
- KeRaiseIrql(HIGH_LEVEL,&old);
- stop_kqpc=KeQueryPerformanceCounter(&stop_freq);
-#ifndef __GNUC__
- __asm
- {
- push eax
- push edx
- push ecx
- rdtsc
- lea ecx, stop_ticks
- mov [ecx+4], edx
- mov [ecx], eax
- pop ecx
- pop edx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%edx;"
- "push %%ecx;"
- "rdtsc;"
- "lea %0,%%ecx;"
- "mov %%edx,(%%ecx+4);"
- "mov %%eax,(%%ecx);"
- "pop %%ecx;"
- "pop %%edx;"
- "pop %%eax;"
- :"=c"(stop_ticks): );
-#endif
- KeLowerIrql(old);
- delta=stop_ticks-start_ticks;
- delta2=stop_kqpc.QuadPart-start_kqpc.QuadPart;
- if (delta>10000000000) {
- delta/=16;
- delta2/=16;
- }
- reference=delta*(start_freq.QuadPart)/delta2;
- data->reference=reference/1000;
- if (reference%1000>500)
- data->reference++;
- data->reference*=1000;
- reference=data->reference;
- KeQuerySystemTime(&system_time);
-#ifndef __GNUC__
- __asm
- {
- push eax
- push edx
- push ecx
- rdtsc
- lea ecx, curr_ticks
- mov [ecx+4], edx
- mov [ecx], eax
- pop ecx
- pop edx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%edx;"
- "push %%ecx;"
- "rdtsc;"
- "lea %0,%%ecx;"
- "mov %%edx,(%%ecx+4);"
- "mov %%eax,(%%ecx);"
- "pop %%ecx;"
- "pop %%edx;"
- "pop %%eax;"
- :"=c"(curr_ticks): );
-#endif
- tmp.tv_sec=-(LONG)(curr_ticks/reference);
- tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference);
- system_time.QuadPart-=116444736000000000;
- tmp.tv_sec+=(LONG)(system_time.QuadPart/10000000);
- tmp.tv_usec+=(LONG)((system_time.QuadPart%10000000)/10);
- if (tmp.tv_usec<0) {
- tmp.tv_sec--;
- tmp.tv_usec+=1000000;
- }
- data->start=tmp;
- IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);)
-}
-
-void FORCE_TIME(struct timeval *src, struct time_conv *dest)
-{
- dest->start=*src;
-}
-
-void GET_TIME(struct timeval *dst, struct time_conv *data)
-{
- ULONGLONG tmp;
-#ifndef __GNUC__
- __asm
- {
- push eax
- push edx
- push ecx
- rdtsc
- lea ecx, tmp
- mov [ecx+4], edx
- mov [ecx], eax
- pop ecx
- pop edx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%edx;"
- "push %%ecx;"
- "rdtsc;"
- "lea %0,%%ecx;"
- "mov %%edx,(%%ecx+4);"
- "mov %%eax,(%%ecx);"
- "pop %%ecx;"
- "pop %%edx;"
- "pop %%eax;"
- :"=c"(tmp): );
-#endif
- if (data->reference==0) {
- return;
- }
- dst->tv_sec=(LONG)(tmp/data->reference);
- dst->tv_usec=(LONG)((tmp-dst->tv_sec*data->reference)*1000000/data->reference);
- dst->tv_sec+=data->start.tv_sec;
- dst->tv_usec+=data->start.tv_usec;
- if (dst->tv_usec>=1000000) {
- dst->tv_sec++;
- dst->tv_usec-=1000000;
- }
-}
-
-#endif /*KQPC_TS*/
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _time_calls
-#define _time_calls
-
-#ifdef WIN_NT_DRIVER
-
-#include "debug.h"
-
-/*!
- \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;
-};
-
-#ifdef __GNUC__
-
-void TIME_DESYNCHRONIZE(struct time_conv *data);
-VOID TIME_SYNCHRONIZE(struct time_conv *data);
-void FORCE_TIME(struct timeval *src, struct time_conv *dest);
-void GET_TIME(struct timeval *dst, struct time_conv *data);
-
-#else /* __GNUC__ */
-
-#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;
-}
-
-#ifdef KQPC_TS
-
-/* KeQueryPerformanceCounter TimeStamps */
-
-__inline VOID TIME_SYNCHRONIZE(struct time_conv *data)
-{
- struct timeval tmp;
- LARGE_INTEGER SystemTime;
- LARGE_INTEGER i;
- ULONG tmp2;
- LARGE_INTEGER TimeFreq,PTime;
-
- if (data->reference!=0)
- return;
-
- // get the absolute value of the system boot time.
- PTime=KeQueryPerformanceCounter(&TimeFreq);
- KeQuerySystemTime(&SystemTime);
- tmp.tv_sec=(LONG)(SystemTime.QuadPart/10000000-11644473600);
- tmp.tv_usec=(LONG)((SystemTime.QuadPart%10000000)/10);
- tmp.tv_sec-=(ULONG)(PTime.QuadPart/TimeFreq.QuadPart);
- tmp.tv_usec-=(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
- if (tmp.tv_usec<0) {
- tmp.tv_sec--;
- tmp.tv_usec+=1000000;
- }
- data->start=tmp;
- data->reference=1;
-}
-
-__inline void GET_TIME(struct timeval *dst, struct time_conv *data)
-{
- LARGE_INTEGER PTime, TimeFreq;
- LONG tmp;
-
- PTime=KeQueryPerformanceCounter(&TimeFreq);
- tmp=(LONG)(PTime.QuadPart/TimeFreq.QuadPart);
- dst->tv_sec=data->start.tv_sec+tmp;
- dst->tv_usec=data->start.tv_usec+(LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart);
- if (dst->tv_usec>=1000000) {
- dst->tv_sec++;
- dst->tv_usec-=1000000;
- }
-}
-
-__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest)
-{
- dest->start=*src;
-}
-
-#else
-
-/*RDTSC timestamps*/
-
-/* callers must be at IRQL=PASSIVE_LEVEL */
-__inline VOID TIME_SYNCHRONIZE(struct time_conv *data)
-{
- struct timeval tmp;
- LARGE_INTEGER system_time;
- ULONGLONG curr_ticks;
- KIRQL old;
- LARGE_INTEGER start_kqpc,stop_kqpc,start_freq,stop_freq;
- ULONGLONG start_ticks,stop_ticks;
- ULONGLONG delta,delta2;
- KEVENT event;
- LARGE_INTEGER i;
- ULONGLONG reference;
-
- if (data->reference!=0)
- return;
-
- KeInitializeEvent(&event,NotificationEvent,FALSE);
- i.QuadPart=-3500000;
- KeRaiseIrql(HIGH_LEVEL,&old);
- start_kqpc=KeQueryPerformanceCounter(&start_freq);
-#ifndef __GNUC__
- __asm
- {
- push eax
- push edx
- push ecx
- rdtsc
- lea ecx, start_ticks
- mov [ecx+4], edx
- mov [ecx], eax
- pop ecx
- pop edx
- pop eax
- }
-#else
-#endif
- KeLowerIrql(old);
- KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i);
- KeRaiseIrql(HIGH_LEVEL,&old);
- stop_kqpc=KeQueryPerformanceCounter(&stop_freq);
-#ifndef __GNUC__
- __asm
- {
- push eax
- push edx
- push ecx
- rdtsc
- lea ecx, stop_ticks
- mov [ecx+4], edx
- mov [ecx], eax
- pop ecx
- pop edx
- pop eax
- }
-#else
-#endif
- KeLowerIrql(old);
- delta=stop_ticks-start_ticks;
- delta2=stop_kqpc.QuadPart-start_kqpc.QuadPart;
- if (delta>10000000000) {
- delta/=16;
- delta2/=16;
- }
- reference=delta*(start_freq.QuadPart)/delta2;
- data->reference=reference/1000;
- if (reference%1000>500)
- data->reference++;
- data->reference*=1000;
- reference=data->reference;
- KeQuerySystemTime(&system_time);
-#ifndef __GNUC__
- __asm
- {
- push eax
- push edx
- push ecx
- rdtsc
- lea ecx, curr_ticks
- mov [ecx+4], edx
- mov [ecx], eax
- pop ecx
- pop edx
- pop eax
- }
-#else
-#endif
- tmp.tv_sec=-(LONG)(curr_ticks/reference);
- tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference);
- system_time.QuadPart-=116444736000000000;
- tmp.tv_sec+=(LONG)(system_time.QuadPart/10000000);
- tmp.tv_usec+=(LONG)((system_time.QuadPart%10000000)/10);
- if (tmp.tv_usec<0) {
- tmp.tv_sec--;
- tmp.tv_usec+=1000000;
- }
- data->start=tmp;
- IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data->reference);)
-}
-
-__inline void FORCE_TIME(struct timeval *src, struct time_conv *dest)
-{
- dest->start=*src;
-}
-
-__inline void GET_TIME(struct timeval *dst, struct time_conv *data)
-{
- ULONGLONG tmp;
-#ifndef __GNUC__
- __asm
- {
- push eax
- push edx
- push ecx
- rdtsc
- lea ecx, tmp
- mov [ecx+4], edx
- mov [ecx], eax
- pop ecx
- pop edx
- pop eax
- }
-#else
-#endif
- if (data->reference==0) {
- return;
- }
- dst->tv_sec=(LONG)(tmp/data->reference);
- dst->tv_usec=(LONG)((tmp-dst->tv_sec*data->reference)*1000000/data->reference);
- dst->tv_sec+=data->start.tv_sec;
- dst->tv_usec+=data->start.tv_usec;
- if (dst->tv_usec>=1000000) {
- dst->tv_sec++;
- dst->tv_usec-=1000000;
- }
-}
-
-#endif /*KQPC_TS*/
-
-#endif /*WIN_NT_DRIVER*/
-
-#endif /* __GNUC__ */
-
-#endif /*_time_calls*/
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifdef WIN32
-#include "tme.h"
-#endif
-
-#ifdef __FreeBSD__
-#include <net/tme/tme.h>
-#endif
-
-/* 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;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef __tme_include_
-#define __tme_include_
-
-#ifdef WIN_NT_DRIVER
-
-#include "ntddk.h"
-#include "memory_t.h"
-#include "time_calls.h"
-#endif /*WIN_NT_DRIVER*/
-
-#ifdef WIN32
-#include "memory_t.h"
-#include "time_calls.h"
-#endif /*WIN32*/
-
-
-
-#ifdef __FreeBSD__
-
-#ifdef _KERNEL
-#include <net/tme/time_calls.h>
-#else
-#include <tme/time_calls.h>
-#endif
-
-#endif
-
-/* 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 */
-#ifndef __GNUC__
-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);
-#else
-typedef uint32 (*lut_fcn)(uint8 *key, void *data,MEM_TYPE *mem_ex, struct time_conv *time_ref );
-typedef uint32 (*exec_fcn)(uint8 *block, uint32 pkt_size, void *data, MEM_TYPE *mem_ex, uint8 *mem_data);
-#endif
-
-/* 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
-
+++ /dev/null
-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,
- 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,
- 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,
- 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,
- 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,
- 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
- };
-
-#define VALID_INSTRUCTIONS_LEN (sizeof(valid_instructions)/sizeof(u_short))
+++ /dev/null
-/*-
- * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/drivers/net/npf/win_bpf.h,v 1.1 2003/01/08 19:55:02 robd Exp $ (LBL)
- */
-
-#ifndef BPF_MAJOR_VERSION
-
-/* BSD style release date */
-#define BPF_RELEASE 199606
-
-#ifndef _BSDTYPES_DEFINED
-typedef UCHAR u_char;
-typedef USHORT u_short;
-typedef UINT 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
-
-#include "time_calls.h"
-
-/*
- * The instruction data structure.
- */
-struct bpf_insn {
- u_short code;
- u_char jt;
- u_char jf;
- bpf_int32 k;
-};
-
-/*
- * Structure for BIOCSETF.
- */
-struct bpf_program {
- u_int bf_len;
- struct bpf_insn *bf_insns;
-};
-
-/*
- * Struct returned by BIOCGSTATS.
- */
-struct bpf_stat {
- u_int bs_recv; /* number of packets received */
- u_int bs_drop; /* number of packets dropped */
-};
-
-/*
- * 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
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1999, 2000
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *
- *
- * Portions 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.c 7.5 (Berkeley) 7/15/91
-*/
-
-#include "tme.h"
-#include "win_bpf.h"
-
-#include "debug.h"
-
-#include "valid_insns.h"
-
-#define EXTRACT_SHORT(p)\
- ((u_short)\
- ((u_short)*((u_char *)p+0)<<8|\
- (u_short)*((u_char *)p+1)<<0))
-#define EXTRACT_LONG(p)\
- ((u_int32)*((u_char *)p+0)<<24|\
- (u_int32)*((u_char *)p+1)<<16|\
- (u_int32)*((u_char *)p+2)<<8|\
- (u_int32)*((u_char *)p+3)<<0)
-
-
-u_int bpf_filter(pc, p, wirelen, buflen,mem_ex,tme,time_ref)
- register struct bpf_insn *pc;
- register u_char *p;
- u_int wirelen;
- register u_int buflen;
- PMEM_TYPE mem_ex;
- PTME_CORE tme;
- struct time_conv *time_ref;
-
-{
- register u_int32 A, X;
- register int k;
- u_int32 j,tmp;
- u_short tmp2;
-
- int32 mem[BPF_MEMWORDS];
-
- if (pc == 0)
- /*
- * No filter means accept all.
- */
- return (u_int)-1;
- A = 0;
- X = 0;
- --pc;
- while (1) {
- ++pc;
- switch (pc->code) {
-
- default:
-
- return 0;
-
- case BPF_RET|BPF_K:
- return (u_int)pc->k;
-
- case BPF_RET|BPF_A:
- return (u_int)A;
-
- case BPF_LD|BPF_W|BPF_ABS:
- k = pc->k;
- if (k + sizeof(int32) > buflen) {
- return 0;
- }
- A = EXTRACT_LONG(&p[k]);
- continue;
-
- case BPF_LD|BPF_H|BPF_ABS:
- k = pc->k;
- if (k + sizeof(short) > buflen) {
- return 0;
- }
- A = EXTRACT_SHORT(&p[k]);
- continue;
-
- case BPF_LD|BPF_B|BPF_ABS:
- k = pc->k;
- if ((int)k >= (int)buflen) {
- return 0;
- }
- A = p[k];
- continue;
-
- case BPF_LD|BPF_W|BPF_LEN:
- A = wirelen;
- continue;
-
- case BPF_LDX|BPF_W|BPF_LEN:
- X = wirelen;
- continue;
-
- case BPF_LD|BPF_W|BPF_IND:
- k = X + pc->k;
- if (k + sizeof(int32) > buflen) {
- return 0;
- }
- A = EXTRACT_LONG(&p[k]);
- continue;
-
- case BPF_LD|BPF_H|BPF_IND:
- k = X + pc->k;
- if (k + sizeof(short) > buflen) {
- return 0;
- }
- A = EXTRACT_SHORT(&p[k]);
- continue;
-
- case BPF_LD|BPF_B|BPF_IND:
- k = X + pc->k;
- if ((int)k >= (int)buflen) {
- return 0;
- }
- A = p[k];
- continue;
-
- case BPF_LDX|BPF_MSH|BPF_B:
- k = pc->k;
- if ((int)k >= (int)buflen) {
- return 0;
- }
- X = (p[pc->k] & 0xf) << 2;
- continue;
-
- 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;
-
-/* LD NO PACKET INSTRUCTIONS */
-
- 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:
- A = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
- continue;
-
- case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
- X = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
- continue;
-
- case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
- A = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
- continue;
-
- case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
- X = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
- 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;
- }
- A=EXTRACT_SHORT((uint32*)&mem_ex->buffer[k]);
- continue;
-
- case BPF_LD|BPF_MEM_EX_IND|BPF_W:
- k = X + pc->k;
- if ((int32)(k+3)>= (int32)mem_ex->size) {
- return 0;
- }
- A=EXTRACT_LONG((uint32*)&mem_ex->buffer[k]);
- continue;
-/* END LD NO PACKET INSTRUCTIONS */
-
- case BPF_ST:
- mem[pc->k] = A;
- continue;
-
- case BPF_STX:
- mem[pc->k] = X;
- continue;
-
-/* STORE INSTRUCTIONS */
- 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=A;
- *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
- continue;
-
- case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
- tmp=X;
- *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
- continue;
-
- case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
- tmp2=(uint16)A;
- *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
- continue;
-
- case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
- tmp2=(uint16)X;
- *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
- 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=A;
- *(uint32*)&mem_ex->buffer[pc->k+X]=EXTRACT_LONG(&tmp);
- continue;
-
- case BPF_ST|BPF_MEM_EX_IND|BPF_H:
- tmp2=(uint16)A;
- *(uint16*)&mem_ex->buffer[pc->k+X]=EXTRACT_SHORT(&tmp2);
- continue;
-/* END STORE INSTRUCTIONS */
-
- case BPF_JMP|BPF_JA:
- pc += pc->k;
- continue;
-
- case BPF_JMP|BPF_JGT|BPF_K:
- pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JGE|BPF_K:
- pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JEQ|BPF_K:
- pc += ((int)A == (int)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;
-
- 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:
- A = (u_int32)(-((int)A));
- continue;
-
- case BPF_MISC|BPF_TAX:
- X = A;
- continue;
-
- case BPF_MISC|BPF_TXA:
- A = X;
- continue;
-
-/* 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,wirelen,pc->k)==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_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,FALSE)==TME_ERROR)
- return 0;
- continue;
-/* END TME INSTRUCTIONS */
-
- }
- }
-}
-
-//-------------------------------------------------------------------
-
-u_int bpf_filter_with_2_buffers(pc, p, pd, headersize, wirelen, buflen, mem_ex,tme,time_ref)
- 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;
-{
- register u_int32 A, X;
- register int k;
- int32 mem[BPF_MEMWORDS];
- u_int32 j,tmp;
- u_short tmp2;
-
- if (pc == 0)
- /*
- * No filter means accept all.
- */
- return (u_int)-1;
- A = 0;
- X = 0;
- --pc;
- while (1) {
- ++pc;
- switch (pc->code) {
-
- default:
-
- return 0;
-
- case BPF_RET|BPF_K:
- return (u_int)pc->k;
-
- case BPF_RET|BPF_A:
- return (u_int)A;
-
- case BPF_LD|BPF_W|BPF_ABS:
- k = pc->k;
- if (k + sizeof(int32) > buflen) {
- return 0;
- }
-
- if(k + (int)sizeof(int32) < headersize) A = EXTRACT_LONG(&p[k]);
- else if(k + 2 == headersize){
- A=(u_int32)*((u_char *)p+k)<<24|
- (u_int32)*((u_char *)p+k+1)<<16|
- (u_int32)*((u_char *)p+k+2)<<8|
- (u_int32)*((u_char *)pd+k-headersize);
- }
- else if(k == headersize-1){
- A=(u_int32)*((u_char *)p+k)<<24|
- (u_int32)*((u_char *)p+k+1)<<16|
- (u_int32)*((u_char *)pd+k-headersize)<<8|
- (u_int32)*((u_char *)pd+k-headersize+1);
- }
- else if(k == headersize){
- A=(u_int32)*((u_char *)p+k)<<24|
- (u_int32)*((u_char *)pd+k-headersize+1)<<16|
- (u_int32)*((u_char *)pd+k-headersize+2)<<8|
- (u_int32)*((u_char *)pd+k-headersize+3);
- }
- A = EXTRACT_LONG(&pd[k-headersize]);
-
- continue;
-
- case BPF_LD|BPF_H|BPF_ABS:
- k = pc->k;
- if (k + sizeof(short) > buflen) {
- return 0;
- }
-
- if(k + (int)sizeof(short) < headersize) A = EXTRACT_SHORT(&p[k]);
- else if(k == headersize){
- A=(u_short)*((u_char *)p+k)<<8|
- (u_short)*((u_char *)pd+k-headersize);
- }
- A = EXTRACT_SHORT(&pd[k-headersize]);
-
- continue;
-
- case BPF_LD|BPF_B|BPF_ABS:
- k = pc->k;
- if ((int)k >= (int)buflen) {
- return 0;
- }
-
- if(k<headersize) A = p[k];
- else A = pd[k-headersize];
-
- continue;
-
- case BPF_LD|BPF_W|BPF_LEN:
- A = wirelen;
- continue;
-
- case BPF_LDX|BPF_W|BPF_LEN:
- X = wirelen;
- continue;
-
- case BPF_LD|BPF_W|BPF_IND:
- k = X + pc->k;
- if (k + sizeof(int32) > buflen) {
- return 0;
- }
-
- if(k + (int)sizeof(int32) < headersize) A = EXTRACT_LONG(&p[k]);
- else if(k + (int)sizeof(int32) == headersize+2){
- A=(u_int32)*((u_char *)p+k)<<24|
- (u_int32)*((u_char *)p+k+1)<<16|
- (u_int32)*((u_char *)p+k+2)<<8|
- (u_int32)*((u_char *)pd+k-headersize);
- }
- else if(k + (int)sizeof(int32) == headersize+3){
- A=(u_int32)*((u_char *)p+k)<<24|
- (u_int32)*((u_char *)p+k+1)<<16|
- (u_int32)*((u_char *)pd+k-headersize)<<8|
- (u_int32)*((u_char *)pd+k-headersize+1);
- }
- else if(k + (int)sizeof(int32) == headersize+4){
- A=(u_int32)*((u_char *)p+k)<<24|
- (u_int32)*((u_char *)pd+k-headersize+1)<<16|
- (u_int32)*((u_char *)pd+k-headersize+2)<<8|
- (u_int32)*((u_char *)pd+k-headersize+3);
- }
- A = EXTRACT_LONG(&pd[k-headersize]);
-
- continue;
-
- case BPF_LD|BPF_H|BPF_IND:
- k = X + pc->k;
- if (k + sizeof(short) > buflen) {
- return 0;
- }
-
- if(k + (int)sizeof(short) < headersize) A = EXTRACT_SHORT(&p[k]);
- else if(k == headersize){
- A=(u_short)*((u_char *)p+k)<<8|
- (u_short)*((u_char *)pd+k-headersize);
- }
- A = EXTRACT_SHORT(&pd[k-headersize]);
-
- continue;
-
- case BPF_LD|BPF_B|BPF_IND:
- k = X + pc->k;
- if ((int)k >= (int)buflen) {
- return 0;
- }
-
- if(k<headersize) A = p[k];
- else A = pd[k-headersize];
-
- continue;
-
- case BPF_LDX|BPF_MSH|BPF_B:
- k = pc->k;
- if ((int)k >= (int)buflen) {
- return 0;
- }
-
- if((pc->k)<headersize) X = (p[pc->k] & 0xf) << 2;
- else X = (pd[(pc->k)-headersize] & 0xf) << 2;
-
- continue;
-
- 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;
-
-/* LD NO PACKET INSTRUCTIONS */
-
- 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:
- A = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
- continue;
-
- case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
- X = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
- continue;
-
- case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
- A = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
- continue;
-
- case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
- X = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
- 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;
- }
- A=EXTRACT_SHORT((uint32*)&mem_ex->buffer[k]);
- continue;
-
- case BPF_LD|BPF_MEM_EX_IND|BPF_W:
- k = X + pc->k;
- if ((int32)(k+3)>= (int32)mem_ex->size) {
- return 0;
- }
- A=EXTRACT_LONG((uint32*)&mem_ex->buffer[k]);
- continue;
-/* END LD NO PACKET INSTRUCTIONS */
-
- case BPF_ST:
- mem[pc->k] = A;
- continue;
-
- case BPF_STX:
- mem[pc->k] = X;
- continue;
-
-
-/* STORE INSTRUCTIONS */
- 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=A;
- *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
- continue;
-
- case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
- tmp=X;
- *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
- continue;
-
- case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
- tmp2=(uint16)A;
- *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
- continue;
-
- case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
- tmp2=(uint16)X;
- *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
- 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=A;
- *(uint32*)&mem_ex->buffer[pc->k+X]=EXTRACT_LONG(&tmp);
- continue;
-
- case BPF_ST|BPF_MEM_EX_IND|BPF_H:
- tmp2=(uint16)A;
- *(uint16*)&mem_ex->buffer[pc->k+X]=EXTRACT_SHORT(&tmp2);
- continue;
-/* END STORE INSTRUCTIONS */
-
-
-
- case BPF_JMP|BPF_JA:
- pc += pc->k;
- continue;
-
- case BPF_JMP|BPF_JGT|BPF_K:
- pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JGE|BPF_K:
- pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JEQ|BPF_K:
- pc += ((int)A == (int)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;
-
- 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:
- A = (u_int32)(-((int)A));
- continue;
-
- case BPF_MISC|BPF_TAX:
- X = A;
- continue;
-
- case BPF_MISC|BPF_TXA:
- A = X;
- continue;
-
-/* 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,wirelen,pc->k)==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_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,FALSE)==TME_ERROR)
- return 0;
- continue;
-/* END TME INSTRUCTIONS */
-
- }
- }
-}
-
-int32
-bpf_validate(f, len,mem_ex_size)
- struct bpf_insn *f;
- int32 len;
- uint32 mem_ex_size;
-{
- register int32 i,j;
- register struct bpf_insn *p;
- int32 flag;
-
- for (i = 0; i < len; ++i) {
- /*
- * Check that that jumps are forward, and within
- * the code block.
- */
-
- p = &f[i];
-
- IF_LOUD(DbgPrint("Validating program");)
-
- flag=0;
- for(j=0;j<(int32)VALID_INSTRUCTIONS_LEN;j++)
- if (p->code==valid_instructions[j])
- flag=1;
- if (flag==0)
- return 0;
-
- IF_LOUD(DbgPrint("Validating program: no unknown instructions");)
-
- if (BPF_CLASS(p->code) == BPF_JMP) {
- register int32 from = i + 1;
-
- if (BPF_OP(p->code) == BPF_JA) {
- if (from + p->k >= len)
- return 0;
- }
- else if (from + p->jt >= len || from + p->jf >= len)
- return 0;
- }
-
- IF_LOUD(DbgPrint("Validating program: no wrong JUMPS");)
-
- /*
- * Check that memory operations use valid addresses.
- */
- if (((BPF_CLASS(p->code) == BPF_ST && ((p->code &BPF_MEM_EX_IMM)!=BPF_MEM_EX_IMM && (p->code &BPF_MEM_EX_IND)!=BPF_MEM_EX_IND)) ||
- (BPF_CLASS(p->code) == BPF_LD &&
- (p->code & 0xe0) == BPF_MEM)) &&
- (p->k >= BPF_MEMWORDS || p->k < 0))
- return 0;
-
- IF_LOUD(DbgPrint("Validating program: no wrong ST/LD memory locations");)
-
- /*
- * Check if key stores use valid addresses
- */
- if (BPF_CLASS(p->code) == BPF_ST && (p->code &BPF_MEM_EX_IMM)==BPF_MEM_EX_IMM)
- switch (BPF_SIZE(p->code))
- {
- case BPF_W: if (p->k<0 || p->k+3>=(int32)mem_ex_size) return 0;
- case BPF_H: if (p->k<0 || p->k+1>=(int32)mem_ex_size) return 0;
- case BPF_B: if (p->k<0 || p->k>=(int32)mem_ex_size) return 0;
- }
-
- IF_LOUD(DbgPrint("Validating program: no wrong ST/LD mem_ex locations");)
-
- /*
- * Check for constant division by 0.
- */
- if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
- return 0;
- }
- return BPF_CLASS(f[len - 1].code) == BPF_RET;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *
- *
- * Portions 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.
- */
-
-#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];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx,tmp2
- xor eax, eax
- mov ax, [ebx]
- bswap eax
- mov A, eax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(A),"=c"(tmp2): );
-#endif
- continue;
-
- case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
- tmp2=(uint16*)&mem_ex->buffer[pc->k];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx,tmp2
- xor eax, eax
- mov ax, [ebx]
- bswap eax
- mov X, eax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(X),"=c"(tmp2): );
-#endif
- continue;
-
- case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
- tmp=(uint32*)&mem_ex->buffer[pc->k];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx,tmp
- mov eax, [ebx]
- bswap eax
- mov A, eax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(A),"=c"(tmp): );
-#endif
- continue;
-
- case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
- tmp=(uint32*)&mem_ex->buffer[pc->k];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx,tmp
- mov eax, [ebx]
- bswap eax
- mov X, eax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(X),"=c"(tmp): );
-#endif
- continue;
-
- 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];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx,tmp2
- xor eax, eax
- mov ax, [ebx]
- bswap eax
- mov A, eax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(A),"=c"(tmp2): );
-#endif
- continue;
-
- 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];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx,tmp
- mov eax, [ebx]
- bswap eax
- mov A, eax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(A),"=c"(tmp): );
-#endif
- continue;
-/* END LD NO PACKET INSTRUCTIONS */
-
-/* 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];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx, tmp
- mov eax, A
- bswap eax
- mov [ebx], eax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(A),"=c"(tmp): );
-#endif
- continue;
-
- case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
- tmp=(uint32*)&mem_ex->buffer[pc->k];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx, tmp
- mov eax, X
- bswap eax
- mov [ebx], eax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(X),"=c"(tmp): );
-#endif
- continue;
-
- case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
- tmp2=(uint16*)&mem_ex->buffer[pc->k];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx, tmp2
- mov eax, A
- xchg ah, al
- mov [ebx], ax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(A),"=c"(tmp2): );
-#endif
- continue;
-
- case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
- tmp2=(uint16*)&mem_ex->buffer[pc->k];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx, tmp2
- mov eax, X
- xchg ah, al
- mov [ebx], ax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(X),"=c"(tmp2): );
-#endif
- continue;
-
- 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];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx, tmp
- mov eax, A
- bswap eax
- mov [ebx], eax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(A),"=c"(tmp): );
-#endif
- continue;
-
- case BPF_ST|BPF_MEM_EX_IND|BPF_H:
- tmp2=(uint16*)&mem_ex->buffer[pc->k+X];
-#ifndef __GNUC__
- __asm
- {
- push eax
- push ebx
- mov ebx, tmp2
- mov eax, A
- xchg ah, al
- mov [ebx], ax
- pop ebx
- pop eax
- }
-#else
- asm("push %%eax;"
- "push %%ebx;"
- "mov %1,%%ebx;"
- "xor %%eax, %%eax;"
- "mov (%%ebx), %%ax;"
- "bswap %%eax;"
- "mov %%eax, %0;"
- "pop %%ebx;"
- "pop %%eax;"
- :"=a"(A),"=c"(tmp2): );
-#endif
- continue;
-/* END STORE INSTRUCTIONS */
-
-/* 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:
- A = (uint32)(-((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<0)||(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 */
-
- }
- }
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2001
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef __FILTER_INIT
-#define __FILTER_INIT
-
-#include "tme.h"
-
-#define INIT_OK 1
-#define INIT_ERROR 0
-
-uint32 bpf_filter_init(register struct bpf_insn *pc,MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref);
-
-#endif
-
+++ /dev/null
-/*
- * Copyright (c) 1999, 2000
- * Politecnico di Torino. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the Politecnico
- * di Torino, and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifdef _MSC_VER
-#include "stdarg.h"
-#include "ntddk.h"
-#include "ntiologc.h"
-#include "ndis.h"
-#else
-#include <ntddk.h>
-#include <ndis.h>
-#define NdisReinitializePacket(Packet) \
-{ \
- (Packet)->Private.Head = (PNDIS_BUFFER)NULL; \
- (Packet)->Private.ValidCounts = FALSE; \
-}
-
-#endif
-
-#include "debug.h"
-#include "packet.h"
-
-
-//-------------------------------------------------------------------
-
-NTSTATUS STDCALL
-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_LOUD(DbgPrint("Max frame size = %d\n", Open->MaxFrameSize);)
-
-
- if(IrpSp->Parameters.Write.Length == 0 || // Check that the buffer provided by the user is not empty
- Open->MaxFrameSize == 0 || // Check that the MaxFrameSize is correctly initialized
- IrpSp->Parameters.Write.Length > Open->MaxFrameSize) // Check that the fame size is smaller that the MTU
- {
- IF_LOUD(DbgPrint("frame size out of range, send aborted\n");)
-
- Irp->IoStatus.Status = NDIS_STATUS_SUCCESS;
- IoCompleteRequest (Irp, IO_NO_INCREMENT);
- return NDIS_STATUS_SUCCESS;
- }
-
-
- 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;
- }
-
- // The packet has 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);
-
- // 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;
- LARGE_INTEGER StartTicks, CurTicks;
- LARGE_INTEGER TimeFreq;
- struct timeval BufStartTime;
- 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;
-
- // Security check on the length of the user buffer
- if(UserBuff==0)
- {
- return 0;
- }
-
- // Check that the MaxFrameSize is correctly initialized
- if(Open->MaxFrameSize == 0)
- {
- IF_LOUD(DbgPrint("BufferedWrite: Open->MaxFrameSize not initialized, probably because of a problem in the OID query\n");)
-
- return 0;
- }
-
-
- // Start from the first packet
- winpcap_hdr = (struct sf_pkthdr*)UserBuff;
-
- // Retrieve the time references
- StartTicks = KeQueryPerformanceCounter(&TimeFreq);
- BufStartTime.tv_sec = winpcap_hdr->ts.tv_sec;
- BufStartTime.tv_usec = winpcap_hdr->ts.tv_usec;
-
- // 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;
- }
-
- // Save the current time stamp counter
- CurTicks = KeQueryPerformanceCounter(NULL);
-
- // 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 free packets
- IF_LOUD(DbgPrint("NPF_BufferedWrite: no more free packets, returning.\n");)
-
- return (PCHAR)winpcap_hdr - UserBuff;
- }
-
- // The packet has a buffer that needs to be freed after every single write
- RESERVED(pPacket)->FreeBufAfterWrite = TRUE;
-
- // Attach the MDL to the packet
- NdisChainBufferAtFront(pPacket,TmpMdl);
-
- // 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
- winpcap_hdr = (struct sf_pkthdr *)((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");)
-
- return (PCHAR)winpcap_hdr - UserBuff;
- }
-
- if( Sync ){
-
- // Release the application if it has been blocked for approximately more than 1 seconds
- if( winpcap_hdr->ts.tv_sec - BufStartTime.tv_sec > 1 )
- {
- IF_LOUD(DbgPrint("NPF_BufferedWrite: timestamp elapsed, returning.\n");)
-
- return (PCHAR)winpcap_hdr - UserBuff;
- }
-
-#ifndef __GNUC__
- // Calculate the time interval to wait before sending the next packet
- TargetTicks.QuadPart = StartTicks.QuadPart +
- (LONGLONG)((winpcap_hdr->ts.tv_sec - BufStartTime.tv_sec) * 1000000 +
- winpcap_hdr->ts.tv_usec - BufStartTime.tv_usec) *
- (TimeFreq.QuadPart) / 1000000;
-
- // Wait until the time interval has elapsed
- while( CurTicks.QuadPart <= TargetTicks.QuadPart )
- CurTicks = KeQueryPerformanceCounter(NULL);
-#else
-#endif
- }
-
- }
-
- return (PCHAR)winpcap_hdr - UserBuff;
-
-}
-
-
-//-------------------------------------------------------------------
-
-VOID STDCALL
-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 ){
- // Free the MDL associated with the packet
- NdisUnchainBufferAtFront(pPacket, &TmpMdl);
- IoFreeMdl(TmpMdl);
- }
- else{
- if((Open->Nwrites - Open->Multiple_Write_Counter) %100 == 99)
- NdisSetEvent(&Open->WriteEvent);
-
- Open->Multiple_Write_Counter--;
- }
-
- // recyle the packet
- NdisReinitializePacket(pPacket);
-
- // Put the packet back on the free list
- NdisFreePacket(pPacket);
-
- if( !(RESERVED(pPacket)->FreeBufAfterWrite) ){
- if(Open->Multiple_Write_Counter==0){
- // Release the buffer and awake the application
- NdisUnchainBufferAtFront(pPacket, &TmpMdl);
-
- Irp=RESERVED(pPacket)->Irp;
- irpSp = IoGetCurrentIrpStackLocation(Irp);
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = irpSp->Parameters.Write.Length;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- }
- }
-
- return;
-}
-
-
-#ifdef __GNUC__
-/*
-__divdi3()
-{
- //_alldiv();
-}
-
-//_allmul();
-//_allrem();
-
-*/
-#endif