2
votes

I am currently trying to send my own packets with a NDIS filter driver from the windows driver samples.

I think that I have to send the packets with the function FilterSendNetBufferLists. But I don't know how to create those packets and whether I should add them to the existing NetBufferList or create my own one.

Do I also need to modify the function FilterSendNetBufferListsComplete?

1

1 Answers

2
votes
  1. When your driver starts (DriverEntry), or when your filter attaches to a miniport (FilterAttach), allocate a NET_BUFFER_LIST (NBL) pool with NdisAllocateNetBufferListPool. For typical usage, you'll want to get one NET_BUFFER (NB) automatically with each NBL, so set fAllocateNetBuffer=TRUE. If you want NDIS to allocate the data payload buffers for you, also give a non-zero DataSize. If you already have the packet payload in some other buffer, you can transmit faster by pointing the NB at the existing MDL, but this is also more complex to code up.
  2. To send a packet, allocate a new NBL from NdisAllocateNetBufferAndNetBufferList. Put your FilterModuleHandle into NBL->SourceHandle. Assign NB->DataLength and copy in the data. Call NdisFSendNetBufferLists on your new NBL. Do not touch the NBL until it's returned back to you.
  3. Eventually, NDIS will return the NBL back to you via FilterSendNetBufferListsComplete. Note that all NBLs come through there in one jumbled linked list -- both your own NBLs, as well as any NBLs you just passed through from above. So you have to slice the linked list based on NBL->SourceHandle: if the SourceHandle is yours, take the NBL out of the stream and free it via NdisFreeNetBufferList. Otherwise, if the NBL is not yours, continue propagating it along by calling NdisFSendNetBufferListsComplete.
  4. Do not allow FilterPause to complete until all the NBLs you originated have been returned to you. You can do this any way you want, but the usual approach is to add some refcounting to the send and sendcomplete paths. You are not required to worry about any NBLs that you didn't create.

When you're creating NBLs, you can use !ndiskd.nbl to double-check your work. It can detect a variety of errors. There's a likely problem with the NBL if ndiskd reports any field in red text.