[PATCH 05/15] wpa_supplicant: Limit RRM response size to MMPDU size
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Dec 28 05:06:37 PST 2016
From: Avraham Stern <avraham.stern at intel.com>
The length of a Measurement Report frame should be limited by the
maximum allowed MMPDU size (IEEE802.11 - 2012, section 8.5.2.3).
Enforce this size limit, and in case the report elements are longer
than the allowed size, split them between several MPDUs.
Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
wpa_supplicant/rrm.c | 75 ++++++++++++++++++++++++++-------------
wpa_supplicant/wpa_supplicant_i.h | 3 ++
2 files changed, 54 insertions(+), 24 deletions(-)
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
index e284543..3ffde24 100644
--- a/wpa_supplicant/rrm.c
+++ b/wpa_supplicant/rrm.c
@@ -410,12 +410,59 @@ out:
}
+static void wpas_rrm_send_msr_report_mpdu(struct wpa_supplicant *wpa_s,
+ const u8 *data, size_t len)
+{
+ struct wpabuf *report = wpabuf_alloc(len + 3);
+
+ if (!report)
+ return;
+
+ wpabuf_put_u8(report, WLAN_ACTION_RADIO_MEASUREMENT);
+ wpabuf_put_u8(report, WLAN_RRM_RADIO_MEASUREMENT_REPORT);
+ wpabuf_put_u8(report, wpa_s->rrm.token);
+
+ wpabuf_put_data(report, data, len);
+
+ if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
+ wpa_s->own_addr, wpa_s->bssid,
+ wpabuf_head(report), wpabuf_len(report), 0)) {
+ wpa_printf(MSG_ERROR,
+ "RRM: Radio measurement report failed. Send action failed");
+ }
+
+ wpabuf_free(report);
+}
+
+static void wpas_rrm_send_msr_report(struct wpa_supplicant *wpa_s,
+ struct wpabuf *buf)
+{
+ int len = wpabuf_len(buf);
+ const u8 *pos = wpabuf_head_u8(buf), *next = pos;
+
+#define MPDU_REPORT_LEN (int)(IEEE80211_MAX_MMPDU_SIZE - IEEE80211_HDRLEN - 3)
+
+ while (len) {
+ int send_len = (len > MPDU_REPORT_LEN) ? next - pos : len;
+
+ if (send_len == len ||
+ (send_len + next[1] + 2) > MPDU_REPORT_LEN) {
+ wpas_rrm_send_msr_report_mpdu(wpa_s, pos, send_len);
+ len -= send_len;
+ pos = next;
+ }
+
+ next += next[1] + 2;
+ }
+#undef MPDU_REPORT_LEN
+}
+
+
void wpas_rrm_handle_radio_measurement_request(struct wpa_supplicant *wpa_s,
const u8 *src,
const u8 *frame, size_t len)
{
- struct wpabuf *buf, *report;
- u8 token;
+ struct wpabuf *report;
if (wpa_s->wpa_state != WPA_COMPLETED) {
wpa_printf(MSG_INFO,
@@ -435,35 +482,15 @@ void wpas_rrm_handle_radio_measurement_request(struct wpa_supplicant *wpa_s,
return;
}
- token = *frame;
+ wpa_s->rrm.token = *frame;
/* Num of repetitions is not supported */
report = wpas_rrm_process_msr_req_elems(wpa_s, frame + 3, len - 3);
-
if (!report)
return;
- buf = wpabuf_alloc(3 + wpabuf_len(report));
- if (!buf) {
- wpabuf_free(report);
- return;
- }
-
- wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
- wpabuf_put_u8(buf, WLAN_RRM_RADIO_MEASUREMENT_REPORT);
- wpabuf_put_u8(buf, token);
-
- wpabuf_put_buf(buf, report);
- wpabuf_free(report);
-
- if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0)) {
- wpa_printf(MSG_ERROR,
- "RRM: Radio measurement report failed: Sending Action frame failed");
- }
- wpabuf_free(buf);
+ wpas_rrm_send_msr_report(wpa_s, report);
wpabuf_free(report);
}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index f03d51a..b182dda 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -424,6 +424,9 @@ struct rrm_data {
/* next_neighbor_rep_token - Next request's dialog token */
u8 next_neighbor_rep_token;
+
+ /* token - Dialog token of the current radio measurement */
+ u8 token;
};
enum wpa_supplicant_test_failure {
--
1.9.1
More information about the Hostap
mailing list