From ed87f6a80eb5595e08fc57d3b10968f99ea57568 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 2 Jan 2019 17:56:41 +0200 Subject: [PATCH] Use a helper function for checking Extended Capabilities field The new ieee802_11_ext_capab() and wpa_bss_ext_capab() functions can be used to check whether a specific extended capability bit is set instead of having to implement bit parsing separately for each need. Signed-off-by: Jouni Malinen --- src/common/ieee802_11_common.c | 10 +++- src/common/ieee802_11_common.h | 4 +- src/common/ieee802_11_defs.h | 82 +++++++++++++++++++++++++++++++- wpa_supplicant/bss.c | 9 +++- wpa_supplicant/bss.h | 3 +- wpa_supplicant/ctrl_iface.c | 9 ++-- wpa_supplicant/hs20_supplicant.c | 3 +- wpa_supplicant/interworking.c | 4 +- 8 files changed, 108 insertions(+), 16 deletions(-) diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index 46d2a3546..871536f59 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -1,6 +1,6 @@ /* * IEEE 802.11 Common routines - * Copyright (c) 2002-2015, Jouni Malinen + * Copyright (c) 2002-2019, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -1866,3 +1866,11 @@ int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, return nei_pos - nei_rep; } + + +int ieee802_11_ext_capab(const u8 *ie, unsigned int capab) +{ + if (!ie || ie[1] <= capab / 8) + return 0; + return !!(ie[2 + capab / 8] & BIT(capab % 8)); +} diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index 5f22fcd31..4e8c766e4 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -1,6 +1,6 @@ /* * IEEE 802.11 Common routines - * Copyright (c) 2002-2012, Jouni Malinen + * Copyright (c) 2002-2019, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -212,4 +212,6 @@ int oper_class_bw_to_int(const struct oper_class_map *map); int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, size_t nei_rep_len); +int ieee802_11_ext_capab(const u8 *ie, unsigned int capab); + #endif /* IEEE802_11_COMMON_H */ diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index ee750fa45..178cab041 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -1,6 +1,6 @@ /* * IEEE 802.11 Frame type definitions - * Copyright (c) 2002-2015, Jouni Malinen + * Copyright (c) 2002-2019, Jouni Malinen * Copyright (c) 2007-2008 Intel Corporation * * This software may be distributed under the terms of the BSD license. @@ -469,6 +469,86 @@ #define WLAN_EID_EXT_HE_OPERATION 36 #define WLAN_EID_EXT_OCV_OCI 54 +/* Extended Capabilities field */ +#define WLAN_EXT_CAPAB_20_40_COEX 0 +#define WLAN_EXT_CAPAB_GLK 1 +#define WLAN_EXT_CAPAB_EXT_CHAN_SWITCH 2 +#define WLAN_EXT_CAPAB_GLK_GCR 3 +#define WLAN_EXT_CAPAB_PSMP 4 +/* 5 - Reserved */ +#define WLAN_EXT_CAPAB_S_PSMP 6 +#define WLAN_EXT_CAPAB_EVENT 7 +#define WLAN_EXT_CAPAB_DIAGNOSTICS 8 +#define WLAN_EXT_CAPAB_MULTICAST_DIAGNOSTICS 9 +#define WLAN_EXT_CAPAB_LOCATION_TRACKING 10 +#define WLAN_EXT_CAPAB_FMS 11 +#define WLAN_EXT_CAPAB_PROXY_ARP 12 +#define WLAN_EXT_CAPAB_COLL_INTERF_REP 13 +#define WLAN_EXT_CAPAB_CIVIC_LOCATION 14 +#define WLAN_EXT_CAPAB_GEOSPATIAL_LOCATION 15 +#define WLAN_EXT_CAPAB_TFS 16 +#define WLAN_EXT_CAPAB_WNM_SLEEP_MODE 17 +#define WLAN_EXT_CAPAB_TIM_BROADCAST 18 +#define WLAN_EXT_CAPAB_BSS_TRANSITION 19 +#define WLAN_EXT_CAPAB_QOS_TRAFFIC 20 +#define WLAN_EXT_CAPAB_AC_STA_COUNT 21 +#define WLAN_EXT_CAPAB_MULTIPLE_BSSID 22 +#define WLAN_EXT_CAPAB_TIMING_MEASUREMENT 23 +#define WLAN_EXT_CAPAB_CHANNEL_USAGE 24 +#define WLAN_EXT_CAPAB_SSID_LIST 25 +#define WLAN_EXT_CAPAB_DMS 26 +#define WLAN_EXT_CAPAB_UTF_TSF_OFFSET 27 +#define WLAN_EXT_CAPAB_TPU_BUFFER_STA 28 +#define WLAN_EXT_CAPAB_TDLS_PEER_PSM 29 +#define WLAN_EXT_CAPAB_TDLS_CHANNEL_SWITCH 30 +#define WLAN_EXT_CAPAB_INTERWORKING 31 +#define WLAN_EXT_CAPAB_QOS_MAP 32 +#define WLAN_EXT_CAPAB_EBR 33 +#define WLAN_EXT_CAPAB_SSPN_INTERFACE 34 +/* 35 - Reserved */ +#define WLAN_EXT_CAPAB_MSGCF 36 +#define WLAN_EXT_CAPAB_TDLS 37 +#define WLAN_EXT_CAPAB_TDLS_PROHIBITED 38 +#define WLAN_EXT_CAPAB_TDLS_CHANNEL_SWITCH_PROHIBITED 39 +#define WLAN_EXT_CAPAB_REJECT_UNADMITTED_FRAME 40 +#define WLAN_EXT_CAPAB_ +/* 41-43 - Service Interval Granularity */ +#define WLAN_EXT_CAPAB_IDENTIFIER_LOCATION 44 +#define WLAN_EXT_CAPAB_U_APSD_COEX 45 +#define WLAN_EXT_CAPAB_WNM_NOTIFCATION 46 +#define WLAN_EXT_CAPAB_QAB 47 +#define WLAN_EXT_CAPAB_UTF_8_SSID 48 +#define WLAN_EXT_CAPAB_QMF 49 +#define WLAN_EXT_CAPAB_QMF_RECONFIG 50 +#define WLAN_EXT_CAPAB_ROBUST_AV_STREAMING 51 +#define WLAN_EXT_CAPAB_ADVANCED_GCR 52 +#define WLAN_EXT_CAPAB_MESH_GCR 53 +#define WLAN_EXT_CAPAB_SCS 54 +#define WLAN_EXT_CAPAB_QLOAD_REPORT 55 +#define WLAN_EXT_CAPAB_ALT_EDCA 56 +#define WLAN_EXT_CAPAB_UNPROT_TXOP_NEG 57 +#define WLAN_EXT_CAPAB_PROT_TXOP_NEG 58 +/* 59 - Reserved */ +#define WLAN_EXT_CAPAB_PROT_QLOAD_REPORT 60 +#define WLAN_EXT_CAPAB_TDLS_WIDER_BW 61 +#define WLAN_EXT_CAPAB_OPMODE_NOTIF 62 +#define WLAN_EXT_CAPAB_ +/* 63-64 - Max Number of MSDUs In A-MSDU */ +#define WLAN_EXT_CAPAB_CHANNEL_SCHEDULE_MGMT 65 +#define WLAN_EXT_CAPAB_GEODB_INBAND_ENABLING_SIGNAL 66 +#define WLAN_EXT_CAPAB_NETWORK_CHANNEL_CTRL 67 +#define WLAN_EXT_CAPAB_WHITE_SPACE_MAP 68 +#define WLAN_EXT_CAPAB_CHANNEL_AVAIL_QUERY 69 +#define WLAN_EXT_CAPAB_FTM_RESPONDER 70 +#define WLAN_EXT_CAPAB_FTM_INITIATOR 71 +#define WLAN_EXT_CAPAB_FILS 72 +#define WLAN_EXT_CAPAB_EXT_SPECTRUM_MGMT 73 +#define WLAN_EXT_CAPAB_FUTURE_CHANNEL_GUIDANCE 74 +#define WLAN_EXT_CAPAB_PAD 75 +/* 76-79 - Reserved */ +#define WLAN_EXT_CAPAB_COMPLETE_NON_TX_BSSID_PROFILE 80 +#define WLAN_EXT_CAPAB_SAE_PW_ID 81 +#define WLAN_EXT_CAPAB_SAE_PW_ID_EXCLUSIVELY 82 /* Action frame categories (IEEE Std 802.11-2016, 9.4.1.11, Table 9-76) */ #define WLAN_ACTION_SPECTRUM_MGMT 0 diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index 3a41db98e..9b19f37af 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -1,6 +1,6 @@ /* * BSS table - * Copyright (c) 2009-2015, Jouni Malinen + * Copyright (c) 2009-2019, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -1337,3 +1337,10 @@ const u8 * wpa_bss_get_fils_cache_id(struct wpa_bss *bss) return NULL; } #endif /* CONFIG_FILS */ + + +int wpa_bss_ext_capab(const struct wpa_bss *bss, unsigned int capab) +{ + return ieee802_11_ext_capab(wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB), + capab); +} diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h index 5251b2c35..3ce8cd3f4 100644 --- a/wpa_supplicant/bss.h +++ b/wpa_supplicant/bss.h @@ -1,6 +1,6 @@ /* * BSS table - * Copyright (c) 2009-2015, Jouni Malinen + * Copyright (c) 2009-2019, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -148,6 +148,7 @@ int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates); struct wpa_bss_anqp * wpa_bss_anqp_alloc(void); int wpa_bss_anqp_unshare_alloc(struct wpa_bss *bss); const u8 * wpa_bss_get_fils_cache_id(struct wpa_bss *bss); +int wpa_bss_ext_capab(const struct wpa_bss *bss, unsigned int capab); static inline int bss_is_dmg(const struct wpa_bss *bss) { diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index f9a21d8e1..b4ab9088b 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -1,6 +1,6 @@ /* * WPA Supplicant / Control interface (shared code for all backends) - * Copyright (c) 2004-2015, Jouni Malinen + * Copyright (c) 2004-2019, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -2913,8 +2913,7 @@ static int wpa_supplicant_ctrl_iface_scan_result( pos += ret; } #endif /* CONFIG_FST */ - ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB); - if (ie && ie[1] >= 7 && ie[8] & BIT(0)) { /* Bit 48 - UTF-8 SSID */ + if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_UTF_8_SSID)) { ret = os_snprintf(pos, end - pos, "[UTF-8]"); if (os_snprintf_error(end - pos, ret)) return -1; @@ -4748,9 +4747,7 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, pos += ret; } #endif /* CONFIG_FST */ - ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB); - if (ie && ie[1] >= 7 && ie[8] & BIT(0)) { - /* Bit 48 - UTF-8 SSID */ + if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_UTF_8_SSID)) { ret = os_snprintf(pos, end - pos, "[UTF-8]"); if (os_snprintf_error(end - pos, ret)) return 0; diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c index 030b5aa99..267612afc 100644 --- a/wpa_supplicant/hs20_supplicant.c +++ b/wpa_supplicant/hs20_supplicant.c @@ -95,8 +95,7 @@ void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s) return; } - /* Check if Proxy ARP is enabled (2nd byte in the IE) */ - if (ext_capa[3] & BIT(4)) + if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_PROXY_ARP)) filter |= WPA_DATA_FRAME_FILTER_FLAG_ARP | WPA_DATA_FRAME_FILTER_FLAG_NA; diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 396fea6af..f94cd1614 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -2626,7 +2626,6 @@ static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s) { struct wpa_bss *bss; int found = 0; - const u8 *ie; wpa_printf(MSG_DEBUG, "Interworking: next_anqp_fetch - " "fetch_anqp_in_progress=%d fetch_osu_icon_in_progress=%d", @@ -2649,8 +2648,7 @@ static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s) dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { if (!(bss->caps & IEEE80211_CAP_ESS)) continue; - ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB); - if (ie == NULL || ie[1] < 4 || !(ie[5] & 0x80)) + if (!wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_INTERWORKING)) continue; /* AP does not support Interworking */ if (disallowed_bssid(wpa_s, bss->bssid) || disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len))