aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/mesh_mpm.c
diff options
context:
space:
mode:
authorMathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>2018-08-06 19:46:37 (GMT)
committerJouni Malinen <j@w1.fi>2018-12-17 13:50:12 (GMT)
commit034388ac9cf9f45c7d4000109fd62d51cb9b3a52 (patch)
tree470c7bd4b0814408031dfa99b7d1044c30b3e621 /wpa_supplicant/mesh_mpm.c
parent716ed96e8da31e9833edc9c22fa6ba2e7245c8b1 (diff)
downloadhostap-034388ac9cf9f45c7d4000109fd62d51cb9b3a52.zip
hostap-034388ac9cf9f45c7d4000109fd62d51cb9b3a52.tar.gz
hostap-034388ac9cf9f45c7d4000109fd62d51cb9b3a52.tar.bz2
OCV: Include and verify OCI in the AMPE handshake
Include and verify the OCI element in AMPE Open and Confirm frames. Note that the OCI element is included even if the other STA didn't advertise support of OCV. The OCI element is only required and verified if both peers support OCV. Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
Diffstat (limited to 'wpa_supplicant/mesh_mpm.c')
-rw-r--r--wpa_supplicant/mesh_mpm.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 75ee0f7..4485939 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -12,6 +12,7 @@
#include "utils/eloop.h"
#include "common/ieee802_11_defs.h"
#include "common/hw_features_common.h"
+#include "common/ocv.h"
#include "ap/hostapd.h"
#include "ap/sta_info.h"
#include "ap/ieee802_11.h"
@@ -246,6 +247,11 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_IEEE80211AC */
if (type != PLINK_CLOSE)
buf_len += conf->rsn_ie_len; /* RSN IE */
+#ifdef CONFIG_OCV
+ /* OCI is included even when the other STA doesn't support OCV */
+ if (type != PLINK_CLOSE && conf->ocv)
+ buf_len += OCV_OCI_EXTENDED_LEN;
+#endif /* CONFIG_OCV */
buf = wpabuf_alloc(buf_len);
if (!buf)
@@ -357,6 +363,22 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
}
#endif /* CONFIG_IEEE80211AC */
+#ifdef CONFIG_OCV
+ if (type != PLINK_CLOSE && conf->ocv) {
+ struct wpa_channel_info ci;
+
+ if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
+ wpa_printf(MSG_WARNING,
+ "Mesh MPM: Failed to get channel info for OCI element");
+ goto fail;
+ }
+
+ pos = wpabuf_put(buf, OCV_OCI_EXTENDED_LEN);
+ if (ocv_insert_extended_oci(&ci, pos) < 0)
+ goto fail;
+ }
+#endif /* CONFIG_OCV */
+
if (ampe && mesh_rsn_protect_frame(wpa_s->mesh_rsn, sta, cat, buf)) {
wpa_msg(wpa_s, MSG_INFO,
"Mesh MPM: failed to add AMPE and MIC IE");
@@ -1197,6 +1219,56 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
}
return;
}
+
+#ifdef CONFIG_OCV
+ if (action_field == PLINK_OPEN && elems.rsn_ie) {
+ struct wpa_state_machine *sm = sta->wpa_sm;
+ struct wpa_ie_data data;
+
+ res = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2,
+ elems.rsn_ie_len + 2,
+ &data);
+ if (res) {
+ wpa_printf(MSG_DEBUG,
+ "Failed to parse RSN IE (res=%d)",
+ res);
+ wpa_hexdump(MSG_DEBUG, "RSN IE", elems.rsn_ie,
+ elems.rsn_ie_len);
+ return;
+ }
+
+ wpa_auth_set_ocv(sm, mconf->ocv &&
+ (data.capabilities &
+ WPA_CAPABILITY_OCVC));
+ }
+
+ if (action_field != PLINK_CLOSE &&
+ wpa_auth_uses_ocv(sta->wpa_sm)) {
+ struct wpa_channel_info ci;
+ int tx_chanwidth;
+ int tx_seg1_idx;
+
+ if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
+ wpa_printf(MSG_WARNING,
+ "MPM: Failed to get channel info to validate received OCI in MPM Confirm");
+ return;
+ }
+
+ if (get_tx_parameters(
+ sta, channel_width_to_int(ci.chanwidth),
+ ci.seg1_idx, &tx_chanwidth,
+ &tx_seg1_idx) < 0)
+ return;
+
+ if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
+ tx_chanwidth, tx_seg1_idx) !=
+ 0) {
+ wpa_printf(MSG_WARNING, "MPM: %s",
+ ocv_errorstr);
+ return;
+ }
+ }
+#endif /* CONFIG_OCV */
}
if (sta->plink_state == PLINK_BLOCKED) {