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.
This commit is contained in:
parent
719e7eb28d
commit
244c9303cb
3 changed files with 63 additions and 35 deletions
|
@ -61,14 +61,16 @@ static const char * data_stype(u16 stype)
|
||||||
|
|
||||||
static void rx_data_eth(struct wlantest *wt, const u8 *bssid,
|
static void rx_data_eth(struct wlantest *wt, const u8 *bssid,
|
||||||
const u8 *sta_addr, const u8 *dst, const u8 *src,
|
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) {
|
switch (ethertype) {
|
||||||
case ETH_P_PAE:
|
case ETH_P_PAE:
|
||||||
rx_data_eapol(wt, dst, src, data, len, prot);
|
rx_data_eapol(wt, dst, src, data, len, prot);
|
||||||
break;
|
break;
|
||||||
case ETH_P_IP:
|
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;
|
break;
|
||||||
case 0x890d:
|
case 0x890d:
|
||||||
rx_data_80211_encap(wt, bssid, sta_addr, dst, src, data, len);
|
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,
|
static void rx_data_process(struct wlantest *wt, 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)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
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,
|
||||||
|
peer_addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +185,7 @@ skip_replay_det:
|
||||||
&dlen);
|
&dlen);
|
||||||
if (decrypted) {
|
if (decrypted) {
|
||||||
rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted,
|
rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted,
|
||||||
dlen, 1);
|
dlen, 1, NULL);
|
||||||
os_memcpy(bss->rsc[keyid], pn, 6);
|
os_memcpy(bss->rsc[keyid], pn, 6);
|
||||||
write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
|
write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
|
||||||
decrypted, dlen);
|
decrypted, dlen);
|
||||||
|
@ -334,8 +338,12 @@ skip_replay_det:
|
||||||
else
|
else
|
||||||
decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
|
decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
|
||||||
if (decrypted) {
|
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,
|
rx_data_process(wt, bss->bssid, sta->addr, dst, src, decrypted,
|
||||||
dlen, 1);
|
dlen, 1, peer_addr);
|
||||||
os_memcpy(rsc, pn, 6);
|
os_memcpy(rsc, pn, 6);
|
||||||
write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
|
write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
|
||||||
decrypted, dlen);
|
decrypted, dlen);
|
||||||
|
@ -371,15 +379,23 @@ static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
|
||||||
if (prot)
|
if (prot)
|
||||||
rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
|
rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
|
||||||
else {
|
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) {
|
if (fc & WLAN_FC_TODS) {
|
||||||
bssid = hdr->addr1;
|
bssid = hdr->addr1;
|
||||||
sta_addr = hdr->addr2;
|
sta_addr = hdr->addr2;
|
||||||
} else {
|
peer_addr = NULL;
|
||||||
|
} else if (fc & WLAN_FC_FROMDS) {
|
||||||
bssid = hdr->addr2;
|
bssid = hdr->addr2;
|
||||||
sta_addr = hdr->addr1;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,35 @@
|
||||||
#include "wlantest.h"
|
#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,
|
static void rx_data_icmp(struct wlantest *wt, const u8 *bssid,
|
||||||
const u8 *sta_addr, u32 dst, u32 src,
|
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;
|
struct in_addr addr;
|
||||||
char buf[20];
|
char buf[20];
|
||||||
|
@ -48,9 +74,10 @@ static void rx_data_icmp(struct wlantest *wt, const u8 *bssid,
|
||||||
addr.s_addr = dst;
|
addr.s_addr = dst;
|
||||||
snprintf(buf, sizeof(buf), "%s", inet_ntoa(addr));
|
snprintf(buf, sizeof(buf), "%s", inet_ntoa(addr));
|
||||||
addr.s_addr = src;
|
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",
|
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);
|
bss = bss_find(wt, bssid);
|
||||||
if (bss == NULL) {
|
if (bss == NULL) {
|
||||||
|
@ -69,31 +96,15 @@ static void rx_data_icmp(struct wlantest *wt, const u8 *bssid,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr->type == ICMP_ECHO) {
|
ping_update(sta, hdr->type == ICMP_ECHO, src, dst, id, seq);
|
||||||
sta->icmp_echo_req_src = src;
|
if (peer_addr && (sta = sta_find(bss, peer_addr)))
|
||||||
sta->icmp_echo_req_dst = dst;
|
ping_update(sta, hdr->type == ICMP_ECHO, src, dst, id, seq);
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rx_data_ip(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
|
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 struct iphdr *ip;
|
||||||
const u8 *payload;
|
const u8 *payload;
|
||||||
|
@ -146,7 +157,7 @@ void rx_data_ip(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
|
||||||
switch (ip->protocol) {
|
switch (ip->protocol) {
|
||||||
case IPPROTO_ICMP:
|
case IPPROTO_ICMP:
|
||||||
rx_data_icmp(wt, bssid, sta_addr, ip->daddr, ip->saddr,
|
rx_data_icmp(wt, bssid, sta_addr, ip->daddr, ip->saddr,
|
||||||
payload, plen);
|
payload, plen, peer_addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
|
||||||
const u8 *data, size_t len, int prot);
|
const u8 *data, size_t len, int prot);
|
||||||
void rx_data_ip(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
|
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,
|
void rx_data_80211_encap(struct wlantest *wt, const u8 *bssid,
|
||||||
const u8 *sta_addr, const u8 *dst, const u8 *src,
|
const u8 *sta_addr, const u8 *dst, const u8 *src,
|
||||||
const u8 *data, size_t len);
|
const u8 *data, size_t len);
|
||||||
|
|
Loading…
Reference in a new issue