From: Rajesh Patel on
I have run into a problem while creating my own packet.
I have successfully managed to create new net buffer list and send it
to TCP/IP in FilterReceiveNetBufferLists. However, when I try to
repeat the same process in function, FilterSendNetBufferLists, to send
data to the underlying miniport it fails. Is there a difference
between how you are supposed to construct netbuffer lists? What am I
doing wrong? Is NBL construction missing something?

Here is my sample code and the output log. As you can see, the
miniport is actually sending me SendComplete but I do not see packets
on the wire. If I go back to original code for send, everything works.

Thank you for your help,

Regards,
RP

int CreateMyNBL(PMS_FILTER pFilter, PNET_BUFFER_LIST* ppNBL, char*
pOrigBuf, int nBufLen)
{
PNET_BUFFER_LIST pNBL;
char *pBuf;
PMDL pMdl;

if (ppNBL)
{
*ppNBL = NULL;
}

NdisAllocateMemoryWithTag((void *)(&pBuf), nBufLen, 'DCBA');
if (!pBuf)
{
DBG_PRINT(("<==: Memory Allocation failed\n"));
return -1;
}
// DBG_PRINT(("(%d) NdisAllocateMemoryWithTag returned %p\n",
__LINE__, pBuf));
RtlCopyMemory(pBuf, pOrigBuf, nBufLen);

// create MDL
// DBG_PRINT(("(%d) calling NdisAllocateMdl\n", __LINE__));
pMdl = NdisAllocateMdl(pFilter->FilterHandle,
pBuf,
nBufLen);

// DBG_PRINT(("(%d) NdisAllocateMdl returned %p\n", __LINE__,
pMdl));
if (!pMdl)
return -1;

pNBL = NdisAllocateNetBufferAndNetBufferList(
pFilter->NetBufferListPool,
0,
0,
pMdl,
0,
nBufLen);

if (!pNBL)
return -1;

pNBL->SourceHandle = pFilter->FilterHandle;
if (ppNBL)
{
*ppNBL = pNBL;
}

return 0;
}


int
ProcessSendBuffers
(
PNET_BUFFER_LIST pNetBufferLists,
PMS_FILTER pFilter,
ULONG PortNumber,
ULONG SendFlags
)
{
PNET_BUFFER_LIST pCurNBList = pNetBufferLists;
BOOLEAN DispatchLevel =
NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags);
ULONG ReturnFlags = 0;

DBG_PRINT(("==> ProcessSendBuffers: SendFlags =
%x-------------------------------\n", SendFlags));
for (pCurNBList = pNetBufferLists;
pCurNBList != NULL;
pCurNBList = NET_BUFFER_LIST_NEXT_NBL(pCurNBList))
{
PNET_BUFFER pCurNB;
for (pCurNB = NET_BUFFER_LIST_FIRST_NB(pCurNBList);
pCurNB != NULL;
pCurNB = NET_BUFFER_NEXT_NB(pCurNB))
{
int nRet = 0;
NDIS_STATUS Status;
char *pOrigBuf;
int nBytesRead = 0;

// Just allocate 2048 bytes - should be good enough to see
if it works.
NdisAllocateMemoryWithTag(&pOrigBuf, BUFFERSIZE, 'DCBA');
nRet = ReadDataFromNetBuf(pCurNB, pOrigBuf, BUFFERSIZE,
&nBytesRead);

if (0 == nRet && nBytesRead > 0)
{
ULONG NewSendFlags = 0;
PNET_BUFFER_LIST pSendNBL;

nRet = CreateMyNBL(pFilter, &pSendNBL, pOrigBuf,
nBytesRead);
NdisFreeMemory(pOrigBuf, BUFFERSIZE, 0);

// Drop the original packet. Send the new packet.
if (DispatchLevel)
{
NewSendFlags = NDIS_SEND_FLAGS_DISPATCH_LEVEL;
}

DBG_PRINT(("ProcessSendBuffers: Sending %p Dispatch
Level = %d: SendFlags = %x, NewSendFlags = %x\n",
pSendNBL, DispatchLevel, SendFlags,
NewSendFlags));

NdisFSendNetBufferLists(
pFilter->FilterHandle,
pSendNBL,
PortNumber,
NewSendFlags);

} while(0);
}
}

NdisFSendNetBufferListsComplete(
pFilter->FilterHandle,
pNetBufferLists,
DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0);

DBG_PRINT(("<== ProcessSendBuffers: -------------------------------
\n"));
return 0;
}

VOID
FilterSendNetBufferLists(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN NDIS_PORT_NUMBER PortNumber,
IN ULONG SendFlags
)
{
do {
....
if (1)
{
int nRet = ProcessSendBuffers(NetBufferLists,
pFilter,
PortNumber,
SendFlags);
break;
}
if (pFilter->TrackSends)
{
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);

....
} while(0);
}


00000068 1.39932311 ==> ProcessSendBuffers: SendFlags =
0-------------------------------
00000069 1.39976418 <== Dispatch Level = 0: SendFlags = 0,
NewSendFlags = 0
00000070 1.40053976 <== ProcessSendBuffers:
-------------------------------
00000071 1.40054703 ===>SendNBLComplete, Consume our own
NetBufferList: 852CF018.
00000072 1.40642345 ==> ProcessRecvBuffers: ReceiveFlags =
1-------------------------------
00000073 1.40645361 <== Dispatch Level = 1: ReceiveFlags = 1,
NewReceiveFlags = 3
00000074 1.40650082 <== ProcessRecvBuffers:
-------------------------------
00000075 1.40945852 ==> ProcessRecvBuffers: ReceiveFlags =
1-------------------------------
00000076 1.40947807 <== Dispatch Level = 1: ReceiveFlags = 1,
NewReceiveFlags = 3
00000077 1.40950596 <== ProcessRecvBuffers:
-------------------------------
00000078 1.47461307 ==> ProcessSendBuffers: SendFlags =
0-------------------------------
00000079 1.47466111 <== Dispatch Level = 0: SendFlags = 0,
NewSendFlags = 0
00000080 1.47488499 <== ProcessSendBuffers:
-------------------------------
00000081 1.47492969 ===>SendNBLComplete, Consume our own
NetBufferList: 825CFDC8.
00000082 1.50873673 ==> ProcessRecvBuffers: ReceiveFlags =
1-------------------------------
00000083 1.50878501 <== Dispatch Level = 1: ReceiveFlags = 1,
NewReceiveFlags = 3
00000084 1.50883508 <== ProcessRecvBuffers:
-------------------------------
00000085 1.50960922 ==> ProcessRecvBuffers: ReceiveFlags =
1-------------------------------
00000086 1.50966787 <== Dispatch Level = 1: ReceiveFlags = 1,
NewReceiveFlags = 3
00000087 1.50968933 <== ProcessRecvBuffers:
-------------------------------
00000088 1.51953423 ==> ProcessSendBuffers: SendFlags =
0-------------------------------
00000089 1.51961291 <== Dispatch Level = 0: SendFlags = 0,
NewSendFlags = 0
00000090 1.51979983 <== ProcessSendBuffers:
-------------------------------
00000091 1.51982582 ===>SendNBLComplete, Consume our own
NetBufferList: 852CF018.
00000092 1.55920792 ==> ProcessSendBuffers: SendFlags =
0-------------------------------
00000093 1.55923867 <== Dispatch Level = 0: SendFlags = 0,
NewSendFlags = 0
00000094 1.55998313 <== ProcessSendBuffers:
-------------------------------