⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	}


	/*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 + -