3

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?

Gigliotti
  • 73
  • 6

1 Answers1

5
  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.

Jeffrey Tippet
  • 3,146
  • 1
  • 14
  • 15
  • I have allocated a NBL-Pool in the function `FilterAttach` (see https://pastebin.com/MJCVHYwv) `MyFilterHandle` is a global variable of type NDIS_HANDLE (so I have later access to it). **1.** Now I have to modify the function `FilterSendNetBufferLists`. You said that therefore I have to use the function `NdisAllocateNetBufferAndNetBufferList`. I am not sure about the parameters to put in there. The first parameter is the NDIS_HANDLE that I have saved in the global variable `MyFilterHandle`. But what about the MdlChain of type `PMDL`? I yet do not have a MdlChain. *How do I create one?* – Gigliotti Jul 29 '20 at 13:34
  • **2.** Why do I need to set the NDIS_HANDLE twice? I have already passed `MyFilterHandle` into the function `NdisAllocateNetBufferAndNetBufferList`. Why do I need to set the SourceHandle of the returned NBL? – Gigliotti Jul 29 '20 at 13:34
  • 1
    2. The apparent redundancy is to support more advanced tricks, like allocating NBLs for one miniport stack, but redirecting them to another miniport. – Jeffrey Tippet Jul 31 '20 at 03:09
  • 1
    1. If you give a nonzero DataSize to NANBLP, you'll get MDLs for free, so you don't need to give one to NANBANBL. And then last arg will be 0. – Jeffrey Tippet Jul 31 '20 at 03:15
  • Thank you for your answer. I have tried to follow your instructions, but unfortunately I still have problems in my code (https://pastebin.com/f4RJeyj2). Currently a BlueScreen appears during the installation of the driver. Can you help me with this? I wanted to test sending empty packages as you can see in the code. Is this a problem? Do the packages have to have a content? – Gigliotti Aug 02 '20 at 17:11
  • *Update:* I found out that `MyFilterHandle` was NULL although I had set it in the `FilterAttach` function. I have fixed this error. But unfortunately sending still doesn't work and I end up in a BlueScreen (KERNEL_SECURITY_CHECK_FAILURE). – Gigliotti Aug 03 '20 at 20:02
  • You'll need to start getting comfortable with a kernel debugger - this won't be the last bluescreen you get. It's not technically legal to send a 0-byte NBL over Ethernet; the NIC needs at least an Ethernet header, and Ethernet requires 64 bytes minimum. At best, the NIC is ignoring your packets, at worst, it's crashing. One definite crash is because you're calling NdisFSendNetBufferListsComplete on `NetBufferLists`, which might have been diverted & freed already. – Jeffrey Tippet Aug 04 '20 at 16:32