Home | History | Annotate | Line # | Download | only in drivers
      1 /*
      2  * Common driver-related functions
      3  * Copyright (c) 2003-2017, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      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);
     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);
     46 	E2S(WPS_BUTTON_PUSHED);
     47 	E2S(TX_STATUS);
     48 	E2S(RX_FROM_UNKNOWN);
     49 	E2S(RX_MGMT);
     50 	E2S(REMAIN_ON_CHANNEL);
     51 	E2S(CANCEL_REMAIN_ON_CHANNEL);
     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);
     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);
     69 	E2S(CH_SWITCH);
     70 	E2S(CH_SWITCH_STARTED);
     71 	E2S(WNM);
     72 	E2S(CONNECT_FAILED_REASON);
     73 	E2S(DFS_RADAR_DETECTED);
     74 	E2S(DFS_CAC_FINISHED);
     75 	E2S(DFS_CAC_ABORTED);
     76 	E2S(DFS_NOP_FINISHED);
     77 	E2S(SURVEY);
     78 	E2S(SCAN_STARTED);
     79 	E2S(AVOID_FREQUENCIES);
     80 	E2S(NEW_PEER_CANDIDATE);
     81 	E2S(ACS_CHANNEL_SELECTED);
     82 	E2S(DFS_CAC_STARTED);
     83 	E2S(P2P_LO_STOP);
     84 	E2S(BEACON_LOSS);
     85 	E2S(DFS_PRE_CAC_EXPIRED);
     86 	E2S(EXTERNAL_AUTH);
     87 	E2S(PORT_AUTHORIZED);
     88 	E2S(STATION_OPMODE_CHANGED);
     89 	E2S(INTERFACE_MAC_CHANGED);
     90 	E2S(WDS_STA_INTERFACE_STATUS);
     91 	E2S(UPDATE_DH);
     92 	E2S(UNPROT_BEACON);
     93 	E2S(TX_WAIT_EXPIRE);
     94 	E2S(BSS_COLOR_COLLISION);
     95 	E2S(CCA_STARTED_NOTIFY);
     96 	E2S(CCA_ABORTED_NOTIFY);
     97 	E2S(CCA_NOTIFY);
     98 	E2S(PASN_AUTH);
     99 	E2S(LINK_CH_SWITCH);
    100 	E2S(LINK_CH_SWITCH_STARTED);
    101 	E2S(TID_LINK_MAP);
    102 	E2S(LINK_RECONFIG);
    103 	}
    104 
    105 	return "UNKNOWN";
    106 #undef E2S
    107 }
    108 
    109 
    110 const char * channel_width_to_string(enum chan_width width)
    111 {
    112 	switch (width) {
    113 	case CHAN_WIDTH_20_NOHT:
    114 		return "20 MHz (no HT)";
    115 	case CHAN_WIDTH_20:
    116 		return "20 MHz";
    117 	case CHAN_WIDTH_40:
    118 		return "40 MHz";
    119 	case CHAN_WIDTH_80:
    120 		return "80 MHz";
    121 	case CHAN_WIDTH_80P80:
    122 		return "80+80 MHz";
    123 	case CHAN_WIDTH_160:
    124 		return "160 MHz";
    125 	case CHAN_WIDTH_320:
    126 		return "320 MHz";
    127 	default:
    128 		return "unknown";
    129 	}
    130 }
    131 
    132 
    133 int channel_width_to_int(enum chan_width width)
    134 {
    135 	switch (width) {
    136 	case CHAN_WIDTH_20_NOHT:
    137 	case CHAN_WIDTH_20:
    138 		return 20;
    139 	case CHAN_WIDTH_40:
    140 		return 40;
    141 	case CHAN_WIDTH_80:
    142 		return 80;
    143 	case CHAN_WIDTH_80P80:
    144 	case CHAN_WIDTH_160:
    145 		return 160;
    146 	case CHAN_WIDTH_320:
    147 		return 320;
    148 	default:
    149 		return 0;
    150 	}
    151 }
    152 
    153 
    154 int ht_supported(const struct hostapd_hw_modes *mode)
    155 {
    156 	if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) {
    157 		/*
    158 		 * The driver did not indicate whether it supports HT. Assume
    159 		 * it does to avoid connection issues.
    160 		 */
    161 		return 1;
    162 	}
    163 
    164 	/*
    165 	 * IEEE Std 802.11n-2009 20.1.1:
    166 	 * An HT non-AP STA shall support all EQM rates for one spatial stream.
    167 	 */
    168 	return mode->mcs_set[0] == 0xff;
    169 }
    170 
    171 
    172 int vht_supported(const struct hostapd_hw_modes *mode)
    173 {
    174 	if (!(mode->flags & HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN)) {
    175 		/*
    176 		 * The driver did not indicate whether it supports VHT. Assume
    177 		 * it does to avoid connection issues.
    178 		 */
    179 		return 1;
    180 	}
    181 
    182 	/*
    183 	 * A VHT non-AP STA shall support MCS 0-7 for one spatial stream.
    184 	 * TODO: Verify if this complies with the standard
    185 	 */
    186 	return (mode->vht_mcs_set[0] & 0x3) != 3;
    187 }
    188 
    189 
    190 bool he_supported(const struct hostapd_hw_modes *hw_mode,
    191 		  enum ieee80211_op_mode op_mode)
    192 {
    193 	if (!(hw_mode->flags & HOSTAPD_MODE_FLAG_HE_INFO_KNOWN)) {
    194 		/*
    195 		 * The driver did not indicate whether it supports HE. Assume
    196 		 * it does to avoid connection issues.
    197 		 */
    198 		return true;
    199 	}
    200 
    201 	return hw_mode->he_capab[op_mode].he_supported;
    202 }
    203 
    204 
    205 static int wpa_check_wowlan_trigger(const char *start, const char *trigger,
    206 				    int capa_trigger, u8 *param_trigger)
    207 {
    208 	if (os_strcmp(start, trigger) != 0)
    209 		return 0;
    210 	if (!capa_trigger)
    211 		return 0;
    212 
    213 	*param_trigger = 1;
    214 	return 1;
    215 }
    216 
    217 
    218 struct wowlan_triggers *
    219 wpa_get_wowlan_triggers(const char *wowlan_triggers,
    220 			const struct wpa_driver_capa *capa)
    221 {
    222 	struct wowlan_triggers *triggers;
    223 	char *start, *end, *buf;
    224 	int last;
    225 
    226 	if (!wowlan_triggers)
    227 		return NULL;
    228 
    229 	buf = os_strdup(wowlan_triggers);
    230 	if (buf == NULL)
    231 		return NULL;
    232 
    233 	triggers = os_zalloc(sizeof(*triggers));
    234 	if (triggers == NULL)
    235 		goto out;
    236 
    237 #define CHECK_TRIGGER(trigger) \
    238 	wpa_check_wowlan_trigger(start, #trigger,			\
    239 				  capa->wowlan_triggers.trigger,	\
    240 				  &triggers->trigger)
    241 
    242 	start = buf;
    243 	while (*start != '\0') {
    244 		while (isblank((unsigned char) *start))
    245 			start++;
    246 		if (*start == '\0')
    247 			break;
    248 		end = start;
    249 		while (!isblank((unsigned char) *end) && *end != '\0')
    250 			end++;
    251 		last = *end == '\0';
    252 		*end = '\0';
    253 
    254 		if (!CHECK_TRIGGER(any) &&
    255 		    !CHECK_TRIGGER(disconnect) &&
    256 		    !CHECK_TRIGGER(magic_pkt) &&
    257 		    !CHECK_TRIGGER(gtk_rekey_failure) &&
    258 		    !CHECK_TRIGGER(eap_identity_req) &&
    259 		    !CHECK_TRIGGER(four_way_handshake) &&
    260 		    !CHECK_TRIGGER(rfkill_release)) {
    261 			wpa_printf(MSG_DEBUG,
    262 				   "Unknown/unsupported wowlan trigger '%s'",
    263 				   start);
    264 			os_free(triggers);
    265 			triggers = NULL;
    266 			goto out;
    267 		}
    268 
    269 		if (last)
    270 			break;
    271 		start = end + 1;
    272 	}
    273 #undef CHECK_TRIGGER
    274 
    275 out:
    276 	os_free(buf);
    277 	return triggers;
    278 }
    279 
    280 
    281 const char * driver_flag_to_string(u64 flag)
    282 {
    283 #define DF2S(x) case WPA_DRIVER_FLAGS_ ## x: return #x
    284 	switch (flag) {
    285 	DF2S(DRIVER_IE);
    286 	DF2S(SET_KEYS_AFTER_ASSOC);
    287 	DF2S(DFS_OFFLOAD);
    288 	DF2S(4WAY_HANDSHAKE_PSK);
    289 	DF2S(4WAY_HANDSHAKE_8021X);
    290 	DF2S(WIRED);
    291 	DF2S(SME);
    292 	DF2S(AP);
    293 	DF2S(SET_KEYS_AFTER_ASSOC_DONE);
    294 	DF2S(HT_2040_COEX);
    295 	DF2S(P2P_CONCURRENT);
    296 	DF2S(P2P_DEDICATED_INTERFACE);
    297 	DF2S(P2P_CAPABLE);
    298 	DF2S(AP_TEARDOWN_SUPPORT);
    299 	DF2S(P2P_MGMT_AND_NON_P2P);
    300 	DF2S(VALID_ERROR_CODES);
    301 	DF2S(OFFCHANNEL_TX);
    302 	DF2S(EAPOL_TX_STATUS);
    303 	DF2S(DEAUTH_TX_STATUS);
    304 	DF2S(BSS_SELECTION);
    305 	DF2S(TDLS_SUPPORT);
    306 	DF2S(TDLS_EXTERNAL_SETUP);
    307 	DF2S(PROBE_RESP_OFFLOAD);
    308 	DF2S(AP_UAPSD);
    309 	DF2S(INACTIVITY_TIMER);
    310 	DF2S(AP_MLME);
    311 	DF2S(SAE);
    312 	DF2S(OBSS_SCAN);
    313 	DF2S(IBSS);
    314 	DF2S(RADAR);
    315 	DF2S(DEDICATED_P2P_DEVICE);
    316 	DF2S(QOS_MAPPING);
    317 	DF2S(AP_CSA);
    318 	DF2S(MESH);
    319 	DF2S(ACS_OFFLOAD);
    320 	DF2S(KEY_MGMT_OFFLOAD);
    321 	DF2S(TDLS_CHANNEL_SWITCH);
    322 	DF2S(HT_IBSS);
    323 	DF2S(VHT_IBSS);
    324 	DF2S(SUPPORT_HW_MODE_ANY);
    325 	DF2S(OFFCHANNEL_SIMULTANEOUS);
    326 	DF2S(FULL_AP_CLIENT_STATE);
    327 	DF2S(P2P_LISTEN_OFFLOAD);
    328 	DF2S(SUPPORT_FILS);
    329 	DF2S(BEACON_RATE_LEGACY);
    330 	DF2S(BEACON_RATE_HT);
    331 	DF2S(BEACON_RATE_VHT);
    332 	DF2S(MGMT_TX_RANDOM_TA);
    333 	DF2S(MGMT_TX_RANDOM_TA_CONNECTED);
    334 	DF2S(SCHED_SCAN_RELATIVE_RSSI);
    335 	DF2S(HE_CAPABILITIES);
    336 	DF2S(FILS_SK_OFFLOAD);
    337 	DF2S(OCE_STA);
    338 	DF2S(OCE_AP);
    339 	DF2S(OCE_STA_CFON);
    340 	DF2S(MFP_OPTIONAL);
    341 	DF2S(SELF_MANAGED_REGULATORY);
    342 	DF2S(FTM_RESPONDER);
    343 	DF2S(CONTROL_PORT);
    344 	DF2S(VLAN_OFFLOAD);
    345 	DF2S(UPDATE_FT_IES);
    346 	DF2S(SAFE_PTK0_REKEYS);
    347 	DF2S(BEACON_PROTECTION);
    348 	DF2S(EXTENDED_KEY_ID);
    349 	}
    350 	return "UNKNOWN";
    351 #undef DF2S
    352 }
    353 
    354 
    355 const char * driver_flag2_to_string(u64 flag2)
    356 {
    357 #define DF2S(x) case WPA_DRIVER_FLAGS2_ ## x: return #x
    358 	switch (flag2) {
    359 	DF2S(CONTROL_PORT_RX);
    360 	DF2S(CONTROL_PORT_TX_STATUS);
    361 	DF2S(SEC_LTF_AP);
    362 	DF2S(SEC_RTT_AP);
    363 	DF2S(PROT_RANGE_NEG_AP);
    364 	DF2S(BEACON_RATE_HE);
    365 	DF2S(BEACON_PROTECTION_CLIENT);
    366 	DF2S(OCV);
    367 	DF2S(AP_SME);
    368 	DF2S(SA_QUERY_OFFLOAD_AP);
    369 	DF2S(RADAR_BACKGROUND);
    370 	DF2S(SEC_LTF_STA);
    371 	DF2S(SEC_RTT_STA);
    372 	DF2S(PROT_RANGE_NEG_STA);
    373 	DF2S(MLO);
    374 	DF2S(SCAN_MIN_PREQ);
    375 	DF2S(SAE_OFFLOAD_STA);
    376 	}
    377 	return "UNKNOWN";
    378 #undef DF2S
    379 }
    380