]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
wlantest: Determine ping matches properly for direct link
authorJouni Malinen <jouni.malinen@atheros.com>
Mon, 24 Jan 2011 12:50:51 +0000 (14:50 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 24 Jan 2011 12:50:51 +0000 (14:50 +0200)
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.

wlantest/rx_data.c
wlantest/rx_ip.c
wlantest/wlantest.h

index 95daaf224073e53d97190d0fb6aeec0b3fddb74f..9e0432192961e67b2925316c7a2b957becd92946 100644 (file)
@@ -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);
        }
 }
 
index aa2b0872d064fa75bd0edb74598751d59d9c7659..207015929928fb1de366ec1bc1573445744a5471 100644 (file)
 #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;
        }
 }
index da63d2f577ccba3d7b0e5a7255b106fe0709cbbc..32794caaccd401bc8f627b5bc39ac9da91d757c6 100644 (file)
@@ -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);