|
|
/*++
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")); }
|