From: Jouni Malinen Date: Thu, 31 Aug 2023 12:02:02 +0000 (+0300) Subject: wlantest: Determine whether A1 points to STA once in rx_data_bss_prot() X-Git-Tag: hostap_2_11~1000 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=770e5a808fbb5c8f91ef942c364628c71e6960b0;p=thirdparty%2Fhostap.git wlantest: Determine whether A1 points to STA once in rx_data_bss_prot() Use the initial BSS/STA routines to determine whether A1 points to STA instead of maintaining multiple somewhat different ways of doing this. In addition to making the code easier to maintain, this fixes at least some cases where incorrect tx/rx_tid or rsc_tods/fromds value was selected for 4-address frames. Signed-off-by: Jouni Malinen --- diff --git a/wlantest/rx_data.c b/wlantest/rx_data.c index 0f421d72f..6dc32cf8f 100644 --- a/wlantest/rx_data.c +++ b/wlantest/rx_data.c @@ -376,21 +376,6 @@ skip_replay_det: } -static bool is_sta_link_addr(struct wlantest_sta *sta, const u8 *addr) -{ - unsigned int link_id; - - if (os_memcmp(addr, sta->addr, ETH_ALEN) == 0) - return true; - for (link_id = 0; link_id < MAX_NUM_MLO_LINKS; link_id++) { - if (os_memcmp(sta->link_addr[link_id], addr, ETH_ALEN) == 0) - return true; - } - - return false; -} - - static u8 * try_ptk_decrypt(struct wlantest *wt, struct wlantest_sta *sta, const struct ieee80211_hdr *hdr, const u8 *a1, const u8 *a2, const u8 *a3, @@ -436,6 +421,7 @@ static void rx_data_bss_prot(struct wlantest *wt, int only_zero_tk = 0; u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); const u8 *a1 = NULL, *a2 = NULL, *a3 = NULL; + enum { NO, YES, UNKNOWN } a1_is_sta = UNKNOWN; if (hdr->addr1[0] & 0x01) { rx_data_bss_prot_group(wt, hdr, hdrlen, qos, dst, src, @@ -449,6 +435,7 @@ static void rx_data_bss_prot(struct wlantest *wt, if (bss) { sta = sta_find_mlo(wt, bss, hdr->addr2); if (sta) { + a1_is_sta = NO; sta->counters[ WLANTEST_STA_COUNTER_PROT_DATA_TX]++; } @@ -458,6 +445,7 @@ static void rx_data_bss_prot(struct wlantest *wt, sta2 = sta_find_mlo(wt, bss2, hdr->addr1); if (sta2 && (!sta || sta2->ptk_set)) { + a1_is_sta = YES; bss = bss2; sta = sta2; } @@ -468,6 +456,8 @@ static void rx_data_bss_prot(struct wlantest *wt, if (!bss) return; sta = sta_find_mlo(wt, bss, hdr->addr1); + if (sta) + a1_is_sta = YES; } } else if (fc & WLAN_FC_TODS) { bss = bss_get(wt, hdr->addr1); @@ -478,6 +468,7 @@ static void rx_data_bss_prot(struct wlantest *wt, sta = sta_get(bss, hdr->addr2); if (sta) sta->counters[WLANTEST_STA_COUNTER_PROT_DATA_TX]++; + a1_is_sta = NO; } else if (fc & WLAN_FC_FROMDS) { bss = bss_get(wt, hdr->addr2); if (bss == NULL) @@ -485,6 +476,8 @@ static void rx_data_bss_prot(struct wlantest *wt, sta = sta_find_mlo(wt, bss, hdr->addr1); if (!sta) sta = sta_get(bss, hdr->addr1); + if (sta) + a1_is_sta = YES; } else { bss = bss_get(wt, hdr->addr3); if (bss == NULL) @@ -583,13 +576,13 @@ static void rx_data_bss_prot(struct wlantest *wt, if (qos) { tid = qos[0] & 0x0f; - if (fc & WLAN_FC_TODS) + if (a1_is_sta == NO) sta->tx_tid[tid]++; else sta->rx_tid[tid]++; } else { tid = 0; - if (fc & WLAN_FC_TODS) + if (a1_is_sta == NO) sta->tx_tid[16]++; else sta->rx_tid[16]++; @@ -601,11 +594,11 @@ static void rx_data_bss_prot(struct wlantest *wt, rsc = tdls->rsc_resp[tid]; } else if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == (WLAN_FC_TODS | WLAN_FC_FROMDS)) { - if (os_memcmp(sta->addr, hdr->addr2, ETH_ALEN) == 0) + if (a1_is_sta == NO) rsc = sta->rsc_tods[tid]; else rsc = sta->rsc_fromds[tid]; - } else if (fc & WLAN_FC_TODS) + } else if (a1_is_sta == NO) rsc = sta->rsc_tods[tid]; else rsc = sta->rsc_fromds[tid]; @@ -638,8 +631,9 @@ static void rx_data_bss_prot(struct wlantest *wt, skip_replay_det: if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) && !is_zero_ether_addr(sta->mld_mac_addr) && - !is_zero_ether_addr(bss->mld_mac_addr)) { - if (is_sta_link_addr(sta, hdr->addr1)) { + !is_zero_ether_addr(bss->mld_mac_addr) && + a1_is_sta != UNKNOWN) { + if (a1_is_sta == YES) { a1 = sta->mld_mac_addr; a2 = bss->mld_mac_addr; } else {