]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Helper function for defragmenting of Multi-Link element subelements
authorPooventhiran G <quic_pooventh@quicinc.com>
Fri, 11 Apr 2025 11:28:31 +0000 (16:58 +0530)
committerJouni Malinen <j@w1.fi>
Sat, 12 Apr 2025 10:07:51 +0000 (13:07 +0300)
Subelements contained within an Multi-Link element can themselves be
fragmented if they pack more than 255 bytes of data using a Fragment
subelement similar to how the Multi-Link element uses a Fragment
element. Add a helper function to enable this nested defragmentation by
parsing subelements in a defragmented Multi-Link element.

Reviewed-by: Rohan Dutta <quic_drohan@quicinc.com>
Signed-off-by: Pooventhiran G <quic_pooventh@quicinc.com>
src/common/ieee802_11_common.c
src/common/ieee802_11_common.h

index 1d28437fe638325e51cb70cb8214a550f349fcc7..1adb08eaf49f0d760c426ae315501206ed5b840d 100644 (file)
@@ -3436,6 +3436,70 @@ struct wpabuf * ieee802_11_defrag(const u8 *data, size_t len, bool ext_elem)
 }
 
 
+/**
+ * ieee802_11_defrag_mle_subelem - Defragment Multi-Link element subelements
+ * @mlbuf: Defragmented mlbuf (defragmented using ieee802_11_defrag())
+ * @parent_subelem: Pointer to the subelement which may be fragmented
+ * @defrag_len: Defragmented length of the subelement
+ * Returns: Number of Fragment subelements parsed on success, -1 otherwise
+ *
+ * This function defragments a subelement present inside an Multi-Link element.
+ * It should be called individually for each subelement.
+ *
+ * Subelements can use the Fragment subelement if they pack more than 255 bytes
+ * of data, see IEEE P802.11be/D7.0 Figure 35-4 - Per-STA Profile subelement
+ * fragmentation within a fragmented Multi-Link element.
+ */
+size_t ieee802_11_defrag_mle_subelem(struct wpabuf *mlbuf,
+                                    const u8 *parent_subelem,
+                                    size_t *defrag_len)
+{
+       u8 *buf, *pos, *end;
+       size_t len, subelem_len;
+       const size_t min_defrag_len = 255;
+       int num_frag_subelems = 0;
+
+       if (!mlbuf || !parent_subelem)
+               return -1;
+
+       buf = wpabuf_mhead_u8(mlbuf);
+       len = wpabuf_len(mlbuf);
+       end = buf + len;
+
+       *defrag_len = parent_subelem[1];
+       if (parent_subelem[1] < min_defrag_len)
+               return 0;
+
+       pos = (u8 *) parent_subelem;
+       if (2 + parent_subelem[1] > end - pos)
+               return -1;
+       pos += 2 + parent_subelem[1];
+       subelem_len = parent_subelem[1];
+
+       while (end - pos > 2 &&
+              pos[0] == MULTI_LINK_SUB_ELEM_ID_FRAGMENT && pos[1]) {
+               size_t elen = 2 + pos[1];
+
+               /* This Multi-Link parent subelement has more data and is
+                * fragmented. */
+               num_frag_subelems++;
+
+               if (elen > (size_t) (end - pos))
+                       return -1;
+
+               os_memmove(pos, pos + 2, end - (pos + 2));
+               pos += elen - 2;
+               subelem_len += elen - 2;
+
+               /* Deduct Fragment subelement header */
+               len -= 2;
+       }
+
+       *defrag_len = subelem_len;
+       return num_frag_subelems;
+}
+
+
 const u8 * get_ml_ie(const u8 *ies, size_t len, u8 type)
 {
        const struct element *elem;
index 0edd34c653bf9e75e03a00f342ac304f7d698572..abd17f0628c43ca80ce7274d28fba53a886bfe30 100644 (file)
@@ -378,6 +378,9 @@ int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,
                            struct ieee80211_edmg_config requested);
 
 struct wpabuf * ieee802_11_defrag(const u8 *data, size_t len, bool ext_elem);
+size_t ieee802_11_defrag_mle_subelem(struct wpabuf *mlbuf,
+                                    const u8 *parent_subelem,
+                                    size_t *defrag_len);
 const u8 * get_ml_ie(const u8 *ies, size_t len, u8 type);
 const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len);