📄 packet.c
字号:
{
Open->mode = MODE_CAPT;
SET_RESULT_SUCCESS(0);
break;
}
else if (mode == MODE_MON)
{
//
// The MONITOR_MODE (aka TME extensions) is not supported on
// 64 bit architectures
//
#ifdef __NPF_x86__
Open->mode = MODE_MON;
SET_RESULT_SUCCESS(0);
#else // _NPF_x86__
SET_FAILURE_INVALID_REQUEST();
#endif // __NPF_x86__
break;
}
else{
if(mode & MODE_STAT){
Open->mode = MODE_STAT;
NdisAcquireSpinLock(&Open->CountersLock);
Open->Nbytes.QuadPart = 0;
Open->Npackets.QuadPart = 0;
NdisReleaseSpinLock(&Open->CountersLock);
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;
}
SET_RESULT_SUCCESS(0);
break;
}
SET_FAILURE_INVALID_REQUEST();
break;
case BIOCSETDUMPFILENAME:
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETDUMPFILENAME");
///////kernel dump does not work at the moment//////////////////////////////////////////
SET_FAILURE_INVALID_REQUEST();
break;
///////kernel dump does not work at the moment//////////////////////////////////////////
//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
// DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, '5PWA');
// 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
// ((PSHORT)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:
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETDUMPLIMITS");
///////kernel dump does not work at the moment//////////////////////////////////////////
SET_FAILURE_INVALID_REQUEST();
break;
///////kernel dump does not work at the moment//////////////////////////////////////////
//if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < 2*sizeof(ULONG))
//{
// EXIT_FAILURE(0);
//}
//
//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:
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCISDUMPENDED");
///////kernel dump does not work at the moment//////////////////////////////////////////
SET_FAILURE_INVALID_REQUEST();
break;
///////kernel dump does not work at the moment//////////////////////////////////////////
//if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UINT))
//{
// EXIT_FAILURE(0);
//}
//*((UINT*)Irp->UserBuffer) = (Open->DumpLimitReached)?1:0;
//EXIT_SUCCESS(4);
//break;
case BIOCISETLOBBEH:
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(INT))
{
SET_FAILURE_BUFFER_SMALL();
break;
}
#ifdef __NPF_NT4__
// NT4 doesn't support loopback inhibition / activation
SET_FAILURE_INVALID_REQUEST();
break;
#else //not __NPF_NT4__
//
// win2000/xp/2003/vista
//
if(*(PINT)Irp->AssociatedIrp.SystemBuffer == NPF_DISABLE_LOOPBACK)
{
Open->SkipSentPackets = TRUE;
//
// Reset the capture buffers, since they could contain loopbacked packets
//
NPF_ResetBufferContents(Open);
SET_RESULT_SUCCESS(0);
break;
}
else
if(*(PINT)Irp->AssociatedIrp.SystemBuffer == NPF_ENABLE_LOOPBACK)
{
Open->SkipSentPackets = FALSE;
SET_RESULT_SUCCESS(0);
break;
}
else
{
// Unknown operation
SET_FAILURE_INVALID_REQUEST();
break;
}
#endif // !__NPF_NT4__
break;
case BIOCSETEVENTHANDLE:
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETEVENTHANDLE");
#ifdef __NPF_AMD64__
if (IoIs32bitProcess(Irp))
{
//
// validate the input
//
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (hUserEvent32Bit))
{
SET_FAILURE_INVALID_REQUEST();
break;
}
hUserEvent32Bit = *(VOID*POINTER_32*)Irp->AssociatedIrp.SystemBuffer;
hUserEvent = hUserEvent32Bit;
}
else
#endif //__NPF_AMD64__
{
//
// validate the input
//
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (hUserEvent))
{
SET_FAILURE_INVALID_REQUEST();
break;
}
hUserEvent = *(PHANDLE)Irp->AssociatedIrp.SystemBuffer;
}
//
// NT4 doesn't seem to have EVENT_MODIFY_STATE, so on NT4 we request a wider set
// of privileges for the event handle
//
#ifdef __NPF_NT4__
Status = ObReferenceObjectByHandle(hUserEvent,
OBJECT_TYPE_ALL_ACCESS, *ExEventObjectType, Irp->RequestorMode,
(PVOID*) &pKernelEvent, NULL);
#else //__NPF_NT4__
Status = ObReferenceObjectByHandle(hUserEvent,
EVENT_MODIFY_STATE, *ExEventObjectType, Irp->RequestorMode,
(PVOID*) &pKernelEvent, NULL);
#endif //__NPF_NT4__
if (!NT_SUCCESS(Status))
{
// Status = ??? already set
Information = 0;
break;
}
//
// NT4 does not have InterlockedCompareExchangePointer
// InterlockedCompareExchange on NT4 has the same prototype of InterlockedCompareExchange
// on NT5x, so we use this one.
//
#ifdef __NPF_NT4__
if (InterlockedCompareExchange(&Open->ReadEvent, pKernelEvent, NULL) != NULL)
#else
if (InterlockedCompareExchangePointer(&Open->ReadEvent, pKernelEvent, NULL) != NULL)
#endif
{
//
// dereference the new pointer
//
ObDereferenceObject(pKernelEvent);
SET_FAILURE_INVALID_REQUEST();
break;
}
KeResetEvent(Open->ReadEvent);
SET_RESULT_SUCCESS(0);
break;
case BIOCSETBUFFERSIZE:
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETBUFFERSIZE");
if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
{
SET_FAILURE_BUFFER_SMALL();
break;
}
// Get the number of bytes to allocate
dim = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
if (dim / NCpu < sizeof(struct PacketHeader))
{
dim = 0;
}
else
{
tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, '6PWA');
if (tpointer == NULL)
{
// no memory
SET_FAILURE_NOMEM();
break;
}
}
//
// acquire the locks for all the buffers
//
for (i = 0; i < NCpu ; i++)
{
#pragma prefast(suppress:8103, "There's no Spinlock leak here, as it's released some lines below.")
NdisAcquireSpinLock(&Open->CpuData[i].BufferLock);
}
//
// free the old buffer, if any
//
if (Open->CpuData[0].Buffer != NULL)
{
ExFreePool(Open->CpuData[0].Buffer);
}
for (i = 0 ; i < NCpu ; i++)
{
if (dim > 0)
Open->CpuData[i].Buffer=(PUCHAR)tpointer + (dim/NCpu)*i;
else
Open->CpuData[i].Buffer = NULL;
Open->CpuData[i].Free = dim/NCpu;
Open->CpuData[i].P = 0;
Open->CpuData[i].C = 0;
Open->CpuData[i].Accepted = 0;
Open->CpuData[i].Dropped = 0;
Open->CpuData[i].Received = 0;
}
Open->ReaderSN=0;
Open->WriterSN=0;
Open->Size = dim/NCpu;
//
// acquire the locks for all the buffers
//
i = NCpu;
do
{
i--;
#pragma prefast(suppress:8107, "There's no Spinlock leak here, as it's acquired some lines above.")
NdisReleaseSpinLock(&Open->CpuData[i].BufferLock);
}while(i != 0);
SET_RESULT_SUCCESS(0);
break;
case BIOCSRTIMEOUT: //set the timeout on the read calls
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSRTIMEOUT");
if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
{
SET_FAILURE_BUFFER_SMALL();
break;
}
timeout = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
if(timeout == (ULONG)-1)
Open->TimeOut.QuadPart=(LONGLONG)IMMEDIATE;
else
{
Open->TimeOut.QuadPart = (LONGLONG)timeout;
Open->TimeOut.QuadPart *= 10000;
Open->TimeOut.QuadPart = -Open->TimeOut.QuadPart;
}
TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Read timeout set to %I64d",Open->TimeOut.QuadPart);
SET_RESULT_SUCCESS(0);
break;
case BIOCSWRITEREP: //set the writes repetition number
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSWRITEREP");
if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
{
SET_FAILURE_BUFFER_SMALL();
break;
}
Open->Nwrites = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
SET_RESULT_SUCCESS(0);
break;
case BIOCSMINTOCOPY: //set the minimum buffer's size to copy to the application
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSMINTOCOPY");
if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
{
SET_FAILURE_BUFFER_SMALL();
break;
}
Open->MinToCopy = (*((PULONG)Irp->AssociatedIrp.SystemBuffer))/NCpu; //An hack to make the NCPU-buffers behave like a larger one
SET_RESULT_SUCCESS(0);
break;
case IOCTL_PROTOCOL_RESET:
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "IOCTL_PROTOCOL_RESET");
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:
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETOID - BIOCQUERYOID");
//
// gain ownership of the Ndis Handle
//
if (NPF_StartUsingBinding(Open) == FALSE)
{
//
// MAC unbindind or unbound
//
SET_FAILURE_INVALID_REQUEST();
break;
}
// Extract a request from the list of free ones
RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,&Open->RequestSpinLock);
if (RequestListEntry == NULL)
{
//
// Release ownership of the Ndis Handle
//
NPF_StopUsingBinding(Open);
SET_FAILURE_NOMEM();
break;
}
pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement);
//
// See if it is an Ndis request
//
OidData=Irp->AssociatedIrp.SystemBuffer;
if ((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)) {
TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "BIOCSETOID|BIOCQUERYOID Request: Oid=%08lx, Length=%08lx",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(&pRequest->InternalRequestCompletedEvent);
//
// submit the request
//
NdisRequest(
&Status,
Open->AdapterHandle,
&pRequest->Request
);
} else {
//
// Release ownership of the Ndis Handle
//
NPF_StopUsingBinding(Open);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -