wlantest: Maintain only a single entry for an active direct link

The TDLS link itself is bidirectional, but there is explicit
initiator/responder roles. Remove the other direction of the link if it
exists when processing TDLS Setup Confirm to make sure that the link
counters are stored for the current TDLS entery.

This is also changing the control interface search for TDLS counters
to require initiator/responder addresses in the correct order instead
of matching entries regardless of the role.
This commit is contained in:
Jouni Malinen 2011-01-24 14:26:35 +02:00 committed by Jouni Malinen
parent eb4923fdae
commit 0d2e395d74
4 changed files with 40 additions and 9 deletions

View file

@ -67,6 +67,13 @@ void pmk_deinit(struct wlantest_pmk *pmk)
}
void tdls_deinit(struct wlantest_tdls *tdls)
{
dl_list_del(&tdls->list);
os_free(tdls);
}
void bss_deinit(struct wlantest_bss *bss)
{
struct wlantest_sta *sta, *n;
@ -77,7 +84,7 @@ void bss_deinit(struct wlantest_bss *bss)
dl_list_for_each_safe(pmk, np, &bss->pmk, struct wlantest_pmk, list)
pmk_deinit(pmk);
dl_list_for_each_safe(tdls, nt, &bss->tdls, struct wlantest_tdls, list)
os_free(tdls);
tdls_deinit(tdls);
dl_list_del(&bss->list);
os_free(bss);
}

View file

@ -444,8 +444,7 @@ static void ctrl_get_tdls_counter(struct wlantest *wt, int sock, u8 *cmd,
}
dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
if ((tdls->init == sta && tdls->resp == sta2) ||
(tdls->init == sta2 && tdls->resp == sta)) {
if (tdls->init == sta && tdls->resp == sta2) {
found = 1;
break;
}

View file

@ -23,7 +23,8 @@
#include "wlantest.h"
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)
{
struct wlantest_bss *bss;
struct wlantest_sta *init, *resp;
@ -46,6 +47,9 @@ static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *linkid)
return tdls;
}
if (!create_new)
return NULL;
tdls = os_zalloc(sizeof(*tdls));
if (tdls == NULL)
return NULL;
@ -202,7 +206,7 @@ static void rx_data_tdls_setup_request(struct wlantest *wt, const u8 *bssid,
" initiator STA " MACSTR " responder STA " MACSTR,
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
MAC2STR(elems.link_id + 2 * ETH_ALEN));
tdls = get_tdls(wt, elems.link_id);
tdls = get_tdls(wt, elems.link_id, 1);
if (tdls)
tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_REQ]++;
}
@ -234,7 +238,7 @@ static void rx_data_tdls_setup_response(struct wlantest *wt, const u8 *bssid,
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
MAC2STR(elems.link_id + 2 * ETH_ALEN));
tdls = get_tdls(wt, elems.link_id);
tdls = get_tdls(wt, elems.link_id, 1);
if (!tdls)
return;
if (status)
@ -259,6 +263,7 @@ static void rx_data_tdls_setup_confirm(struct wlantest *wt, const u8 *bssid,
u16 status;
struct ieee802_11_elems elems;
struct wlantest_tdls *tdls;
u8 link_id[3 * ETH_ALEN];
if (len < 3)
return;
@ -275,7 +280,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 + 2 * ETH_ALEN));
tdls = get_tdls(wt, elems.link_id);
tdls = get_tdls(wt, elems.link_id, 1);
if (tdls == NULL)
return;
if (status)
@ -287,13 +292,32 @@ static void rx_data_tdls_setup_confirm(struct wlantest *wt, const u8 *bssid,
return;
tdls->link_up = 1;
if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1)
if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1) {
if (elems.ftie == NULL)
goto remove_reverse;
return;
}
if (tdls_verify_mic(tdls, 3, &elems) == 0) {
tdls->dialog_token = data[2];
wpa_printf(MSG_DEBUG, "TDLS: Dialog Token for the link: %u",
tdls->dialog_token);
}
remove_reverse:
/*
* The TDLS link itself is bidirectional, but there is explicit
* initiator/responder roles. Remove the other direction of the link
* (if it exists) to make sure that the link counters are stored for
* the current TDLS entery.
*/
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 + 2 * ETH_ALEN, elems.link_id + ETH_ALEN, ETH_ALEN);
tdls = get_tdls(wt, link_id, 0);
if (tdls) {
wpa_printf(MSG_DEBUG, "TDLS: Remove reverse link entry");
tdls_deinit(tdls);
}
}
@ -377,7 +401,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 + 2 * ETH_ALEN));
tdls = get_tdls(wt, elems.link_id);
tdls = get_tdls(wt, elems.link_id, 1);
if (tdls) {
tdls->link_up = 0;
tdls_verify_mic_teardown(tdls, 4, data, &elems);

View file

@ -212,6 +212,7 @@ void bss_flush(struct wlantest *wt);
int bss_add_pmk_from_passphrase(struct wlantest_bss *bss,
const char *passphrase);
void pmk_deinit(struct wlantest_pmk *pmk);
void tdls_deinit(struct wlantest_tdls *tdls);
struct wlantest_sta * sta_find(struct wlantest_bss *bss, const u8 *addr);
struct wlantest_sta * sta_get(struct wlantest_bss *bss, const u8 *addr);