wlantest: Initial support for Multiple BSSID procedure
Parse the Multiple BSSID element in Beacon frames and create and update all the nontransmitted BSSs. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
1b96745f1d
commit
2829f1c439
3 changed files with 117 additions and 0 deletions
|
@ -607,6 +607,12 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len,
|
||||||
elems->rrm_enabled = pos;
|
elems->rrm_enabled = pos;
|
||||||
elems->rrm_enabled_len = elen;
|
elems->rrm_enabled_len = elen;
|
||||||
break;
|
break;
|
||||||
|
case WLAN_EID_MULTIPLE_BSSID:
|
||||||
|
if (elen < 1)
|
||||||
|
break;
|
||||||
|
elems->mbssid = pos;
|
||||||
|
elems->mbssid_len = elen;
|
||||||
|
break;
|
||||||
case WLAN_EID_CAG_NUMBER:
|
case WLAN_EID_CAG_NUMBER:
|
||||||
elems->cag_number = pos;
|
elems->cag_number = pos;
|
||||||
elems->cag_number_len = elen;
|
elems->cag_number_len = elen;
|
||||||
|
|
|
@ -115,6 +115,7 @@ struct ieee802_11_elems {
|
||||||
const u8 *tdls_mle;
|
const u8 *tdls_mle;
|
||||||
const u8 *prior_access_mle;
|
const u8 *prior_access_mle;
|
||||||
const u8 *mbssid_known_bss;
|
const u8 *mbssid_known_bss;
|
||||||
|
const u8 *mbssid;
|
||||||
|
|
||||||
u8 ssid_len;
|
u8 ssid_len;
|
||||||
u8 supp_rates_len;
|
u8 supp_rates_len;
|
||||||
|
@ -177,6 +178,7 @@ struct ieee802_11_elems {
|
||||||
size_t tdls_mle_len;
|
size_t tdls_mle_len;
|
||||||
size_t prior_access_mle_len;
|
size_t prior_access_mle_len;
|
||||||
u8 mbssid_known_bss_len;
|
u8 mbssid_known_bss_len;
|
||||||
|
u8 mbssid_len;
|
||||||
|
|
||||||
struct mb_ies_info mb_ies;
|
struct mb_ies_info mb_ies;
|
||||||
|
|
||||||
|
|
|
@ -439,6 +439,115 @@ static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
|
||||||
if (!bss->proberesp_seen)
|
if (!bss->proberesp_seen)
|
||||||
bss_update(wt, bss, &elems, 1);
|
bss_update(wt, bss, &elems, 1);
|
||||||
|
|
||||||
|
if (elems.mbssid) {
|
||||||
|
const u8 *pos = elems.mbssid;
|
||||||
|
const u8 *end = elems.mbssid + elems.mbssid_len;
|
||||||
|
u8 max_bss = *pos++;
|
||||||
|
|
||||||
|
while (end - pos > 2) {
|
||||||
|
u8 s_id, s_len, ssid_len, bssid_idx;
|
||||||
|
const u8 *s_data, *ssid;
|
||||||
|
u16 capa;
|
||||||
|
u8 bssid[ETH_ALEN], b;
|
||||||
|
struct ieee802_11_elems m_elems, merged;
|
||||||
|
struct wlantest_bss *m_bss;
|
||||||
|
|
||||||
|
s_id = *pos++;
|
||||||
|
s_len = *pos++;
|
||||||
|
|
||||||
|
if (end - pos < s_len)
|
||||||
|
break;
|
||||||
|
s_data = pos;
|
||||||
|
pos += s_len;
|
||||||
|
|
||||||
|
if (s_id !=
|
||||||
|
WLAN_MBSSID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Nontransmitted BSSID Capability element */
|
||||||
|
if (pos - s_data < 4 ||
|
||||||
|
s_data[0] != WLAN_EID_NONTRANSMITTED_BSSID_CAPA ||
|
||||||
|
s_data[1] < 2)
|
||||||
|
continue;
|
||||||
|
capa = WPA_GET_LE16(&s_data[2]);
|
||||||
|
s_data += 2 + s_data[1];
|
||||||
|
|
||||||
|
/* SSID element */
|
||||||
|
if (pos - s_data < 2 ||
|
||||||
|
s_data[0] != WLAN_EID_SSID)
|
||||||
|
continue;
|
||||||
|
ssid = &s_data[2];
|
||||||
|
ssid_len = s_data[1];
|
||||||
|
s_data += 2 + s_data[1];
|
||||||
|
|
||||||
|
/* Multiple BSSID-Index element */
|
||||||
|
if (pos - s_data < 3 ||
|
||||||
|
s_data[0] != WLAN_EID_MULTIPLE_BSSID_INDEX)
|
||||||
|
continue;
|
||||||
|
bssid_idx = s_data[2];
|
||||||
|
s_data += 2 + s_data[1];
|
||||||
|
|
||||||
|
if (max_bss < 1 || max_bss > 8)
|
||||||
|
break;
|
||||||
|
os_memcpy(bssid, mgmt->bssid, ETH_ALEN);
|
||||||
|
b = bssid[5] % (1 << max_bss);
|
||||||
|
bssid[5] = bssid[5] - b +
|
||||||
|
(b + bssid_idx) % (1 << max_bss);
|
||||||
|
wpa_printf(MSG_MSGDUMP, "MBSSID: " MACSTR
|
||||||
|
" Capa 0x%x idx=%u MaxBSSID Indicator=%u",
|
||||||
|
MAC2STR(bssid), capa, bssid_idx, max_bss);
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_MSGDUMP, "MBSSID: SSID",
|
||||||
|
ssid, ssid_len);
|
||||||
|
|
||||||
|
/* Rest of the elements */
|
||||||
|
wpa_hexdump(MSG_MSGDUMP, "MBSSID: Elements",
|
||||||
|
s_data, pos - s_data);
|
||||||
|
if (ieee802_11_parse_elems(s_data, pos - s_data,
|
||||||
|
&m_elems,
|
||||||
|
0) == ParseFailed) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MBSSID: Failed to parse nontransmitted BSS elements");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Noninheritance and rest of elements */
|
||||||
|
os_memcpy(&merged, &elems, sizeof(merged));
|
||||||
|
merged.ssid = ssid;
|
||||||
|
merged.ssid_len = ssid_len;
|
||||||
|
|
||||||
|
m_bss = bss_get(wt, bssid);
|
||||||
|
if (!m_bss)
|
||||||
|
continue;
|
||||||
|
if (!m_bss->proberesp_seen)
|
||||||
|
m_bss->capab_info = capa;
|
||||||
|
|
||||||
|
if (m_elems.basic_mle) {
|
||||||
|
merged.basic_mle = m_elems.basic_mle;
|
||||||
|
merged.basic_mle_len = m_elems.basic_mle_len;
|
||||||
|
}
|
||||||
|
if (m_elems.rsn_ie) {
|
||||||
|
merged.rsn_ie = m_elems.rsn_ie;
|
||||||
|
merged.rsn_ie_len = m_elems.rsn_ie_len;
|
||||||
|
}
|
||||||
|
if (m_elems.rsnxe) {
|
||||||
|
merged.rsnxe = m_elems.rsnxe;
|
||||||
|
merged.rsnxe_len = m_elems.rsnxe_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (merged.rsnxe) {
|
||||||
|
os_memcpy(m_bss->rsnxe, merged.rsnxe,
|
||||||
|
merged.rsnxe_len);
|
||||||
|
m_bss->rsnxe_len = merged.rsnxe_len;
|
||||||
|
} else {
|
||||||
|
m_bss->rsnxe_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_bss->proberesp_seen)
|
||||||
|
bss_update(wt, m_bss, &merged, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mme = get_ie(mgmt->u.beacon.variable, len - offset, WLAN_EID_MMIE);
|
mme = get_ie(mgmt->u.beacon.variable, len - offset, WLAN_EID_MMIE);
|
||||||
if (!mme) {
|
if (!mme) {
|
||||||
if (bss->bigtk_idx) {
|
if (bss->bigtk_idx) {
|
||||||
|
|
Loading…
Reference in a new issue