[PATCH 15/50] common: Support parsing link specific association request
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Feb 15 15:08:29 PST 2023
From: Ilan Peer <ilan.peer at intel.com>
An association request in the context of an MLO connection can
contain an ML element that holds the per station profile for
the additional links negotiated. To support this, add a function
to parse the per station profile.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
src/common/ieee802_11_common.c | 147 +++++++++++++++++++++++++++++++++
src/common/ieee802_11_common.h | 4 +
2 files changed, 151 insertions(+)
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index f55eddf62e..0941cb9afe 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -950,6 +950,153 @@ void ieee802_11_elems_clear_ext_ids(struct ieee802_11_elems *elems,
}
+ParseRes ieee802_11_parse_link_assoc_req(const u8 *start, size_t len,
+ struct ieee802_11_elems *elems,
+ struct wpabuf *mlbuf,
+ u8 link_id, int show_errors)
+{
+ struct ieee80211_eht_ml *ml;
+ const u8 *pos;
+ ParseRes res = ParseFailed;
+
+ pos = wpabuf_head(mlbuf);
+ len = wpabuf_len(mlbuf);
+
+ /* must have control and common info length */
+ if (len < sizeof(*ml) + 1 || len < sizeof(*ml) + pos[sizeof(*ml)])
+ goto out;
+
+ ml = (struct ieee80211_eht_ml *)pos;
+
+ /* As we are interested with the Per-Sta profile, ignore other types */
+ if ((le_to_host16(ml->ml_control) & MULTI_LINK_CONTROL_TYPE_MASK) !=
+ MULTI_LINK_CONTROL_TYPE_BASIC)
+ goto out;
+
+ /* skip the common info */
+ len -= sizeof(*ml) + pos[sizeof(*ml)];
+ pos += sizeof(*ml) + pos[sizeof(*ml)];
+
+ while (len > 2) {
+ size_t sub_elem_len = *(pos + 1);
+ size_t sta_info_len;
+ u16 link_info_control;
+ const u8 *non_inherit;
+
+ wpa_printf(MSG_DEBUG,
+ "MLD: sub element: len=%zu, sub_elem_len=%zu",
+ len, sub_elem_len);
+
+ if (2 + sub_elem_len > len) {
+ if (show_errors)
+ wpa_printf(MSG_DEBUG,
+ "MLD: error: len=%zu, sub_elem_len=%zu",
+ len, sub_elem_len);
+ goto out;
+ }
+
+ if (*pos != 0) {
+ pos += 2 + sub_elem_len;
+ len -= 2 + sub_elem_len;
+ continue;
+ }
+
+ if (sub_elem_len < 3) {
+ if (show_errors)
+ wpa_printf(MSG_DEBUG,
+ "MLD: error: sub_elem_len=%zu < 5",
+ sub_elem_len);
+ goto out;
+ }
+
+ link_info_control = WPA_GET_LE16(pos + 2);
+ if ((link_info_control & BASIC_MLE_STA_CTRL_LINK_ID_MASK) !=
+ link_id) {
+ pos += 2 + sub_elem_len;
+ len -= 2 + sub_elem_len;
+ continue;
+ }
+
+ sta_info_len = *(pos + 4);
+ if (sub_elem_len < sta_info_len + 3) {
+ if (show_errors)
+ wpa_printf(MSG_DEBUG,
+ "MLD: error: sub_elem_len=%zu, sta_info_len=%zu",
+ sub_elem_len, sta_info_len);
+ goto out;
+ }
+
+ pos += sta_info_len + 4;
+ sub_elem_len -= sta_info_len + 2;
+
+ if (sub_elem_len < 2) {
+ if (show_errors)
+ wpa_printf(MSG_DEBUG,
+ "MLD: missing capability info");
+ goto out;
+ }
+
+ pos += 2;
+ sub_elem_len -= 2;
+
+ /* handle none inheritance */
+ non_inherit = get_ie_ext(pos, sub_elem_len,
+ WLAN_EID_EXT_NON_INHERITANCE);
+ if (non_inherit && non_inherit[1] > 1) {
+ u8 non_inherit_len = non_inherit[1] - 1;
+
+ /*
+ * Do not include the none inheritance element when
+ * parsing below. It should be the last element in the
+ * sub element.
+ */
+ sub_elem_len -= 3 + non_inherit_len;
+
+ /* skip the ID, length and extension ID */
+ non_inherit += 3;
+
+ if (non_inherit_len < 1UL + non_inherit[0]) {
+ if (show_errors)
+ wpa_printf(MSG_DEBUG,
+ "MLD: invalid inheritance");
+ goto out;
+ }
+
+ ieee802_11_elems_clear_ids(elems,
+ &non_inherit[1],
+ non_inherit[0]);
+
+ non_inherit_len -= 1 + non_inherit[0];
+ non_inherit += 1 + non_inherit[0];
+
+ if (non_inherit_len < 1UL + non_inherit[0]) {
+ if (show_errors)
+ wpa_printf(MSG_DEBUG,
+ "MLD: invalid inheritance");
+ goto out;
+ }
+
+ ieee802_11_elems_clear_ext_ids(elems,
+ &non_inherit[1],
+ non_inherit[0]);
+ }
+
+ wpa_printf(MSG_DEBUG, "MLD: link: sub_elem_len=%zu",
+ sub_elem_len);
+
+ if (sub_elem_len)
+ res = __ieee802_11_parse_elems(pos, sub_elem_len,
+ elems, show_errors);
+ else
+ res = ParseOK;
+ break;
+ }
+
+out:
+ return res;
+}
+
+
int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
{
const struct element *elem;
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index f4b17a55fb..949cab73d6 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -190,6 +190,10 @@ void ieee802_11_elems_clear_ids(struct ieee802_11_elems *elems,
const u8 *ids, size_t num);
void ieee802_11_elems_clear_ext_ids(struct ieee802_11_elems *elems,
const u8 *ids, size_t num);
+ParseRes ieee802_11_parse_link_assoc_req(const u8 *start, size_t len,
+ struct ieee802_11_elems *elems,
+ struct wpabuf *mlbuf,
+ u8 link_id, int show_errors);
int ieee802_11_ie_count(const u8 *ies, size_t ies_len);
struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
u32 oui_type);
--
2.38.1
More information about the Hostap
mailing list