about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorMarc <foxtrot@malloc.me>2021-11-30 22:39:26 +0000
committerMarc <foxtrot@malloc.me>2021-12-01 16:54:44 +0000
commitae6c98a48da409d040604aeffb84a38155fb5bac (patch)
treec27a8e28972209581ce3fba2130bf0c2b4f9c9c0 /src
downloadlibwifi-ae6c98a48da409d040604aeffb84a38155fb5bac.tar.gz
libwifi-ae6c98a48da409d040604aeffb84a38155fb5bac.tar.bz2
libwifi-ae6c98a48da409d040604aeffb84a38155fb5bac.zip
Initial Commit
Signed-off-by: Marc <foxtrot@malloc.me>
Diffstat (limited to 'src')
-rw-r--r--src/libwifi.h75
-rw-r--r--src/libwifi/core/core.c46
-rw-r--r--src/libwifi/core/core.h53
-rw-r--r--src/libwifi/core/frame/control/cts.h35
-rw-r--r--src/libwifi/core/frame/control/rts.h38
-rw-r--r--src/libwifi/core/frame/crc.c63
-rw-r--r--src/libwifi/core/frame/crc.h49
-rw-r--r--src/libwifi/core/frame/data/data.h32
-rw-r--r--src/libwifi/core/frame/frame.c145
-rw-r--r--src/libwifi/core/frame/frame.h334
-rw-r--r--src/libwifi/core/frame/management/action.h93
-rw-r--r--src/libwifi/core/frame/management/assoc_request.h51
-rw-r--r--src/libwifi/core/frame/management/assoc_response.h54
-rw-r--r--src/libwifi/core/frame/management/atim.h33
-rw-r--r--src/libwifi/core/frame/management/authentication.h54
-rw-r--r--src/libwifi/core/frame/management/beacon.h54
-rw-r--r--src/libwifi/core/frame/management/common.h101
-rw-r--r--src/libwifi/core/frame/management/deauthentication.h55
-rw-r--r--src/libwifi/core/frame/management/disassociation.h55
-rw-r--r--src/libwifi/core/frame/management/probe_request.h38
-rw-r--r--src/libwifi/core/frame/management/probe_response.h54
-rw-r--r--src/libwifi/core/frame/management/reassoc_request.h54
-rw-r--r--src/libwifi/core/frame/management/reassoc_response.h54
-rw-r--r--src/libwifi/core/frame/management/timing_ad.h82
-rw-r--r--src/libwifi/core/frame/tag.c131
-rw-r--r--src/libwifi/core/frame/tag.h306
-rw-r--r--src/libwifi/core/frame/tag_iterator.c55
-rw-r--r--src/libwifi/core/frame/tag_iterator.h53
-rw-r--r--src/libwifi/core/misc/byteswap.h31
-rw-r--r--src/libwifi/core/misc/epoch.c23
-rw-r--r--src/libwifi/core/misc/epoch.h26
-rw-r--r--src/libwifi/core/misc/llc.h33
-rw-r--r--src/libwifi/core/misc/radiotap.h83
-rw-r--r--src/libwifi/core/misc/security.h289
-rw-r--r--src/libwifi/core/misc/types.h218
-rw-r--r--src/libwifi/core/radiotap/COPYING14
-rw-r--r--src/libwifi/core/radiotap/platform.h81
-rw-r--r--src/libwifi/core/radiotap/radiotap.c469
-rw-r--r--src/libwifi/core/radiotap/radiotap.h221
-rw-r--r--src/libwifi/core/radiotap/radiotap_iter.h101
-rw-r--r--src/libwifi/gen/control/cts.c30
-rw-r--r--src/libwifi/gen/control/cts.h30
-rw-r--r--src/libwifi/gen/control/rts.c32
-rw-r--r--src/libwifi/gen/control/rts.h32
-rw-r--r--src/libwifi/gen/management/action.c110
-rw-r--r--src/libwifi/gen/management/action.h80
-rw-r--r--src/libwifi/gen/management/assoc_request.c85
-rw-r--r--src/libwifi/gen/management/assoc_request.h39
-rw-r--r--src/libwifi/gen/management/assoc_response.c106
-rw-r--r--src/libwifi/gen/management/assoc_response.h69
-rw-r--r--src/libwifi/gen/management/atim.c35
-rw-r--r--src/libwifi/gen/management/atim.h24
-rw-r--r--src/libwifi/gen/management/authentication.c81
-rw-r--r--src/libwifi/gen/management/authentication.h64
-rw-r--r--src/libwifi/gen/management/beacon.c117
-rw-r--r--src/libwifi/gen/management/beacon.h78
-rw-r--r--src/libwifi/gen/management/common.h54
-rw-r--r--src/libwifi/gen/management/deauthentication.c82
-rw-r--r--src/libwifi/gen/management/deauthentication.h63
-rw-r--r--src/libwifi/gen/management/disassociation.c80
-rw-r--r--src/libwifi/gen/management/disassociation.h63
-rw-r--r--src/libwifi/gen/management/probe_request.c76
-rw-r--r--src/libwifi/gen/management/probe_request.h64
-rw-r--r--src/libwifi/gen/management/probe_response.c118
-rw-r--r--src/libwifi/gen/management/probe_response.h78
-rw-r--r--src/libwifi/gen/management/reassoc_request.c87
-rw-r--r--src/libwifi/gen/management/reassoc_request.h30
-rw-r--r--src/libwifi/gen/management/reassoc_response.c108
-rw-r--r--src/libwifi/gen/management/reassoc_response.h70
-rw-r--r--src/libwifi/gen/management/timing_ad.c111
-rw-r--r--src/libwifi/gen/management/timing_ad.h32
-rw-r--r--src/libwifi/gen/misc/radiotap.c123
-rw-r--r--src/libwifi/gen/misc/radiotap.h31
-rw-r--r--src/libwifi/parse/data/data.c48
-rw-r--r--src/libwifi/parse/data/data.h26
-rw-r--r--src/libwifi/parse/data/eapol.c190
-rw-r--r--src/libwifi/parse/data/eapol.h91
-rw-r--r--src/libwifi/parse/management/assoc_request.c79
-rw-r--r--src/libwifi/parse/management/assoc_request.h32
-rw-r--r--src/libwifi/parse/management/assoc_response.c92
-rw-r--r--src/libwifi/parse/management/assoc_response.h35
-rw-r--r--src/libwifi/parse/management/beacon.c91
-rw-r--r--src/libwifi/parse/management/beacon.h35
-rw-r--r--src/libwifi/parse/management/common.c192
-rw-r--r--src/libwifi/parse/management/common.h70
-rw-r--r--src/libwifi/parse/management/deauthentication.c74
-rw-r--r--src/libwifi/parse/management/deauthentication.h25
-rw-r--r--src/libwifi/parse/management/disassociation.c72
-rw-r--r--src/libwifi/parse/management/disassociation.h25
-rw-r--r--src/libwifi/parse/management/probe_request.c72
-rw-r--r--src/libwifi/parse/management/probe_request.h32
-rw-r--r--src/libwifi/parse/management/probe_response.c88
-rw-r--r--src/libwifi/parse/management/probe_response.h35
-rw-r--r--src/libwifi/parse/management/reassoc_request.c79
-rw-r--r--src/libwifi/parse/management/reassoc_request.h32
-rw-r--r--src/libwifi/parse/management/reassoc_response.c92
-rw-r--r--src/libwifi/parse/management/reassoc_response.h35
-rw-r--r--src/libwifi/parse/misc/radiotap.c126
-rw-r--r--src/libwifi/parse/misc/radiotap.h39
-rw-r--r--src/libwifi/parse/misc/security.c685
-rw-r--r--src/libwifi/parse/misc/security.h124
101 files changed, 8734 insertions, 0 deletions
diff --git a/src/libwifi.h b/src/libwifi.h new file mode 100644 index 0000000..d53789a --- /dev/null +++ b/src/libwifi.h
@@ -0,0 +1,75 @@
1#ifndef LIBWIFI_H
2#define LIBWIFI_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include "libwifi/core/core.h"
9#include "libwifi/core/frame/control/cts.h"
10#include "libwifi/core/frame/control/rts.h"
11#include "libwifi/core/frame/crc.h"
12#include "libwifi/core/frame/data/data.h"
13#include "libwifi/core/frame/frame.h"
14#include "libwifi/core/frame/management/action.h"
15#include "libwifi/core/frame/management/assoc_request.h"
16#include "libwifi/core/frame/management/assoc_response.h"
17#include "libwifi/core/frame/management/atim.h"
18#include "libwifi/core/frame/management/authentication.h"
19#include "libwifi/core/frame/management/beacon.h"
20#include "libwifi/core/frame/management/common.h"
21#include "libwifi/core/frame/management/deauthentication.h"
22#include "libwifi/core/frame/management/disassociation.h"
23#include "libwifi/core/frame/management/probe_request.h"
24#include "libwifi/core/frame/management/probe_response.h"
25#include "libwifi/core/frame/management/reassoc_request.h"
26#include "libwifi/core/frame/management/reassoc_response.h"
27#include "libwifi/core/frame/management/timing_ad.h"
28#include "libwifi/core/frame/tag.h"
29#include "libwifi/core/frame/tag_iterator.h"
30#include "libwifi/core/misc/byteswap.h"
31#include "libwifi/core/misc/epoch.h"
32#include "libwifi/core/misc/llc.h"
33#include "libwifi/core/misc/radiotap.h"
34#include "libwifi/core/misc/security.h"
35#include "libwifi/core/misc/types.h"
36#include "libwifi/core/radiotap/platform.h"
37#include "libwifi/core/radiotap/radiotap.h"
38#include "libwifi/core/radiotap/radiotap_iter.h"
39#include "libwifi/gen/control/cts.h"
40#include "libwifi/gen/control/rts.h"
41#include "libwifi/gen/management/action.h"
42#include "libwifi/gen/management/assoc_request.h"
43#include "libwifi/gen/management/assoc_response.h"
44#include "libwifi/gen/management/atim.h"
45#include "libwifi/gen/management/authentication.h"
46#include "libwifi/gen/management/beacon.h"
47#include "libwifi/gen/management/common.h"
48#include "libwifi/gen/management/deauthentication.h"
49#include "libwifi/gen/management/disassociation.h"
50#include "libwifi/gen/management/probe_request.h"
51#include "libwifi/gen/management/probe_response.h"
52#include "libwifi/gen/management/reassoc_request.h"
53#include "libwifi/gen/management/reassoc_response.h"
54#include "libwifi/gen/management/timing_ad.h"
55#include "libwifi/gen/misc/radiotap.h"
56#include "libwifi/parse/data/data.h"
57#include "libwifi/parse/data/eapol.h"
58#include "libwifi/parse/management/assoc_request.h"
59#include "libwifi/parse/management/assoc_response.h"
60#include "libwifi/parse/management/beacon.h"
61#include "libwifi/parse/management/common.h"
62#include "libwifi/parse/management/deauthentication.h"
63#include "libwifi/parse/management/disassociation.h"
64#include "libwifi/parse/management/probe_request.h"
65#include "libwifi/parse/management/probe_response.h"
66#include "libwifi/parse/management/reassoc_request.h"
67#include "libwifi/parse/management/reassoc_response.h"
68#include "libwifi/parse/misc/radiotap.h"
69#include "libwifi/parse/misc/security.h"
70
71#ifdef __cplusplus
72}
73#endif
74
75#endif /* LIBWIFI_H */
diff --git a/src/libwifi/core/core.c b/src/libwifi/core/core.c new file mode 100644 index 0000000..0340a82 --- /dev/null +++ b/src/libwifi/core/core.c
@@ -0,0 +1,46 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "core.h"
17#include <stdlib.h>
18#include <string.h>
19#include <sys/random.h>
20
21/**
22 * Random MAC addresses, achieved by obtaining 6 bytes of /dev/urandom via getrandom()
23 */
24void libwifi_random_mac(unsigned char buf[6], unsigned char prefix[3]) {
25 memset(buf, 0, 6);
26 if (prefix != NULL) {
27 memcpy(buf, prefix, 3);
28 getrandom(buf + 3, 3, 0);
29 } else {
30 getrandom(buf, 6, 0);
31 }
32}
33
34/**
35 * Dummy linker test function
36 */
37void libwifi_dummy(void) {
38 return;
39}
40
41/**
42 * Version
43 */
44const char *libwifi_get_version(void) {
45 return LIBWIFI_VERSION;
46}
diff --git a/src/libwifi/core/core.h b/src/libwifi/core/core.h new file mode 100644 index 0000000..02e6d45 --- /dev/null +++ b/src/libwifi/core/core.h
@@ -0,0 +1,53 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_H
17#define LIBWIFI_CORE_H
18
19#define LIBWIFI_VERSION "0.0.1"
20
21/**
22 * Commonly used fixed fields
23 */
24#define LIBWIFI_BCAST_MAC "\xFF\xFF\xFF\xFF\xFF\xFF"
25#define LIBWIFI_ZERO_MAC "\x00\x00\x00\x00\x00\x00"
26
27/**
28 * Helpers for MAC Addresses
29 */
30#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
31#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
32
33/**
34 * Function to randomly generate a MAC address.
35 *
36 * @param buf A buffer for the generated MAC to be written to
37 * @param prefix An optional OUI prefix
38 */
39void libwifi_random_mac(unsigned char buf[6], unsigned char prefix[3]);
40
41/**
42 * Dummy function for linker testing purposes.
43 */
44void libwifi_dummy(void);
45
46/**
47 * Obtain the version of libwifi.
48 *
49 * @return The version of the installed libwifi.
50 */
51const char *libwifi_get_version(void);
52
53#endif /* LIBWIFI_CORE_H */
diff --git a/src/libwifi/core/frame/control/cts.h b/src/libwifi/core/frame/control/cts.h new file mode 100644 index 0000000..ecf0007 --- /dev/null +++ b/src/libwifi/core/frame/control/cts.h
@@ -0,0 +1,35 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_CTS_H
17#define LIBWIFI_CORE_CTS_H
18
19#include "../frame.h"
20
21/**
22 * Clear-to-Send Layout
23 * ───────────────────────────────────
24 * ┌─────────────────────────────────┐
25 * │ Header │ Bytes: 4
26 * ├─────────────────────────────────┤
27 * │ Receiver Address │ Bytes: 6
28 * └─────────────────────────────────┘
29 */
30struct libwifi_cts {
31 struct libwifi_ctrl_frame_header frame_header;
32 unsigned char receiver_addr[6];
33};
34
35#endif /* LIBWIFI_CORE_CTS_H */
diff --git a/src/libwifi/core/frame/control/rts.h b/src/libwifi/core/frame/control/rts.h new file mode 100644 index 0000000..0fbaacc --- /dev/null +++ b/src/libwifi/core/frame/control/rts.h
@@ -0,0 +1,38 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_RTS_H
17#define LIBWIFI_CORE_RTS_H
18
19#include "../frame.h"
20
21/**
22 * Request-to-Send Layout
23 * ───────────────────────────────────
24 * ┌─────────────────────────────────┐
25 * │ Header │ Bytes: 4
26 * ├─────────────────────────────────┤
27 * │ Receiver Address │ Bytes: 6
28 * ├─────────────────────────────────┤
29 * │ Transmitter Address │ Bytes: 4
30 * └─────────────────────────────────┘
31 */
32struct libwifi_rts {
33 struct libwifi_ctrl_frame_header frame_header;
34 unsigned char receiver_addr[6];
35 unsigned char transmitter_addr[6];
36};
37
38#endif /* LIBWIFI_CORE_RTS_H */
diff --git a/src/libwifi/core/frame/crc.c b/src/libwifi/core/frame/crc.c new file mode 100644 index 0000000..33dae06 --- /dev/null +++ b/src/libwifi/core/frame/crc.c
@@ -0,0 +1,63 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "crc.h"
17#include "../misc/byteswap.h"
18
19#include <stdint.h>
20#include <sys/types.h>
21
22/*
23 * Basic CRC32 implementation for getting the frame check sum of
24 * a supplied message, usually frame data.
25 */
26uint32_t libwifi_crc32(const unsigned char *message, int message_len) {
27 int i, j;
28 unsigned int byte, crc, mask;
29 i = 0;
30 crc = 0xFFFFFFFF;
31 while (i < message_len) {
32 byte = message[i];
33 crc = crc ^ byte;
34 for (j = 7; j >= 0; j--) {
35 mask = -(crc & 1);
36 crc = (crc >> 1) ^ (0xEDB88320 & mask);
37 }
38 i = i + 1;
39 }
40 return ~crc;
41}
42
43/*
44 * Specific function for calculating a frame FCS, byteswapped for the
45 * host endianess.
46 */
47uint32_t libwifi_calculate_fcs(const unsigned char *frame, size_t frame_len) {
48 return BYTESWAP32(libwifi_crc32(frame, frame_len));
49}
50
51/*
52 * Verify a frame containing a FCS at the end to the FCS calculated
53 * by libwifi.
54 */
55int libwifi_frame_verify(void *frame, size_t frame_len) {
56 uint32_t oCRC = *((uint32_t *) ((char *) frame + frame_len));
57 uint32_t rCRC = libwifi_calculate_fcs(frame, frame_len);
58
59 if (rCRC == oCRC) {
60 return 1;
61 }
62 return 0;
63}
diff --git a/src/libwifi/core/frame/crc.h b/src/libwifi/core/frame/crc.h new file mode 100644 index 0000000..aab1c4e --- /dev/null +++ b/src/libwifi/core/frame/crc.h
@@ -0,0 +1,49 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_CRC_H
17#define LIBWIFI_CORE_CRC_H
18
19#include <stdint.h>
20#include <sys/types.h>
21
22/**
23 * Calculate the CRC32 sum of a given buffer.
24 *
25 * @param message Buffer of data
26 * @param message_len Length of the data buffer
27 * @return CRC32 sum of the given buffer
28 */
29uint32_t libwifi_crc32(const unsigned char *message, int message_len);
30
31/**
32 * Calculate the frame checksum for an 802.11 frame.
33 *
34 * @param frame An 802.11 frame
35 * @param frame_len Length of the frame
36 * @return frame checksum of the frame
37 */
38uint32_t libwifi_calculate_fcs(const unsigned char *frame, size_t frame_len);
39
40/**
41 * Check if the given 802.11 frame has a valid FCS.
42 *
43 * @param frame An 802.11 frame with an FCS
44 * @param frame_len Length of the frame
45 * @return 1 if verified, 0 if not
46 */
47int libwifi_frame_verify(void *frame, size_t frame_len);
48
49#endif /* LIBWIFI_CORE_CRC_H */
diff --git a/src/libwifi/core/frame/data/data.h b/src/libwifi/core/frame/data/data.h new file mode 100644 index 0000000..2eca0ce --- /dev/null +++ b/src/libwifi/core/frame/data/data.h
@@ -0,0 +1,32 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_DATA_H
17#define LIBWIFI_CORE_DATA_H
18
19#include <sys/types.h>
20
21/**
22 * Data Frame Layout
23 * ───────────────────────────────────
24 */
25struct libwifi_data {
26 unsigned char transmitter[6];
27 unsigned char receiver[6];
28 unsigned char *body;
29 size_t body_len;
30};
31
32#endif /* LIBWIFI_CORE_DATA_H */
diff --git a/src/libwifi/core/frame/frame.c b/src/libwifi/core/frame/frame.c new file mode 100644 index 0000000..d885d96 --- /dev/null +++ b/src/libwifi/core/frame/frame.c
@@ -0,0 +1,145 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "frame.h"
17#include "../../parse/misc/radiotap.h"
18#include "../misc/byteswap.h"
19#include "../radiotap/radiotap.h"
20
21#include <errno.h>
22#include <stdlib.h>
23#include <string.h>
24
25/*
26 * Turn sniffed data into a libwifi_frame struct for use with other libwifi functions.
27 *
28 * Supported frames:
29 * - Management Frames (Ordered)
30 * - Management Frames (Unordered)
31 * - Data Frames
32 * - QoS Data Frames
33 * - Control Frames
34 */
35int libwifi_get_wifi_frame(struct libwifi_frame *fi, const unsigned char *frame, size_t frame_len,
36 int radiotap) {
37 union libwifi_frame_header fh = {0};
38 size_t header_len = 0;
39 size_t frame_data_len = frame_len;
40 unsigned char *frame_data = malloc(frame_data_len);
41 memcpy(frame_data, (unsigned char *) frame, frame_data_len);
42
43 if (radiotap) {
44 struct libwifi_radiotap_info rtap_info = {0};
45 libwifi_parse_radiotap_info(&rtap_info, frame_data);
46
47 // Skip forward by the length of the radiotap header
48 frame_data_len -= rtap_info.length;
49 unsigned char *new_data = malloc(frame_data_len);
50 memcpy(new_data, frame_data + rtap_info.length, frame_data_len);
51 free(frame_data);
52 frame_data = new_data;
53
54 // Remove the FCS from the end of the frame data, if present
55 if (rtap_info.flags & IEEE80211_RADIOTAP_F_FCS) {
56 fi->flags |= LIBWIFI_FLAGS_FCS_PRESENT;
57 frame_data_len -= sizeof(uint32_t); // FCS is 4 bytes wide
58 frame_data = realloc(frame_data, frame_data_len);
59 if (frame_data == NULL) {
60 return -ENOMEM;
61 }
62 }
63 }
64
65 struct libwifi_frame_ctrl *frame_control = (struct libwifi_frame_ctrl *) frame_data;
66
67 switch (frame_control->type) {
68 case TYPE_DATA:
69 switch (frame_control->subtype) {
70 case SUBTYPE_DATA_QOS_DATA:
71 case SUBTYPE_DATA_QOS_NULL:
72 case SUBTYPE_DATA_QOS_DATA_CF_ACK:
73 case SUBTYPE_DATA_QOS_DATA_CF_ACK_CF_POLL:
74 case SUBTYPE_DATA_QOS_DATA_CF_POLL:
75 case SUBTYPE_DATA_QOS_CF_ACK_CF_POLL:
76 case SUBTYPE_DATA_QOS_CF_POLL:
77 fi->flags |= LIBWIFI_FLAGS_IS_QOS;
78 break;
79 }
80
81 if (fi->flags & LIBWIFI_FLAGS_IS_QOS) {
82 header_len = sizeof(struct libwifi_data_qos_frame_header);
83 } else {
84 header_len = sizeof(struct libwifi_data_frame_header);
85 }
86
87 if (frame_data_len < header_len) {
88 free(frame_data);
89 return -EINVAL;
90 }
91
92 if (fi->flags & LIBWIFI_FLAGS_IS_QOS) {
93 memset(&fh.data_qos, 0, sizeof(struct libwifi_data_qos_frame_header));
94 memcpy(&fh.data_qos, frame_data, sizeof(struct libwifi_data_qos_frame_header));
95 } else {
96 memset(&fh.data, 0, sizeof(struct libwifi_data_frame_header));
97 memcpy(&fh.data, frame_data, sizeof(struct libwifi_data_frame_header));
98 }
99 break;
100 case TYPE_MANAGEMENT:
101 if (frame_control->flags.ordered) {
102 header_len = sizeof(struct libwifi_mgmt_ordered_frame_header);
103 if (frame_data_len < header_len) {
104 free(frame_data);
105 return -EINVAL;
106 }
107 memcpy(&fh.mgmt_ordered, frame_data, header_len);
108 } else {
109 header_len = sizeof(struct libwifi_mgmt_unordered_frame_header);
110 if (frame_data_len < header_len) {
111 free(frame_data);
112 return -EINVAL;
113 }
114 memcpy(&fh.mgmt_unordered, frame_data, header_len);
115 }
116 break;
117 case TYPE_CONTROL:
118 header_len = sizeof(struct libwifi_ctrl_frame_header);
119 if (frame_data_len < header_len) {
120 free(frame_data);
121 return -EINVAL;
122 }
123 memcpy(&fh.ctrl, frame_data, sizeof(struct libwifi_ctrl_frame_header));
124 break;
125 default:
126 free(frame_data);
127 return -EINVAL;
128 }
129
130 fi->len = frame_data_len;
131 fi->header = fh;
132 fi->header_len = header_len;
133 memcpy(&fi->frame_control, frame_control, sizeof(struct libwifi_frame_ctrl));
134
135 fi->body = malloc(fi->len - fi->header_len);
136 memcpy(fi->body, frame_data + header_len, (fi->len - fi->header_len));
137
138 free(frame_data);
139
140 return 0;
141}
142
143void libwifi_free_wifi_frame(struct libwifi_frame *fi) {
144 free(fi->body);
145}
diff --git a/src/libwifi/core/frame/frame.h b/src/libwifi/core/frame/frame.h new file mode 100644 index 0000000..8c5c89f --- /dev/null +++ b/src/libwifi/core/frame/frame.h
@@ -0,0 +1,334 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_FRAME_H
17#define LIBWIFI_CORE_FRAME_H
18
19#include "../../core/misc/byteswap.h"
20
21#include <stdint.h>
22#include <sys/types.h>
23
24/* libwifi_frame Flags */
25#define LIBWIFI_FLAGS_FCS_PRESENT (1 << 0)
26#define LIBWIFI_FLAGS_IS_QOS (1 << 1)
27
28/* Defined frame types and sub-types */
29enum libwifi_frame_type {
30 TYPE_MANAGEMENT = 0,
31 TYPE_CONTROL = 1,
32 TYPE_DATA = 2,
33 TYPE_EXTENSION = 3,
34};
35enum libwifi_mgmt_subtypes {
36 SUBTYPE_ASSOC_REQ = 0,
37 SUBTYPE_ASSOC_RESP = 1,
38 SUBTYPE_REASSOC_REQ = 2,
39 SUBTYPE_REASSOC_RESP = 3,
40 SUBTYPE_PROBE_REQ = 4,
41 SUBTYPE_PROBE_RESP = 5,
42 SUBTYPE_TIME_ADV = 6,
43 // Reserved = 7,
44 SUBTYPE_BEACON = 8,
45 SUBTYPE_ATIM = 9,
46 SUBTYPE_DISASSOC = 10,
47 SUBTYPE_AUTH = 11,
48 SUBTYPE_DEAUTH = 12,
49 SUBTYPE_ACTION = 13,
50 SUBTYPE_ACTION_NOACK = 14,
51 // Reserved = 15,
52};
53enum libwifi_control_subtypes {
54 // Reserved = 0-3,
55 SUBTYPE_TACK = 3,
56 SUBTYPE_BEAMFORM_REPORT_POLL = 4,
57 SUBTYPE_VHT_NDP_ANNOUNCE = 5,
58 SUBTYPE_CF_EXTENSION = 6,
59 SUBTYPE_WRAPPER = 7,
60 SUBTYPE_BLOCK_ACK_REQ = 8,
61 SUBTYPE_BLOCK_ACK = 9,
62 SUBTYPE_PS_POLL = 10,
63 SUBTYPE_RTS = 11,
64 SUBTYPE_CTS = 12,
65 SUBTYPE_ACK = 13,
66 SUBTYPE_CF_END = 14,
67 SUBTYPE_CF_END_CF_ACK = 15,
68};
69enum libwifi_control_extension_subtypes {
70 // Reserved = 0-1,
71 SUBTYPE_CF_EXT_POLL = 2,
72 SUBTYPE_CF_EXT_SPR = 3,
73 SUBTYPE_CF_EXT_GRANT = 4,
74 SUBTYPE_CF_EXT_DMG_CTS = 5,
75 SUBTYPE_CF_EXT_DMG_DTS = 6,
76 SUBTYPE_CF_EXT_GRANT_ACK = 7,
77 SUBTYPE_CF_EXT_SSW = 8,
78 SUBTYPE_CF_EXT_SSW_FEEDBACK = 9,
79 SUBTYPE_CF_EXT_SSW_ACK = 10,
80 // Reserved = 11-15,
81};
82enum libwifi_data_subtypes {
83 SUBTYPE_DATA = 0,
84 // Reserved = 1-3,
85 SUBTYPE_DATA_NULL = 4,
86 // Reserved = 4-7,
87 SUBTYPE_DATA_QOS_DATA = 8,
88 SUBTYPE_DATA_QOS_DATA_CF_ACK = 9,
89 SUBTYPE_DATA_QOS_DATA_CF_POLL = 10,
90 SUBTYPE_DATA_QOS_DATA_CF_ACK_CF_POLL = 11,
91 SUBTYPE_DATA_QOS_NULL = 12,
92 // Reserved = 13,
93 SUBTYPE_DATA_QOS_CF_POLL = 14,
94 SUBTYPE_DATA_QOS_CF_ACK_CF_POLL = 15,
95};
96enum libwifi_extension_subtypes {
97 SUBTYPE_EXTENSION_DMG_BEACON = 0,
98 SUBTYPE_EXTENSION_SIG_BEACON = 1,
99 // Reserved = 2-15
100};
101
102/*
103 * libwifi Representation of an 802.11 Frame Control Field's Flags.
104 */
105
106struct libwifi_frame_ctrl_flags {
107 unsigned int to_ds : 1;
108 unsigned int from_ds : 1;
109 unsigned int more_frags : 1;
110 unsigned int retry : 1;
111 unsigned int power_mgmt : 1;
112 unsigned int more_data : 1;
113 unsigned int protect : 1;
114 unsigned int ordered : 1;
115} __attribute__((packed));
116
117/*
118 * libwifi Representation of an 802.11 Frame Control Field.
119 */
120struct libwifi_frame_ctrl {
121 unsigned int version : 2;
122 unsigned int type : 2;
123 unsigned int subtype : 4;
124 struct libwifi_frame_ctrl_flags flags;
125} __attribute__((packed));
126
127/*
128 * libwifi Representation of an 802.11 Sequence Control Field.
129 */
130struct libwifi_seq_control {
131 unsigned int fragment_number : 4;
132 unsigned int sequence_number : 12;
133} __attribute__((packed));
134
135/*
136 * libwifi Representation of an 802.11 Data QoS Control Field.
137 *
138 * As the bits of the QoS Control Field can vary depending on other
139 * factors, generic bit names are used here.
140 */
141struct libwifi_qos_control {
142 unsigned int bit1 : 1;
143 unsigned int bit2 : 1;
144 unsigned int bit3 : 1;
145 unsigned int bit4 : 1;
146 unsigned int bit5 : 1;
147 unsigned int bit6 : 1;
148 unsigned int bit7 : 1;
149 unsigned int bit8 : 1;
150 unsigned int bit9 : 1;
151 unsigned int bit10 : 1;
152 unsigned int bit11 : 1;
153 unsigned int bit12 : 1;
154 unsigned int bit13 : 1;
155 unsigned int bit14 : 1;
156 unsigned int bit15 : 1;
157 unsigned int bit16 : 1;
158} __attribute__((packed));
159
160/*
161 * libwifi Representation of an ordered Management Frame header.
162 *
163 * ┌───────────────────────────┐
164 * │ Frame Control Field │ ── 2 Bytes
165 * ├───────────────────────────┤
166 * │ Duration │ ── 2 Bytes
167 * ├───────────────────────────┤
168 * │ Address 1 │ ── 6 Bytes
169 * ├───────────────────────────┤
170 * │ Address 2 │ ── 6 Bytes
171 * ├───────────────────────────┤
172 * │ Address 3 │ ── 6 Bytes
173 * ├───────────────────────────┤
174 * │ Sequence Control │ ── 2 Bytes
175 * ├───────────────────────────┤
176 * │ HT Control │ ── 4 Bytes
177 * └───────────────────────────┘
178 */
179struct libwifi_mgmt_ordered_frame_header {
180 struct libwifi_frame_ctrl frame_control;
181 uint16_t duration;
182 unsigned char addr1[6];
183 unsigned char addr2[6];
184 unsigned char addr3[6];
185 struct libwifi_seq_control seq_control;
186 uint32_t ht_control;
187} __attribute__((packed));
188
189/*
190 * libwifi Representation of an unordered Management Frame header.
191 *
192 * ┌───────────────────────────┐
193 * │ Frame Control Field │ ── 2 Bytes
194 * ├───────────────────────────┤
195 * │ Duration │ ── 2 Bytes
196 * ├───────────────────────────┤
197 * │ Address 1 │ ── 6 Bytes
198 * ├───────────────────────────┤
199 * │ Address 2 │ ── 6 Bytes
200 * ├───────────────────────────┤
201 * │ Address 3 │ ── 6 Bytes
202 * ├───────────────────────────┤
203 * │ Sequence Control │ ── 2 Bytes
204 * └───────────────────────────┘
205 */
206struct libwifi_mgmt_unordered_frame_header {
207 struct libwifi_frame_ctrl frame_control;
208 uint16_t duration;
209 unsigned char addr1[6];
210 unsigned char addr2[6];
211 unsigned char addr3[6];
212 struct libwifi_seq_control seq_control;
213} __attribute__((packed));
214
215/*
216 * libwifi Representation of a Control Frame header.
217 *
218 * ┌───────────────────────────┐
219 * │ Frame Control Field │ ── 2 Bytes
220 * ├───────────────────────────┤
221 * │ Duration │ ── 2 Bytes
222 * └───────────────────────────┘
223 */
224struct libwifi_ctrl_frame_header {
225 struct libwifi_frame_ctrl frame_control;
226 uint16_t duration;
227} __attribute__((packed));
228
229/*
230 * libwifi Representation of a non-QoS Data Frame header.
231 *
232 * ┌───────────────────────────┐
233 * │ Frame Control Field │ ── 2 Bytes
234 * ├───────────────────────────┤
235 * │ Duration │ ── 2 Bytes
236 * ├───────────────────────────┤
237 * │ Address 1 │ ── 6 Bytes
238 * ├───────────────────────────┤
239 * │ Address 2 │ ── 6 Bytes
240 * ├───────────────────────────┤
241 * │ Address 3 │ ── 6 Bytes
242 * ├───────────────────────────┤
243 * │ Sequence Control │ ── 2 Bytes
244 * └───────────────────────────┘
245 */
246struct libwifi_data_frame_header {
247 struct libwifi_frame_ctrl frame_control;
248 uint16_t duration;
249 unsigned char addr1[6];
250 unsigned char addr2[6];
251 unsigned char addr3[6];
252 struct libwifi_seq_control seq_control;
253} __attribute__((packed));
254
255/*
256 * libwifi Representation of a QoS Data Frame header.
257 *
258 * ┌───────────────────────────┐
259 * │ Frame Control Field │ ── 2 Bytes
260 * ├───────────────────────────┤
261 * │ Duration │ ── 2 Bytes
262 * ├───────────────────────────┤
263 * │ Address 1 │ ── 6 Bytes
264 * ├───────────────────────────┤
265 * │ Address 2 │ ── 6 Bytes
266 * ├───────────────────────────┤
267 * │ Address 3 │ ── 6 Bytes
268 * ├───────────────────────────┤
269 * │ Sequence Control │ ── 2 Bytes
270 * ├───────────────────────────┤
271 * │ QoS Control │ ── 2 Bytes
272 * └───────────────────────────┘
273 */
274struct libwifi_data_qos_frame_header {
275 struct libwifi_frame_ctrl frame_control;
276 uint16_t duration;
277 unsigned char addr1[6];
278 unsigned char addr2[6];
279 unsigned char addr3[6];
280 struct libwifi_seq_control seq_control;
281 struct libwifi_qos_control qos_control;
282} __attribute__((packed));
283
284/*
285 * Union of all frame type headers for use with a libwifi_frame struct
286 */
287union libwifi_frame_header {
288 struct libwifi_mgmt_ordered_frame_header mgmt_ordered;
289 struct libwifi_mgmt_unordered_frame_header mgmt_unordered;
290 struct libwifi_ctrl_frame_header ctrl;
291 struct libwifi_data_frame_header data;
292 struct libwifi_data_qos_frame_header data_qos;
293};
294
295/*
296 * Union of all Management Frame headers
297 */
298union libwifi_mgmt_frame_header {
299 struct libwifi_mgmt_ordered_frame_header ordered;
300 struct libwifi_mgmt_unordered_frame_header unordered;
301};
302
303/*
304 * A libwifi_frame struct is used to represent any type of 802.11
305 * frame in libwifi.
306 */
307struct libwifi_frame {
308 uint16_t flags;
309 struct libwifi_frame_ctrl frame_control;
310 size_t len;
311 union libwifi_frame_header header;
312 size_t header_len;
313 unsigned char *body;
314};
315
316/**
317 * Convert a sniffed 802.11 frame into a libwifi_frame.
318 *
319 * @param fi A libwifi_frame struct
320 * @param frame An 802.11 frame
321 * @param frame_len Length of the sniffed 802.11 frame
322 * @return
323 */
324int libwifi_get_wifi_frame(struct libwifi_frame *fi, const unsigned char *frame, size_t frame_len,
325 int radiotap);
326
327/**
328 * Free any dynamically allocated data inside a libwifi_frame.
329 *
330 * @param fi A libwifi_frame struct
331 */
332void libwifi_free_wifi_frame(struct libwifi_frame *fi);
333
334#endif /* LIBWIFI_CORE_FRAME_H */
diff --git a/src/libwifi/core/frame/management/action.h b/src/libwifi/core/frame/management/action.h new file mode 100644 index 0000000..4bd78dd --- /dev/null +++ b/src/libwifi/core/frame/management/action.h
@@ -0,0 +1,93 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_ACTIONS_H
17#define LIBWIFI_CORE_ACTIONS_H
18
19#include "../frame.h"
20#include <stdint.h>
21
22/* Defined action fixed parameter values */
23enum libwifi_actions {
24 ACTION_SPECTRUM_MGMT = 0,
25 ACTION_QOS = 1,
26 // Reserved 2
27 ACTION_BLOCK_ACK = 3,
28 ACTION_PUBLIC = 4,
29 ACTION_RADIO_MEASUREMENT = 5,
30 ACTION_FAST_BSS_TRANSITION = 6,
31 ACTION_HT = 7,
32 ACTION_SA_QUERY = 8,
33 ACTION_PROTECTED_DOPA = 9,
34 ACTION_WNM = 10,
35 ACTION_UNSUPPORTED_WNM = 11,
36 ACTION_TDLS = 12,
37 ACTION_MESH = 13,
38 ACTION_MULTIHOP = 14,
39 ACTION_SELF_PROTECTED = 15,
40 ACTION_DMG = 16,
41 // Reserved 17
42 ACTION_FAST_SESSION_TRANSFER = 18,
43 ACTION_ROBUST_AV_STREAM = 19,
44 ACTION_UNPROTECTED_DMG = 20,
45 ACTION_VHT = 21,
46 ACTION_UNPROTECTED_SIG = 22,
47 ACTION_SIG = 23,
48 ACTION_FLOW_CONTROL = 24,
49 ACTION_CTRL_MCS_NEG = 25,
50 ACTION_FILS = 26,
51 ACTION_CDMG = 27,
52 ACTION_CMMG = 28,
53 ACTION_GLK = 29,
54 // Reserved 30-125
55 ACTION_VENDOR_PROTECTED = 126,
56 ACTION_VENDOR = 127,
57 // Error 128-255
58};
59
60/**
61 * Action Layout
62 * ─────────────────────────────────────
63 * ┌─────────────────────────────────────┐
64 * │ Header │ Bytes: 24
65 * ├─────────────────────────────────────┤
66 * │ Fixed Parameters │ Bytes: Variable
67 * │┌───────────────────────────────────┐│
68 * ││ category ││ Bytes: 1
69 * │├───────────────────────────────────┤│
70 * ││ detail ││ Bytes: Variable
71 * ││┌─────────────────────────────────┐││
72 * │││ tagged parameters │││
73 * ││└─────────────────────────────────┘││
74 * │└───────────────────────────────────┘│
75 * └─────────────────────────────────────┘
76 */
77
78struct libwifi_action_detail {
79 uint8_t detail_length;
80 char *detail;
81} __attribute__((packed));
82
83struct libwifi_action_fixed_parameters {
84 uint8_t category;
85 struct libwifi_action_detail details;
86} __attribute__((packed));
87
88struct libwifi_action {
89 struct libwifi_mgmt_unordered_frame_header frame_header;
90 struct libwifi_action_fixed_parameters fixed_parameters;
91} __attribute__((packed));
92
93#endif /* LIBWIFI_CORE_ACTIONS_H */
diff --git a/src/libwifi/core/frame/management/assoc_request.h b/src/libwifi/core/frame/management/assoc_request.h new file mode 100644 index 0000000..5a35762 --- /dev/null +++ b/src/libwifi/core/frame/management/assoc_request.h
@@ -0,0 +1,51 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_ASSOCREQ_H
17#define LIBWIFI_CORE_ASSOCREQ_H
18
19#include "../frame.h"
20#include "../tag.h"
21#include <stdint.h>
22
23/**
24 * Association Request Layout
25 * ─────────────────────────────────
26 * ┌─────────────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├─────────────────────────────────┤
29 * │ Fixed Parameters │ Bytes: 4
30 * │┌───────────────────────────────┐│
31 * ││ capabilities ││ Bytes: 2
32 * │├───────────────────────────────┤│
33 * ││ listen interval ││ Bytes: 2
34 * │└───────────────────────────────┘│
35 * ├─────────────────────────────────┤
36 * │ Tagged Parameters │ Bytes: Variable
37 * └─────────────────────────────────┘
38 */
39
40struct libwifi_assoc_req_fixed_parameters {
41 uint16_t capabilities_information;
42 uint16_t listen_interval;
43} __attribute__((packed));
44
45struct libwifi_assoc_req {
46 struct libwifi_mgmt_unordered_frame_header frame_header;
47 struct libwifi_assoc_req_fixed_parameters fixed_parameters;
48 struct libwifi_tagged_parameters tags;
49} __attribute__((packed));
50
51#endif /* LIBWIFI_CORE_ASSOCREQ_H */
diff --git a/src/libwifi/core/frame/management/assoc_response.h b/src/libwifi/core/frame/management/assoc_response.h new file mode 100644 index 0000000..85f5328 --- /dev/null +++ b/src/libwifi/core/frame/management/assoc_response.h
@@ -0,0 +1,54 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_ASSOCRESP_H
17#define LIBWIFI_CORE_ASSOCRESP_H
18
19#include "../frame.h"
20#include "../tag.h"
21#include <stdint.h>
22
23/**
24 * Association Response Layout
25 * ─────────────────────────────────
26 * ┌─────────────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├─────────────────────────────────┤
29 * │ Fixed Parameters │ Bytes: 6
30 * │┌───────────────────────────────┐│
31 * ││ capabilities ││ Bytes: 2
32 * │├───────────────────────────────┤│
33 * ││ status ││ Bytes: 2
34 * │├───────────────────────────────┤│
35 * ││ association id ││ Bytes: 2
36 * │└───────────────────────────────┘│
37 * ├─────────────────────────────────┤
38 * │ Tagged Parameters │ Bytes: Variable
39 * └─────────────────────────────────┘
40 */
41
42struct libwifi_assoc_resp_fixed_parameters {
43 uint16_t capabilities_information;
44 uint16_t status_code;
45 uint16_t association_id;
46} __attribute__((packed));
47
48struct libwifi_assoc_resp {
49 struct libwifi_mgmt_unordered_frame_header frame_header;
50 struct libwifi_assoc_resp_fixed_parameters fixed_parameters;
51 struct libwifi_tagged_parameters tags;
52} __attribute__((packed));
53
54#endif /* LIBWIFI_CORE_ASSOCRESP_H */
diff --git a/src/libwifi/core/frame/management/atim.h b/src/libwifi/core/frame/management/atim.h new file mode 100644 index 0000000..18a01e2 --- /dev/null +++ b/src/libwifi/core/frame/management/atim.h
@@ -0,0 +1,33 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_ATIM_H
17#define LIBWIFI_CORE_ATIM_H
18
19#include "../frame.h"
20
21/**
22 * ATIM Frame Layout
23 * ─────────────────────────────────
24 * ┌─────────────────────────────────┐
25 * │ Header │ Bytes: 24
26 * └─────────────────────────────────┘
27 */
28
29struct libwifi_atim {
30 struct libwifi_mgmt_unordered_frame_header frame_header;
31};
32
33#endif /* LIBWIFI_CORE_ATIM_H */
diff --git a/src/libwifi/core/frame/management/authentication.h b/src/libwifi/core/frame/management/authentication.h new file mode 100644 index 0000000..c7707c6 --- /dev/null +++ b/src/libwifi/core/frame/management/authentication.h
@@ -0,0 +1,54 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_AUTH_H
17#define LIBWIFI_CORE_AUTH_H
18
19#include "../frame.h"
20#include "../tag.h"
21#include <stdint.h>
22
23/**
24 * Authentication Layout
25 * ─────────────────────────────────
26 * ┌─────────────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├─────────────────────────────────┤
29 * │ Fixed Parameters │ Bytes: 6
30 * │┌───────────────────────────────┐│
31 * ││ algorithm ││ Bytes: 2
32 * │├───────────────────────────────┤│
33 * ││ transaction ││ Bytes: 2
34 * │├───────────────────────────────┤│
35 * ││ status ││ Bytes: 2
36 * │└───────────────────────────────┘│
37 * ├─────────────────────────────────┤
38 * │ Tagged Parameters │ Bytes: Variable
39 * └─────────────────────────────────┘
40 */
41
42struct libwifi_auth_fixed_parameters {
43 uint16_t algorithm_number;
44 uint16_t transaction_sequence;
45 uint16_t status_code;
46} __attribute__((packed));
47
48struct libwifi_auth {
49 struct libwifi_mgmt_unordered_frame_header frame_header;
50 struct libwifi_auth_fixed_parameters fixed_parameters;
51 struct libwifi_tagged_parameters tags;
52} __attribute__((packed));
53
54#endif /* LIBWIFI_CORE_AUTH_H */
diff --git a/src/libwifi/core/frame/management/beacon.h b/src/libwifi/core/frame/management/beacon.h new file mode 100644 index 0000000..f5c4d72 --- /dev/null +++ b/src/libwifi/core/frame/management/beacon.h
@@ -0,0 +1,54 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_BEACON_H
17#define LIBWIFI_CORE_BEACON_H
18
19#include "../frame.h"
20#include "../tag.h"
21#include <stdint.h>
22
23/**
24 * Beacon Layout
25 * ──────────────────────────────
26 * ┌──────────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├──────────────────────────────┤
29 * │ Fixed Parameters │ Bytes: 12
30 * │┌────────────────────────────┐│
31 * ││ timestamp ││ Bytes: 4
32 * │├────────────────────────────┤│
33 * ││ interval ││ Bytes: 2
34 * │├────────────────────────────┤│
35 * ││ capabilities ││ Bytes: 2
36 * │└────────────────────────────┘│
37 * ├──────────────────────────────┤
38 * │ Tagged Parameters │ Bytes: Variable
39 * └──────────────────────────────┘
40 */
41
42struct libwifi_beacon_fixed_parameters {
43 uint64_t timestamp;
44 uint16_t beacon_interval;
45 uint16_t capabilities_information;
46} __attribute__((packed));
47
48struct libwifi_beacon {
49 struct libwifi_mgmt_unordered_frame_header frame_header;
50 struct libwifi_beacon_fixed_parameters fixed_parameters;
51 struct libwifi_tagged_parameters tags;
52} __attribute__((packed));
53
54#endif /* LIBWIFI_CORE_BEACON_H */
diff --git a/src/libwifi/core/frame/management/common.h b/src/libwifi/core/frame/management/common.h new file mode 100644 index 0000000..1f5d042 --- /dev/null +++ b/src/libwifi/core/frame/management/common.h
@@ -0,0 +1,101 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_COMMON_H
17#define LIBWIFI_CORE_COMMON_H
18
19#include "../../misc/security.h"
20#include "../tag.h"
21#include <stdint.h>
22#include <stdlib.h>
23
24#define LIBWIFI_BSS 0
25#define LIBWIFI_STA 1
26
27/*
28 * A libwifi_bss struct is used as a common model for BSS / APs, and can be derived
29 * from parsed frames or used to generate new frames. Fields may be optional.
30 *
31 * transmitter - The transmitter MAC address
32 * receiver - The receiver MAC address
33 * bssid - BSSID MAC address
34 * ssid - AP SSID
35 * hidden - Hidden state boolean
36 * channel - BSS Channel
37 * wps - WPS state boolean
38 * encryption_info - Bitfield of encryption state, such as WPA version and ciphers
39 * signal - RSSI in dBm
40 * wpa_info - WPA1 information, present if encryption_info has the WPA1 bit set
41 * rsn_info - WPA2 and/or WPA3 information, present if encryption_info has WPA2 or WPA3 bit set
42 * tags - List of tagged parameters
43 */
44struct libwifi_bss {
45 unsigned char transmitter[6];
46 unsigned char receiver[6];
47 unsigned char bssid[6];
48 char ssid[33];
49 int8_t hidden;
50 uint8_t channel;
51 uint8_t wps;
52 uint64_t encryption_info;
53 int signal;
54 struct libwifi_wpa_info wpa_info;
55 struct libwifi_rsn_info rsn_info;
56 struct libwifi_tagged_parameters tags;
57};
58
59/*
60 * A libwifi_bss can be populated with dynamically allocated tags, which must be free'd by
61 * the user application to avoid memory leaks. This function provides an easy wrapper for any
62 * libwifi allocations made.
63 */
64static inline void libwifi_free_bss(struct libwifi_bss *bss) {
65 free(bss->tags.parameters);
66}
67
68/*
69 * A libwifi_sta struct is used as a common model for stations, roaming or associated,
70 * and can be derived from parsed frames or used to generate new frames. Fields may be optional.
71 *
72 * channel - BSS Channel
73 * randomized - Client has a likely randomized MAC
74 * transmitter - The transmitter MAC address
75 * receiver - The receiver MAC address
76 * bssid - BSSID MAC address
77 * ssid - AP SSID
78 * broadcast_ssid - STA is broadcasting for SSID
79 * tags - List of tagged parameters
80 */
81struct libwifi_sta {
82 uint8_t channel;
83 uint8_t randomized;
84 unsigned char transmitter[6];
85 unsigned char receiver[6];
86 unsigned char bssid[6];
87 char ssid[33];
88 uint8_t broadcast_ssid;
89 struct libwifi_tagged_parameters tags;
90};
91
92/*
93 * A libwifi_sta can be populated with dynamically allocated tags, which must be free'd by
94 * the user application to avoid memory leaks. This function provides an easy wrapper for any
95 * libwifi allocations made.
96 */
97static inline void libwifi_free_sta(struct libwifi_sta *sta) {
98 free(sta->tags.parameters);
99}
100
101#endif /* LIBWIFI_CORE_COMMON_H */
diff --git a/src/libwifi/core/frame/management/deauthentication.h b/src/libwifi/core/frame/management/deauthentication.h new file mode 100644 index 0000000..a01de7c --- /dev/null +++ b/src/libwifi/core/frame/management/deauthentication.h
@@ -0,0 +1,55 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_DEAUTH_H
17#define LIBWIFI_CORE_DEAUTH_H
18
19#include "../frame.h"
20#include "../tag.h"
21#include <stdint.h>
22
23/**
24 * Deauthentication Layout
25 * ──────────────────────────
26 * ┌──────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├──────────────────────────┤
29 * │ Fixed Parameters │ Bytes: 2
30 * │┌────────────────────────┐│
31 * ││ reason code ││ Bytes: 2
32 * │└────────────────────────┘│
33 * ├──────────────────────────┤
34 * │ Tagged Parameters │ Bytes: Variable
35 * └──────────────────────────┘
36 */
37
38struct libwifi_deauth_fixed_parameters {
39 uint16_t reason_code;
40} __attribute__((packed));
41
42struct libwifi_deauth {
43 struct libwifi_mgmt_unordered_frame_header frame_header;
44 struct libwifi_deauth_fixed_parameters fixed_parameters;
45 struct libwifi_tagged_parameters tags;
46} __attribute__((packed));
47
48struct libwifi_parsed_deauth {
49 int ordered;
50 union libwifi_mgmt_frame_header frame_header;
51 struct libwifi_deauth_fixed_parameters fixed_parameters;
52 struct libwifi_tagged_parameters tags;
53} __attribute__((packed));
54
55#endif /* LIBWIFI_CORE_DEAUTH_H */
diff --git a/src/libwifi/core/frame/management/disassociation.h b/src/libwifi/core/frame/management/disassociation.h new file mode 100644 index 0000000..ec6752a --- /dev/null +++ b/src/libwifi/core/frame/management/disassociation.h
@@ -0,0 +1,55 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_DISASSOC_H
17#define LIBWIFI_CORE_DISASSOC_H
18
19#include "../frame.h"
20#include "../tag.h"
21#include <stdint.h>
22
23/**
24 * Disassociation Layout
25 * ──────────────────────────
26 * ┌──────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├──────────────────────────┤
29 * │ Fixed Parameters │ Bytes: 2
30 * │┌────────────────────────┐│
31 * ││ reason code ││ Bytes: 2
32 * │└────────────────────────┘│
33 * ├──────────────────────────┤
34 * │ Tagged Parameters │ Bytes: Variable
35 * └──────────────────────────┘
36 */
37
38struct libwifi_disassoc_fixed_parameters {
39 uint16_t reason_code;
40} __attribute__((packed));
41
42struct libwifi_disassoc {
43 struct libwifi_mgmt_unordered_frame_header frame_header;
44 struct libwifi_disassoc_fixed_parameters fixed_parameters;
45 struct libwifi_tagged_parameters tags;
46} __attribute__((packed));
47
48struct libwifi_parsed_disassoc {
49 int ordered;
50 union libwifi_mgmt_frame_header frame_header;
51 struct libwifi_disassoc_fixed_parameters fixed_parameters;
52 struct libwifi_tagged_parameters tags;
53} __attribute__((packed));
54
55#endif /* LIBWIFI_CORE_DISASSOC_H */
diff --git a/src/libwifi/core/frame/management/probe_request.h b/src/libwifi/core/frame/management/probe_request.h new file mode 100644 index 0000000..c54cafa --- /dev/null +++ b/src/libwifi/core/frame/management/probe_request.h
@@ -0,0 +1,38 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_PROBEREQ_H
17#define LIBWIFI_CORE_PROBEREQ_H
18
19#include "../frame.h"
20#include "../tag.h"
21#include <stdint.h>
22
23/**
24 * Probe Request Layout
25 * ──────────────────────────
26 * ┌──────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├──────────────────────────┤
29 * │ Tagged Parameters │ Bytes: Variable
30 * └──────────────────────────┘
31 */
32
33struct libwifi_probe_req {
34 struct libwifi_mgmt_unordered_frame_header frame_header;
35 struct libwifi_tagged_parameters tags;
36} __attribute__((packed));
37
38#endif /* LIBWIFI_CORE_PROBEREQ_H */
diff --git a/src/libwifi/core/frame/management/probe_response.h b/src/libwifi/core/frame/management/probe_response.h new file mode 100644 index 0000000..f89ae6f --- /dev/null +++ b/src/libwifi/core/frame/management/probe_response.h
@@ -0,0 +1,54 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_PROBERESP_H
17#define LIBWIFI_CORE_PROBERESP_H
18
19#include "../frame.h"
20#include "../tag.h"
21#include <stdint.h>
22
23/**
24 * Probe Response Layout
25 * ──────────────────────────────
26 * ┌──────────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├──────────────────────────────┤
29 * │ Fixed Parameters │ Bytes: 12
30 * │┌────────────────────────────┐│
31 * ││ timestamp ││ Bytes: 4
32 * │├────────────────────────────┤│
33 * ││ interval ││ Bytes: 2
34 * │├────────────────────────────┤│
35 * ││ capabilities ││ Bytes: 2
36 * │└────────────────────────────┘│
37 * ├──────────────────────────────┤
38 * │ Tagged Parameters │ Bytes: Variable
39 * └──────────────────────────────┘
40 */
41
42struct libwifi_probe_resp_fixed_parameters {
43 uint64_t timestamp;
44 uint16_t probe_resp_interval;
45 uint16_t capabilities_information;
46} __attribute__((packed));
47
48struct libwifi_probe_resp {
49 struct libwifi_mgmt_unordered_frame_header frame_header;
50 struct libwifi_probe_resp_fixed_parameters fixed_parameters;
51 struct libwifi_tagged_parameters tags;
52} __attribute__((packed));
53
54#endif /* LIBWIFI_CORE_PROBERESP_H */
diff --git a/src/libwifi/core/frame/management/reassoc_request.h b/src/libwifi/core/frame/management/reassoc_request.h new file mode 100644 index 0000000..fe5784c --- /dev/null +++ b/src/libwifi/core/frame/management/reassoc_request.h
@@ -0,0 +1,54 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_REASSOCREQ_H
17#define LIBWIFI_CORE_REASSOCREQ_H
18
19#include "../frame.h"
20#include "../tag.h"
21#include <stdint.h>
22
23/**
24 * Reassociation Request Layout
25 * ───────────────────────────────
26 * ┌───────────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├───────────────────────────────┤
29 * │ Fixed Parameters │ Bytes: 10
30 * │┌─────────────────────────────┐│
31 * ││ capabilities ││ Bytes: 2
32 * │├─────────────────────────────┤│
33 * ││ interval ││ Bytes: 2
34 * │├─────────────────────────────┤│
35 * ││ current AP address ││ Bytes: 6
36 * │└─────────────────────────────┘│
37 * ├───────────────────────────────┤
38 * │ Tagged Parameters │ Bytes: Variable
39 * └───────────────────────────────┘
40 */
41
42struct libwifi_reassoc_req_fixed_parameters {
43 uint16_t capabilities_information;
44 uint16_t listen_interval;
45 unsigned char current_ap_address[6];
46} __attribute__((packed));
47
48struct libwifi_reassoc_req {
49 struct libwifi_mgmt_unordered_frame_header frame_header;
50 struct libwifi_reassoc_req_fixed_parameters fixed_parameters;
51 struct libwifi_tagged_parameters tags;
52} __attribute__((packed));
53
54#endif /* LIBWIFI_CORE_REASSOCREQ_H */
diff --git a/src/libwifi/core/frame/management/reassoc_response.h b/src/libwifi/core/frame/management/reassoc_response.h new file mode 100644 index 0000000..c0b7f62 --- /dev/null +++ b/src/libwifi/core/frame/management/reassoc_response.h
@@ -0,0 +1,54 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_REASSOCRESP_H
17#define LIBWIFI_CORE_REASSOCRESP_H
18
19#include "../frame.h"
20#include "../tag.h"
21#include <stdint.h>
22
23/**
24 * Reassociation Response Layout
25 * ──────────────────────────────────
26 * ┌──────────────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├──────────────────────────────────┤
29 * │ Fixed Parameters │ Bytes: 6
30 * │┌────────────────────────────────┐│
31 * ││ capabilities ││ Bytes: 2
32 * │├────────────────────────────────┤│
33 * ││ status ││ Bytes: 2
34 * │├────────────────────────────────┤│
35 * ││ association id ││ Bytes: 2
36 * │└────────────────────────────────┘│
37 * ├──────────────────────────────────┤
38 * │ Tagged Parameters │ Bytes: Variable
39 * └──────────────────────────────────┘
40 */
41
42struct libwifi_reassoc_resp_fixed_parameters {
43 uint16_t capabilities_information;
44 uint16_t status_code;
45 uint16_t association_id;
46} __attribute__((packed));
47
48struct libwifi_reassoc_resp {
49 struct libwifi_mgmt_unordered_frame_header frame_header;
50 struct libwifi_reassoc_resp_fixed_parameters fixed_parameters;
51 struct libwifi_tagged_parameters tags;
52} __attribute__((packed));
53
54#endif /* LIBWIFI_CORE_REASSOCRESP_H */
diff --git a/src/libwifi/core/frame/management/timing_ad.h b/src/libwifi/core/frame/management/timing_ad.h new file mode 100644 index 0000000..d0a8ac3 --- /dev/null +++ b/src/libwifi/core/frame/management/timing_ad.h
@@ -0,0 +1,82 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_TIMINGAD_H
17#define LIBWIFI_CORE_TIMINGAD_H
18
19#include <stdint.h>
20#include "../frame.h"
21#include "../tag.h"
22
23/**
24 * Timing Advertisement Layout
25 * ──────────────────────────────────
26 * ┌──────────────────────────────────┐
27 * │ Header │ Bytes: 24
28 * ├──────────────────────────────────┤
29 * │ Fixed Parameters │ Bytes: 6
30 * │┌────────────────────────────────┐│
31 * ││ timestamp ││ Bytes: 8
32 * │├────────────────────────────────┤│
33 * ││ measurement pilot interval ││ Bytes: 1
34 * │├────────────────────────────────┤│
35 * ││ beacon interval ││ Bytes: 2
36 * │├────────────────────────────────┤│
37 * ││ capabilities information ││ Bytes: 2
38 * │├────────────────────────────────┤│
39 * ││ country code ││ Bytes: 3
40 * │├────────────────────────────────┤│
41 * ││ maxmimum regulatory power ││ Bytes: 2
42 * │├────────────────────────────────┤│
43 * ││ maximum transmit power ││ Bytes: 1
44 * │├────────────────────────────────┤│
45 * ││ transmit power used ││ Bytes: 1
46 * │├────────────────────────────────┤│
47 * ││ noise floor ││ Bytes: 1
48 * │└────────────────────────────────┘│
49 * ├──────────────────────────────────┤
50 * │ Tagged Parameters │ Bytes: Variable
51 * │┌────────────────────────────────┐│
52 * ││ timing advert fields ││ Bytes: 17
53 * │└────────────────────────────────┘│
54 * └──────────────────────────────────┘
55 */
56
57struct libwifi_timing_advert_fields {
58 uint8_t timing_capabilities;
59 unsigned char time_value[10];
60 unsigned char time_error[5];
61 unsigned char time_update[1];
62} __attribute__((packed));
63
64struct libwifi_timing_advert_fixed_params {
65 uint64_t timestamp;
66 uint8_t measurement_pilot_interval;
67 uint16_t beacon_interval;
68 uint16_t capabilities_information;
69 char country[3];
70 uint16_t max_reg_power;
71 uint8_t max_tx_power;
72 uint8_t tx_power_used;
73 uint8_t noise_floor;
74} __attribute__((packed));
75
76struct libwifi_timing_advert {
77 struct libwifi_mgmt_unordered_frame_header frame_header;
78 struct libwifi_timing_advert_fixed_params fixed_parameters;
79 struct libwifi_tagged_parameters tags;
80} __attribute__((packed));
81
82#endif /* LIBWIFI_CORE_TIMINGAD_H */
diff --git a/src/libwifi/core/frame/tag.c b/src/libwifi/core/frame/tag.c new file mode 100644 index 0000000..9dec547 --- /dev/null +++ b/src/libwifi/core/frame/tag.c
@@ -0,0 +1,131 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "tag.h"
17#include "tag_iterator.h"
18
19#include <errno.h>
20#include <stdint.h>
21#include <stdlib.h>
22#include <string.h>
23#include <sys/types.h>
24
25int libwifi_add_tag(struct libwifi_tagged_parameters *tags, struct libwifi_tagged_parameter *tag) {
26 // Calculate the total length of the new tag
27 size_t parameter_len = sizeof(struct libwifi_tag_header) + tag->header.tag_len;
28
29 // Initalise the supplied tagged parameters list, if not already done.
30 // Otherwise, extend the allocation to fit the new tag.
31 if (tags->length == 0) {
32 tags->parameters = malloc(parameter_len);
33 if (tags->parameters == NULL) {
34 return -ENOMEM;
35 }
36 } else {
37 void *buf = realloc(tags->parameters, tags->length + parameter_len);
38 if (buf == NULL) {
39 return -ENOMEM;
40 }
41 tags->parameters = buf;
42 }
43
44 // Append the new tag to the list
45 memcpy(tags->parameters + tags->length, &tag->header, sizeof(struct libwifi_tag_header));
46 memcpy(tags->parameters + tags->length + sizeof(struct libwifi_tag_header), tag->body,
47 tag->header.tag_len);
48
49 // Update total tagged parameters length
50 tags->length += parameter_len;
51
52 return 0;
53}
54
55int libwifi_remove_tag(struct libwifi_tagged_parameters *tags, int tag_number) {
56 // Initalise a tag iterator
57 struct libwifi_tag_iterator it = {0};
58 if (libwifi_tag_iterator_init(&it, tags->parameters, tags->length) != 0) {
59 return -EINVAL;
60 }
61
62 // Loop through the tagged parameters list until landing on the supplied tag number
63 do {
64 if (it.tag_header->tag_num == tag_number) {
65 // Calculate the length of the tag we're removing, so that we know
66 // how many bytes to shrink the tagged parameter list by
67 size_t copy_len = tags->length -
68 (it.tag_data - tags->parameters) -
69 (it.tag_header->tag_len + sizeof(struct libwifi_tag_header));
70 memcpy(tags->parameters, it.tag_data + it.tag_header->tag_len, copy_len);
71 size_t new_len = tags->length - it.tag_header->tag_len - sizeof(struct libwifi_tag_header);
72 tags->parameters = realloc(tags->parameters, new_len);
73 tags->length = new_len;
74 break;
75 }
76 } while (libwifi_tag_iterator_next(&it) != -1);
77
78 return 0;
79}
80
81size_t libwifi_create_tag(struct libwifi_tagged_parameter *tagged_parameter, int tag_number,
82 const unsigned char *tag_data, size_t tag_length) {
83 // Initalise the supplied tagged parameter struct
84 memset(tagged_parameter, 0, sizeof(struct libwifi_tagged_parameter));
85 tagged_parameter->header.tag_len = tag_length;
86 tagged_parameter->header.tag_num = tag_number;
87 tagged_parameter->body = malloc(tag_length);
88 if (tagged_parameter->body == NULL) {
89 return -ENOMEM;
90 }
91 memset(tagged_parameter->body, 0, tag_length);
92
93 // Copy the supplied data into the new tag body
94 memcpy(tagged_parameter->body, tag_data, tag_length);
95
96 return sizeof(struct libwifi_tag_header) + tag_length;
97}
98
99void libwifi_free_tag(struct libwifi_tagged_parameter *tagged_parameter) {
100 free(tagged_parameter->body);
101}
102
103size_t libwifi_dump_tag(struct libwifi_tagged_parameter *tag, unsigned char *buf, size_t buf_len) {
104 if (tag->header.tag_len > buf_len) {
105 return -EINVAL;
106 }
107
108 size_t offset = 0;
109
110 memcpy(buf, &tag->header, sizeof(struct libwifi_tag_header));
111 offset += sizeof(struct libwifi_tag_header);
112 memcpy(buf + offset, tag->body, tag->header.tag_len);
113 offset += tag->header.tag_len;
114
115 return sizeof(struct libwifi_tag_header) + tag->header.tag_len;
116}
117
118int libwifi_quick_add_tag(struct libwifi_tagged_parameters *tags, int tag_number,
119 const unsigned char *tag_data, size_t tag_length) {
120 struct libwifi_tagged_parameter tagged_parameter = {0};
121
122 size_t ret = libwifi_create_tag(&tagged_parameter, tag_number, tag_data, tag_length);
123 if (ret <= 0) {
124 return ret;
125 }
126
127 libwifi_add_tag(tags, &tagged_parameter);
128 libwifi_free_tag(&tagged_parameter);
129
130 return 0;
131}
diff --git a/src/libwifi/core/frame/tag.h b/src/libwifi/core/frame/tag.h new file mode 100644 index 0000000..02928fe --- /dev/null +++ b/src/libwifi/core/frame/tag.h
@@ -0,0 +1,306 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_TAG_H
17#define LIBWIFI_CORE_TAG_H
18
19#include <stdint.h>
20#include <sys/types.h>
21
22/* 802.11 Tagged Parameter values */
23enum libwifi_tag_numbers {
24 TAG_SSID = 0,
25 TAG_SUPP_RATES = 1,
26 // Reserved 2
27 TAG_DS_PARAMETER = 3,
28 TAG_CF_PARAMETER = 4,
29 TAG_TIM = 5,
30 TAG_BSS_PARAMETERS = 6,
31 TAG_COUNTRY = 7,
32 // Reserved 8-9
33 TAG_REQUEST = 10,
34 TAG_BSS_LOAD = 11,
35 TAG_EDCA_PARAMETERS = 12,
36 TAG_TSPEC = 13,
37 TAG_TCLAS = 14,
38 TAG_SCHEDULE = 15,
39 TAG_CHALLENGE_TEXT = 16,
40 // Reserved 17-31
41 TAG_POWER_CONSTRAINT = 32,
42 TAG_POWER_CAPABILITY = 33,
43 TAG_TPC_REQUEST = 34,
44 TAG_TPC_REPORT = 35,
45 TAG_SUPPORTED_CHANNELS = 36,
46 TAG_CHANNEL_SWITCH_ANNOUNCEMENT = 37,
47 TAG_MEASUREMENT_REQUEST = 38,
48 TAG_MEASUREMENT_REPORT = 39,
49 TAG_QUIET = 40,
50 TAG_IBSS_DFS = 41,
51 TAG_ERP = 42,
52 TAG_TS_DELAY = 43,
53 TAG_TCLAS_PROCESSING = 44,
54 TAG_HT_CAPABILITIES = 45,
55 TAG_QOS_CAPABILITY = 46,
56 // Reserved 47
57 TAG_RSN = 48,
58 // Reserved 49
59 TAG_EXTENDED_SUPPORTED_RATES = 50,
60 TAG_AP_CHANNEL_REPORT = 51,
61 TAG_NEIGHBOR_REPORT = 52,
62 TAG_RCPI = 53,
63 TAG_MOBILITY_DOMAIN = 54,
64 TAG_FAST_BSS_TRANSITION = 55,
65 TAG_TIMEOUT_INTERVAL = 56,
66 TAG_RIC_DATA = 57,
67 TAG_DSE_REGISTERED_LOCATION = 58,
68 TAG_SUPPORTED_OPERATING_CLASSES = 59,
69 TAG_EXTENDED_CHANNEL_SWITCH_ANNOUNCEMENT = 60,
70 TAG_HT_OPERATION = 61,
71 TAG_SECONDARY_CHANNEL_OFFSET = 62,
72 TAG_BSS_AVERAGE_ACCESS_DELAY = 63,
73 TAG_ANTENNA = 64,
74 TAG_RSNI = 65,
75 TAG_MEASUREMENT_PILOT_TRANSMISSION = 66,
76 TAG_BSS_AVAILABLE_ADMISSION_CAPACITY = 67,
77 TAG_BSS_AC_ACCESS_DELAY = 68,
78 TAG_TIME_ADVERTISEMENT = 69,
79 TAG_RM_ENABLED_CAPABILITIES = 70,
80 TAG_MULTIPLE_BSSID = 71,
81 TAG_BSS_COEXISTENCE = 72,
82 TAG_BSS_INTOLERANT_CHANNEL_REPORT = 73,
83 TAG_OVERLAPPING_BSS_PARAMETERS = 74,
84 TAG_RIC_DESCRIPTOR = 75,
85 TAG_MANAGEMENT_MIC = 76,
86 // Undefined 77
87 TAG_EVENT_REQUEST = 78,
88 TAG_EVENT_REPORT = 79,
89 TAG_DIAGNOSTIC_REQUEST = 80,
90 TAG_DIAGNOSTIC_REPORT = 81,
91 TAG_LOCATION_PARAMTERS = 82,
92 TAG_NONTRANSMITTED_BSSID_CAPABILITY = 83,
93 TAG_SSID_LIST = 84,
94 TAG_MULTIPLE_BSSID_INDEX = 85,
95 TAG_FMS_DESCRIPTOR = 86,
96 TAG_FMS_REQUEST = 87,
97 TAG_FMS_RESPONSE = 88,
98 TAG_QOS_TRAFFIC_CAPABILITY = 89,
99 TAG_BSS_MAX_IDLE_PERIOD = 90,
100 TAG_TFS_REQUEST = 91,
101 TAG_TFS_RESPONSE = 92,
102 TAG_WNM_SLEEP_MODE = 93,
103 TAG_TIM_BROADCAST_REQUEST = 94,
104 TAG_TIM_BROADCAST_RESPONSE = 95,
105 TAG_COLLOCATED_INTERFERENCE_REPORT = 96,
106 TAG_CHANNEL_USAGE = 97,
107 TAG_TIME_ZONE = 98,
108 TAG_DMS_REQUEST = 99,
109 TAG_DMS_RESPONSE = 100,
110 TAG_LINK_IDENTIFIER = 101,
111 TAG_WAKEUP_SCHEDULE = 102,
112 // Undefined 103
113 TAG_CHANNEL_SWITCH_TIMING = 104,
114 TAG_PTI_CONTROL = 105,
115 TAG_TPU_BUFFER_STATUS = 106,
116 TAG_INTERWORKING = 107,
117 TAG_ADVERTISEMENT_PROTOCOL = 108,
118 TAG_EXPEDITED_BANDWIDTH_REQUEST = 109,
119 TAG_QOS_MAP = 110,
120 TAG_ROAMING_CONSORTIUM = 111,
121 TAG_EMERGENCY_ALERT_IDENTIFIER = 112,
122 TAG_MESH_CONFIGURATION = 113,
123 TAG_MESH_ID = 114,
124 TAG_MESH_LINK_METRIC_REPORT = 115,
125 TAG_CONGESTION_NOTIFICATION = 116,
126 TAG_MESH_PEERING_MANAGEMENT = 117,
127 TAG_MESH_CHANNEL_SWITCH_PARAMETERS = 118,
128 TAG_MESH_AWAKE_WINDOW = 119,
129 TAG_BEACON_TIMING = 120,
130 TAG_MCCAOP_SETUP_REQUEST = 121,
131 TAG_MCCAOP_SETUP_REPLY = 122,
132 TAG_MCCAOP_ADVERTISEMENT = 123,
133 TAG_MCCAOP_TEARDOWN = 124,
134 TAG_GANN = 125,
135 TAG_RANN = 126,
136 TAG_EXTENDED_CAPABILITIES = 127,
137 // Reserved 128-129
138 TAG_PREQ = 130,
139 TAG_PREP = 131,
140 TAG_PERR = 132,
141 // Reserved 133-136
142 TAG_PXU = 137,
143 TAG_PXUC = 138,
144 TAG_AUTHENTICATED_MESH_PEERING_EXCHANGE = 139,
145 TAG_MIC = 140,
146 TAG_DESTINATION_URI = 141,
147 TAG_U_APSD_COEXISTENCE = 142,
148 TAG_DMG_WAKEUP_SCHEDULE = 143,
149 TAG_EXTENDED_SCHEDULE = 144,
150 TAG_STA_AVAILABILITY = 145,
151 TAG_DMG_TSPEC = 146,
152 TAG_NEXT_DMG_ATI = 147,
153 // Reserved 149-150
154 TAG_DMG_OPERATION = 151,
155 TAG_DMG_BSS_PARAMETER_CHANGE = 152,
156 TAG_DMG_BEAM_REFINEMENT = 153,
157 TAG_CHANNEL_MEASUREMENT_FEEDBACK = 154,
158 // Reserved 155-156
159 TAG_AWAKE_WINDOW = 157,
160 TAG_MULTI_BAND = 158,
161 TAG_ADDBA_EXTENSION = 159,
162 TAG_NEXTPCP_LIST = 160,
163 TAG_PCP_HANDOVER = 161,
164 TAG_DMG_LINK_MARGIN = 162,
165 TAG_SWITCHING_STREAM = 163,
166 TAG_SESSION_TRANSITION = 164,
167 TAG_DYNAMIC_TONE_PAIRING_REPORT = 165,
168 TAG_CLUSTER_REPORT = 166,
169 TAG_RELAY_CAPABILITIES = 167,
170 TAG_RELAY_TRANSFER_PARAMETER_SET = 168,
171 TAG_BEAMLINK_MAINTENANCE = 169,
172 TAG_MULTIPLE_MAC_SUBLAYERS = 170,
173 TAG_U_PID = 171,
174 TAG_DMG_LINK_ADAPTATION_ACKNOWLEDGEMENT = 172,
175 // Reserved 173
176 TAG_MCCAOP_ADVERTISEMENT_OVERVIEW = 174,
177 TAG_QUIET_PERIOD_REQUEST = 175,
178 // Reserved 176
179 TAG_QUIET_PERIOD_RESPONSE = 177,
180 // Reserved 178-180
181 TAG_QMF_POLICY = 181,
182 TAG_ECAPC_POLICY = 182,
183 TAG_CLUSTER_TIME_OFFSET = 183,
184 TAG_INTRA_ACCESS_CATEGORY_PRIORITY = 184,
185 TAG_SCS_DESCRIPTOR = 185,
186 TAG_QLOAD_REPORT = 186,
187 TAG_HCCA_TXOP_UPDATE_COUNT = 187,
188 TAG_HIGHER_LAYER_STREAM_ID = 188,
189 TAG_GCR_GROUP_ADDRESS = 189,
190 TAG_ANTENNA_SECTOR_ID_PATTERN = 190,
191 TAG_VHT_CAPABILITIES = 191,
192 TAG_VHT_OPERATION = 192,
193 TAG_EXTENDED_BSS_LOAD = 193,
194 TAG_WIDE_BANDWIDTH_CHANNEL_SWITCH = 194,
195 TAG_TRANSMIT_POWER_ENVELOPE = 195,
196 TAG_CHANNEL_SWITCH_WRAPPER = 196,
197 TAG_AID = 197,
198 TAG_QUIET_CHANNEL = 198,
199 TAG_UPSIM = 200,
200 TAG_REDUCED_NEIGHBOR_REPORT = 201,
201 TAG_TVHT_OPERATION = 202,
202 // Reserved 203
203 TAG_DEVICE_LOCATION = 204,
204 TAG_WHITE_SPACE_MAP = 205,
205 TAG_FINE_TIMING_MEASUREMENT_PARAMETERS = 206,
206 // Reserved 207-220
207 TAG_VENDOR_SPECIFIC = 221,
208 // Reserved 222-254
209};
210
211/**
212 * A tagged parameter always consists of a tag number and length
213 */
214struct libwifi_tag_header {
215 uint8_t tag_num;
216 uint8_t tag_len;
217} __attribute__((packed));
218
219/*
220 * A tagged parameter will include a header as well as some body,
221 * depending on the tag number. The length of the body buffer is
222 * determined with the header.tag_len variable.
223 */
224struct libwifi_tagged_parameter {
225 struct libwifi_tag_header header;
226 unsigned char *body;
227} __attribute__((packed));
228
229/*
230 * A collection of total tagged parameters
231 */
232struct libwifi_tagged_parameters {
233 size_t length;
234 unsigned char *parameters;
235} __attribute__((packed));
236
237/*
238 * Vendor specific tagged parameters have an OUI and Sub-Type
239 * to determine their use
240 */
241struct libwifi_tag_vendor_header {
242 unsigned char oui[3];
243 int8_t type;
244} __attribute__((packed));
245
246/**
247 * Add a tagged parameter to a list of frame tagged parameters.
248 *
249 * @param tagged_parameters A management frame's tagged parameters
250 * @param tagged_parameter The new tagged parameter
251 */
252int libwifi_add_tag(struct libwifi_tagged_parameters *tagged_parameters,
253 struct libwifi_tagged_parameter *tagged_parameter);
254
255/**
256 * Remove a tagged parameter from a list of frame tagged parameters.
257 *
258 * @param tagged_parameters A management frame's tagged parameters
259 * @param tag_number Number of the tag to remove
260 */
261int libwifi_remove_tag(struct libwifi_tagged_parameters *tagged_parameters, int tag_number);
262
263/**
264 * Create a tagged parameter from a tag number, length and data.
265 * This can be useful when generating tags on their own, for use with
266 * action frame body's.
267 *
268 * @param tagged_parameter A new tagged parameter struct
269 * @param tag_number Tagged parameter number
270 * @param tag_data The tag body
271 * @param tag_length Length of the tag body
272 * @return length of the created tag
273 */
274size_t libwifi_create_tag(struct libwifi_tagged_parameter *tagged_parameter, int tag_number,
275 const unsigned char *tag_data, size_t tag_length);
276
277/**
278 * Free a tagged parameters body
279 *
280 * @param tagged_parameter A used tagged parameter
281 */
282void libwifi_free_tag(struct libwifi_tagged_parameter *tagged_parameter);
283
284/**
285 * Dump a tagged parameter into a raw buffer, for use with other buffers
286 * or injection.
287 *
288 * @param tag A used tagged parameter struct
289 * @param buf A buffer for the raw data
290 * @param buf_len Length of buf
291 */
292size_t libwifi_dump_tag(struct libwifi_tagged_parameter *tag, unsigned char *buf, size_t buf_len);
293
294/**
295 * Add a tagged parameter via tag number and data to a management frame.
296 *
297 * @param tagged_parameters A management frame's tagged parameters
298 * @param tag_number Tagged parameter to add
299 * @param tag_data Data to copy into new tag
300 * @param tag_length Length of the new tag
301 * @return 0 on success, negative number on error
302 */
303int libwifi_quick_add_tag(struct libwifi_tagged_parameters *tagged_parameters, int tag_number,
304 const unsigned char *tag_data, size_t tag_length);
305
306#endif /* LIBWIFI_CORE_TAG_H */
diff --git a/src/libwifi/core/frame/tag_iterator.c b/src/libwifi/core/frame/tag_iterator.c new file mode 100644 index 0000000..c197752 --- /dev/null +++ b/src/libwifi/core/frame/tag_iterator.c
@@ -0,0 +1,55 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "tag_iterator.h"
17
18#include <errno.h>
19#include <stdio.h>
20#include <string.h>
21
22int libwifi_tag_iterator_init(struct libwifi_tag_iterator *it, const void *tags_start, size_t data_len) {
23 it->tag_header = (struct libwifi_tag_header *) tags_start;
24 if (it->tag_header->tag_len < 0) {
25 return -EINVAL;
26 }
27
28 it->tag_data = (unsigned char *) tags_start + sizeof(struct libwifi_tag_header);
29 it->_next_tag_header = (struct libwifi_tag_header *) (it->tag_data + it->tag_header->tag_len);
30 it->_frame_end = (unsigned char *) (tags_start) + data_len - 1;
31
32 return 0;
33}
34
35int libwifi_tag_iterator_next(struct libwifi_tag_iterator *it) {
36 unsigned char *next_th = (unsigned char *) it->_next_tag_header;
37 if (next_th >= it->_frame_end) {
38 return -1;
39 }
40
41 it->tag_header = it->_next_tag_header;
42 if (it->tag_header->tag_len < 0) {
43 return -1;
44 }
45
46 unsigned long bytes_left = (char *) it->_frame_end - (char *) it->tag_header;
47 if (it->tag_header->tag_len >= bytes_left) {
48 return -1;
49 }
50
51 it->tag_data = ((unsigned char *) (it->tag_header)) + sizeof(struct libwifi_tag_header);
52 it->_next_tag_header = (struct libwifi_tag_header *) (it->tag_data + it->tag_header->tag_len);
53
54 return it->tag_header->tag_num;
55}
diff --git a/src/libwifi/core/frame/tag_iterator.h b/src/libwifi/core/frame/tag_iterator.h new file mode 100644 index 0000000..ae2d4ba --- /dev/null +++ b/src/libwifi/core/frame/tag_iterator.h
@@ -0,0 +1,53 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_TAGITERATOR_H
17#define LIBWIFI_CORE_TAGITERATOR_H
18
19#include "../misc/byteswap.h"
20#include "frame.h"
21#include "tag.h"
22#include <stddef.h>
23
24/**
25 * A libwifi_tag_iterator is used to iterate through a list of tagged parameters
26 * in a wifi frame.
27 */
28struct libwifi_tag_iterator {
29 struct libwifi_tag_header *tag_header;
30 const unsigned char *tag_data;
31 struct libwifi_tag_header *_next_tag_header;
32 const unsigned char *_frame_end;
33};
34
35/**
36 * Initialise a libwifi frame tag iterator.
37 *
38 * @param it A libwifi tag iterator struct
39 * @param tags_start The beginning of a frame's tag data
40 * @param data_len The total length of the frame's tag data
41 * @return negative number on error, zero on success
42 */
43int libwifi_tag_iterator_init(struct libwifi_tag_iterator *it, const void *tags_start, size_t data_len);
44
45/**
46 * Iterate towards the next tagged parameter in a libwifi tag iterator.
47 *
48 * @param A libwifi tag iterator sturct, after being initalised
49 * @return The tag number of the next tag
50 */
51int libwifi_tag_iterator_next(struct libwifi_tag_iterator *it);
52
53#endif /* LIBWIFI_CORE_TAGITERATOR_H */
diff --git a/src/libwifi/core/misc/byteswap.h b/src/libwifi/core/misc/byteswap.h new file mode 100644 index 0000000..cab264f --- /dev/null +++ b/src/libwifi/core/misc/byteswap.h
@@ -0,0 +1,31 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_BYTESWAP_H
17#define LIBWIFI_CORE_BYTESWAP_H
18
19#include <byteswap.h>
20
21#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
22#define BYTESWAP16(x) x
23#define BYTESWAP32(x) x
24#define BYTESWAP64(x) x
25#else
26#define BYTESWAP16(x) (__bswap_16(x))
27#define BYTESWAP32(x) (__bswap_32(x))
28#define BYTESWAP64(x) (__bswap_32(x))
29#endif
30
31#endif /* LIBWIFI_CORE_BYTESWAP_H */
diff --git a/src/libwifi/core/misc/epoch.c b/src/libwifi/core/misc/epoch.c new file mode 100644 index 0000000..d043f06 --- /dev/null +++ b/src/libwifi/core/misc/epoch.c
@@ -0,0 +1,23 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "epoch.h"
17#include <time.h>
18
19unsigned long long libwifi_get_epoch(void) {
20 struct timespec spec;
21 clock_gettime(CLOCK_REALTIME, &spec);
22 return spec.tv_sec * 1000 + spec.tv_nsec / 1000;
23}
diff --git a/src/libwifi/core/misc/epoch.h b/src/libwifi/core/misc/epoch.h new file mode 100644 index 0000000..f8d312f --- /dev/null +++ b/src/libwifi/core/misc/epoch.h
@@ -0,0 +1,26 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_EPOCH_H
17#define LIBWIFI_CORE_EPOCH_H
18
19/**
20 * Get the current system time in epoch.
21 *
22 * @return current time in unix epoch.
23 */
24unsigned long long libwifi_get_epoch(void);
25
26#endif /* LIBWIFI_CORE_EPOCH_H */
diff --git a/src/libwifi/core/misc/llc.h b/src/libwifi/core/misc/llc.h new file mode 100644 index 0000000..9c8350d --- /dev/null +++ b/src/libwifi/core/misc/llc.h
@@ -0,0 +1,33 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_LLC_H
17#define LIBWIFI_CORE_LLC_H
18
19#include <stdint.h>
20
21#define XEROX_OUI "\x00\x00\x00"
22
23#define LLC_TYPE_AUTH 0x888E
24
25struct libwifi_logical_link_ctrl {
26 uint8_t dsap;
27 uint8_t ssap;
28 uint8_t control;
29 unsigned char oui[3];
30 uint16_t type;
31} __attribute__((packed));
32
33#endif /* LIBWIFI_CORE_LLC_H */
diff --git a/src/libwifi/core/misc/radiotap.h b/src/libwifi/core/misc/radiotap.h new file mode 100644 index 0000000..85ed7b8 --- /dev/null +++ b/src/libwifi/core/misc/radiotap.h
@@ -0,0 +1,83 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_RADIOTAP_H
17#define LIBWIFI_CORE_RADIOTAP_H
18
19#include <stdint.h>
20
21#define LIBWIFI_MAX_RADIOTAP_LEN 128
22#define LIBWIFI_MAX_RADIOTAP_ANTENNAS 16
23
24/**
25 * A channel field in radiotap consists of a 2-byte wide flags
26 * sub-field and a 2-byte wide frequency field
27 */
28struct libwifi_radiotap_channel {
29 uint16_t flags;
30 uint16_t freq;
31} __attribute__((packed));
32
33/**
34 * The radiotap antenna field consists of an antenna number and signal in dBm
35 */
36struct libwifi_radiotap_antenna {
37 uint8_t antenna_number;
38 int8_t signal;
39} __attribute__((packed));
40
41/**
42 * The radiotap MCS field is made up of 3 2-byte fields.
43 */
44struct libwifi_radiotap_mcs {
45 uint8_t known;
46 uint8_t flags;
47 uint8_t mcs;
48} __attribute__((packed));
49
50/**
51 * The radiotap timestamp field consists of a timestamp field, accuracy, unit and flags.
52 */
53struct libwifi_radiotap_timestamp {
54 uint64_t timestamp;
55 uint16_t accuracy;
56 uint8_t unit;
57 uint8_t flags;
58} __attribute__((packed));
59
60struct libwifi_radiotap_info {
61 // Header
62 uint32_t present;
63 // Body
64 struct libwifi_radiotap_channel channel;
65 int8_t rate_raw;
66 float rate;
67 uint8_t antenna_count;
68 struct libwifi_radiotap_antenna antennas[LIBWIFI_MAX_RADIOTAP_ANTENNAS];
69 int8_t signal;
70 uint8_t flags;
71 uint32_t extended_flags;
72 uint16_t rx_flags;
73 uint16_t tx_flags;
74 struct libwifi_radiotap_mcs mcs;
75 int8_t tx_power;
76 struct libwifi_radiotap_timestamp timestamp;
77 uint8_t rts_retries;
78 uint8_t data_retries;
79 // Other
80 uint8_t length;
81} __attribute__((packed));
82
83#endif /* LIBWIFI_CORE_RADIOTAP_H */
diff --git a/src/libwifi/core/misc/security.h b/src/libwifi/core/misc/security.h new file mode 100644 index 0000000..6d97b13 --- /dev/null +++ b/src/libwifi/core/misc/security.h
@@ -0,0 +1,289 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_SECURITY_H
17#define LIBWIFI_CORE_SECURITY_H
18
19#include <stdint.h>
20
21/* 802.1X Key Information Field Values */
22#define EAPOL_KEY_INFO_M1 0x008A
23#define EAPOL_KEY_INFO_M2 0x010A
24#define EAPOL_KEY_INFO_M3 0x13CA
25#define EAPOL_KEY_INFO_M4 0x030A
26
27/* Sane maximum value for Cipher Suite Count */
28#define LIBWIFI_MAX_CIPHER_SUITES 6
29
30/* Cipher Suite OUIs for WPA and RSN */
31#define MICROSOFT_OUI "\x00\x50\xF2"
32#define CIPHER_SUITE_OUI "\x00\x0F\xAC"
33
34/* Common Microsoft Vendor Types */
35#define MICROSOFT_OUI_TYPE_WPA 1
36#define MICROSOFT_OUI_TYPE_WMM 2
37#define MICROSOFT_OUI_TYPE_WPS 4
38
39/* Cipher Suite Values */
40#define CIPHER_SUITE_GROUP 0 /* WPA1/2 */
41#define CIPHER_SUITE_WEP40 1 /* WEP */
42#define CIPHER_SUITE_TKIP 2 /* WPA1/2 */
43#define CIPHER_SUITE_RESERVED 3 /* WPA1/2 */
44#define CIPHER_SUITE_CCMP128 4 /* WPA2 */
45#define CIPHER_SUITE_WEP104 5 /* WEP */
46#define CIPHER_SUITE_BIP_CMAC128 6 /* WPA2 */
47#define CIPHER_SUITE_NOTALLOWED 7 /* WPA2 */
48#define CIPHER_SUITE_GCMP128 8 /* WPA3 */
49#define CIPHER_SUITE_GCMP256 9 /* WPA3 */
50#define CIPHER_SUITE_CCMP256 10 /* WPA3 */
51#define CIPHER_SUITE_BIP_GMAC128 11 /* WPA3 */
52#define CIPHER_SUITE_BIP_GMAC256 12 /* WPA3 */
53#define CIPHER_SUITE_BIP_CMAC256 13 /* WPA3 */
54
55/* Auth Key Management Suite Values */
56#define AKM_SUITE_RESERVED 0 /* WPA1/2 */
57#define AKM_SUITE_1X 1 /* WPA1/2 */
58#define AKM_SUITE_PSK 2 /* WPA1/2 */
59#define AKM_SUITE_1X_FT 3 /* WPA1/2 */
60#define AKM_SUITE_PSK_FT 4 /* WPA2 */
61#define AKM_SUITE_1X_SHA256 5 /* WPA2 */
62#define AKM_SUITE_PSK_SHA256 6 /* WPA2 */
63#define AKM_SUITE_TDLS 7 /* WPA2 */
64#define AKM_SUITE_SAE 8 /* WPA3 */
65#define AKM_SUITE_SAE_FT 9 /* WPA3 */
66#define AKM_SUITE_AP_PEER 10 /* WPA3 */
67#define AKM_SUITE_1X_SUITEB_SHA256 11 /* WPA3 */
68#define AKM_SUITE_1X_SUITEB_SHA384 12 /* WPA3 */
69#define AKM_SUITE_1X_FT_SHA384 13 /* WPA3 */
70#define AKM_SUITE_FILS_SHA256 14 /* WPA3 */
71#define AKM_SUITE_FILS_SHA384 15 /* WPA3 */
72#define AKM_SUITE_FILS_SHA256_FT 16 /* WPA3 */
73#define AKM_SUITE_FILS_SHA384_FT 17 /* WPA3 */
74#define AKM_SUITE_OWE 18 /* WPA3 */
75#define AKM_PSK_SHA384_FT 19 /* WPA3 */
76#define AKM_PSK_SHA384 20 /* WPA3 */
77
78/* Authentication Scheme Values */
79#define AUTH_OPEN 0
80#define AUTH_SHARED_KEY 1
81#define AUTH_FAST_BSS 2
82#define AUTH_SAE 3
83#define AUTH_VENDOR 65535
84
85/* libwifi Security Type Values for libwifi_bss encryption_info */
86#define WEP (1ULL << 1)
87#define WPA (1ULL << 2)
88#define WPA2 (1ULL << 3)
89#define WPA3 (1ULL << 4)
90
91/* libwifi Group or Multicast Cipher Values for libwifi_bss encryption_info */
92#define LIBWIFI_GROUP_CIPHER_SUITE_WEP40 (1ULL << 5)
93#define LIBWIFI_GROUP_CIPHER_SUITE_TKIP (1ULL << 6)
94#define LIBWIFI_GROUP_CIPHER_SUITE_RESERVED (1ULL << 7)
95#define LIBWIFI_GROUP_CIPHER_SUITE_CCMP128 (1ULL << 8)
96#define LIBWIFI_GROUP_CIPHER_SUITE_WEP104 (1ULL << 9)
97#define LIBWIFI_GROUP_CIPHER_SUITE_BIP_CMAC128 (1ULL << 10)
98#define LIBWIFI_GROUP_CIPHER_SUITE_NOTALLOWED (1ULL << 11)
99#define LIBWIFI_GROUP_CIPHER_SUITE_GCMP128 (1ULL << 12)
100#define LIBWIFI_GROUP_CIPHER_SUITE_GCMP256 (1ULL << 13)
101#define LIBWIFI_GROUP_CIPHER_SUITE_CCMP256 (1ULL << 14)
102#define LIBWIFI_GROUP_CIPHER_SUITE_BIP_GMAC128 (1ULL << 15)
103#define LIBWIFI_GROUP_CIPHER_SUITE_BIP_GMAC256 (1ULL << 16)
104#define LIBWIFI_GROUP_CIPHER_SUITE_BIP_CMAC256 (1ULL << 17)
105
106/* libwifi Pairwise or Unicast Cipher Values for libwifi_bss encryption_info */
107#define LIBWIFI_PAIRWISE_SUITE_GROUP (1ULL << 18)
108#define LIBWIFI_PAIRWISE_CIPHER_SUITE_WEP40 (1ULL << 19)
109#define LIBWIFI_PAIRWISE_CIPHER_SUITE_TKIP (1ULL << 20)
110#define LIBWIFI_PAIRWISE_CIPHER_SUITE_RESERVED (1ULL << 21)
111#define LIBWIFI_PAIRWISE_CIPHER_SUITE_CCMP128 (1ULL << 22)
112#define LIBWIFI_PAIRWISE_CIPHER_SUITE_WEP104 (1ULL << 23)
113#define LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_CMAC128 (1ULL << 24)
114#define LIBWIFI_PAIRWISE_CIPHER_SUITE_NOTALLOWED (1ULL << 25)
115#define LIBWIFI_PAIRWISE_CIPHER_SUITE_GCMP128 (1ULL << 26)
116#define LIBWIFI_PAIRWISE_CIPHER_SUITE_GCMP256 (1ULL << 27)
117#define LIBWIFI_PAIRWISE_CIPHER_SUITE_CCMP256 (1ULL << 28)
118#define LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_GMAC128 (1ULL << 29)
119#define LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_GMAC256 (1ULL << 30)
120#define LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_CMAC256 (1ULL << 31)
121
122/* libwifi Auth Key Management Values for libwifi_bss encryption_info */
123#define LIBWIFI_AKM_SUITE_RESERVED (1ULL << 32)
124#define LIBWIFI_AKM_SUITE_1X (1ULL << 33)
125#define LIBWIFI_AKM_SUITE_PSK (1ULL << 34)
126#define LIBWIFI_AKM_SUITE_1X_FT (1ULL << 35)
127#define LIBWIFI_AKM_SUITE_PSK_FT (1ULL << 36)
128#define LIBWIFI_AKM_SUITE_1X_SHA256 (1ULL << 37)
129#define LIBWIFI_AKM_SUITE_PSK_SHA256 (1ULL << 39)
130#define LIBWIFI_AKM_SUITE_TDLS (1ULL << 40)
131#define LIBWIFI_AKM_SUITE_SAE (1ULL << 41)
132#define LIBWIFI_AKM_SUITE_SAE_FT (1ULL << 42)
133#define LIBWIFI_AKM_SUITE_AP_PEER (1ULL << 43)
134#define LIBWIFI_AKM_SUITE_1X_SUITEB_SHA256 (1ULL << 44)
135#define LIBWIFI_AKM_SUITE_1X_SUITEB_SHA384 (1ULL << 45)
136#define LIBWIFI_AKM_SUITE_1X_FT_SHA384 (1ULL << 46)
137#define LIBWIFI_AKM_SUITE_FILS_SHA256 (1ULL << 47)
138#define LIBWIFI_AKM_SUITE_FILS_SHA384 (1ULL << 48)
139#define LIBWIFI_AKM_SUITE_FILS_SHA256_FT (1ULL << 49)
140#define LIBWIFI_AKM_SUITE_FILS_SHA384_FT (1ULL << 50)
141#define LIBWIFI_AKM_SUITE_OWE (1ULL << 51)
142#define LIBWIFI_AKM_PSK_SHA384_FT (1ULL << 52)
143#define LIBWIFI_AKM_PSK_SHA384 (1ULL << 53)
144
145/* libwifi Authentication Scheme Values for libwifi_bss encryption_info */
146#define LIBWIFI_AUTH_OPEN (1ULL << 54)
147#define LIBWIFI_AUTH_SHARED_KEY (1ULL << 55)
148#define LIBWIFI_AUTH_FAST_BSS (1ULL << 56)
149#define LIBWIFI_AUTH_SAE (1ULL << 57)
150#define LIBWIFI_AUTH_VENDOR (1ULL << 58)
151
152/* libwifi RSN Capability flags */
153#define LIBWIFI_RSN_CAPAB_PREAUTH (1 << 0)
154#define LIBWIFI_RSN_CAPAB_PAIRWISE (1 << 1)
155#define LIBWIFI_RSN_CAPAB_PTKSA_REPLAY (1 << 2 | 1 << 3)
156#define LIBWIFI_RSN_CAPAB_GTKSA_REPLAY (1 << 4 | 1 << 5)
157#define LIBWIFI_RSN_CAPAB_MFP_REQUIRED (1 << 6)
158#define LIBWIFI_RSN_CAPAB_MFP_CAPABLE (1 << 7)
159#define LIBWIFI_RSN_CAPAB_JOINT_RSNA (1 << 8)
160#define LIBWIFI_RSN_CAPAB_PEERKEY (1 << 9)
161#define LIBWIFI_RSN_CAPAB_EXT_KEY_ID (1 << 13)
162
163/**
164 * libwifi Representation of a WPA or RSN cipher suite
165 * ┌────────────────────────┬────────────┐
166 * │ OUI │ Suite Type │
167 * ├────────────────────────┼────────────┤
168 * │ 3 Bytes │ 1 Byte │
169 * └────────────────────────┴────────────┘
170 *
171 */
172struct libwifi_cipher_suite {
173 unsigned char oui[3];
174 uint8_t suite_type;
175} __attribute__((packed));
176
177/**
178 * libwifi Representation of a Microsoft WPA Information Element
179 * ┌───────────────────────────────────┐
180 * │ Version │ ── 2 Bytes
181 * ├───────────────────────────────────┤
182 * │ Multicast Cipher Suite │ ── 4 Bytes
183 * ├───────────────────────────────────┤
184 * │ Unicast Cipher Suite Count │ ── 2 Bytes
185 * ├───────────────────────────────────┤
186 * │ Unicast Cipher Suites │ ── 4 to 12 Bytes
187 * ├───────────────────────────────────┤
188 * │ Auth Key Management Suite Count │ ── 2 Bytes
189 * ├───────────────────────────────────┤
190 * │ Auth Key Management Suites │ ── 4 to 12 Bytes
191 * └───────────────────────────────────┘
192 */
193struct libwifi_wpa_info {
194 uint16_t wpa_version;
195 struct libwifi_cipher_suite multicast_cipher_suite;
196 uint16_t num_unicast_cipher_suites;
197 struct libwifi_cipher_suite unicast_cipher_suites[LIBWIFI_MAX_CIPHER_SUITES];
198 uint16_t num_auth_key_mgmt_suites;
199 struct libwifi_cipher_suite auth_key_mgmt_suites[LIBWIFI_MAX_CIPHER_SUITES];
200} __attribute__((packed));
201
202/**
203 * libwifi Representation of a 802.11 RSN Information Element
204 * ┌───────────────────────────────────┐
205 * │ Version │ ── 2 Bytes
206 * ├───────────────────────────────────┤
207 * │ Group Cipher Suite │ ── 4 Bytes
208 * ├───────────────────────────────────┤
209 * │ Pairwise Cipher Suite Count │ ── 2 Bytes
210 * ├───────────────────────────────────┤
211 * │ Pairwise Cipher Suites │ ── 4 to 12 Bytes
212 * ├───────────────────────────────────┤
213 * │ Auth Key Management Suite Count │ ── 2 Bytes
214 * ├───────────────────────────────────┤
215 * │ Auth Key Management Suites │ ── 4 to 12 Bytes
216 * ├───────────────────────────────────┤
217 * │ RSN Capabilities │ ── 2 Bytes
218 * └───────────────────────────────────┘
219 */
220struct libwifi_rsn_info {
221 uint16_t rsn_version;
222 struct libwifi_cipher_suite group_cipher_suite;
223 int num_pairwise_cipher_suites;
224 struct libwifi_cipher_suite pairwise_cipher_suites[LIBWIFI_MAX_CIPHER_SUITES];
225 int num_auth_key_mgmt_suites;
226 struct libwifi_cipher_suite auth_key_mgmt_suites[LIBWIFI_MAX_CIPHER_SUITES];
227 uint16_t rsn_capabilities;
228} __attribute__((packed));
229
230/*
231 * libwifi Representation of the 802.1X/EAPOL Key Information section
232 * ┌───────────────────────────────────┐
233 * │ Key Information │ ── 2 Bytes
234 * ├───────────────────────────────────┤
235 * │ Key Length │ ── 2 Bytes
236 * ├───────────────────────────────────┤
237 * │ Replay Counter │ ── 8 Bytes
238 * ├───────────────────────────────────┤
239 * │ WPA Key Nonce │ ── 32 Bytes
240 * ├───────────────────────────────────┤
241 * │ WPA Key IV │ ── 16 Bytes
242 * ├───────────────────────────────────┤
243 * │ WPA Key RSC │ ── 8 Bytes
244 * ├───────────────────────────────────┤
245 * │ WPA Key ID │ ── 8 Bytes
246 * ├───────────────────────────────────┤
247 * │ WPA Key MIC │ ── 16 Bytes
248 * ├───────────────────────────────────┤
249 * │ WPA Key Data Length │ ── 4 Bytes
250 * ├───────────────────────────────────┤
251 * │ WPA Key Data │ ── Variable
252 * └───────────────────────────────────┘
253 */
254struct libwifi_wpa_key_info {
255 uint16_t information;
256 uint16_t key_length;
257 uint64_t replay_counter;
258 unsigned char nonce[32];
259 unsigned char iv[16];
260 unsigned char rsc[8];
261 unsigned char id[8];
262 unsigned char mic[16];
263 uint16_t key_data_length;
264 unsigned char *key_data;
265} __attribute__((packed));
266
267/**
268 * libwifi Representation of the encapsulating 802.1X data in an EAPOL frame
269 * ┌─────────────────┐
270 * │ Version │ ── 1 Byte
271 * ├─────────────────┤
272 * │ Type │ ── 1 Byte
273 * ├─────────────────┤
274 * │ Length │ ── 2 Bytes
275 * ├─────────────────┤
276 * │ Descriptor │ ── 1 Byte
277 * ├─────────────────┤
278 * │ Key Information │ ── See libwifi_wpa_key_info
279 * └─────────────────┘
280 */
281struct libwifi_wpa_auth_data {
282 uint8_t version;
283 uint8_t type;
284 uint16_t length;
285 uint8_t descriptor;
286 struct libwifi_wpa_key_info key_info;
287} __attribute__((packed));
288
289#endif /* LIBWIFI_CORE_SECURITY_H */
diff --git a/src/libwifi/core/misc/types.h b/src/libwifi/core/misc/types.h new file mode 100644 index 0000000..3532183 --- /dev/null +++ b/src/libwifi/core/misc/types.h
@@ -0,0 +1,218 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_CORE_TYPES_H
17#define LIBWIFI_CORE_TYPES_H
18
19#include "../../core/misc/byteswap.h"
20
21/* 802.11 Management Frame "reason code" fixed parameter values */
22enum libwifi_reason_codes {
23 REASON_UNSPECIFIED_FAILURE = 1,
24 REASON_PREVIOUS_AUTH_INVALID = 2,
25 REASON_STA_LEAVING_ESS = 3,
26 REASON_INACTIVE = 4,
27 REASON_TOO_MANY_STAS = 5,
28 REASON_CLASS_2_FRAME = 6,
29 REASON_CLASS_3_FRAME = 7,
30 REASON_STA_LEAVING_BSS = 8,
31 REASON_STA_REQUESTING_REASSOC_NOT_AUTHED = 9,
32 REASON_UNNACCEPTABLE_POWER_CAPABILITY = 10,
33 REASON_UNNACCEPTABLE_CHANNELS = 11,
34 REASON_BSS_TRANSITION_MGMT = 12,
35 REASON_INVALID_ELEMENT = 13,
36 REASON_MIC_FAILURE = 14,
37 REASON_FOURWAY_HANDSHAKE_TIMEOUT = 15,
38 REASON_GROUPKEY_HANDSHAKE_TIMEOUT = 16,
39 REASON_INVALID_FOURWAY = 17,
40 REASON_INVALID_GROUP_CIPHER = 18,
41 REASON_INVALID_PAIRWISE_CIPHER = 19,
42 REASON_INVALID_AKMP = 20,
43 REASON_UNSUPPORTED_RSNE_VERSION = 21,
44 REASON_INVALID_RSNE_CAPABILITIES = 22,
45 REASON_INVALID_8021X_AUTH = 23,
46 REASON_CIPHER_SUITE_REJECTED = 24,
47 REASON_TDLS_DIRECT_LINK_TEARDOWN_UNREACHABLE = 25,
48 REASON_TDLS_DIRECT_LINK_TEARDOWN_UNSPECIFIED = 26,
49 REASON_SSP_REQUEST = 27,
50 REASON_LACKS_SSP_ROAMING = 28,
51 REASON_CIPHER_OR_AKM_REQUIRED = 29,
52 REASON_SERVICE_NOT_AUTHORIZED = 30,
53 REASON_SERVICE_CHANGE_PRECLUDES_TS = 31,
54 REASON_UNSPECIFIED_QOS = 32,
55 REASON_INSUFFICIENT_BANDWIDTH = 33,
56 REASON_EXCESSIVE_ACKS_REQUIRED = 34,
57 REASON_TXOPS_EXCEEDED = 35,
58 REASON_STA_LEAVING = 36,
59 REASON_END_TS = 37,
60 REASON_UNKNOWN_TS_OR_BA = 38,
61 REASON_TIMEOUT = 39,
62 REASON_PEERKEY_MISMATCH = 45,
63 REASON_PEER_INITIATED = 46,
64 REASON_AP_INITIATED = 47,
65 REASON_INVALID_FT_ACTION_FRAMECOUNT = 48,
66 REASON_INVALID_PMKI = 49,
67 REASON_INVALID_MDE = 50,
68 REASON_INVALID_FTE = 51,
69 REASON_MESH_PEERING_CANCELED = 52,
70 REASON_MESH_MAX_PEERS = 53,
71 REASON_MESH_CONFIGURATION_POLICY_VIOLATION = 54,
72 REASON_MESH_CLOSE_RCVD = 55,
73 REASON_MESH_MAX_RETRIES = 56,
74 REASON_MESH_CONFIRM_TIMEOUT = 57,
75 REASON_MESH_INVALID_GTK = 58,
76 REASON_MESH_INCONSISTENT_PARAMETERS = 59,
77 REASON_MESH_INVALID_SECURITY_CAPABILITY = 60,
78 REASON_MESH_PATH_ERROR_NO_PROXY_INFORMATION = 61,
79 REASON_MESH_PATH_ERROR_NO_FORWARDING_INFORMATION = 62,
80 REASON_MESH_PATH_ERROR_DESTINATION_UNREACHABLE = 63,
81 REASON_MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64,
82 REASON_MESH_CHANNEL_SWITCH_REGULATORY_REQUIREMENTS = 65,
83 REASON_MESH_CHANNEL_SWITCH_UNSPECIFIED = 66,
84};
85
86/* 802.11 Management Frame "status code" fixed parameter values */
87enum libwifi_status_codes {
88 STATUS_SUCCESS = 0,
89 STATUS_REFUSED = 1,
90 STATUS_TDLS_REJECTED_ALTERNATIVE_PROVIDED = 2,
91 // Reserved = 4,
92 STATUS_SECURITY_DISABLED = 5,
93 STATUS_UNACCEPTABLE_LIFETIME = 6,
94 STATUS_NOT_IN_SAME_BSS = 7,
95 // Reserved = 8,
96 // Reserved = 9,
97 STATUS_REFUSED_CAPABILITIES_MISMATCH = 10,
98 STATUS_DENIED_NO_ASSOCIATION_EXISTS = 11,
99 STATUS_DENIED_OTHER_REASON = 12,
100 STATUS_UNSUPPORTED_AUTH_ALGORITHM = 13,
101 STATUS_TRANSACTION_SEQUENCE_ERROR = 14,
102 STATUS_CHALLENGE_FAILURE = 15,
103 STATUS_REJECTED_SEQUENCE_TIMEOUT = 16,
104 STATUS_DENIED_NO_MORE_STAS = 17,
105 STATUS_REFUSED_BASIC_RATES_MISMATCH = 18,
106 STATUS_DENIED_NO_SHORT_PREAMBLE_SUPPORT = 19,
107 // Reserved = 20,
108 // Reserved = 21,
109 STATUS_REJECTED_SPECTRUM_MANAGEMENT_REQUIRED = 22,
110 STATUS_REJECTED_BAD_POWER_CAPABILITY = 23,
111 STATUS_REJECTED_BAD_SUPPORTED_CHANNELS = 24,
112 STATUS_DENIED_NO_SHORT_SLOT_TIME_SUPPORT = 25,
113 // Reserved = 26,
114 STATUS_DENIED_NO_HT_SUPPORT = 27,
115 STATUS_R0KH_UNREACHABLE = 28,
116 STATUS_DENIED_PCO_TIME_NOT_SUPPORTED = 29,
117 STATUS_REFUSED_TEMPORARILY = 30,
118 STATUS_ROBUST_MANAGEMENT_POLICY_VIOLATION = 31,
119 STATUS_UNSPECIFIED_QOS_FAILURE = 32,
120 STATUS_DENIED_INSUFFICIENT_BANDWIDTH = 33,
121 STATUS_DENIED_POOR_CHANNEL_CONDITIONS = 34,
122 STATUS_DENIED_QOS_NOT_SUPPORTED = 35,
123 // Reserved = 36,
124 STATUS_REQUEST_DECLINED = 37,
125 STATUS_INVALID_PARAMETERS = 38,
126 STATUS_REJECTED_WITH_SUGGESTED_CHANGES = 39,
127 STATUS_STATUS_INVALID_ELEMENT = 40,
128 STATUS_STATUS_INVALID_GROUP_CIPHER = 41,
129 STATUS_STATUS_INVALID_PAIRWISE_CIPHER = 42,
130 STATUS_STATUS_INVALID_AKMP = 43,
131 STATUS_UNSUPPORTED_RSNE_VERSION = 44,
132 STATUS_INVALID_RSNE_CAPABILITIES = 45,
133 STATUS_STATUS_CIPHER_OUT_OF_POLICY = 46,
134 STATUS_REJECTED_FOR_DELAY_PERIOD = 47,
135 STATUS_DLS_NOT_ALLOWED = 48,
136 STATUS_NOT_PRESENT = 49,
137 STATUS_NOT_QOS_STA = 50,
138 STATUS_DENIED_LISTEN_INTERVAL_TOO_LARGE = 51,
139 STATUS_STATUS_INVALID_FT_ACTION_FRAME_COUNT = 52,
140 STATUS_STATUS_INVALID_PMKID = 53,
141 STATUS_STATUS_INVALID_MDE = 54,
142 STATUS_STATUS_INVALID_FTE = 55,
143 STATUS_REQUESTED_TCLAS_NOT_SUPPORTED = 56,
144 STATUS_INSUFFICIENT_TCLAS_PROCESSING_RESOURCES = 57,
145 STATUS_TRY_ANOTHER_BSS = 58,
146 STATUS_GAS_ADVERTISEMENT_PROTOCOL_NOT_SUPPORTED = 59,
147 STATUS_NO_OUTSTANDING_GAS_REQUEST = 60,
148 STATUS_GAS_RESPONSE_NOT_RECEIVED_FROM = 61,
149 STATUS_GAS_QUERY_TIMEOUT = 62,
150 STATUS_GAS_QUERY_RESPONSE_TOO_ = 63,
151 STATUS_REJECTED_HOME_WITH_SUGGESTED_CHANGES = 64,
152 STATUS_SERVER_UNREACHABLE = 65,
153 // Reserved = 66,
154 STATUS_REJECTED_FOR_SSP_PERMISSIONS = 67,
155 STATUS_REFUSED_UNAUTHENTICATED_ACCESS_NOT_SUPPORTED = 68,
156 // Reserved = 69,
157 // Reserved = 70,
158 // Reserved = 71,
159 STATUS_INVALID_RSNE = 72,
160 STATUS_U_APSD_COEXISTANCE_NOT_SUPPORTED = 73,
161 STATUS_U_APSD_COEX_MODE_NOT_SUPPORTED = 74,
162 STATUS_BAD_INTERVAL_WITH_U_APSD_COEX = 75,
163 STATUS_ANTI_CLOGGING_TOKEN_REQUIRED = 76,
164 STATUS_UNSUPPORTED_FINITE_CYCLIC_GROUP = 77,
165 STATUS_CANNOT_FIND_ALTERNATIVE_TBTT = 78,
166 STATUS_TRANSMISSION_FAILURE = 79,
167 STATUS_REQUESTED_TCLAS_NOT_SUPPORTED_2 = 80,
168 STATUS_TCLAS_RESOURCES_EXHAUSTED = 81,
169 STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION = 82,
170 STATUS_REJECT_WITH_SCHEDULE = 83,
171 STATUS_REJECT_NO_WAKEUP_SPECIFIED = 84,
172 STATUS_SUCCESS_POWER_SAVE_MODE = 85,
173 STATUS_PENDING_ADMITTING_FST_SESSION = 86,
174 STATUS_PERFORMING_FST_NOW = 87,
175 STATUS_PENDING_GAP_IN_BA_WINDOW = 88,
176 STATUS_REJECT_U_PID_SETTING = 89,
177 // Reserved = 90,
178 // Reserved = 91,
179 STATUS_REFUSED_EXTERNAL_REASON = 92,
180 STATUS_REFUSED_AP_OUT_OF_MEMORY = 93,
181 STATUS_REJECTED_EMERGENCY_SERVICES_NOT_SUPPORTED = 94,
182 STATUS_QUERY_RESPONSE_OUTSTANDING = 95,
183 STATUS_REJECT_DSE_BAND = 96,
184 STATUS_TCLAS_PROCESSING_TERMINATED = 97,
185 STATUS_TS_SCHEDULE_CONFLICT = 98,
186 STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
187 STATUS_MCCAOP_RESERVATION_CONFLICT = 100,
188 STATUS_MAF_LIMIT_EXCEEDED = 101,
189 STATUS_MCCA_TRACK_LIMIT_EXCEEDED = 102,
190 STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
191 STATUS_DENIED_VHT_NOT_SUPPORTED = 104,
192 STATUS_ENABLEMENT_DENIED = 105,
193 STATUS_RESTRICTION_FROM_AUTHORIZED_GDB = 106,
194 STATUS_AUTHORIZATION_DEENABLED = 107,
195 // Reserved = 108–65535
196};
197
198/* Defined capabilities_information fixed parameter values */
199#define libwifi_check_capabilities(x, cap) (BYTESWAP16(x) & (1 << cap))
200enum libwifi_capabilities {
201 CAPABILITIES_ESS = 0,
202 CAPABILITIES_IBSS = 1,
203 CAPABILITIES_POLL = 2,
204 CAPABILITIES_POLL_REQ = 3,
205 CAPABILITIES_PRIVACY = 4,
206 CAPABILITIES_SHORT_PREAMBLE = 5,
207 CAPABILITIES_PBCC = 6,
208 CAPABILITIES_CHAN_AGILITY = 7,
209 CAPABILITIES_SPECTRUM_AGILITY = 8 & (8 >> 1),
210 CAPABILITIES_SHORT_SLOT = 10,
211 CAPABILITIES_POWER_SAVE = 11,
212 CAPABILITIES_MEASUREMENT = 12,
213 CAPABILITIES_DSSS_OFDM = 13,
214 CAPABILITIES_DELAYED_ACK = 14,
215 CAPABILITIES_IMMEDIATE_ACK = 15,
216};
217
218#endif /* LIBWIFI_CORE_TYPES_H */
diff --git a/src/libwifi/core/radiotap/COPYING b/src/libwifi/core/radiotap/COPYING new file mode 100644 index 0000000..4cc12c2 --- /dev/null +++ b/src/libwifi/core/radiotap/COPYING
@@ -0,0 +1,14 @@
1Copyright (c) 2007-2009 Andy Green <andy@warmcat.com>
2Copyright (c) 2007-2009 Johannes Berg <johannes@sipsolutions.net>
3
4Permission to use, copy, modify, and/or distribute this software for any
5purpose with or without fee is hereby granted, provided that the above
6copyright notice and this permission notice appear in all copies.
7
8THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/src/libwifi/core/radiotap/platform.h b/src/libwifi/core/radiotap/platform.h new file mode 100644 index 0000000..e0ad99f --- /dev/null +++ b/src/libwifi/core/radiotap/platform.h
@@ -0,0 +1,81 @@
1#include <errno.h>
2#include <stddef.h>
3#include <string.h>
4
5#if defined(linux) || defined(Linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux__)
6#include <endian.h>
7#if defined(__UCLIBC__)
8#include <asm/byteorder.h>
9#ifndef le16toh
10#define le16toh __le16_to_cpu
11#endif
12#ifndef le32toh
13#define le32toh __le32_to_cpu
14#endif
15#endif
16#endif
17
18#if defined(__CYGWIN32__) || defined(CYGWIN)
19#include <asm/byteorder.h>
20#include <endian.h>
21#endif
22
23#if defined(__APPLE__)
24#include <machine/endian.h>
25#endif
26
27#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__MidnightBSD__) || \
28 defined(__NetBSD__)
29#include <sys/endian.h>
30#include <sys/types.h>
31#endif
32
33#if defined(__SVR4) && defined(__sun__)
34#include <sys/byteorder.h>
35#include <sys/types.h>
36#endif
37
38#ifndef le16_to_cpu
39#define le16_to_cpu le16toh
40#endif
41
42#ifndef le32_to_cpu
43#define le32_to_cpu le32toh
44#endif
45
46#if defined(_MSC_VER)
47// Microsoft
48#define EXPORT __declspec(dllexport)
49#define IMPORT __declspec(dllimport)
50#elif defined(__GNUC__) || defined(__llvm__) || defined(__clang__) || defined(__INTEL_COMPILER)
51#define EXPORT __attribute__((visibility("default")))
52#define IMPORT
53#else
54// do nothing and hope for the best?
55#define EXPORT
56#define IMPORT
57#pragma warning Unknown dynamic link import / export semantics.
58#endif
59
60#if defined(RADIOTAP_FAST_UNALIGNED_ACCESS)
61#define get_unaligned(p) \
62 __extension__({ \
63 struct packed_dummy_struct { \
64 typeof(*(p)) __val; \
65 } __attribute__((packed)) *__ptr = (void *) (p); \
66 \
67 __ptr->__val; \
68 })
69#else
70#define get_unaligned(p) \
71 __extension__({ \
72 typeof(*(p)) __tmp; \
73 memmove(&__tmp, (p), sizeof(*(p))); \
74 __tmp; \
75 })
76#endif
77
78#define get_unaligned_le16(p) le16_to_cpu(get_unaligned((uint16_t *) (p)))
79#define get_unaligned_le32(p) le32_to_cpu(get_unaligned((uint32_t *) (p)))
80
81#define UNALIGNED_ADDRESS(x) ((void *) (x))
diff --git a/src/libwifi/core/radiotap/radiotap.c b/src/libwifi/core/radiotap/radiotap.c new file mode 100644 index 0000000..5d46223 --- /dev/null +++ b/src/libwifi/core/radiotap/radiotap.c
@@ -0,0 +1,469 @@
1/*
2 * Radiotap parser
3 *
4 * Copyright 2007 Andy Green <andy@warmcat.com>
5 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Alternatively, this software may be distributed under the terms of ISC
12 * license, see COPYING for more details.
13 */
14#include "platform.h"
15#include "radiotap_iter.h"
16
17/* function prototypes and related defs are in radiotap_iter.h */
18
19static const struct radiotap_align_size rtap_namespace_sizes[] = {
20 [IEEE80211_RADIOTAP_TSFT] =
21 {
22 .align = 8,
23 .size = 8,
24 },
25 [IEEE80211_RADIOTAP_FLAGS] =
26 {
27 .align = 1,
28 .size = 1,
29 },
30 [IEEE80211_RADIOTAP_RATE] =
31 {
32 .align = 1,
33 .size = 1,
34 },
35 [IEEE80211_RADIOTAP_CHANNEL] =
36 {
37 .align = 2,
38 .size = 4,
39 },
40 [IEEE80211_RADIOTAP_FHSS] =
41 {
42 .align = 2,
43 .size = 2,
44 },
45 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] =
46 {
47 .align = 1,
48 .size = 1,
49 },
50 [IEEE80211_RADIOTAP_DBM_ANTNOISE] =
51 {
52 .align = 1,
53 .size = 1,
54 },
55 [IEEE80211_RADIOTAP_LOCK_QUALITY] =
56 {
57 .align = 2,
58 .size = 2,
59 },
60 [IEEE80211_RADIOTAP_TX_ATTENUATION] =
61 {
62 .align = 2,
63 .size = 2,
64 },
65 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] =
66 {
67 .align = 2,
68 .size = 2,
69 },
70 [IEEE80211_RADIOTAP_DBM_TX_POWER] =
71 {
72 .align = 1,
73 .size = 1,
74 },
75 [IEEE80211_RADIOTAP_ANTENNA] =
76 {
77 .align = 1,
78 .size = 1,
79 },
80 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] =
81 {
82 .align = 1,
83 .size = 1,
84 },
85 [IEEE80211_RADIOTAP_DB_ANTNOISE] =
86 {
87 .align = 1,
88 .size = 1,
89 },
90 [IEEE80211_RADIOTAP_RX_FLAGS] =
91 {
92 .align = 2,
93 .size = 2,
94 },
95 [IEEE80211_RADIOTAP_TX_FLAGS] =
96 {
97 .align = 2,
98 .size = 2,
99 },
100 [IEEE80211_RADIOTAP_RTS_RETRIES] =
101 {
102 .align = 1,
103 .size = 1,
104 },
105 [IEEE80211_RADIOTAP_DATA_RETRIES] =
106 {
107 .align = 1,
108 .size = 1,
109 },
110 [IEEE80211_RADIOTAP_MCS] =
111 {
112 .align = 1,
113 .size = 3,
114 },
115 [IEEE80211_RADIOTAP_AMPDU_STATUS] =
116 {
117 .align = 4,
118 .size = 8,
119 },
120 [IEEE80211_RADIOTAP_VHT] =
121 {
122 .align = 2,
123 .size = 12,
124 },
125 [IEEE80211_RADIOTAP_TIMESTAMP] =
126 {
127 .align = 8,
128 .size = 12,
129 },
130 /*
131 * add more here as they are defined in radiotap.h
132 */
133};
134
135const struct ieee80211_radiotap_namespace radiotap_ns = {
136 .n_bits = sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]),
137 .align_size = rtap_namespace_sizes,
138};
139
140/**
141 * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization
142 * @iterator: radiotap_iterator to initialize
143 * @radiotap_header: radiotap header to parse
144 * @max_length: total length we can parse into (eg, whole packet length)
145 *
146 * Returns: 0 or a negative error code if there is a problem.
147 *
148 * This function initializes an opaque iterator struct which can then
149 * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap
150 * argument which is present in the header. It knows about extended
151 * present headers and handles them.
152 *
153 * How to use:
154 * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
155 * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
156 * checking for a good 0 return code. Then loop calling
157 * __ieee80211_radiotap_iterator_next()... it returns either 0,
158 * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem.
159 * The iterator's @this_arg member points to the start of the argument
160 * associated with the current argument index that is present, which can be
161 * found in the iterator's @this_arg_index member. This arg index corresponds
162 * to the IEEE80211_RADIOTAP_... defines.
163 *
164 * Radiotap header length:
165 * You can find the CPU-endian total radiotap header length in
166 * iterator->max_length after executing ieee80211_radiotap_iterator_init()
167 * successfully.
168 *
169 * Alignment Gotcha:
170 * You must take care when dereferencing iterator.this_arg
171 * for multibyte types... the pointer is not aligned. Use
172 * get_unaligned((type *)iterator.this_arg) to dereference
173 * iterator.this_arg for type "type" safely on all arches.
174 *
175 * Example code: parse.c
176 */
177
178EXPORT
179int ieee80211_radiotap_iterator_init(struct ieee80211_radiotap_iterator *iterator,
180 struct ieee80211_radiotap_header *radiotap_header, int max_length,
181 const struct ieee80211_radiotap_vendor_namespaces *vns) {
182 /* must at least have the radiotap header */
183 if (max_length < (int) sizeof(struct ieee80211_radiotap_header))
184 return -EINVAL;
185
186 /* Linux only supports version 0 radiotap format */
187 if (radiotap_header->it_version)
188 return -EINVAL;
189
190 /* sanity check for allowed length and radiotap length field */
191 if (max_length < get_unaligned_le16(UNALIGNED_ADDRESS(&radiotap_header->it_len)))
192 return -EINVAL;
193
194 iterator->_rtheader = radiotap_header;
195 iterator->_max_length = get_unaligned_le16(UNALIGNED_ADDRESS(&radiotap_header->it_len));
196 iterator->_arg_index = 0;
197 iterator->_bitmap_shifter = get_unaligned_le32(UNALIGNED_ADDRESS(&radiotap_header->it_present));
198 iterator->_arg = (uint8_t *) radiotap_header + sizeof(*radiotap_header);
199 iterator->_reset_on_ext = 0;
200#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 9
201#pragma GCC diagnostic push
202#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
203#endif
204 iterator->_next_bitmap = UNALIGNED_ADDRESS(&radiotap_header->it_present);
205#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 9
206#pragma GCC diagnostic pop
207#endif
208 iterator->_next_bitmap++;
209 iterator->_vns = vns;
210 iterator->current_namespace = &radiotap_ns;
211 iterator->is_radiotap_ns = 1;
212#ifdef RADIOTAP_SUPPORT_OVERRIDES
213 iterator->n_overrides = 0;
214 iterator->overrides = NULL;
215#endif
216
217 /* find payload start allowing for extended bitmap(s) */
218
219 if (iterator->_bitmap_shifter & (1 << IEEE80211_RADIOTAP_EXT)) {
220 if ((unsigned long) iterator->_arg - (unsigned long) iterator->_rtheader + sizeof(uint32_t) >
221 (unsigned long) iterator->_max_length)
222 return -EINVAL;
223 while (get_unaligned_le32(iterator->_arg) & (1 << IEEE80211_RADIOTAP_EXT)) {
224 iterator->_arg += sizeof(uint32_t);
225
226 /*
227 * check for insanity where the present bitmaps
228 * keep claiming to extend up to or even beyond the
229 * stated radiotap header length
230 */
231
232 if ((unsigned long) iterator->_arg - (unsigned long) iterator->_rtheader + sizeof(uint32_t) >
233 (unsigned long) iterator->_max_length)
234 return -EINVAL;
235 }
236
237 iterator->_arg += sizeof(uint32_t);
238
239 /*
240 * no need to check again for blowing past stated radiotap
241 * header length, because ieee80211_radiotap_iterator_next
242 * checks it before it is dereferenced
243 */
244 }
245
246 iterator->this_arg = iterator->_arg;
247
248 /* we are all initialized happily */
249
250 return 0;
251}
252
253static void find_ns(struct ieee80211_radiotap_iterator *iterator, uint32_t oui, uint8_t subns) {
254 int i;
255
256 iterator->current_namespace = NULL;
257
258 if (!iterator->_vns)
259 return;
260
261 for (i = 0; i < iterator->_vns->n_ns; i++) {
262 if (iterator->_vns->ns[i].oui != oui)
263 continue;
264 if (iterator->_vns->ns[i].subns != subns)
265 continue;
266
267 iterator->current_namespace = &iterator->_vns->ns[i];
268 break;
269 }
270}
271
272#ifdef RADIOTAP_SUPPORT_OVERRIDES
273static int find_override(struct ieee80211_radiotap_iterator *iterator, int *align, int *size) {
274 int i;
275
276 if (!iterator->overrides)
277 return 0;
278
279 for (i = 0; i < iterator->n_overrides; i++) {
280 if (iterator->_arg_index == iterator->overrides[i].field) {
281 *align = iterator->overrides[i].align;
282 *size = iterator->overrides[i].size;
283 if (!*align) /* erroneous override */
284 return 0;
285 return 1;
286 }
287 }
288
289 return 0;
290}
291#endif
292
293/**
294 * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
295 * @iterator: radiotap_iterator to move to next arg (if any)
296 *
297 * Returns: 0 if there is an argument to handle,
298 * -ENOENT if there are no more args or -EINVAL
299 * if there is something else wrong.
300 *
301 * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*)
302 * in @this_arg_index and sets @this_arg to point to the
303 * payload for the field. It takes care of alignment handling and extended
304 * present fields. @this_arg can be changed by the caller (eg,
305 * incremented to move inside a compound argument like
306 * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in
307 * little-endian format whatever the endianness of your CPU.
308 *
309 * Alignment Gotcha:
310 * You must take care when dereferencing iterator.this_arg
311 * for multibyte types... the pointer is not aligned. Use
312 * get_unaligned((type *)iterator.this_arg) to dereference
313 * iterator.this_arg for type "type" safely on all arches.
314 */
315
316EXPORT
317int ieee80211_radiotap_iterator_next(struct ieee80211_radiotap_iterator *iterator) {
318 while (1) {
319 int hit = 0;
320 int pad, align, size, subns;
321 uint32_t oui;
322
323 /* if no more EXT bits, that's it */
324 if ((iterator->_arg_index % 32) == IEEE80211_RADIOTAP_EXT && !(iterator->_bitmap_shifter & 1))
325 return -ENOENT;
326
327 if (!(iterator->_bitmap_shifter & 1))
328 goto next_entry; /* arg not present */
329
330 /* get alignment/size of data */
331 switch (iterator->_arg_index % 32) {
332 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
333 case IEEE80211_RADIOTAP_EXT:
334 align = 1;
335 size = 0;
336 break;
337 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
338 align = 2;
339 size = 6;
340 break;
341 default:
342#ifdef RADIOTAP_SUPPORT_OVERRIDES
343 if (find_override(iterator, &align, &size)) {
344 /* all set */
345 } else
346#endif
347 if (!iterator->current_namespace ||
348 iterator->_arg_index >= iterator->current_namespace->n_bits) {
349 if (iterator->current_namespace == &radiotap_ns)
350 return -ENOENT;
351 align = 0;
352 } else {
353 align = iterator->current_namespace->align_size[iterator->_arg_index].align;
354 size = iterator->current_namespace->align_size[iterator->_arg_index].size;
355 }
356 if (!align) {
357 /* skip all subsequent data */
358 iterator->_arg = iterator->_next_ns_data;
359 /* give up on this namespace */
360 iterator->current_namespace = NULL;
361 goto next_entry;
362 }
363 break;
364 }
365
366 /*
367 * arg is present, account for alignment padding
368 *
369 * Note that these alignments are relative to the start
370 * of the radiotap header. There is no guarantee
371 * that the radiotap header itself is aligned on any
372 * kind of boundary.
373 *
374 * The above is why get_unaligned() is used to dereference
375 * multibyte elements from the radiotap area.
376 */
377
378 pad = ((unsigned long) iterator->_arg - (unsigned long) iterator->_rtheader) & (align - 1);
379
380 if (pad)
381 iterator->_arg += align - pad;
382
383 if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
384 int vnslen;
385
386 if ((unsigned long) iterator->_arg + size - (unsigned long) iterator->_rtheader >
387 (unsigned long) iterator->_max_length)
388 return -EINVAL;
389
390 oui = (*iterator->_arg << 16) | (*(iterator->_arg + 1) << 8) | *(iterator->_arg + 2);
391 subns = *(iterator->_arg + 3);
392
393 find_ns(iterator, oui, subns);
394
395 vnslen = get_unaligned_le16(iterator->_arg + 4);
396 iterator->_next_ns_data = iterator->_arg + size + vnslen;
397 if (!iterator->current_namespace)
398 size += vnslen;
399 }
400
401 /*
402 * this is what we will return to user, but we need to
403 * move on first so next call has something fresh to test
404 */
405 iterator->this_arg_index = iterator->_arg_index;
406 iterator->this_arg = iterator->_arg;
407 iterator->this_arg_size = size;
408
409 /* internally move on the size of this arg */
410 iterator->_arg += size;
411
412 /*
413 * check for insanity where we are given a bitmap that
414 * claims to have more arg content than the length of the
415 * radiotap section. We will normally end up equalling this
416 * max_length on the last arg, never exceeding it.
417 */
418
419 if ((unsigned long) iterator->_arg - (unsigned long) iterator->_rtheader >
420 (unsigned long) iterator->_max_length)
421 return -EINVAL;
422
423 /* these special ones are valid in each bitmap word */
424 switch (iterator->_arg_index % 32) {
425 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
426 iterator->_reset_on_ext = 1;
427
428 iterator->is_radiotap_ns = 0;
429 /*
430 * If parser didn't register this vendor
431 * namespace with us, allow it to show it
432 * as 'raw. Do do that, set argument index
433 * to vendor namespace.
434 */
435 iterator->this_arg_index = IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
436 if (!iterator->current_namespace)
437 hit = 1;
438 goto next_entry;
439 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
440 iterator->_reset_on_ext = 1;
441 iterator->current_namespace = &radiotap_ns;
442 iterator->is_radiotap_ns = 1;
443 goto next_entry;
444 case IEEE80211_RADIOTAP_EXT:
445 /*
446 * bit 31 was set, there is more
447 * -- move to next u32 bitmap
448 */
449 iterator->_bitmap_shifter = get_unaligned_le32(iterator->_next_bitmap);
450 iterator->_next_bitmap++;
451 if (iterator->_reset_on_ext)
452 iterator->_arg_index = 0;
453 else
454 iterator->_arg_index++;
455 iterator->_reset_on_ext = 0;
456 break;
457 default:
458 /* we've got a hit! */
459 hit = 1;
460 next_entry:
461 iterator->_bitmap_shifter >>= 1;
462 iterator->_arg_index++;
463 }
464
465 /* if we found a valid arg earlier, return it now */
466 if (hit)
467 return 0;
468 }
469}
diff --git a/src/libwifi/core/radiotap/radiotap.h b/src/libwifi/core/radiotap/radiotap.h new file mode 100644 index 0000000..cd6dd57 --- /dev/null +++ b/src/libwifi/core/radiotap/radiotap.h
@@ -0,0 +1,221 @@
1/*
2 * Copyright (c) 2017 Intel Deutschland GmbH
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef __RADIOTAP_H
17#define __RADIOTAP_H
18
19#if defined(__APPLE__)
20#include <libkern/OSByteOrder.h>
21#define bswap_16 OSSwapInt16
22#define bswap_32 OSSwapInt32
23#define bswap_64 OSSwapInt64
24#include <machine/endian.h>
25#ifndef le16toh
26#define le16toh(x) OSSwapLittleToHostInt16(x)
27#endif
28#ifndef le32toh
29#define le32toh(x) OSSwapLittleToHostInt32(x)
30#endif
31#ifndef le64toh
32#define le64toh(x) OSSwapLittleToHostInt64(x)
33#endif
34#endif
35
36#include <stdint.h>
37
38/**
39 * struct ieee82011_radiotap_header - base radiotap header
40 */
41struct ieee80211_radiotap_header {
42 /**
43 * @it_version: radiotap version, always 0
44 */
45 uint8_t it_version;
46
47 /**
48 * @it_pad: padding (or alignment)
49 */
50 uint8_t it_pad;
51
52 /**
53 * @it_len: overall radiotap header length
54 */
55 uint16_t it_len;
56
57 /**
58 * @it_present: (first) present word
59 */
60 uint32_t it_present;
61} __attribute__((__packed__));
62
63/* version is always 0 */
64#define PKTHDR_RADIOTAP_VERSION 0
65
66extern const struct ieee80211_radiotap_namespace radiotap_ns;
67
68/* see the radiotap website for the descriptions */
69enum ieee80211_radiotap_presence {
70 IEEE80211_RADIOTAP_TSFT = 0,
71 IEEE80211_RADIOTAP_FLAGS = 1,
72 IEEE80211_RADIOTAP_RATE = 2,
73 IEEE80211_RADIOTAP_CHANNEL = 3,
74 IEEE80211_RADIOTAP_FHSS = 4,
75 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
76 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
77 IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
78 IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
79 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
80 IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
81 IEEE80211_RADIOTAP_ANTENNA = 11,
82 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
83 IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
84 IEEE80211_RADIOTAP_RX_FLAGS = 14,
85 IEEE80211_RADIOTAP_TX_FLAGS = 15,
86 IEEE80211_RADIOTAP_RTS_RETRIES = 16,
87 IEEE80211_RADIOTAP_DATA_RETRIES = 17,
88 /* 18 is XChannel, but it's not defined yet */
89 IEEE80211_RADIOTAP_MCS = 19,
90 IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
91 IEEE80211_RADIOTAP_VHT = 21,
92 IEEE80211_RADIOTAP_TIMESTAMP = 22,
93
94 /* valid in every it_present bitmap, even vendor namespaces */
95 IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
96 IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
97 IEEE80211_RADIOTAP_EXT = 31
98};
99
100/* for IEEE80211_RADIOTAP_FLAGS */
101enum ieee80211_radiotap_flags {
102 IEEE80211_RADIOTAP_F_CFP = 0x01,
103 IEEE80211_RADIOTAP_F_SHORTPRE = 0x02,
104 IEEE80211_RADIOTAP_F_WEP = 0x04,
105 IEEE80211_RADIOTAP_F_FRAG = 0x08,
106 IEEE80211_RADIOTAP_F_FCS = 0x10,
107 IEEE80211_RADIOTAP_F_DATAPAD = 0x20,
108 IEEE80211_RADIOTAP_F_BADFCS = 0x40,
109};
110
111/* for IEEE80211_RADIOTAP_CHANNEL */
112enum ieee80211_radiotap_channel_flags {
113 IEEE80211_CHAN_CCK = 0x0020,
114 IEEE80211_CHAN_OFDM = 0x0040,
115 IEEE80211_CHAN_2GHZ = 0x0080,
116 IEEE80211_CHAN_5GHZ = 0x0100,
117 IEEE80211_CHAN_DYN = 0x0400,
118 IEEE80211_CHAN_HALF = 0x4000,
119 IEEE80211_CHAN_QUARTER = 0x8000,
120};
121
122/* for IEEE80211_RADIOTAP_RX_FLAGS */
123enum ieee80211_radiotap_rx_flags {
124 IEEE80211_RADIOTAP_F_RX_BADPLCP = 0x0002,
125};
126
127/* for IEEE80211_RADIOTAP_TX_FLAGS */
128enum ieee80211_radiotap_tx_flags {
129 IEEE80211_RADIOTAP_F_TX_FAIL = 0x0001,
130 IEEE80211_RADIOTAP_F_TX_CTS = 0x0002,
131 IEEE80211_RADIOTAP_F_TX_RTS = 0x0004,
132 IEEE80211_RADIOTAP_F_TX_NOACK = 0x0008,
133};
134
135/* for IEEE80211_RADIOTAP_MCS "have" flags */
136enum ieee80211_radiotap_mcs_have {
137 IEEE80211_RADIOTAP_MCS_HAVE_BW = 0x01,
138 IEEE80211_RADIOTAP_MCS_HAVE_MCS = 0x02,
139 IEEE80211_RADIOTAP_MCS_HAVE_GI = 0x04,
140 IEEE80211_RADIOTAP_MCS_HAVE_FMT = 0x08,
141 IEEE80211_RADIOTAP_MCS_HAVE_FEC = 0x10,
142 IEEE80211_RADIOTAP_MCS_HAVE_STBC = 0x20,
143};
144
145enum ieee80211_radiotap_mcs_flags {
146 IEEE80211_RADIOTAP_MCS_BW_MASK = 0x03,
147 IEEE80211_RADIOTAP_MCS_BW_20 = 0,
148 IEEE80211_RADIOTAP_MCS_BW_40 = 1,
149 IEEE80211_RADIOTAP_MCS_BW_20L = 2,
150 IEEE80211_RADIOTAP_MCS_BW_20U = 3,
151
152 IEEE80211_RADIOTAP_MCS_SGI = 0x04,
153 IEEE80211_RADIOTAP_MCS_FMT_GF = 0x08,
154 IEEE80211_RADIOTAP_MCS_FEC_LDPC = 0x10,
155 IEEE80211_RADIOTAP_MCS_STBC_MASK = 0x60,
156 IEEE80211_RADIOTAP_MCS_STBC_1 = 1,
157 IEEE80211_RADIOTAP_MCS_STBC_2 = 2,
158 IEEE80211_RADIOTAP_MCS_STBC_3 = 3,
159 IEEE80211_RADIOTAP_MCS_STBC_SHIFT = 5,
160};
161
162/* for IEEE80211_RADIOTAP_AMPDU_STATUS */
163enum ieee80211_radiotap_ampdu_flags {
164 IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN = 0x0001,
165 IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN = 0x0002,
166 IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN = 0x0004,
167 IEEE80211_RADIOTAP_AMPDU_IS_LAST = 0x0008,
168 IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR = 0x0010,
169 IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN = 0x0020,
170};
171
172/* for IEEE80211_RADIOTAP_VHT */
173enum ieee80211_radiotap_vht_known {
174 IEEE80211_RADIOTAP_VHT_KNOWN_STBC = 0x0001,
175 IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA = 0x0002,
176 IEEE80211_RADIOTAP_VHT_KNOWN_GI = 0x0004,
177 IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS = 0x0008,
178 IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM = 0x0010,
179 IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED = 0x0020,
180 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH = 0x0040,
181 IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID = 0x0080,
182 IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID = 0x0100,
183};
184
185enum ieee80211_radiotap_vht_flags {
186 IEEE80211_RADIOTAP_VHT_FLAG_STBC = 0x01,
187 IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA = 0x02,
188 IEEE80211_RADIOTAP_VHT_FLAG_SGI = 0x04,
189 IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9 = 0x08,
190 IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM = 0x10,
191 IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED = 0x20,
192};
193
194enum ieee80211_radiotap_vht_coding {
195 IEEE80211_RADIOTAP_CODING_LDPC_USER0 = 0x01,
196 IEEE80211_RADIOTAP_CODING_LDPC_USER1 = 0x02,
197 IEEE80211_RADIOTAP_CODING_LDPC_USER2 = 0x04,
198 IEEE80211_RADIOTAP_CODING_LDPC_USER3 = 0x08,
199};
200
201/* for IEEE80211_RADIOTAP_TIMESTAMP */
202enum ieee80211_radiotap_timestamp_unit_spos {
203 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MASK = 0x000F,
204 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MS = 0x0000,
205 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US = 0x0001,
206 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_NS = 0x0003,
207 IEEE80211_RADIOTAP_TIMESTAMP_SPOS_MASK = 0x00F0,
208 IEEE80211_RADIOTAP_TIMESTAMP_SPOS_BEGIN_MDPU = 0x0000,
209 IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ = 0x0010,
210 IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_PPDU = 0x0020,
211 IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_MPDU = 0x0030,
212 IEEE80211_RADIOTAP_TIMESTAMP_SPOS_UNKNOWN = 0x00F0,
213};
214
215enum ieee80211_radiotap_timestamp_flags {
216 IEEE80211_RADIOTAP_TIMESTAMP_FLAG_64BIT = 0x00,
217 IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT = 0x01,
218 IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY = 0x02,
219};
220
221#endif /* __RADIOTAP_H */
diff --git a/src/libwifi/core/radiotap/radiotap_iter.h b/src/libwifi/core/radiotap/radiotap_iter.h new file mode 100644 index 0000000..5495a64 --- /dev/null +++ b/src/libwifi/core/radiotap/radiotap_iter.h
@@ -0,0 +1,101 @@
1#ifndef __RADIOTAP_ITER_H
2#define __RADIOTAP_ITER_H
3
4#include "platform.h"
5#include "radiotap.h"
6#include <stdint.h>
7
8/* Radiotap header iteration
9 * implemented in radiotap.c
10 */
11
12struct radiotap_override {
13 uint8_t field;
14 uint8_t align : 4, size : 4;
15};
16
17struct radiotap_align_size {
18 uint8_t align : 4, size : 4;
19};
20
21struct ieee80211_radiotap_namespace {
22 const struct radiotap_align_size *align_size;
23 int n_bits;
24 uint32_t oui;
25 uint8_t subns;
26};
27
28struct ieee80211_radiotap_vendor_namespaces {
29 const struct ieee80211_radiotap_namespace *ns;
30 int n_ns;
31};
32
33/**
34 * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
35 * @this_arg_index: index of current arg, valid after each successful call
36 * to ieee80211_radiotap_iterator_next()
37 * @this_arg: pointer to current radiotap arg; it is valid after each
38 * call to ieee80211_radiotap_iterator_next() but also after
39 * ieee80211_radiotap_iterator_init() where it will point to
40 * the beginning of the actual data portion
41 * @this_arg_size: length of the current arg, for convenience
42 * @current_namespace: pointer to the current namespace definition
43 * (or internally %NULL if the current namespace is unknown)
44 * @is_radiotap_ns: indicates whether the current namespace is the default
45 * radiotap namespace or not
46 *
47 * @overrides: override standard radiotap fields
48 * @n_overrides: number of overrides
49 *
50 * @_rtheader: pointer to the radiotap header we are walking through
51 * @_max_length: length of radiotap header in cpu byte ordering
52 * @_arg_index: next argument index
53 * @_arg: next argument pointer
54 * @_next_bitmap: internal pointer to next present u32
55 * @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
56 * @_vns: vendor namespace definitions
57 * @_next_ns_data: beginning of the next namespace's data
58 * @_reset_on_ext: internal; reset the arg index to 0 when going to the
59 * next bitmap word
60 *
61 * Describes the radiotap parser state. Fields prefixed with an underscore
62 * must not be used by users of the parser, only by the parser internally.
63 */
64
65struct ieee80211_radiotap_iterator {
66 struct ieee80211_radiotap_header *_rtheader;
67 const struct ieee80211_radiotap_vendor_namespaces *_vns;
68 const struct ieee80211_radiotap_namespace *current_namespace;
69
70 unsigned char *_arg, *_next_ns_data;
71 uint32_t *_next_bitmap;
72
73 unsigned char *this_arg;
74 const struct radiotap_override *overrides; /* Only for RADIOTAP_SUPPORT_OVERRIDES */
75 int n_overrides; /* Only for RADIOTAP_SUPPORT_OVERRIDES */
76 int this_arg_index;
77 int this_arg_size;
78
79 int is_radiotap_ns;
80
81 int _max_length;
82 int _arg_index;
83 uint32_t _bitmap_shifter;
84 int _reset_on_ext;
85};
86
87#ifdef __cplusplus
88#define CALLING_CONVENTION "C"
89#else
90#define CALLING_CONVENTION
91#endif
92
93IMPORT extern CALLING_CONVENTION int
94ieee80211_radiotap_iterator_init(struct ieee80211_radiotap_iterator *iterator,
95 struct ieee80211_radiotap_header *radiotap_header, int max_length,
96 const struct ieee80211_radiotap_vendor_namespaces *vns);
97
98IMPORT extern CALLING_CONVENTION int
99ieee80211_radiotap_iterator_next(struct ieee80211_radiotap_iterator *iterator);
100
101#endif /* __RADIOTAP_ITER_H */
diff --git a/src/libwifi/gen/control/cts.c b/src/libwifi/gen/control/cts.c new file mode 100644 index 0000000..f0e4df8 --- /dev/null +++ b/src/libwifi/gen/control/cts.c
@@ -0,0 +1,30 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "cts.h"
17
18#include <string.h>
19
20int libwifi_create_cts(struct libwifi_cts *cts, const unsigned char receiver[6], uint16_t duration) {
21 memset(cts, 0, sizeof(struct libwifi_cts));
22
23 cts->frame_header.frame_control.type = TYPE_CONTROL;
24 cts->frame_header.frame_control.subtype = SUBTYPE_CTS;
25 cts->frame_header.duration = duration;
26
27 memcpy(cts->receiver_addr, receiver, 6);
28
29 return 0;
30}
diff --git a/src/libwifi/gen/control/cts.h b/src/libwifi/gen/control/cts.h new file mode 100644 index 0000000..bd31d33 --- /dev/null +++ b/src/libwifi/gen/control/cts.h
@@ -0,0 +1,30 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_CTS_H
17#define LIBWIFI_GEN_CTS_H
18
19#include "../../core/frame/control/cts.h"
20
21/**
22 * Create a CTS Control frame
23 *
24 * @param cts A fresh libwifi_cts struct
25 * @param receiver The receiver MAC address
26 * @param duration The duration of the clear-to-send
27 */
28int libwifi_create_cts(struct libwifi_cts *cts, const unsigned char receiver[6], uint16_t duration);
29
30#endif /* LIBWIFI_GEN_CTS_H */
diff --git a/src/libwifi/gen/control/rts.c b/src/libwifi/gen/control/rts.c new file mode 100644 index 0000000..e1710f9 --- /dev/null +++ b/src/libwifi/gen/control/rts.c
@@ -0,0 +1,32 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "rts.h"
17
18#include <string.h>
19
20int libwifi_create_rts(struct libwifi_rts *rts, const unsigned char transmitter[6],
21 const unsigned char receiver[6], uint16_t duration) {
22 memset(rts, 0, sizeof(struct libwifi_rts));
23
24 rts->frame_header.frame_control.type = TYPE_CONTROL;
25 rts->frame_header.frame_control.subtype = SUBTYPE_RTS;
26 rts->frame_header.duration = duration;
27
28 memcpy(rts->transmitter_addr, transmitter, 6);
29 memcpy(rts->receiver_addr, receiver, 6);
30
31 return 0;
32}
diff --git a/src/libwifi/gen/control/rts.h b/src/libwifi/gen/control/rts.h new file mode 100644 index 0000000..4ad0bae --- /dev/null +++ b/src/libwifi/gen/control/rts.h
@@ -0,0 +1,32 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_RTS_H
17#define LIBWIFI_GEN_RTS_H
18
19#include "../../core/frame/control/rts.h"
20
21/**
22 * Create a RTS Control frame
23 *
24 * @param rts A fresh libwifi_rts struct
25 * @param transmitter The transmitter MAC address
26 * @param receiver The receiver MAC address
27 * @param duration The duration of the clear-to-send
28 */
29int libwifi_create_rts(struct libwifi_rts *rts, const unsigned char transmitter[6],
30 const unsigned char receiver[6], uint16_t duration);
31
32#endif /* LIBWIFI_GEN_RTS_H */
diff --git a/src/libwifi/gen/management/action.c b/src/libwifi/gen/management/action.c new file mode 100644 index 0000000..04d7a5f --- /dev/null +++ b/src/libwifi/gen/management/action.c
@@ -0,0 +1,110 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "action.h"
17
18#include <errno.h>
19#include <stdlib.h>
20#include <string.h>
21
22size_t libwifi_add_action_detail(struct libwifi_action_detail *detail, const unsigned char *data,
23 size_t data_len) {
24 if (detail->detail_length != 0) {
25 detail->detail = realloc(detail->detail, data_len);
26 } else {
27 detail->detail = malloc(data_len);
28 }
29
30 if (detail->detail == NULL) {
31 return -EINVAL;
32 }
33
34 detail->detail_length = data_len;
35
36 memcpy(detail->detail, data, data_len);
37 detail->detail_length = data_len;
38
39 return detail->detail_length;
40}
41
42void libwifi_free_action_detail(struct libwifi_action_detail *detail) {
43 if (detail->detail_length != 0) {
44 free(detail->detail);
45 detail->detail_length = 0;
46 }
47}
48
49int libwifi_create_action(struct libwifi_action *action, const unsigned char receiver[6],
50 const unsigned char transmitter[6], uint8_t category) {
51 memset(action, 0, sizeof(struct libwifi_action));
52
53 action->frame_header.frame_control.type = TYPE_MANAGEMENT;
54 action->frame_header.frame_control.subtype = SUBTYPE_ACTION;
55 memcpy(&action->frame_header.addr1, receiver, 6);
56 memcpy(&action->frame_header.addr2, transmitter, 6);
57 memcpy(&action->frame_header.addr3, transmitter, 6);
58
59 action->frame_header.seq_control.sequence_number = (rand() % 4096);
60
61 action->fixed_parameters.category = category;
62
63 return 0;
64}
65
66int libwifi_create_action_no_ack(struct libwifi_action *action, const unsigned char receiver[6],
67 const unsigned char transmitter[6], uint8_t category) {
68 memset(action, 0, sizeof(struct libwifi_action));
69
70 action->frame_header.frame_control.type = TYPE_MANAGEMENT;
71 action->frame_header.frame_control.subtype = SUBTYPE_ACTION_NOACK;
72 memcpy(&action->frame_header.addr1, receiver, 6);
73 memcpy(&action->frame_header.addr2, transmitter, 6);
74 memcpy(&action->frame_header.addr3, transmitter, 6);
75
76 action->frame_header.seq_control.sequence_number = (rand() % 4096);
77
78 action->fixed_parameters.category = category;
79
80 return 0;
81}
82
83size_t libwifi_get_action_length(struct libwifi_action *action) {
84 return sizeof(struct libwifi_mgmt_unordered_frame_header) + sizeof(action->fixed_parameters.category) +
85 action->fixed_parameters.details.detail_length;
86}
87
88size_t libwifi_dump_action(struct libwifi_action *action, unsigned char *buf, size_t buf_len) {
89 size_t action_len = libwifi_get_action_length(action);
90 if (action_len > buf_len) {
91 return -EINVAL;
92 }
93
94 size_t offset = 0;
95
96 memcpy(buf + offset, &action->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
97 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
98
99 memcpy(buf + offset, &action->fixed_parameters.category, sizeof(action->fixed_parameters.category));
100 offset += sizeof(action->fixed_parameters.category);
101 memcpy(buf + offset, action->fixed_parameters.details.detail,
102 action->fixed_parameters.details.detail_length);
103 offset += action->fixed_parameters.details.detail_length;
104
105 return action_len;
106}
107
108void libwifi_free_action(struct libwifi_action *action) {
109 free(action->fixed_parameters.details.detail);
110}
diff --git a/src/libwifi/gen/management/action.h b/src/libwifi/gen/management/action.h new file mode 100644 index 0000000..ae1b5cc --- /dev/null +++ b/src/libwifi/gen/management/action.h
@@ -0,0 +1,80 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_ACTION_H
17#define LIBWIFI_GEN_ACTION_H
18
19#include "../../core/frame/management/action.h"
20#include <stdint.h>
21
22/**
23 * Create a detail for an action frame by supplying raw data and it's length.
24 * New data can be added to an existing libwifi_action_detail.
25 *
26 * @param detail A libwifi_action_detail struct
27 * @param data Raw data to be added to the libwifi_action_detail
28 * @param data_len Length of the raw data
29 * @return Length of the action
30 */
31size_t libwifi_add_action_detail(struct libwifi_action_detail *detail, const unsigned char *data,
32 size_t data_len);
33
34/**
35 * Free all memory in a given libwifi_action_detail.
36 *
37 * @param detail A used libwifi_action_detail struct
38 */
39void libwifi_free_action_detail(struct libwifi_action_detail *detail);
40
41/**
42 * Create a new action frame with a specified action and category.
43 *
44 * @param action A new libwifi_action struct
45 * @param receiver The receiver MAC address
46 * @param transmitter The transmitter MAC address
47 * @param category The action frame category
48 * @return zero on success
49 */
50int libwifi_create_action(struct libwifi_action *action, const unsigned char receiver[6],
51 const unsigned char transmitter[6], uint8_t category);
52int libwifi_create_action_no_ack(struct libwifi_action *action, const unsigned char receiver[6],
53 const unsigned char transmitter[6], uint8_t category);
54
55/**
56 * Get the length of a given libwifi_action
57 *
58 * @param action A used libwifi_action struct
59 * @return The length of the given libwifi_action
60 */
61size_t libwifi_get_action_length(struct libwifi_action *action);
62
63/**
64 * Dump a given libwifi_action to a raw buffer
65 *
66 * @param action A used libwifi_action struct
67 * @param buf A buffer receiver
68 * @param buf_len The length of the given buf
69 * @return Bytes written to the buf
70 */
71size_t libwifi_dump_action(struct libwifi_action *action, unsigned char *buf, size_t buf_len);
72
73/**
74 * Free data associated to a given libwifi_action
75 *
76 * @param action A used libwifi_action struct
77 */
78void libwifi_free_action(struct libwifi_action *action);
79
80#endif /* LIBWIFI_GEN_ACTION_H */
diff --git a/src/libwifi/gen/management/assoc_request.c b/src/libwifi/gen/management/assoc_request.c new file mode 100644 index 0000000..8ba3585 --- /dev/null +++ b/src/libwifi/gen/management/assoc_request.c
@@ -0,0 +1,85 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "assoc_request.h"
17#include "common.h"
18
19#include <errno.h>
20#include <stdlib.h>
21#include <string.h>
22
23/**
24 * The length of an association request frame is the sum of the header length, the fixed parameters length,
25 * and the tagged parameters length.
26 */
27size_t libwifi_get_assoc_req_length(struct libwifi_assoc_req *assoc_req) {
28 return sizeof(assoc_req->frame_header) + sizeof(struct libwifi_assoc_req_fixed_parameters) +
29 assoc_req->tags.length;
30}
31
32/**
33 * The generated association request frame is made with sane defaults defined in common.h.
34 * Two tagged parameters are also added to the association request: SSID and Channel.
35 */
36int libwifi_create_assoc_req(struct libwifi_assoc_req *assoc_req, const unsigned char receiver[6],
37 const unsigned char transmitter[6], const char *ssid, uint8_t channel) {
38 memset(assoc_req, 0, sizeof(struct libwifi_assoc_req));
39
40 assoc_req->frame_header.frame_control.type = TYPE_MANAGEMENT;
41 assoc_req->frame_header.frame_control.subtype = SUBTYPE_ASSOC_REQ;
42 memcpy(&assoc_req->frame_header.addr1, receiver, 6);
43 memcpy(&assoc_req->frame_header.addr2, transmitter, 6);
44 memcpy(&assoc_req->frame_header.addr3, receiver, 6);
45 assoc_req->frame_header.seq_control.sequence_number = (rand() % 4096);
46
47 assoc_req->fixed_parameters.capabilities_information = BYTESWAP16(LIBWIFI_DEFAULT_AP_CAPABS);
48 assoc_req->fixed_parameters.listen_interval = BYTESWAP16(LIBWIFI_DEFAULT_LISTEN_INTERVAL);
49
50 libwifi_quick_add_tag(&assoc_req->tags, TAG_SSID, (const unsigned char *) ssid, strlen(ssid));
51 libwifi_quick_add_tag(&assoc_req->tags, TAG_DS_PARAMETER, (const unsigned char *) &channel, 1);
52
53 return 0;
54}
55
56/**
57 * Copy a libwifi_assoc_req into a regular unsigned char buffer. This is useful when injecting generated
58 * libwifi frames.
59 */
60size_t libwifi_dump_assoc_req(struct libwifi_assoc_req *assoc_req, unsigned char *buf, size_t buf_len) {
61 size_t assoc_req_len = libwifi_get_assoc_req_length(assoc_req);
62 if (assoc_req_len > buf_len) {
63 return -EINVAL;
64 }
65
66 size_t offset = 0;
67 memcpy(buf + offset, &assoc_req->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
68 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
69
70 memcpy(buf + offset, &assoc_req->fixed_parameters, sizeof(struct libwifi_assoc_req_fixed_parameters));
71 offset += sizeof(struct libwifi_assoc_req_fixed_parameters);
72
73 memcpy(buf + offset, assoc_req->tags.parameters, assoc_req->tags.length);
74 offset += assoc_req->tags.length;
75
76 return assoc_req_len;
77}
78
79/**
80 * Because the tagged parameters memory is managed inside of the library, the library must
81 * be the one to free it, too.
82 */
83void libwifi_free_assoc_req(struct libwifi_assoc_req *assoc_req) {
84 free(assoc_req->tags.parameters);
85}
diff --git a/src/libwifi/gen/management/assoc_request.h b/src/libwifi/gen/management/assoc_request.h new file mode 100644 index 0000000..85cbd3b --- /dev/null +++ b/src/libwifi/gen/management/assoc_request.h
@@ -0,0 +1,39 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_ASSOCREQUEST_H
17#define LIBWIFI_GEN_ASSOCREQUEST_H
18
19#include "../../core/frame/frame.h"
20#include "../../core/frame/management/assoc_request.h"
21#include "../../core/frame/management/common.h"
22
23/**
24 * Create a new association request
25 *
26 * @param assoc_req A new libwifi_assoc_req struct
27 * @param receiver The receiver MAC address
28 * @param transmitter The transmitter MAC address
29 * @param ssid The desired BSS SSID
30 * @param channel The desired channel
31 * @param zero on success
32 */
33int libwifi_create_assoc_req(struct libwifi_assoc_req *assoc_req, const unsigned char receiver[6],
34 const unsigned char transmitter[6], const char *ssid, uint8_t channel);
35size_t libwifi_get_assoc_req_length(struct libwifi_assoc_req *assoc_req);
36size_t libwifi_dump_assoc_req(struct libwifi_assoc_req *assoc_req, unsigned char *buf, size_t buf_len);
37void libwifi_free_assoc_req(struct libwifi_assoc_req *assoc_req);
38
39#endif /* LIBWIFI_GEN_ASSOCREQUEST_H */
diff --git a/src/libwifi/gen/management/assoc_response.c b/src/libwifi/gen/management/assoc_response.c new file mode 100644 index 0000000..be00511 --- /dev/null +++ b/src/libwifi/gen/management/assoc_response.c
@@ -0,0 +1,106 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "assoc_response.h"
17#include "../../core/frame/tag.h"
18#include "../../core/frame/tag_iterator.h"
19#include "../../core/misc/byteswap.h"
20#include "../../core/misc/epoch.h"
21#include "../../core/misc/types.h"
22#include "common.h"
23
24#include <errno.h>
25#include <stdint.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/types.h>
30
31/**
32 * The length of an association response frame is the sum of the header length, the fixed parameters length,
33 * and the tagged parameters length.
34 */
35size_t libwifi_get_assoc_resp_length(struct libwifi_assoc_resp *assoc_resp) {
36 return sizeof(struct libwifi_mgmt_unordered_frame_header) +
37 sizeof(struct libwifi_assoc_resp_fixed_parameters) + assoc_resp->tags.length;
38}
39
40/**
41 * Simple helper function to set the channel of an association response by removing and re-adding the
42 * DS tagged parameter.
43 */
44void libwifi_set_assoc_resp_channel(struct libwifi_assoc_resp *assoc_resp, uint8_t channel) {
45 if (assoc_resp->tags.length != 0) {
46 libwifi_remove_tag(&assoc_resp->tags, TAG_DS_PARAMETER);
47 }
48
49 const unsigned char *chan = (const unsigned char *) &channel;
50
51 libwifi_quick_add_tag(&assoc_resp->tags, TAG_DS_PARAMETER, chan, 1);
52}
53
54/**
55 * The generated association response frame is made with sane defaults defined in common.h and core/types.h.
56 * Two tagged parameters are also added to the association response: Channel and Supported Rates.
57 */
58void libwifi_create_assoc_resp(struct libwifi_assoc_resp *assoc_resp, const unsigned char receiver[6],
59 const unsigned char transmitter[6], uint8_t channel) {
60 memset(assoc_resp, 0, sizeof(struct libwifi_assoc_resp));
61
62 assoc_resp->frame_header.frame_control.type = TYPE_MANAGEMENT;
63 assoc_resp->frame_header.frame_control.subtype = SUBTYPE_ASSOC_RESP;
64 memcpy(&assoc_resp->frame_header.addr1, receiver, 6);
65 memcpy(&assoc_resp->frame_header.addr2, transmitter, 6);
66
67 assoc_resp->fixed_parameters.capabilities_information = BYTESWAP16(LIBWIFI_DEFAULT_AP_CAPABS);
68 assoc_resp->fixed_parameters.status_code = STATUS_SUCCESS;
69 assoc_resp->fixed_parameters.association_id = rand() % 4096;
70
71 libwifi_set_assoc_resp_channel(assoc_resp, channel);
72
73 const unsigned char supported_rates[] = LIBWIFI_DEFAULT_SUPP_RATES;
74 libwifi_quick_add_tag(&assoc_resp->tags, TAG_SUPP_RATES, supported_rates, sizeof(supported_rates) - 1);
75}
76
77/**
78 * Copy a libwifi_assoc_resp into a regular unsigned char buffer. This is useful when injecting generated
79 * libwifi frames.
80 */
81size_t libwifi_dump_assoc_resp(struct libwifi_assoc_resp *assoc_resp, unsigned char *buf, size_t buf_len) {
82 size_t assoc_resp_len = libwifi_get_assoc_resp_length(assoc_resp);
83 if (assoc_resp_len > buf_len) {
84 return -EINVAL;
85 }
86
87 size_t offset = 0;
88 memcpy(buf + offset, &assoc_resp->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
89 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
90
91 memcpy(buf + offset, &assoc_resp->fixed_parameters, sizeof(struct libwifi_assoc_resp_fixed_parameters));
92 offset += sizeof(struct libwifi_assoc_resp_fixed_parameters);
93
94 memcpy(buf + offset, assoc_resp->tags.parameters, assoc_resp->tags.length);
95 offset += assoc_resp->tags.length;
96
97 return assoc_resp_len;
98}
99
100/**
101 * Because the tagged parameters memory is managed inside of the library, the library must
102 * be the one to free it, too.
103 */
104void libwifi_free_assoc_resp(struct libwifi_assoc_resp *assoc_resp) {
105 free(assoc_resp->tags.parameters);
106}
diff --git a/src/libwifi/gen/management/assoc_response.h b/src/libwifi/gen/management/assoc_response.h new file mode 100644 index 0000000..9162d1c --- /dev/null +++ b/src/libwifi/gen/management/assoc_response.h
@@ -0,0 +1,69 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_ASSOCRESP_H
17#define LIBWIFI_GEN_ASSOCRESP_H
18
19#include "../../core/frame/management/assoc_response.h"
20
21/**
22 * Set the channel of a libwifi_assoc_resp.
23 *
24 * @param assoc_resp A libwifi_assoc_resp
25 * @param channel The new channel
26 */
27void libwifi_set_assoc_resp_channel(struct libwifi_assoc_resp *assoc_resp, uint8_t channel);
28
29/**
30 * Calculate the length of a given libwifi_assoc_resp
31 *
32 * @param assoc_resp A libwifi_assoc_resp
33 * @return The length of the given assoc_resp
34 */
35size_t libwifi_get_assoc_resp_length(struct libwifi_assoc_resp *assoc_resp);
36
37/**
38 * Generate a populated libwifi assoc_resp.
39 *
40 * A generated libwifi assoc_resp can be "dumped" into a buffer for packet injection
41 * via the libwifi_dump_assoc_resp.
42 *
43 * @param assoc_resp A libwifi_assoc_resp
44 * @param receiver The receiver MAC address, aka address 1
45 * @param transmitter The source MAC address, aka address 2
46 * @param channel The desired channel of the assoc_resp
47 *
48 */
49void libwifi_create_assoc_resp(struct libwifi_assoc_resp *assoc_resp, const unsigned char receiver[6],
50 const unsigned char transmitter[6], uint8_t channel);
51
52/**
53 * Dump a libwifi_assoc_resp into a raw format for packet injection.
54 *
55 * @param assoc_resp A libwifi_assoc_resp
56 * @param buf The output buffer for the frame data
57 * @param buf_len The length of the output buffer
58 * @return The length of the dumped assoc_resp
59 */
60size_t libwifi_dump_assoc_resp(struct libwifi_assoc_resp *assoc_resp, unsigned char *buf, size_t buf_len);
61
62/**
63 * Free any memory claimed by a libwifi_assoc_resp back to the system.
64 *
65 * @param assoc_resp A libwifi_assoc_resp
66 */
67void libwifi_free_assoc_resp(struct libwifi_assoc_resp *assoc_resp);
68
69#endif /* LIBWIFI_GEN_ASSOCRESP_H */
diff --git a/src/libwifi/gen/management/atim.c b/src/libwifi/gen/management/atim.c new file mode 100644 index 0000000..960a2de --- /dev/null +++ b/src/libwifi/gen/management/atim.c
@@ -0,0 +1,35 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "atim.h"
17
18#include <stdlib.h>
19#include <string.h>
20
21int libwifi_create_atim(struct libwifi_atim *atim, const unsigned char transmitter[6],
22 const unsigned char receiver[6], const unsigned char bssid[6]) {
23 memset(atim, 0, sizeof(struct libwifi_atim));
24
25 atim->frame_header.frame_control.type = TYPE_MANAGEMENT;
26 atim->frame_header.frame_control.subtype = SUBTYPE_ATIM;
27 memcpy(&atim->frame_header.addr1, transmitter, 6);
28 memcpy(&atim->frame_header.addr2, receiver, 6);
29 memcpy(&atim->frame_header.addr3, bssid, 6);
30 atim->frame_header.frame_control.flags.power_mgmt = 1;
31 atim->frame_header.duration = (rand() % 4096);
32 atim->frame_header.seq_control.sequence_number = (rand() % 4096);
33
34 return 0;
35}
diff --git a/src/libwifi/gen/management/atim.h b/src/libwifi/gen/management/atim.h new file mode 100644 index 0000000..d9a306a --- /dev/null +++ b/src/libwifi/gen/management/atim.h
@@ -0,0 +1,24 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_ATIM_H
17#define LIBWIFI_GEN_ATIM_H
18
19#include "../../core/frame/management/atim.h"
20
21int libwifi_create_atim(struct libwifi_atim *atim, const unsigned char transmitter[6],
22 const unsigned char receiver[6], const unsigned char bssid[6]);
23
24#endif /* LIBWIFI_GEN_ATIM_H */
diff --git a/src/libwifi/gen/management/authentication.c b/src/libwifi/gen/management/authentication.c new file mode 100644 index 0000000..7fcaa22 --- /dev/null +++ b/src/libwifi/gen/management/authentication.c
@@ -0,0 +1,81 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "authentication.h"
17#include "../../core/misc/byteswap.h"
18
19#include <errno.h>
20#include <stdlib.h>
21#include <string.h>
22
23/**
24 * The length of an authentication frame is the sum of the header length, the fixed parameters length, and the
25 * tagged parameters length.
26 */
27size_t libwifi_get_auth_length(struct libwifi_auth *auth) {
28 return sizeof(struct libwifi_mgmt_unordered_frame_header) + sizeof(struct libwifi_auth_fixed_parameters) +
29 auth->tags.length;
30}
31
32/**
33 * The generated authentication frame is made with sane defaults defined in common.h.
34 */
35void libwifi_create_auth(struct libwifi_auth *auth, const unsigned char receiver[6],
36 const unsigned char transmitter[6], uint16_t algorithm_number,
37 uint16_t transaction_sequence, uint16_t status_code) {
38 memset(auth, 0, sizeof(struct libwifi_auth));
39
40 auth->frame_header.frame_control.type = TYPE_MANAGEMENT;
41 auth->frame_header.frame_control.subtype = SUBTYPE_AUTH;
42 memcpy(&auth->frame_header.addr1, receiver, 6);
43 memcpy(&auth->frame_header.addr2, transmitter, 6);
44 memcpy(&auth->frame_header.addr3, transmitter, 6);
45 auth->frame_header.seq_control.sequence_number = (rand() % 4096);
46
47 auth->fixed_parameters.algorithm_number = algorithm_number;
48 auth->fixed_parameters.transaction_sequence = transaction_sequence;
49 auth->fixed_parameters.status_code = status_code;
50}
51
52/**
53 * Copy a libwifi_auth into a regular unsigned char buffer. This is useful when injecting generated
54 * libwifi frames.
55 */
56size_t libwifi_dump_auth(struct libwifi_auth *auth, unsigned char *buf, size_t buf_len) {
57 size_t auth_len = libwifi_get_auth_length(auth);
58 if (auth_len > buf_len) {
59 return -EINVAL;
60 }
61
62 size_t offset = 0;
63 memcpy(buf + offset, &auth->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
64 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
65
66 memcpy(buf + offset, &auth->fixed_parameters, sizeof(struct libwifi_auth_fixed_parameters));
67 offset += sizeof(struct libwifi_auth_fixed_parameters);
68
69 memcpy(buf + offset, auth->tags.parameters, auth->tags.length);
70 offset += auth->tags.length;
71
72 return auth_len;
73}
74
75/**
76 * Because the tagged parameters memory is managed inside of the library, the library must
77 * be the one to free it, too.
78 */
79void libwifi_free_auth(struct libwifi_auth *auth) {
80 free(auth->tags.parameters);
81}
diff --git a/src/libwifi/gen/management/authentication.h b/src/libwifi/gen/management/authentication.h new file mode 100644 index 0000000..4328f95 --- /dev/null +++ b/src/libwifi/gen/management/authentication.h
@@ -0,0 +1,64 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_AUTH_H
17#define LIBWIFI_GEN_AUTH_H
18
19#include <stdint.h>
20
21#include "../../core/frame/management/authentication.h"
22
23/**
24 * Calculate the length of a given libwifi_auth
25 *
26 * @param auth A libwifi_auth
27 * @return The length of the given auth
28 */
29size_t libwifi_get_auth_length(struct libwifi_auth *auth);
30
31/**
32 * Generate a populated libwifi auth.
33 *
34 * A generated libwifi auth can be "dumped" into a buffer for packet injection
35 * via the libwifi_dump_auth.
36 *
37 * @param auth A libwifi_auth
38 * @param receiver The receiver MAC address, aka address 1
39 * @param transmitter The source MAC address, aka address 2
40 * @param algorithm_number Algorithm type to use
41 *
42 */
43void libwifi_create_auth(struct libwifi_auth *auth, const unsigned char receiver[6],
44 const unsigned char transmitter[6], uint16_t algorithm_number,
45 uint16_t transaction_sequence, uint16_t status_code);
46
47/**
48 * Dump a libwifi_auth into a raw format for packet injection.
49 *
50 * @param auth A libwifi_auth
51 * @param buf The output buffer for the frame data
52 * @param buf_len The length of the output buffer
53 * @return The length of the dumped auth
54 */
55size_t libwifi_dump_auth(struct libwifi_auth *auth, unsigned char *buf, size_t buf_len);
56
57/**
58 * Free any memory claimed by a libwifi_auth back to the system.
59 *
60 * @param auth A libwifi_auth
61 */
62void libwifi_free_auth(struct libwifi_auth *auth);
63
64#endif /* LIBWIFI_GEN_AUTH_H */
diff --git a/src/libwifi/gen/management/beacon.c b/src/libwifi/gen/management/beacon.c new file mode 100644 index 0000000..4eb394a --- /dev/null +++ b/src/libwifi/gen/management/beacon.c
@@ -0,0 +1,117 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "beacon.h"
17#include "../../core/frame/tag.h"
18#include "../../core/frame/tag_iterator.h"
19#include "../../core/misc/byteswap.h"
20#include "../../core/misc/epoch.h"
21#include "common.h"
22
23#include <errno.h>
24#include <stdint.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <sys/types.h>
29
30/**
31 * The length of a beacon frame is the sum of the header length, the fixed parameters length, and the tagged
32 * parameters length.
33 */
34size_t libwifi_get_beacon_length(struct libwifi_beacon *beacon) {
35 return sizeof(struct libwifi_mgmt_unordered_frame_header) +
36 sizeof(struct libwifi_beacon_fixed_parameters) + beacon->tags.length;
37}
38
39/**
40 * Simple helper to set the beacon SSID tag by removing it and then adding it back with the new value.
41 */
42void libwifi_set_beacon_ssid(struct libwifi_beacon *beacon, const char *ssid) {
43 if (beacon->tags.length != 0) {
44 libwifi_remove_tag(&beacon->tags, TAG_SSID);
45 }
46
47 libwifi_quick_add_tag(&beacon->tags, TAG_SSID, (void *) ssid, strlen(ssid));
48}
49
50/**
51 * Simple helper to set the beacon DS tag by removing it and then adding it back with the new value.
52 */
53void libwifi_set_beacon_channel(struct libwifi_beacon *beacon, uint8_t channel) {
54 if (beacon->tags.length != 0) {
55 libwifi_remove_tag(&beacon->tags, TAG_DS_PARAMETER);
56 }
57
58 const unsigned char *chan = (const unsigned char *) &channel;
59
60 libwifi_quick_add_tag(&beacon->tags, TAG_DS_PARAMETER, chan, 1);
61}
62
63/**
64 * The generated beacon frame is made with sane defaults defined in common.h.
65 * Three tagged parameters are also added to the beacon: SSID, Channel and Supported Rates.
66 */
67void libwifi_create_beacon(struct libwifi_beacon *beacon, const unsigned char receiver[6],
68 const unsigned char transmitter[6], const char *ssid, uint8_t channel) {
69 memset(beacon, 0, sizeof(struct libwifi_beacon));
70
71 beacon->frame_header.frame_control.type = TYPE_MANAGEMENT;
72 beacon->frame_header.frame_control.subtype = SUBTYPE_BEACON;
73 memcpy(&beacon->frame_header.addr1, receiver, 6);
74 memcpy(&beacon->frame_header.addr2, transmitter, 6);
75 beacon->frame_header.seq_control.sequence_number = (rand() % 4096);
76
77 beacon->fixed_parameters.timestamp = BYTESWAP64(libwifi_get_epoch());
78 beacon->fixed_parameters.beacon_interval = BYTESWAP16(LIBWIFI_DEFAULT_BEACON_INTERVAL);
79 beacon->fixed_parameters.capabilities_information = BYTESWAP16(LIBWIFI_DEFAULT_AP_CAPABS);
80
81 libwifi_set_beacon_ssid(beacon, ssid);
82 libwifi_set_beacon_channel(beacon, channel);
83
84 const unsigned char supported_rates[] = LIBWIFI_DEFAULT_SUPP_RATES;
85 libwifi_quick_add_tag(&beacon->tags, TAG_SUPP_RATES, supported_rates, sizeof(supported_rates) - 1);
86}
87
88/**
89 * Copy a libwifi_beacon into a regular unsigned char buffer. This is useful when injecting generated
90 * libwifi frames.
91 */
92size_t libwifi_dump_beacon(struct libwifi_beacon *beacon, unsigned char *buf, size_t buf_len) {
93 size_t beacon_len = libwifi_get_beacon_length(beacon);
94 if (beacon_len > buf_len) {
95 return -EINVAL;
96 }
97
98 size_t offset = 0;
99 memcpy(buf + offset, &beacon->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
100 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
101
102 memcpy(buf + offset, &beacon->fixed_parameters, sizeof(struct libwifi_beacon_fixed_parameters));
103 offset += sizeof(struct libwifi_beacon_fixed_parameters);
104
105 memcpy(buf + offset, beacon->tags.parameters, beacon->tags.length);
106 offset += beacon->tags.length;
107
108 return beacon_len;
109}
110
111/**
112 * Because the tagged parameters memory is managed inside of the library, the library must
113 * be the one to free it, too.
114 */
115void libwifi_free_beacon(struct libwifi_beacon *beacon) {
116 free(beacon->tags.parameters);
117}
diff --git a/src/libwifi/gen/management/beacon.h b/src/libwifi/gen/management/beacon.h new file mode 100644 index 0000000..3da342b --- /dev/null +++ b/src/libwifi/gen/management/beacon.h
@@ -0,0 +1,78 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_BEACON_H
17#define LIBWIFI_GEN_BEACON_H
18
19#include "../../core/frame/management/beacon.h"
20
21/**
22 * Set the SSID of a struct libwifi_beacon.
23 *
24 * @param beacon A struct libwifi_beacon
25 * @param ssid The new SSID
26 */
27void libwifi_set_beacon_ssid(struct libwifi_beacon *beacon, const char *ssid);
28
29/**
30 * Set the channel of a struct libwifi_beacon.
31 *
32 * @param beacon A struct libwifi_beacon
33 * @param channel The new channel
34 */
35void libwifi_set_beacon_channel(struct libwifi_beacon *beacon, uint8_t channel);
36
37/**
38 * Calculate the length of a given struct libwifi_beacon
39 *
40 * @param beacon A struct libwifi_beacon
41 * @return The length of the given beacon
42 */
43size_t libwifi_get_beacon_length(struct libwifi_beacon *beacon);
44
45/**
46 * Generate a populated libwifi beacon.
47 *
48 * A generated libwifi beacon can be "dumped" into a buffer for packet injection
49 * via the libwifi_dump_beacon.
50 *
51 * @param beacon A struct libwifi_beacon
52 * @param receiver The receiver MAC address, aka address 1
53 * @param transmitter The source MAC address, aka address 2
54 * @param ssid The SSID of the beacon. Maximum length is 32 characters
55 * @param channel The desired channel of the beacon
56 *
57 */
58void libwifi_create_beacon(struct libwifi_beacon *beacon, const unsigned char receiver[6],
59 const unsigned char transmitter[6], const char *ssid, uint8_t channel);
60
61/**
62 * Dump a struct libwifi_beacon into a raw format for packet injection.
63 *
64 * @param beacon A struct libwifi_beacon
65 * @param buf The output buffer for the frame data
66 * @param buf_len The length of the output buffer
67 * @return The length of the dumped beacon
68 */
69size_t libwifi_dump_beacon(struct libwifi_beacon *beacon, unsigned char *buf, size_t buf_len);
70
71/**
72 * Free any memory claimed by a struct libwifi_beacon back to the system.
73 *
74 * @param beacon A struct libwifi_beacon
75 */
76void libwifi_free_beacon(struct libwifi_beacon *beacon);
77
78#endif /* LIBWIFI_GEN_BEACON_H */
diff --git a/src/libwifi/gen/management/common.h b/src/libwifi/gen/management/common.h new file mode 100644 index 0000000..ec3b744 --- /dev/null +++ b/src/libwifi/gen/management/common.h
@@ -0,0 +1,54 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_COMMON_H
17#define LIBWIFI_GEN_COMMON_H
18
19/**
20 * A sane default for an AP-side capabilities information field.
21 *
22 * 0x0001 = Transmitter is an AP
23 */
24#define LIBWIFI_DEFAULT_AP_CAPABS 0x0001
25
26/**
27 * A sane default for an STA-side capabilities information field.
28 *
29 * 0x0000 = None
30 */
31#define LIBWIFI_DEFAULT_STA_CAPABS 0x0000
32
33/**
34 * A sane default for the listen_interval field.
35 *
36 * 0x0001 = 1 Beacon Interval
37 */
38#define LIBWIFI_DEFAULT_LISTEN_INTERVAL 0x0001
39
40/**
41 * A sane default for a beacon_interval field.
42 *
43 * 0x0064 = 0.1024 Seconds
44 */
45#define LIBWIFI_DEFAULT_BEACON_INTERVAL 0x0064
46
47/**
48 * A sane default for the supported rates frame field.
49 *
50 * 1, 2, 5.5, 11, 18, 24, 36, 54 Mbit/s
51 */
52#define LIBWIFI_DEFAULT_SUPP_RATES "\x82\x84\x8b\x96\x24\x30\x48\x6c"
53
54#endif /* LIBWIFI_GEN_COMMON_H */
diff --git a/src/libwifi/gen/management/deauthentication.c b/src/libwifi/gen/management/deauthentication.c new file mode 100644 index 0000000..14f2c26 --- /dev/null +++ b/src/libwifi/gen/management/deauthentication.c
@@ -0,0 +1,82 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "deauthentication.h"
17#include "../../core/misc/byteswap.h"
18
19#include <errno.h>
20#include <stdlib.h>
21#include <string.h>
22
23/**
24 * The length of a deauth frame is the sum of the header length, the fixed parameters length, and the tagged
25 * parameters length.
26 */
27size_t libwifi_get_deauth_length(struct libwifi_deauth *deauth) {
28 return sizeof(struct libwifi_mgmt_unordered_frame_header) +
29 sizeof(struct libwifi_deauth_fixed_parameters) + deauth->tags.length;
30}
31
32/**
33 * The generated deauthentication frame contains only the supplied receiver, transmitter and reason_code by
34 * default.
35 */
36int libwifi_create_deauth(struct libwifi_deauth *deauth, const unsigned char receiver[6],
37 const unsigned char transmitter[6], uint16_t reason_code) {
38 memset(deauth, 0, sizeof(struct libwifi_deauth));
39
40 deauth->frame_header.frame_control.type = TYPE_MANAGEMENT;
41 deauth->frame_header.frame_control.subtype = SUBTYPE_DEAUTH;
42 memcpy(&deauth->frame_header.addr1, receiver, 6);
43 memcpy(&deauth->frame_header.addr2, transmitter, 6);
44 memcpy(&deauth->frame_header.addr3, transmitter, 6);
45
46 deauth->frame_header.seq_control.sequence_number = (rand() % 4096);
47
48 memcpy(&deauth->fixed_parameters.reason_code, &reason_code, sizeof(reason_code));
49
50 return 0;
51}
52
53/**
54 * Copy a libwifi_deauth into a regular unsigned char buffer. This is useful when injecting generated
55 * libwifi frames.
56 */
57size_t libwifi_dump_deauth(struct libwifi_deauth *deauth, unsigned char *buf, size_t buf_len) {
58 size_t deauth_len = libwifi_get_deauth_length(deauth);
59 if (deauth_len > buf_len) {
60 return -EINVAL;
61 }
62
63 size_t offset = 0;
64 memcpy(buf + offset, &deauth->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
65 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
66
67 memcpy(buf + offset, &deauth->fixed_parameters, sizeof(struct libwifi_deauth_fixed_parameters));
68 offset += sizeof(struct libwifi_deauth_fixed_parameters);
69
70 memcpy(buf + offset, deauth->tags.parameters, deauth->tags.length);
71 offset += deauth->tags.length;
72
73 return deauth_len;
74}
75
76/**
77 * Because the tagged parameters memory is managed inside of the library, the library must
78 * be the one to free it, too.
79 */
80void libwifi_free_deauth(struct libwifi_deauth *deauth) {
81 free(deauth->tags.parameters);
82}
diff --git a/src/libwifi/gen/management/deauthentication.h b/src/libwifi/gen/management/deauthentication.h new file mode 100644 index 0000000..902241d --- /dev/null +++ b/src/libwifi/gen/management/deauthentication.h
@@ -0,0 +1,63 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_DEAUTH_H
17#define LIBWIFI_GEN_DEAUTH_H
18
19#include <stdint.h>
20
21#include "../../core/frame/management/deauthentication.h"
22
23/**
24 * Calculate the length of a given libwifi_deauth
25 *
26 * @param deauth A libwifi_deauth
27 * @return The length of the given deauth
28 */
29size_t libwifi_get_deauth_length(struct libwifi_deauth *deauth);
30
31/**
32 * Generate a populated libwifi deauth.
33 *
34 * A generated libwifi deauth can be "dumped" into a buffer for packet injection
35 * via the libwifi_dump_deauth.
36 *
37 * @param deauth A libwifi_deauth
38 * @param receiver The receiver MAC address, aka address 1
39 * @param transmitter The source MAC address, aka address 2
40 * @param reason_code The deauth reason code
41 *
42 */
43int libwifi_create_deauth(struct libwifi_deauth *deauth, const unsigned char receiver[6],
44 const unsigned char transmitter[6], uint16_t reason_code);
45
46/**
47 * Dump a libwifi_deauth into a raw format for packet injection.
48 *
49 * @param deauth A libwifi_deauth
50 * @param buf The output buffer for the frame data
51 * @param buf_len The length of the output buffer
52 * @return The length of the dumped deauth
53 */
54size_t libwifi_dump_deauth(struct libwifi_deauth *deauth, unsigned char *buf, size_t buf_len);
55
56/**
57 * Free any memory claimed by a libwifi_deauth back to the system.
58 *
59 * @param deauth A libwifi_deauth
60 */
61void libwifi_free_deauth(struct libwifi_deauth *deauth);
62
63#endif /* LIBWIFI_GEN_DEAUTH_H */
diff --git a/src/libwifi/gen/management/disassociation.c b/src/libwifi/gen/management/disassociation.c new file mode 100644 index 0000000..a885efd --- /dev/null +++ b/src/libwifi/gen/management/disassociation.c
@@ -0,0 +1,80 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "disassociation.h"
17#include "../../core/misc/byteswap.h"
18
19#include <errno.h>
20#include <stdlib.h>
21#include <string.h>
22
23/**
24 * The length of a disassoc frame is the sum of the header length, the fixed parameters length, and the tagged
25 * parameters length.
26 */
27size_t libwifi_get_disassoc_length(struct libwifi_disassoc *disassoc) {
28 return sizeof(struct libwifi_mgmt_unordered_frame_header) +
29 sizeof(struct libwifi_disassoc_fixed_parameters) + disassoc->tags.length;
30}
31
32/**
33 * The generated disassociation frame contains only the supplied receiver, transmitter and reason_code by
34 * default.
35 */
36void libwifi_create_disassoc(struct libwifi_disassoc *disassoc, const unsigned char receiver[6],
37 const unsigned char transmitter[6], uint16_t reason_code) {
38 memset(disassoc, 0, sizeof(struct libwifi_disassoc));
39
40 disassoc->frame_header.frame_control.type = TYPE_MANAGEMENT;
41 disassoc->frame_header.frame_control.subtype = SUBTYPE_DISASSOC;
42 memcpy(&disassoc->frame_header.addr1, receiver, 6);
43 memcpy(&disassoc->frame_header.addr2, transmitter, 6);
44 memcpy(&disassoc->frame_header.addr3, transmitter, 6);
45
46 disassoc->frame_header.seq_control.sequence_number = (rand() % 4096);
47
48 memcpy(&disassoc->fixed_parameters.reason_code, &reason_code, sizeof(reason_code));
49}
50
51/**
52 * Copy a libwifi_disassoc into a regular unsigned char buffer. This is useful when injecting generated
53 * libwifi frames.
54 */
55size_t libwifi_dump_disassoc(struct libwifi_disassoc *disassoc, unsigned char *buf, size_t buf_len) {
56 size_t disassoc_len = libwifi_get_disassoc_length(disassoc);
57 if (disassoc_len > buf_len) {
58 return -EINVAL;
59 }
60
61 size_t offset = 0;
62 memcpy(buf + offset, &disassoc->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
63 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
64
65 memcpy(buf + offset, &disassoc->fixed_parameters, sizeof(struct libwifi_disassoc_fixed_parameters));
66 offset += sizeof(struct libwifi_disassoc_fixed_parameters);
67
68 memcpy(buf + offset, disassoc->tags.parameters, disassoc->tags.length);
69 offset += disassoc->tags.length;
70
71 return disassoc_len;
72}
73
74/**
75 * Because the tagged parameters memory is managed inside of the library, the library must
76 * be the one to free it, too.
77 */
78void libwifi_free_disassoc(struct libwifi_disassoc *disassoc) {
79 free(disassoc->tags.parameters);
80}
diff --git a/src/libwifi/gen/management/disassociation.h b/src/libwifi/gen/management/disassociation.h new file mode 100644 index 0000000..fada9f0 --- /dev/null +++ b/src/libwifi/gen/management/disassociation.h
@@ -0,0 +1,63 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_DISASSOC_H
17#define LIBWIFI_GEN_DISASSOC_H
18
19#include <stdint.h>
20
21#include "../../core/frame/management/disassociation.h"
22
23/**
24 * Calculate the length of a given libwifi_disassoc
25 *
26 * @param disassoc A libwifi_disassoc
27 * @return The length of the given disassoc
28 */
29size_t libwifi_get_disassoc_length(struct libwifi_disassoc *disassoc);
30
31/**
32 * Generate a populated libwifi disassoc.
33 *
34 * A generated libwifi disassoc can be "dumped" into a buffer for packet injection
35 * via the libwifi_dump_disassoc.
36 *
37 * @param disassoc A libwifi_disassoc
38 * @param receiver The receiver MAC address, aka address 1
39 * @param transmitter The source MAC address, aka address 2
40 * @param reason_code The disassoc reason code
41 *
42 */
43void libwifi_create_disassoc(struct libwifi_disassoc *disassoc, const unsigned char receiver[6],
44 const unsigned char transmitter[6], uint16_t reason_code);
45
46/**
47 * Dump a libwifi_disassoc into a raw format for packet injection.
48 *
49 * @param disassoc A libwifi_disassoc
50 * @param buf The output buffer for the frame data
51 * @param buf_len The length of the output buffer
52 * @return The length of the dumped disassoc
53 */
54size_t libwifi_dump_disassoc(struct libwifi_disassoc *disassoc, unsigned char *buf, size_t buf_len);
55
56/**
57 * Free any memory claimed by a libwifi_disassoc back to the system.
58 *
59 * @param disassoc A libwifi_disassoc
60 */
61void libwifi_free_disassoc(struct libwifi_disassoc *disassoc);
62
63#endif /* LIBWIFI_GEN_DISASSOC_H */
diff --git a/src/libwifi/gen/management/probe_request.c b/src/libwifi/gen/management/probe_request.c new file mode 100644 index 0000000..7c5b99e --- /dev/null +++ b/src/libwifi/gen/management/probe_request.c
@@ -0,0 +1,76 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "probe_request.h"
17#include "../../core/misc/byteswap.h"
18
19#include <errno.h>
20#include <stdlib.h>
21#include <string.h>
22
23/**
24 * The length of a probe request frame is the sum of the header length plus the tagged parameters length.
25 */
26size_t libwifi_get_probe_req_length(struct libwifi_probe_req *probe_req) {
27 return sizeof(struct libwifi_mgmt_unordered_frame_header) + probe_req->tags.length;
28}
29
30/**
31 * The generated probe request frame is made with sane defaults defined in common.h.
32 * Two tagged parameters are also added to the beacon: SSID and Channel.
33 */
34void libwifi_create_probe_req(struct libwifi_probe_req *probe_req, const unsigned char receiver[6],
35 const unsigned char transmitter[6], const unsigned char bssid[6],
36 const char *ssid, uint8_t channel) {
37 memset(probe_req, 0, sizeof(struct libwifi_probe_req));
38
39 probe_req->frame_header.frame_control.type = TYPE_MANAGEMENT;
40 probe_req->frame_header.frame_control.subtype = SUBTYPE_PROBE_REQ;
41 memcpy(&probe_req->frame_header.addr1, receiver, 6);
42 memcpy(&probe_req->frame_header.addr2, transmitter, 6);
43 memcpy(&probe_req->frame_header.addr3, bssid, 6);
44 probe_req->frame_header.seq_control.sequence_number = (rand() % 4096);
45
46 libwifi_quick_add_tag(&probe_req->tags, TAG_SSID, (const unsigned char *) ssid, strlen(ssid));
47 libwifi_quick_add_tag(&probe_req->tags, TAG_DS_PARAMETER, (const unsigned char *) &channel, 1);
48}
49
50/**
51 * Copy a libwifi_probe_req into a regular unsigned char buffer. This is useful when injecting generated
52 * libwifi frames.
53 */
54size_t libwifi_dump_probe_req(struct libwifi_probe_req *probe_req, unsigned char *buf, size_t buf_len) {
55 size_t probe_req_len = libwifi_get_probe_req_length(probe_req);
56 if (probe_req_len > buf_len) {
57 return -EINVAL;
58 }
59
60 size_t offset = 0;
61 memcpy(buf + offset, &probe_req->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
62 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
63
64 memcpy(buf + offset, probe_req->tags.parameters, probe_req->tags.length);
65 offset += probe_req->tags.length;
66
67 return probe_req_len;
68}
69
70/**
71 * Because the tagged parameters memory is managed inside of the library, the library must
72 * be the one to free it, too.
73 */
74void libwifi_free_probe_req(struct libwifi_probe_req *probe_req) {
75 free(probe_req->tags.parameters);
76}
diff --git a/src/libwifi/gen/management/probe_request.h b/src/libwifi/gen/management/probe_request.h new file mode 100644 index 0000000..f98b70a --- /dev/null +++ b/src/libwifi/gen/management/probe_request.h
@@ -0,0 +1,64 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_PROBEREQ_H
17#define LIBWIFI_GEN_PROBEREQ_H
18
19#include <stdint.h>
20
21#include "../../core/frame/management/probe_request.h"
22
23/**
24 * Calculate the length of a given libwifi_probe_req
25 *
26 * @param probe_req A libwifi_probe_req
27 * @return The length of the given probe_req
28 */
29size_t libwifi_get_probe_req_length(struct libwifi_probe_req *probe_req);
30
31/**
32 * Generate a populated libwifi probe_req.
33 *
34 * A generated libwifi probe_req can be "dumped" into a buffer for packet injection
35 * via the libwifi_dump_probe_req.
36 *
37 * @param probe_req A libwifi_probe_req
38 * @param receiver The receiver MAC address, aka address 1
39 * @param transmitter The source MAC address, aka address 2
40 * @param reason_code The probe_req reason code
41 *
42 */
43void libwifi_create_probe_req(struct libwifi_probe_req *probe_req, const unsigned char receiver[6],
44 const unsigned char transmitter[6], const unsigned char bssid[6],
45 const char *ssid, uint8_t channel);
46
47/**
48 * Dump a libwifi_probe_req into a raw format for packet injection.
49 *
50 * @param probe_req A libwifi_probe_req
51 * @param buf The output buffer for the frame data
52 * @param buf_len The length of the output buffer
53 * @return The length of the dumped probe_req
54 */
55size_t libwifi_dump_probe_req(struct libwifi_probe_req *probe_req, unsigned char *buf, size_t buf_len);
56
57/**
58 * Free any memory claimed by a libwifi_probe_req back to the system.
59 *
60 * @param probe_req A libwifi_probe_req
61 */
62void libwifi_free_probe_req(struct libwifi_probe_req *probe_req);
63
64#endif /* LIBWIFI_GEN_PROBEREQ_H */
diff --git a/src/libwifi/gen/management/probe_response.c b/src/libwifi/gen/management/probe_response.c new file mode 100644 index 0000000..403a8bc --- /dev/null +++ b/src/libwifi/gen/management/probe_response.c
@@ -0,0 +1,118 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "probe_response.h"
17#include "../../core/frame/tag.h"
18#include "../../core/frame/tag_iterator.h"
19#include "../../core/misc/byteswap.h"
20#include "../../core/misc/epoch.h"
21#include "common.h"
22
23#include <errno.h>
24#include <stdint.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <sys/types.h>
29
30/**
31 * The length of a probe response frame is the sum of the header length, the fixed parameters length, and the
32 * tagged parameters length.
33 */
34size_t libwifi_get_probe_resp_length(struct libwifi_probe_resp *probe_resp) {
35 return sizeof(struct libwifi_mgmt_unordered_frame_header) +
36 sizeof(struct libwifi_probe_resp_fixed_parameters) + probe_resp->tags.length;
37}
38
39/**
40 * Simple helper to set the probe response SSID tag by removing it and then adding it back with the new value.
41 */
42void libwifi_set_probe_resp_ssid(struct libwifi_probe_resp *probe_resp, const char *ssid) {
43 if (probe_resp->tags.length != 0) {
44 libwifi_remove_tag(&probe_resp->tags, TAG_SSID);
45 }
46
47 libwifi_quick_add_tag(&probe_resp->tags, TAG_SSID, (void *) ssid, strlen(ssid));
48}
49
50/**
51 * Simple helper to set the probe response DS tag by removing it and then adding it back with the new value.
52 */
53void libwifi_set_probe_resp_channel(struct libwifi_probe_resp *probe_resp, uint8_t channel) {
54 if (probe_resp->tags.length != 0) {
55 libwifi_remove_tag(&probe_resp->tags, TAG_DS_PARAMETER);
56 }
57
58 const unsigned char *chan = (const unsigned char *) &channel;
59
60 libwifi_quick_add_tag(&probe_resp->tags, TAG_DS_PARAMETER, chan, 1);
61}
62
63/**
64 * The generated probe response frame is made with sane defaults defined in common.h.
65 * Three tagged parameters are also added to the probe response: SSID, Channel and Supported Rates.
66 */
67void libwifi_create_probe_resp(struct libwifi_probe_resp *probe_resp, const unsigned char receiver[6],
68 const unsigned char transmitter[6], const char *ssid, uint8_t channel) {
69 memset(probe_resp, 0, sizeof(struct libwifi_probe_resp));
70
71 probe_resp->frame_header.frame_control.type = TYPE_MANAGEMENT;
72 probe_resp->frame_header.frame_control.subtype = SUBTYPE_PROBE_RESP;
73 memcpy(&probe_resp->frame_header.addr1, receiver, 6);
74 memcpy(&probe_resp->frame_header.addr2, transmitter, 6);
75
76 probe_resp->frame_header.seq_control.sequence_number = (rand() % 4096);
77 probe_resp->fixed_parameters.timestamp = BYTESWAP64(libwifi_get_epoch());
78 uint16_t probe_resp_interval = 50 + (rand() % 100);
79 probe_resp->fixed_parameters.probe_resp_interval = BYTESWAP16(probe_resp_interval);
80 probe_resp->fixed_parameters.capabilities_information = BYTESWAP16(LIBWIFI_DEFAULT_AP_CAPABS);
81
82 libwifi_set_probe_resp_ssid(probe_resp, ssid);
83 libwifi_set_probe_resp_channel(probe_resp, channel);
84
85 const unsigned char supported_rates[] = LIBWIFI_DEFAULT_SUPP_RATES;
86 libwifi_quick_add_tag(&probe_resp->tags, TAG_SUPP_RATES, supported_rates, sizeof(supported_rates) - 1);
87}
88
89/**
90 * Copy a libwifi_probe_resp into a regular unsigned char buffer. This is useful when injecting generated
91 * libwifi frames.
92 */
93size_t libwifi_dump_probe_resp(struct libwifi_probe_resp *probe_resp, unsigned char *buf, size_t buf_len) {
94 size_t probe_resp_len = libwifi_get_probe_resp_length(probe_resp);
95 if (probe_resp_len > buf_len) {
96 return -EINVAL;
97 }
98
99 size_t offset = 0;
100 memcpy(buf + offset, &probe_resp->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
101 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
102
103 memcpy(buf + offset, &probe_resp->fixed_parameters, sizeof(struct libwifi_probe_resp_fixed_parameters));
104 offset += sizeof(struct libwifi_probe_resp_fixed_parameters);
105
106 memcpy(buf + offset, probe_resp->tags.parameters, probe_resp->tags.length);
107 offset += probe_resp->tags.length;
108
109 return probe_resp_len;
110}
111
112/**
113 * Because the tagged parameters memory is managed inside of the library, the library must
114 * be the one to free it, too.
115 */
116void libwifi_free_probe_resp(struct libwifi_probe_resp *probe_resp) {
117 free(probe_resp->tags.parameters);
118}
diff --git a/src/libwifi/gen/management/probe_response.h b/src/libwifi/gen/management/probe_response.h new file mode 100644 index 0000000..56243ee --- /dev/null +++ b/src/libwifi/gen/management/probe_response.h
@@ -0,0 +1,78 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_PROBERESP_H
17#define LIBWIFI_GEN_PROBERESP_H
18
19#include "../../core/frame/management/probe_response.h"
20
21/**
22 * Set the SSID of a libwifi_probe_resp.
23 *
24 * @param probe_resp A libwifi_probe_resp
25 * @param ssid The new SSID
26 */
27void libwifi_set_probe_resp_ssid(struct libwifi_probe_resp *probe_resp, const char *ssid);
28
29/**
30 * Set the channel of a libwifi_probe_resp.
31 *
32 * @param probe_resp A libwifi_probe_resp
33 * @param channel The new channel
34 */
35void libwifi_set_probe_resp_channel(struct libwifi_probe_resp *probe_resp, uint8_t channel);
36
37/**
38 * Calculate the length of a given libwifi_probe_resp
39 *
40 * @param probe_resp A libwifi_probe_resp
41 * @return The length of the given probe_resp
42 */
43size_t libwifi_get_probe_resp_length(struct libwifi_probe_resp *probe_resp);
44
45/**
46 * Generate a populated libwifi probe_resp.
47 *
48 * A generated libwifi probe_resp can be "dumped" into a buffer for packet injection
49 * via the libwifi_dump_probe_resp.
50 *
51 * @param probe_resp A libwifi_probe_resp
52 * @param receiver The receiver MAC address, aka address 1
53 * @param transmitter The source MAC address, aka address 2
54 * @param ssid The SSID of the probe_resp. Maximum length is 32 characters
55 * @param channel The desired channel of the probe_resp
56 *
57 */
58void libwifi_create_probe_resp(struct libwifi_probe_resp *probe_resp, const unsigned char receiver[6],
59 const unsigned char transmitter[6], const char *ssid, uint8_t channel);
60
61/**
62 * Dump a libwifi_probe_resp into a raw format for packet injection.
63 *
64 * @param probe_resp A libwifi_probe_resp
65 * @param buf The output buffer for the frame data
66 * @param buf_len The length of the output buffer
67 * @return The length of the dumped probe_resp
68 */
69size_t libwifi_dump_probe_resp(struct libwifi_probe_resp *probe_resp, unsigned char *buf, size_t buf_len);
70
71/**
72 * Free any memory claimed by a libwifi_probe_resp back to the system.
73 *
74 * @param probe_resp A libwifi_probe_resp
75 */
76void libwifi_free_probe_resp(struct libwifi_probe_resp *probe_resp);
77
78#endif /* LIBWIFI_GEN_PROBERESP_H */
diff --git a/src/libwifi/gen/management/reassoc_request.c b/src/libwifi/gen/management/reassoc_request.c new file mode 100644 index 0000000..f678caf --- /dev/null +++ b/src/libwifi/gen/management/reassoc_request.c
@@ -0,0 +1,87 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "reassoc_request.h"
17#include "common.h"
18
19#include <errno.h>
20#include <stdlib.h>
21#include <string.h>
22
23/**
24 * The length of a reassociation request frame is the sum of the header length, the fixed parameters length,
25 * and the tagged parameters length.
26 */
27size_t libwifi_get_reassoc_req_length(struct libwifi_reassoc_req *reassoc_req) {
28 return sizeof(struct libwifi_mgmt_unordered_frame_header) +
29 sizeof(struct libwifi_reassoc_req_fixed_parameters) + reassoc_req->tags.length;
30}
31
32/**
33 * The generated reassociation request frame is made with sane defaults defined in common.h.
34 * Two tagged parameters are also added to the reassociation frame: SSID and Channel
35 */
36int libwifi_create_reassoc_req(struct libwifi_reassoc_req *reassoc_req, const unsigned char receiver[6],
37 const unsigned char transmitter[6], const unsigned char current_ap[6],
38 const char *ssid, uint8_t channel) {
39 memset(reassoc_req, 0, sizeof(struct libwifi_reassoc_req));
40
41 reassoc_req->frame_header.frame_control.type = TYPE_MANAGEMENT;
42 reassoc_req->frame_header.frame_control.subtype = SUBTYPE_REASSOC_REQ;
43 memcpy(&reassoc_req->frame_header.addr1, receiver, 6);
44 memcpy(&reassoc_req->frame_header.addr2, transmitter, 6);
45 memcpy(&reassoc_req->frame_header.addr3, receiver, 6);
46 reassoc_req->frame_header.seq_control.sequence_number = (rand() % 4096);
47
48 reassoc_req->fixed_parameters.capabilities_information = BYTESWAP16(LIBWIFI_DEFAULT_AP_CAPABS);
49 reassoc_req->fixed_parameters.listen_interval = BYTESWAP16(LIBWIFI_DEFAULT_LISTEN_INTERVAL);
50 memcpy(&reassoc_req->fixed_parameters.current_ap_address, current_ap, 6);
51
52 libwifi_quick_add_tag(&reassoc_req->tags, TAG_SSID, (const unsigned char *) ssid, strlen(ssid));
53 libwifi_quick_add_tag(&reassoc_req->tags, TAG_DS_PARAMETER, (const unsigned char *) &channel, 1);
54
55 return 0;
56}
57
58/**
59 * Copy a libwifi_reassoc_req into a regular unsigned char buffer. This is useful when injecting generated
60 * libwifi frames.
61 */
62size_t libwifi_dump_reassoc_req(struct libwifi_reassoc_req *reassoc_req, unsigned char *buf, size_t buf_len) {
63 size_t reassoc_req_len = libwifi_get_reassoc_req_length(reassoc_req);
64 if (reassoc_req_len > buf_len) {
65 return -EINVAL;
66 }
67
68 size_t offset = 0;
69 memcpy(buf + offset, &reassoc_req->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
70 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
71
72 memcpy(buf + offset, &reassoc_req->fixed_parameters, sizeof(struct libwifi_reassoc_req_fixed_parameters));
73 offset += sizeof(struct libwifi_reassoc_req_fixed_parameters);
74
75 memcpy(buf + offset, reassoc_req->tags.parameters, reassoc_req->tags.length);
76 offset += reassoc_req->tags.length;
77
78 return reassoc_req_len;
79}
80
81/**
82 * Because the tagged parameters memory is managed inside of the library, the library must
83 * be the one to free it, too.
84 */
85void libwifi_free_reassoc_req(struct libwifi_reassoc_req *reassoc_req) {
86 free(reassoc_req->tags.parameters);
87}
diff --git a/src/libwifi/gen/management/reassoc_request.h b/src/libwifi/gen/management/reassoc_request.h new file mode 100644 index 0000000..3db971f --- /dev/null +++ b/src/libwifi/gen/management/reassoc_request.h
@@ -0,0 +1,30 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_REASSOCREQUEST_H
17#define LIBWIFI_GEN_REASSOCREQUEST_H
18
19#include "../../core/frame/frame.h"
20#include "../../core/frame/management/common.h"
21#include "../../core/frame/management/reassoc_request.h"
22
23int libwifi_create_reassoc_req(struct libwifi_reassoc_req *reassoc_req, const unsigned char receiver[6],
24 const unsigned char transmitter[6], const unsigned char current_ap[6],
25 const char *ssid, uint8_t channel);
26size_t libwifi_get_reassoc_req_length(struct libwifi_reassoc_req *reassoc_req);
27size_t libwifi_dump_reassoc_req(struct libwifi_reassoc_req *reassoc_req, unsigned char *buf, size_t buf_len);
28void libwifi_free_reassoc_req(struct libwifi_reassoc_req *reassoc_req);
29
30#endif /* LIBWIFI_GEN_REASSOCREQUEST_H */
diff --git a/src/libwifi/gen/management/reassoc_response.c b/src/libwifi/gen/management/reassoc_response.c new file mode 100644 index 0000000..b9acbb6 --- /dev/null +++ b/src/libwifi/gen/management/reassoc_response.c
@@ -0,0 +1,108 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "reassoc_response.h"
17#include "../../core/frame/tag.h"
18#include "../../core/frame/tag_iterator.h"
19#include "../../core/misc/byteswap.h"
20#include "../../core/misc/epoch.h"
21#include "../../core/misc/types.h"
22#include "common.h"
23
24#include <errno.h>
25#include <stdint.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/types.h>
30
31/**
32 * The length of a reassociation response frame is the sum of the header length, the fixed parameters length,
33 * and the tagged parameters length.
34 */
35size_t libwifi_get_reassoc_resp_length(struct libwifi_reassoc_resp *reassoc_resp) {
36 return sizeof(struct libwifi_mgmt_unordered_frame_header) +
37 sizeof(struct libwifi_reassoc_resp_fixed_parameters) + reassoc_resp->tags.length;
38}
39
40/**
41 * Simple helper to set the reassociation response DS tag by removing it and then adding it back with the new
42 * value.
43 */
44void libwifi_set_reassoc_resp_channel(struct libwifi_reassoc_resp *reassoc_resp, uint8_t channel) {
45 if (reassoc_resp->tags.length != 0) {
46 libwifi_remove_tag(&reassoc_resp->tags, TAG_DS_PARAMETER);
47 }
48
49 const unsigned char *chan = (const unsigned char *) &channel;
50
51 libwifi_quick_add_tag(&reassoc_resp->tags, TAG_DS_PARAMETER, chan, 1);
52}
53
54/**
55 * The generated reassoc_resp frame is made with sane defaults defined in common.h.
56 * Three tagged parameters are also added to the reassoc_resp: SSID, Channel and Supported Rates.
57 */
58void libwifi_create_reassoc_resp(struct libwifi_reassoc_resp *reassoc_resp, const unsigned char receiver[6],
59 const unsigned char transmitter[6], uint8_t channel) {
60 memset(reassoc_resp, 0, sizeof(struct libwifi_reassoc_resp));
61
62 reassoc_resp->frame_header.frame_control.type = TYPE_MANAGEMENT;
63 reassoc_resp->frame_header.frame_control.subtype = SUBTYPE_REASSOC_RESP;
64 memcpy(&reassoc_resp->frame_header.addr1, receiver, 6);
65 memcpy(&reassoc_resp->frame_header.addr2, transmitter, 6);
66
67 reassoc_resp->fixed_parameters.capabilities_information = BYTESWAP16(LIBWIFI_DEFAULT_AP_CAPABS);
68 reassoc_resp->fixed_parameters.status_code = STATUS_SUCCESS;
69 reassoc_resp->fixed_parameters.association_id = rand() % 4096;
70
71 libwifi_set_reassoc_resp_channel(reassoc_resp, channel);
72
73 const unsigned char supported_rates[] = LIBWIFI_DEFAULT_SUPP_RATES;
74 libwifi_quick_add_tag(&reassoc_resp->tags, TAG_SUPP_RATES, supported_rates, sizeof(supported_rates) - 1);
75}
76
77/**
78 * Copy a libwifi_reassoc_resp into a regular unsigned char buffer. This is useful when injecting generated
79 * libwifi frames.
80 */
81size_t libwifi_dump_reassoc_resp(struct libwifi_reassoc_resp *reassoc_resp, unsigned char *buf,
82 size_t buf_len) {
83 size_t reassoc_resp_len = libwifi_get_reassoc_resp_length(reassoc_resp);
84 if (reassoc_resp_len > buf_len) {
85 return -EINVAL;
86 }
87
88 size_t offset = 0;
89 memcpy(buf + offset, &reassoc_resp->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
90 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
91
92 memcpy(buf + offset, &reassoc_resp->fixed_parameters,
93 sizeof(struct libwifi_reassoc_resp_fixed_parameters));
94 offset += sizeof(struct libwifi_reassoc_resp_fixed_parameters);
95
96 memcpy(buf + offset, reassoc_resp->tags.parameters, reassoc_resp->tags.length);
97 offset += reassoc_resp->tags.length;
98
99 return reassoc_resp_len;
100}
101
102/**
103 * Because the tagged parameters memory is managed inside of the library, the library must
104 * be the one to free it, too.
105 */
106void libwifi_free_reassoc_resp(struct libwifi_reassoc_resp *reassoc_resp) {
107 free(reassoc_resp->tags.parameters);
108}
diff --git a/src/libwifi/gen/management/reassoc_response.h b/src/libwifi/gen/management/reassoc_response.h new file mode 100644 index 0000000..f0a2da2 --- /dev/null +++ b/src/libwifi/gen/management/reassoc_response.h
@@ -0,0 +1,70 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_REASSOCRESP_H
17#define LIBWIFI_GEN_REASSOCRESP_H
18
19#include "../../core/frame/management/reassoc_response.h"
20
21/**
22 * Set the channel of a libwifi_reassoc_resp.
23 *
24 * @param reassoc_resp A libwifi_reassoc_resp
25 * @param channel The new channel
26 */
27void libwifi_set_reassoc_resp_channel(struct libwifi_reassoc_resp *reassoc_resp, uint8_t channel);
28
29/**
30 * Calculate the length of a given libwifi_reassoc_resp
31 *
32 * @param reassoc_resp A libwifi_reassoc_resp
33 * @return The length of the given reassoc_resp
34 */
35size_t libwifi_get_reassoc_resp_length(struct libwifi_reassoc_resp *reassoc_resp);
36
37/**
38 * Generate a populated libwifi reassoc_resp.
39 *
40 * A generated libwifi reassoc_resp can be "dumped" into a buffer for packet injection
41 * via the libwifi_dump_reassoc_resp.
42 *
43 * @param reassoc_resp A libwifi_reassoc_resp
44 * @param receiver The receiver MAC address, aka address 1
45 * @param transmitter The source MAC address, aka address 2
46 * @param channel The desired channel of the reassoc_resp
47 *
48 */
49void libwifi_create_reassoc_resp(struct libwifi_reassoc_resp *reassoc_resp, const unsigned char receiver[6],
50 const unsigned char transmitter[6], uint8_t channel);
51
52/**
53 * Dump a libwifi_reassoc_resp into a raw format for packet injection.
54 *
55 * @param reassoc_resp A libwifi_reassoc_resp
56 * @param buf The output buffer for the frame data
57 * @param buf_len The length of the output buffer
58 * @return The length of the dumped reassoc_resp
59 */
60size_t libwifi_dump_reassoc_resp(struct libwifi_reassoc_resp *reassoc_resp, unsigned char *buf,
61 size_t buf_len);
62
63/**
64 * Free any memory claimed by a libwifi_reassoc_resp back to the system.
65 *
66 * @param reassoc_resp A libwifi_reassoc_resp
67 */
68void libwifi_free_reassoc_resp(struct libwifi_reassoc_resp *reassoc_resp);
69
70#endif /* LIBWIFI_GEN_REASSOCRESP_H */
diff --git a/src/libwifi/gen/management/timing_ad.c b/src/libwifi/gen/management/timing_ad.c new file mode 100644 index 0000000..6e67a6b --- /dev/null +++ b/src/libwifi/gen/management/timing_ad.c
@@ -0,0 +1,111 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "common.h"
17#include "timing_ad.h"
18#include "../../core/frame/management/timing_ad.h"
19#include "../../core/misc/epoch.h"
20#include "../../core/frame/tag.h"
21
22#include <stdlib.h>
23#include <string.h>
24
25void libwifi_create_timing_advert(struct libwifi_timing_advert *adv, const unsigned char destination[6],
26 const unsigned char transmitter[6], struct libwifi_timing_advert_fields *adv_fields,
27 const char country[3], uint16_t max_reg_power, uint8_t max_tx_power, uint8_t tx_power_used,
28 uint8_t noise_floor) {
29 memset(adv, 0, sizeof(struct libwifi_timing_advert));
30
31 adv->frame_header.frame_control.type = TYPE_MANAGEMENT;
32 adv->frame_header.frame_control.subtype = SUBTYPE_TIME_ADV;
33 memcpy(&adv->frame_header.addr1, destination, 6);
34 memcpy(&adv->frame_header.addr2, transmitter, 6);
35 adv->frame_header.seq_control.sequence_number = (rand() % 4096);
36
37 adv->fixed_parameters.timestamp = BYTESWAP64(libwifi_get_epoch());
38 adv->fixed_parameters.measurement_pilot_interval = LIBWIFI_DEFAULT_BEACON_INTERVAL;
39 adv->fixed_parameters.beacon_interval = LIBWIFI_DEFAULT_BEACON_INTERVAL;
40 adv->fixed_parameters.capabilities_information = BYTESWAP16(LIBWIFI_DEFAULT_AP_CAPABS);
41 memcpy(adv->fixed_parameters.country, country, sizeof(adv->fixed_parameters.country));
42 adv->fixed_parameters.max_reg_power = BYTESWAP16(max_reg_power);
43 adv->fixed_parameters.max_tx_power = max_tx_power;
44 adv->fixed_parameters.tx_power_used = tx_power_used;
45 adv->fixed_parameters.noise_floor = noise_floor;
46
47 if (adv_fields == NULL) {
48 return;
49 }
50
51 // Maximum element size is 17
52 unsigned char element_data[17] = {0};
53 size_t element_data_len = 0;
54 int offset = 0;
55
56 memcpy(element_data, &adv_fields->timing_capabilities, sizeof(adv_fields->timing_capabilities));
57 offset += sizeof(adv_fields->timing_capabilities);
58
59 switch (adv_fields->timing_capabilities) {
60 case 1: { /* Time Value and Time Error fields present */
61 memcpy(element_data + offset, &adv_fields->time_value, sizeof(adv_fields->time_value));
62 offset += sizeof(adv_fields->time_value);
63 memcpy(element_data + offset, &adv_fields->time_error, sizeof(adv_fields->time_error));
64 offset += sizeof(adv_fields->time_error);
65 break;
66 }
67 case 2: { /* Time Value, Time Error, and Time Update fields present */
68 memcpy(element_data + offset, &adv_fields->time_value, sizeof(adv_fields->time_value));
69 offset += sizeof(adv_fields->time_value);
70 memcpy(element_data + offset, &adv_fields->time_error, sizeof(adv_fields->time_error));
71 offset += sizeof(adv_fields->time_error);
72 memcpy(element_data + offset, &adv_fields->time_update, sizeof(adv_fields->time_update));
73 offset += sizeof(adv_fields->time_update);
74 }
75 default:
76 break;
77 }
78
79 element_data_len = offset;
80
81 libwifi_quick_add_tag(&adv->tags, TAG_TIME_ADVERTISEMENT, element_data, element_data_len);
82}
83
84size_t libwifi_get_timing_advert_length(struct libwifi_timing_advert *adv) {
85 return sizeof(struct libwifi_mgmt_unordered_frame_header) +
86 sizeof(struct libwifi_timing_advert_fixed_params) +
87 adv->tags.length;
88}
89
90size_t libwifi_dump_timing_advert(struct libwifi_timing_advert *adv, unsigned char *buf, size_t buf_len) {
91 size_t adv_len = libwifi_get_timing_advert_length(adv);
92 if (adv_len > buf_len) {
93 return -1;
94 }
95
96 size_t offset = 0;
97 memcpy(buf + offset, &adv->frame_header, sizeof(struct libwifi_mgmt_unordered_frame_header));
98 offset += sizeof(struct libwifi_mgmt_unordered_frame_header);
99
100 memcpy(buf + offset, &adv->fixed_parameters, sizeof(struct libwifi_timing_advert_fixed_params));
101 offset += sizeof(struct libwifi_timing_advert_fixed_params);
102
103 memcpy(buf + offset, adv->tags.parameters, adv->tags.length);
104 offset += adv->tags.length;
105
106 return adv_len;
107}
108
109void libwifi_free_timing_advert(struct libwifi_timing_advert *adv) {
110 free(adv->tags.parameters);
111}
diff --git a/src/libwifi/gen/management/timing_ad.h b/src/libwifi/gen/management/timing_ad.h new file mode 100644 index 0000000..cdcb827 --- /dev/null +++ b/src/libwifi/gen/management/timing_ad.h
@@ -0,0 +1,32 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_TIMINGAD_H
17#define LIBWIFI_GEN_TIMINGAD_H
18
19#include "../../core/frame/management/timing_ad.h"
20
21void libwifi_create_timing_advert(struct libwifi_timing_advert *adv, const unsigned char destination[6],
22 const unsigned char transmitter[6], struct libwifi_timing_advert_fields *adv_fields,
23 const char country[3], uint16_t max_reg_power, uint8_t max_tx_power, uint8_t tx_power_used,
24 uint8_t noise_floor);
25
26size_t libwifi_get_timing_advert_length(struct libwifi_timing_advert *adv);
27
28size_t libwifi_dump_timing_advert(struct libwifi_timing_advert *adv, unsigned char *buf, size_t buf_len);
29
30void libwifi_free_timing_advert(struct libwifi_timing_advert *adv);
31
32#endif /* LIBWIFI_GEN_TIMINGAD_H */
diff --git a/src/libwifi/gen/misc/radiotap.c b/src/libwifi/gen/misc/radiotap.c new file mode 100644 index 0000000..cc02097 --- /dev/null +++ b/src/libwifi/gen/misc/radiotap.c
@@ -0,0 +1,123 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "radiotap.h"
17#include "../../core/radiotap/radiotap.h"
18#include "../../core/radiotap/radiotap_iter.h"
19
20#include <stdint.h>
21#include <stdlib.h>
22#include <string.h>
23
24#define LIBWIFI_RADIOTAP_HEADER_LEN 8
25
26size_t libwifi_create_radiotap(struct libwifi_radiotap_info *info, char *radiotap_header) {
27 struct ieee80211_radiotap_header rtap_hdr = {0};
28 rtap_hdr.it_version = 0;
29 rtap_hdr.it_pad = 0;
30 rtap_hdr.it_present = info->present;
31 rtap_hdr.it_len = sizeof(struct ieee80211_radiotap_header);
32
33 char rtap_data[LIBWIFI_MAX_RADIOTAP_LEN - LIBWIFI_RADIOTAP_HEADER_LEN] = {0};
34 int offset = 0;
35
36 uint32_t presence_bit = rtap_hdr.it_present;
37 for (int field = 0; field < radiotap_ns.n_bits; field++) {
38 if (presence_bit & 1) {
39 switch (field) {
40 case IEEE80211_RADIOTAP_CHANNEL:
41 memcpy(rtap_data + offset, &info->channel.freq, sizeof(info->channel.freq));
42 offset += sizeof(info->channel.freq);
43 memcpy(rtap_data + offset, &info->channel.flags, sizeof(info->channel.flags));
44 offset += sizeof(info->channel.flags);
45 break;
46 case IEEE80211_RADIOTAP_RATE:
47 memcpy(rtap_data + offset, &info->rate_raw, sizeof(info->rate_raw));
48 offset += sizeof(info->rate_raw);
49 break;
50 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
51 memcpy(rtap_data + offset, &info->signal, sizeof(info->signal));
52 offset += sizeof(info->signal);
53 break;
54 case IEEE80211_RADIOTAP_ANTENNA:
55 for (int i = 0; i < info->antenna_count; i++) {
56 memcpy(rtap_data + offset, &info->antennas->antenna_number,
57 sizeof(info->antennas->antenna_number));
58 offset += sizeof(info->antennas->antenna_number);
59 memcpy(rtap_data + offset, &info->antennas->signal, sizeof(info->antennas->signal));
60 offset += sizeof(info->antennas->signal);
61 }
62 break;
63 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
64 break;
65 case IEEE80211_RADIOTAP_FLAGS:
66 memcpy(rtap_data + offset, &info->flags, sizeof(info->flags));
67 offset += sizeof(info->flags);
68 break;
69 case IEEE80211_RADIOTAP_EXT:
70 memcpy(rtap_data + offset, &info->extended_flags, sizeof(info->extended_flags));
71 offset += sizeof(info->extended_flags);
72 break;
73 case IEEE80211_RADIOTAP_RX_FLAGS:
74 memcpy(rtap_data + offset, &info->rx_flags, sizeof(info->rx_flags));
75 offset += sizeof(info->rx_flags);
76 break;
77 case IEEE80211_RADIOTAP_TX_FLAGS:
78 memcpy(rtap_data + offset, &info->tx_flags, sizeof(info->tx_flags));
79 offset += sizeof(info->tx_flags);
80 break;
81 case IEEE80211_RADIOTAP_MCS:
82 memcpy(rtap_data + offset, &info->mcs.known, sizeof(info->mcs.known));
83 offset += sizeof(info->mcs.known);
84 memcpy(rtap_data + offset, &info->mcs.flags, sizeof(info->mcs.flags));
85 offset += sizeof(info->mcs.flags);
86 memcpy(rtap_data + offset, &info->mcs.mcs, sizeof(info->mcs.mcs));
87 offset += sizeof(info->mcs.mcs);
88 break;
89 case IEEE80211_RADIOTAP_DBM_TX_POWER:
90 memcpy(rtap_data + offset, &info->tx_power, sizeof(info->tx_power));
91 offset += sizeof(info->tx_power);
92 break;
93 case IEEE80211_RADIOTAP_TIMESTAMP:
94 memcpy(rtap_data + offset, &info->timestamp.timestamp, sizeof(info->timestamp.timestamp));
95 offset += sizeof(info->timestamp.timestamp);
96 memcpy(rtap_data + offset, &info->timestamp.accuracy, sizeof(info->timestamp.accuracy));
97 offset += sizeof(info->timestamp.accuracy);
98 memcpy(rtap_data + offset, &info->timestamp.unit, sizeof(info->timestamp.unit));
99 offset += sizeof(info->timestamp.unit);
100 memcpy(rtap_data + offset, &info->timestamp.flags, sizeof(info->timestamp.flags));
101 offset += sizeof(info->timestamp.flags);
102 break;
103 case IEEE80211_RADIOTAP_RTS_RETRIES:
104 memcpy(rtap_data + offset, &info->rts_retries, sizeof(info->rts_retries));
105 offset += sizeof(info->rts_retries);
106 break;
107 case IEEE80211_RADIOTAP_DATA_RETRIES:
108 memcpy(rtap_data + offset, &info->data_retries, sizeof(info->data_retries));
109 offset += sizeof(info->data_retries);
110 break;
111 }
112 }
113
114 presence_bit >>= 1;
115 }
116
117 rtap_hdr.it_len += offset;
118
119 memcpy(radiotap_header, &rtap_hdr, sizeof(struct ieee80211_radiotap_header));
120 memcpy(radiotap_header + sizeof(struct ieee80211_radiotap_header), &rtap_data, offset);
121
122 return rtap_hdr.it_len;
123}
diff --git a/src/libwifi/gen/misc/radiotap.h b/src/libwifi/gen/misc/radiotap.h new file mode 100644 index 0000000..00e2ac8 --- /dev/null +++ b/src/libwifi/gen/misc/radiotap.h
@@ -0,0 +1,31 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_GEN_RADIOTAP_H
17#define LIBWIFI_GEN_RADIOTAP_H
18
19#include "../../core/misc/radiotap.h"
20#include <sys/types.h>
21
22/*
23 * Generate a customised radiotap header based on the input provided in info.
24 *
25 * @param info A libwifi_radiotap_info struct with desired radiotap data.
26 * @param radiotap_header Buffer to write the radiotap header into.
27 * @return Length of the generated radiotap header.
28 */
29size_t libwifi_create_radiotap(struct libwifi_radiotap_info *info, char *radiotap_header);
30
31#endif /* LIBWIFI_GEN_RADIOTAP_H */
diff --git a/src/libwifi/parse/data/data.c b/src/libwifi/parse/data/data.c new file mode 100644 index 0000000..74bff32 --- /dev/null +++ b/src/libwifi/parse/data/data.c
@@ -0,0 +1,48 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "data.h"
17
18#include <errno.h>
19#include <stdlib.h>
20#include <string.h>
21
22int libwifi_parse_data(struct libwifi_data *data, struct libwifi_frame *frame) {
23 if (frame->frame_control.type != TYPE_DATA) {
24 return -EINVAL;
25 }
26
27 if (frame->flags & LIBWIFI_FLAGS_IS_QOS) {
28 memcpy(data->receiver, frame->header.data_qos.addr1, 6);
29 memcpy(data->transmitter, frame->header.data_qos.addr2, 6);
30 } else {
31 memcpy(data->receiver, frame->header.data.addr1, 6);
32 memcpy(data->transmitter, frame->header.data.addr2, 6);
33 }
34
35 data->body_len = frame->len - frame->header_len;
36
37 data->body = malloc(data->body_len);
38 if (data->body == NULL) {
39 return -ENOMEM;
40 }
41 memcpy(frame->body, data->body, data->body_len);
42
43 return 0;
44}
45
46void libwifi_free_data(struct libwifi_data *data) {
47 free(data->body);
48}
diff --git a/src/libwifi/parse/data/data.h b/src/libwifi/parse/data/data.h new file mode 100644 index 0000000..3ed3bd4 --- /dev/null +++ b/src/libwifi/parse/data/data.h
@@ -0,0 +1,26 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_DATA_H
17#define LIBWIFI_PARSE_DATA_H
18
19#include "../../core/frame/data/data.h"
20#include "../../core/frame/frame.h"
21
22int libwifi_parse_data(struct libwifi_data *data, struct libwifi_frame *frame);
23
24void libwifi_free_data(struct libwifi_data *data);
25
26#endif /* LIBWIFI_PARSE_DATA_H */
diff --git a/src/libwifi/parse/data/eapol.c b/src/libwifi/parse/data/eapol.c new file mode 100644 index 0000000..b8e3d18 --- /dev/null +++ b/src/libwifi/parse/data/eapol.c
@@ -0,0 +1,190 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "eapol.h"
17#include "../../core/frame/frame.h"
18#include "../../core/misc/byteswap.h"
19#include "../../core/misc/llc.h"
20#include "../../core/misc/security.h"
21
22#include <arpa/inet.h>
23#include <errno.h>
24#include <netinet/in.h>
25#include <stdlib.h>
26#include <string.h>
27
28/**
29 * A libwifi_frame is deemed to be an EAPOL handshake if the following criteria is met:
30 * - The frame is of type TYPE_DATA, and
31 * - The frame contains a logical link control layer, and
32 * - There is enough data in the frame body to fill a libwifi_wpa_auth_data struct.
33 */
34int libwifi_check_wpa_handshake(struct libwifi_frame *frame) {
35 // WPA Handshakes are transmitted in EAPOL frames
36 if (frame->frame_control.type != TYPE_DATA) {
37 return -EINVAL;
38 }
39
40 // Data frame must be at least the length of the header plus the encapsulating LLC
41 if (frame->len < (frame->header_len + sizeof(struct libwifi_logical_link_ctrl))) {
42 return -EINVAL;
43 }
44
45 // Represent the LLC layer so that we can check the OUI and ensure it is correct
46 struct libwifi_logical_link_ctrl *llc = (struct libwifi_logical_link_ctrl *) (frame->body);
47 if (memcmp(llc->oui, XEROX_OUI, sizeof(llc->oui)) != 0) {
48 return -EINVAL;
49 }
50
51 // Match the network byte-order of LLC and ensure we have a frame containing 802.1X information
52 if (ntohs(llc->type) != LLC_TYPE_AUTH) {
53 return -EINVAL;
54 }
55
56 // Ensure we have enough information in the frame to fill a libwifi_wpa_auth_data struct
57 // This value is calculated by ensuring the frame is at least the length of the LLC layer, plus the length
58 // of the libwifi_wpa_auth_data struct, however, the length of an unsigned char pointer is subtracted due
59 // to the possibility of the frame having no WPA key data.
60 size_t required_data_length =
61 frame->header_len + (sizeof(struct libwifi_logical_link_ctrl) +
62 (sizeof(struct libwifi_wpa_auth_data) - sizeof(unsigned char *)));
63 if (frame->len < required_data_length) {
64 return -EINVAL;
65 }
66
67 return 1;
68}
69
70/*
71 * The specific EAPOL message in the supplied libwifi_frame is determined via the 802.1X key information
72 * field.
73 */
74int libwifi_check_wpa_message(struct libwifi_frame *frame) {
75 // Ensure we have enough information in the frame to fill a libwifi_wpa_auth_data struct
76 // This value is calculated by ensuring the frame is at least the length of the LLC layer, plus the length
77 // of the libwifi_wpa_auth_data struct, however, the length of an unsigned char pointer is subtracted due
78 // to the possibility of the frame having no WPA key data.
79 size_t required_data_length =
80 frame->header_len + (sizeof(struct libwifi_logical_link_ctrl) +
81 (sizeof(struct libwifi_wpa_auth_data) - sizeof(unsigned char *)));
82 if (frame->len < required_data_length) {
83 return HANDSHAKE_INVALID;
84 }
85
86 struct libwifi_wpa_auth_data *auth_data =
87 (struct libwifi_wpa_auth_data *) (frame->body + sizeof(struct libwifi_logical_link_ctrl));
88 switch (ntohs(auth_data->key_info.information)) {
89 case EAPOL_KEY_INFO_M1:
90 return HANDSHAKE_M1;
91 case EAPOL_KEY_INFO_M2:
92 return HANDSHAKE_M2;
93 case EAPOL_KEY_INFO_M3:
94 return HANDSHAKE_M3;
95 case EAPOL_KEY_INFO_M4:
96 return HANDSHAKE_M4;
97 default:
98 return HANDSHAKE_INVALID;
99 }
100}
101
102/*
103 * Simple helper function to print a string depending on the EAPOL message
104 */
105const char *libwifi_get_wpa_message_string(struct libwifi_frame *frame) {
106 int message = libwifi_check_wpa_message(frame);
107
108 switch (message) {
109 case HANDSHAKE_M1:
110 return "Message 1";
111 case HANDSHAKE_M2:
112 return "Message 2";
113 case HANDSHAKE_M3:
114 return "Message 3";
115 case HANDSHAKE_M4:
116 return "Message 4";
117 case HANDSHAKE_INVALID:
118 default:
119 return "Invalid";
120 }
121}
122
123/*
124 * The value returned here is the length of the data available _after_ the rest of the EAPOL data,
125 * and should be used for obtaining the EAPOL Key Data, if present.
126 */
127int libwifi_get_wpa_key_data_length(struct libwifi_frame *frame) {
128 if (libwifi_check_wpa_handshake(frame) < 0) {
129 return -EINVAL;
130 }
131
132 struct libwifi_wpa_auth_data *auth_data =
133 (struct libwifi_wpa_auth_data *) (frame->body + sizeof(struct libwifi_logical_link_ctrl));
134
135 // Byte-swap the multi-byte length key_data_length for the host system
136 return ntohs(auth_data->key_info.key_data_length);
137}
138
139/*
140 * Data in the supplied libwifi_frame is expected to be in network byte order. To avoid confusion, this
141 * data is byte-swapped to the host system's endianess.
142 *
143 * If the supplied key_data is not NULL, any key data at the end of the frame will be written into the
144 * supplied key_data buffer. You can obtain the length to malloc such a buffer with
145 * libwifi_get_wpa_key_data_length.
146 */
147int libwifi_get_wpa_data(struct libwifi_frame *frame, struct libwifi_wpa_auth_data *data) {
148 memset(data, 0, sizeof(struct libwifi_wpa_auth_data));
149
150 if (libwifi_check_wpa_handshake(frame) < 0) {
151 return -EINVAL;
152 }
153
154 struct libwifi_wpa_auth_data *auth_data =
155 (struct libwifi_wpa_auth_data *) (frame->body + sizeof(struct libwifi_logical_link_ctrl));
156
157 // Multi-byte fields will be byte-swapped to the host byte order
158 data->version = auth_data->version;
159 data->type = auth_data->type;
160 data->length = ntohs(auth_data->length);
161 data->descriptor = auth_data->descriptor;
162 memcpy(&data->key_info, &auth_data->key_info, sizeof(struct libwifi_wpa_key_info));
163 data->key_info.information = ntohs(auth_data->key_info.information);
164 data->key_info.key_length = ntohs(auth_data->key_info.key_length);
165 data->key_info.replay_counter = be64toh(auth_data->key_info.replay_counter);
166 data->key_info.key_data_length = ntohs(auth_data->key_info.key_data_length);
167
168 if (data->key_info.key_data_length > 0) {
169 // Prevent huge allocations in corrupted or malicious frames
170 if (data->key_info.key_data_length > 1024) {
171 data->key_info.key_data_length = 1024;
172 }
173
174 data->key_info.key_data = malloc(data->key_info.key_data_length);
175 if (data->key_info.key_data == NULL) {
176 return -ENOMEM;
177 }
178 size_t key_data_offset = sizeof(struct libwifi_logical_link_ctrl) +
179 sizeof(struct libwifi_wpa_auth_data) - sizeof(unsigned char *);
180 memcpy(data->key_info.key_data, frame->body + key_data_offset, data->key_info.key_data_length);
181 }
182
183 return 0;
184}
185
186void libwifi_free_wpa_data(struct libwifi_wpa_auth_data *data) {
187 if (data->key_info.key_data_length > 0) {
188 free(data->key_info.key_data);
189 }
190}
diff --git a/src/libwifi/parse/data/eapol.h b/src/libwifi/parse/data/eapol.h new file mode 100644 index 0000000..08b7a35 --- /dev/null +++ b/src/libwifi/parse/data/eapol.h
@@ -0,0 +1,91 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_EAPOL_H
17#define LIBWIFI_PARSE_EAPOL_H
18
19#include "../../core/frame/frame.h"
20#include "../../core/misc/security.h"
21
22enum WPA_HANDSHAKE_PART {
23 HANDSHAKE_M1 = 1,
24 HANDSHAKE_M2 = 2,
25 HANDSHAKE_M3 = 4,
26 HANDSHAKE_M4 = 8,
27 HANDSHAKE_INVALID = 16
28};
29
30/**
31 * Check if a libwifi_frame contains a WPA1/2 handshake message.
32 *
33 * @param libwifi_frame A libwifi_frame
34 * @return 1 if a handshake is detected, 0 if not.
35 */
36int libwifi_check_wpa_handshake(struct libwifi_frame *frame);
37
38/**
39 * Check what message of the WPA1/2 handshake is in the given frame.
40 *
41 * The returned value can be used with the WPA_HANDSHAKE_PART enum,
42 * such as:
43 *
44 * part = libwifi_check_wpa_message(frame);
45 * if (part & HANDSHAKE_M1) {
46 * // This is EAPOL Message 1
47 * }
48 *
49 * @param libwifi_frame A libwifi_frame
50 * @return A bitmask of parts.
51 */
52int libwifi_check_wpa_message(struct libwifi_frame *frame);
53
54/**
55 * Get a string describing the WPA handshake message inside a supplied libwifi_frame.
56 *
57 * @param libwifi_frame A libwifi_frame
58 * @return A string describing the WPA handshake message found
59 */
60const char *libwifi_get_wpa_message_string(struct libwifi_frame *frame);
61
62/**
63 * Get the length of the key data, if any, present at the end of an EAPOL frame.
64 *
65 * @param libwifi_frame A libwifi_frame
66 * @return The length of the key data
67 */
68int libwifi_get_wpa_key_data_length(struct libwifi_frame *frame);
69
70/**
71 * Get the EAPOL/WPA information from a given libwifi_frame.
72 *
73 * As the values in the frame below and including the logical link control layer will be in
74 * network byte order, the values will be automatically byte swapped if necessary to match
75 * the host systems byte order.
76 *
77 * @param libwifi_frame A libwifi_frame
78 * @param data A pointer to a libwifi_wpa_auth_data struct
79 * @return 0 on success, -1 on failure
80 */
81int libwifi_get_wpa_data(struct libwifi_frame *frame, struct libwifi_wpa_auth_data *data);
82
83/**
84 * Free any memory allocated inside of a libwifi_wpa_auth data, such as a buffer
85 * for WPA key data allocated by the library.
86 *
87 * @param data A pointer to a libwifi_wpa_auth_data struct
88 */
89void libwifi_free_wpa_data(struct libwifi_wpa_auth_data *data);
90
91#endif /* LIBWIFI_PARSE_EAPOL_H */
diff --git a/src/libwifi/parse/management/assoc_request.c b/src/libwifi/parse/management/assoc_request.c new file mode 100644 index 0000000..5e1f783 --- /dev/null +++ b/src/libwifi/parse/management/assoc_request.c
@@ -0,0 +1,79 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "assoc_request.h"
17#include "../../core/frame/tag_iterator.h"
18#include "common.h"
19
20#include <errno.h>
21#include <stdlib.h>
22#include <string.h>
23
24/**
25 * libwifi_parse_assoc_req will parse useful fields into a struct libwifi_sta.
26 *
27 * This function also checks to see if the transmitter address can be ANDed
28 * with 0x02, to determine a likelihood of randomized addresses.
29 *
30 * ┌─────────────────────────────────────────────┐
31 * │ Header (Ordered or Unordered) │ ── Association Request Header
32 * ├─────────────────────────────────────────────┤
33 * │ Fixed Parameters │ ─┐
34 * ├─────────────────────────────────────────────┤ ├── Association Request Body
35 * │ Tagged Parameters │ ─┘
36 * └─────────────────────────────────────────────┘
37 */
38int libwifi_parse_assoc_req(struct libwifi_sta *sta, struct libwifi_frame *frame) {
39 memset(sta, 0, sizeof(struct libwifi_sta));
40
41 if (frame->frame_control.type != TYPE_MANAGEMENT || frame->frame_control.subtype != SUBTYPE_ASSOC_REQ) {
42 return -EINVAL;
43 }
44
45 if (frame->frame_control.flags.ordered) {
46 memcpy(sta->transmitter, frame->header.mgmt_ordered.addr2, 6);
47 memcpy(sta->bssid, frame->header.mgmt_ordered.addr3, 6);
48 } else {
49 memcpy(sta->transmitter, frame->header.mgmt_unordered.addr2, 6);
50 memcpy(sta->bssid, frame->header.mgmt_unordered.addr3, 6);
51 }
52
53 if (sta->transmitter[0] & 0x02) {
54 sta->randomized = 1;
55 } else {
56 sta->randomized = 0;
57 }
58
59 // Fixed Parameters must be present
60 if (frame->len <= (frame->header_len + sizeof(struct libwifi_assoc_req_fixed_parameters))) {
61 return -EINVAL;
62 }
63
64 sta->tags.length = (frame->len - frame->header_len);
65 const unsigned char *tagged_params = frame->body;
66 sta->tags.parameters = malloc(sta->tags.length);
67 memcpy(sta->tags.parameters, tagged_params, sta->tags.length);
68
69 struct libwifi_tag_iterator it;
70 if (libwifi_tag_iterator_init(&it, sta->tags.parameters, sta->tags.length) != 0) {
71 return -EINVAL;
72 }
73
74 if (libwifi_sta_tag_parser(sta, &it) != 0) {
75 return -EINVAL;
76 }
77
78 return 0;
79}
diff --git a/src/libwifi/parse/management/assoc_request.h b/src/libwifi/parse/management/assoc_request.h new file mode 100644 index 0000000..2695711 --- /dev/null +++ b/src/libwifi/parse/management/assoc_request.h
@@ -0,0 +1,32 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_ASSOCREQ_H
17#define LIBWIFI_PARSE_ASSOCREQ_H
18
19#include "../../core/frame/frame.h"
20#include "../../core/frame/management/assoc_request.h"
21#include "../../core/frame/management/common.h"
22
23/**
24 * Parse a association request into a libwifi_sta.
25 *
26 * @param sta A libwifi_sta
27 * @param frame A libwifi_frame
28 * @return 0 if successful, a negative number if not
29 */
30int libwifi_parse_assoc_req(struct libwifi_sta *sta, struct libwifi_frame *frame);
31
32#endif /* LIBWIFI_PARSE_ASSOCREQ_H */
diff --git a/src/libwifi/parse/management/assoc_response.c b/src/libwifi/parse/management/assoc_response.c new file mode 100644 index 0000000..27db560 --- /dev/null +++ b/src/libwifi/parse/management/assoc_response.c
@@ -0,0 +1,92 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "../../core/frame/management/assoc_response.h"
17#include "../../core/frame/frame.h"
18#include "../../core/frame/tag.h"
19#include "../../core/frame/tag_iterator.h"
20#include "../../core/misc/types.h"
21#include "../../parse/misc/security.h"
22#include "assoc_response.h"
23#include "common.h"
24
25#include <errno.h>
26#include <stdlib.h>
27#include <string.h>
28
29/**
30 * libwifi_parse_assoc_resp will parse useful information out of a Probe Response
31 * into a struct libwifi_bss. As Probe Response frames are very similar to Beacon
32 * frames, they can be treated in much the same way.
33 *
34 * ┌─────────────────────────────────────────────┐
35 * │ Header (Ordered or Unordered) │ ── Probe Response Header
36 * ├─────────────────────────────────────────────┤
37 * │ Fixed Parameters │ ─┐
38 * ├─────────────────────────────────────────────┤ ├── Probe Response Body
39 * │ Tagged Parameters │ ─┘
40 * └─────────────────────────────────────────────┘
41 */
42int libwifi_parse_assoc_resp(struct libwifi_bss *bss, struct libwifi_frame *frame) {
43 memset(bss, 0, sizeof(struct libwifi_bss));
44
45 if (frame->frame_control.type != TYPE_MANAGEMENT || frame->frame_control.subtype != SUBTYPE_ASSOC_RESP) {
46 return -EINVAL;
47 }
48
49 if (frame->frame_control.flags.ordered) {
50 memcpy(bss->receiver, frame->header.mgmt_ordered.addr1, 6);
51 memcpy(bss->transmitter, frame->header.mgmt_ordered.addr2, 6);
52 memcpy(bss->bssid, frame->header.mgmt_ordered.addr3, 6);
53 } else {
54 memcpy(bss->receiver, frame->header.mgmt_unordered.addr1, 6);
55 memcpy(bss->transmitter, frame->header.mgmt_unordered.addr2, 6);
56 memcpy(bss->bssid, frame->header.mgmt_unordered.addr3, 6);
57 }
58
59 // Fixed Parameters must be present
60 if (frame->len <= (frame->header_len + sizeof(struct libwifi_assoc_resp_fixed_parameters))) {
61 return -EINVAL;
62 }
63
64 // At least one Tagged Parameter must be present
65 if (frame->len < (frame->header_len + sizeof(struct libwifi_assoc_resp_fixed_parameters) + 2)) {
66 return -EINVAL;
67 }
68
69 struct libwifi_assoc_resp_fixed_parameters *fixed_params =
70 (struct libwifi_assoc_resp_fixed_parameters *) frame->body;
71 if (libwifi_check_capabilities(fixed_params->capabilities_information, CAPABILITIES_PRIVACY)) {
72 bss->encryption_info |= WEP;
73 }
74
75 bss->tags.length =
76 (frame->len - (frame->header_len + sizeof(struct libwifi_assoc_resp_fixed_parameters)));
77 const unsigned char *tagged_params = frame->body + sizeof(struct libwifi_assoc_resp_fixed_parameters);
78 bss->tags.parameters = malloc(bss->tags.length);
79 memcpy(bss->tags.parameters, tagged_params, bss->tags.length);
80
81 // Iterate through common BSS tagged parameters (WPA, RSN, etc)
82 struct libwifi_tag_iterator it;
83 memset(&it, 0, sizeof(struct libwifi_tag_iterator));
84 if (libwifi_tag_iterator_init(&it, bss->tags.parameters, bss->tags.length) != 0) {
85 return -EINVAL;
86 }
87 if (libwifi_bss_tag_parser(bss, &it) != 0) {
88 return -EINVAL;
89 };
90
91 return 0;
92}
diff --git a/src/libwifi/parse/management/assoc_response.h b/src/libwifi/parse/management/assoc_response.h new file mode 100644 index 0000000..142388d --- /dev/null +++ b/src/libwifi/parse/management/assoc_response.h
@@ -0,0 +1,35 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_ASSOCRESP_H
17#define LIBWIFI_PARSE_ASSOCRESP_H
18
19#include <stdint.h>
20#include <sys/types.h>
21
22#include "../../core/frame/frame.h"
23#include "../../core/frame/management/common.h"
24#include "../../core/misc/security.h"
25
26/**
27 * Parse an association response frame into a libwifi_bss.
28 *
29 * @param bss A libwifi_bss
30 * @param frame A libwifi_frame
31 * @return 0 if successful, a negative number if not.
32 */
33int libwifi_parse_assoc_resp(struct libwifi_bss *bss, struct libwifi_frame *frame);
34
35#endif /* LIBWIFI_PARSE_ASSOCRESP_H */
diff --git a/src/libwifi/parse/management/beacon.c b/src/libwifi/parse/management/beacon.c new file mode 100644 index 0000000..bd36daf --- /dev/null +++ b/src/libwifi/parse/management/beacon.c
@@ -0,0 +1,91 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "../../core/frame/management/beacon.h"
17#include "../../core/frame/frame.h"
18#include "../../core/frame/tag.h"
19#include "../../core/frame/tag_iterator.h"
20#include "../../core/misc/types.h"
21#include "../../parse/misc/security.h"
22#include "beacon.h"
23#include "common.h"
24
25#include <errno.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30/**
31 * libwifi_parse_beacon will parse useful fields out of a supplied beacon frame
32 * in the format of a struct libwifi_frame.
33 *
34 * ┌─────────────────────────────────────────────┐
35 * │ Header (Ordered or Unordered) │ ── Beacon Header
36 * ├─────────────────────────────────────────────┤
37 * │ Fixed Parameters │ ─┐
38 * ├─────────────────────────────────────────────┤ ├── Beacon Body
39 * │ Tagged Parameters │ ─┘
40 * └─────────────────────────────────────────────┘
41 */
42int libwifi_parse_beacon(struct libwifi_bss *bss, struct libwifi_frame *frame) {
43 memset(bss, 0, sizeof(struct libwifi_bss));
44
45 if (frame->frame_control.type != TYPE_MANAGEMENT || frame->frame_control.subtype != SUBTYPE_BEACON) {
46 return -EINVAL;
47 }
48
49 if (frame->frame_control.flags.ordered) {
50 memcpy(bss->receiver, frame->header.mgmt_ordered.addr1, 6);
51 memcpy(bss->transmitter, frame->header.mgmt_ordered.addr2, 6);
52 memcpy(bss->bssid, frame->header.mgmt_ordered.addr3, 6);
53 } else {
54 memcpy(bss->receiver, frame->header.mgmt_unordered.addr1, 6);
55 memcpy(bss->transmitter, frame->header.mgmt_unordered.addr2, 6);
56 memcpy(bss->bssid, frame->header.mgmt_unordered.addr3, 6);
57 }
58
59 // Fixed Parameters must be present
60 if (frame->len <= (frame->header_len + sizeof(struct libwifi_beacon_fixed_parameters))) {
61 return -EINVAL;
62 }
63
64 // At least one Tagged Parameter must be present
65 if (frame->len < (frame->header_len + sizeof(struct libwifi_beacon_fixed_parameters) + 2)) {
66 return -EINVAL;
67 }
68
69 struct libwifi_beacon_fixed_parameters *fixed_params =
70 (struct libwifi_beacon_fixed_parameters *) frame->body;
71 if (libwifi_check_capabilities(fixed_params->capabilities_information, CAPABILITIES_PRIVACY)) {
72 bss->encryption_info |= WEP;
73 }
74
75 bss->tags.length = (frame->len - (frame->header_len + sizeof(struct libwifi_beacon_fixed_parameters)));
76 const unsigned char *tagged_params = frame->body + sizeof(struct libwifi_beacon_fixed_parameters);
77 bss->tags.parameters = malloc(bss->tags.length);
78 memcpy(bss->tags.parameters, tagged_params, bss->tags.length);
79
80 // Iterate through common BSS tagged parameters (WPA, RSN, etc)
81 struct libwifi_tag_iterator it;
82 memset(&it, 0, sizeof(struct libwifi_tag_iterator));
83 if (libwifi_tag_iterator_init(&it, bss->tags.parameters, bss->tags.length) != 0) {
84 return -EINVAL;
85 }
86 if (libwifi_bss_tag_parser(bss, &it) != 0) {
87 return -EINVAL;
88 };
89
90 return 0;
91}
diff --git a/src/libwifi/parse/management/beacon.h b/src/libwifi/parse/management/beacon.h new file mode 100644 index 0000000..8817d32 --- /dev/null +++ b/src/libwifi/parse/management/beacon.h
@@ -0,0 +1,35 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_BEACON_H
17#define LIBWIFI_PARSE_BEACON_H
18
19#include <stdint.h>
20#include <sys/types.h>
21
22#include "../../core/frame/frame.h"
23#include "../../core/frame/management/common.h"
24#include "../../core/misc/security.h"
25
26/**
27 * Parse useful properties from a beacon frame into a libwifi_bss.
28 *
29 * @param bss A libwifi_bss
30 * @param frame A libwifi_frame
31 * @return 0 if successful, a negative number if not.
32 */
33int libwifi_parse_beacon(struct libwifi_bss *bss, struct libwifi_frame *frame);
34
35#endif /* LIBWIFI_PARSE_BEACON_H */
diff --git a/src/libwifi/parse/management/common.c b/src/libwifi/parse/management/common.c new file mode 100644 index 0000000..14d3d42 --- /dev/null +++ b/src/libwifi/parse/management/common.c
@@ -0,0 +1,192 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "common.h"
17#include "../../core/frame/tag.h"
18#include "../misc/security.h"
19
20#include <errno.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25/**
26 * Different implementations can have variations of hidden SSIDs.
27 * It is common to simply set the SSID to an empty string, but some
28 * devices may "blank" the real SSID without reducing the character count.
29 *
30 * Example: "My-SSID" -> "\x00\x00\x00\x00\x00\x00\x00"
31 */
32void libwifi_handle_ssid_tag(void *target, int target_type, const char *tag_data, int tag_len) {
33 int hidden = 0;
34 int null_ssid = 1;
35
36 if (tag_len <= 0) {
37 hidden = 1;
38 } else if (tag_len > 32) {
39 tag_len = 32;
40 }
41
42 for (int i = 0; i < tag_len; i++) {
43 if (memcmp(&tag_data[i], "\x00", 1) != 0) {
44 null_ssid = 0;
45 break;
46 }
47 }
48
49 if (null_ssid) {
50 hidden = 1;
51 }
52
53 if (target_type == LIBWIFI_BSS) {
54 struct libwifi_bss *bss = (struct libwifi_bss *) target;
55 memcpy(bss->ssid, tag_data, tag_len);
56 bss->hidden = hidden;
57 } else if (target_type == LIBWIFI_STA) {
58 struct libwifi_sta *sta = (struct libwifi_sta *) target;
59 memcpy(sta->ssid, tag_data, tag_len);
60 }
61}
62
63/**
64 * Handle the RSN Tagged Parameter.
65 *
66 * At the minimum, the required RSN data is the version and the group cipher suites.
67 * RSN information is then enumerated within the libwifi_get_rsn_info() function.
68 */
69int libwifi_bss_handle_rsn_tag(struct libwifi_bss *bss, const unsigned char *rsn_data, int rsn_len) {
70 struct libwifi_rsn_info rsn_info = {0};
71
72 bss->encryption_info &= ~(unsigned int) WEP;
73
74 int min_len = sizeof(rsn_info.rsn_version) + sizeof(struct libwifi_cipher_suite);
75 if (rsn_len < min_len) {
76 return -EINVAL;
77 }
78
79 const unsigned char *rsn_end = rsn_data + rsn_len;
80
81 if ((libwifi_get_rsn_info(&rsn_info, rsn_data, rsn_end) != 0)) {
82 return -EINVAL;
83 }
84
85 libwifi_enumerate_rsn_suites(&rsn_info, bss);
86
87 memcpy(&bss->rsn_info, &rsn_info, sizeof(struct libwifi_rsn_info));
88
89 return 0;
90}
91
92/**
93 * The Microsoft vendor tag is used to advertise WPA and WPS information, as well as
94 * some other features such as WMM/WME.
95 *
96 * The difference between the tags is found via the "Vendor Specific OUI Type" field.
97 * A common representation of this is XX:XX:XX:YY, such as 00:50:F2:04, where
98 * 00:50:F2 is the Microsoft OUI and 04 is the type.
99 *
100 * It is important to skip the OUI and Type as described above before parsing the data of
101 * the tag. This is encapsulated with the libwifi_tag_vendor_header struct.
102 */
103int libwifi_bss_handle_msft_tag(struct libwifi_bss *bss, const unsigned char *msft_data, int msft_len) {
104 struct libwifi_wpa_info wpa_info = {0};
105 struct libwifi_tag_vendor_header *vendor_header = (struct libwifi_tag_vendor_header *) msft_data;
106
107 switch (vendor_header->type) {
108 case MICROSOFT_OUI_TYPE_WPA:
109 bss->encryption_info &= ~(unsigned int) WEP;
110 bss->encryption_info |= WPA;
111
112 // Skip 4 bytes for the OUI (3) and Vendor Tag Type (1)
113 const unsigned char *wpa_data = msft_data + sizeof(struct libwifi_tag_vendor_header);
114 const unsigned char *wpa_end = msft_data + (msft_len + sizeof(struct libwifi_tag_vendor_header));
115
116 if ((libwifi_get_wpa_info(&wpa_info, wpa_data, wpa_end) != 0)) {
117 return -EINVAL;
118 }
119
120 libwifi_enumerate_wpa_suites(&wpa_info, bss);
121
122 memcpy(&bss->wpa_info, &wpa_info, sizeof(struct libwifi_wpa_info));
123 break;
124 case MICROSOFT_OUI_TYPE_WMM:
125 // WMM/WME Supported
126 break;
127 case MICROSOFT_OUI_TYPE_WPS:
128 bss->wps = 1;
129 break;
130 }
131
132 return 0;
133}
134
135/**
136 * This function is a parser for common and useful tags found in frames usually originating
137 * from the BSS. These include the SSID and DS or HT fields, which can be used to determine
138 * the channel.
139 */
140int libwifi_bss_tag_parser(struct libwifi_bss *bss, struct libwifi_tag_iterator *it) {
141 struct libwifi_tag_vendor_header *vendor_header = NULL;
142
143 do {
144 switch (it->tag_header->tag_num) {
145 case TAG_SSID:
146 libwifi_handle_ssid_tag((void *) bss, LIBWIFI_BSS, (const char *) it->tag_data,
147 it->tag_header->tag_len);
148 break;
149 case TAG_DS_PARAMETER:
150 case TAG_HT_OPERATION:
151 memcpy(&bss->channel, it->tag_data, 1);
152 break;
153 case TAG_RSN:
154 if ((libwifi_bss_handle_rsn_tag(bss, it->tag_data, it->tag_header->tag_len) != 0)) {
155 return -EINVAL;
156 };
157 break;
158 case TAG_VENDOR_SPECIFIC:
159 vendor_header = (struct libwifi_tag_vendor_header *) it->tag_data;
160
161 if (memcmp(vendor_header->oui, MICROSOFT_OUI, 3) == 0) {
162 if ((libwifi_bss_handle_msft_tag(bss, it->tag_data, it->tag_header->tag_len) != 0)) {
163 return -EINVAL;
164 }
165 }
166 break;
167 }
168 } while (libwifi_tag_iterator_next(it) != -1);
169
170 return 0;
171}
172
173/**
174 * This function is a parser for common and useful tags found in frames usually originating
175 * from the STA. These include the SSID and DS or HT fields, which can be used to determine
176 * the channel.
177 */
178int libwifi_sta_tag_parser(struct libwifi_sta *sta, struct libwifi_tag_iterator *it) {
179 do {
180 switch (it->tag_header->tag_num) {
181 case TAG_SSID:
182 libwifi_handle_ssid_tag(sta, LIBWIFI_STA, (const char *) it->tag_data,
183 it->tag_header->tag_len);
184 break;
185 case TAG_DS_PARAMETER:
186 memcpy(&sta->channel, it->tag_data, 1);
187 break;
188 }
189 } while (libwifi_tag_iterator_next(it) != -1);
190
191 return 0;
192}
diff --git a/src/libwifi/parse/management/common.h b/src/libwifi/parse/management/common.h new file mode 100644 index 0000000..ad6b1dc --- /dev/null +++ b/src/libwifi/parse/management/common.h
@@ -0,0 +1,70 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_MGMT_COMMON_H
17#define LIBWIFI_PARSE_MGMT_COMMON_H
18
19#include "../../core/frame/management/common.h"
20#include "../../core/frame/tag_iterator.h"
21#include "../../core/misc/security.h"
22
23/**
24 * A helper function to set the SSID of a libwifi_bss, as well as check
25 * if it is hidden or not.
26 *
27 * @param target A libwifi_bss or libwifi_sta
28 * @param target_type LIBWIFI_BSS or LIBWIFI_STA
29 * @param ssid The SSID to set
30 * @param ssid_len The length of the supplied SSID
31 */
32void libwifi_handle_ssid_tag(void *target, int target_type, const char *ssid, int ssid_len);
33
34/**
35 * A helper function to handle the parsing of the RSN IE.
36 *
37 * @param bss A libwifi_bss
38 * @param rsn_data The RSN tag data
39 * @param rsn_len The length of the RSN tag data
40 */
41int libwifi_bss_handle_rsn_tag(struct libwifi_bss *bss, const unsigned char *rsn_data, int rsn_len);
42
43/**
44 * A helper function to handle the parsing of the Microsoft Vendor IE.
45 *
46 * @param bss A libwifi_bss
47 * @param msft_data The Microsoft vendor tag data
48 * @param msft_len The length of the Microsoft tag data
49 */
50int libwifi_bss_handle_msft_tag(struct libwifi_bss *bss, const unsigned char *msft_data, int msft_len);
51
52/**
53 * A helper function to iterate through common tags found in a libwifi_bss.
54 *
55 * @param bss A libwifi_bss
56 * @param it A libwifi_tag_iterator
57 * @return 0 if successful, a negative number if not
58 */
59int libwifi_bss_tag_parser(struct libwifi_bss *bss, struct libwifi_tag_iterator *it);
60
61/**
62 * A helper function to iterate through common tags found in a libwifi_sta.
63 *
64 * @param sta A libwifi_sta
65 * @param it A libwifi_tag_iterator
66 * @return 0 if successful, a negative number if not
67 */
68int libwifi_sta_tag_parser(struct libwifi_sta *sta, struct libwifi_tag_iterator *it);
69
70#endif /* LIBWIFI_PARSE_MGMT_COMMON_H */
diff --git a/src/libwifi/parse/management/deauthentication.c b/src/libwifi/parse/management/deauthentication.c new file mode 100644 index 0000000..1d976dc --- /dev/null +++ b/src/libwifi/parse/management/deauthentication.c
@@ -0,0 +1,74 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "deauthentication.h"
17#include "common.h"
18
19#include <errno.h>
20#include <stdlib.h>
21#include <string.h>
22
23/**
24 * TODO: potentally write a parsed_to_gen function that converts a parsed deauth back into
25 * something that can be passed directly into the interface?
26 */
27
28/**
29 * Deauthentication frames can originate from the BSS or the STA, with no way to know
30 * who sent the frame by looking at just the frame alone. Because of this, they are
31 * parsed into a struct libwifi_parsed_deauth instead of a libwifi_bss or libwifi_sta.
32 *
33 * ┌─────────────────────────────────────────────┐
34 * │ Header (Ordered or Unordered) │ ── Deauthentication Header
35 * ├─────────────────────────────────────────────┤
36 * │ Fixed Parameters │ ─┐
37 * ├─────────────────────────────────────────────┤ ├── Deauthentication Body
38 * │ Tagged Parameters │ ─┘
39 * └─────────────────────────────────────────────┘
40 */
41int libwifi_parse_deauth(struct libwifi_parsed_deauth *deauth, struct libwifi_frame *frame) {
42 memset(deauth, 0, sizeof(struct libwifi_parsed_deauth));
43
44 int tags_len = 0;
45
46 if (frame->frame_control.type != TYPE_MANAGEMENT || frame->frame_control.subtype != SUBTYPE_DEAUTH) {
47 return -EINVAL;
48 }
49
50 deauth->ordered = frame->frame_control.flags.ordered;
51
52 if (deauth->ordered) {
53 memcpy(&deauth->frame_header.ordered, &frame->header.mgmt_ordered,
54 sizeof(struct libwifi_mgmt_ordered_frame_header));
55 tags_len = (frame->len - sizeof(struct libwifi_mgmt_ordered_frame_header) -
56 sizeof(struct libwifi_deauth_fixed_parameters));
57 } else {
58 memcpy(&deauth->frame_header.unordered, &frame->header.mgmt_unordered,
59 sizeof(struct libwifi_mgmt_unordered_frame_header));
60 tags_len = (frame->len - sizeof(struct libwifi_mgmt_unordered_frame_header) -
61 sizeof(struct libwifi_deauth_fixed_parameters));
62 }
63
64 unsigned char *body = (unsigned char *) frame->body;
65
66 memcpy(&deauth->fixed_parameters, body, sizeof(struct libwifi_deauth_fixed_parameters));
67 body += sizeof(struct libwifi_deauth_fixed_parameters);
68
69 deauth->tags.parameters = malloc(tags_len);
70 memcpy(&deauth->tags.parameters, body, tags_len);
71 memcpy(&deauth->tags.length, &tags_len, sizeof(tags_len));
72
73 return 0;
74}
diff --git a/src/libwifi/parse/management/deauthentication.h b/src/libwifi/parse/management/deauthentication.h new file mode 100644 index 0000000..761e25c --- /dev/null +++ b/src/libwifi/parse/management/deauthentication.h
@@ -0,0 +1,25 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_DEAUTH_H
17#define LIBWIFI_PARSE_DEAUTH_H
18
19#include "../../core/frame/frame.h"
20#include "../../core/frame/management/common.h"
21#include "../../core/frame/management/deauthentication.h"
22
23int libwifi_parse_deauth(struct libwifi_parsed_deauth *deauth, struct libwifi_frame *frame);
24
25#endif /* LIBWIFI_PARSE_DEAUTH_H */
diff --git a/src/libwifi/parse/management/disassociation.c b/src/libwifi/parse/management/disassociation.c new file mode 100644 index 0000000..2272066 --- /dev/null +++ b/src/libwifi/parse/management/disassociation.c
@@ -0,0 +1,72 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "disassociation.h"
17#include "common.h"
18
19#include <errno.h>
20#include <string.h>
21
22/**
23 * TODO: potentally write a parsed_to_gen function that converts a parsed disassoc back into
24 * something that can be passed directly into the interface?
25 */
26
27/**
28 * Disassociation frames can originate from the BSS or the STA, with no way to know
29 * who sent the frame by looking at just the frame alone. Because of this, they are
30 * parsed into a struct libwifi_parsed_deauth instead of a libwifi_bss or libwifi_sta.
31 *
32 * ┌─────────────────────────────────────────────┐
33 * │ Header (Ordered or Unordered) │ ── Disassociation Header
34 * ├─────────────────────────────────────────────┤
35 * │ Fixed Parameters │ ─┐
36 * ├─────────────────────────────────────────────┤ ├── Disassociation Body
37 * │ Tagged Parameters │ ─┘
38 * └─────────────────────────────────────────────┘
39 */
40int libwifi_parse_disassoc(struct libwifi_parsed_disassoc *disassoc, struct libwifi_frame *frame) {
41 memset(disassoc, 0, sizeof(struct libwifi_parsed_disassoc));
42
43 int tags_len = 0;
44
45 if (frame->frame_control.type != TYPE_MANAGEMENT || frame->frame_control.subtype != SUBTYPE_DISASSOC) {
46 return -EINVAL;
47 }
48
49 disassoc->ordered = frame->frame_control.flags.ordered;
50
51 if (disassoc->ordered) {
52 memcpy(&disassoc->frame_header.ordered, &frame->header.mgmt_ordered,
53 sizeof(struct libwifi_mgmt_ordered_frame_header));
54 tags_len = (frame->len - sizeof(struct libwifi_mgmt_ordered_frame_header) -
55 sizeof(struct libwifi_disassoc_fixed_parameters));
56 } else {
57 memcpy(&disassoc->frame_header.unordered, &frame->header.mgmt_unordered,
58 sizeof(struct libwifi_mgmt_unordered_frame_header));
59 tags_len = (frame->len - sizeof(struct libwifi_mgmt_unordered_frame_header) -
60 sizeof(struct libwifi_disassoc_fixed_parameters));
61 }
62
63 unsigned char *body = (unsigned char *) frame->body;
64
65 memcpy(&disassoc->fixed_parameters, body, sizeof(struct libwifi_disassoc_fixed_parameters));
66 body += sizeof(struct libwifi_disassoc_fixed_parameters);
67
68 memcpy(&disassoc->tags, body, tags_len);
69 body += tags_len;
70
71 return 0;
72}
diff --git a/src/libwifi/parse/management/disassociation.h b/src/libwifi/parse/management/disassociation.h new file mode 100644 index 0000000..dc9a086 --- /dev/null +++ b/src/libwifi/parse/management/disassociation.h
@@ -0,0 +1,25 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_DISASSOC_H
17#define LIBWIFI_PARSE_DISASSOC_H
18
19#include "../../core/frame/frame.h"
20#include "../../core/frame/management/common.h"
21#include "../../core/frame/management/disassociation.h"
22
23int libwifi_parse_disassoc(struct libwifi_parsed_disassoc *disassoc, struct libwifi_frame *frame);
24
25#endif /* LIBWIFI_PARSE_DISASSOC_H */
diff --git a/src/libwifi/parse/management/probe_request.c b/src/libwifi/parse/management/probe_request.c new file mode 100644 index 0000000..7b3fadf --- /dev/null +++ b/src/libwifi/parse/management/probe_request.c
@@ -0,0 +1,72 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "probe_request.h"
17#include "../../core/frame/tag_iterator.h"
18#include "common.h"
19
20#include <errno.h>
21#include <stdlib.h>
22#include <string.h>
23
24/**
25 * libwifi_parse_probe_req will parse useful fields into a struct libwifi_sta.
26 *
27 * This function also checks to see if the transmitter address can be ANDed
28 * with 0x02, to determine a likelihood of randomized addresses.
29 *
30 * ┌─────────────────────────────────────────────┐
31 * │ Header (Ordered or Unordered) │ ── Probe Request Header
32 * ├─────────────────────────────────────────────┤
33 * │ Tagged Parameters │ ── Probe Request Body
34 * └─────────────────────────────────────────────┘
35 */
36int libwifi_parse_probe_req(struct libwifi_sta *sta, struct libwifi_frame *frame) {
37 memset(sta, 0, sizeof(struct libwifi_sta));
38
39 if (frame->frame_control.type != TYPE_MANAGEMENT || frame->frame_control.subtype != SUBTYPE_PROBE_REQ) {
40 return -EINVAL;
41 }
42
43 if (frame->frame_control.flags.ordered) {
44 memcpy(sta->transmitter, frame->header.mgmt_ordered.addr2, 6);
45 memcpy(sta->bssid, frame->header.mgmt_ordered.addr3, 6);
46 } else {
47 memcpy(sta->transmitter, frame->header.mgmt_unordered.addr2, 6);
48 memcpy(sta->bssid, frame->header.mgmt_unordered.addr3, 6);
49 }
50
51 if (sta->transmitter[0] & 0x02) {
52 sta->randomized = 1;
53 } else {
54 sta->randomized = 0;
55 }
56
57 sta->tags.length = (frame->len - frame->header_len);
58 const unsigned char *tagged_params = frame->body;
59 sta->tags.parameters = malloc(sta->tags.length);
60 memcpy(sta->tags.parameters, tagged_params, sta->tags.length);
61
62 struct libwifi_tag_iterator it;
63 if (libwifi_tag_iterator_init(&it, sta->tags.parameters, sta->tags.length) != 0) {
64 return -EINVAL;
65 }
66
67 if (libwifi_sta_tag_parser(sta, &it) != 0) {
68 return -EINVAL;
69 }
70
71 return 0;
72}
diff --git a/src/libwifi/parse/management/probe_request.h b/src/libwifi/parse/management/probe_request.h new file mode 100644 index 0000000..f318b2c --- /dev/null +++ b/src/libwifi/parse/management/probe_request.h
@@ -0,0 +1,32 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_PROBEREQ_H
17#define LIBWIFI_PARSE_PROBEREQ_H
18
19#include "../../core/frame/frame.h"
20#include "../../core/frame/management/common.h"
21#include "../../core/frame/management/probe_request.h"
22
23/**
24 * Parse a probe request into a libwifi_sta.
25 *
26 * @param sta A libwifi_sta
27 * @param frame A libwifi_frame
28 * @return 0 if successful, a negative number if not
29 */
30int libwifi_parse_probe_req(struct libwifi_sta *sta, struct libwifi_frame *frame);
31
32#endif /* LIBWIFI_PARSE_PROBEREQ_H */
diff --git a/src/libwifi/parse/management/probe_response.c b/src/libwifi/parse/management/probe_response.c new file mode 100644 index 0000000..ed2e27f --- /dev/null +++ b/src/libwifi/parse/management/probe_response.c
@@ -0,0 +1,88 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "../../core/frame/management/probe_response.h"
17#include "../../core/frame/frame.h"
18#include "../../core/frame/tag.h"
19#include "../../core/frame/tag_iterator.h"
20#include "../../core/misc/types.h"
21#include "../../parse/misc/security.h"
22#include "common.h"
23#include "probe_response.h"
24
25#include <errno.h>
26#include <stdlib.h>
27#include <string.h>
28
29/**
30 * libwifi_parse_probe_resp will parse useful information out of a Probe Response
31 * into a struct libwifi_bss. As Probe Response frames are very similar to Beacon
32 * frames, they can be treated in much the same way.
33 *
34 * ┌─────────────────────────────────────────────┐
35 * │ Header (Ordered or Unordered) │ ── Probe Response Header
36 * ├─────────────────────────────────────────────┤
37 * │ Fixed Parameters │ ─┐
38 * ├─────────────────────────────────────────────┤ ├── Probe Response Body
39 * │ Tagged Parameters │ ─┘
40 * └─────────────────────────────────────────────┘
41 */
42int libwifi_parse_probe_resp(struct libwifi_bss *bss, struct libwifi_frame *frame) {
43 memset(bss, 0, sizeof(struct libwifi_bss));
44
45 if (frame->frame_control.type != TYPE_MANAGEMENT || frame->frame_control.subtype != SUBTYPE_PROBE_RESP) {
46 return -EINVAL;
47 }
48
49 if (frame->frame_control.flags.ordered) {
50 memcpy(bss->bssid, frame->header.mgmt_ordered.addr3, 6);
51 } else {
52 memcpy(bss->bssid, frame->header.mgmt_unordered.addr3, 6);
53 }
54
55 // Fixed Parameters must be present
56 if (frame->len <= (frame->header_len + sizeof(struct libwifi_probe_resp_fixed_parameters))) {
57 return -EINVAL;
58 }
59
60 // At least one Tagged Parameter must be present
61 if (frame->len < (frame->header_len + sizeof(struct libwifi_probe_resp_fixed_parameters) + 2)) {
62 return -EINVAL;
63 }
64
65 struct libwifi_probe_resp_fixed_parameters *fixed_params =
66 (struct libwifi_probe_resp_fixed_parameters *) frame->body;
67 if (libwifi_check_capabilities(fixed_params->capabilities_information, CAPABILITIES_PRIVACY)) {
68 bss->encryption_info |= WEP;
69 }
70
71 bss->tags.length =
72 (frame->len - (frame->header_len + sizeof(struct libwifi_probe_resp_fixed_parameters)));
73 const unsigned char *tagged_params = frame->body + sizeof(struct libwifi_probe_resp_fixed_parameters);
74 bss->tags.parameters = malloc(bss->tags.length);
75 memcpy(bss->tags.parameters, tagged_params, bss->tags.length);
76
77 // Iterate through common BSS tagged parameters (WPA, RSN, etc)
78 struct libwifi_tag_iterator it;
79 memset(&it, 0, sizeof(struct libwifi_tag_iterator));
80 if (libwifi_tag_iterator_init(&it, bss->tags.parameters, bss->tags.length) != 0) {
81 return -EINVAL;
82 }
83 if (libwifi_bss_tag_parser(bss, &it) != 0) {
84 return -EINVAL;
85 };
86
87 return 0;
88}
diff --git a/src/libwifi/parse/management/probe_response.h b/src/libwifi/parse/management/probe_response.h new file mode 100644 index 0000000..6810fed --- /dev/null +++ b/src/libwifi/parse/management/probe_response.h
@@ -0,0 +1,35 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_PROBERESP_H
17#define LIBWIFI_PARSE_PROBERESP_H
18
19#include <stdint.h>
20#include <sys/types.h>
21
22#include "../../core/frame/frame.h"
23#include "../../core/frame/management/common.h"
24#include "../../core/misc/security.h"
25
26/**
27 * Parse a probe response frame into a libwifi_bss.
28 *
29 * @param bss A libwifi_bss
30 * @param frame A libwifi_frame
31 * @return 0 if successful, a negative number if not.
32 */
33int libwifi_parse_probe_resp(struct libwifi_bss *bss, struct libwifi_frame *frame);
34
35#endif /* LIBWIFI_PARSE_PROBERESP_H */
diff --git a/src/libwifi/parse/management/reassoc_request.c b/src/libwifi/parse/management/reassoc_request.c new file mode 100644 index 0000000..7c4f8ad --- /dev/null +++ b/src/libwifi/parse/management/reassoc_request.c
@@ -0,0 +1,79 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "reassoc_request.h"
17#include "../../core/frame/tag_iterator.h"
18#include "common.h"
19
20#include <errno.h>
21#include <stdlib.h>
22#include <string.h>
23
24/**
25 * libwifi_parse_reassoc_req will parse useful fields into a struct libwifi_sta.
26 *
27 * This function also checks to see if the transmitter address can be ANDed
28 * with 0x02, to determine a likelihood of randomized addresses.
29 *
30 * ┌─────────────────────────────────────────────┐
31 * │ Header (Ordered or Unordered) │ ── Ressociation Request Header
32 * ├─────────────────────────────────────────────┤
33 * │ Fixed Parameters │ ─┐
34 * ├─────────────────────────────────────────────┤ |── Ressociation Request Body
35 * │ Tagged Parameters │ ─┘
36 * └─────────────────────────────────────────────┘
37 */
38int libwifi_parse_reassoc_req(struct libwifi_sta *sta, struct libwifi_frame *frame) {
39 memset(sta, 0, sizeof(struct libwifi_sta));
40
41 if (frame->frame_control.type != TYPE_MANAGEMENT || frame->frame_control.subtype != SUBTYPE_REASSOC_REQ) {
42 return -EINVAL;
43 }
44
45 if (frame->frame_control.flags.ordered) {
46 memcpy(sta->transmitter, frame->header.mgmt_ordered.addr2, 6);
47 memcpy(sta->bssid, frame->header.mgmt_ordered.addr3, 6);
48 } else {
49 memcpy(sta->transmitter, frame->header.mgmt_unordered.addr2, 6);
50 memcpy(sta->bssid, frame->header.mgmt_unordered.addr3, 6);
51 }
52
53 if (sta->transmitter[0] & 0x02) {
54 sta->randomized = 1;
55 } else {
56 sta->randomized = 0;
57 }
58
59 // Fixed Parameters must be present
60 if (frame->len <= (frame->header_len + sizeof(struct libwifi_reassoc_req_fixed_parameters))) {
61 return -EINVAL;
62 }
63
64 sta->tags.length = (frame->len - frame->header_len);
65 const unsigned char *tagged_params = frame->body;
66 sta->tags.parameters = malloc(sta->tags.length);
67 memcpy(sta->tags.parameters, tagged_params, sta->tags.length);
68
69 struct libwifi_tag_iterator it;
70 if (libwifi_tag_iterator_init(&it, sta->tags.parameters, sta->tags.length) != 0) {
71 return -EINVAL;
72 }
73
74 if (libwifi_sta_tag_parser(sta, &it) != 0) {
75 return -EINVAL;
76 }
77
78 return 0;
79}
diff --git a/src/libwifi/parse/management/reassoc_request.h b/src/libwifi/parse/management/reassoc_request.h new file mode 100644 index 0000000..73e0c79 --- /dev/null +++ b/src/libwifi/parse/management/reassoc_request.h
@@ -0,0 +1,32 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_REASSOCREQ_H
17#define LIBWIFI_PARSE_REASSOCREQ_H
18
19#include "../../core/frame/frame.h"
20#include "../../core/frame/management/common.h"
21#include "../../core/frame/management/reassoc_request.h"
22
23/**
24 * Parse a reassociation request into a libwifi_sta.
25 *
26 * @param sta A libwifi_sta
27 * @param frame A libwifi_frame
28 * @return 0 if successful, a negative number if not
29 */
30int libwifi_parse_reassoc_req(struct libwifi_sta *sta, struct libwifi_frame *frame);
31
32#endif /* LIBWIFI_PARSE_REASSOCREQ_H */
diff --git a/src/libwifi/parse/management/reassoc_response.c b/src/libwifi/parse/management/reassoc_response.c new file mode 100644 index 0000000..2c92827 --- /dev/null +++ b/src/libwifi/parse/management/reassoc_response.c
@@ -0,0 +1,92 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "../../core/frame/management/reassoc_response.h"
17#include "../../core/frame/frame.h"
18#include "../../core/frame/tag.h"
19#include "../../core/frame/tag_iterator.h"
20#include "../../core/misc/types.h"
21#include "../../parse/misc/security.h"
22#include "common.h"
23#include "reassoc_response.h"
24
25#include <errno.h>
26#include <stdlib.h>
27#include <string.h>
28
29/**
30 * libwifi_parse_reassoc_resp will parse useful information out of a Reassocation Response
31 * into a struct libwifi_bss.
32 *
33 * ┌─────────────────────────────────────────────┐
34 * │ Header (Ordered or Unordered) │ ── Reassocation Response Header
35 * ├─────────────────────────────────────────────┤
36 * │ Fixed Parameters │ ─┐
37 * ├─────────────────────────────────────────────┤ ├── Reassociation Response Body
38 * │ Tagged Parameters │ ─┘
39 * └─────────────────────────────────────────────┘
40 */
41int libwifi_parse_reassoc_resp(struct libwifi_bss *bss, struct libwifi_frame *frame) {
42 memset(bss, 0, sizeof(struct libwifi_bss));
43
44 if (frame->frame_control.type != TYPE_MANAGEMENT ||
45 frame->frame_control.subtype != SUBTYPE_REASSOC_RESP) {
46 return -EINVAL;
47 }
48
49 if (frame->frame_control.flags.ordered) {
50 memcpy(bss->receiver, frame->header.mgmt_ordered.addr1, 6);
51 memcpy(bss->transmitter, frame->header.mgmt_ordered.addr2, 6);
52 memcpy(bss->bssid, frame->header.mgmt_ordered.addr3, 6);
53 } else {
54 memcpy(bss->receiver, frame->header.mgmt_unordered.addr1, 6);
55 memcpy(bss->transmitter, frame->header.mgmt_unordered.addr2, 6);
56 memcpy(bss->bssid, frame->header.mgmt_unordered.addr3, 6);
57 }
58
59 // Fixed Parameters must be present
60 if (frame->len <= (frame->header_len + sizeof(struct libwifi_reassoc_resp_fixed_parameters))) {
61 return -EINVAL;
62 }
63
64 // At least one Tagged Parameter must be present
65 if (frame->len < (frame->header_len + sizeof(struct libwifi_reassoc_resp_fixed_parameters) + 2)) {
66 return -EINVAL;
67 }
68
69 struct libwifi_reassoc_resp_fixed_parameters *fixed_params =
70 (struct libwifi_reassoc_resp_fixed_parameters *) frame->body;
71 if (libwifi_check_capabilities(fixed_params->capabilities_information, CAPABILITIES_PRIVACY)) {
72 bss->encryption_info |= WEP;
73 }
74
75 bss->tags.length =
76 (frame->len - (frame->header_len + sizeof(struct libwifi_reassoc_resp_fixed_parameters)));
77 const unsigned char *tagged_params = frame->body + sizeof(struct libwifi_reassoc_resp_fixed_parameters);
78 bss->tags.parameters = malloc(bss->tags.length);
79 memcpy(bss->tags.parameters, tagged_params, bss->tags.length);
80
81 // Iterate through common BSS tagged parameters (WPA, RSN, etc)
82 struct libwifi_tag_iterator it;
83 memset(&it, 0, sizeof(struct libwifi_tag_iterator));
84 if (libwifi_tag_iterator_init(&it, bss->tags.parameters, bss->tags.length) != 0) {
85 return -EINVAL;
86 }
87 if (libwifi_bss_tag_parser(bss, &it) != 0) {
88 return -EINVAL;
89 };
90
91 return 0;
92}
diff --git a/src/libwifi/parse/management/reassoc_response.h b/src/libwifi/parse/management/reassoc_response.h new file mode 100644 index 0000000..ba14a6d --- /dev/null +++ b/src/libwifi/parse/management/reassoc_response.h
@@ -0,0 +1,35 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_REASSOCRESP_H
17#define LIBWIFI_PARSE_REASSOCRESP_H
18
19#include <stdint.h>
20#include <sys/types.h>
21
22#include "../../core/frame/frame.h"
23#include "../../core/frame/management/common.h"
24#include "../../core/misc/security.h"
25
26/**
27 * Parse a reassociation response frame into a libwifi_bss.
28 *
29 * @param bss A libwifi_bss
30 * @param frame A libwifi_frame
31 * @return 0 if successful, a negative number if not.
32 */
33int libwifi_parse_reassoc_resp(struct libwifi_bss *bss, struct libwifi_frame *frame);
34
35#endif /* LIBWIFI_PARSE_REASSOCRESP_H */
diff --git a/src/libwifi/parse/misc/radiotap.c b/src/libwifi/parse/misc/radiotap.c new file mode 100644 index 0000000..176167e --- /dev/null +++ b/src/libwifi/parse/misc/radiotap.c
@@ -0,0 +1,126 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "radiotap.h"
17#include "../../core/radiotap/radiotap_iter.h"
18
19#include <endian.h>
20#include <stdint.h>
21
22/**
23 * The libwifi radiotap parser uses the usual ieee80211_radiotap_iterator to parse incoming
24 * radiotap headers into a consumable libwifi_radiotap_info struct.
25 */
26void libwifi_parse_radiotap_info(struct libwifi_radiotap_info *info, const unsigned char *frame) {
27 memset(info, 0, sizeof(struct libwifi_radiotap_info));
28
29 struct ieee80211_radiotap_header *rh = (struct ieee80211_radiotap_header *) frame;
30 struct ieee80211_radiotap_iterator it = {0};
31 int ret = ieee80211_radiotap_iterator_init(&it, (void *) frame, rh->it_len, NULL);
32
33 int skipped_antenna = 0;
34 info->length = rh->it_len;
35
36 while (!ret) {
37 switch (it.this_arg_index) {
38 case IEEE80211_RADIOTAP_CHANNEL:
39 info->channel.freq = le16toh(*(uint16_t *) it.this_arg);
40 info->channel.flags = le16toh(*(uint16_t *) (it.this_arg + 2));
41 break;
42 case IEEE80211_RADIOTAP_RATE:
43 info->rate_raw = *it.this_arg;
44 info->rate = (*it.this_arg / 2.0);
45 break;
46 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
47 // Radiotap Headers will include the ANTSIGNAL without an explicit Antenna definition.
48 if (!skipped_antenna) {
49 info->signal = *it.this_arg;
50 skipped_antenna = 1;
51 break;
52 }
53
54 if (info->antenna_count < LIBWIFI_MAX_RADIOTAP_ANTENNAS) {
55 struct libwifi_radiotap_antenna antenna = {.antenna_number = info->antenna_count,
56 .signal = *it.this_arg};
57 info->antennas[info->antenna_count] = antenna;
58 info->antenna_count += 1;
59 }
60 break;
61 case IEEE80211_RADIOTAP_ANTENNA:
62 info->antennas[info->antenna_count - 1].antenna_number = *it.this_arg;
63 break;
64 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
65 break;
66 case IEEE80211_RADIOTAP_FLAGS:
67 info->flags = *it.this_arg;
68 break;
69 case IEEE80211_RADIOTAP_EXT:
70 info->extended_flags = *it.this_arg;
71 break;
72 case IEEE80211_RADIOTAP_RX_FLAGS:
73 info->rx_flags = *it.this_arg;
74 break;
75 case IEEE80211_RADIOTAP_TX_FLAGS:
76 info->tx_flags = *it.this_arg;
77 break;
78 case IEEE80211_RADIOTAP_MCS:
79 info->mcs.known = *(uint8_t *) it.this_arg;
80 info->mcs.flags = *(uint8_t *) (it.this_arg + 2);
81 info->mcs.mcs = *(uint8_t *) (it.this_arg + 3);
82 break;
83 case IEEE80211_RADIOTAP_DBM_TX_POWER:
84 info->tx_power = *it.this_arg;
85 break;
86 case IEEE80211_RADIOTAP_TIMESTAMP:
87 info->timestamp.timestamp = le64toh(*(uint64_t *) it.this_arg);
88 info->timestamp.accuracy = le16toh(*(uint16_t *) (it.this_arg + 2));
89 info->timestamp.unit = *(uint8_t *) (it.this_arg + 3);
90 info->timestamp.flags = *(uint8_t *) (it.this_arg + 4);
91 break;
92 case IEEE80211_RADIOTAP_RTS_RETRIES:
93 info->rts_retries = *it.this_arg;
94 break;
95 case IEEE80211_RADIOTAP_DATA_RETRIES:
96 info->data_retries = *it.this_arg;
97 break;
98 }
99
100 ret = ieee80211_radiotap_iterator_next(&it);
101 }
102}
103
104/**
105 * A simpler function than the main libwifi_parse_radiotap_info function, designed to extract
106 * only the signal strength field.
107 */
108int8_t libwifi_parse_radiotap_rssi(const unsigned char *frame) {
109 struct ieee80211_radiotap_header *rh = (struct ieee80211_radiotap_header *) frame;
110
111 int8_t rssi = 0;
112
113 struct ieee80211_radiotap_iterator it;
114 int ret = ieee80211_radiotap_iterator_init(&it, (void *) frame, rh->it_len, NULL);
115
116 while (!ret) {
117 if (it.this_arg_index == IEEE80211_RADIOTAP_DBM_ANTSIGNAL) {
118 rssi = *it.this_arg;
119 break;
120 }
121
122 ret = ieee80211_radiotap_iterator_next(&it);
123 }
124
125 return rssi;
126}
diff --git a/src/libwifi/parse/misc/radiotap.h b/src/libwifi/parse/misc/radiotap.h new file mode 100644 index 0000000..8f74e6a --- /dev/null +++ b/src/libwifi/parse/misc/radiotap.h
@@ -0,0 +1,39 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_RADIOTAP_H
17#define LIBWIFI_PARSE_RADIOTAP_H
18
19#include "../../core/misc/radiotap.h"
20#include <stdint.h>
21
22/**
23 * Parse the radiotap information out of a raw frame into a
24 * libwifi_radiotap_info.
25 *
26 * @param info A libwifi_radiotap_info
27 * @param frame A raw 802.11 frame
28 */
29void libwifi_parse_radiotap_info(struct libwifi_radiotap_info *info, const unsigned char *frame);
30
31/**
32 * Retrieve the signal strength from a raw frame via radiotap header.
33 *
34 * @param frame A raw 802.11 frame
35 * @return signal strength in dBm
36 */
37int8_t libwifi_parse_radiotap_rssi(const unsigned char *frame);
38
39#endif /* LIBWIFI_PARSE_RADIOTAP_H */
diff --git a/src/libwifi/parse/misc/security.c b/src/libwifi/parse/misc/security.c new file mode 100644 index 0000000..bf211f7 --- /dev/null +++ b/src/libwifi/parse/misc/security.c
@@ -0,0 +1,685 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "security.h"
17#include "../../core/misc/byteswap.h"
18
19#include <errno.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
24/**
25 * RSN Information is supplied via the raw tag data. The supplied data is then "walked"
26 * through as a pointer to extract the details of the tag and write them into
27 * a struct libwifi_rsn_info.
28 *
29 * libwifi supports a maximum of 3 Pairwise Cipher Suites and 3 Auth Key Management Suites.
30 * The Version, Group Cipher Suite and Capabilities fields are all required.
31 */
32int libwifi_get_rsn_info(struct libwifi_rsn_info *info, const unsigned char *tag_data,
33 const unsigned char *tag_end) {
34 memset(info, 0, sizeof(struct libwifi_rsn_info));
35
36 // Create a pointer we can manipulate from the tag data
37 unsigned char *data = (unsigned char *) tag_data;
38
39 // Handle the RSN Version
40 memcpy(&info->rsn_version, data, sizeof(info->rsn_version));
41 data += sizeof(info->rsn_version);
42
43 // Handle the RSN Group Cipher Suites
44 memcpy(&info->group_cipher_suite, data, sizeof(struct libwifi_cipher_suite));
45 data += sizeof(struct libwifi_cipher_suite);
46
47 // Bounds check and handle the RSN Pairwise Ciphers
48 if (data > tag_end) {
49 return -EINVAL;
50 }
51 if ((data + sizeof(uint16_t)) > tag_end) {
52 return -EINVAL;
53 }
54 uint16_t suite_count = *data;
55 if (suite_count > LIBWIFI_MAX_CIPHER_SUITES) {
56 suite_count = LIBWIFI_MAX_CIPHER_SUITES;
57 }
58 data += sizeof(suite_count);
59 if ((((suite_count * sizeof(struct libwifi_cipher_suite)) + data)) > tag_end) {
60 return -EINVAL;
61 }
62 info->num_pairwise_cipher_suites = suite_count;
63
64 // Iterate through the found Pairwise Ciphers, adding them each time
65 struct wifi_cipher_suite *cur_cipher_suite = NULL;
66 for (int i = 0; i < suite_count; ++i) {
67 if (data > tag_end) {
68 return -EINVAL;
69 }
70 cur_cipher_suite = (struct wifi_cipher_suite *) data;
71 memcpy(&info->pairwise_cipher_suites[i], cur_cipher_suite, sizeof(struct libwifi_cipher_suite));
72 info->pairwise_cipher_suites[i].suite_type = info->pairwise_cipher_suites[i].suite_type;
73 data += sizeof(struct libwifi_cipher_suite);
74 }
75
76 // Bounds check and handle the RSN Authentication Key Management Suites
77 if ((data + sizeof(suite_count)) > tag_end) {
78 return -EINVAL;
79 }
80 suite_count = *data;
81 if (suite_count > LIBWIFI_MAX_CIPHER_SUITES) {
82 suite_count = LIBWIFI_MAX_CIPHER_SUITES;
83 }
84 data += sizeof(suite_count);
85 if ((((suite_count * sizeof(struct libwifi_cipher_suite)) + data)) > tag_end) {
86 return -EINVAL;
87 }
88 info->num_auth_key_mgmt_suites = suite_count;
89
90 // Iterate through the found Auth Key Management Suites, adding them each time
91 for (int i = 0; i < suite_count; ++i) {
92 if (data > tag_end) {
93 return -EINVAL;
94 }
95 cur_cipher_suite = (struct wifi_cipher_suite *) data;
96 memcpy(&info->auth_key_mgmt_suites[i], cur_cipher_suite, sizeof(struct libwifi_cipher_suite));
97 info->auth_key_mgmt_suites[i].suite_type = info->auth_key_mgmt_suites[i].suite_type;
98 data += sizeof(struct libwifi_cipher_suite);
99 }
100
101 // Bounds check and handle the RSN Capabilities field
102 if (data > tag_end) {
103 return -EINVAL;
104 }
105 memcpy(&info->rsn_capabilities, data, sizeof(info->rsn_capabilities));
106
107 return 0;
108}
109
110/**
111 * This function will enumerate over a supplied struct libwifi_rsn_info and write
112 * the following into a supplied struct libwifi_bss:
113 *
114 * - Group Cipher Suite
115 * - Up to 3 Pairwise Cipher Suites
116 * - Up to 3 Auth Key Management Suites
117 * - The WPA Type (WPA2 or WPA3)
118 *
119 * The bss->encryption_info field is a 64-bit wide bitmask. The larger length is
120 * required to accomodate the different types of cipher suites without having
121 * any overlap between group cipher and pairwise cipher.
122 */
123void libwifi_enumerate_rsn_suites(struct libwifi_rsn_info *rsn_info, struct libwifi_bss *bss) {
124 switch (rsn_info->group_cipher_suite.suite_type) {
125 case CIPHER_SUITE_WEP40:
126 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_WEP40;
127 break;
128 case CIPHER_SUITE_TKIP:
129 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_TKIP;
130 break;
131 case CIPHER_SUITE_RESERVED:
132 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_RESERVED;
133 break;
134 case CIPHER_SUITE_CCMP128:
135 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_CCMP128;
136 break;
137 case CIPHER_SUITE_WEP104:
138 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_WEP104;
139 break;
140 case CIPHER_SUITE_BIP_CMAC128:
141 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_BIP_CMAC128;
142 break;
143 case CIPHER_SUITE_NOTALLOWED:
144 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_NOTALLOWED;
145 break;
146 case CIPHER_SUITE_GCMP128:
147 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_GCMP128;
148 break;
149 case CIPHER_SUITE_GCMP256:
150 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_GCMP256;
151 break;
152 case CIPHER_SUITE_CCMP256:
153 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_CCMP256;
154 break;
155 case CIPHER_SUITE_BIP_GMAC128:
156 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_BIP_GMAC128;
157 break;
158 case CIPHER_SUITE_BIP_GMAC256:
159 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_BIP_GMAC256;
160 break;
161 case CIPHER_SUITE_BIP_CMAC256:
162 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_BIP_CMAC256;
163 break;
164 default:
165 break;
166 }
167
168 for (int i = 0; i < rsn_info->num_pairwise_cipher_suites; ++i) {
169 if ((memcmp(rsn_info->pairwise_cipher_suites[i].oui, CIPHER_SUITE_OUI, 3) == 0)) {
170 switch (rsn_info->pairwise_cipher_suites[i].suite_type) {
171 case CIPHER_SUITE_GROUP:
172 bss->encryption_info |= LIBWIFI_PAIRWISE_SUITE_GROUP;
173 break;
174 case CIPHER_SUITE_TKIP:
175 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_TKIP;
176 break;
177 case CIPHER_SUITE_RESERVED:
178 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_RESERVED;
179 break;
180 case CIPHER_SUITE_CCMP128:
181 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_CCMP128;
182 break;
183 case CIPHER_SUITE_BIP_CMAC128:
184 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_CMAC128;
185 break;
186 case CIPHER_SUITE_NOTALLOWED:
187 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_NOTALLOWED;
188 break;
189 case CIPHER_SUITE_GCMP128:
190 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_GCMP128;
191 break;
192 case CIPHER_SUITE_GCMP256:
193 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_GCMP256;
194 break;
195 case CIPHER_SUITE_CCMP256:
196 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_CCMP256;
197 break;
198 case CIPHER_SUITE_BIP_GMAC128:
199 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_GMAC128;
200 break;
201 case CIPHER_SUITE_BIP_GMAC256:
202 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_GMAC256;
203 break;
204 case CIPHER_SUITE_BIP_CMAC256:
205 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_CMAC256;
206 break;
207 default:
208 break;
209 }
210 }
211 }
212
213 for (int i = 0; i < rsn_info->num_auth_key_mgmt_suites; ++i) {
214 if (memcmp(rsn_info->auth_key_mgmt_suites[i].oui, CIPHER_SUITE_OUI, 3) == 0) {
215 switch (rsn_info->auth_key_mgmt_suites[i].suite_type) {
216 case AKM_SUITE_RESERVED:
217 bss->encryption_info |= WPA2;
218 bss->encryption_info |= LIBWIFI_AKM_SUITE_RESERVED;
219 break;
220 case AKM_SUITE_1X:
221 bss->encryption_info |= WPA2;
222 bss->encryption_info |= LIBWIFI_AKM_SUITE_1X;
223 break;
224 case AKM_SUITE_PSK:
225 bss->encryption_info |= WPA2;
226 bss->encryption_info |= LIBWIFI_AKM_SUITE_PSK;
227 break;
228 case AKM_SUITE_1X_FT:
229 bss->encryption_info |= WPA2;
230 bss->encryption_info |= LIBWIFI_AKM_SUITE_1X_FT;
231 break;
232 case AKM_SUITE_PSK_FT:
233 bss->encryption_info |= WPA2;
234 bss->encryption_info |= LIBWIFI_AKM_SUITE_PSK_FT;
235 break;
236 case AKM_SUITE_1X_SHA256:
237 bss->encryption_info |= WPA2;
238 bss->encryption_info |= LIBWIFI_AKM_SUITE_1X_SHA256;
239 break;
240 case AKM_SUITE_PSK_SHA256:
241 bss->encryption_info |= WPA2;
242 bss->encryption_info |= LIBWIFI_AKM_SUITE_PSK_SHA256;
243 break;
244 case AKM_SUITE_TDLS:
245 bss->encryption_info |= WPA2;
246 bss->encryption_info |= LIBWIFI_AKM_SUITE_TDLS;
247 break;
248 case AKM_SUITE_SAE:
249 bss->encryption_info |= WPA3;
250 bss->encryption_info |= LIBWIFI_AKM_SUITE_SAE;
251 break;
252 case AKM_SUITE_SAE_FT:
253 bss->encryption_info |= WPA3;
254 bss->encryption_info |= LIBWIFI_AKM_SUITE_SAE_FT;
255 break;
256 case AKM_SUITE_AP_PEER:
257 bss->encryption_info |= WPA3;
258 bss->encryption_info |= LIBWIFI_AKM_SUITE_AP_PEER;
259 break;
260 case AKM_SUITE_1X_SUITEB_SHA256:
261 bss->encryption_info |= WPA3;
262 bss->encryption_info |= LIBWIFI_AKM_SUITE_1X_SUITEB_SHA256;
263 break;
264 case AKM_SUITE_1X_SUITEB_SHA384:
265 bss->encryption_info |= WPA3;
266 bss->encryption_info |= LIBWIFI_AKM_SUITE_1X_SUITEB_SHA384;
267 break;
268 case AKM_SUITE_1X_FT_SHA384:
269 bss->encryption_info |= WPA3;
270 bss->encryption_info |= LIBWIFI_AKM_SUITE_1X_FT_SHA384;
271 break;
272 case AKM_SUITE_FILS_SHA256:
273 bss->encryption_info |= WPA2;
274 bss->encryption_info |= LIBWIFI_AKM_SUITE_FILS_SHA256;
275 break;
276 case AKM_SUITE_FILS_SHA384:
277 bss->encryption_info |= WPA3;
278 bss->encryption_info |= LIBWIFI_AKM_SUITE_FILS_SHA384;
279 break;
280 case AKM_SUITE_FILS_SHA256_FT:
281 bss->encryption_info |= WPA2;
282 bss->encryption_info |= LIBWIFI_AKM_SUITE_FILS_SHA256_FT;
283 break;
284 case AKM_SUITE_FILS_SHA384_FT:
285 bss->encryption_info |= WPA3;
286 bss->encryption_info |= LIBWIFI_AKM_SUITE_FILS_SHA384_FT;
287 break;
288 case AKM_SUITE_OWE:
289 bss->encryption_info |= WPA3;
290 bss->encryption_info |= LIBWIFI_AKM_SUITE_OWE;
291 break;
292 case AKM_PSK_SHA384_FT:
293 bss->encryption_info |= WPA3;
294 bss->encryption_info |= LIBWIFI_AKM_PSK_SHA384_FT;
295 break;
296 case AKM_PSK_SHA384:
297 bss->encryption_info |= WPA3;
298 bss->encryption_info |= LIBWIFI_AKM_PSK_SHA384;
299 break;
300 default:
301 break;
302 }
303 }
304 }
305}
306
307/**
308 * Similar to libwifi_get_rsn_info, WPA Information is supplied via the raw tag data.
309 * The supplied data is then "walked" through as a pointer to extract the details of
310 * the tag and write them into a struct libwifi_wpa_info.
311 *
312 * libwifi supports a maximum of 3 Unicast Cipher Suites and 3 Auth Key Management Suites.
313 * The Version and Multicast Cipher Suite fields are required.
314 */
315int libwifi_get_wpa_info(struct libwifi_wpa_info *info, const unsigned char *tag_data,
316 const unsigned char *tag_end) {
317 memset(info, 0, sizeof(struct libwifi_wpa_info));
318
319 // Create a pointer we can manipulate from the tag data
320 unsigned char *data = ((unsigned char *) tag_data);
321
322 // Handle the WPA Version
323 memcpy(&info->wpa_version, data, sizeof(info->wpa_version));
324 data += sizeof(info->wpa_version);
325
326 // Handle the WPA Multicast Cipher Suite
327 memcpy(&info->multicast_cipher_suite, data, sizeof(struct libwifi_cipher_suite));
328 data += sizeof(struct libwifi_cipher_suite);
329
330 // Bounds check and handle the WPA Unicast Cipher Suites
331 if (data > tag_end) {
332 return -EINVAL;
333 }
334 if ((data + sizeof(uint16_t)) > tag_end) {
335 return -EINVAL;
336 }
337 uint16_t suite_count = *data;
338 if (suite_count > LIBWIFI_MAX_CIPHER_SUITES) {
339 suite_count = LIBWIFI_MAX_CIPHER_SUITES;
340 }
341 data += sizeof(suite_count);
342 if ((((suite_count * sizeof(struct libwifi_cipher_suite)) + data)) > tag_end) {
343 return -EINVAL;
344 }
345 info->num_unicast_cipher_suites = suite_count;
346
347 // Iterate through the found Unicast Ciphers, adding them each time
348 struct wifi_cipher_suite *cur_cipher_suite = NULL;
349 for (int i = 0; i < suite_count; ++i) {
350 if (data > tag_end) {
351 return -EINVAL;
352 }
353 cur_cipher_suite = (struct wifi_cipher_suite *) data;
354 memcpy(&info->unicast_cipher_suites[i], cur_cipher_suite, sizeof(struct libwifi_cipher_suite));
355 info->unicast_cipher_suites[i].suite_type = info->unicast_cipher_suites[i].suite_type;
356 data += sizeof(struct libwifi_cipher_suite);
357 }
358
359 // Bounds check and handle the WPA Authentication Key Management Suites
360 if ((data + sizeof(suite_count)) > tag_end) {
361 return -EINVAL;
362 }
363 suite_count = *data;
364 if (suite_count > LIBWIFI_MAX_CIPHER_SUITES) {
365 suite_count = LIBWIFI_MAX_CIPHER_SUITES;
366 }
367 data += sizeof(suite_count);
368 if ((((suite_count * sizeof(struct libwifi_cipher_suite)) + data)) > tag_end) {
369 return -EINVAL;
370 }
371 info->num_auth_key_mgmt_suites = suite_count;
372
373 // Iterate through the found Auth Key Management Suites, adding them each time
374 for (int i = 0; i < suite_count; ++i) {
375 if (data > tag_end) {
376 return -EINVAL;
377 }
378 cur_cipher_suite = (struct wifi_cipher_suite *) data;
379 memcpy(&info->auth_key_mgmt_suites[i], cur_cipher_suite, sizeof(struct libwifi_cipher_suite));
380 info->auth_key_mgmt_suites[i].suite_type = info->auth_key_mgmt_suites[i].suite_type;
381 data += sizeof(struct libwifi_cipher_suite);
382 }
383
384 return 0;
385}
386
387/**
388 * Similarly to libwifi_enumerate_wpa_suites, this function will enumerate over a supplied
389 * struct libwifi_wpa_info and write the following into a supplied struct libwifi_bss:
390 *
391 * - Multicast Cipher Suite
392 * - Up to 3 Unicast Cipher Suites
393 * - Up to 3 Auth Key Management Suites
394 *
395 * The bss->encryption_info field is a 64-bit wide bitmask. The larger length is
396 * required to accomodate the different types of cipher suites without having
397 * any overlap between group cipher and pairwise cipher.
398 */
399void libwifi_enumerate_wpa_suites(struct libwifi_wpa_info *wpa_info, struct libwifi_bss *bss) {
400 switch (wpa_info->multicast_cipher_suite.suite_type) {
401 case CIPHER_SUITE_WEP40:
402 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_WEP40;
403 break;
404 case CIPHER_SUITE_WEP104:
405 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_WEP104;
406 break;
407 case CIPHER_SUITE_TKIP:
408 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_TKIP;
409 break;
410 case CIPHER_SUITE_RESERVED:
411 bss->encryption_info |= LIBWIFI_GROUP_CIPHER_SUITE_RESERVED;
412 break;
413 default:
414 break;
415 }
416
417 for (int i = 0; i < wpa_info->num_unicast_cipher_suites; ++i) {
418 if ((memcmp(wpa_info->unicast_cipher_suites[i].oui, MICROSOFT_OUI, 3) == 0)) {
419 switch (wpa_info->unicast_cipher_suites[i].suite_type) {
420 case CIPHER_SUITE_GROUP:
421 bss->encryption_info |= LIBWIFI_PAIRWISE_SUITE_GROUP;
422 break;
423 case CIPHER_SUITE_TKIP:
424 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_TKIP;
425 break;
426 case CIPHER_SUITE_RESERVED:
427 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_RESERVED;
428 break;
429 case CIPHER_SUITE_WEP40:
430 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_WEP40;
431 break;
432 case CIPHER_SUITE_WEP104:
433 bss->encryption_info |= LIBWIFI_PAIRWISE_CIPHER_SUITE_WEP104;
434 break;
435 default:
436 break;
437 }
438 }
439 }
440
441 for (int i = 0; i < wpa_info->num_auth_key_mgmt_suites; ++i) {
442 if (memcmp(wpa_info->auth_key_mgmt_suites[i].oui, MICROSOFT_OUI, 3) == 0) {
443 switch (wpa_info->auth_key_mgmt_suites[i].suite_type) {
444 case AKM_SUITE_RESERVED:
445 bss->encryption_info |= WPA;
446 bss->encryption_info |= LIBWIFI_AKM_SUITE_RESERVED;
447 break;
448 case AKM_SUITE_1X:
449 bss->encryption_info |= WPA;
450 bss->encryption_info |= LIBWIFI_AKM_SUITE_1X;
451 break;
452 case AKM_SUITE_PSK:
453 bss->encryption_info |= WPA;
454 bss->encryption_info |= LIBWIFI_AKM_SUITE_PSK;
455 break;
456 case AKM_SUITE_1X_FT:
457 bss->encryption_info |= WPA;
458 bss->encryption_info |= LIBWIFI_AKM_SUITE_1X_FT;
459 break;
460 case AKM_SUITE_PSK_FT:
461 bss->encryption_info |= WPA;
462 bss->encryption_info |= LIBWIFI_AKM_SUITE_PSK_FT;
463 break;
464 }
465 }
466 }
467}
468
469void libwifi_get_security_type(struct libwifi_bss *bss, char *buf) {
470 memset(buf, 0, LIBWIFI_SECURITY_BUF_LEN);
471
472 int offset = 0;
473 int append = 0;
474
475 if (bss->encryption_info == 0) {
476 snprintf(buf, LIBWIFI_SECURITY_BUF_LEN, "None");
477 return;
478 }
479
480 if (bss->encryption_info & WPA3) {
481 _libwifi_add_sec_item(buf, &offset, &append, "WPA3");
482 }
483 if (bss->encryption_info & WPA2) {
484 _libwifi_add_sec_item(buf, &offset, &append, "WPA2");
485 }
486 if (bss->encryption_info & WPA) {
487 _libwifi_add_sec_item(buf, &offset, &append, "WPA");
488 }
489 if (bss->encryption_info & WEP) {
490 _libwifi_add_sec_item(buf, &offset, &append, "WEP");
491 }
492}
493
494void libwifi_get_group_ciphers(struct libwifi_bss *bss, char *buf) {
495 memset(buf, 0, LIBWIFI_SECURITY_BUF_LEN);
496
497 int offset = 0;
498 int append = 0;
499
500 if (bss->encryption_info == 0) {
501 snprintf(buf + offset, LIBWIFI_SECURITY_BUF_LEN, "None");
502 return;
503 }
504
505 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_WEP40) {
506 _libwifi_add_sec_item(buf, &offset, &append, "WEP40");
507 }
508 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_TKIP) {
509 _libwifi_add_sec_item(buf, &offset, &append, "TKIP");
510 }
511 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_RESERVED) {
512 _libwifi_add_sec_item(buf, &offset, &append, "RESERVED");
513 }
514 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_CCMP128) {
515 _libwifi_add_sec_item(buf, &offset, &append, "CCMP128");
516 }
517 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_WEP104) {
518 _libwifi_add_sec_item(buf, &offset, &append, "WEP104");
519 }
520 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_BIP_CMAC128) {
521 _libwifi_add_sec_item(buf, &offset, &append, "BIP_CMAC128");
522 }
523 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_NOTALLOWED) {
524 _libwifi_add_sec_item(buf, &offset, &append, "NOT_ALLOWED");
525 }
526 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_GCMP128) {
527 _libwifi_add_sec_item(buf, &offset, &append, "GCMP128");
528 }
529 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_GCMP256) {
530 _libwifi_add_sec_item(buf, &offset, &append, "GCMP256");
531 }
532 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_CCMP256) {
533 _libwifi_add_sec_item(buf, &offset, &append, "CCMP256");
534 }
535 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_BIP_GMAC128) {
536 _libwifi_add_sec_item(buf, &offset, &append, "BIP_GMAC128");
537 }
538 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_BIP_GMAC256) {
539 _libwifi_add_sec_item(buf, &offset, &append, "BIP_GMAC256");
540 }
541 if (bss->encryption_info & LIBWIFI_GROUP_CIPHER_SUITE_BIP_CMAC256) {
542 _libwifi_add_sec_item(buf, &offset, &append, "BIP_CMAC256");
543 }
544}
545
546void libwifi_get_pairwise_ciphers(struct libwifi_bss *bss, char *buf) {
547 memset(buf, 0, LIBWIFI_SECURITY_BUF_LEN);
548
549 int offset = 0;
550 int append = 0;
551
552 if (bss->encryption_info == 0) {
553 snprintf(buf + offset, LIBWIFI_SECURITY_BUF_LEN, "None");
554 return;
555 }
556
557 if (bss->encryption_info & LIBWIFI_PAIRWISE_SUITE_GROUP) {
558 _libwifi_add_sec_item(buf, &offset, &append, "GROUP");
559 }
560 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_WEP40) {
561 _libwifi_add_sec_item(buf, &offset, &append, "WEP40");
562 }
563 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_TKIP) {
564 _libwifi_add_sec_item(buf, &offset, &append, "TKIP");
565 }
566 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_RESERVED) {
567 _libwifi_add_sec_item(buf, &offset, &append, "RESERVED");
568 }
569 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_CCMP128) {
570 _libwifi_add_sec_item(buf, &offset, &append, "CCMP128");
571 }
572 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_WEP104) {
573 _libwifi_add_sec_item(buf, &offset, &append, "WEP104");
574 }
575 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_CMAC128) {
576 _libwifi_add_sec_item(buf, &offset, &append, "BIP_CMAC128");
577 }
578 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_NOTALLOWED) {
579 _libwifi_add_sec_item(buf, &offset, &append, "NOT_ALLOWED");
580 }
581 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_GCMP128) {
582 _libwifi_add_sec_item(buf, &offset, &append, "GCMP128");
583 }
584 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_GCMP256) {
585 _libwifi_add_sec_item(buf, &offset, &append, "GCMP256");
586 }
587 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_CCMP256) {
588 _libwifi_add_sec_item(buf, &offset, &append, "CCMP256");
589 }
590 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_GMAC128) {
591 _libwifi_add_sec_item(buf, &offset, &append, "BIP_GMAC128");
592 }
593 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_GMAC256) {
594 _libwifi_add_sec_item(buf, &offset, &append, "BIP_GMAC256");
595 }
596 if (bss->encryption_info & LIBWIFI_PAIRWISE_CIPHER_SUITE_BIP_CMAC256) {
597 _libwifi_add_sec_item(buf, &offset, &append, "BIP_CMAC256");
598 }
599}
600
601void libwifi_get_auth_key_suites(struct libwifi_bss *bss, char *buf) {
602 memset(buf, 0, LIBWIFI_SECURITY_BUF_LEN);
603
604 int offset = 0;
605 int append = 0;
606
607 if (bss->encryption_info == 0) {
608 snprintf(buf + offset, LIBWIFI_SECURITY_BUF_LEN, "None");
609 return;
610 }
611
612 if (bss->encryption_info & LIBWIFI_AKM_SUITE_RESERVED) {
613 _libwifi_add_sec_item(buf, &offset, &append, "RESERVED");
614 }
615 if (bss->encryption_info & LIBWIFI_AKM_SUITE_1X) {
616 _libwifi_add_sec_item(buf, &offset, &append, "802.1X");
617 }
618 if (bss->encryption_info & LIBWIFI_AKM_SUITE_PSK) {
619 _libwifi_add_sec_item(buf, &offset, &append, "PSK");
620 }
621 if (bss->encryption_info & LIBWIFI_AKM_SUITE_1X_FT) {
622 _libwifi_add_sec_item(buf, &offset, &append, "802.1X_FT");
623 }
624 if (bss->encryption_info & LIBWIFI_AKM_SUITE_PSK_FT) {
625 _libwifi_add_sec_item(buf, &offset, &append, "PSK_FT");
626 }
627 if (bss->encryption_info & LIBWIFI_AKM_SUITE_1X_SHA256) {
628 _libwifi_add_sec_item(buf, &offset, &append, "802.1X_SHA256");
629 }
630 if (bss->encryption_info & LIBWIFI_AKM_SUITE_PSK_SHA256) {
631 _libwifi_add_sec_item(buf, &offset, &append, "PSK_SHA256");
632 }
633 if (bss->encryption_info & LIBWIFI_AKM_SUITE_TDLS) {
634 _libwifi_add_sec_item(buf, &offset, &append, "TDLS");
635 }
636 if (bss->encryption_info & LIBWIFI_AKM_SUITE_SAE) {
637 _libwifi_add_sec_item(buf, &offset, &append, "SAE");
638 }
639 if (bss->encryption_info & LIBWIFI_AKM_SUITE_SAE_FT) {
640 _libwifi_add_sec_item(buf, &offset, &append, "SAE_FT");
641 }
642 if (bss->encryption_info & LIBWIFI_AKM_SUITE_AP_PEER) {
643 _libwifi_add_sec_item(buf, &offset, &append, "AP_PEER");
644 }
645 if (bss->encryption_info & LIBWIFI_AKM_SUITE_1X_SUITEB_SHA256) {
646 _libwifi_add_sec_item(buf, &offset, &append, "802.1X_SUITEB_SHA256");
647 }
648 if (bss->encryption_info & LIBWIFI_AKM_SUITE_1X_SUITEB_SHA384) {
649 _libwifi_add_sec_item(buf, &offset, &append, "802.1X_SUITEB_SHA384");
650 }
651 if (bss->encryption_info & LIBWIFI_AKM_SUITE_1X_FT_SHA384) {
652 _libwifi_add_sec_item(buf, &offset, &append, "802.1X_FT_SHA384");
653 }
654 if (bss->encryption_info & LIBWIFI_AKM_SUITE_FILS_SHA256) {
655 _libwifi_add_sec_item(buf, &offset, &append, "FILS_SHA256");
656 }
657 if (bss->encryption_info & LIBWIFI_AKM_SUITE_FILS_SHA384) {
658 _libwifi_add_sec_item(buf, &offset, &append, "FILS_SHA384");
659 }
660 if (bss->encryption_info & LIBWIFI_AKM_SUITE_FILS_SHA256_FT) {
661 _libwifi_add_sec_item(buf, &offset, &append, "FILS_SHA256_FT");
662 }
663 if (bss->encryption_info & LIBWIFI_AKM_SUITE_FILS_SHA384_FT) {
664 _libwifi_add_sec_item(buf, &offset, &append, "FILS_SHA384_FT");
665 }
666 if (bss->encryption_info & LIBWIFI_AKM_SUITE_OWE) {
667 _libwifi_add_sec_item(buf, &offset, &append, "OWE");
668 }
669 if (bss->encryption_info & LIBWIFI_AKM_PSK_SHA384_FT) {
670 _libwifi_add_sec_item(buf, &offset, &append, "PSK_SHA384_FT");
671 }
672 if (bss->encryption_info & LIBWIFI_AKM_PSK_SHA384) {
673 _libwifi_add_sec_item(buf, &offset, &append, "PSK_SHA384");
674 }
675}
676
677void _libwifi_add_sec_item(char *buf, int *offset, int *append, char *item) {
678 if (*append) {
679 snprintf(buf + *offset, LIBWIFI_SECURITY_BUF_LEN, ", ");
680 *offset += strlen(", ");
681 }
682 snprintf(buf + *offset, LIBWIFI_SECURITY_BUF_LEN, "%s", item);
683 *offset += strlen(item);
684 *append = 1;
685}
diff --git a/src/libwifi/parse/misc/security.h b/src/libwifi/parse/misc/security.h new file mode 100644 index 0000000..dba2850 --- /dev/null +++ b/src/libwifi/parse/misc/security.h
@@ -0,0 +1,124 @@
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef LIBWIFI_PARSE_SECURITY_H
17#define LIBWIFI_PARSE_SECURITY_H
18
19#include "../../core/frame/management/common.h"
20#include "../../core/misc/security.h"
21
22#include <stdint.h>
23
24#define LIBWIFI_SECURITY_BUF_LEN 256
25
26/**
27 * Get the RSN related information and store it in a
28 * libwifi_rsn_info. This function will detect and enumerate
29 * cipher suites, and AKM suites, and the RSN capabilities
30 * from a specified RSN IE.
31 *
32 * @param info A libwifi_rsn_info
33 * @param tag_data An RSN IE tag
34 * @param tag_end The end of the specified RSN IE tag
35 * @return
36 */
37int libwifi_get_rsn_info(struct libwifi_rsn_info *info, const unsigned char *tag_data,
38 const unsigned char *tag_end);
39
40/**
41 * Enumerate the RSN cipher suites in a libwifi_rsn_info.
42 *
43 * This function can be used to fill a libwifi_bss struct
44 * with information related to the cipher suites and AKM suites
45 * in the specified libwifi_rsn_info.
46 *
47 * @param rsn_info A libwifi_rsn_info
48 * @param libwifi_bss A libwifi_bss
49 */
50void libwifi_enumerate_rsn_suites(struct libwifi_rsn_info *rsn_info, struct libwifi_bss *bss);
51
52/**
53 * Get the WPA related information and store it in a
54 * libwifi_wpa_info. This function will detect and enumerate
55 * cipher suites and AKM suites from a specified WPA IE.
56 *
57 * @param info A libwifi_wpa_info
58 * @param tag_data A WPA IE tag
59 * @param tag_end The end of the specified WPA IE tag
60 * @return
61 */
62int libwifi_get_wpa_info(struct libwifi_wpa_info *info, const unsigned char *tag_data,
63 const unsigned char *tag_end);
64
65/**
66 * Enumerate the WPA cipher suites in a libwifi_wpa_info.
67 *
68 * This function can be used to fill a libwifi_bss struct
69 * with information related to the cipher suites and AKM suites
70 * in the specified libwifi_wpa_info.
71 *
72 * @param wpa_info A libwifi_wpa_info
73 * @param libwifi_bss A libwifi_bss
74 */
75void libwifi_enumerate_wpa_suites(struct libwifi_wpa_info *wpa_info, struct libwifi_bss *bss);
76
77/**
78 * Enumerate the security types (WEP, WPA, WPA2, WPA3, etc) in a given libwifi_bss,
79 * formatted into the given buffer.
80 *
81 * @param bss A libwifi_bss struct
82 * @param buf A buffer of length LIBWIFI_SECURITY_BUF_LEN
83 */
84void libwifi_get_security_type(struct libwifi_bss *bss, char *buf);
85
86/**
87 * Enumerate the group ciphers (CCMP, GCMP128, etc) in a given libwifi_bss,
88 * formatted into the given buffer.
89 *
90 * @param bss A libwifi_bss struct
91 * @param buf A buffer of length LIBWIFI_SECURITY_BUF_LEN
92 */
93void libwifi_get_group_ciphers(struct libwifi_bss *bss, char *buf);
94
95/**
96 * Enumerate the pairwise ciphers (GROUP, CCMP, BIP_CMAC128, etc) in a given libwifi_bss,
97 * formatted into the given buffer.
98 *
99 * @param bss A libwifi_bss struct
100 * @param buf A buffer of length LIBWIFI_SECURITY_BUF_LEN
101 */
102void libwifi_get_pairwise_ciphers(struct libwifi_bss *bss, char *buf);
103
104/**
105 * Enumerate the auth key management suites in a given libwifi_bss,
106 * formatted into the given buffer.
107 *
108 * @param bss A libwifi_bss struct
109 * @param buf A buffer of length LIBWIFI_SECURITY_BUF_LEN
110 */
111void libwifi_get_auth_key_suites(struct libwifi_bss *bss, char *buf);
112
113/**
114 * Internal function for adding a formatted string to a buffer for use with
115 * libwifi_get_* security functions.
116 *
117 * @param buf A buffer of length LIBWIFI_SECURITY_BUF_LEN
118 * @param offset A pointer to the current buffer offset variable
119 * @param append A pointer to the append state variable
120 * @param item A pointer to the string to append to the given buf
121 */
122void _libwifi_add_sec_item(char *buf, int *offset, int *append, char *item);
123
124#endif /* LIBWIFI_PARSE_SECURITY_H */