]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add helper functions for parsing Basic MLE to fetch EML capa and Link ID
authorAbishek Ganapathy <abishekg@qti.qualcomm.com>
Thu, 30 Oct 2025 19:14:06 +0000 (00:44 +0530)
committerJouni Malinen <j@w1.fi>
Wed, 26 Nov 2025 10:41:56 +0000 (12:41 +0200)
Add helper functions to fetch the EML Capabilities field and the Link ID
Info field from a Basic Multi-Link element.

Co-developed-by: Rohan Dutta <drohan@qti.qualcomm.com>
Signed-off-by: Rohan Dutta <drohan@qti.qualcomm.com>
Signed-off-by: Abishek Ganapathy <abishekg@qti.qualcomm.com>
src/common/ieee802_11_common.c
src/common/ieee802_11_common.h
src/common/ieee802_11_defs.h

index 82a4c1f734c431fc9ff5aafb86a4e49684b2f993..a0b51c014f85067f7f1495b132c073fb8f88d2ee 100644 (file)
@@ -3562,3 +3562,83 @@ const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len)
 
        return &buf[mld_addr_pos];
 }
+
+
+const u8 * get_basic_mle_eml_capa(const u8 *buf, size_t len)
+{
+       const struct ieee80211_eht_ml *ml =
+               (const struct ieee80211_eht_ml *) buf;
+       u16 ctrl;
+       size_t eml_capa_pos =
+               MULTI_LINK_CONTROL_LEN + /* Multi-Link Control field */
+               1 + /* Common Info Length field (Basic) */
+               ETH_ALEN; /* MLD MAC Address field (Basic) */
+       size_t common_info_limit;
+       u8 common_info_len;
+
+       if (len < MULTI_LINK_CONTROL_LEN)
+               return NULL;
+
+       ctrl = le_to_host16(ml->ml_control);
+       if ((ctrl & MULTI_LINK_CONTROL_TYPE_MASK) !=
+           MULTI_LINK_CONTROL_TYPE_BASIC)
+               return NULL;
+       if (!(ctrl & BASIC_MULTI_LINK_CTRL_PRES_EML_CAPA))
+               return NULL;
+
+       /* Validate Common Info Length against available data */
+       common_info_len = buf[MULTI_LINK_CONTROL_LEN];
+       if (len < (size_t) MULTI_LINK_CONTROL_LEN + common_info_len)
+               return NULL;
+       common_info_limit = MULTI_LINK_CONTROL_LEN + common_info_len;
+
+       if (ctrl & BASIC_MULTI_LINK_CTRL_PRES_LINK_ID)
+               eml_capa_pos += EHT_ML_LINK_ID_LEN;
+
+       if (ctrl & BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT)
+               eml_capa_pos++;
+
+       if (ctrl & BASIC_MULTI_LINK_CTRL_PRES_MSD_INFO)
+               eml_capa_pos += 2;
+
+       /* Ensure EML Capabilities field fits within the declared Common Info */
+       if (eml_capa_pos + EHT_ML_EML_CAPA_LEN > common_info_limit)
+               return NULL;
+
+       return &buf[eml_capa_pos];
+}
+
+
+int get_basic_mle_link_id(const u8 *buf, size_t len)
+{
+       struct ieee80211_eht_ml *ml = (struct ieee80211_eht_ml *) buf;
+       u16 ctrl;
+       size_t link_id_pos =
+               MULTI_LINK_CONTROL_LEN + /* Multi-Link Control field */
+               1 + /* Common Info Length field (Basic) */
+               ETH_ALEN; /* MLD MAC Address field (Basic) */
+       size_t common_info_limit;
+       u8 common_info_len;
+
+       if (len < MULTI_LINK_CONTROL_LEN)
+               return -1;
+
+       ctrl = le_to_host16(ml->ml_control);
+       if ((ctrl & MULTI_LINK_CONTROL_TYPE_MASK) !=
+           MULTI_LINK_CONTROL_TYPE_BASIC)
+               return -1;
+
+       /* Validate Common Info Length against available data */
+       common_info_len = buf[MULTI_LINK_CONTROL_LEN];
+       if (len < (size_t) MULTI_LINK_CONTROL_LEN + common_info_len)
+               return -1;
+       common_info_limit = MULTI_LINK_CONTROL_LEN + common_info_len;
+
+       if (!(ctrl & BASIC_MULTI_LINK_CTRL_PRES_LINK_ID))
+               return -1;
+
+       if (link_id_pos + EHT_ML_LINK_ID_LEN > common_info_limit)
+               return -1;
+
+       return buf[link_id_pos] & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
+}
index 906c13854615d9cd8ab20ef9102c55a4f153e691..af011a35719777726c8465b81a0e091fa1920382 100644 (file)
@@ -387,5 +387,7 @@ size_t ieee802_11_defrag_mle_subelem(struct wpabuf *mlbuf,
                                     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);
+const u8 * get_basic_mle_eml_capa(const u8 *buf, size_t len);
+int get_basic_mle_link_id(const u8 *buf, size_t len);
 
 #endif /* IEEE802_11_COMMON_H */
index 1d803660caf58c568bc3dac7a5f7a845f81e7b6d..d969f05037cfde23af0a3de3c869a7beadd887b0 100644 (file)
@@ -2859,6 +2859,12 @@ struct eht_ml_basic_common_info {
        u8 variable[];
 } STRUCT_PACKED;
 
+/* Length of the EML Capabilities field in the Common Info field (in octets) */
+#define EHT_ML_EML_CAPA_LEN  2
+
+/* Length of the Link ID Info field in the Common Info field (in octets) */
+#define EHT_ML_LINK_ID_LEN  1
+
 #define EHT_ML_LINK_ID_MSK   0x0f
 
 #define EHT_ML_MEDIUM_SYNC_DELAY_DURATION   0x00ff