📄 read.c
字号:
}
/*see if there are pending requests*/
NdisAcquireSpinLock( &pOpen->RcvQSpinLock );
PacketListEntry = PacketRemoveHeadList( &pOpen->RcvList );
NdisReleaseSpinLock( &pOpen->RcvQSpinLock );
if ( PacketListEntry == NULL )
{
/*no requests. This means that the application is not performing a read in this
moment: the packet must go in the buffer*/
TRACE_ENTER( "IndicateReceive" );
if(pOpen->BufSize==0)return NDIS_STATUS_NOT_ACCEPTED;
Thead=pOpen->Bhead;
Ttail=pOpen->Btail;
TLastByte=pOpen->BLastByte;
maxbufspace=fres+sizeof(struct bpf_hdr);
if(Ttail+maxbufspace>=pOpen->BufSize){
if(Thead<=maxbufspace)
{
/*the buffer is full: the packet is lost*/
pOpen->Dropped++;
return NDIS_STATUS_NOT_ACCEPTED;
}
else{
Ttail=0;
}
}
if((Ttail<Thead)&&(Ttail+maxbufspace>=Thead))
{
/*the buffer is full: the packet is lost*/
pOpen->Dropped++;
return NDIS_STATUS_NOT_ACCEPTED;
}
CurrBuff=pOpen->Buffer+Ttail;
/*allocate the ndis buffer*/
NdisAllocateBuffer( &Status,
&pNdisBuffer,
pOpen->BufferPool,
CurrBuff+sizeof(struct bpf_hdr),
fres);
if (Status != NDIS_STATUS_SUCCESS)
{
pOpen->Dropped++;
return NDIS_STATUS_NOT_ACCEPTED;
}
/*allocate the packet from NDIS*/
NdisAllocatePacket(&Status,&pPacketb,pOpen->PacketPool);
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFreeBuffer( pNdisBuffer );
pOpen->Dropped++;
return NDIS_STATUS_NOT_ACCEPTED;
}
/*link the buffer to the packet*/
NdisChainBufferAtFront(pPacketb,pNdisBuffer);
if ( uiHeaderBufferSize > 0 )
{
if ( uiHeaderBufferSize > pNdisBuffer->Length )
uiHeaderBufferSize = pNdisBuffer->Length;
/*copy the header*/
NdisMoveMemory(pNdisBuffer->VirtualAddress, pvHeaderBuffer, uiHeaderBufferSize );
uiBytesTransferred = uiHeaderBufferSize;
(BYTE *)(pNdisBuffer->VirtualAddress) += uiHeaderBufferSize;
pNdisBuffer->Length -= uiHeaderBufferSize;
}
ulSizeToTransfer = uiPacketSize;
if ( ulSizeToTransfer > pNdisBuffer->Length )
ulSizeToTransfer = pNdisBuffer->Length;
/*Copy the remaining part of the packet*/
NdisTransferData( &Status,
pOpen->AdapterHandle,
MacReceiveContext,
0,
ulSizeToTransfer,
pPacketb,
&uiBytesTransferred );
uiBytesTransferred+=uiHeaderBufferSize;
/*get the capture time*/
lCapTime=QuerySystemTime();
/*fill the bpf header for this packet*/
if( fres>uiBytesTransferred )fres=uiBytesTransferred;
lCapTime+=pOpen->StartTime;
header=(struct bpf_hdr*)CurrBuff;
header->bh_tstamp.tv_usec=(long)((lCapTime%1193182)*1000000/1193182);
header->bh_tstamp.tv_sec=(long)((lCapTime)/1193182);
header->bh_caplen=(UINT)fres;
header->bh_datalen=(UINT)uiPacketSize+uiHeaderBufferSize;
header->bh_hdrlen=sizeof(struct bpf_hdr);
/*update the buffer*/
Ttail+=Packet_WORDALIGN(fres+sizeof(struct bpf_hdr));
if(Ttail>Thead)TLastByte=Ttail;
pOpen->Btail=Ttail;
pOpen->BLastByte=TLastByte;
/*free the allocated buffer*/
NdisFreeBuffer( pNdisBuffer );
/*recylcle the packet*/
NdisReinitializePacket(pPacketb);
/*Put the packet on the free queue*/
NdisFreePacket(pPacketb);
TEvent=pOpen->ReadEvent;
_asm mov eax,TEvent;
VxDCall(_VWIN32_SetWin32Event);
TRACE_LEAVE( "Packet_tap" );
return NDIS_STATUS_SUCCESS;
}
/*cancel the timeout on this read call*/
to=pOpen->ReadTimeoutTimer;
_asm push esi;
_asm mov esi,to;
CancelReadTimeOut();
_asm pop esi;
pOpen->ReadTimeoutTimer=0;
pReserved = CONTAINING_RECORD( PacketListEntry, PACKET_RESERVED, ListElement );
pPacket = CONTAINING_RECORD( pReserved, NDIS_PACKET, ProtocolReserved );
IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD )
{
IF_TRACE_MSG( " Reserved : %lx", pReserved );
IF_TRACE_MSG( " pPacket : %lx", pPacket );
IF_TRACE_MSG2( " Header : %lx %lx", pvHeaderBuffer, uiHeaderBufferSize );
IF_TRACE_MSG2( " LookAhead : %lx %lx", pvLookAheadBuffer, uiLookaheadBufferSize );
IF_TRACE_MSG( " PacketSize : %lx", uiPacketSize );
}
PACKETASSERT( (pReserved != NULL) );
PACKETASSERT( (pPacket != NULL) );
pNdisBuffer = pPacket->Private.Head;
/*virtual address of the buffer that will contain the packet*/
pvActualVirtualAddress = pNdisBuffer->VirtualAddress;
uiActualLength = pNdisBuffer->Length;
CurrBuff=pNdisBuffer->VirtualAddress;
(BYTE *)(pNdisBuffer->VirtualAddress) += sizeof(struct bpf_hdr);
if ( uiHeaderBufferSize > 0 )
{
if ( uiHeaderBufferSize > pNdisBuffer->Length )
uiHeaderBufferSize = pNdisBuffer->Length;
/*copy the header*/
NdisMoveMemory(pNdisBuffer->VirtualAddress, pvHeaderBuffer, uiHeaderBufferSize );
uiBytesTransferred = uiHeaderBufferSize;
(BYTE *)(pNdisBuffer->VirtualAddress) += uiHeaderBufferSize;
pNdisBuffer->Length -= uiHeaderBufferSize;
}
ulSizeToTransfer = uiPacketSize/*uiPacketSize - uiLookaheadBufferSize*/;
if ( ulSizeToTransfer > pNdisBuffer->Length )
ulSizeToTransfer = pNdisBuffer->Length;
/*Copy the remaining part of the packet*/
NdisTransferData( &Status,
pOpen->AdapterHandle,
MacReceiveContext,
0,
ulSizeToTransfer,
pPacket,
&uiBytesTransferred );
uiBytesTransferred+=uiHeaderBufferSize;
pNdisBuffer->VirtualAddress = pvActualVirtualAddress;
pNdisBuffer->Length = uiActualLength;
if ( Status != NDIS_STATUS_PENDING )
{
/*store the capture time*/
lCapTime=QuerySystemTime();
/*fill the bpf header for this packet*/
if( fres>uiBytesTransferred )fres=uiBytesTransferred;
lCapTime+=pOpen->StartTime;
header=(struct bpf_hdr*)CurrBuff;
header->bh_tstamp.tv_usec=(long)((lCapTime%1193182)*1000000/1193182);
header->bh_tstamp.tv_sec=(long)((lCapTime)/1193182);
header->bh_caplen=(UINT)fres;
header->bh_datalen=(UINT)uiPacketSize+uiHeaderBufferSize;
header->bh_hdrlen=sizeof(struct bpf_hdr);
/*call the completion routine*/
PacketTransferDataComplete( pOpen,
pPacket,
Status,
fres);
}
else
{
Status = NDIS_STATUS_SUCCESS;
PacketTransferDataComplete( pOpen,
pPacket,
Status,
0 );
}
TRACE_LEAVE( "Packet_tap" );
return NDIS_STATUS_SUCCESS;
}
/*Ends the transfer started with the Packet_tap function*/
VOID NDIS_API
PacketTransferDataComplete ( IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET pPacket,
IN NDIS_STATUS Status,
IN UINT uiBytesTransferred
)
{
PPACKET_RESERVED pReserved;
OVERLAPPED* pOverlap;
PNDIS_BUFFER pNdisBuffer;
TRACE_ENTER( "TransferDataComplete" );
pReserved = (PPACKET_RESERVED) pPacket->ProtocolReserved;
pOverlap = (OVERLAPPED *) pReserved->lpoOverlapped;
PACKETASSERT( (pOpen != NULL) );
PACKETASSERT( (pReserved != NULL) );
PACKETASSERT( (pOverlap != NULL) );
IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD )
{
IF_TRACE_MSG( " Status : %lx", Status );
IF_TRACE_MSG( "BytesXfered : %lx", uiBytesTransferred );
IF_TRACE_MSG( "Byte Offset : %lx", *(pReserved->lpcbBytesReturned) );
}
NdisUnchainBufferAtFront( pPacket, &pNdisBuffer );
PACKETASSERT( (pNdisBuffer != NULL) );
if ( pNdisBuffer )
NdisFreeBuffer( pNdisBuffer );
*(pReserved->lpcbBytesReturned) = uiBytesTransferred+sizeof(struct bpf_hdr);
pOverlap->O_InternalHigh = *(pReserved->lpcbBytesReturned);
/*wakes the application process*/
VWIN32_DIOCCompletionRoutine( pOverlap->O_Internal );
PacketPageUnlock( pReserved->lpBuffer, pReserved->cbBuffer );
PacketPageUnlock( pReserved->lpcbBytesReturned, sizeof(DWORD) );
PacketPageUnlock( pReserved->lpoOverlapped, sizeof(OVERLAPPED) );
NdisReinitializePacket( pPacket );
NdisFreePacket( pPacket );
TRACE_LEAVE( "TransferDataComplete" );
return;
}
VOID NDIS_API
PacketReceiveComplete( IN NDIS_HANDLE ProtocolBindingContext )
{
IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD )
{
TRACE_ENTER( "ReceiveComplete" );
TRACE_LEAVE( "ReceiveComplete" );
}
return;
}
/************************************************************
Routine called by the kernel when the timeout set in the
PacketRead function expires
************************************************************/
void _cdecl ReadTimeout(void)
{
POPEN_INSTANCE Open;
PLIST_ENTRY PacketListEntry;
PNDIS_PACKET pPacket;
PPACKET_RESERVED Reserved;
OVERLAPPED* pOverlap;
PNDIS_BUFFER pNdisBuffer;
PUCHAR CurrBuff;
struct bpf_hdr *header;
UINT to;
__int64 lCapTime;
//the parameter is in edx
_asm{
mov Open,edx
}
NdisAcquireSpinLock( &Open->RcvQSpinLock );
PacketListEntry = PacketRemoveHeadList( &Open->RcvList );
NdisReleaseSpinLock( &Open->RcvQSpinLock );
Open->ReadTimeoutTimer=0;
if (PacketListEntry == NULL)
{
return;
}
Reserved=CONTAINING_RECORD(PacketListEntry,PACKET_RESERVED,ListElement);
pPacket=CONTAINING_RECORD(Reserved,NDIS_PACKET,ProtocolReserved);
Reserved = (PPACKET_RESERVED) pPacket->ProtocolReserved;
pOverlap = (OVERLAPPED *) Reserved->lpoOverlapped;
if(Open->mode==1){
//count mode
pNdisBuffer = pPacket->Private.Head;
CurrBuff=pNdisBuffer->VirtualAddress;
/*get system time*/
lCapTime=QuerySystemTime();
/*fill the bpf header for this packet*/
lCapTime+=Open->StartTime;
header=(struct bpf_hdr*)CurrBuff;
header->bh_tstamp.tv_usec=(long)((lCapTime%1193182)*1000000/1193182);
header->bh_tstamp.tv_sec=(long)((lCapTime)/1193182);
header->bh_caplen=(UINT)16;
header->bh_datalen=(UINT)16;
header->bh_hdrlen=sizeof(struct bpf_hdr);
*(__int64*)(CurrBuff+sizeof(struct bpf_hdr))=Open->Npackets;
*(__int64*)(CurrBuff+sizeof(struct bpf_hdr)+8)=Open->Nbytes;
//reset the countetrs
Open->Npackets=0;
Open->Nbytes=0;
NdisUnchainBufferAtFront( pPacket, &pNdisBuffer );
if ( pNdisBuffer )
NdisFreeBuffer( pNdisBuffer );
*(Reserved->lpcbBytesReturned) = 16 + sizeof(struct bpf_hdr);
pOverlap->O_InternalHigh = 16 + sizeof(struct bpf_hdr);
VWIN32_DIOCCompletionRoutine( pOverlap->O_Internal );
PacketPageUnlock( Reserved->lpBuffer, Reserved->cbBuffer );
PacketPageUnlock( Reserved->lpcbBytesReturned, sizeof(DWORD) );
PacketPageUnlock( Reserved->lpoOverlapped, sizeof(OVERLAPPED) );
NdisReinitializePacket( pPacket );
NdisFreePacket( pPacket );
return;
}
NdisUnchainBufferAtFront( pPacket, &pNdisBuffer );
if ( pNdisBuffer )
NdisFreeBuffer( pNdisBuffer );
//wakes the application process
*(Reserved->lpcbBytesReturned) = 0;
pOverlap->O_InternalHigh = *(Reserved->lpcbBytesReturned);
VWIN32_DIOCCompletionRoutine( pOverlap->O_Internal );
PacketPageUnlock( Reserved->lpBuffer, Reserved->cbBuffer );
PacketPageUnlock( Reserved->lpcbBytesReturned, sizeof(DWORD) );
PacketPageUnlock( Reserved->lpoOverlapped, sizeof(OVERLAPPED) );
NdisReinitializePacket( pPacket );
NdisFreePacket( pPacket );
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -