wlantest: Skip Mesh Control field from the beginning of payload
This allows correct processing of Data frames with Mesh Control field by finding the LLC/SNAP header after that field. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
503901e72d
commit
e90ededb4b
3 changed files with 42 additions and 8 deletions
|
@ -227,6 +227,8 @@ void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
|
||||||
if (elems->mdie)
|
if (elems->mdie)
|
||||||
os_memcpy(bss->mdid, elems->mdie, 2);
|
os_memcpy(bss->mdid, elems->mdie, 2);
|
||||||
|
|
||||||
|
bss->mesh = elems->mesh_id != NULL;
|
||||||
|
|
||||||
if (!update)
|
if (!update)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -99,15 +99,46 @@ static void rx_data_eth(struct wlantest *wt, const u8 *bssid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void rx_data_process(struct wlantest *wt, const u8 *bssid,
|
static void rx_data_process(struct wlantest *wt, struct wlantest_bss *bss,
|
||||||
|
const u8 *bssid,
|
||||||
const u8 *sta_addr,
|
const u8 *sta_addr,
|
||||||
const u8 *dst, const u8 *src,
|
const u8 *dst, const u8 *src,
|
||||||
const u8 *data, size_t len, int prot,
|
const u8 *data, size_t len, int prot,
|
||||||
const u8 *peer_addr)
|
const u8 *peer_addr, const u8 *qos)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (bss && bss->mesh && qos && !(qos[0] & BIT(7)) &&
|
||||||
|
(qos[1] & BIT(0))) {
|
||||||
|
u8 addr_ext_mode;
|
||||||
|
size_t mesh_control_len = 6;
|
||||||
|
|
||||||
|
/* Skip Mesh Control field if this is not an A-MSDU */
|
||||||
|
if (len < mesh_control_len) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"Not enough room for Mesh Control field");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_ext_mode = data[0] & 0x03;
|
||||||
|
if (addr_ext_mode == 3) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"Reserved Mesh Control :: Address Extension Mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh_control_len += addr_ext_mode * ETH_ALEN;
|
||||||
|
if (len < mesh_control_len) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"Not enough room for Mesh Address Extension");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len -= mesh_control_len;
|
||||||
|
data += mesh_control_len;
|
||||||
|
}
|
||||||
|
|
||||||
if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
|
if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
|
||||||
rx_data_eth(wt, bssid, sta_addr, dst, src,
|
rx_data_eth(wt, bssid, sta_addr, dst, src,
|
||||||
WPA_GET_BE16(data + 6), data + 8, len - 8, prot,
|
WPA_GET_BE16(data + 6), data + 8, len - 8, prot,
|
||||||
|
@ -310,8 +341,8 @@ skip_replay_det:
|
||||||
bss->gtk_len[keyid]);
|
bss->gtk_len[keyid]);
|
||||||
add_note(wt, MSG_EXCESSIVE, "GTK[%d] %s", keyid, gtk);
|
add_note(wt, MSG_EXCESSIVE, "GTK[%d] %s", keyid, gtk);
|
||||||
process:
|
process:
|
||||||
rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted,
|
rx_data_process(wt, bss, bss->bssid, NULL, dst, src, decrypted,
|
||||||
dlen, 1, NULL);
|
dlen, 1, NULL, qos);
|
||||||
if (!replay)
|
if (!replay)
|
||||||
os_memcpy(bss->rsc[keyid], pn, 6);
|
os_memcpy(bss->rsc[keyid], pn, 6);
|
||||||
write_pcap_decrypted(wt, (const u8 *) hdr, hdrlen,
|
write_pcap_decrypted(wt, (const u8 *) hdr, hdrlen,
|
||||||
|
@ -622,8 +653,8 @@ check_zero_tk:
|
||||||
peer_addr = hdr->addr1;
|
peer_addr = hdr->addr1;
|
||||||
if (!replay && rsc)
|
if (!replay && rsc)
|
||||||
os_memcpy(rsc, pn, 6);
|
os_memcpy(rsc, pn, 6);
|
||||||
rx_data_process(wt, bss->bssid, sta->addr, dst, src, decrypted,
|
rx_data_process(wt, bss, bss->bssid, sta->addr, dst, src,
|
||||||
dlen, 1, peer_addr);
|
decrypted, dlen, 1, peer_addr, qos);
|
||||||
write_pcap_decrypted(wt, (const u8 *) hdr, hdrlen,
|
write_pcap_decrypted(wt, (const u8 *) hdr, hdrlen,
|
||||||
decrypted, dlen);
|
decrypted, dlen);
|
||||||
} else if (sta->tptk_set) {
|
} else if (sta->tptk_set) {
|
||||||
|
@ -726,8 +757,8 @@ static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rx_data_process(wt, bssid, sta_addr, dst, src, data, len, 0,
|
rx_data_process(wt, bss, bssid, sta_addr, dst, src, data, len,
|
||||||
peer_addr);
|
0, peer_addr, qos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,7 @@ struct wlantest_bss {
|
||||||
u8 r0kh_id[FT_R0KH_ID_MAX_LEN];
|
u8 r0kh_id[FT_R0KH_ID_MAX_LEN];
|
||||||
size_t r0kh_id_len;
|
size_t r0kh_id_len;
|
||||||
u8 r1kh_id[FT_R1KH_ID_LEN];
|
u8 r1kh_id[FT_R1KH_ID_LEN];
|
||||||
|
bool mesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlantest_radius {
|
struct wlantest_radius {
|
||||||
|
|
Loading…
Reference in a new issue