aboutsummaryrefslogtreecommitdiffstats
path: root/wlantest
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2011-01-24 14:26:35 +0200
committerJouni Malinen <j@w1.fi>2011-01-24 14:34:45 +0200
commit0d2e395d74e5d4a77faad08bedb8609209ea0a12 (patch)
tree803ebddc417155ec193f67f294751f209206d793 /wlantest
parenteb4923fdae82a8d9609762bfc87d3012e9f29414 (diff)
downloadexternal_wpa_supplicant_8_ti-0d2e395d74e5d4a77faad08bedb8609209ea0a12.zip
external_wpa_supplicant_8_ti-0d2e395d74e5d4a77faad08bedb8609209ea0a12.tar.gz
external_wpa_supplicant_8_ti-0d2e395d74e5d4a77faad08bedb8609209ea0a12.tar.bz2
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.
Diffstat (limited to 'wlantest')
-rw-r--r--wlantest/bss.c9
-rw-r--r--wlantest/ctrl.c3
-rw-r--r--wlantest/rx_tdls.c36
-rw-r--r--wlantest/wlantest.h1
4 files changed, 40 insertions, 9 deletions
diff --git a/wlantest/bss.c b/wlantest/bss.c
index a4a3155..34dee50 100644
--- a/wlantest/bss.c
+++ b/wlantest/bss.c
@@ -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);
}
diff --git a/wlantest/ctrl.c b/wlantest/ctrl.c
index 11a7dd4..e97448d 100644
--- a/wlantest/ctrl.c
+++ b/wlantest/ctrl.c
@@ -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;
}
diff --git a/wlantest/rx_tdls.c b/wlantest/rx_tdls.c
index fd18c08..4e25cce 100644
--- a/wlantest/rx_tdls.c
+++ b/wlantest/rx_tdls.c
@@ -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);
diff --git a/wlantest/wlantest.h b/wlantest/wlantest.h
index 4301504..da63d2f 100644
--- a/wlantest/wlantest.h
+++ b/wlantest/wlantest.h
@@ -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);