📄 packet.c
字号:
pEntry=pEntry->Flink;
}while (pEntry != pHead);
*(ULONG*)(pDiocParms->lpcbBytesReturned) = dwBytes;
IF_TRACE_MSG( " Bytes Returned: %lu", *(ULONG*)(pDiocParms->lpcbBytesReturned) );
TRACE_LEAVE( "PacketGetMacNameList" );
return NDIS_STATUS_SUCCESS;
}
/************************************************************
This is the dispatch routine for create/open and close requests.
These requests complete successfully.
INPUT: dwDDB e hDevice - parameters sent by the DeviceIOControl procedure
dwService - requested service
pDiocParms - structure containing the parameters of the call
OUTPUT: the status of the operation
************************************************************/
DWORD _stdcall PacketIOControl( DWORD dwService,
DWORD dwDDB,
DWORD hDevice,
PDIOCPARAMETERS pDiocParms )
{
PUCHAR tpointer;
int *StatsBuf;
PUCHAR prog;
ULONG dim,timeout;
NDIS_STATUS Status;
PPACKET_OID_DATA reqbuff;
POPEN_INSTANCE Open,tOpen;
PNDIS_STRING str;
ULONG mode;
PLIST_ENTRY pEntry;
PLIST_ENTRY pHead;
PADAPTER_NAME AName;
UINT i;
SHORT timezone;
TRACE_ENTER( "DeviceIoControl" );
if(!(dwService==IOCTL_PROTOCOL_MACNAME ||
dwService==IOCTL_OPEN ||
dwService==0)){
Open=GetRunningAdapter(hDevice,pDiocParms->tagProcess);
if(Open==NULL) return NDIS_STATUS_FAILURE;
}
switch ( dwService )
{
case IOCTL_OPEN: //open message
Instances++;
//get the NDIS name of current adapter
str=GetNDISAdapterName((BYTE*)pDiocParms->lpvInBuffer);
if(str==NULL) return NDIS_STATUS_FAILURE;
//try to open an instance of the adapter
Status = PacketOpen( str, dwDDB, hDevice, pDiocParms);
return Status;
break;
case BIOCGSTATS: //fuction to obtain the capture stats
StatsBuf=(int*)pDiocParms->lpvOutBuffer;
StatsBuf[0]=Open->Received;
StatsBuf[1]=Open->Dropped;
*(DWORD *)(pDiocParms->lpcbBytesReturned) = 8;
return NDIS_STATUS_SUCCESS;
break;
case BIOCEVNAME: //fuction to set the shared Event
Open->ReadEvent=((DWORD*)pDiocParms->lpvInBuffer)[0];
*(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
return NDIS_STATUS_SUCCESS;
break;
case BIOCSETF: //fuction to set a new bpf filter
/*free the previous buffer if it was present*/
if(Open->bpfprogram!=NULL){
NdisFreeMemory(Open->bpfprogram,Open->bpfprogramlen,0);
Open->bpfprogram=NULL; //NULL means accept all
Open->bpfprogramlen=0;
}
/*get the pointer to the new program*/
prog=(PUCHAR)pDiocParms->lpvInBuffer;
/*before accepting the program we must check that it's valid
Otherwise, a bogus program could easily crash the system*/
Open->bpfprogramlen=pDiocParms->cbInBuffer;
if(bpf_validate((struct bpf_insn*)prog,Open->bpfprogramlen/sizeof(struct bpf_insn))==0)
{
Open->bpfprogramlen=0;
Open->bpfprogram=NULL;
return NDIS_STATUS_FAILURE; // filter not accepted
}
/*allocate the memory to contain the new filter program*/
if(NdisAllocateMemory(&Open->bpfprogram,Open->bpfprogramlen, 0, -1 )==NDIS_STATUS_FAILURE)
{
// no memory
Open->bpfprogramlen=0;
Open->bpfprogram=NULL;
return NDIS_STATUS_FAILURE;
}
/*copy the program in the new buffer*/
NdisMoveMemory(Open->bpfprogram,prog,Open->bpfprogramlen);
/*reset the buffer that could contain packets that don't match the filter*/
Open->Bhead=0;
Open->Btail=0;
Open->BLastByte=0;
Open->Received=0;
Open->Dropped=0;
*(DWORD *)(pDiocParms->lpcbBytesReturned) = Open->bpfprogramlen;
break;
case BIOCSETBUFFERSIZE: //function to set the dimension of the buffer for the packets
/*get the size to allocate*/
dim=((PULONG)pDiocParms->lpvInBuffer)[0];
/*free the old buffer*/
if(Open->Buffer!=NULL)
NdisFreeMemory(Open->Buffer,Open->BufSize,0);
Open->Buffer=NULL;
/*allocate the new buffer*/
if(dim>0){
NdisAllocateMemory( (PVOID *)&tpointer,dim, 0, -1 );
if (tpointer==NULL)
{
// no memory
Open->BufSize=0;
return NDIS_STATUS_FAILURE;
}
Open->Buffer=tpointer;
}
Open->Bhead=0;
Open->Btail=0;
Open->BLastByte=0;
Open->BufSize=(UINT)dim;
*(DWORD *)(pDiocParms->lpcbBytesReturned) = dim;
break;
case BIOCSMODE:
mode=((PULONG)pDiocParms->lpvInBuffer)[0];
if(mode==MODE_STAT){
Open->mode=MODE_STAT;
Open->Nbytes=0;
Open->Npackets=0;
if(Open->TimeOut==0)Open->TimeOut=1000;
}
else if(mode==MODE_CAPT){
Open->mode=MODE_CAPT;
return NDIS_STATUS_SUCCESS;
}
else{
return NDIS_STATUS_FAILURE;
}
break;
case BIOCSRTIMEOUT:
timeout=((PULONG)pDiocParms->lpvInBuffer)[0];
Open->TimeOut=timeout;
*(DWORD *)(pDiocParms->lpcbBytesReturned) = timeout;
break;
case BIOCSTIMEZONE:
timezone=((PSHORT)pDiocParms->lpvInBuffer)[0];
Open->StartTime+=((__int64)timezone)*(__int64)1193182*60;
*(DWORD *)(pDiocParms->lpcbBytesReturned) = timezone;
break;
case BIOCSWRITEREP: //set the writes repetition number
Open->Nwrites=((PULONG)pDiocParms->lpvInBuffer)[0];
*(DWORD *)(pDiocParms->lpcbBytesReturned) = Open->Nwrites;
break;
case DIOC_CLOSEHANDLE:
Status=PacketClose( Open, dwDDB, hDevice, pDiocParms );
Instances--;
if(Instances<=0)
if ( GlobalDeviceExtension )
{
//If any instance is still opened we must close it
NdisAcquireSpinLock(&GlobalDeviceExtension->OpenSpinLock);
nOpen=0;
pHead = &(GlobalDeviceExtension->OpenList);
if(pHead!=NULL && !IsListEmpty(pHead))
{
//count the number of open instances
pEntry=pHead->Flink;
do {
tOpen = CONTAINING_RECORD( pEntry, OPEN_INSTANCE, ListElement );
pEntry=pEntry->Flink;
if(tOpen!=NULL)
InstToClose[nOpen++]=tOpen;
}while (pEntry != pHead);
for(i=0;i<nOpen;i++){
PacketClose(InstToClose[i],0,InstToClose[i]->hDevice,NULL);
}
}
NdisReleaseSpinLock( &GlobalDeviceExtension->OpenSpinLock );
//free the names' list
pHead = &(GlobalDeviceExtension->AdapterNames);
if(pHead!=NULL)
{
while((pEntry=PacketRemoveHeadList(pHead))!=NULL){
AName= CONTAINING_RECORD( pEntry, ADAPTER_NAME, ListElement);
NdisFreeMemory(AName,sizeof(ADAPTER_NAME),0);
}
}
//unregister the protocol from NDIS
NdisDeregisterProtocol( &Status, GlobalDeviceExtension->NdisProtocolHandle );
//free the global device extension
NdisFreeMemory(GlobalDeviceExtension,sizeof( DEVICE_EXTENSION ),0);
}
break;
case IOCTL_PROTOCOL_RESET:
PacketReset( &Status, Open );
break;
case BIOCQUERYOID:
case BIOCSETOID:
case IOCTL_PROTOCOL_STATISTICS:
return PacketRequest( Open, dwService, dwDDB, hDevice, pDiocParms );
case IOCTL_PROTOCOL_READ:
return PacketRead( Open, dwDDB, hDevice, pDiocParms );
case IOCTL_PROTOCOL_WRITE:
return PacketWrite( Open, dwDDB, hDevice, pDiocParms );
case IOCTL_PROTOCOL_MACNAME:
PacketGetMacNameList( dwDDB, hDevice, pDiocParms );
break;
default:
/*unknown function*/
*(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
break;
}
TRACE_LEAVE( "DeviceIoControl" );
return NDIS_STATUS_SUCCESS;
}
/************************************************************
Function called by NDIS when there is something to communicate
to the upper level
************************************************************/
VOID
PacketStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize
)
{
TRACE_ENTER( "Status Indication" );
TRACE_LEAVE( "Status Indication" );
return;
}
/************************************************************
Complete the previous call
************************************************************/
VOID NDIS_API
PacketStatusComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
{
TRACE_ENTER( "StatusIndicationComplete" );
TRACE_LEAVE( "StatusIndicationComplete" );
return;
}
/************************************************************
Removes an element from a list.
Performs a check to see if the list is empty
************************************************************/
PLIST_ENTRY
PacketRemoveHeadList(
IN PLIST_ENTRY pListHead
)
{
if ( !IsListEmpty( pListHead ) )
{
PLIST_ENTRY pLE = RemoveHeadList( pListHead );
return pLE;
}
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -