diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 038c4ec0e..9518545c8 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2164,6 +2164,7 @@ struct ieee80211_he_capabilities { * and optional variable length PPE Thresholds field. */ u8 optional[37]; } STRUCT_PACKED; +#define IEEE80211_HE_CAPAB_MIN_LEN (6 + 11) struct ieee80211_he_operation { le32 he_oper_params; /* HE Operation Parameters[3] and diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index 2b8c7f661..04d49ee4c 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -3226,6 +3226,11 @@ int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie) pos[1] >= sizeof(struct ieee80211_vht_capabilities)) { ie->vht_capabilities = pos + 2; + } else if (*pos == WLAN_EID_EXTENSION && + pos[1] >= 1 + IEEE80211_HE_CAPAB_MIN_LEN && + pos[2] == WLAN_EID_EXT_HE_CAPABILITIES) { + ie->he_capabilities = pos + 3; + ie->he_capab_len = pos[1] - 1; } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) { ie->qosinfo = pos[2]; } else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) { diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index c31e1a0fa..0e9f252ad 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -592,6 +592,8 @@ struct wpa_eapol_ie_parse { size_t ext_supp_rates_len; const u8 *ht_capabilities; const u8 *vht_capabilities; + const u8 *he_capabilities; + size_t he_capab_len; const u8 *supp_channels; size_t supp_channels_len; const u8 *supp_oper_classes; diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 7c4ef191c..af692680c 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -136,6 +136,8 @@ struct wpa_tdls_peer { struct ieee80211_ht_capabilities *ht_capabilities; struct ieee80211_vht_capabilities *vht_capabilities; + struct ieee80211_he_capabilities *he_capabilities; + size_t he_capab_len; u8 qos_info; @@ -703,6 +705,8 @@ static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer) peer->ht_capabilities = NULL; os_free(peer->vht_capabilities); peer->vht_capabilities = NULL; + os_free(peer->he_capabilities); + peer->he_capabilities = NULL; os_free(peer->ext_capab); peer->ext_capab = NULL; os_free(peer->supp_channels); @@ -1652,6 +1656,29 @@ static int copy_peer_vht_capab(const struct wpa_eapol_ie_parse *kde, } +static int copy_peer_he_capab(const struct wpa_eapol_ie_parse *kde, + struct wpa_tdls_peer *peer) +{ + if (!kde->he_capabilities) { + wpa_printf(MSG_DEBUG, "TDLS: No HE capabilities received"); + return 0; + } + + os_free(peer->he_capabilities); + peer->he_capab_len = 0; + peer->he_capabilities = os_memdup(kde->he_capabilities, + kde->he_capab_len); + if (!peer->he_capabilities) + return -1; + + peer->he_capab_len = kde->he_capab_len; + wpa_hexdump(MSG_DEBUG, "TDLS: Peer HE capabilities", + peer->he_capabilities, peer->he_capab_len); + + return 0; +} + + static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde, struct wpa_tdls_peer *peer) { @@ -1761,6 +1788,8 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer, peer->supp_rates, peer->supp_rates_len, peer->ht_capabilities, peer->vht_capabilities, + peer->he_capabilities, + peer->he_capab_len, peer->qos_info, peer->wmm_capable, peer->ext_capab, peer->ext_capab_len, peer->supp_channels, @@ -1896,7 +1925,8 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, if (copy_peer_ht_capab(&kde, peer) < 0) goto error; - if (copy_peer_vht_capab(&kde, peer) < 0) + if (copy_peer_vht_capab(&kde, peer) < 0 || + copy_peer_he_capab(&kde, peer) < 0) goto error; if (copy_peer_ext_capab(&kde, peer) < 0) @@ -1925,7 +1955,8 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, "TDLS setup - send own request"); peer->initiator = 1; wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, - NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0); + NULL, NULL, 0, 0, 0, NULL, 0, NULL, 0, + NULL, 0); if (wpa_tdls_send_tpk_m1(sm, peer) == -2) { peer = NULL; goto error; @@ -2303,7 +2334,8 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr, if (copy_peer_ht_capab(&kde, peer) < 0) goto error; - if (copy_peer_vht_capab(&kde, peer) < 0) + if (copy_peer_vht_capab(&kde, peer) < 0 || + copy_peer_he_capab(&kde, peer) < 0) goto error; if (copy_peer_ext_capab(&kde, peer) < 0) @@ -2690,7 +2722,8 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr) /* add the peer to the driver as a "setup in progress" peer */ if (wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, - NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0)) { + NULL, NULL, 0, 0, 0, NULL, 0, NULL, 0, + NULL, 0)) { wpa_tdls_disable_peer_link(sm, peer); return -1; } diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 8e4533e45..f377acba2 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -69,6 +69,8 @@ struct wpa_sm_ctx { size_t supp_rates_len, const struct ieee80211_ht_capabilities *ht_capab, const struct ieee80211_vht_capabilities *vht_capab, + const struct ieee80211_he_capabilities *he_capab, + size_t he_capab_len, u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len, const u8 *supp_channels, size_t supp_channels_len, diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 1dc963963..e7281bf3b 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -398,6 +398,8 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, size_t supp_rates_len, const struct ieee80211_ht_capabilities *ht_capab, const struct ieee80211_vht_capabilities *vht_capab, + const struct ieee80211_he_capabilities *he_capab, + size_t he_capab_len, u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len, const u8 *supp_channels, size_t supp_channels_len, const u8 *supp_oper_classes, @@ -407,7 +409,9 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add, aid, capability, supp_rates, supp_rates_len, ht_capab, - vht_capab, qosinfo, wmm, + vht_capab, + he_capab, he_capab_len, + qosinfo, wmm, ext_capab, ext_capab_len, supp_channels, supp_channels_len, diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 345c87d35..240e3d2d9 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -778,6 +778,8 @@ static int wpa_supplicant_tdls_peer_addset( const u8 *supp_rates, size_t supp_rates_len, const struct ieee80211_ht_capabilities *ht_capab, const struct ieee80211_vht_capabilities *vht_capab, + const struct ieee80211_he_capabilities *he_capab, + size_t he_capab_len, u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len, const u8 *supp_channels, size_t supp_channels_len, const u8 *supp_oper_classes, size_t supp_oper_classes_len) @@ -801,6 +803,8 @@ static int wpa_supplicant_tdls_peer_addset( params.ht_capabilities = ht_capab; params.vht_capabilities = vht_capab; + params.he_capab = he_capab; + params.he_capab_len = he_capab_len; params.qosinfo = qosinfo; params.listen_interval = 0; params.supp_rates = supp_rates;