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/libwifi | |
| 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/libwifi')
100 files changed, 8659 insertions, 0 deletions
| 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 */ | ||
