wlantest: Defragment Basic MLE before processing

The Basic Multi-Link element is going to be fragmented in many cases, so
defragment it first before trying to parse it.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
Jouni Malinen 2023-09-01 18:29:18 +03:00 committed by Jouni Malinen
parent 528abdeb67
commit 990600753d

View file

@ -61,10 +61,11 @@ static const char * mgmt_stype(u16 stype)
static void parse_basic_ml(const u8 *ie, size_t len, bool ap, static void parse_basic_ml(const u8 *ie, size_t len, bool ap,
struct wlantest_sta *sta) struct wlantest_sta *sta)
{ {
const u8 *pos, *end, *ci_end, *info_end; const u8 *pos, *end, *ci_end, *info_end, *li_end;
u16 ctrl, eml, cap; u16 ctrl, eml, cap;
const struct element *elem; const struct element *elem;
wpa_hexdump(MSG_MSGDUMP, "Basic MLE", ie, len);
pos = ie; pos = ie;
end = ie + len; end = ie + len;
@ -97,6 +98,7 @@ static void parse_basic_ml(const u8 *ie, size_t len, bool ap,
ci_end = pos + len; ci_end = pos + len;
pos++; pos++;
wpa_hexdump(MSG_MSGDUMP, "Basic MLE - Common Info", pos, ci_end - pos);
wpa_printf(MSG_DEBUG, "MLD MAC Address: " MACSTR, MAC2STR(pos)); wpa_printf(MSG_DEBUG, "MLD MAC Address: " MACSTR, MAC2STR(pos));
if (!ap && sta && is_zero_ether_addr(sta->mld_mac_addr)) { if (!ap && sta && is_zero_ether_addr(sta->mld_mac_addr)) {
os_memcpy(sta->mld_mac_addr, pos, ETH_ALEN); os_memcpy(sta->mld_mac_addr, pos, ETH_ALEN);
@ -202,8 +204,10 @@ static void parse_basic_ml(const u8 *ie, size_t len, bool ap,
} }
/* Link Info */ /* Link Info */
wpa_hexdump(MSG_MSGDUMP, "Basic MLE - Link Info", pos, end - pos);
for_each_element(elem, pos, end - pos) { li_end = end;
for_each_element(elem, pos, li_end - pos) {
u8 link_id; u8 link_id;
if (elem->id != EHT_ML_SUB_ELEM_PER_STA_PROFILE) { if (elem->id != EHT_ML_SUB_ELEM_PER_STA_PROFILE) {
@ -222,6 +226,8 @@ static void parse_basic_ml(const u8 *ie, size_t len, bool ap,
"Truncated Per-STA Profile subelement"); "Truncated Per-STA Profile subelement");
continue; continue;
} }
wpa_hexdump(MSG_MSGDUMP, "Basic MLE - Per-STA Profile",
pos, end - pos);
ctrl = WPA_GET_LE16(pos); ctrl = WPA_GET_LE16(pos);
pos += 2; pos += 2;
@ -338,6 +344,19 @@ static void parse_basic_ml(const u8 *ie, size_t len, bool ap,
} }
static void parse_basic_ml_elems(struct ieee802_11_elems *elems, bool ap,
struct wlantest_sta *sta)
{
struct wpabuf *mlbuf;
mlbuf = ieee802_11_defrag_mle(elems, MULTI_LINK_CONTROL_TYPE_BASIC);
if (mlbuf) {
parse_basic_ml(wpabuf_head(mlbuf), wpabuf_len(mlbuf), ap, sta);
wpabuf_free(mlbuf);
}
}
static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len) static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
{ {
const struct ieee80211_mgmt *mgmt; const struct ieee80211_mgmt *mgmt;
@ -553,8 +572,7 @@ static void process_ft_auth(struct wlantest *wt, struct wlantest_bss *bss,
if (trans == 1) { if (trans == 1) {
if (elems.basic_mle) if (elems.basic_mle)
parse_basic_ml(elems.basic_mle, elems.basic_mle_len, parse_basic_ml_elems(&elems, false, sta);
false, sta);
sta->key_mgmt = parse.key_mgmt; sta->key_mgmt = parse.key_mgmt;
sta->pairwise_cipher = parse.pairwise_cipher; sta->pairwise_cipher = parse.pairwise_cipher;
if (parse.fte_snonce) if (parse.fte_snonce)
@ -1040,8 +1058,7 @@ static void rx_mgmt_assoc_req(struct wlantest *wt, const u8 *data, size_t len)
" from Association Request (assoc link)", " from Association Request (assoc link)",
bss->link_id, MAC2STR(mgmt->sa)); bss->link_id, MAC2STR(mgmt->sa));
} }
parse_basic_ml(elems.basic_mle, elems.basic_mle_len, false, parse_basic_ml_elems(&elems, false, sta);
sta);
dump_mld_info(wt, sta); dump_mld_info(wt, sta);
} }
} }
@ -1145,8 +1162,9 @@ static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
aid & 0x3fff); aid & 0x3fff);
ml = get_ml_ie(ies, ies_len, MULTI_LINK_CONTROL_TYPE_BASIC); ml = get_ml_ie(ies, ies_len, MULTI_LINK_CONTROL_TYPE_BASIC);
if (ml) if (ml &&
parse_basic_ml(ml + 3, ml[1], true, NULL); ieee802_11_parse_elems(ies, ies_len, &elems, 0) != ParseFailed)
parse_basic_ml_elems(&elems, true, NULL);
if (sta->auth_alg == WLAN_AUTH_FILS_SK) { if (sta->auth_alg == WLAN_AUTH_FILS_SK) {
const u8 *session, *frame_ad, *frame_ad_end, *encr_end; const u8 *session, *frame_ad, *frame_ad_end, *encr_end;
@ -1344,8 +1362,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data,
" from Reassociation Request (assoc link)", " from Reassociation Request (assoc link)",
bss->link_id, MAC2STR(mgmt->sa)); bss->link_id, MAC2STR(mgmt->sa));
} }
parse_basic_ml(elems.basic_mle, elems.basic_mle_len, false, parse_basic_ml_elems(&elems, false, sta);
sta);
dump_mld_info(wt, sta); dump_mld_info(wt, sta);
} }
@ -1905,8 +1922,9 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
aid & 0x3fff); aid & 0x3fff);
ml = get_ml_ie(ies, ies_len, MULTI_LINK_CONTROL_TYPE_BASIC); ml = get_ml_ie(ies, ies_len, MULTI_LINK_CONTROL_TYPE_BASIC);
if (ml) if (ml &&
parse_basic_ml(ml + 3, ml[1], true, NULL); ieee802_11_parse_elems(ies, ies_len, &elems, 0) != ParseFailed)
parse_basic_ml_elems(&elems, true, NULL);
if (sta->auth_alg == WLAN_AUTH_FILS_SK) { if (sta->auth_alg == WLAN_AUTH_FILS_SK) {
const u8 *session, *frame_ad, *frame_ad_end, *encr_end; const u8 *session, *frame_ad, *frame_ad_end, *encr_end;