]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Multi-AP: Parse the Multi-AP element using a shared helper function
authorManoj Sekar <quic_sekar@quicinc.com>
Mon, 26 Feb 2024 12:48:21 +0000 (18:18 +0530)
committerJouni Malinen <j@w1.fi>
Tue, 19 Mar 2024 16:53:42 +0000 (18:53 +0200)
This makes it more convenient to handle extensions to the element and
allows code to be shared between hostapd and wpa_supplicant.

Signed-off-by: Manoj Sekar <quic_sekar@quicinc.com>
src/ap/ieee802_11.c
src/common/ieee802_11_common.c
src/common/ieee802_11_common.h
wpa_supplicant/events.c

index 77553dc6119b09fa1c981604c04426f95362f380..463d904e384957c6be341990f32448167948125f 100644 (file)
@@ -3416,37 +3416,26 @@ static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta,
 static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
                          const u8 *multi_ap_ie, size_t multi_ap_len)
 {
-       u8 multi_ap_value = 0;
+       struct multi_ap_params multi_ap;
+       u16 status;
 
        sta->flags &= ~WLAN_STA_MULTI_AP;
 
        if (!hapd->conf->multi_ap)
                return WLAN_STATUS_SUCCESS;
 
-       if (multi_ap_ie) {
-               const u8 *multi_ap_subelem;
-
-               multi_ap_subelem = get_ie(multi_ap_ie + 4,
-                                         multi_ap_len - 4,
-                                         MULTI_AP_SUB_ELEM_TYPE);
-               if (multi_ap_subelem && multi_ap_subelem[1] == 1) {
-                       multi_ap_value = multi_ap_subelem[2];
-               } else {
-                       hostapd_logger(hapd, sta->addr,
-                                      HOSTAPD_MODULE_IEEE80211,
-                                      HOSTAPD_LEVEL_INFO,
-                                      "Multi-AP IE has missing or invalid Multi-AP subelement");
-                       return WLAN_STATUS_INVALID_IE;
-               }
-       }
+       status = check_multi_ap_ie(multi_ap_ie + 4, multi_ap_len - 4,
+                                  &multi_ap);
+       if (status != WLAN_STATUS_SUCCESS)
+               return status;
 
-       if (multi_ap_value && multi_ap_value != MULTI_AP_BACKHAUL_STA)
+       if (multi_ap.capability && multi_ap.capability != MULTI_AP_BACKHAUL_STA)
                hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
                               HOSTAPD_LEVEL_INFO,
                               "Multi-AP IE with unexpected value 0x%02x",
-                              multi_ap_value);
+                              multi_ap.capability);
 
-       if (!(multi_ap_value & MULTI_AP_BACKHAUL_STA)) {
+       if (!(multi_ap.capability & MULTI_AP_BACKHAUL_STA)) {
                if (hapd->conf->multi_ap & FRONTHAUL_BSS)
                        return WLAN_STATUS_SUCCESS;
 
index 8bde67f26d482f4561d0ed1768234cdcd84688ea..38f27644635c096e476db22ba76aa99a1d842b59 100644 (file)
@@ -2571,6 +2571,54 @@ size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
 }
 
 
+u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len,
+                     struct multi_ap_params *multi_ap)
+{
+       const struct element *elem;
+       bool ext_present = false;
+
+       os_memset(multi_ap, 0, sizeof(*multi_ap));
+
+       for_each_element(elem, multi_ap_ie, multi_ap_len) {
+               u8 id = elem->id, elen = elem->datalen;
+               const u8 *pos = elem->data;
+
+               switch (id) {
+               case MULTI_AP_SUB_ELEM_TYPE:
+                       if (elen >= 1) {
+                               multi_ap->capability = *pos;
+                               ext_present = true;
+                       } else {
+                               wpa_printf(MSG_DEBUG,
+                                          "Multi-AP invalid Multi-AP subelement");
+                               return WLAN_STATUS_INVALID_IE;
+                       }
+                       break;
+               default:
+                       wpa_printf(MSG_DEBUG,
+                                  "Ignore unknown subelement %u in Multi-AP IE",
+                                  id);
+                       break;
+               }
+       }
+
+       if (!for_each_element_completed(elem, multi_ap_ie, multi_ap_len)) {
+               wpa_printf(MSG_DEBUG, "Multi AP IE parse failed @%d",
+                          (int) (multi_ap_ie + multi_ap_len -
+                                 (const u8 *) elem));
+               wpa_hexdump(MSG_MSGDUMP, "IEs", multi_ap_ie, multi_ap_len);
+       }
+
+       if (!ext_present) {
+               wpa_printf(MSG_DEBUG,
+                          "Multi-AP element without Multi-AP Extension subelement");
+               return WLAN_STATUS_INVALID_IE;
+       }
+
+       return WLAN_STATUS_SUCCESS;
+}
+
+
 size_t add_multi_ap_ie(u8 *buf, size_t len,
                       const struct multi_ap_params *multi_ap)
 {
index 4eba7109763bfd320fd9fbd53b9d1c3675efbff7..d038d210b9c8f0817471f1117832559035930af0 100644 (file)
@@ -271,6 +271,8 @@ const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type);
 
 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
 
+u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len,
+                     struct multi_ap_params *multi_ap);
 size_t add_multi_ap_ie(u8 *buf, size_t len,
                       const struct multi_ap_params *multi_ap);
 
index 78bd2a1e4a8bce4fc597d96a2d63fb0dc419ea9e..f9ee7c0b6d26f6205cabbe008baab2220bb8a107 100644 (file)
@@ -2996,25 +2996,24 @@ static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
                                        const u8 *ies, size_t ies_len)
 {
        struct ieee802_11_elems elems;
-       const u8 *map_sub_elem, *pos;
-       size_t len;
+       struct multi_ap_params multi_ap;
+       u16 status;
 
        wpa_s->multi_ap_ie = 0;
 
        if (!ies ||
            ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed ||
-           !elems.multi_ap || elems.multi_ap_len < 7)
+           !elems.multi_ap)
                return;
 
-       pos = elems.multi_ap + 4;
-       len = elems.multi_ap_len - 4;
-
-       map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE);
-       if (!map_sub_elem || map_sub_elem[1] < 1)
+       status = check_multi_ap_ie(elems.multi_ap + 4, elems.multi_ap_len - 4,
+                                  &multi_ap);
+       if (status != WLAN_STATUS_SUCCESS)
                return;
 
-       wpa_s->multi_ap_backhaul = !!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS);
-       wpa_s->multi_ap_fronthaul = !!(map_sub_elem[2] &
+       wpa_s->multi_ap_backhaul = !!(multi_ap.capability &
+                                     MULTI_AP_BACKHAUL_BSS);
+       wpa_s->multi_ap_fronthaul = !!(multi_ap.capability &
                                       MULTI_AP_FRONTHAUL_BSS);
        wpa_s->multi_ap_ie = 1;
 }