diff options
author | Marc <marc@malloc.me> | 2022-09-10 20:18:18 +0100 |
---|---|---|
committer | Marc <marc@malloc.me> | 2022-09-10 20:18:18 +0100 |
commit | 7c2b373bf37186fd94fdc1d46393780e46f646a8 (patch) | |
tree | c424e584658ee3fdcf0f0c0d3466f2906681577b /src | |
parent | 18b3f897df1d17e9d140fb24b7bad4bdd2b849f1 (diff) | |
download | libwifi-7c2b373bf37186fd94fdc1d46393780e46f646a8.tar.gz libwifi-7c2b373bf37186fd94fdc1d46393780e46f646a8.tar.bz2 libwifi-7c2b373bf37186fd94fdc1d46393780e46f646a8.zip |
core/parse: Better handling of Radiotap information
Radiotap information is now stored in the `libwifi_frame` struct, and will be kept automatically in `libwifi_frame.radiotap_info` for the lifecycle of said frame, if it is present. A new flag has been added for the frame for use with `libwifi_frame.flags` to detect if the radiotap info is present: `LIBWIFI_FLAGS_RADIOTAP_PRESENT`. The frame parser will now automatically calculate the band and center channel from radiotap data, and will store them in `libwifi_radiotap_info.channel.center` and `libwifi_radiotap_info.channel.band`. Four new flags have been added for use with the new radiotap band field: - `LIBWIFI_RADIOTAP_BAND_2GHZ` - `LIBWIFI_RADIOTAP_BAND_5GHZ` - `LIBWIFI_RADIOTAP_BAND_6GHZ` - `LIBWIFI_RADIOTAP_BAND_900MHZ` These can be used with a binary AND: `if (rtap.channel.band & LIBWIFI_RADIOTAP_BAND_6GHZ) { }`
Diffstat (limited to 'src')
-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 |
4 files changed, 36 insertions, 3 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; |