140 lines
3.4 KiB
C
140 lines
3.4 KiB
C
/*++
|
|
|
|
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"));
|
|
}
|