wlantest: Fix TDLS setup failure counting

Need to be able to handle TDLS Setup Response frame with LinkId IE
when non-zero status code is used. In addition, allow finding of a
TDLS entry based on real BSSID instead of the one used in the LinkId
to allow negative testing of different BSS.
This commit is contained in:
Jouni Malinen 2011-01-24 15:25:59 +02:00 committed by Jouni Malinen
parent 244c9303cb
commit 44a0486607

View file

@ -24,13 +24,22 @@
static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *linkid, static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *linkid,
int create_new) int create_new, const u8 *bssid)
{ {
struct wlantest_bss *bss; struct wlantest_bss *bss;
struct wlantest_sta *init, *resp; struct wlantest_sta *init, *resp;
struct wlantest_tdls *tdls; struct wlantest_tdls *tdls;
bss = bss_find(wt, linkid); bss = bss_find(wt, linkid);
if (bss == NULL && bssid) {
bss = bss_find(wt, bssid);
if (bss)
wpa_printf(MSG_INFO, "TDLS: Incorrect BSSID " MACSTR
" in LinkId?! (init=" MACSTR " resp="
MACSTR ")",
MAC2STR(linkid), MAC2STR(linkid + ETH_ALEN),
MAC2STR(linkid + 2 * ETH_ALEN));
}
if (bss == NULL) if (bss == NULL)
return NULL; return NULL;
@ -194,8 +203,11 @@ static void rx_data_tdls_setup_request(struct wlantest *wt, const u8 *bssid,
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
struct wlantest_tdls *tdls; struct wlantest_tdls *tdls;
if (len < 3) if (len < 3) {
wpa_printf(MSG_INFO, "Too short TDLS Setup Request " MACSTR
" -> " MACSTR, MAC2STR(src), MAC2STR(dst));
return; return;
}
wpa_printf(MSG_DEBUG, "TDLS Setup Request " MACSTR " -> " wpa_printf(MSG_DEBUG, "TDLS Setup Request " MACSTR " -> "
MACSTR, MAC2STR(src), MAC2STR(dst)); MACSTR, MAC2STR(src), MAC2STR(dst));
@ -206,9 +218,51 @@ static void rx_data_tdls_setup_request(struct wlantest *wt, const u8 *bssid,
" initiator STA " MACSTR " responder STA " MACSTR, " initiator STA " MACSTR " responder STA " MACSTR,
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN), MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
MAC2STR(elems.link_id + 2 * ETH_ALEN)); MAC2STR(elems.link_id + 2 * ETH_ALEN));
tdls = get_tdls(wt, elems.link_id, 1); tdls = get_tdls(wt, elems.link_id, 1, bssid);
if (tdls) if (tdls) {
tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_REQ]++; tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_REQ]++;
tdls->dialog_token = data[0];
}
}
static void rx_data_tdls_setup_response_failure(struct wlantest *wt,
const u8 *bssid,
const u8 *sta_addr,
u8 dialog_token, u16 status)
{
struct wlantest_bss *bss;
struct wlantest_tdls *tdls;
struct wlantest_sta *sta;
if (status == WLAN_STATUS_SUCCESS) {
wpa_printf(MSG_INFO, "TDLS: Invalid TDLS Setup Response from "
MACSTR, MAC2STR(sta_addr));
return;
}
bss = bss_find(wt, bssid);
if (!bss)
return;
sta = sta_find(bss, sta_addr);
if (!sta)
return;
dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
if (tdls->resp == sta) {
if (dialog_token != tdls->dialog_token) {
wpa_printf(MSG_DEBUG, "TDLS: Dialog token "
"mismatch in TDLS Setup Response "
"(failure)");
break;
}
wpa_printf(MSG_DEBUG, "TDLS: Found matching TDLS "
"setup session based on dialog token");
tdls->counters[
WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL]++;
break;
}
}
} }
@ -221,30 +275,44 @@ static void rx_data_tdls_setup_response(struct wlantest *wt, const u8 *bssid,
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
struct wlantest_tdls *tdls; struct wlantest_tdls *tdls;
if (len < 5) if (len < 3) {
wpa_printf(MSG_INFO, "Too short TDLS Setup Response " MACSTR
" -> " MACSTR, MAC2STR(src), MAC2STR(dst));
return; return;
}
status = WPA_GET_LE16(data); status = WPA_GET_LE16(data);
wpa_printf(MSG_DEBUG, "TDLS Setup Response " MACSTR " -> " wpa_printf(MSG_DEBUG, "TDLS Setup Response " MACSTR " -> "
MACSTR " (status %d)", MACSTR " (status %d)",
MAC2STR(src), MAC2STR(dst), status); MAC2STR(src), MAC2STR(dst), status);
if (status != WLAN_STATUS_SUCCESS) if (len < 5) {
wpa_printf(MSG_INFO, "Too short TDLS Setup Response " MACSTR
" -> " MACSTR, MAC2STR(src), MAC2STR(dst));
return; return;
}
if (ieee802_11_parse_elems(data + 5, len - 5, &elems, 1) == if (ieee802_11_parse_elems(data + 5, len - 5, &elems, 1) ==
ParseFailed || elems.link_id == NULL) ParseFailed || elems.link_id == NULL) {
/* Need to match TDLS link based on Dialog Token */
rx_data_tdls_setup_response_failure(wt, bssid, sta_addr,
data[2], status);
return; return;
}
wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
" initiator STA " MACSTR " responder STA " MACSTR, " initiator STA " MACSTR " responder STA " MACSTR,
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN), MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
MAC2STR(elems.link_id + 2 * ETH_ALEN)); MAC2STR(elems.link_id + 2 * ETH_ALEN));
tdls = get_tdls(wt, elems.link_id, 1); tdls = get_tdls(wt, elems.link_id, 1, bssid);
if (!tdls) if (!tdls)
return; return;
if (status) if (status)
tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL]++; tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL]++;
else else
tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_RESP_OK]++; tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_RESP_OK]++;
if (status != WLAN_STATUS_SUCCESS)
return;
if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1) if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1)
return; return;
if (tdls_verify_mic(tdls, 2, &elems) == 0) { if (tdls_verify_mic(tdls, 2, &elems) == 0) {
@ -265,8 +333,11 @@ static void rx_data_tdls_setup_confirm(struct wlantest *wt, const u8 *bssid,
struct wlantest_tdls *tdls; struct wlantest_tdls *tdls;
u8 link_id[3 * ETH_ALEN]; u8 link_id[3 * ETH_ALEN];
if (len < 3) if (len < 3) {
wpa_printf(MSG_INFO, "Too short TDLS Setup Confirm " MACSTR
" -> " MACSTR, MAC2STR(src), MAC2STR(dst));
return; return;
}
status = WPA_GET_LE16(data); status = WPA_GET_LE16(data);
wpa_printf(MSG_DEBUG, "TDLS Setup Confirm " MACSTR " -> " wpa_printf(MSG_DEBUG, "TDLS Setup Confirm " MACSTR " -> "
MACSTR " (status %d)", MACSTR " (status %d)",
@ -280,7 +351,7 @@ static void rx_data_tdls_setup_confirm(struct wlantest *wt, const u8 *bssid,
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN), MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
MAC2STR(elems.link_id + 2 * ETH_ALEN)); MAC2STR(elems.link_id + 2 * ETH_ALEN));
tdls = get_tdls(wt, elems.link_id, 1); tdls = get_tdls(wt, elems.link_id, 1, bssid);
if (tdls == NULL) if (tdls == NULL)
return; return;
if (status) if (status)
@ -313,7 +384,7 @@ remove_reverse:
os_memcpy(link_id, elems.link_id, ETH_ALEN); os_memcpy(link_id, elems.link_id, ETH_ALEN);
os_memcpy(link_id + ETH_ALEN, elems.link_id + 2 * ETH_ALEN, ETH_ALEN); os_memcpy(link_id + ETH_ALEN, elems.link_id + 2 * ETH_ALEN, ETH_ALEN);
os_memcpy(link_id + 2 * ETH_ALEN, elems.link_id + ETH_ALEN, ETH_ALEN); os_memcpy(link_id + 2 * ETH_ALEN, elems.link_id + ETH_ALEN, ETH_ALEN);
tdls = get_tdls(wt, link_id, 0); tdls = get_tdls(wt, link_id, 0, bssid);
if (tdls) { if (tdls) {
wpa_printf(MSG_DEBUG, "TDLS: Remove reverse link entry"); wpa_printf(MSG_DEBUG, "TDLS: Remove reverse link entry");
tdls_deinit(tdls); tdls_deinit(tdls);
@ -401,7 +472,7 @@ static void rx_data_tdls_teardown(struct wlantest *wt, const u8 *bssid,
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN), MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
MAC2STR(elems.link_id + 2 * ETH_ALEN)); MAC2STR(elems.link_id + 2 * ETH_ALEN));
tdls = get_tdls(wt, elems.link_id, 1); tdls = get_tdls(wt, elems.link_id, 1, bssid);
if (tdls) { if (tdls) {
tdls->link_up = 0; tdls->link_up = 0;
tdls_verify_mic_teardown(tdls, 4, data, &elems); tdls_verify_mic_teardown(tdls, 4, data, &elems);