First, there’s something you should be aware of when trying to transmit raw 802.12 frames- the device driver must support packet injection.
You mentioned monitor mode, which is at a high level the rx equivalent of the injection capability- which is not a “mode”, jist a capability/feature. I say this because some 892.11 device drivers on Linux either:
- Support monitor mode and frame injection
- Support monitor mode and not frame injection
- Support neither
I don’t know any straightforward way to check if the driver supports frame injection aside from attempting frame injection and sniffing the air on another device to confirm it was seen.
Monitor mode is usually easy to check by using sudo wlan0 set monitor
and seeing what the return code and/or output is.
It’s been a few years since I’ve worked on this but at the time, very few devices supported monitor mode and frame injection “out of the box”. Many only supported monitor mode with a modified version of the vendor or kernel driver
You’ll want to make sure your device has a driver available that fully supports both. This sort of task (frame monitoring and injection) is common for Penetration Testers who tend to use Kali Linux, which is really just an Ubuntu distribution with a bunch of “hacking” tools and (modified) 802.11 device drivers preloaded and in its repositories. You can often save time finding a well supported card by using a search engine to find the device and driver recommended for Kali users
I’m bringing this monitor/injection capability up explicitly because when I first worked on a similar project a few years ago, I needed to use a patched version of the official kernel driver to support monitor mode- it was an rtl8812au chipset. At that time, I made an incorrect assumption that monitor mode support in the driver implied full injection support. I spent 2 days banging my head against the wall, convinced my frames weren’t built correctly in my application, causing no frames to leave the card. Turned out I needed a more recent branch of the driver I was using to get the full injection support. This driver in particular supports both monitor mode and frame injection now. The most frustrating thing about diagnosing that problem was that I did not receive any errors from system calls or in kernel messages while trying to transmit the frames- they were just being silently discarded somewhere, presumably in the driver
To your main question about how to do this- the answer is almost certainly libpcap if you’re writing your application in C/C++ as libpcap provides not only packet capture APIs but also packet injection APIs
If you do it in Python, scapy is an excellent option. The benefit of Python/scapy is that
- Python code is much quicker to write than C
- scapy provides a significant amount of classes that you can use to intuitively create a frame layer by layer
- Because the layers are implemented as classes, you can also extend and “register” existing classes to make certain frames easier to create (or parse when received)
You can do this in straight C using the UNIX sockets API with raw sockets directly- but you’ll have to deal with things that libpcap exists to abstract from you- like underlying system calls that may be required when doing raw frame transmission, aside from the standard socket()
, send()
, recv()
calls. I’m speculating that there are a handful of ioctl
calls you may need at the least, specific to the kernel 802.11x subsystem/framework- and these ioctl()
calls and their values may not be completely portable across different major kernel versions. I’ll admit I ended up not using the pure C (without libpcap) approach, so I’m not 100% sure about this potential problem. It’s something you should look more into if you plan to do it without libpcap. I don’t recommend it unless you have a really good reason to