Ndislwf: drop some packets but error

Hello everyone!

I am writting ndis lw filter which is supposed to filter packets and drop those with specified port or content.
I searched some archives, and then write in the FilterSendNetBufferLists function as follow:

PNET_BUFFER_LIST fNetBufferLists = NULL; //queue the NBL which would be freed
PNET_BUFFER_LIST fNetBufferListstmp = NULL;
PNET_BUFFER_LIST sNetBufferLists = NULL; // queue the NBL which would be sended
PNET_BUFFER_LIST sNetBufferListstmp = NULL;
USHORT flag;
do
{
CurrNbl = NetBufferLists;
while (CurrNbl)
{
NextNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
for(pCurrentNetBuffer = NET_BUFFER_LIST_FIRST_NB(CurrNbl);
pCurrentNetBuffer != NULL;
pCurrentNetBuffer = NET_BUFFER_NEXT_NB(pCurrentNetBuffer))
{

NdisGetDataBuffer(pCurrentNetBuffer,scanlength,pPakData,1,0)
if( (flag = search(pPakData, scanlength)) == STREAM_POLICY_DENY )
goto ExitNBFilter;

}
ExitNBFilter:
if( flag & STREAM_POLICY_DENY){
if( fNetBufferListstmp != NULL ){
NET_BUFFER_LIST_NEXT_NBL(fNetBufferListstmp) = CurrNbl;
fNetBufferListstmp = CurrNbl;
NET_BUFFER_LIST_NEXT_NBL(fNetBufferListstmp) = NULL;
}
else
{
fNetBufferLists = CurrNbl;
fNetBufferListstmp = CurrNbl;
NET_BUFFER_LIST_NEXT_NBL(fNetBufferListstmp) = NULL;
}
}
else
{
if( sNetBufferListstmp != NULL ){
NET_BUFFER_LIST_NEXT_NBL(sNetBufferListstmp) = CurrNbl;
sNetBufferListstmp = CurrNbl;
NET_BUFFER_LIST_NEXT_NBL(sNetBufferListstmp) = NULL;
}
else
{
sNetBufferLists = CurrNbl;
sNetBufferListstmp = CurrNbl;
NET_BUFFER_LIST_NEXT_NBL(sNetBufferListstmp) = NULL;
}

}
CurrNbl= NextNbl;
}
if(fNetBufferLists != NULL)
NdisReturnNetBufferLists(pFilter->FilterHandle, fNetBufferLists, SendFlags);
if(sNetBufferLists != NULL)
NdisFSendNetBufferLists(pFilter->FilterHandle, sNetBufferLists, PortNumber, SendFlags);
}while (bFalse);

Then i test the dirver, and the bulescreen happened, the info in windbg is like this:

STACK_COMMAND: kb

FOLLOWUP_IP:
ndislwf!FilterSendNetBufferLists+775 [z:\coding\app_ndis\filter.c @ 1465]
8dfe12e5 8b4d14 mov ecx,dword ptr [ebp+14h]

FAULTING_SOURCE_CODE:
1464: NdisReturnNetBufferLists(pFilter->FilterHandle, fNetBufferLists, SendFlags);

1465: NdisFSendNetBufferLists(pFilter->FilterHandle, sNetBufferLists, PortNumber, SendFlags);
1466:
1467: }
1468: while (bFalse);

There are error codes, but i can’t find why.
I am newbie, Thanks a lot for your time!

You have two bugs, both on the same line of code:

NdisReturnNetBufferLists(pFilter->FilterHandle, fNetBufferLists,
SendFlags);

First, this needs to be NdisFSendNetBufferListsComplete (note the F in the name – that’s important too).

Second, you cannot just blindly pass SendFlags to a SendComplete function. SendComplete flags are different from SendFlags. The correct code would resemble:

if ( fNetBufferLists != NULL ){
ULONG SendCompleteFlags = 0;
if ( SendFlags & NDIS_SEND_FLAGS_DISPATCH_LEVEL )
SendCompleteFlags |= NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL;
NdisFSendNetBufferListsComplete(pFilter->FilterHandle, fNetBufferLists, SendCompleteFlags);
}

The NDIS jargon for the four parts of the datapath are: Send->SendComplete; Receive->Return. (There’s also a Cancel in there, but you can usually ignore it).

Finally, I’d be remiss if I didn’t insert an advertisement for WFP. If you’re just scanning UDP/TCP ports or similar, the WFP framework will help you do a lot of the heavy lifting. As a bonus, it also automatically solves all the corner cases (like navigating IPv6 extension headers, peeling back tunneled traffic headers, and peeking into IPsec-encrypted payloads).

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of tongjinam@qq.com
Sent: Monday, August 08, 2011 11:37 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Ndislwf: drop some packets but error

Hello everyone!

I am writting ndis lw filter which is supposed to filter packets and drop those with specified port or content.
I searched some archives, and then write in the FilterSendNetBufferLists function as follow:

