wlantest: Count number of STA ACK'ed Deauth/Disassoc frames
This commit is contained in:
		
							parent
							
								
									1da4da6f76
								
							
						
					
					
						commit
						fb8f5fc6fd
					
				
					 5 changed files with 125 additions and 0 deletions
				
			
		|  | @ -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) | static void rx_frame(struct wlantest *wt, const u8 *data, size_t len) | ||||||
| { | { | ||||||
| 	const struct ieee80211_hdr *hdr; | 	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) | 		if (len < 10) | ||||||
| 			break; | 			break; | ||||||
| 		wt->rx_ctrl++; | 		wt->rx_ctrl++; | ||||||
|  | 		if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACK) | ||||||
|  | 			rx_ack(wt, hdr); | ||||||
| 		break; | 		break; | ||||||
| 	case WLAN_FC_TYPE_DATA: | 	case WLAN_FC_TYPE_DATA: | ||||||
| 		if (len < 24) | 		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)); | 			   WLAN_FC_GET_TYPE(fc)); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	os_memcpy(wt->last_hdr, data, len > sizeof(wt->last_hdr) ? | ||||||
|  | 		  sizeof(wt->last_hdr) : len); | ||||||
|  | 	wt->last_len = len; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1035,4 +1035,88 @@ void rx_mgmt(struct wlantest *wt, const u8 *data, size_t len) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	os_free(decrypted); | 	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; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -160,6 +160,10 @@ struct wlantest { | ||||||
| 	void *write_pcap; /* pcap_t* */ | 	void *write_pcap; /* pcap_t* */ | ||||||
| 	void *write_pcap_dumper; /* pcpa_dumper_t */ | 	void *write_pcap_dumper; /* pcpa_dumper_t */ | ||||||
| 	struct timeval write_pcap_time; | 	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); | 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); | int monitor_init_wired(struct wlantest *wt, const char *ifname); | ||||||
| void monitor_deinit(struct wlantest *wt); | void monitor_deinit(struct wlantest *wt); | ||||||
| void rx_mgmt(struct wlantest *wt, const u8 *data, size_t len); | 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(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); | ||||||
|  |  | ||||||
|  | @ -540,6 +540,13 @@ static const struct sta_counters sta_counters[] = { | ||||||
| 	{ "assocresp_comeback", WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK }, | 	{ "assocresp_comeback", WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK }, | ||||||
| 	{ "reassocresp_comeback", WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK }, | 	{ "reassocresp_comeback", WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK }, | ||||||
| 	{ "ping_ok_first_assoc", WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC }, | 	{ "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 } | 	{ NULL, 0 } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -97,6 +97,10 @@ enum wlantest_sta_counter { | ||||||
| 	WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK, | 	WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK, | ||||||
| 	WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK, | 	WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK, | ||||||
| 	WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC, | 	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 | 	NUM_WLANTEST_STA_COUNTER | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jouni Malinen
						Jouni Malinen