-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
170 lines (151 loc) · 6.68 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
---
layout: default
---
<div class="posts">
<h1>What is libwifi?</h1>
<div class="entry">
<a href="https://github.com/libwifi/libwifi" target="_blank">libwifi</a> is a fast, simple C shared library with a
<a href="https://www.apache.org/licenses/LICENSE-2.0" target="_blank">permissive license</a> for generating and parsing a wide variety of <a href="https://en.wikipedia.org/wiki/IEEE_802.11#Layer_2_%E2%80%93_Datagrams" target="_blank">802.11 wireless frames</a> on Linux and macOS with a few lines of straight forward code.
<br/><br/>
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.
<br/><br/>
Other goals of the library include cross-architecture support, clean compilation without warnings and strict error checking.
</div>
<h1>How do I use it?</h1>
<div class="entry">
libwifi exposes functions and structs to make parsing and generating WiFi frames very easy, and examples can be found in the source <a href="https://github.com/libwifi/libwifi/tree/main/examples" target="_blank">examples</a> directory.
<br/><br/>
When using libwifi, be sure to pass <code>-lwifi</code> to the linker, and make sure that the libwifi shared library is installed on the system.
<br/>
<h2>Parsing</h2>
The generic flow of a program using libwifi to parse frames is a loop that reads captured packets as raw data, such as with <a href="https://github.com/the-tcpdump-group/libpcap" target="_blank">libpcap</a> from a file or monitor interface, then parse the frame into a common datatype, then parse again to retrieve frame specific data.
<br/>
<div class="code"><code><pre>
static int got_radiotap = 0;
int main(int argc, const char *argv[]) {
pcap_t handle = {0};
char errbuf[PCAP_ERRBUF_SIZE] = {0};
if ((handle = pcap_create(argv[2], errbuf)) == NULL) {
exit(EXIT_FAILURE);
}
if (pcap_activate(handle) != 0) {
pcap_close(handle);
exit(EXIT_FAILURE);
}
int linktype = pcap_datalink(handle);
if (linktype == DLT_IEEE802_11_RADIO) {
got_radiotap = 1;
} else if (linktype == DLT_IEEE802_11) {
got_radiotap = 0;
} else {
pcap_close(handle);
exit(EXIT_FAILURE);
}
pd = pcap_dump_open(handle, PCAP_SAVEFILE);
pcap_loop(handle, -1 /*INFINITY*/, &parse_packet, (unsigned char *) pd);
}
</pre></code></div>
The data from the libpcap loop is then given to <code>libwifi_get_frame()</code> which checks for frame validity and type/subtype, and stores the data in a <code>struct libwifi_frame</code>.
<br/>
<div class="code"><code><pre>
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 = {0};
int ret = libwifi_get_wifi_frame(&frame, data, data_len, got_radiotap);
if (ret != 0) {
printf("[!] Error getting libwifi_frame: %d\n", ret);
return;
}
</pre></code></div>
The <code>libwifi_frame</code> struct can then be given to one of the frame parser functions, such as <code>libwifi_parse_beacon()</code>. Since the header comment for
<code>libwifi_parse_beacon()</code> indicates that the parsed data is stored in a <code>struct libwifi_bss</code>, we need to initalise one and pass it as a parameter.
<br/><br/>
We'll use the BSS struct to easily show the SSID and Channel from the sniffed beacon frame.
<br/>
<div class="code"><code><pre>
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);
}
}
</pre></code></div>
<h2>Generation</h2>
For frame generation, you only need to provide the required data to one of the frame generation functions. In this example, <code>libwifi_create_beacon()</code>.
<div class="code"><code><pre>
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;
}
</pre></code></div>
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 <code>pcap_dump()</code> or transmitting from a monitor mode interface.
<div class="code"><code><pre>
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);
}
</pre></code></div>
</div>
</div>
<h1>How do I build it?</h1>
<div class="entry">
The build system is implemented with <a href="https://cmake.org/" target="_blank">CMake</a>. To build it, clone the repository
and run the following commands.
<br/>
<div class="code"><code><pre>
$ mkdir build && cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Release
$ make -j8
$ sudo make install
</pre></code></div>
</div>
<h1>How fast is it?</h1>
<div class="entry">
There is a simple benchmark for measuring basic Beacon parsing performance in the
<a href="https://github.com/libwifi/libwifi/tree/main/benchmark" target="_blank">benchmark</a> directory. Here are the results
when ran on an i7-1185G7 at 3.00GHz.
<br/>
<div class="code"><code><pre>
$ ./benchmark_beacon
Run 1: 0.0000190 Seconds
Run 2: 0.0000030 Seconds
Run 3: 0.0000020 Seconds
Run 4: 0.0000010 Seconds
Run 5: 0.0000010 Seconds
Run 6: 0.0000010 Seconds
Run 7: 0.0000020 Seconds
Run 8: 0.0000020 Seconds
Run 9: 0.0000020 Seconds
Run 10: 0.0000010 Seconds
Run 11: 0.0000010 Seconds
Run 12: 0.0000010 Seconds
</pre></code></div>
</div>
<h1>Where are the docs?</h1>
<div class="entry">
The source code for libwifi is fully documented with code comments, including diagrams for structs
and frame layouts where necessary. You can also view the generated docs <a href="https://libwifi.so/docs" target="_blank">here</a>.
</div>