about summary refs log tree commit diff stats
path: root/examples/generate_beacon/README.md
blob: 4b7103d47d2cb47ef2748ac29e47198cb3f7881a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Generating 802.11 Beacons
This example shows the reader how to generate an 802.11 Beacon, with an SSID and Channel element. It also adds a tagged parameter with the string "libwifi-tag" inside.

# Building and Using
```
>> cd examples/generate_beacon/
>> make
clang -Wall -Werror -O3 -o generate_beacon   -c -o generate_beacon.o generate_beacon.c
clang -Wall -Werror -O3 -o generate_beacon generate_beacon.c -lpcap -lwifi
>> ./generate_beacon --file beacon.pcap
[+] Setup Complete
[*] Creating Beacon Frame
[*] Writing Beacon Frame to pcap
>> tshark -r beacon.pcap 
    1   0.000000 ca:38:6d:6d:3f:bd → Broadcast    802.11 78 Beacon frame, SN=1383, FN=0, Flags=........, BI=100, SSID=libwifi-beacon
>>
```
# Output
![image](https://user-images.githubusercontent.com/4153572/143600844-ce7dee11-46b0-40a5-a12c-881d79bd584d.png)
onstant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#include <libwifi.h>

#include <pcap.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int has_radiotap = 0;

int print_tag_info(unsigned char *tag_data, size_t tag_data_len) {
    // Initialise a libwifi_tag_iterator
    struct libwifi_tag_iterator it = {0};
    if (libwifi_tag_iterator_init(&it, tag_data, tag_data_len) != 0) {
        return -1;
    }

    do {
        printf("\tTag: %d (%s) (Size: %d)\n", it.tag_header->tag_num,
                                              libwifi_get_tag_name(it.tag_header->tag_num),
                                              it.tag_header->tag_len);

        int max_size = 16;
        if (it.tag_header->tag_len < 16) {
            max_size = it.tag_header->tag_len;
        }
        printf("\t\t%d bytes of Tag Data: ", max_size);
        for (size_t i = 0; i < max_size; i++) {
            printf("%02x ", it.tag_data[i]);
        }
        printf("\n");
    } while (libwifi_tag_iterator_next(&it) != -1);

    return 0;
}

void handle_pkt(unsigned char *args, const struct pcap_pkthdr *header, const unsigned char *packet) {
    unsigned long data_len = header->caplen;
    unsigned char *data = (unsigned char *) packet;

    // Initialise a libwifi_frame struct and populate it
    struct libwifi_frame frame = {0};
    int ret = libwifi_get_wifi_frame(&frame, data, data_len, has_radiotap);
    if (ret != 0) {
        return;
    }

    // Ensure the frame is a Beacon frame
    if (frame.frame_control.type == TYPE_MANAGEMENT && frame.frame_control.subtype == SUBTYPE_BEACON) {
        // Initalise a libwifi_bss struct and populate it with the data from the sniffed frame
        struct libwifi_bss bss = {0};
        ret = libwifi_parse_beacon(&bss, &frame);
        if (ret != 0) {
            return;
        }

        // Print basic information from the new struct
        printf("ESSID: %s\n", bss.hidden ? "(hidden)" : bss.ssid);
        printf("BSSID: " MACSTR "\n", MAC2STR(bss.bssid));
        printf("Receiver: " MACSTR "\n", MAC2STR(bss.receiver));
        printf("Transmitter: " MACSTR "\n", MAC2STR(bss.transmitter));
        printf("Channel: %d\n", bss.channel);
        printf("WPS: %s\n", bss.wps ? "Yes" : "No");

        // Initialse a char buffer of length LIBWIFI_SECURITY_BUF_LEN, and use libwifi to
        // write the security suite (WEP, WPA, etc) to it, before printing it.
        char sec_buf[LIBWIFI_SECURITY_BUF_LEN];
        libwifi_get_security_type(&bss, sec_buf);
        printf("Encryption: %s\n", sec_buf);

        // We can re-use the sec_buf buffer for other security related items, since libwifi
        // will take care of the memory for us.
        // We'll use the same buffer to get the WPA/2/3 group ciphers from the beacon, if any.
        libwifi_get_group_ciphers(&bss, sec_buf);
        printf("\tGroup Ciphers: %s\n", sec_buf);

        // ... and the same for the pairwise ciphers
        libwifi_get_pairwise_ciphers(&bss, sec_buf);
        printf("\tPairwise Ciphers: %s\n", sec_buf);

        // ... and the same for the authentication maagement key suites
        libwifi_get_auth_key_suites(&bss, sec_buf);
        printf("\tAuth Key Suites: %s\n", sec_buf);

        // Check for enabled RSN Capabilities. In this example, we will check for the
        // presence of Management Frame Protection (802.11w)
        if (bss.rsn_info.rsn_capabilities & LIBWIFI_RSN_CAPAB_MFP_CAPABLE) {
            printf("\tMFP Capable: Yes\n");
        }
        if (bss.rsn_info.rsn_capabilities & LIBWIFI_RSN_CAPAB_MFP_REQUIRED) {
            printf("\tMFP Required: Yes\n");
        }

        // If any tagged parameters are available for this frame, we can iterate through them
        // since libwifi will automatically find them.
        if (bss.tags.length) {
            printf("Tagged Parameters:\n");
            print_tag_info(bss.tags.parameters, bss.tags.length);
        } else {
            printf("Tagged Parameters: None\n");
        }

        // Cleanup the libwifi bss
        libwifi_free_bss(&bss);
    }

    printf("\n");

    // Clean up the libwifi frame
    libwifi_free_wifi_frame(&frame);
}

void helpexit() {
    fprintf(stderr, "[!] Usage: ./parse_beacon --file <file.pcap>\n");
    exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
    pcap_t *handle = NULL;
    pcap_dumper_t *dumper = NULL;
    char errbuf[PCAP_ERRBUF_SIZE];

    if (argc < 2) {
        helpexit();
    }
    if (strcmp(argv[1], "--file") == 0) {
        if ((handle = pcap_open_offline(argv[2], errbuf)) == NULL) {
            fprintf(stderr, "[!] Error opening file %s (%s)\n", argv[2], errbuf);
            exit(EXIT_FAILURE);
        }
    } else {
        helpexit();
    }

    int linktype = pcap_datalink(handle);
    if (linktype == DLT_IEEE802_11_RADIO) {
        has_radiotap = 1;
    }
    if (linktype != DLT_IEEE802_11 && linktype != DLT_IEEE802_11_RADIO) {
        fprintf(stderr, "[!] 802.11 and radiotap headers not provided (%d)\n", pcap_datalink(handle));
        pcap_close(handle);
        exit(EXIT_FAILURE);
    }

    printf("[+] Setup Complete\n");

    dumper = pcap_dump_open(handle, "/tmp/parse_beacon.pcap");
    pcap_loop(handle, -1 /*INFINITY*/, &handle_pkt, (unsigned char *) dumper);

    pcap_dump_close(dumper);
    pcap_close(handle);
    return 0;
}