about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorMarc <marc@malloc.me>2022-09-10 20:18:18 +0100
committerMarc <marc@malloc.me>2022-09-10 20:18:18 +0100
commit7c2b373bf37186fd94fdc1d46393780e46f646a8 (patch)
treec424e584658ee3fdcf0f0c0d3466f2906681577b /src
parent18b3f897df1d17e9d140fb24b7bad4bdd2b849f1 (diff)
downloadlibwifi-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.c8
-rw-r--r--src/libwifi/core/frame/frame.h3
-rw-r--r--src/libwifi/core/misc/radiotap.h11
-rw-r--r--src/libwifi/parse/misc/radiotap.c17
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 */
35int libwifi_get_wifi_frame(struct libwifi_frame *fi, const unsigned char *frame, size_t frame_len, 35int 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
136void libwifi_free_wifi_frame(struct libwifi_frame *fi) { 139void 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 */
30enum libwifi_frame_type { 32enum libwifi_frame_type {
@@ -306,6 +308,7 @@ union libwifi_mgmt_frame_header {
306 * frame in libwifi. 308 * frame in libwifi.
307 */ 309 */
308struct libwifi_frame { 310struct 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 */
28struct libwifi_radiotap_channel { 35struct 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;