fragattacks/src/drivers/driver_common.c
Jouni Malinen f1d3856090 nl80211: Beacon protection capability flag and default key type
Add a new capability flag based on the nl80211 feature advertisement and
start using the new default key type for Beacon protection. This enables
AP mode functionality to allow Beacon protection to be enabled. This is
also enabling the previously added ap_pmf_beacon_protection_* hwsim test
cases.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
2020-02-24 12:20:38 +02:00

322 lines
6.4 KiB
C

/*
* Common driver-related functions
* Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "includes.h"
#include "utils/common.h"
#include "driver.h"
void wpa_scan_results_free(struct wpa_scan_results *res)
{
size_t i;
if (res == NULL)
return;
for (i = 0; i < res->num; i++)
os_free(res->res[i]);
os_free(res->res);
os_free(res);
}
const char * event_to_string(enum wpa_event_type event)
{
#define E2S(n) case EVENT_ ## n: return #n
switch (event) {
E2S(ASSOC);
E2S(DISASSOC);
E2S(MICHAEL_MIC_FAILURE);
E2S(SCAN_RESULTS);
E2S(ASSOCINFO);
E2S(INTERFACE_STATUS);
E2S(PMKID_CANDIDATE);
E2S(TDLS);
E2S(FT_RESPONSE);
E2S(IBSS_RSN_START);
E2S(AUTH);
E2S(DEAUTH);
E2S(ASSOC_REJECT);
E2S(AUTH_TIMED_OUT);
E2S(ASSOC_TIMED_OUT);
E2S(WPS_BUTTON_PUSHED);
E2S(TX_STATUS);
E2S(RX_FROM_UNKNOWN);
E2S(RX_MGMT);
E2S(REMAIN_ON_CHANNEL);
E2S(CANCEL_REMAIN_ON_CHANNEL);
E2S(RX_PROBE_REQ);
E2S(NEW_STA);
E2S(EAPOL_RX);
E2S(SIGNAL_CHANGE);
E2S(INTERFACE_ENABLED);
E2S(INTERFACE_DISABLED);
E2S(CHANNEL_LIST_CHANGED);
E2S(INTERFACE_UNAVAILABLE);
E2S(BEST_CHANNEL);
E2S(UNPROT_DEAUTH);
E2S(UNPROT_DISASSOC);
E2S(STATION_LOW_ACK);
E2S(IBSS_PEER_LOST);
E2S(DRIVER_GTK_REKEY);
E2S(SCHED_SCAN_STOPPED);
E2S(DRIVER_CLIENT_POLL_OK);
E2S(EAPOL_TX_STATUS);
E2S(CH_SWITCH);
E2S(CH_SWITCH_STARTED);
E2S(WNM);
E2S(CONNECT_FAILED_REASON);
E2S(DFS_RADAR_DETECTED);
E2S(DFS_CAC_FINISHED);
E2S(DFS_CAC_ABORTED);
E2S(DFS_NOP_FINISHED);
E2S(SURVEY);
E2S(SCAN_STARTED);
E2S(AVOID_FREQUENCIES);
E2S(NEW_PEER_CANDIDATE);
E2S(ACS_CHANNEL_SELECTED);
E2S(DFS_CAC_STARTED);
E2S(P2P_LO_STOP);
E2S(BEACON_LOSS);
E2S(DFS_PRE_CAC_EXPIRED);
E2S(EXTERNAL_AUTH);
E2S(PORT_AUTHORIZED);
E2S(STATION_OPMODE_CHANGED);
E2S(INTERFACE_MAC_CHANGED);
E2S(WDS_STA_INTERFACE_STATUS);
E2S(UPDATE_DH);
}
return "UNKNOWN";
#undef E2S
}
const char * channel_width_to_string(enum chan_width width)
{
switch (width) {
case CHAN_WIDTH_20_NOHT:
return "20 MHz (no HT)";
case CHAN_WIDTH_20:
return "20 MHz";
case CHAN_WIDTH_40:
return "40 MHz";
case CHAN_WIDTH_80:
return "80 MHz";
case CHAN_WIDTH_80P80:
return "80+80 MHz";
case CHAN_WIDTH_160:
return "160 MHz";
default:
return "unknown";
}
}
int channel_width_to_int(enum chan_width width)
{
switch (width) {
case CHAN_WIDTH_20_NOHT:
case CHAN_WIDTH_20:
return 20;
case CHAN_WIDTH_40:
return 40;
case CHAN_WIDTH_80:
return 80;
case CHAN_WIDTH_80P80:
case CHAN_WIDTH_160:
return 160;
default:
return 0;
}
}
int ht_supported(const struct hostapd_hw_modes *mode)
{
if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) {
/*
* The driver did not indicate whether it supports HT. Assume
* it does to avoid connection issues.
*/
return 1;
}
/*
* IEEE Std 802.11n-2009 20.1.1:
* An HT non-AP STA shall support all EQM rates for one spatial stream.
*/
return mode->mcs_set[0] == 0xff;
}
int vht_supported(const struct hostapd_hw_modes *mode)
{
if (!(mode->flags & HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN)) {
/*
* The driver did not indicate whether it supports VHT. Assume
* it does to avoid connection issues.
*/
return 1;
}
/*
* A VHT non-AP STA shall support MCS 0-7 for one spatial stream.
* TODO: Verify if this complies with the standard
*/
return (mode->vht_mcs_set[0] & 0x3) != 3;
}
static int wpa_check_wowlan_trigger(const char *start, const char *trigger,
int capa_trigger, u8 *param_trigger)
{
if (os_strcmp(start, trigger) != 0)
return 0;
if (!capa_trigger)
return 0;
*param_trigger = 1;
return 1;
}
struct wowlan_triggers *
wpa_get_wowlan_triggers(const char *wowlan_triggers,
const struct wpa_driver_capa *capa)
{
struct wowlan_triggers *triggers;
char *start, *end, *buf;
int last;
if (!wowlan_triggers)
return NULL;
buf = os_strdup(wowlan_triggers);
if (buf == NULL)
return NULL;
triggers = os_zalloc(sizeof(*triggers));
if (triggers == NULL)
goto out;
#define CHECK_TRIGGER(trigger) \
wpa_check_wowlan_trigger(start, #trigger, \
capa->wowlan_triggers.trigger, \
&triggers->trigger)
start = buf;
while (*start != '\0') {
while (isblank((unsigned char) *start))
start++;
if (*start == '\0')
break;
end = start;
while (!isblank((unsigned char) *end) && *end != '\0')
end++;
last = *end == '\0';
*end = '\0';
if (!CHECK_TRIGGER(any) &&
!CHECK_TRIGGER(disconnect) &&
!CHECK_TRIGGER(magic_pkt) &&
!CHECK_TRIGGER(gtk_rekey_failure) &&
!CHECK_TRIGGER(eap_identity_req) &&
!CHECK_TRIGGER(four_way_handshake) &&
!CHECK_TRIGGER(rfkill_release)) {
wpa_printf(MSG_DEBUG,
"Unknown/unsupported wowlan trigger '%s'",
start);
os_free(triggers);
triggers = NULL;
goto out;
}
if (last)
break;
start = end + 1;
}
#undef CHECK_TRIGGER
out:
os_free(buf);
return triggers;
}
const char * driver_flag_to_string(u64 flag)
{
#define DF2S(x) case WPA_DRIVER_FLAGS_ ## x: return #x
switch (flag) {
DF2S(DRIVER_IE);
DF2S(SET_KEYS_AFTER_ASSOC);
DF2S(DFS_OFFLOAD);
DF2S(4WAY_HANDSHAKE_PSK);
DF2S(4WAY_HANDSHAKE_8021X);
DF2S(WIRED);
DF2S(SME);
DF2S(AP);
DF2S(SET_KEYS_AFTER_ASSOC_DONE);
DF2S(HT_2040_COEX);
DF2S(P2P_CONCURRENT);
DF2S(P2P_DEDICATED_INTERFACE);
DF2S(P2P_CAPABLE);
DF2S(AP_TEARDOWN_SUPPORT);
DF2S(P2P_MGMT_AND_NON_P2P);
DF2S(SANE_ERROR_CODES);
DF2S(OFFCHANNEL_TX);
DF2S(EAPOL_TX_STATUS);
DF2S(DEAUTH_TX_STATUS);
DF2S(BSS_SELECTION);
DF2S(TDLS_SUPPORT);
DF2S(TDLS_EXTERNAL_SETUP);
DF2S(PROBE_RESP_OFFLOAD);
DF2S(AP_UAPSD);
DF2S(INACTIVITY_TIMER);
DF2S(AP_MLME);
DF2S(SAE);
DF2S(OBSS_SCAN);
DF2S(IBSS);
DF2S(RADAR);
DF2S(DEDICATED_P2P_DEVICE);
DF2S(QOS_MAPPING);
DF2S(AP_CSA);
DF2S(MESH);
DF2S(ACS_OFFLOAD);
DF2S(KEY_MGMT_OFFLOAD);
DF2S(TDLS_CHANNEL_SWITCH);
DF2S(HT_IBSS);
DF2S(VHT_IBSS);
DF2S(SUPPORT_HW_MODE_ANY);
DF2S(OFFCHANNEL_SIMULTANEOUS);
DF2S(FULL_AP_CLIENT_STATE);
DF2S(P2P_LISTEN_OFFLOAD);
DF2S(SUPPORT_FILS);
DF2S(BEACON_RATE_LEGACY);
DF2S(BEACON_RATE_HT);
DF2S(BEACON_RATE_VHT);
DF2S(MGMT_TX_RANDOM_TA);
DF2S(MGMT_TX_RANDOM_TA_CONNECTED);
DF2S(SCHED_SCAN_RELATIVE_RSSI);
DF2S(HE_CAPABILITIES);
DF2S(FILS_SK_OFFLOAD);
DF2S(OCE_STA);
DF2S(OCE_AP);
DF2S(OCE_STA_CFON);
DF2S(MFP_OPTIONAL);
DF2S(SELF_MANAGED_REGULATORY);
DF2S(FTM_RESPONDER);
DF2S(CONTROL_PORT);
DF2S(VLAN_OFFLOAD);
DF2S(UPDATE_FT_IES);
DF2S(SAFE_PTK0_REKEYS);
DF2S(BEACON_PROTECTION);
}
return "UNKNOWN";
#undef DF2S
}