RE: NDIS FILTER DRIVER
- From: Anton Bassov <AntonBassov@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Wed, 28 Mar 2007 05:14:04 -0700
I have virtual lan
device (used from DDK).and two NIC's on the same machine. Every
packet you receive on these two nics should be sent to Virtual NIC as
a copy.
So in the FilterReceivenetBufferlists I am cloning the each packet and
sending it to the Virtual Miniport
Is this virtual miniport's protocol side bound to physical NICs??? If it is,
then it receives packets from them anyway. If it is not bound to physical
NICs, then it is not related to LWF that is bound to them either, so that
your indications are not going to reach it. In other words, no matter how you
look at it, your project just does not seem to make sense, at least in its
current implementation. It would make sense if virtual miniport was bound
only to NIC X, and you wanted to forward a copy of data that arrives on NIC
Y ( i.e the one it is not bound to) to it, using NDIS_HANDLE that corresponds
to binding between NIC X and your LWF.
I think there is some problem with freeing the clone buffer list.
Indeed, I see a *HUGE* problem here, although it is not related to the
memory leak.....
What will be best place to free this buffer?
It does not matter *WHERE* you free it - it depends on *HOW* you do things...
If you don't specify NDIS_RECEIVE_FLAG_RESOURCES, then your buffer will be
returned to FilterReturnNetBufferLists() so that you can free it.
Alternatively, you can
set NDIS_RECEIVE_FLAG_RESOURCES in 'ReceiveFlags' parameter of
NdisFIndicateReceiveNetBufferLists(), which forces overlying drivers to copy
packet data. If you do it this way, then you have to free it in the function
that calls NdisFIndicateReceiveNetBufferLists(), which is
FilterReceiveNetBufferList() in your case.
Now look at what you do:
NdisFIndicateReceiveNetBufferLists( ClonetFilter->FilterHandle,
ClonedList, PortNumber, 1, ReceiveFlags);
NdisFreeCloneNetBufferList(ClonedList,0);
Once you have not specified NDIS_RECEIVE_FLAG_RESOURCES flag, overlying
drivers are free to access it until calling NdisReturnNetBufferLists(), i.e.
something that can be done at some later stage. However, you free the list
right after
NdisFIndicateReceiveNetBufferLists() returns control. In other words,
overlying drivers may eventually access a list that you have already freed.
BANG!!!!!
Concerning the memory leak, I can see 2 calls to
NdisAllocateNetBufferListContext(), but not a single one to
NdisFreeNetBufferListContext().....
Anton Bassov
"Abhi" wrote:
Hello All,.
I am trying to do a "customized mac bridge" between two lans.I
started with LWF of DDK. My project is like this. I have virtual lan
device (used from DDK).and two NIC's on the same machine. Every
packet you receive on these two nics should be sent to Virtual NIC as
a copy.
So in the FilterReceivenetBufferlists I am cloning the each packet and
sending it to the Virtual Miniport. I have attached my function here.
But the problem I am facing is the whenever i try to file transfer or
big network load receive ,network connection is just disconnected.but
with smaller ping traffics it just works fine.After the drop of
connection I need to restart the machine(it doesn't hang) to start the
network.
Can anybody suggest me what must be happening? I think there is some
problem with freeing the clone buffer list.What will be best place to
free this buffer?
///
.....
//////////
do
{
DispatchLevel = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags);
ASSERT(NumberOfNetBufferLists >= 1);
{
CurrNbl = NetBufferLists;
while (CurrNbl)
{
DbgPrint(" RecvNetBufferList: CurrNbl = %p\n",
CurrNbl);
if(g_bIsVirtual==FALSE)
{
ClonedList=NdisAllocateCloneNetBufferList(CurrNbl,0,0,0);
Status =
NdisAllocateNetBufferListContext(ClonedList,sizeof(IM_NBL_ENTRY), 0,
FILTER_TAG);
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFreeCloneNetBufferList(ClonedList,0);
}
else
{
CloneRecvContext = (PIM_NBL_ENTRY)
NET_BUFFER_LIST_CONTEXT_DATA_START(ClonedList);
NdisZeroMemory(CloneRecvContext, sizeof(IM_NBL_ENTRY));
// SendContext->PreviousSourceHandle =
CurrNbl->SourceHandle;
CloneRecvContext->pFilter = gpVirtual;
ClonetFilter = gpVirtual;
NdisFIndicateReceiveNetBufferLists(
ClonetFilter->FilterHandle,
ClonedList,
PortNumber,
1,
ReceiveFlags);
//NdisFreeCloneNetBufferList(ClonedList,0);
}
}//End of checking whether it is virtual or not.
/*CHEATING END*/
NetBufferLists = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
NET_BUFFER_LIST_NEXT_NBL(CurrNbl) = NULL;
{
NET_BUFFER *pNB = NET_BUFFER_LIST_FIRST_NB(CurrNbl);
DbgPrint(" Data Length:%d\n",
NET_BUFFER_DATA_LENGTH(pNB));
pEthFrame = NdisGetDataBuffer(pNB, 14, NULL, 1, 0);
}
Status = NdisAllocateNetBufferListContext(CurrNbl,
sizeof(IM_NBL_ENTRY), 0, FILTER_TAG);
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFReturnNetBufferLists(
pFilter->FilterHandle, CurrNbl,
DispatchLevel ?
NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0);
}
else
{
RecvContext = (PIM_NBL_ENTRY)
NET_BUFFER_LIST_CONTEXT_DATA_START(CurrNbl);
NdisZeroMemory(RecvContext, sizeof(IM_NBL_ENTRY));
// SendContext->PreviousSourceHandle =
CurrNbl->SourceHandle;
RecvContext->pFilter = pFilter;
tFilter = pFilter;
DbgPrint(" toVNIC:%d\n", toVNIC);
}
DbgPrint(" LWF==>%c%c TCPIP==>%c%c\n",
pFilter->MiniportFriendlyName.Buffer[13],
pFilter->MiniportFriendlyName.Buffer[14],
tFilter->MiniportFriendlyName.Buffer[13],
tFilter->MiniportFriendlyName.Buffer[14]);
NdisFIndicateReceiveNetBufferLists(
tFilter->FilterHandle,
CurrNbl,
PortNumber,
1,
ReceiveFlags);
}
CurrNbl = NetBufferLists;
}
}
} while (FALSE);
- References:
- NDIS FILTER DRIVER
- From: Abhi
- NDIS FILTER DRIVER
- Prev by Date: Re: Getting MAC Header Size from an Intermediate Driver
- Next by Date: Re: Getting DC from SURFOBJ or HDEV
- Previous by thread: NDIS FILTER DRIVER
- Next by thread: NDIS ProtocolReceive - Is It Dead Yet?
- Index(es):
Relevant Pages
|