diff options
Diffstat (limited to 'wlantest')
-rw-r--r-- | wlantest/rx_data.c | 34 | ||||
-rw-r--r-- | wlantest/rx_ip.c | 61 | ||||
-rw-r--r-- | wlantest/wlantest.h | 3 |
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); |