1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
/*++
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"
VOID
NdisWanQueueLoopbackPacket(
PADAPTERCB AdapterCB,
PNDIS_PACKET NdisPacket
)
{
PLOOPBACK_DESC LoopbackDesc;
ULONG AllocationSize, BufferLength;
NdisWanDbgOut(DBG_TRACE, DBG_LOOPBACK, ("NdisWanQueueLoopbackPacket: Enter"));
NdisWanDbgOut(DBG_INFO, DBG_LOOPBACK, ("AdapterCB: 0x%8.8x, NdisPacket: 0x%8.8x",
AdapterCB, NdisPacket));
//
// Create a loopback descriptor
//
NdisQueryPacket(NdisPacket,
NULL,
NULL,
NULL,
&BufferLength);
AllocationSize = BufferLength + sizeof(LOOPBACK_DESC);
NdisWanAllocateMemory(&LoopbackDesc, AllocationSize);
if (LoopbackDesc != NULL) {
ULONG BytesCopied;
PDEFERRED_DESC DeferredDesc;
//
// For loopback we do not care about the bundlecb/protocolcb
// states so they will remain NULL.
//
LoopbackDesc->AllocationSize = (USHORT)AllocationSize;
LoopbackDesc->BufferLength = (USHORT)BufferLength;
LoopbackDesc->Buffer = (PUCHAR)LoopbackDesc + sizeof(LOOPBACK_DESC);
//
// Copy the current packet
//
NdisWanCopyFromPacketToBuffer(NdisPacket,
0,
0xFFFFFFFF,
LoopbackDesc->Buffer,
&BytesCopied);
ASSERT(BytesCopied == BufferLength);
NdisAcquireSpinLock(&AdapterCB->Lock);
NdisWanGetDeferredDesc(AdapterCB, &DeferredDesc);
ASSERT(DeferredDesc != NULL);
DeferredDesc->Context = (PVOID)LoopbackDesc;
InsertTailDeferredQueue(&AdapterCB->DeferredQueue[Loopback], DeferredDesc);
NdisWanSetDeferred(AdapterCB);
NdisReleaseSpinLock(&AdapterCB->Lock);
} else {
NdisWanDbgOut(DBG_FAILURE, DBG_LOOPBACK, ("NdisWanQueueLoopbackPacket: Memory allocation failure!"));
}
}
VOID
NdisWanProcessLoopbacks(
PADAPTERCB AdapterCB
)
{
RECV_DESC RecvDesc;
NdisWanDbgOut(DBG_TRACE, DBG_LOOPBACK, ("NdisWanIndicateLoopback: Enter"));
NdisWanDbgOut(DBG_TRACE, DBG_LOOPBACK, ("NdisWanIndicateLoopback: AdapterCB 0x%8.8x", AdapterCB));
while (!IsDeferredQueueEmpty(&AdapterCB->DeferredQueue[Loopback])) {
PDEFERRED_DESC ReturnDesc;
PLOOPBACK_DESC LoopbackDesc;
ReturnDesc = RemoveHeadDeferredQueue(&AdapterCB->DeferredQueue[Loopback]);
NdisReleaseSpinLock(&AdapterCB->Lock);
LoopbackDesc = ReturnDesc->Context;
NdisWanDbgOut(DBG_INFO, DBG_LOOPBACK, ("NdisWanIndicateLoopback: Desc 0x%8.8x", LoopbackDesc));
RecvDesc.Flags = 0x4c4F4F50;
RecvDesc.WanHeader = LoopbackDesc->Buffer;
RecvDesc.WanHeaderLength = 14;
RecvDesc.LookAhead = NULL;
RecvDesc.LookAheadLength = 0;
RecvDesc.CurrentBuffer = LoopbackDesc->Buffer + 14;
RecvDesc.CurrentBufferLength = LoopbackDesc->BufferLength - 14;
ASSERT((LONG)RecvDesc.CurrentBufferLength > 0);
NdisMEthIndicateReceive(AdapterCB->hMiniportHandle,
&RecvDesc,
LoopbackDesc->Buffer,
14,
LoopbackDesc->Buffer + 14,
LoopbackDesc->BufferLength - 14,
LoopbackDesc->BufferLength - 14);
NdisWanFreeMemory(LoopbackDesc);
NdisAcquireSpinLock(&AdapterCB->Lock);
AdapterCB->Flags |= RECEIVE_COMPLETE;
InsertHeadDeferredQueue(&AdapterCB->FreeDeferredQueue, ReturnDesc);
}
}
|