🚀 Discover this insightful post from Hacker News 📖
📂 Category:
✅ Here’s what you’ll learn:
permissive license for generating and parsing a wide variety of 802.11 wireless frames on Linux and macOS with a few lines of straight forward code.
It is written with a simple-to-use approach while also exposing features that allow more advanced use, with clean and readable code being a priority.
Other goals of the library include cross-architecture support, clean compilation without warnings and strict error checking.
When using libwifi, be sure to pass -lwifi to the linker, and make sure that the libwifi shared library is installed on the system.
Parsing
The generic flow of a program using libwifi to parse frames is a loop that reads captured packets as raw data, such as with libpcap from a file or monitor interface, then parse the frame into a common datatype, then parse again to retrieve frame specific data.
static int got_radiotap = 0;
int main(int argc, const char *argv[]) {
pcap_t handle = 💬;
char errbuf[PCAP_ERRBUF_SIZE] = What do you think?;
if ((handle = pcap_create(argv[2], errbuf)) == NULL) ⚡
if (pcap_activate(handle) != 0) Tell us your thoughts in comments!
int linktype = pcap_datalink(handle);
if (linktype == DLT_IEEE802_11_RADIO) ⚡ else if (linktype == DLT_IEEE802_11) What do you think? else 🔥
pd = pcap_dump_open(handle, PCAP_SAVEFILE);
pcap_loop(handle, -1 /*INFINITY*/, &parse_packet, (unsigned char *) pd);
}
The data from the libpcap loop is then given to libwifi_get_frame() which checks for frame validity and type/subtype, and stores the data in a struct libwifi_frame.
void parse_packet(unsigned char *args,
const struct pcap_pkthdr *header,
const unsigned char *packet) {
unsigned long data_len = header->caplen;
unsigned char *data = (unsigned char *) packet;
struct libwifi_frame frame = Share your opinion below!;
int ret = libwifi_get_wifi_frame(&frame, data, data_len, got_radiotap);
if (ret != 0) {
printf("[!] Error getting libwifi_frame: %d\n", ret);
return;
}
The libwifi_frame struct can then be given to one of the frame parser functions, such as libwifi_parse_beacon(). Since the header comment for
libwifi_parse_beacon() indicates that the parsed data is stored in a struct libwifi_bss, we need to initalise one and pass it as a parameter.
We’ll use the BSS struct to easily show the SSID and Channel from the sniffed beacon frame.
if (frame.frame_control.type == TYPE_MANAGEMENT &&
frame.frame_control.subtype == SUBTYPE_BEACON) {
struct libwifi_bss bss = {0};
int ret = libwifi_parse_beacon(&bss, &frame);
if (ret != 0) {
printf("Failed to parse beacon: %d\n", ret);
return;
}
printf("SSID: %s, Channel: %d\n", bss.ssid, bss.channel);
}
}
Generation
For frame generation, you only need to provide the required data to one of the frame generation functions. In this example, libwifi_create_beacon().
int main(int argc, char **argv) {
struct libwifi_beacon beacon = {0};
static unsigned char bcast[] = "\xFF\xFF\xFF\xFF\xFF\xFF";
static unsigned char tx[] = "\x00\x20\x91\xAA\xBB\CC";
int ret = libwifi_create_beacon(&beacon, bcast, tx, tx, "wifi-beacon", 11);
if (ret != 0) {
return ret;
}
From here, we can use the dumper function for this frame subtype to write the beacon in raw byte format to a buffer. This can be useful for writing the
generated frame out to a pcap file using pcap_dump() or transmitting from a monitor mode interface.
unsigned char *buf = NULL;
size_t buf_sz = libwifi_get_beacon_length(&beacon);
buf = malloc(buf_sz);
if (buf == NULL) {
exit(EXIT_FAILURE);
}
ret = libwifi_dump_beacon(&beacon, buf, buf_sz);
if (ret < 0) {
return ret;
}
// Inject frame bytes or write bytes to file
libwifi_free_beacon(&beacon);
free(buf);
}
{💬|⚡|🔥} {What do you think?|Share your opinion below!|Tell us your thoughts in comments!}
#️⃣ #libwifi #Frame #Parsing #Generation #library #written
🕒 Posted on 1763250830
