How to prepend headers to a NetBuffer in NDIS 6? - ndis

We are upgrading our NDIS 5.1 Intermediate Miniport driver to NDIS 6.
We need to prepend some header information to a packet that is goind to be sent. In 5.1 we used NdisChainBufferAtFront().
We already did the entire kitchen to traverse and clone the entire NetBufferLists structure, we are down to preparing each cloned NetBuffer.
What is the correct way to prepend (means, at front!) a 22-byte header to a packet (NetBuffer) that is going to be sent? (We would prefer a method that avoids copying original MDL data)

You can use NdisRetreatNetBufferDataStart to add bytes for header information.
read this link till remarks to know how its done. It will surely help:
http://msdn.microsoft.com/en-in/library/windows/hardware/ff564527%28v=vs.85%29.aspx
ps: you dont at all need to copy mdl

Related

Proper way to absorb and reinject a MAC_FRAME_ETHERNET in WFP?

I want to write a WFP driver that works on the inbound/outbound MAC_FRAME_ETHERNET WFP layer in order to capture the entire packet (That is why I chose MAC_FRAME instead of IPPACKET). Therefore i have a thread that receives these absorbed MAC_FRAMES and reinjects those that are OK and not malicious.
My question is, what are the proper steps that i need to do this?
Currently I'm doing it this way:
ClassifyFn:
// I DO NOT use FwpsReferenceNetBufferList( nbl )
FwpsAllocateCloneNetBufferList( nbl, cloneNbl ) // I retreat before clone with the size of ETH header in case of inbound and advance it afterward, otherwise no retreat.
// Absorb
classifyOut->actionType = FWP_ACTION_BLOCK
classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE
Thread:
FwpsInjectMacSendAsync( cloneNbl ) // if the packet was OK
FwpsInjectMacReceiveAsync( cloneNbl ) // if the packet was OK
InjectCompletion:
FwpsFreeCloneNetBufferList
So these are my questions:
Am i doing it correctly? Is there anything i can do to improve and make it more stable?
Do i need to reference the original NBL and deref it in the injection completion?
What is the difference between using FwpsAllocateNetBufferAndNetBufferList0 vs FwpsAllocateCloneNetBufferList in this scenario?
Can i safely access the cloned NBL forever without referencing the original NBL?
Note that i do not Modify the packets at all, either i drop it or allow it.
I'm asking this because there seems to be some pool corruption somewhere that is causing random BSODs, and I'm not sure if its related to me doing something wrong or not?

Why does NdisFSendNetBufferLists only work when called from FilterSendNetBufferLists?

