aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2011-01-24 12:50:51 (GMT)
committerJouni Malinen <j@w1.fi>2011-01-24 12:50:51 (GMT)
commit244c9303cb148f96e6e7bbd0c5b24479ce4df3b8 (patch)
tree0874f90b38a681ae9497e0b9fc65fe5b03443488
parent719e7eb28d5679e9a3c7e44366a80d4403bc5cdc (diff)
downloadhostap-244c9303cb148f96e6e7bbd0c5b24479ce4df3b8.zip
hostap-244c9303cb148f96e6e7bbd0c5b24479ce4df3b8.tar.gz
hostap-244c9303cb148f96e6e7bbd0c5b24479ce4df3b8.tar.bz2
wlantest: Determine ping matches properly for direct link
Check ICMP echo request/response matches for both STAs to get proper counter values for a ping from a one STA to another one using TDLS.
-rw-r--r--wlantest/rx_data.c34
-rw-r--r--wlantest/rx_ip.c61
-rw-r--r--wlantest/wlantest.h3
3 files changed, 63 insertions, 35 deletions
diff --git a/wlantest/rx_data.c b/wlantest/rx_data.c
index 95daaf2..9e04321 100644
--- a/wlantest/rx_data.c
+++ b/wlantest/rx_data.c
@@ -61,14 +61,16 @@ static const char * data_stype(u16 stype)
static void rx_data_eth(struct wlantest *wt, const u8 *bssid,
const u8 *sta_addr, const u8 *dst, const u8 *src,
- u16 ethertype, const u8 *data, size_t len, int prot)
+ u16 ethertype, const u8 *data, size_t len, int prot,
+ const u8 *peer_addr)
{
switch (ethertype) {
case ETH_P_PAE:
rx_data_eapol(wt, dst, src, data, len, prot);
break;
case ETH_P_IP:
- rx_data_ip(wt, bssid, sta_addr, dst, src, data, len);
+ rx_data_ip(wt, bssid, sta_addr, dst, src, data, len,
+ peer_addr);
break;
case 0x890d:
rx_data_80211_encap(wt, bssid, sta_addr, dst, src, data, len);
@@ -80,14 +82,16 @@ static void rx_data_eth(struct wlantest *wt, const u8 *bssid,
static void rx_data_process(struct wlantest *wt, const u8 *bssid,
const u8 *sta_addr,
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)
{
if (len == 0)
return;
if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
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,
+ peer_addr);
return;
}
@@ -181,7 +185,7 @@ skip_replay_det:
&dlen);
if (decrypted) {
rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted,
- dlen, 1);
+ dlen, 1, NULL);
os_memcpy(bss->rsc[keyid], pn, 6);
write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
decrypted, dlen);
@@ -334,8 +338,12 @@ skip_replay_det:
else
decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
if (decrypted) {
+ u16 fc = le_to_host16(hdr->frame_control);
+ u8 *peer_addr = NULL;
+ if (!(fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)))
+ peer_addr = hdr->addr1;
rx_data_process(wt, bss->bssid, sta->addr, dst, src, decrypted,
- dlen, 1);
+ dlen, 1, peer_addr);
os_memcpy(rsc, pn, 6);
write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
decrypted, dlen);
@@ -371,15 +379,23 @@ static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
if (prot)
rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
else {
- const u8 *bssid, *sta_addr;
+ const u8 *bssid, *sta_addr, *peer_addr;
+ int direct_link = !(fc & (WLAN_FC_FROMDS | WLAN_FC_TODS));
if (fc & WLAN_FC_TODS) {
bssid = hdr->addr1;
sta_addr = hdr->addr2;
- } else {
+ peer_addr = NULL;
+ } else if (fc & WLAN_FC_FROMDS) {
bssid = hdr->addr2;
sta_addr = hdr->addr1;
+ peer_addr = NULL;
+ } else {
+ bssid = hdr->addr3;
+ sta_addr = hdr->addr2;
+ peer_addr = hdr->addr1;
}
- rx_data_process(wt, bssid, sta_addr, dst, src, data, len, 0);
+ rx_data_process(wt, bssid, sta_addr, dst, src, data, len, 0,
+ peer_addr);
}
}
diff --git a/wlantest/rx_ip.c b/wlantest/rx_ip.c
index aa2b087..2070159 100644
--- a/wlantest/rx_ip.c
+++ b/wlantest/rx_ip.c
@@ -20,9 +20,35 @@
#include "wlantest.h"
+static void ping_update(struct wlantest_sta *sta, int req, u32 src, u32 dst,
+ u16 id, u16 seq)
+{
+ if (req) {
+ sta->icmp_echo_req_src = src;
+ sta->icmp_echo_req_dst = dst;
+ sta->icmp_echo_req_id = id;
+ sta->icmp_echo_req_seq = seq;
+ return;
+ }
+
+ if (sta->icmp_echo_req_src == dst &&
+ sta->icmp_echo_req_dst == src &&
+ sta->icmp_echo_req_id == id &&
+ sta->icmp_echo_req_seq == seq) {
+ sta->counters[WLANTEST_STA_COUNTER_PING_OK]++;
+ if (sta->counters[WLANTEST_STA_COUNTER_ASSOCREQ_TX] == 0 &&
+ sta->counters[WLANTEST_STA_COUNTER_REASSOCREQ_TX] == 0)
+ sta->counters[
+ WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC]++;
+ wpa_printf(MSG_DEBUG, "ICMP echo (ping) match for STA " MACSTR,
+ MAC2STR(sta->addr));
+ }
+}
+
+
static void rx_data_icmp(struct wlantest *wt, const u8 *bssid,
const u8 *sta_addr, u32 dst, u32 src,
- const u8 *data, size_t len)
+ const u8 *data, size_t len, const u8 *peer_addr)
{
struct in_addr addr;
char buf[20];
@@ -48,9 +74,10 @@ static void rx_data_icmp(struct wlantest *wt, const u8 *bssid,
addr.s_addr = dst;
snprintf(buf, sizeof(buf), "%s", inet_ntoa(addr));
addr.s_addr = src;
- wpa_printf(MSG_DEBUG, "ICMP echo %s %s -> %s id=%04x seq=%u len=%u",
+ wpa_printf(MSG_DEBUG, "ICMP echo %s %s -> %s id=%04x seq=%u len=%u%s",
hdr->type == ICMP_ECHO ? "request" : "response",
- inet_ntoa(addr), buf, id, seq, (unsigned) len - 8);
+ inet_ntoa(addr), buf, id, seq, (unsigned) len - 8,
+ peer_addr ? " [DL]" : "");
bss = bss_find(wt, bssid);
if (bss == NULL) {
@@ -69,31 +96,15 @@ static void rx_data_icmp(struct wlantest *wt, const u8 *bssid,
return;
}
- if (hdr->type == ICMP_ECHO) {
- sta->icmp_echo_req_src = src;
- sta->icmp_echo_req_dst = dst;
- sta->icmp_echo_req_id = id;
- sta->icmp_echo_req_seq = seq;
- return;
- }
-
- if (sta->icmp_echo_req_src == dst &&
- sta->icmp_echo_req_dst == src &&
- sta->icmp_echo_req_id == id &&
- sta->icmp_echo_req_seq == seq) {
- sta->counters[WLANTEST_STA_COUNTER_PING_OK]++;
- if (sta->counters[WLANTEST_STA_COUNTER_ASSOCREQ_TX] == 0 &&
- sta->counters[WLANTEST_STA_COUNTER_REASSOCREQ_TX] == 0)
- sta->counters[
- WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC]++;
- wpa_printf(MSG_DEBUG, "ICMP echo (ping) match for STA " MACSTR,
- MAC2STR(sta->addr));
- }
+ ping_update(sta, hdr->type == ICMP_ECHO, src, dst, id, seq);
+ if (peer_addr && (sta = sta_find(bss, peer_addr)))
+ ping_update(sta, hdr->type == ICMP_ECHO, src, dst, id, seq);
}
void rx_data_ip(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
- const u8 *dst, const u8 *src, const u8 *data, size_t len)
+ const u8 *dst, const u8 *src, const u8 *data, size_t len,
+ const u8 *peer_addr)
{
const struct iphdr *ip;
const u8 *payload;
@@ -146,7 +157,7 @@ void rx_data_ip(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
switch (ip->protocol) {
case IPPROTO_ICMP:
rx_data_icmp(wt, bssid, sta_addr, ip->daddr, ip->saddr,
- payload, plen);
+ payload, plen, peer_addr);
break;
}
}
diff --git a/wlantest/wlantest.h b/wlantest/wlantest.h
index da63d2f..32794ca 100644
--- a/wlantest/wlantest.h
+++ b/wlantest/wlantest.h
@@ -198,7 +198,8 @@ void rx_data(struct wlantest *wt, const u8 *data, size_t len);
void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
const u8 *data, size_t len, int prot);
void rx_data_ip(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
- const u8 *dst, const u8 *src, const u8 *data, size_t len);
+ const u8 *dst, const u8 *src, const u8 *data, size_t len,
+ const u8 *peer_addr);
void rx_data_80211_encap(struct wlantest *wt, const u8 *bssid,
const u8 *sta_addr, const u8 *dst, const u8 *src,
const u8 *data, size_t len);