diff options
author | Marc <foxtrot@malloc.me> | 2021-11-30 22:39:26 +0000 |
---|---|---|
committer | Marc <foxtrot@malloc.me> | 2021-12-01 16:54:44 +0000 |
commit | ae6c98a48da409d040604aeffb84a38155fb5bac (patch) | |
tree | c27a8e28972209581ce3fba2130bf0c2b4f9c9c0 /src | |
download | libwifi-ae6c98a48da409d040604aeffb84a38155fb5bac.tar.gz libwifi-ae6c98a48da409d040604aeffb84a38155fb5bac.tar.bz2 libwifi-ae6c98a48da409d040604aeffb84a38155fb5bac.zip |
Initial Commit
Signed-off-by: Marc <foxtrot@malloc.me>
Diffstat (limited to 'src')
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 | ||
5 | extern "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 | */ | ||
24 | void 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 | */ | ||
37 | void libwifi_dummy(void) { | ||
38 | return; | ||
39 | } | ||
40 | |||
41 | /** | ||
42 | * Version | ||
43 | */ | ||
44 | const 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 | */ | ||
39 | void libwifi_random_mac(unsigned char buf[6], unsigned char prefix[3]); | ||
40 | |||
41 | /** | ||
42 | * Dummy function for linker testing purposes. | ||
43 | */ | ||
44 | void libwifi_dummy(void); | ||
45 | |||
46 | /** | ||
47 | * Obtain the version of libwifi. | ||
48 | * | ||
49 | * @return The version of the installed libwifi. | ||
50 | */ | ||
51 | const 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 | */ | ||
30 | struct 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 | */ | ||
32 | struct 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 | */ | ||
26 | uint32_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 | */ | ||
47 | uint32_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 | */ | ||
55 | int 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 | */ | ||
29 | uint32_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 | */ | ||
38 | uint32_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 | */ | ||
47 | int 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 | */ | ||
25 | struct 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 | */ | ||
35 | int 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 | |||
143 | void 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 */ | ||
29 | enum libwifi_frame_type { | ||
30 | TYPE_MANAGEMENT = 0, | ||
31 | TYPE_CONTROL = 1, | ||
32 | TYPE_DATA = 2, | ||
33 | TYPE_EXTENSION = 3, | ||
34 | }; | ||
35 | enum 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 | }; | ||
53 | enum 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 | }; | ||
69 | enum 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 | }; | ||
82 | enum 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 | }; | ||
96 | enum 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 | |||
106 | struct 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 | */ | ||
120 | struct 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 | */ | ||
130 | struct 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 | */ | ||
141 | struct 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 | */ | ||
179 | struct 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 | */ | ||
206 | struct 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 | */ | ||
224 | struct 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 | */ | ||
246 | struct 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 | */ | ||
274 | struct 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 | */ | ||
287 | union 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 | */ | ||
298 | union 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 | */ | ||
307 | struct 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 | */ | ||
324 | int 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 | */ | ||
332 | void 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 */ | ||
23 | enum 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 | |||
78 | struct libwifi_action_detail { | ||
79 | uint8_t detail_length; | ||
80 | char *detail; | ||
81 | } __attribute__((packed)); | ||
82 | |||
83 | struct libwifi_action_fixed_parameters { | ||
84 | uint8_t category; | ||
85 | struct libwifi_action_detail details; | ||
86 | } __attribute__((packed)); | ||
87 | |||
88 | struct 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 | |||
40 | struct libwifi_assoc_req_fixed_parameters { | ||
41 | uint16_t capabilities_information; | ||
42 | uint16_t listen_interval; | ||
43 | } __attribute__((packed)); | ||
44 | |||
45 | struct 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 | |||
42 | struct libwifi_assoc_resp_fixed_parameters { | ||
43 | uint16_t capabilities_information; | ||
44 | uint16_t status_code; | ||
45 | uint16_t association_id; | ||
46 | } __attribute__((packed)); | ||
47 | |||
48 | struct 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 | |||
29 | struct 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 | |||
42 | struct libwifi_auth_fixed_parameters { | ||
43 | uint16_t algorithm_number; | ||
44 | uint16_t transaction_sequence; | ||
45 | uint16_t status_code; | ||
46 | } __attribute__((packed)); | ||
47 | |||
48 | struct 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 | |||
42 | struct libwifi_beacon_fixed_parameters { | ||
43 | uint64_t timestamp; | ||
44 | uint16_t beacon_interval; | ||
45 | uint16_t capabilities_information; | ||
46 | } __attribute__((packed)); | ||
47 | |||
48 | struct 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 | */ | ||
44 | struct 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 | */ | ||
64 | static 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 | */ | ||
81 | struct 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 | */ | ||
97 | static 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 | |||
38 | struct libwifi_deauth_fixed_parameters { | ||
39 | uint16_t reason_code; | ||
40 | } __attribute__((packed)); | ||
41 | |||
42 | struct 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 | |||
48 | struct 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 | |||
38 | struct libwifi_disassoc_fixed_parameters { | ||
39 | uint16_t reason_code; | ||
40 | } __attribute__((packed)); | ||
41 | |||
42 | struct 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 | |||
48 | struct 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 | |||
33 | struct 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 | |||
42 | struct libwifi_probe_resp_fixed_parameters { | ||
43 | uint64_t timestamp; | ||
44 | uint16_t probe_resp_interval; | ||
45 | uint16_t capabilities_information; | ||
46 | } __attribute__((packed)); | ||
47 | |||
48 | struct 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 | |||
42 | struct 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 | |||
48 | struct 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 | |||
42 | struct libwifi_reassoc_resp_fixed_parameters { | ||
43 | uint16_t capabilities_information; | ||
44 | uint16_t status_code; | ||
45 | uint16_t association_id; | ||
46 | } __attribute__((packed)); | ||
47 | |||
48 | struct 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 | |||
57 | struct 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 | |||
64 | struct 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 | |||
76 | struct 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 | |||
25 | int 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 | |||
55 | int 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 | |||
81 | size_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 | |||
99 | void libwifi_free_tag(struct libwifi_tagged_parameter *tagged_parameter) { | ||
100 | free(tagged_parameter->body); | ||
101 | } | ||
102 | |||
103 | size_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 | |||
118 | int 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 */ | ||
23 | enum 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 | */ | ||
214 | struct 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 | */ | ||
224 | struct 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 | */ | ||
232 | struct 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 | */ | ||
241 | struct 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 | */ | ||
252 | int 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 | */ | ||
261 | int 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 | */ | ||
274 | size_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 | */ | ||
282 | void 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 | */ | ||
292 | size_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 | */ | ||
303 | int 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 | |||
22 | int 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 | |||
35 | int 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 | */ | ||
28 | struct 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 | */ | ||
43 | int 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 | */ | ||
51 | int 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 | |||
19 | unsigned 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 | */ | ||
24 | unsigned 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 | |||
25 | struct 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 | */ | ||
28 | struct 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 | */ | ||
36 | struct 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 | */ | ||
44 | struct 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 | */ | ||
53 | struct libwifi_radiotap_timestamp { | ||
54 | uint64_t timestamp; | ||
55 | uint16_t accuracy; | ||
56 | uint8_t unit; | ||
57 | uint8_t flags; | ||
58 | } __attribute__((packed)); | ||
59 | |||
60 | struct 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 | */ | ||
172 | struct 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 | */ | ||
193 | struct 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 | */ | ||
220 | struct 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 | */ | ||
254 | struct 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 | */ | ||
281 | struct 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 */ | ||
22 | enum 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 */ | ||
87 | enum 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)) | ||
200 | enum 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 @@ | |||
1 | Copyright (c) 2007-2009 Andy Green <andy@warmcat.com> | ||
2 | Copyright (c) 2007-2009 Johannes Berg <johannes@sipsolutions.net> | ||
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. | ||
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 | |||
19 | static 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 | |||
135 | const 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 | |||
178 | EXPORT | ||
179 | int 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 | |||
253 | static 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 | ||
273 | static 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 | |||
316 | EXPORT | ||
317 | int 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 | */ | ||
41 | struct 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 | |||
66 | extern const struct ieee80211_radiotap_namespace radiotap_ns; | ||
67 | |||
68 | /* see the radiotap website for the descriptions */ | ||
69 | enum 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 */ | ||
101 | enum 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 */ | ||
112 | enum 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 */ | ||
123 | enum ieee80211_radiotap_rx_flags { | ||
124 | IEEE80211_RADIOTAP_F_RX_BADPLCP = 0x0002, | ||
125 | }; | ||
126 | |||
127 | /* for IEEE80211_RADIOTAP_TX_FLAGS */ | ||
128 | enum 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 */ | ||
136 | enum 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 | |||
145 | enum 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 */ | ||
163 | enum 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 */ | ||
173 | enum 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 | |||
185 | enum 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 | |||
194 | enum 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 */ | ||
202 | enum 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 | |||
215 | enum 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 | |||
12 | struct radiotap_override { | ||
13 | uint8_t field; | ||
14 | uint8_t align : 4, size : 4; | ||
15 | }; | ||
16 | |||
17 | struct radiotap_align_size { | ||
18 | uint8_t align : 4, size : 4; | ||
19 | }; | ||
20 | |||
21 | struct 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 | |||
28 | struct 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 | |||
65 | struct 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 | |||
93 | IMPORT extern CALLING_CONVENTION int | ||
94 | ieee80211_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 | |||
98 | IMPORT extern CALLING_CONVENTION int | ||
99 | ieee80211_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 | |||
20 | int 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 | */ | ||
28 | int 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 | |||
20 | int 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 | */ | ||
29 | int 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 | |||
22 | size_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 | |||
42 | void 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 | |||
49 | int 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 | |||
66 | int 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 | |||
83 | size_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 | |||
88 | size_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 | |||
108 | void 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 | */ | ||
31 | size_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 | */ | ||
39 | void 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 | */ | ||
50 | int libwifi_create_action(struct libwifi_action *action, const unsigned char receiver[6], | ||
51 | const unsigned char transmitter[6], uint8_t category); | ||
52 | int 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 | */ | ||
61 | size_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 | */ | ||
71 | size_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 | */ | ||
78 | void 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 | */ | ||
27 | size_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 | */ | ||
36 | int 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 | */ | ||
60 | size_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 | */ | ||
83 | void 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 | */ | ||
33 | int 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); | ||
35 | size_t libwifi_get_assoc_req_length(struct libwifi_assoc_req *assoc_req); | ||
36 | size_t libwifi_dump_assoc_req(struct libwifi_assoc_req *assoc_req, unsigned char *buf, size_t buf_len); | ||
37 | void 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 | */ | ||
35 | size_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 | */ | ||
44 | void 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 | */ | ||
58 | void 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 | */ | ||
81 | size_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 | */ | ||
104 | void 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 | */ | ||
27 | void 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 | */ | ||
35 | size_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 | */ | ||
49 | void 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 | */ | ||
60 | size_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 | */ | ||
67 | void 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 | |||
21 | int 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 | |||
21 | int 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 | */ | ||
27 | size_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 | */ | ||
35 | void 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 | */ | ||
56 | size_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 | */ | ||
79 | void 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 | */ | ||
29 | size_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 | */ | ||
43 | void 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 | */ | ||
55 | size_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 | */ | ||
62 | void 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 | */ | ||
34 | size_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 | */ | ||
42 | void 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 | */ | ||
53 | void 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 | */ | ||
67 | void 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 | */ | ||
92 | size_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 | */ | ||
115 | void 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 | */ | ||
27 | void 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 | */ | ||
35 | void 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 | */ | ||
43 | size_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 | */ | ||
58 | void 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 | */ | ||
69 | size_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 | */ | ||
76 | void 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 | */ | ||
27 | size_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 | */ | ||
36 | int 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 | */ | ||
57 | size_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 | */ | ||
80 | void 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 | */ | ||
29 | size_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 | */ | ||
43 | int 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 | */ | ||
54 | size_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 | */ | ||
61 | void 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 | */ | ||
27 | size_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 | */ | ||
36 | void 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 | */ | ||
55 | size_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 | */ | ||
78 | void 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 | */ | ||
29 | size_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 | */ | ||
43 | void 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 | */ | ||
54 | size_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 | */ | ||
61 | void 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 | */ | ||
26 | size_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 | */ | ||
34 | void 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 | */ | ||
54 | size_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 | */ | ||
74 | void 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 | */ | ||
29 | size_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 | */ | ||
43 | void 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 | */ | ||
55 | size_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 | */ | ||
62 | void 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 | */ | ||
34 | size_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 | */ | ||
42 | void 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 | */ | ||
53 | void 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 | */ | ||
67 | void 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 | */ | ||
93 | size_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 | */ | ||
116 | void 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 | */ | ||
27 | void 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 | */ | ||
35 | void 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 | */ | ||
43 | size_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 | */ | ||
58 | void 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 | */ | ||
69 | size_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 | */ | ||
76 | void 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 | */ | ||
27 | size_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 | */ | ||
36 | int 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 | */ | ||
62 | size_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 | */ | ||
85 | void 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 | |||
23 | int 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); | ||
26 | size_t libwifi_get_reassoc_req_length(struct libwifi_reassoc_req *reassoc_req); | ||
27 | size_t libwifi_dump_reassoc_req(struct libwifi_reassoc_req *reassoc_req, unsigned char *buf, size_t buf_len); | ||
28 | void 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 | */ | ||
35 | size_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 | */ | ||
44 | void 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 | */ | ||
58 | void 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 | */ | ||
81 | size_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 | */ | ||
106 | void 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 | */ | ||
27 | void 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 | */ | ||
35 | size_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 | */ | ||
49 | void 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 | */ | ||
60 | size_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 | */ | ||
68 | void 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 | |||
25 | void 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 | |||
84 | size_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 | |||
90 | size_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 | |||
109 | void 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 | |||
21 | void 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 | |||
26 | size_t libwifi_get_timing_advert_length(struct libwifi_timing_advert *adv); | ||
27 | |||
28 | size_t libwifi_dump_timing_advert(struct libwifi_timing_advert *adv, unsigned char *buf, size_t buf_len); | ||
29 | |||
30 | void 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 | |||
26 | size_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 | */ | ||
29 | size_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 | |||
22 | int 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 | |||
46 | void 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 | |||
22 | int libwifi_parse_data(struct libwifi_data *data, struct libwifi_frame *frame); | ||
23 | |||
24 | void 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 | */ | ||
34 | int 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 | */ | ||
74 | int 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 | */ | ||
105 | const 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 | */ | ||
127 | int 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 | */ | ||
147 | int 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 | |||
186 | void 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 | |||
22 | enum 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 | */ | ||
36 | int 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 | */ | ||
52 | int 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 | */ | ||
60 | const 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 | */ | ||
68 | int 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 | */ | ||
81 | int 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 | */ | ||
89 | void 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 | */ | ||
38 | int 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 | */ | ||
30 | int 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 | */ | ||
42 | int 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 | */ | ||
33 | int 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 | */ | ||
42 | int 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 | */ | ||
33 | int 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 | */ | ||
32 | void 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 | */ | ||
69 | int 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 | */ | ||
103 | int 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 | */ | ||
140 | int 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 | */ | ||
178 | int 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 | */ | ||
32 | void 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 | */ | ||
41 | int 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 | */ | ||
50 | int 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 | */ | ||
59 | int 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 | */ | ||
68 | int 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 | */ | ||
41 | int 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 | |||
23 | int 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 | */ | ||
40 | int 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 | |||
23 | int 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 | */ | ||
36 | int 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 | */ | ||
30 | int 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 | */ | ||
42 | int 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 | */ | ||
33 | int 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 | */ | ||
38 | int 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 | */ | ||
30 | int 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 | */ | ||
41 | int 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 | */ | ||
33 | int 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 | */ | ||
26 | void 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 | */ | ||
108 | int8_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 | */ | ||
29 | void 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 | */ | ||
37 | int8_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 | */ | ||
32 | int 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 | */ | ||
123 | void 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 | */ | ||
315 | int 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 | */ | ||
399 | void 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 | |||
469 | void 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 | |||
494 | void 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 | |||
546 | void 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 | |||
601 | void 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 | |||
677 | void _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 | */ | ||
37 | int 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 | */ | ||
50 | void 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 | */ | ||
62 | int 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 | */ | ||
75 | void 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 | */ | ||
84 | void 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 | */ | ||
93 | void 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 | */ | ||
102 | void 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 | */ | ||
111 | void 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 | */ | ||
122 | void _libwifi_add_sec_item(char *buf, int *offset, int *append, char *item); | ||
123 | |||
124 | #endif /* LIBWIFI_PARSE_SECURITY_H */ | ||