diff options
-rw-r--r-- | src/libwifi/core/frame/frame.c | 8 | ||||
-rw-r--r-- | src/libwifi/core/frame/frame.h | 3 | ||||
-rw-r--r-- | src/libwifi/core/misc/radiotap.h | 11 | ||||
-rw-r--r-- | src/libwifi/parse/misc/radiotap.c | 17 | ||||
-rw-r--r-- | utils/src/test_parsing.c | 84 |
5 files changed, 67 insertions, 56 deletions
diff --git a/src/libwifi/core/frame/frame.c b/src/libwifi/core/frame/frame.c index c8b6816..99f7fdc 100644 --- a/src/libwifi/core/frame/frame.c +++ b/src/libwifi/core/frame/frame.c | |||
@@ -32,8 +32,7 @@ | |||
32 | * - QoS Data Frames | 32 | * - QoS Data Frames |
33 | * - Control Frames | 33 | * - Control Frames |
34 | */ | 34 | */ |
35 | int libwifi_get_wifi_frame(struct libwifi_frame *fi, const unsigned char *frame, size_t frame_len, | 35 | int libwifi_get_wifi_frame(struct libwifi_frame *fi, const unsigned char *frame, size_t frame_len, int radiotap) { |
36 | int radiotap) { | ||
37 | union libwifi_frame_header fh = {0}; | 36 | union libwifi_frame_header fh = {0}; |
38 | size_t header_len = 0; | 37 | size_t header_len = 0; |
39 | size_t frame_data_len = frame_len; | 38 | size_t frame_data_len = frame_len; |
@@ -55,6 +54,10 @@ int libwifi_get_wifi_frame(struct libwifi_frame *fi, const unsigned char *frame, | |||
55 | fi->flags |= LIBWIFI_FLAGS_FCS_PRESENT; | 54 | fi->flags |= LIBWIFI_FLAGS_FCS_PRESENT; |
56 | frame_data_len -= sizeof(uint32_t); // FCS is 4 bytes wide | 55 | frame_data_len -= sizeof(uint32_t); // FCS is 4 bytes wide |
57 | } | 56 | } |
57 | |||
58 | fi->flags |= LIBWIFI_FLAGS_RADIOTAP_PRESENT; | ||
59 | fi->radiotap_info = malloc(sizeof(struct libwifi_radiotap_info)); | ||
60 | memcpy(fi->radiotap_info, &rtap_info, sizeof(struct libwifi_radiotap_info)); | ||
58 | } | 61 | } |
59 | 62 | ||
60 | struct libwifi_frame_ctrl *frame_control = (struct libwifi_frame_ctrl *) frame_data; | 63 | struct libwifi_frame_ctrl *frame_control = (struct libwifi_frame_ctrl *) frame_data; |
@@ -134,5 +137,6 @@ int libwifi_get_wifi_frame(struct libwifi_frame *fi, const unsigned char *frame, | |||
134 | } | 137 | } |
135 | 138 | ||
136 | void libwifi_free_wifi_frame(struct libwifi_frame *fi) { | 139 | void libwifi_free_wifi_frame(struct libwifi_frame *fi) { |
140 | free(fi->radiotap_info); | ||
137 | free(fi->body); | 141 | free(fi->body); |
138 | } | 142 | } |
diff --git a/src/libwifi/core/frame/frame.h b/src/libwifi/core/frame/frame.h index 5d44dbe..f775479 100644 --- a/src/libwifi/core/frame/frame.h +++ b/src/libwifi/core/frame/frame.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #define LIBWIFI_CORE_FRAME_H | 17 | #define LIBWIFI_CORE_FRAME_H |
18 | 18 | ||
19 | #include "../../core/misc/byteswap.h" | 19 | #include "../../core/misc/byteswap.h" |
20 | #include "../../core/misc/radiotap.h" | ||
20 | 21 | ||
21 | #include <stdint.h> | 22 | #include <stdint.h> |
22 | #include <sys/types.h> | 23 | #include <sys/types.h> |
@@ -25,6 +26,7 @@ | |||
25 | #define LIBWIFI_FLAGS_FCS_PRESENT (1 << 0) | 26 | #define LIBWIFI_FLAGS_FCS_PRESENT (1 << 0) |
26 | #define LIBWIFI_FLAGS_IS_QOS (1 << 1) | 27 | #define LIBWIFI_FLAGS_IS_QOS (1 << 1) |
27 | #define LIBWIFI_FLAGS_IS_ORDERED (1 << 2) | 28 | #define LIBWIFI_FLAGS_IS_ORDERED (1 << 2) |
29 | #define LIBWIFI_FLAGS_RADIOTAP_PRESENT (1 << 3) | ||
28 | 30 | ||
29 | /* Defined frame types and sub-types */ | 31 | /* Defined frame types and sub-types */ |
30 | enum libwifi_frame_type { | 32 | enum libwifi_frame_type { |
@@ -306,6 +308,7 @@ union libwifi_mgmt_frame_header { | |||
306 | * frame in libwifi. | 308 | * frame in libwifi. |
307 | */ | 309 | */ |
308 | struct libwifi_frame { | 310 | struct libwifi_frame { |
311 | struct libwifi_radiotap_info *radiotap_info; | ||
309 | uint16_t flags; | 312 | uint16_t flags; |
310 | struct libwifi_frame_ctrl frame_control; | 313 | struct libwifi_frame_ctrl frame_control; |
311 | size_t len; | 314 | size_t len; |
diff --git a/src/libwifi/core/misc/radiotap.h b/src/libwifi/core/misc/radiotap.h index 85ed7b8..f6704e8 100644 --- a/src/libwifi/core/misc/radiotap.h +++ b/src/libwifi/core/misc/radiotap.h | |||
@@ -21,13 +21,22 @@ | |||
21 | #define LIBWIFI_MAX_RADIOTAP_LEN 128 | 21 | #define LIBWIFI_MAX_RADIOTAP_LEN 128 |
22 | #define LIBWIFI_MAX_RADIOTAP_ANTENNAS 16 | 22 | #define LIBWIFI_MAX_RADIOTAP_ANTENNAS 16 |
23 | 23 | ||
24 | #define LIBWIFI_RADIOTAP_BAND_2GHZ (1 << 0) | ||
25 | #define LIBWIFI_RADIOTAP_BAND_5GHZ (1 << 1) | ||
26 | #define LIBWIFI_RADIOTAP_BAND_6GHZ (1 << 2) | ||
27 | #define LIBWIFI_RADIOTAP_BAND_900MHZ (1 << 3) | ||
28 | |||
24 | /** | 29 | /** |
25 | * A channel field in radiotap consists of a 2-byte wide flags | 30 | * A channel field in radiotap consists of a 2-byte wide flags |
26 | * sub-field and a 2-byte wide frequency field | 31 | * sub-field and a 2-byte wide frequency field. |
32 | * | ||
33 | * libwifi will also calculate the band and center channel. | ||
27 | */ | 34 | */ |
28 | struct libwifi_radiotap_channel { | 35 | struct libwifi_radiotap_channel { |
29 | uint16_t flags; | 36 | uint16_t flags; |
30 | uint16_t freq; | 37 | uint16_t freq; |
38 | uint8_t center; | ||
39 | uint8_t band; | ||
31 | } __attribute__((packed)); | 40 | } __attribute__((packed)); |
32 | 41 | ||
33 | /** | 42 | /** |
diff --git a/src/libwifi/parse/misc/radiotap.c b/src/libwifi/parse/misc/radiotap.c index faf6009..9bf6b54 100644 --- a/src/libwifi/parse/misc/radiotap.c +++ b/src/libwifi/parse/misc/radiotap.c | |||
@@ -47,6 +47,23 @@ int libwifi_parse_radiotap_info(struct libwifi_radiotap_info *info, const unsign | |||
47 | case IEEE80211_RADIOTAP_CHANNEL: | 47 | case IEEE80211_RADIOTAP_CHANNEL: |
48 | info->channel.freq = le16toh(*(uint16_t *) it.this_arg); | 48 | info->channel.freq = le16toh(*(uint16_t *) it.this_arg); |
49 | info->channel.flags = le16toh(*(uint16_t *) (it.this_arg + 2)); | 49 | info->channel.flags = le16toh(*(uint16_t *) (it.this_arg + 2)); |
50 | |||
51 | // Handle band and channel | ||
52 | if (info->channel.freq >= 2412 && info->channel.freq <= 2484) { | ||
53 | info->channel.band |= LIBWIFI_RADIOTAP_BAND_2GHZ; | ||
54 | if (info->channel.freq == 2484) { | ||
55 | info->channel.center = 14; | ||
56 | } else { | ||
57 | info->channel.center = (info->channel.freq - 2407) / 5; | ||
58 | } | ||
59 | } else if (info->channel.freq >= 5160 && info->channel.freq <= 5885) { | ||
60 | info->channel.band |= LIBWIFI_RADIOTAP_BAND_5GHZ; | ||
61 | info->channel.center = (info->channel.freq - 5000) / 5; | ||
62 | } else if (info->channel.freq >= 5955 && info->channel.freq <= 7115) { | ||
63 | info->channel.band |= LIBWIFI_RADIOTAP_BAND_6GHZ; | ||
64 | info->channel.center = (info->channel.freq - 5950) / 5; | ||
65 | } | ||
66 | |||
50 | break; | 67 | break; |
51 | case IEEE80211_RADIOTAP_RATE: | 68 | case IEEE80211_RADIOTAP_RATE: |
52 | info->rate_raw = *it.this_arg; | 69 | info->rate_raw = *it.this_arg; |
diff --git a/utils/src/test_parsing.c b/utils/src/test_parsing.c index b9f9dbc..b5e2d53 100644 --- a/utils/src/test_parsing.c +++ b/utils/src/test_parsing.c | |||
@@ -132,26 +132,36 @@ void print_tag_info(unsigned char *data, size_t data_len) { | |||
132 | } while (libwifi_tag_iterator_next(&it) != -1); | 132 | } while (libwifi_tag_iterator_next(&it) != -1); |
133 | } | 133 | } |
134 | 134 | ||
135 | void parse_radiotap(const unsigned char *packet, size_t packet_len) { | 135 | void parse_radiotap(const struct libwifi_frame *frame) { |
136 | struct libwifi_radiotap_info rtap_info; | 136 | const struct libwifi_radiotap_info *rtap_info = frame->radiotap_info; |
137 | libwifi_parse_radiotap_info(&rtap_info, packet, packet_len); | ||
138 | 137 | ||
139 | printf("=== Radiotap Parsing ===\n"); | 138 | printf("=== Radiotap Parsing ===\n"); |
140 | printf("Radiotap Channel: %d\n", rtap_info.channel.freq); | 139 | printf("Radiotap Channel Freq: %d MHz\n", rtap_info->channel.freq); |
141 | printf("Radiotap Channel Flags: 0x%04x\n", rtap_info.channel.flags); | 140 | printf("Radiotap Freq Band: "); |
142 | printf("Radiotap Rate: %.2f Mb/s\n", rtap_info.rate); | 141 | if (rtap_info->channel.band & LIBWIFI_RADIOTAP_BAND_2GHZ) { |
143 | printf("Radiotap Rate Raw: 0x%02x\n", rtap_info.rate_raw); | 142 | printf("2.4 GHz\n"); |
144 | printf("Radiotap Signal: %d dBm\n", rtap_info.signal); | 143 | } else if (rtap_info->channel.band & LIBWIFI_RADIOTAP_BAND_5GHZ) { |
145 | for (int i = 0; i < rtap_info.antenna_count; i++) { | 144 | printf("5 GHz\n"); |
146 | printf("Radiotap Antenna %d: %d dBm\n", rtap_info.antennas[i].antenna_number, rtap_info.antennas[i].signal); | 145 | } else if (rtap_info->channel.band & LIBWIFI_RADIOTAP_BAND_6GHZ) { |
146 | printf("6 GHz\n"); | ||
147 | } else { | ||
148 | printf("Unknown Band\n"); | ||
149 | } | ||
150 | printf("Radiotap Channel: %d\n", rtap_info->channel.center); | ||
151 | printf("Radiotap Channel Flags: 0x%04x\n", rtap_info->channel.flags); | ||
152 | printf("Radiotap Rate: %.2f Mb/s\n", rtap_info->rate); | ||
153 | printf("Radiotap Rate Raw: 0x%02x\n", rtap_info->rate_raw); | ||
154 | printf("Radiotap Signal: %d dBm\n", rtap_info->signal); | ||
155 | for (int i = 0; i < rtap_info->antenna_count; i++) { | ||
156 | printf("Radiotap Antenna %d: %d dBm\n", rtap_info->antennas[i].antenna_number, rtap_info->antennas[i].signal); | ||
147 | } | 157 | } |
148 | printf("Radiotap Flags: 0x%04x\n", rtap_info.flags); | 158 | printf("Radiotap Flags: 0x%04x\n", rtap_info->flags); |
149 | printf("Radiotap Extended Flags: 0x%08x\n", rtap_info.extended_flags); | 159 | printf("Radiotap Extended Flags: 0x%08x\n", rtap_info->extended_flags); |
150 | printf("Radiotap RX Flags: 0x%04x\n", rtap_info.rx_flags); | 160 | printf("Radiotap RX Flags: 0x%04x\n", rtap_info->rx_flags); |
151 | printf("Radiotap TX Flags: 0x%04x\n", rtap_info.tx_flags); | 161 | printf("Radiotap TX Flags: 0x%04x\n", rtap_info->tx_flags); |
152 | printf("Radiotap TX Power: %d\n", rtap_info.tx_power); | 162 | printf("Radiotap TX Power: %d\n", rtap_info->tx_power); |
153 | printf("Radiotap RTS Retries: %d\n", rtap_info.rts_retries); | 163 | printf("Radiotap RTS Retries: %d\n", rtap_info->rts_retries); |
154 | printf("Radiotap Data Retries: %d\n", rtap_info.data_retries); | 164 | printf("Radiotap Data Retries: %d\n", rtap_info->data_retries); |
155 | printf("=== Radiotap End ===\n"); | 165 | printf("=== Radiotap End ===\n"); |
156 | } | 166 | } |
157 | 167 | ||
@@ -165,10 +175,6 @@ void parse_beacon(struct libwifi_frame frame, unsigned char *args, const struct | |||
165 | return; | 175 | return; |
166 | } | 176 | } |
167 | 177 | ||
168 | if (got_radiotap && parse_radiotap_header) { | ||
169 | parse_radiotap(packet, header->caplen); | ||
170 | } | ||
171 | |||
172 | print_bss_info(&bss); | 178 | print_bss_info(&bss); |
173 | } | 179 | } |
174 | } | 180 | } |
@@ -183,10 +189,6 @@ void parse_probe_request(struct libwifi_frame frame, unsigned char *args, const | |||
183 | return; | 189 | return; |
184 | } | 190 | } |
185 | 191 | ||
186 | if (got_radiotap && parse_radiotap_header) { | ||
187 | parse_radiotap(packet, header->caplen); | ||
188 | } | ||
189 | |||
190 | print_sta_info(&sta); | 192 | print_sta_info(&sta); |
191 | } | 193 | } |
192 | } | 194 | } |
@@ -200,10 +202,6 @@ void parse_probe_response(struct libwifi_frame frame, unsigned char *args, const | |||
200 | return; | 202 | return; |
201 | } | 203 | } |
202 | 204 | ||
203 | if (got_radiotap && parse_radiotap_header) { | ||
204 | parse_radiotap(packet, header->caplen); | ||
205 | } | ||
206 | |||
207 | print_bss_info(&bss); | 205 | print_bss_info(&bss); |
208 | } | 206 | } |
209 | } | 207 | } |
@@ -218,10 +216,6 @@ void parse_deauth(struct libwifi_frame frame, unsigned char *args, const struct | |||
218 | return; | 216 | return; |
219 | } | 217 | } |
220 | 218 | ||
221 | if (got_radiotap && parse_radiotap_header) { | ||
222 | parse_radiotap(packet, header->caplen); | ||
223 | } | ||
224 | |||
225 | printf("=== Deauthentication Frame ===\n"); | 219 | printf("=== Deauthentication Frame ===\n"); |
226 | if (deauth.ordered) { | 220 | if (deauth.ordered) { |
227 | printf("Address 1: " MACSTR "\n", MAC2STR(deauth.frame_header.ordered.addr1)); | 221 | printf("Address 1: " MACSTR "\n", MAC2STR(deauth.frame_header.ordered.addr1)); |
@@ -257,10 +251,6 @@ void parse_disassoc(struct libwifi_frame frame, unsigned char *args, const struc | |||
257 | return; | 251 | return; |
258 | } | 252 | } |
259 | 253 | ||
260 | if (got_radiotap && parse_radiotap_header) { | ||
261 | parse_radiotap(packet, header->caplen); | ||
262 | } | ||
263 | |||
264 | printf("=== Disassociation Frame ===\n"); | 254 | printf("=== Disassociation Frame ===\n"); |
265 | if (disassoc.ordered) { | 255 | if (disassoc.ordered) { |
266 | printf("Address 1: " MACSTR "\n", MAC2STR(disassoc.frame_header.ordered.addr1)); | 256 | printf("Address 1: " MACSTR "\n", MAC2STR(disassoc.frame_header.ordered.addr1)); |
@@ -295,10 +285,6 @@ void parse_assoc_request(struct libwifi_frame frame, unsigned char *args, const | |||
295 | return; | 285 | return; |
296 | } | 286 | } |
297 | 287 | ||
298 | if (got_radiotap && parse_radiotap_header) { | ||
299 | parse_radiotap(packet, header->caplen); | ||
300 | } | ||
301 | |||
302 | print_sta_info(&sta); | 288 | print_sta_info(&sta); |
303 | } | 289 | } |
304 | } | 290 | } |
@@ -312,10 +298,6 @@ void parse_assoc_response(struct libwifi_frame frame, unsigned char *args, const | |||
312 | return; | 298 | return; |
313 | } | 299 | } |
314 | 300 | ||
315 | if (got_radiotap && parse_radiotap_header) { | ||
316 | parse_radiotap(packet, header->caplen); | ||
317 | } | ||
318 | |||
319 | print_bss_info(&bss); | 301 | print_bss_info(&bss); |
320 | } | 302 | } |
321 | } | 303 | } |
@@ -329,10 +311,6 @@ void parse_reassoc_request(struct libwifi_frame frame, unsigned char *args, cons | |||
329 | return; | 311 | return; |
330 | } | 312 | } |
331 | 313 | ||
332 | if (got_radiotap && parse_radiotap_header) { | ||
333 | parse_radiotap(packet, header->caplen); | ||
334 | } | ||
335 | |||
336 | print_sta_info(&sta); | 314 | print_sta_info(&sta); |
337 | } | 315 | } |
338 | } | 316 | } |
@@ -346,10 +324,6 @@ void parse_reassoc_response(struct libwifi_frame frame, unsigned char *args, con | |||
346 | return; | 324 | return; |
347 | } | 325 | } |
348 | 326 | ||
349 | if (got_radiotap && parse_radiotap_header) { | ||
350 | parse_radiotap(packet, header->caplen); | ||
351 | } | ||
352 | |||
353 | print_bss_info(&bss); | 327 | print_bss_info(&bss); |
354 | } | 328 | } |
355 | } | 329 | } |
@@ -427,6 +401,10 @@ void parse_packet(unsigned char *args, const struct pcap_pkthdr *header, const u | |||
427 | return; | 401 | return; |
428 | } | 402 | } |
429 | 403 | ||
404 | if (got_radiotap && parse_radiotap_header && frame.flags & LIBWIFI_FLAGS_RADIOTAP_PRESENT) { | ||
405 | parse_radiotap(&frame); | ||
406 | } | ||
407 | |||
430 | memset(&bss, 0, sizeof(struct libwifi_bss)); | 408 | memset(&bss, 0, sizeof(struct libwifi_bss)); |
431 | memset(&sta, 0, sizeof(struct libwifi_sta)); | 409 | memset(&sta, 0, sizeof(struct libwifi_sta)); |
432 | 410 | ||