diff mbox series

[v5,1/5] ie: add validation for HE Capabilities element

Message ID 20220720212932.873353-1-prestwoj@gmail.com (mailing list archive)
State Accepted, archived
Headers show
Series [v5,1/5] ie: add validation for HE Capabilities element | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
prestwoj/iwd-alpine-ci-fetch success Fetch PR
prestwoj/iwd-ci-fetch success Fetch PR
prestwoj/iwd-ci-gitlint success GitLint
prestwoj/iwd-alpine-ci-makedistcheck success Make Distcheck
prestwoj/iwd-ci-makedistcheck success Make Distcheck
prestwoj/iwd-alpine-ci-build success Build - Configure
prestwoj/iwd-ci-build success Build - Configure
prestwoj/iwd-ci-clang success clang PASS
prestwoj/iwd-ci-makecheckvalgrind success Make Check w/Valgrind
prestwoj/iwd-ci-makecheck success Make Check
prestwoj/iwd-alpine-ci-makecheckvalgrind success Make Check w/Valgrind
prestwoj/iwd-alpine-ci-makecheck success Make Check
prestwoj/iwd-ci-incremental_build success Incremental Build with patches
prestwoj/iwd-alpine-ci-incremental_build success Incremental Build with patches
prestwoj/iwd-ci-testrunner success test-runner PASS

Commit Message

James Prestwood July 20, 2022, 9:29 p.m. UTC
This makes sure the width set bits are sane, and validates the length
depending on which MCS sets are enabled.
---
 src/ie.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/ie.h |  2 ++
 2 files changed, 50 insertions(+)
diff mbox series

Patch

diff --git a/src/ie.c b/src/ie.c
index 7ef07c37..070454ef 100644
--- a/src/ie.c
+++ b/src/ie.c
@@ -2577,3 +2577,51 @@  int ie_parse_oci(const void *data, size_t len, const uint8_t **oci)
 
 	return 0;
 }
+
+/*
+ * Checks the supported width set (Table 9-322b) meets the following
+ * requirements:
+ *  - B0 and bits B1/B2/B3 are mutually exclusive.
+ *  - B2 is only set if B1 is set
+ *  - B3 is only set if B2 is set (and in turn, B1 is set)
+ *  - The IE length supports B2 and B3 MCS sets
+ */
+bool ie_validate_he_capabilities(const void *data, size_t len)
+{
+	uint8_t width_set;
+	const uint8_t *ptr = data;
+	bool freq_2_4;
+	bool width_40_80;
+	bool width_160;
+	bool width_80p80;
+
+	if (len < 22)
+		return false;
+
+	width_set = bit_field((ptr + 7)[0], 1, 7);
+
+	/* B0 indicates support for 40MHz, but only in 2.4GHz band */
+	freq_2_4 = test_bit(&width_set, 0);
+
+	/* B1 indicates support for 40/80MHz */
+	width_40_80 = test_bit(&width_set, 1);
+
+	if (width_40_80 && freq_2_4)
+		return false;
+
+	/* B2 indicates support for 160MHz MCS table */
+	width_160 = test_bit(&width_set, 2);
+
+	/* Ensure B1 is set, not B0, and the length includes this MCS table */
+	if (width_160 && (!width_40_80 || freq_2_4 || len < 26))
+		return false;
+
+	/* B3 indicates support for 80+80Mhz MCS table */
+	width_80p80 = test_bit(&width_set, 3);
+
+	/* Ensure B2 is set, not B0, and the length includes this MCS table */
+	if (width_80p80 && (!width_160 || freq_2_4 || len < 30))
+		return false;
+
+	return true;
+}
diff --git a/src/ie.h b/src/ie.h
index d38e9e8e..e56df984 100644
--- a/src/ie.h
+++ b/src/ie.h
@@ -682,3 +682,5 @@  int ie_parse_owe_transition(const void *data, size_t len,
 				struct ie_owe_transition_info *info);
 
 int ie_parse_oci(const void *data, size_t len, const uint8_t **oci);
+
+bool ie_validate_he_capabilities(const void *data, size_t len);