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 | ||
