/*++ Copyright (c) 1990-1995 Microsoft Corporation Module Name: Loopback.c Abstract: This file contains the procedures for doing loopback of send packets for ndiswan. Loopback is being done in NdisWan because the NDIS wrapper could not meet all of the needs of NdisWan. Author: Tony Bell (TonyBe) January 25, 1996 Environment: Kernel Mode Revision History: TonyBe 01/25/96 Created --*/ #include "wan.h" #define __FILE_SIG__ LOOPBACK_FILESIG VOID NdisWanIndicateLoopbackPacket( PMINIPORTCB MiniportCB, PNDIS_PACKET NdisPacket ) { ULONG BytesCopied, PacketLength; PRECV_DESC RecvDesc; PNDIS_PACKET LocalNdisPacket; PNDIS_BUFFER NdisBuffer; NDIS_STATUS Status; PCM_VCCB CmVcCB; KIRQL OldIrql; NdisWanDbgOut(DBG_TRACE, DBG_LOOPBACK, ("NdisWanIndicateLoopbackPacket: Enter")); NdisWanDbgOut(DBG_INFO, DBG_LOOPBACK, ("MiniportCB: 0x%p, NdisPacket: 0x%p", MiniportCB, NdisPacket)); NdisQueryPacket(NdisPacket, NULL, NULL, NULL, &PacketLength); RecvDesc = NdisWanAllocateRecvDesc(PacketLength); if (RecvDesc == NULL) { return; } NdisWanCopyFromPacketToBuffer(NdisPacket, 0, PacketLength, RecvDesc->StartBuffer, &BytesCopied); ASSERT(BytesCopied == PacketLength); if (MiniportCB->ProtocolType == PROTOCOL_IP) { UCHAR x[ETH_LENGTH_OF_ADDRESS]; // // If this is IP we are going to assume // that wanarp has set the appropriate // bit requiring ndiswan to loopback the // packet so we must switch the src/dest // contexts. ETH_COPY_NETWORK_ADDRESS(x, &RecvDesc->StartBuffer[6]); ETH_COPY_NETWORK_ADDRESS(&RecvDesc->StartBuffer[6], &RecvDesc->StartBuffer[0]); ETH_COPY_NETWORK_ADDRESS(&RecvDesc->StartBuffer[0], x); } RecvDesc->CurrentLength = PacketLength; LocalNdisPacket = RecvDesc->NdisPacket; NdisBuffer = RecvDesc->NdisBuffer; // // Attach the buffers // NdisAdjustBufferLength(NdisBuffer, RecvDesc->CurrentLength); NdisRecalculatePacketCounts(LocalNdisPacket); CmVcCB = PMINIPORT_RESERVED_FROM_NDIS(NdisPacket)->CmVcCB; KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); NDIS_SET_PACKET_STATUS(LocalNdisPacket, NDIS_STATUS_RESOURCES); INSERT_DBG_RECV(PacketTypeNdis, MiniportCB, NULL, NULL, LocalNdisPacket); // // Indicate the packet // if (CmVcCB != NULL) { NdisMCoIndicateReceivePacket(CmVcCB->NdisVcHandle, &LocalNdisPacket, 1); } else { NdisMIndicateReceivePacket(MiniportCB->MiniportHandle, &LocalNdisPacket, 1); } KeLowerIrql(OldIrql); #if DBG Status = NDIS_GET_PACKET_STATUS(LocalNdisPacket); ASSERT(Status == NDIS_STATUS_RESOURCES); #endif REMOVE_DBG_RECV(PacketTypeNdis, MiniportCB, LocalNdisPacket); NdisWanFreeRecvDesc(RecvDesc); NdisWanDbgOut(DBG_TRACE, DBG_LOOPBACK, ("NdisWanIndicateLoopbackPacket: Exit")); }