aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common/ieee802_11_defs.h1
-rw-r--r--src/drivers/driver.h4
-rw-r--r--src/rsn_supp/tdls.c84
-rw-r--r--src/rsn_supp/wpa.h5
-rw-r--r--src/rsn_supp/wpa_i.h11
-rw-r--r--src/rsn_supp/wpa_ie.c6
-rw-r--r--src/rsn_supp/wpa_ie.h4
-rw-r--r--wpa_supplicant/wpas_glue.c8
8 files changed, 116 insertions, 7 deletions
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 137c3090..eec1a2e8 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -225,6 +225,7 @@
#define WLAN_EID_FAST_BSS_TRANSITION 55
#define WLAN_EID_TIMEOUT_INTERVAL 56
#define WLAN_EID_RIC_DATA 57
+#define WLAN_EID_SUPPORTED_OPERATING_CLASSES 59
#define WLAN_EID_HT_OPERATION 61
#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62
#define WLAN_EID_WAPI 68
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 23883f05..89ad5db7 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -983,6 +983,10 @@ struct hostapd_sta_add_params {
u8 qosinfo;
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;
};
struct hostapd_freq_params {
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 52309442..e06c9ad6 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -136,6 +136,12 @@ struct wpa_tdls_peer {
u8 *ext_capab;
size_t ext_capab_len;
+
+ u8 *supp_channels;
+ size_t supp_channels_len;
+
+ u8 *supp_oper_classes;
+ size_t supp_oper_classes_len;
};
@@ -633,6 +639,10 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
peer->vht_capabilities = NULL;
os_free(peer->ext_capab);
peer->ext_capab = NULL;
+ os_free(peer->supp_channels);
+ peer->supp_channels = NULL;
+ os_free(peer->supp_oper_classes);
+ peer->supp_oper_classes = NULL;
peer->rsnie_i_len = peer->rsnie_p_len = 0;
peer->cipher = 0;
peer->tpk_set = peer->tpk_success = 0;
@@ -1434,6 +1444,58 @@ static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde,
}
+static int copy_peer_supp_channels(const struct wpa_eapol_ie_parse *kde,
+ struct wpa_tdls_peer *peer)
+{
+ if (!kde->supp_channels) {
+ wpa_printf(MSG_DEBUG, "TDLS: No supported channels received");
+ return 0;
+ }
+
+ if (!peer->supp_channels ||
+ peer->supp_channels_len < kde->supp_channels_len) {
+ os_free(peer->supp_channels);
+ peer->supp_channels = os_zalloc(kde->supp_channels_len);
+ if (peer->supp_channels == NULL)
+ return -1;
+ }
+
+ peer->supp_channels_len = kde->supp_channels_len;
+
+ os_memcpy(peer->supp_channels, kde->supp_channels,
+ peer->supp_channels_len);
+ wpa_hexdump(MSG_DEBUG, "TDLS: Peer Supported Channels",
+ (u8 *) peer->supp_channels, peer->supp_channels_len);
+ return 0;
+}
+
+
+static int copy_peer_supp_oper_classes(const struct wpa_eapol_ie_parse *kde,
+ struct wpa_tdls_peer *peer)
+{
+ if (!kde->supp_oper_classes) {
+ wpa_printf(MSG_DEBUG, "TDLS: No supported operating classes received");
+ return 0;
+ }
+
+ if (!peer->supp_oper_classes ||
+ peer->supp_oper_classes_len < kde->supp_oper_classes_len) {
+ os_free(peer->supp_oper_classes);
+ peer->supp_oper_classes = os_zalloc(kde->supp_oper_classes_len);
+ if (peer->supp_oper_classes == NULL)
+ return -1;
+ }
+
+ peer->supp_oper_classes_len = kde->supp_oper_classes_len;
+ os_memcpy(peer->supp_oper_classes, kde->supp_oper_classes,
+ peer->supp_oper_classes_len);
+ wpa_hexdump(MSG_DEBUG, "TDLS: Peer Supported Operating Classes",
+ (u8 *) peer->supp_oper_classes,
+ peer->supp_oper_classes_len);
+ return 0;
+}
+
+
static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
const u8 *buf, size_t len)
{
@@ -1546,6 +1608,12 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
if (copy_peer_ext_capab(&kde, peer) < 0)
goto error;
+ if (copy_peer_supp_channels(&kde, peer) < 0)
+ goto error;
+
+ if (copy_peer_supp_oper_classes(&kde, peer) < 0)
+ goto error;
+
peer->qos_info = kde.qosinfo;
peer->aid = kde.aid;
@@ -1739,7 +1807,7 @@ skip_rsn:
skip_rsn_check:
/* add the peer to the driver as a "setup in progress" peer */
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0,
- NULL, 0);
+ NULL, 0, NULL, 0, NULL, 0);
peer->tpk_in_progress = 1;
wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
@@ -1788,7 +1856,11 @@ static int wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
peer->ht_capabilities,
peer->vht_capabilities,
peer->qos_info, peer->ext_capab,
- peer->ext_capab_len) < 0)
+ peer->ext_capab_len,
+ peer->supp_channels,
+ peer->supp_channels_len,
+ peer->supp_oper_classes,
+ peer->supp_oper_classes_len) < 0)
return -1;
if (peer->reconfig_key && wpa_tdls_set_key(sm, peer) < 0) {
@@ -1916,6 +1988,12 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
if (copy_peer_ext_capab(&kde, peer) < 0)
goto error;
+ if (copy_peer_supp_channels(&kde, peer) < 0)
+ goto error;
+
+ if (copy_peer_supp_oper_classes(&kde, peer) < 0)
+ goto error;
+
peer->qos_info = kde.qosinfo;
peer->aid = kde.aid;
@@ -2267,7 +2345,7 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
/* add the peer to the driver as a "setup in progress" peer */
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0,
- NULL, 0);
+ NULL, 0, NULL, 0, NULL, 0);
peer->tpk_in_progress = 1;
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 26e9c6ca..f5ee76c3 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -62,7 +62,10 @@ struct wpa_sm_ctx {
const struct ieee80211_ht_capabilities *ht_capab,
const struct ieee80211_vht_capabilities *vht_capab,
u8 qosinfo, const u8 *ext_capab,
- size_t ext_capab_len);
+ 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);
#endif /* CONFIG_TDLS */
void (*set_rekey_offload)(void *ctx, const u8 *kek, const u8 *kck,
const u8 *replay_ctr);
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index 0e0d373f..cad6c8d9 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -286,14 +286,21 @@ 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,
- u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
+ u8 qosinfo, 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)
{
if (sm->ctx->tdls_peer_addset)
return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add,
aid, capability, supp_rates,
supp_rates_len, ht_capab,
vht_capab, qosinfo,
- ext_capab, ext_capab_len);
+ ext_capab, ext_capab_len,
+ supp_channels,
+ supp_channels_len,
+ supp_oper_classes,
+ supp_oper_classes_len);
return -1;
}
#endif /* CONFIG_TDLS */
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index 50b9272b..ab8d104d 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -434,6 +434,12 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
ie->vht_capabilities_len = pos[1];
} else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
ie->qosinfo = pos[2];
+ } else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) {
+ ie->supp_channels = pos + 2;
+ ie->supp_channels_len = pos[1];
+ } else if (*pos == WLAN_EID_SUPPORTED_OPERATING_CLASSES) {
+ ie->supp_oper_classes = pos + 2;
+ ie->supp_oper_classes_len = pos[1];
} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
ret = wpa_parse_generic(pos, end, ie);
if (ret < 0)
diff --git a/src/rsn_supp/wpa_ie.h b/src/rsn_supp/wpa_ie.h
index 2c788012..0375767d 100644
--- a/src/rsn_supp/wpa_ie.h
+++ b/src/rsn_supp/wpa_ie.h
@@ -53,6 +53,10 @@ struct wpa_eapol_ie_parse {
size_t ht_capabilities_len;
const u8 *vht_capabilities;
size_t vht_capabilities_len;
+ const u8 *supp_channels;
+ size_t supp_channels_len;
+ const u8 *supp_oper_classes;
+ size_t supp_oper_classes_len;
u8 qosinfo;
u16 aid;
};
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 61a42bd0..19616221 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -560,7 +560,9 @@ 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,
- u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
+ u8 qosinfo, 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)
{
struct wpa_supplicant *wpa_s = ctx;
struct hostapd_sta_add_params params;
@@ -588,6 +590,10 @@ static int wpa_supplicant_tdls_peer_addset(
params.set = !add;
params.ext_capab = ext_capab;
params.ext_capab_len = ext_capab_len;
+ params.supp_channels = supp_channels;
+ params.supp_channels_len = supp_channels_len;
+ params.supp_oper_classes = supp_oper_classes;
+ params.supp_oper_classes_len = supp_oper_classes_len;
return wpa_drv_sta_add(wpa_s, &params);
}