Dmitry Shmidt | 1f69aa5 | 2012-01-24 16:10:04 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Common driver-related functions |
Paul Stewart | 092955c | 2017-02-06 09:13:09 -0800 | [diff] [blame] | 3 | * Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi> |
Dmitry Shmidt | 1f69aa5 | 2012-01-24 16:10:04 -0800 | [diff] [blame] | 4 | * |
Dmitry Shmidt | c5ec7f5 | 2012-03-06 16:33:24 -0800 | [diff] [blame] | 5 | * This software may be distributed under the terms of the BSD license. |
| 6 | * See README for more details. |
Dmitry Shmidt | 1f69aa5 | 2012-01-24 16:10:04 -0800 | [diff] [blame] | 7 | */ |
| 8 | |
| 9 | #include "includes.h" |
| 10 | #include "utils/common.h" |
| 11 | #include "driver.h" |
| 12 | |
| 13 | void wpa_scan_results_free(struct wpa_scan_results *res) |
| 14 | { |
| 15 | size_t i; |
| 16 | |
| 17 | if (res == NULL) |
| 18 | return; |
| 19 | |
| 20 | for (i = 0; i < res->num; i++) |
| 21 | os_free(res->res[i]); |
| 22 | os_free(res->res); |
| 23 | os_free(res); |
| 24 | } |
| 25 | |
| 26 | |
| 27 | const char * event_to_string(enum wpa_event_type event) |
| 28 | { |
| 29 | #define E2S(n) case EVENT_ ## n: return #n |
| 30 | switch (event) { |
| 31 | E2S(ASSOC); |
| 32 | E2S(DISASSOC); |
| 33 | E2S(MICHAEL_MIC_FAILURE); |
| 34 | E2S(SCAN_RESULTS); |
| 35 | E2S(ASSOCINFO); |
| 36 | E2S(INTERFACE_STATUS); |
| 37 | E2S(PMKID_CANDIDATE); |
Dmitry Shmidt | 1f69aa5 | 2012-01-24 16:10:04 -0800 | [diff] [blame] | 38 | E2S(TDLS); |
| 39 | E2S(FT_RESPONSE); |
| 40 | E2S(IBSS_RSN_START); |
| 41 | E2S(AUTH); |
| 42 | E2S(DEAUTH); |
| 43 | E2S(ASSOC_REJECT); |
| 44 | E2S(AUTH_TIMED_OUT); |
| 45 | E2S(ASSOC_TIMED_OUT); |
Dmitry Shmidt | 1f69aa5 | 2012-01-24 16:10:04 -0800 | [diff] [blame] | 46 | E2S(WPS_BUTTON_PUSHED); |
| 47 | E2S(TX_STATUS); |
| 48 | E2S(RX_FROM_UNKNOWN); |
| 49 | E2S(RX_MGMT); |
Dmitry Shmidt | 1f69aa5 | 2012-01-24 16:10:04 -0800 | [diff] [blame] | 50 | E2S(REMAIN_ON_CHANNEL); |
| 51 | E2S(CANCEL_REMAIN_ON_CHANNEL); |
Dmitry Shmidt | 1f69aa5 | 2012-01-24 16:10:04 -0800 | [diff] [blame] | 52 | E2S(RX_PROBE_REQ); |
| 53 | E2S(NEW_STA); |
| 54 | E2S(EAPOL_RX); |
| 55 | E2S(SIGNAL_CHANGE); |
| 56 | E2S(INTERFACE_ENABLED); |
| 57 | E2S(INTERFACE_DISABLED); |
| 58 | E2S(CHANNEL_LIST_CHANGED); |
| 59 | E2S(INTERFACE_UNAVAILABLE); |
| 60 | E2S(BEST_CHANNEL); |
| 61 | E2S(UNPROT_DEAUTH); |
| 62 | E2S(UNPROT_DISASSOC); |
| 63 | E2S(STATION_LOW_ACK); |
Dmitry Shmidt | 1f69aa5 | 2012-01-24 16:10:04 -0800 | [diff] [blame] | 64 | E2S(IBSS_PEER_LOST); |
| 65 | E2S(DRIVER_GTK_REKEY); |
| 66 | E2S(SCHED_SCAN_STOPPED); |
| 67 | E2S(DRIVER_CLIENT_POLL_OK); |
| 68 | E2S(EAPOL_TX_STATUS); |
Dmitry Shmidt | 0494959 | 2012-07-19 12:16:46 -0700 | [diff] [blame] | 69 | E2S(CH_SWITCH); |
Hai Shalom | 81f62d8 | 2019-07-22 12:10:00 -0700 | [diff] [blame] | 70 | E2S(CH_SWITCH_STARTED); |
Dmitry Shmidt | 61d9df3 | 2012-08-29 16:22:06 -0700 | [diff] [blame] | 71 | E2S(WNM); |
Dmitry Shmidt | f862328 | 2013-02-20 14:34:59 -0800 | [diff] [blame] | 72 | E2S(CONNECT_FAILED_REASON); |
Dmitry Shmidt | ea69e84 | 2013-05-13 14:52:28 -0700 | [diff] [blame] | 73 | E2S(DFS_RADAR_DETECTED); |
| 74 | E2S(DFS_CAC_FINISHED); |
| 75 | E2S(DFS_CAC_ABORTED); |
| 76 | E2S(DFS_NOP_FINISHED); |
Dmitry Shmidt | b7b4d0e | 2013-08-26 12:09:05 -0700 | [diff] [blame] | 77 | E2S(SURVEY); |
Dmitry Shmidt | fb79edc | 2014-01-10 10:45:54 -0800 | [diff] [blame] | 78 | E2S(SCAN_STARTED); |
Dmitry Shmidt | cf32e60 | 2014-01-28 10:57:39 -0800 | [diff] [blame] | 79 | E2S(AVOID_FREQUENCIES); |
Dmitry Shmidt | 6c0da2b | 2015-01-05 13:08:17 -0800 | [diff] [blame] | 80 | E2S(NEW_PEER_CANDIDATE); |
| 81 | E2S(ACS_CHANNEL_SELECTED); |
Dmitry Shmidt | 7f65602 | 2015-02-25 14:36:37 -0800 | [diff] [blame] | 82 | E2S(DFS_CAC_STARTED); |
Dmitry Shmidt | 58d12ad | 2016-07-28 10:07:03 -0700 | [diff] [blame] | 83 | E2S(P2P_LO_STOP); |
Paul Stewart | 092955c | 2017-02-06 09:13:09 -0800 | [diff] [blame] | 84 | E2S(BEACON_LOSS); |
Dmitry Shmidt | d2986c2 | 2017-10-23 14:22:09 -0700 | [diff] [blame] | 85 | E2S(DFS_PRE_CAC_EXPIRED); |
Roshan Pius | 3a1667e | 2018-07-03 15:17:14 -0700 | [diff] [blame] | 86 | E2S(EXTERNAL_AUTH); |
| 87 | E2S(PORT_AUTHORIZED); |
| 88 | E2S(STATION_OPMODE_CHANGED); |
| 89 | E2S(INTERFACE_MAC_CHANGED); |
| 90 | E2S(WDS_STA_INTERFACE_STATUS); |
Hai Shalom | 81f62d8 | 2019-07-22 12:10:00 -0700 | [diff] [blame] | 91 | E2S(UPDATE_DH); |
Hai Shalom | fdcde76 | 2020-04-02 11:19:20 -0700 | [diff] [blame] | 92 | E2S(UNPROT_BEACON); |
Hai Shalom | a20dcd7 | 2022-02-04 13:43:00 -0800 | [diff] [blame] | 93 | E2S(TX_WAIT_EXPIRE); |
Sunil Ravi | a04bd25 | 2022-05-02 22:54:18 -0700 | [diff] [blame] | 94 | E2S(BSS_COLOR_COLLISION); |
| 95 | E2S(CCA_STARTED_NOTIFY); |
| 96 | E2S(CCA_ABORTED_NOTIFY); |
| 97 | E2S(CCA_NOTIFY); |
Sunil Ravi | 89eba10 | 2022-09-13 21:04:37 -0700 | [diff] [blame^] | 98 | E2S(PASN_AUTH); |
| 99 | E2S(LINK_CH_SWITCH); |
| 100 | E2S(LINK_CH_SWITCH_STARTED); |
Dmitry Shmidt | 1f69aa5 | 2012-01-24 16:10:04 -0800 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | return "UNKNOWN"; |
| 104 | #undef E2S |
| 105 | } |
Dmitry Shmidt | 661b4f7 | 2014-09-29 14:58:27 -0700 | [diff] [blame] | 106 | |
| 107 | |
| 108 | const char * channel_width_to_string(enum chan_width width) |
| 109 | { |
| 110 | switch (width) { |
| 111 | case CHAN_WIDTH_20_NOHT: |
| 112 | return "20 MHz (no HT)"; |
| 113 | case CHAN_WIDTH_20: |
| 114 | return "20 MHz"; |
| 115 | case CHAN_WIDTH_40: |
| 116 | return "40 MHz"; |
| 117 | case CHAN_WIDTH_80: |
| 118 | return "80 MHz"; |
| 119 | case CHAN_WIDTH_80P80: |
| 120 | return "80+80 MHz"; |
| 121 | case CHAN_WIDTH_160: |
| 122 | return "160 MHz"; |
Sunil | 8cd6f4d | 2022-06-28 18:40:46 +0000 | [diff] [blame] | 123 | case CHAN_WIDTH_320: |
| 124 | return "320 MHz"; |
Dmitry Shmidt | 661b4f7 | 2014-09-29 14:58:27 -0700 | [diff] [blame] | 125 | default: |
| 126 | return "unknown"; |
| 127 | } |
| 128 | } |
Dmitry Shmidt | 6c0da2b | 2015-01-05 13:08:17 -0800 | [diff] [blame] | 129 | |
| 130 | |
Hai Shalom | 74f70d4 | 2019-02-11 14:42:39 -0800 | [diff] [blame] | 131 | int channel_width_to_int(enum chan_width width) |
| 132 | { |
| 133 | switch (width) { |
| 134 | case CHAN_WIDTH_20_NOHT: |
| 135 | case CHAN_WIDTH_20: |
| 136 | return 20; |
| 137 | case CHAN_WIDTH_40: |
| 138 | return 40; |
| 139 | case CHAN_WIDTH_80: |
| 140 | return 80; |
| 141 | case CHAN_WIDTH_80P80: |
| 142 | case CHAN_WIDTH_160: |
| 143 | return 160; |
Sunil | 8cd6f4d | 2022-06-28 18:40:46 +0000 | [diff] [blame] | 144 | case CHAN_WIDTH_320: |
| 145 | return 320; |
Hai Shalom | 74f70d4 | 2019-02-11 14:42:39 -0800 | [diff] [blame] | 146 | default: |
| 147 | return 0; |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | |
Dmitry Shmidt | 6c0da2b | 2015-01-05 13:08:17 -0800 | [diff] [blame] | 152 | int ht_supported(const struct hostapd_hw_modes *mode) |
| 153 | { |
| 154 | if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) { |
| 155 | /* |
| 156 | * The driver did not indicate whether it supports HT. Assume |
| 157 | * it does to avoid connection issues. |
| 158 | */ |
| 159 | return 1; |
| 160 | } |
| 161 | |
| 162 | /* |
| 163 | * IEEE Std 802.11n-2009 20.1.1: |
| 164 | * An HT non-AP STA shall support all EQM rates for one spatial stream. |
| 165 | */ |
| 166 | return mode->mcs_set[0] == 0xff; |
| 167 | } |
| 168 | |
| 169 | |
| 170 | int vht_supported(const struct hostapd_hw_modes *mode) |
| 171 | { |
| 172 | if (!(mode->flags & HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN)) { |
| 173 | /* |
| 174 | * The driver did not indicate whether it supports VHT. Assume |
| 175 | * it does to avoid connection issues. |
| 176 | */ |
| 177 | return 1; |
| 178 | } |
| 179 | |
| 180 | /* |
| 181 | * A VHT non-AP STA shall support MCS 0-7 for one spatial stream. |
| 182 | * TODO: Verify if this complies with the standard |
| 183 | */ |
| 184 | return (mode->vht_mcs_set[0] & 0x3) != 3; |
| 185 | } |
| 186 | |
| 187 | |
| 188 | static int wpa_check_wowlan_trigger(const char *start, const char *trigger, |
| 189 | int capa_trigger, u8 *param_trigger) |
| 190 | { |
| 191 | if (os_strcmp(start, trigger) != 0) |
| 192 | return 0; |
| 193 | if (!capa_trigger) |
| 194 | return 0; |
| 195 | |
| 196 | *param_trigger = 1; |
| 197 | return 1; |
| 198 | } |
| 199 | |
| 200 | |
| 201 | struct wowlan_triggers * |
| 202 | wpa_get_wowlan_triggers(const char *wowlan_triggers, |
| 203 | const struct wpa_driver_capa *capa) |
| 204 | { |
| 205 | struct wowlan_triggers *triggers; |
| 206 | char *start, *end, *buf; |
| 207 | int last; |
| 208 | |
| 209 | if (!wowlan_triggers) |
| 210 | return NULL; |
| 211 | |
| 212 | buf = os_strdup(wowlan_triggers); |
| 213 | if (buf == NULL) |
| 214 | return NULL; |
| 215 | |
| 216 | triggers = os_zalloc(sizeof(*triggers)); |
| 217 | if (triggers == NULL) |
| 218 | goto out; |
| 219 | |
| 220 | #define CHECK_TRIGGER(trigger) \ |
| 221 | wpa_check_wowlan_trigger(start, #trigger, \ |
| 222 | capa->wowlan_triggers.trigger, \ |
| 223 | &triggers->trigger) |
| 224 | |
| 225 | start = buf; |
| 226 | while (*start != '\0') { |
Dmitry Shmidt | 57c2d39 | 2016-02-23 13:40:19 -0800 | [diff] [blame] | 227 | while (isblank((unsigned char) *start)) |
Dmitry Shmidt | 6c0da2b | 2015-01-05 13:08:17 -0800 | [diff] [blame] | 228 | start++; |
| 229 | if (*start == '\0') |
| 230 | break; |
| 231 | end = start; |
Dmitry Shmidt | 57c2d39 | 2016-02-23 13:40:19 -0800 | [diff] [blame] | 232 | while (!isblank((unsigned char) *end) && *end != '\0') |
Dmitry Shmidt | 6c0da2b | 2015-01-05 13:08:17 -0800 | [diff] [blame] | 233 | end++; |
| 234 | last = *end == '\0'; |
| 235 | *end = '\0'; |
| 236 | |
| 237 | if (!CHECK_TRIGGER(any) && |
| 238 | !CHECK_TRIGGER(disconnect) && |
| 239 | !CHECK_TRIGGER(magic_pkt) && |
| 240 | !CHECK_TRIGGER(gtk_rekey_failure) && |
| 241 | !CHECK_TRIGGER(eap_identity_req) && |
| 242 | !CHECK_TRIGGER(four_way_handshake) && |
| 243 | !CHECK_TRIGGER(rfkill_release)) { |
| 244 | wpa_printf(MSG_DEBUG, |
| 245 | "Unknown/unsupported wowlan trigger '%s'", |
| 246 | start); |
| 247 | os_free(triggers); |
| 248 | triggers = NULL; |
| 249 | goto out; |
| 250 | } |
| 251 | |
| 252 | if (last) |
| 253 | break; |
| 254 | start = end + 1; |
| 255 | } |
| 256 | #undef CHECK_TRIGGER |
| 257 | |
| 258 | out: |
| 259 | os_free(buf); |
| 260 | return triggers; |
| 261 | } |
Dmitry Shmidt | 58d12ad | 2016-07-28 10:07:03 -0700 | [diff] [blame] | 262 | |
| 263 | |
| 264 | const char * driver_flag_to_string(u64 flag) |
| 265 | { |
| 266 | #define DF2S(x) case WPA_DRIVER_FLAGS_ ## x: return #x |
| 267 | switch (flag) { |
| 268 | DF2S(DRIVER_IE); |
| 269 | DF2S(SET_KEYS_AFTER_ASSOC); |
| 270 | DF2S(DFS_OFFLOAD); |
Hai Shalom | 74f70d4 | 2019-02-11 14:42:39 -0800 | [diff] [blame] | 271 | DF2S(4WAY_HANDSHAKE_PSK); |
| 272 | DF2S(4WAY_HANDSHAKE_8021X); |
Dmitry Shmidt | 58d12ad | 2016-07-28 10:07:03 -0700 | [diff] [blame] | 273 | DF2S(WIRED); |
| 274 | DF2S(SME); |
| 275 | DF2S(AP); |
| 276 | DF2S(SET_KEYS_AFTER_ASSOC_DONE); |
| 277 | DF2S(HT_2040_COEX); |
| 278 | DF2S(P2P_CONCURRENT); |
| 279 | DF2S(P2P_DEDICATED_INTERFACE); |
| 280 | DF2S(P2P_CAPABLE); |
| 281 | DF2S(AP_TEARDOWN_SUPPORT); |
| 282 | DF2S(P2P_MGMT_AND_NON_P2P); |
Hai Shalom | a20dcd7 | 2022-02-04 13:43:00 -0800 | [diff] [blame] | 283 | DF2S(VALID_ERROR_CODES); |
Dmitry Shmidt | 58d12ad | 2016-07-28 10:07:03 -0700 | [diff] [blame] | 284 | DF2S(OFFCHANNEL_TX); |
| 285 | DF2S(EAPOL_TX_STATUS); |
| 286 | DF2S(DEAUTH_TX_STATUS); |
| 287 | DF2S(BSS_SELECTION); |
| 288 | DF2S(TDLS_SUPPORT); |
| 289 | DF2S(TDLS_EXTERNAL_SETUP); |
| 290 | DF2S(PROBE_RESP_OFFLOAD); |
| 291 | DF2S(AP_UAPSD); |
| 292 | DF2S(INACTIVITY_TIMER); |
| 293 | DF2S(AP_MLME); |
| 294 | DF2S(SAE); |
| 295 | DF2S(OBSS_SCAN); |
| 296 | DF2S(IBSS); |
| 297 | DF2S(RADAR); |
| 298 | DF2S(DEDICATED_P2P_DEVICE); |
| 299 | DF2S(QOS_MAPPING); |
| 300 | DF2S(AP_CSA); |
| 301 | DF2S(MESH); |
| 302 | DF2S(ACS_OFFLOAD); |
| 303 | DF2S(KEY_MGMT_OFFLOAD); |
| 304 | DF2S(TDLS_CHANNEL_SWITCH); |
| 305 | DF2S(HT_IBSS); |
| 306 | DF2S(VHT_IBSS); |
| 307 | DF2S(SUPPORT_HW_MODE_ANY); |
| 308 | DF2S(OFFCHANNEL_SIMULTANEOUS); |
| 309 | DF2S(FULL_AP_CLIENT_STATE); |
| 310 | DF2S(P2P_LISTEN_OFFLOAD); |
Roshan Pius | 3a1667e | 2018-07-03 15:17:14 -0700 | [diff] [blame] | 311 | DF2S(SUPPORT_FILS); |
| 312 | DF2S(BEACON_RATE_LEGACY); |
| 313 | DF2S(BEACON_RATE_HT); |
| 314 | DF2S(BEACON_RATE_VHT); |
| 315 | DF2S(MGMT_TX_RANDOM_TA); |
| 316 | DF2S(MGMT_TX_RANDOM_TA_CONNECTED); |
| 317 | DF2S(SCHED_SCAN_RELATIVE_RSSI); |
| 318 | DF2S(HE_CAPABILITIES); |
| 319 | DF2S(FILS_SK_OFFLOAD); |
| 320 | DF2S(OCE_STA); |
| 321 | DF2S(OCE_AP); |
| 322 | DF2S(OCE_STA_CFON); |
| 323 | DF2S(MFP_OPTIONAL); |
Hai Shalom | fdcde76 | 2020-04-02 11:19:20 -0700 | [diff] [blame] | 324 | DF2S(SELF_MANAGED_REGULATORY); |
| 325 | DF2S(FTM_RESPONDER); |
| 326 | DF2S(CONTROL_PORT); |
| 327 | DF2S(VLAN_OFFLOAD); |
| 328 | DF2S(UPDATE_FT_IES); |
| 329 | DF2S(SAFE_PTK0_REKEYS); |
| 330 | DF2S(BEACON_PROTECTION); |
| 331 | DF2S(EXTENDED_KEY_ID); |
Dmitry Shmidt | 58d12ad | 2016-07-28 10:07:03 -0700 | [diff] [blame] | 332 | } |
| 333 | return "UNKNOWN"; |
| 334 | #undef DF2S |
| 335 | } |
Hai Shalom | b755a2a | 2020-04-23 21:49:02 -0700 | [diff] [blame] | 336 | |
| 337 | |
| 338 | const char * driver_flag2_to_string(u64 flag2) |
| 339 | { |
| 340 | #define DF2S(x) case WPA_DRIVER_FLAGS2_ ## x: return #x |
| 341 | switch (flag2) { |
| 342 | DF2S(CONTROL_PORT_RX); |
Hai Shalom | 899fcc7 | 2020-10-19 14:38:18 -0700 | [diff] [blame] | 343 | DF2S(CONTROL_PORT_TX_STATUS); |
Hai Shalom | b755a2a | 2020-04-23 21:49:02 -0700 | [diff] [blame] | 344 | } |
| 345 | return "UNKNOWN"; |
| 346 | #undef DF2S |
| 347 | } |