PNET_BUFFER_LIST fNetBufferLists = NULL; //queue the NBL which would be freed
PNET_BUFFER_LIST fNetBufferListstmp = NULL;
PNET_BUFFER_LIST sNetBufferLists = NULL; // queue the NBL which would be sended
PNET_BUFFER_LIST sNetBufferListstmp = NULL;
USHORT flag;
do
{
CurrNbl = NetBufferLists;
while (CurrNbl)
{
NextNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
for(pCurrentNetBuffer = NET_BUFFER_LIST_FIRST_NB(CurrNbl);
pCurrentNetBuffer != NULL;
pCurrentNetBuffer = NET_BUFFER_NEXT_NB(pCurrentNetBuffer))
{

NdisGetDataBuffer(pCurrentNetBuffer,scanlength,pPakData,1,0)
if( (flag = search(pPakData, scanlength)) == STREAM_POLICY_DENY )
goto ExitNBFilter;

}
ExitNBFilter:
if( flag & STREAM_POLICY_DENY){
if( fNetBufferListstmp != NULL ){
NET_BUFFER_LIST_NEXT_NBL(fNetBufferListstmp) = CurrNbl;
fNetBufferListstmp = CurrNbl;
NET_BUFFER_LIST_NEXT_NBL(fNetBufferListstmp) = NULL;
}
else
{
fNetBufferLists = CurrNbl;
fNetBufferListstmp = CurrNbl;
NET_BUFFER_LIST_NEXT_NBL(fNetBufferListstmp) = NULL;
}
}
else
{
if( sNetBufferListstmp != NULL ){
NET_BUFFER_LIST_NEXT_NBL(sNetBufferListstmp) = CurrNbl;
sNetBufferListstmp = CurrNbl;
NET_BUFFER_LIST_NEXT_NBL(sNetBufferListstmp) = NULL;
}
else
{
sNetBufferLists = CurrNbl;
sNetBufferListstmp = CurrNbl;
NET_BUFFER_LIST_NEXT_NBL(sNetBufferListstmp) = NULL;
}

}
CurrNbl= NextNbl;
}
if(fNetBufferLists != NULL)
NdisReturnNetBufferLists(pFilter->FilterHandle, fNetBufferLists, SendFlags);
if(sNetBufferLists != NULL)
NdisFSendNetBufferLists(pFilter->FilterHandle, sNetBufferLists, PortNumber, SendFlags); }while (bFalse);

Then i test the dirver, and the bulescreen happened, the info in windbg is like this:

STACK_COMMAND: kb

FOLLOWUP_IP:
ndislwf!FilterSendNetBufferLists+775 [z:\coding\app_ndis\filter.c @ 1465]
8dfe12e5 8b4d14 mov ecx,dword ptr [ebp+14h]

FAULTING_SOURCE_CODE:
1464: NdisReturnNetBufferLists(pFilter->FilterHandle, fNetBufferLists, SendFlags);

1465: NdisFSendNetBufferLists(pFilter->FilterHandle, sNetBufferLists, PortNumber, SendFlags);
1466:
1467: }
1468: while (bFalse);

There are error codes, but i can’t find why.
I am newbie, Thanks a lot for your time!


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Jeffrey is a much better man than I am. I was too confused by the OPs packet
queuing scheme that I wrote a quick note about this one aspect of his code:

http://ndis.com/ndis-ndis6/packetsort/packetsort.htm

Perhaps it will be of help to someone down the road…

I’d like to suggest to the OP that he use WinDbg. Saying “I gotta BSOD…”
is rarely a sign that the poster is serious about driver development.

Thomas F. Divine


From: “Jeffrey Tippet”
Sent: Tuesday, August 09, 2011 7:04 PM
To: “Windows System Software Devs Interest List”
Subject: RE: [ntdev] Ndislwf: drop some packets but error

