Ejemplo n.º 1
0
VOID
LpxFakeTransferDataComplete (
    IN NDIS_HANDLE BindingContext,
    IN PNDIS_PACKET NdisPacket,
    IN NDIS_STATUS NdisStatus,
    IN UINT BytesTransferred
)
{
    ENTER_LPX;
    LpxTransferDataComplete (BindingContext, NdisPacket, NdisStatus, BytesTransferred);
    LEAVE_LPX;
}
Ejemplo n.º 2
0
NDIS_STATUS
LpxReceiveIndication (
	IN NDIS_HANDLE	ProtocolBindingContext,
	IN NDIS_HANDLE	MacReceiveContext,
	IN PVOID		HeaderBuffer,
	IN UINT		    HeaderBufferSize,
	IN PVOID		LookAheadBuffer,
	IN UINT		    LookAheadBufferSize,
	IN UINT		    PacketSize
	)
/*++

Routine Description:

	This routine receives control from the physical provider as an
	indication that a frame has been received on the physical link.
	This routine is time critical, so we only allocate a
	buffer and copy the packet into it. We also perform minimal
	validation on this packet. It gets queued to the device context
	to allow for processing later.

Arguments:

	BindingContext - The Adapter Binding specified at initialization time.

	ReceiveContext - A magic cookie for the MAC.

	HeaderBuffer - pointer to a buffer containing the packet header.

	HeaderBufferSize - the size of the header.

	LookaheadBuffer - pointer to a buffer containing the negotiated minimum
		amount of buffer I get to look at (not including header).

	LookaheadBufferSize - the size of the above. May be less than asked
		for, if that's all there is.

	PacketSize - Overall size of the packet (not including header).

Return Value:

	NDIS_STATUS - status of operation, one of:

			     NDIS_STATUS_SUCCESS if packet accepted,
			     NDIS_STATUS_NOT_RECOGNIZED if not recognized by protocol,
			     NDIS_any_other_thing if I understand, but can't handle.

--*/
{
	PDEVICE_CONTEXT	deviceContext;
	USHORT		    protocol;
	PNDIS_PACKET	packet;
	NDIS_STATUS		status;
	UINT		    bytesTransfered = 0;
	UINT		    startOffset = 0;


	DebugPrint( 4, ("LpxReceiveIndication, Entered\n") );
	
	deviceContext = (PDEVICE_CONTEXT)ProtocolBindingContext;

	//
	//	validation
	//

	if (HeaderBufferSize != ETHERNET_HEADER_LENGTH) {

		DebugPrint( 4, ("HeaderBufferSize = %x\n", HeaderBufferSize) );
		return NDIS_STATUS_NOT_RECOGNIZED;
	}
	
	RtlCopyMemory( (PUCHAR)&protocol, &((PUCHAR)HeaderBuffer)[12], sizeof(USHORT) );

	//
	//	Discard 802.2 LLC SNAP field.
	//
	// if Ether Type less than 0x0600 ( 1536 )
	//

	if (NTOHS(protocol) < 0x0600  && 
	    protocol != HTONS(0x0060) && // LOOP: Ethernet Loopback
		protocol != HTONS(0x0200) && // PUP : Xerox PUP packet
		protocol != HTONS(0x0201)) { // PUPAP: Xerox PUP address trans packet 

#if __LPX__
		NdisCopyLookaheadData( (PUCHAR)&protocol,
								&((PUCHAR)LookAheadBuffer)[LENGTH_8022LLCSNAP - 2],
								sizeof(USHORT),
								deviceContext->MacOptions );
#endif
		PacketSize -= LENGTH_8022LLCSNAP;
		LookAheadBufferSize -= LENGTH_8022LLCSNAP;
		startOffset = LENGTH_8022LLCSNAP;
	}

	if (protocol != HTONS(ETH_P_LPX)) {
	
		DebugPrint( 4, ("Type = %x\n", protocol) );
		return NDIS_STATUS_NOT_RECOGNIZED;
	}


	//
	//	Check to see if the device context is initialized.
	//

	//ACQUIRE_DPC_SPIN_LOCK( &deviceContext->SpinLock );

	if (!FlagOn(deviceContext->LpxFlags, LPX_DEVICE_CONTEXT_START) || FlagOn(deviceContext->LpxFlags, LPX_DEVICE_CONTEXT_STOP)) {
	
		//RELEASE_DPC_SPIN_LOCK( &deviceContext->SpinLock );
		DebugPrint( 4,("Device is not initialized. Drop packet\n") );

		return NDIS_STATUS_NOT_RECOGNIZED;
	}

	ASSERT( deviceContext->NdisBindingHandle );

	//RELEASE_DPC_SPIN_LOCK( &deviceContext->SpinLock );

	//
	// DROP PACKET for DEBUGGING!!!!
	//

#if 1 //DBG // Enabled for testing

	if (PacketRxDropRate) {

		PacketRxCountForDrop++;
				
		if ((PacketRxCountForDrop % 1000) <= PacketRxDropRate) {
			PLPX_HEADER        lpxHeader = (PLPX_HEADER)LookAheadBuffer;
#if 0
			if ((PacketRxCountForDrop % (PacketRxDropRate*20)) == 0) 
				DebugPrint( 1, ("[Drop(%x,%x,%x))]\n", 
								 NTOHS(lpxHeader->Lsctl), NTOHS(lpxHeader->Sequence), NTOHS(lpxHeader->AckSequence)) );
#endif			
			DebugPrint( 1, ("D") );

			return NDIS_STATUS_NOT_RECOGNIZED;
		}
	}

#endif

	ASSERT( startOffset == 0 );

	DebugPrint( 4, ("LpxReceiveIndication, PacketSize = %d, LookAheadBufferSize = %d, LPX_HEADER size = %d\n",
					 PacketSize, LookAheadBufferSize, sizeof(LPX_HEADER)) );

	if (LookAheadBufferSize >= sizeof(LPX_HEADER)) {

		PNDIS_BUFFER	firstBuffer;    
		PUCHAR		    packetData;
		PLPX_HEADER		lpxHeader;
		USHORT			lpxHeaderSize;

		
		lpxHeader = (PLPX_HEADER)((PBYTE)LookAheadBuffer + startOffset);
		
		lpxHeaderSize = sizeof(LPX_HEADER);

#if __LPX_OPTION_ADDRESSS__

		if (FlagOn(lpxHeader->Option, LPX_OPTION_SOURCE_ADDRESS)) {

			lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
		}

		if (FlagOn(lpxHeader->Option, LPX_OPTION_DESTINATION_ADDRESS)) {

			lpxHeaderSize += ETHERNET_ADDRESS_LENGTH;
		}

#endif

		if (NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK) == lpxHeaderSize) {

			status = RcvPacketAlloc( deviceContext,
									 0,
									 &packet );

			if (status == STATUS_SUCCESS) {

				NdisCopyLookaheadData( &RESERVED(packet)->EthernetHeader,
										HeaderBuffer,
										ETHERNET_HEADER_LENGTH,
										deviceContext->MacOptions );

				RESERVED(packet)->EthernetHeader.Type = protocol;
				RESERVED(packet)->RecvTime = CurrentTime();
			
				RtlCopyMemory( &RESERVED(packet)->LpxHeader, lpxHeader, lpxHeaderSize );
				RESERVED(packet)->HeaderCopied = TRUE;

				RESERVED(packet)->PacketRawDataLength = 0;
				RESERVED(packet)->PacketRawDataOffset = 0;

				LpxTransferDataComplete( deviceContext,
					                     packet,
					                     NDIS_STATUS_SUCCESS,
					                     LookAheadBufferSize );

				return NDIS_STATUS_SUCCESS;
			}

		} else if (LookAheadBufferSize >= NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK)) {
				
			status = RcvPacketAlloc( deviceContext,
									 NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK) - lpxHeaderSize,
									 &packet );

			if (status == STATUS_SUCCESS) {
			
				NdisCopyLookaheadData( &RESERVED(packet)->EthernetHeader,
										HeaderBuffer,
										ETHERNET_HEADER_LENGTH,
										deviceContext->MacOptions );

				RESERVED(packet)->EthernetHeader.Type = protocol;
				RESERVED(packet)->RecvTime = CurrentTime();

				RtlCopyMemory( &RESERVED(packet)->LpxHeader, lpxHeader, lpxHeaderSize );
				RESERVED(packet)->HeaderCopied = TRUE;

				RESERVED(packet)->PacketRawDataLength = NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK) - lpxHeaderSize;
				RESERVED(packet)->PacketRawDataOffset = 0;

				NdisQueryPacket( packet, NULL, NULL, &firstBuffer, NULL );
				packetData = MmGetMdlVirtualAddress( firstBuffer );

				NdisCopyLookaheadData( packetData,
									   (PBYTE)LookAheadBuffer + startOffset + lpxHeaderSize,
									   RESERVED(packet)->PacketRawDataLength,
									   deviceContext->MacOptions );

				LpxTransferDataComplete( deviceContext,
					                     packet,
					                     NDIS_STATUS_SUCCESS,
					                     LookAheadBufferSize );

				return NDIS_STATUS_SUCCESS;
			}

		} else {

			status = RcvPacketAlloc( deviceContext,
									 startOffset + NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK),
									 &packet );
			
			if (status == STATUS_SUCCESS) {
			
				NdisCopyLookaheadData( &RESERVED(packet)->EthernetHeader,
										HeaderBuffer,
										ETHERNET_HEADER_LENGTH,
										deviceContext->MacOptions );

				RESERVED(packet)->EthernetHeader.Type = protocol;
				RESERVED(packet)->RecvTime = CurrentTime();

				RtlCopyMemory( &RESERVED(packet)->LpxHeader, lpxHeader, lpxHeaderSize );
				RESERVED(packet)->HeaderCopied = TRUE;

				RESERVED(packet)->PacketRawDataLength = startOffset + NTOHS(lpxHeader->PacketSize & ~LPX_TYPE_MASK);
				RESERVED(packet)->PacketRawDataOffset = startOffset + lpxHeaderSize;
			}
		}

	} else {

		PLPX_HEADER		lpxHeader;
		PNDIS_BUFFER	firstBuffer;	
		PUCHAR			packetData;
		UINT			packetDataLength;

		ASSERT( FALSE );

		status = RcvPacketAlloc( deviceContext, PacketSize, &packet );
		
		if (status == STATUS_SUCCESS) {
		
			RtlCopyMemory( &RESERVED(packet)->EthernetHeader,
						   HeaderBuffer,
						   ETHERNET_HEADER_LENGTH );

			RESERVED(packet)->EthernetHeader.Type = protocol;
			RESERVED(packet)->RecvTime = CurrentTime();

			RESERVED(packet)->PacketRawDataLength = PacketSize;
			RESERVED(packet)->PacketRawDataOffset = startOffset;

			NdisQueryPacket( packet, NULL, NULL, &firstBuffer, NULL );
			NdisQueryBufferSafe( firstBuffer, &packetData, &packetDataLength, HighPagePriority );

			lpxHeader = (PLPX_HEADER)(packetData + RESERVED(packet)->PacketRawDataOffset);
			RtlZeroMemory( lpxHeader, sizeof(LPX_HEADER) );

			RESERVED(packet)->HeaderCopied = FALSE;
		}
	}

	if (status != NDIS_STATUS_SUCCESS) {
	
		return NDIS_STATUS_NOT_RECOGNIZED;
	}

	ASSERT( packet->Private.NdisPacketFlags & fPACKET_ALLOCATED_BY_NDIS );
			
	if (deviceContext->NdisBindingHandle) {

		//ASSERT( FALSE );

		NdisTransferData( &status,
						  deviceContext->NdisBindingHandle,
						  MacReceiveContext,
						  0, //RESERVED(packet)->PacketRawDataOffset,
						  RESERVED(packet)->PacketRawDataLength,
						  packet,
						  &bytesTransfered );

			
		if (status == NDIS_STATUS_PENDING) {

			LPX_ASSERT( FALSE );
		    status = NDIS_STATUS_SUCCESS;
		
		} else if (status == NDIS_STATUS_SUCCESS) {
		
			LpxTransferDataComplete( deviceContext,
									 packet,
									 status,
									 bytesTransfered );

		} else {
	
			LPX_ASSERT( FALSE );
			DebugPrint( 1, ("NdisTransferData() failed. STATUS=%08lx\n", status) );
		}

	} else {
			
		status = NDIS_STATUS_NOT_RECOGNIZED;
		DebugPrint( 1, ("Invalid device status. STATUS=%08lx\n", status) );
	}

	return status;
}