I have got an NDIS Filter Driver (see https://pastebin.com/c5r87NNw) and a userspace application.
I want to send an arbitrary packet with my filter driver (in the function SendData). I can see with a DbgPrint in the function FilterReceiveNetBufferLists that I have received the packet but I can not find the packet in WireShark.
As long as the code from SendData was called or directly pasted in the FilterSendNetBufferLists-function, it worked just fine. But now, as the execution of SendData is triggered by the userspace application, it doesn't work anymore.
Do you have any guess why that might be?
Wireshark is an interesting thing, because it isn't necessarily telling you the exact truth. If possible, I suggest running Wireshark on another PC, which will give you a cleaner perspective on what actually got put onto the wire. (For the purest perspective: disable the other PC's hardware offloads, especially RSC, so the other PC's NIC isn't munging the packets before you can capture them.)
Older versions of Wireshark have an NDIS5 protocol driver named NPF. This guy sits above all the filter drivers, so he wouldn't ordinarily see any of the Tx traffic. But as a special concession to this situation, NDIS will loop back the Tx path back onto the Rx path (with the NDIS_NBL_FLAGS_IS_LOOPBACK_PACKET flag set), so old drivers like NPF can see a copy of the Tx packet in their Rx path.
Recently, the npcap project converted the old NPF driver to an NDIS6 LWF named NPCAP. This driver is much better, for a number of reasons, but one thing to keep in mind is that, as a filter driver, it sits somewhere in the filter stack. If it sits above your LWF, then it won't see any packets you transmit (or modify).
Check with !ndiskd.miniport to see what wireshark looks like on your machine: is it a protocol named NPF, or is there a filter driver named NPCAP. If the latter, is it above or below your filter driver?
Anyway, all that is to say that you can't completely trust wireshark on the same box as the drivers you're testing. It's better and easier to do packet capture on a separate machine.
As for your code, make sure that your FilterSendNetBufferListsComplete handler is looking though all the NBLs and removing ones whose NET_BUFFER_LIST::SourceHandle is equal to your OriginalNdisFilterHandle. Those should be freed back to NdisFreeNetBufferList (or cached for later reuse, but NDIS does a decent job of caching already). You may already have that code, and it just didn't make it onto pastebin.
I don't see anything that would cause the Tx to always fail. You do need to track the pause state of the filter, and prevent (or queue) Tx operations while paused. So your SendData function could be written like this:
NTSTATUS SendData(MY_FILTER *filter) {
if (!ExAcquireRundownProtection(&filter->PauseRundown)) {
return STATUS_NDIS_PAUSED;
}
. . . allocate and send NBL . . .;
return STATUS_SUCCESS;
}
void FilterSendNetBufferListsComplete(MY_FILTER *filter, NET_BUFFER_LIST *nblChain) {
for (auto nbl = nblChain; nbl; nbl = nbl->Next) {
if (nbl->SourceHandle == filter->NdisHandle) {
. . . detach NBL from chain . . .;
. . . free NBL back to NDIS . . .;
ExReleaseRundownProtection(&filter->PauseRundown);
}
}
}
void FilterPause(MY_FILTER *filter) {
ExWaitForRundownProtectionRelease(&filter->PauseRundown);
}
void FilterRestart(MY_FILTER *filter) {
ExReInitializeRundownProtection(&filter->PauseRundown);
}
If you get that wrong, then sometimes NDIS will crash when you send a packet. Some packets will also quietly fail to transmit, if you are unlucky enough to send them while the datapath is paused. (Fixing this won't magically cause packets to always succeed to transmit -- it'll just mean that it won't be quiet anymore: you'll see STATUS_NDIS_PAUSED when trying to send a packet when the NIC isn't ready yet.)
I made it work: The error was in my OriginalNdisFilterHandle. I set it in the function FilterAttach and didn't think that the function gets called multiple times. Because of this the variable had the wrong value.

Jump to App from custom bootloader in TMS320 digital media processor

I am working on a boot loader for TMS320DM6437. The idea is to create 2 independent firmware that one will update another. In firmware1 I will download firmware2 file and write it to NOR flash in a specified address. Both firmware are stored in NOR flash in ais format. Now I have two applications in flash. One is my custom boot loader and the second one is my main project. I want to know how I can jump from the first program to the second program located at a specified address. I also expect information about documents which may help me to create custom bootloader
Any recommendations?
You can jump to the entry point. I'm using this approach on TMS320 2802x and 2803x, but it should be the same.
The symbol of the entry point is c_int00.
To get to know the address of c_int00 in the second application, you have to fix the Run-Time Support (RTS) library at a specific address, by modifying the linker command file.
Otherwise you can leave the RTS unconstrained, and create a C variable (at a fixed address) that is initialized with the value of cint_00. Using this method your memory map is more flexible and you can add, togheter with the C variable, a comprehensive data structure with other information for your bootloader, e.g. CRC, version number, etc.
Be carefull with the (re)initialization of the peripherals in the second application, since you are not starting from a hardware reset, and you may need to explicity reset some more registers, or clear interrupt requests.

Malformed radiotap header in wireshark

I have set up an experiment to measure Wireless communication parameters using two laptops. I am injecting custom packets into the network on a monitor interface using one laptop programmed as a transmitter(Macbook Pro using Broadcom BCM 4331 interface card) and another laptop ( Dell Latitude E6410 using the Intel Corporation Centrino Ultimate-N 6300 interface card) programmed as a receiver sniffs the network for the custom injected packets and reports parameters such as Received signal strength, propagation delay etc... The transmission is working fine and i am able to get the injected packets on the receiving side.
However , When i use Wireshark to analyze the incoming packets using the monitor interface created using airmon-ng, the radio tap header seems to be malformed. This is the same for all packets .
Also why is the Noise parameter now shown in the radio tap details?
Could anyone help me out with this?
The header might well be malformed, due to, for example, a driver bug. (I.e., a bug in the Linux driver for the Centrino adapter on your laptop.)
Unfortunately, Wireshark didn't put in any indication of what was malformed, so it's hard to diagnose this problem.
I just checked into the Wireshark trunk a change to add expert info for malformed radiotap headers; if you could try building the current SVN trunk head and see what it reports, that might indicate what's wrong with the header.
What's wrong is probably that the length field in the radiotap header is wrong.
If when you said "Also why is the Noise parameter now shown in the radio tap details?" you meant "Also why is the Noise parameter not shown in the radio tap details?", the length field being too short would explain that - the presence bitmap says that the noise parameter is present, but the header field specifies a length not large enough to include the noise parameter, so when Wireshark tries to fetch that field, it discovers that it's run past the end of the radiotap header, and reports a problem.
In addition, that would also explain why the 802.2 LLC header on several of those frames look bogus - if Wiretap skips past the length specified in the radiotap header to find the 802.11 header, and that puts it in the middle of, for example, the Noise parameter, and it tries to dissect that as if it were an 802.11 header, and tries to dissect what's after the 802.11 header as an 802.2 header, both of them could be bogus.

How to modify struct sk_buff

I have to write a vpn module. First of all, I have wrote a kernel module that modifies all the incoming and outgoing TCP packets. It uses netfilter hooks. For the incoming packets, I have modified the bytes between (struct sk_buff)->data and (struct sk_buff)->tail pointers by incrementing them by one. For the outgoing packets, I have modified the bytes between (struct sk_buff)->data and (struct sk_buff)->tail pointers by decrementing them by one.
However, I tried to establish a TCP connection between localhost and localhost (by means of netcat) and I had not succeeded. Can you tell me what I am doing wrong? Need I modify some other fields from the struct sk_buff structure?
Is it possible to implement my simple vpn module only from kernel space?(thus without using special libraies such as libnetfilter_queue)?
Thank you.
Yes, you can do this without using libnetfilter. But given the limited information that you've provided about your project it's hard to give a good recommendation as to how to go about fixing your issue. Here's some references that should help.
1) I would recommend you take a look at the TUN/TAP interface driver APIs. This will allow you to implement your code in application space rather than kernel. See openvpn for a great example of this type of VPN.
If you're interested in doing more advanced kernel space hooking...
2) Check this article out on hooking into netfilter netfilter kernel hooks

Resources