> You have two bugs, both on the same line of code:
>
> NdisReturnNetBufferLists(pFilter->FilterHandle, fNetBufferLists,
> SendFlags);
>
> First, this needs to be NdisFSendNetBufferListsComplete (note the F in the
> name – that’s important too).
>
> Second, you cannot just blindly pass SendFlags to a SendComplete function.
> SendComplete flags are different from SendFlags. The correct code would
> resemble:
>
> if ( fNetBufferLists != NULL ){
> ULONG SendCompleteFlags = 0;
> if ( SendFlags & NDIS_SEND_FLAGS_DISPATCH_LEVEL )
> SendCompleteFlags |= NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL;
> NdisFSendNetBufferListsComplete(pFilter->FilterHandle, fNetBufferLists,
> SendCompleteFlags);
> }
>
> The NDIS jargon for the four parts of the datapath are:
> Send->SendComplete; Receive->Return. (There’s also a Cancel in there, but
> you can usually ignore it).
>
> Finally, I’d be remiss if I didn’t insert an advertisement for WFP. If
> you’re just scanning UDP/TCP ports or similar, the WFP framework will help
> you do a lot of the heavy lifting. As a bonus, it also automatically
> solves all the corner cases (like navigating IPv6 extension headers,
> peeling back tunneled traffic headers, and peeking into IPsec-encrypted
> payloads).
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of tongjinam@qq.com
> Sent: Monday, August 08, 2011 11:37 PM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] Ndislwf: drop some packets but error
>
> Hello everyone!
>
> I am writting ndis lw filter which is supposed to filter packets and drop
> those with specified port or content.
> I searched some archives, and then write in the FilterSendNetBufferLists
> function as follow:
>
> PNET_BUFFER_LIST fNetBufferLists = NULL; //queue the NBL which
> would be freed
> PNET_BUFFER_LIST fNetBufferListstmp = NULL;
> PNET_BUFFER_LIST sNetBufferLists = NULL; // queue the NBL which
> would be sended
> PNET_BUFFER_LIST sNetBufferListstmp = NULL;
> USHORT flag;
> do
> {
> CurrNbl = NetBufferLists;
> while (CurrNbl)
> {
> NextNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
> for(pCurrentNetBuffer = NET_BUFFER_LIST_FIRST_NB(CurrNbl);
> pCurrentNetBuffer != NULL;
> pCurrentNetBuffer = NET_BUFFER_NEXT_NB(pCurrentNetBuffer))
> {
> …
> NdisGetDataBuffer(pCurrentNetBuffer,scanlength,pPakData,1,0)
> if( (flag = search(pPakData, scanlength)) == STREAM_POLICY_DENY )
> goto ExitNBFilter;
> …
> }
> ExitNBFilter:
> if( flag & STREAM_POLICY_DENY){
> if( fNetBufferListstmp != NULL ){
> NET_BUFFER_LIST_NEXT_NBL(fNetBufferListstmp) = CurrNbl;
> fNetBufferListstmp = CurrNbl;
> NET_BUFFER_LIST_NEXT_NBL(fNetBufferListstmp) = NULL;
> }
> else
> {
> fNetBufferLists = CurrNbl;
> fNetBufferListstmp = CurrNbl;
> NET_BUFFER_LIST_NEXT_NBL(fNetBufferListstmp) = NULL;
> }
> }
> else
> {
> if( sNetBufferListstmp != NULL ){
> NET_BUFFER_LIST_NEXT_NBL(sNetBufferListstmp) = CurrNbl;
> sNetBufferListstmp = CurrNbl;
> NET_BUFFER_LIST_NEXT_NBL(sNetBufferListstmp) = NULL;
> }
> else
> {
> sNetBufferLists = CurrNbl;
> sNetBufferListstmp = CurrNbl;
> NET_BUFFER_LIST_NEXT_NBL(sNetBufferListstmp) = NULL;
> }
>
> }
> CurrNbl= NextNbl;
> }
> if(fNetBufferLists != NULL)
> NdisReturnNetBufferLists(pFilter->FilterHandle, fNetBufferLists,
> SendFlags);
> if(sNetBufferLists != NULL)
> NdisFSendNetBufferLists(pFilter->FilterHandle, sNetBufferLists,
> PortNumber, SendFlags); }while (bFalse);
>
> Then i test the dirver, and the bulescreen happened, the info in windbg is
> like this:
>
> STACK_COMMAND: kb
>
> FOLLOWUP_IP:
> ndislwf!FilterSendNetBufferLists+775 [z:\coding\app_ndis\filter.c @ 1465]
> 8dfe12e5 8b4d14 mov ecx,dword ptr [ebp+14h]
>
> FAULTING_SOURCE_CODE:
> 1464: NdisReturnNetBufferLists(pFilter->FilterHandle, fNetBufferLists,
> SendFlags);
>> 1465: NdisFSendNetBufferLists(pFilter->FilterHandle, sNetBufferLists,
>> PortNumber, SendFlags);
> 1466:
> 1467: }
> 1468: while (bFalse);
>
> There are error codes, but i can’t find why.
> I am newbie, Thanks a lot for your time!
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
>
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Ah, I give away a fish, while Thomas is here teaching how to fish. Yes, I encourage the OP to read the article below, and adopt its technique. It will make code more readable. And when you ask for help, you’ll get it faster, because we won’t have to pick through the linked-list manipulation code. :slight_smile:

Internally NDIS uses an almost identical set of macros, but we don’t expose any API for that in NDIS.H. Maybe we should…

In defense of the OP, there was some windbg info at the bottom of the original post.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Thomas F. Divine
Sent: Tuesday, August 09, 2011 4:32 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Ndislwf: drop some packets but error

Jeffrey is a much better man than I am. I was too confused by the OPs packet queuing scheme that I wrote a quick note about this one aspect of his code:

http://ndis.com/ndis-ndis6/packetsort/packetsort.htm

Perhaps it will be of help to someone down the road…

I’d like to suggest to the OP that he use WinDbg. Saying “I gotta BSOD…”
is rarely a sign that the poster is serious about driver development.

Thomas F. Divine

Thank you, Jeffrey and Thomas. Your suggestions are very helpful!