aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2011-01-03 19:28:40 +0200
committerJouni Malinen <j@w1.fi>2011-01-03 19:28:40 +0200
commitfb8f5fc6fd9534721a9ce2ce4af479e585062add (patch)
tree591e59b843caf88231015b7f97b796ac467401e3
parent1da4da6f76d17399c72ddb295e0d9d298e2f919e (diff)
downloadexternal_wpa_supplicant_8_ti-fb8f5fc6fd9534721a9ce2ce4af479e585062add.zip
external_wpa_supplicant_8_ti-fb8f5fc6fd9534721a9ce2ce4af479e585062add.tar.gz
external_wpa_supplicant_8_ti-fb8f5fc6fd9534721a9ce2ce4af479e585062add.tar.bz2
wlantest: Count number of STA ACK'ed Deauth/Disassoc frames
-rw-r--r--wlantest/process.c25
-rw-r--r--wlantest/rx_mgmt.c84
-rw-r--r--wlantest/wlantest.h5
-rw-r--r--wlantest/wlantest_cli.c7
-rw-r--r--wlantest/wlantest_ctrl.h4
5 files changed, 125 insertions, 0 deletions
diff --git a/wlantest/process.c b/wlantest/process.c
index 6cdb10b..f740a64 100644
--- a/wlantest/process.c
+++ b/wlantest/process.c
@@ -100,6 +100,25 @@ static int rx_duplicate(struct wlantest *wt, const struct ieee80211_hdr *hdr,
}
+static void rx_ack(struct wlantest *wt, const struct ieee80211_hdr *hdr)
+{
+ struct ieee80211_hdr *last = (struct ieee80211_hdr *) wt->last_hdr;
+ u16 fc;
+
+ if (wt->last_len < 24 || (last->addr1[0] & 0x01) ||
+ os_memcmp(hdr->addr1, last->addr2, ETH_ALEN) != 0) {
+ wpa_printf(MSG_MSGDUMP, "Unknown Ack frame (previous frame "
+ "not seen)");
+ return;
+ }
+
+ /* Ack to the previous frame */
+ fc = le_to_host16(last->frame_control);
+ if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
+ rx_mgmt_ack(wt, last);
+}
+
+
static void rx_frame(struct wlantest *wt, const u8 *data, size_t len)
{
const struct ieee80211_hdr *hdr;
@@ -129,6 +148,8 @@ static void rx_frame(struct wlantest *wt, const u8 *data, size_t len)
if (len < 10)
break;
wt->rx_ctrl++;
+ if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACK)
+ rx_ack(wt, hdr);
break;
case WLAN_FC_TYPE_DATA:
if (len < 24)
@@ -142,6 +163,10 @@ static void rx_frame(struct wlantest *wt, const u8 *data, size_t len)
WLAN_FC_GET_TYPE(fc));
break;
}
+
+ os_memcpy(wt->last_hdr, data, len > sizeof(wt->last_hdr) ?
+ sizeof(wt->last_hdr) : len);
+ wt->last_len = len;
}
diff --git a/wlantest/rx_mgmt.c b/wlantest/rx_mgmt.c
index 7630dcb..8941129 100644
--- a/wlantest/rx_mgmt.c
+++ b/wlantest/rx_mgmt.c
@@ -1035,4 +1035,88 @@ void rx_mgmt(struct wlantest *wt, const u8 *data, size_t len)
}
os_free(decrypted);
+
+ wt->last_mgmt_valid = valid;
+}
+
+
+static void rx_mgmt_deauth_ack(struct wlantest *wt,
+ const struct ieee80211_hdr *hdr)
+{
+ const struct ieee80211_mgmt *mgmt;
+ struct wlantest_bss *bss;
+ struct wlantest_sta *sta;
+
+ mgmt = (const struct ieee80211_mgmt *) hdr;
+ bss = bss_get(wt, mgmt->bssid);
+ if (bss == NULL)
+ return;
+ if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
+ sta = sta_get(bss, mgmt->da);
+ else
+ sta = sta_get(bss, mgmt->sa);
+ if (sta == NULL)
+ return;
+
+ wpa_printf(MSG_DEBUG, "DEAUTH from " MACSTR " acknowledged by " MACSTR,
+ MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
+ if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0) {
+ int c;
+ c = wt->last_mgmt_valid ?
+ WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK :
+ WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK;
+ sta->counters[c]++;
+ }
+}
+
+
+static void rx_mgmt_disassoc_ack(struct wlantest *wt,
+ const struct ieee80211_hdr *hdr)
+{
+ const struct ieee80211_mgmt *mgmt;
+ struct wlantest_bss *bss;
+ struct wlantest_sta *sta;
+
+ mgmt = (const struct ieee80211_mgmt *) hdr;
+ bss = bss_get(wt, mgmt->bssid);
+ if (bss == NULL)
+ return;
+ if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
+ sta = sta_get(bss, mgmt->da);
+ else
+ sta = sta_get(bss, mgmt->sa);
+ if (sta == NULL)
+ return;
+
+ wpa_printf(MSG_DEBUG, "DISASSOC from " MACSTR " acknowledged by "
+ MACSTR, MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
+ if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0) {
+ int c;
+ c = wt->last_mgmt_valid ?
+ WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK :
+ WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK;
+ sta->counters[c]++;
+ }
+}
+
+
+void rx_mgmt_ack(struct wlantest *wt, const struct ieee80211_hdr *hdr)
+{
+ u16 fc, stype;
+ fc = le_to_host16(hdr->frame_control);
+ stype = WLAN_FC_GET_STYPE(fc);
+
+ wpa_printf(MSG_MSGDUMP, "MGMT ACK: stype=%u a1=" MACSTR " a2=" MACSTR
+ " a3=" MACSTR,
+ stype, MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
+ MAC2STR(hdr->addr3));
+
+ switch (stype) {
+ case WLAN_FC_STYPE_DEAUTH:
+ rx_mgmt_deauth_ack(wt, hdr);
+ break;
+ case WLAN_FC_STYPE_DISASSOC:
+ rx_mgmt_disassoc_ack(wt, hdr);
+ break;
+ }
}
diff --git a/wlantest/wlantest.h b/wlantest/wlantest.h
index 5247909..64e9b6a 100644
--- a/wlantest/wlantest.h
+++ b/wlantest/wlantest.h
@@ -160,6 +160,10 @@ struct wlantest {
void *write_pcap; /* pcap_t* */
void *write_pcap_dumper; /* pcpa_dumper_t */
struct timeval write_pcap_time;
+
+ u8 last_hdr[30];
+ size_t last_len;
+ int last_mgmt_valid;
};
int read_cap_file(struct wlantest *wt, const char *fname);
@@ -178,6 +182,7 @@ int monitor_init(struct wlantest *wt, const char *ifname);
int monitor_init_wired(struct wlantest *wt, const char *ifname);
void monitor_deinit(struct wlantest *wt);
void rx_mgmt(struct wlantest *wt, const u8 *data, size_t len);
+void rx_mgmt_ack(struct wlantest *wt, const struct ieee80211_hdr *hdr);
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);
diff --git a/wlantest/wlantest_cli.c b/wlantest/wlantest_cli.c
index b40eb54..a2bb6b9 100644
--- a/wlantest/wlantest_cli.c
+++ b/wlantest/wlantest_cli.c
@@ -540,6 +540,13 @@ static const struct sta_counters sta_counters[] = {
{ "assocresp_comeback", WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK },
{ "reassocresp_comeback", WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK },
{ "ping_ok_first_assoc", WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC },
+ { "valid_deauth_rx_ack", WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK },
+ { "valid_disassoc_rx_ack",
+ WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK },
+ { "invalid_deauth_rx_ack",
+ WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK },
+ { "invalid_disassoc_rx_ack",
+ WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK },
{ NULL, 0 }
};
diff --git a/wlantest/wlantest_ctrl.h b/wlantest/wlantest_ctrl.h
index c8d4ce8..0dbf8c5 100644
--- a/wlantest/wlantest_ctrl.h
+++ b/wlantest/wlantest_ctrl.h
@@ -97,6 +97,10 @@ enum wlantest_sta_counter {
WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK,
WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK,
WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC,
+ WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK,
+ WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK,
+ WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK,
+ WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK,
NUM_WLANTEST_STA_COUNTER
};