Browse Source

wlantest: Add per-TID RX/TX counters

Signed-hostap: Jouni Malinen <j@w1.fi>
Jouni Malinen 11 years ago
parent
commit
99d7c1dedf
5 changed files with 239 additions and 2 deletions
  1. 78 0
      wlantest/ctrl.c
  2. 36 2
      wlantest/rx_data.c
  3. 3 0
      wlantest/wlantest.h
  4. 119 0
      wlantest/wlantest_cli.c
  5. 3 0
      wlantest/wlantest_ctrl.h

+ 78 - 0
wlantest/ctrl.c

@@ -290,6 +290,8 @@ static void ctrl_clear_sta_counters(struct wlantest *wt, int sock, u8 *cmd,
 	}
 
 	os_memset(sta->counters, 0, sizeof(sta->counters));
+	os_memset(sta->tx_tid, 0, sizeof(sta->tx_tid));
+	os_memset(sta->rx_tid, 0, sizeof(sta->rx_tid));
 	ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
 }
 
@@ -1195,6 +1197,76 @@ static void ctrl_relog(struct wlantest *wt, int sock)
 }
 
 
+static void ctrl_get_tx_tid(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
+{
+	u8 *addr;
+	size_t addr_len;
+	struct wlantest_bss *bss;
+	struct wlantest_sta *sta;
+	u32 counter;
+	u8 buf[4 + 12], *end, *pos;
+
+	bss = ctrl_get_bss(wt, sock, cmd, clen);
+	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
+	if (sta == NULL)
+		return;
+
+	addr = attr_get(cmd, clen, WLANTEST_ATTR_TID, &addr_len);
+	if (addr == NULL || addr_len != 4) {
+		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
+		return;
+	}
+	counter = WPA_GET_BE32(addr);
+	if (counter >= 16 + 1) {
+		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
+		return;
+	}
+
+	pos = buf;
+	end = buf + sizeof(buf);
+	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
+	pos += 4;
+	pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
+			    sta->tx_tid[counter]);
+	ctrl_send(wt, sock, buf, pos - buf);
+}
+
+
+static void ctrl_get_rx_tid(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
+{
+	u8 *addr;
+	size_t addr_len;
+	struct wlantest_bss *bss;
+	struct wlantest_sta *sta;
+	u32 counter;
+	u8 buf[4 + 12], *end, *pos;
+
+	bss = ctrl_get_bss(wt, sock, cmd, clen);
+	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
+	if (sta == NULL)
+		return;
+
+	addr = attr_get(cmd, clen, WLANTEST_ATTR_TID, &addr_len);
+	if (addr == NULL || addr_len != 4) {
+		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
+		return;
+	}
+	counter = WPA_GET_BE32(addr);
+	if (counter >= 16 + 1) {
+		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
+		return;
+	}
+
+	pos = buf;
+	end = buf + sizeof(buf);
+	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
+	pos += 4;
+	pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
+			    sta->rx_tid[counter]);
+	ctrl_send(wt, sock, buf, pos - buf);
+}
+
+
 static void ctrl_read(int sock, void *eloop_ctx, void *sock_ctx)
 {
 	struct wlantest *wt = eloop_ctx;
@@ -1281,6 +1353,12 @@ static void ctrl_read(int sock, void *eloop_ctx, void *sock_ctx)
 	case WLANTEST_CTRL_RELOG:
 		ctrl_relog(wt, sock);
 		break;
+	case WLANTEST_CTRL_GET_TX_TID:
+		ctrl_get_tx_tid(wt, sock, buf + 4, len - 4);
+		break;
+	case WLANTEST_CTRL_GET_RX_TID:
+		ctrl_get_rx_tid(wt, sock, buf + 4, len - 4);
+		break;
 	default:
 		ctrl_send_simple(wt, sock, WLANTEST_CTRL_UNKNOWN_CMD);
 		break;

+ 36 - 2
wlantest/rx_data.c

@@ -300,6 +300,8 @@ static void rx_data_bss_prot(struct wlantest *wt,
 		return;
 	}
 
+	if (sta == NULL)
+		return;
 	if (sta->pairwise_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
 	    !(data[3] & 0x20)) {
 		add_note(wt, MSG_INFO, "Expected TKIP/CCMP frame from "
@@ -336,10 +338,19 @@ static void rx_data_bss_prot(struct wlantest *wt,
 			 keyid, MAC2STR(hdr->addr2));
 	}
 
-	if (qos)
+	if (qos) {
 		tid = qos[0] & 0x0f;
-	else
+		if (fc & WLAN_FC_TODS)
+			sta->tx_tid[tid]++;
+		else
+			sta->rx_tid[tid]++;
+	} else {
 		tid = 0;
+		if (fc & WLAN_FC_TODS)
+			sta->tx_tid[16]++;
+		else
+			sta->rx_tid[16]++;
+	}
 	if (tk) {
 		if (os_memcmp(hdr->addr2, tdls->init->addr, ETH_ALEN) == 0)
 			rsc = tdls->rsc_init[tid];
@@ -434,6 +445,8 @@ static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
 		rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
 	else {
 		const u8 *bssid, *sta_addr, *peer_addr;
+		struct wlantest_bss *bss;
+
 		if (fc & WLAN_FC_TODS) {
 			bssid = hdr->addr1;
 			sta_addr = hdr->addr2;
@@ -447,6 +460,27 @@ static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
 			sta_addr = hdr->addr2;
 			peer_addr = hdr->addr1;
 		}
+
+		bss = bss_get(wt, bssid);
+		if (bss) {
+			struct wlantest_sta *sta = sta_get(bss, sta_addr);
+
+			if (sta) {
+				if (qos) {
+					int tid = qos[0] & 0x0f;
+					if (fc & WLAN_FC_TODS)
+						sta->tx_tid[tid]++;
+					else
+						sta->rx_tid[tid]++;
+				} else {
+					if (fc & WLAN_FC_TODS)
+						sta->tx_tid[16]++;
+					else
+						sta->rx_tid[16]++;
+				}
+			}
+		}
+
 		rx_data_process(wt, bssid, sta_addr, dst, src, data, len, 0,
 				peer_addr);
 	}

+ 3 - 0
wlantest/wlantest.h

@@ -97,6 +97,9 @@ struct wlantest_sta {
 	u8 gtk[32];
 	size_t gtk_len;
 	int gtk_idx;
+
+	u32 tx_tid[16 + 1];
+	u32 rx_tid[16 + 1];
 };
 
 struct wlantest_tdls {

+ 119 - 0
wlantest/wlantest_cli.c

@@ -1452,6 +1452,119 @@ static char ** complete_info_bss(int s, const char *str, int pos)
 }
 
 
+static int cmd_get_tx_tid(int s, int argc, char *argv[])
+{
+	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
+	u8 buf[100], *end, *pos;
+	int rlen;
+	size_t len;
+
+	if (argc != 3) {
+		printf("get_tx_tid needs three arguments: "
+		       "BSSID, STA address, and TID\n");
+		return -1;
+	}
+
+	pos = buf;
+	end = buf + sizeof(buf);
+	WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_TX_TID);
+	pos += 4;
+
+	pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
+	if (hwaddr_aton(argv[0], pos) < 0) {
+		printf("Invalid BSSID '%s'\n", argv[0]);
+		return -1;
+	}
+	pos += ETH_ALEN;
+
+	pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
+	if (hwaddr_aton(argv[1], pos) < 0) {
+		printf("Invalid STA address '%s'\n", argv[1]);
+		return -1;
+	}
+	pos += ETH_ALEN;
+
+	pos = attr_add_be32(pos, end, WLANTEST_ATTR_TID, atoi(argv[2]));
+
+	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
+	if (rlen < 0)
+		return -1;
+
+	pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
+	if (pos == NULL || len != 4)
+		return -1;
+	printf("%u\n", WPA_GET_BE32(pos));
+	return 0;
+}
+
+
+static int cmd_get_rx_tid(int s, int argc, char *argv[])
+{
+	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
+	u8 buf[100], *end, *pos;
+	int rlen;
+	size_t len;
+
+	if (argc != 3) {
+		printf("get_tx_tid needs three arguments: "
+		       "BSSID, STA address, and TID\n");
+		return -1;
+	}
+
+	pos = buf;
+	end = buf + sizeof(buf);
+	WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_RX_TID);
+	pos += 4;
+
+	pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
+	if (hwaddr_aton(argv[0], pos) < 0) {
+		printf("Invalid BSSID '%s'\n", argv[0]);
+		return -1;
+	}
+	pos += ETH_ALEN;
+
+	pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
+	if (hwaddr_aton(argv[1], pos) < 0) {
+		printf("Invalid STA address '%s'\n", argv[1]);
+		return -1;
+	}
+	pos += ETH_ALEN;
+
+	pos = attr_add_be32(pos, end, WLANTEST_ATTR_TID, atoi(argv[2]));
+
+	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
+	if (rlen < 0)
+		return -1;
+
+	pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
+	if (pos == NULL || len != 4)
+		return -1;
+	printf("%u\n", WPA_GET_BE32(pos));
+	return 0;
+}
+
+
+static char ** complete_get_tid(int s, const char *str, int pos)
+{
+	int arg = get_cmd_arg_num(str, pos);
+	char **res = NULL;
+	u8 addr[ETH_ALEN];
+
+	switch (arg) {
+	case 1:
+		res = get_bssid_list(s);
+		break;
+	case 2:
+		if (hwaddr_aton(&str[get_prev_arg_pos(str, pos)], addr) < 0)
+			break;
+		res = get_sta_list(s, addr, 0);
+		break;
+	}
+
+	return res;
+}
+
+
 struct wlantest_cli_cmd {
 	const char *cmd;
 	int (*handler)(int s, int argc, char *argv[]);
@@ -1503,6 +1616,12 @@ static const struct wlantest_cli_cmd wlantest_cli_commands[] = {
 	  "<counter> <BSSID> = get BSS counter value",
 	  complete_get_bss_counter },
 	{ "relog", cmd_relog, "= re-open log-file (allow rolling logs)", NULL },
+	{ "get_tx_tid", cmd_get_tx_tid,
+	  "<BSSID> <STA> <TID> = get STA TX TID counter value",
+	  complete_get_tid },
+	{ "get_rx_tid", cmd_get_rx_tid,
+	  "<BSSID> <STA> <TID> = get STA RX TID counter value",
+	  complete_get_tid },
 	{ NULL, NULL, NULL, NULL }
 };
 

+ 3 - 0
wlantest/wlantest_ctrl.h

@@ -36,6 +36,8 @@ enum wlantest_ctrl_cmd {
 	WLANTEST_CTRL_CLEAR_TDLS_COUNTERS,
 	WLANTEST_CTRL_GET_TDLS_COUNTER,
 	WLANTEST_CTRL_RELOG,
+	WLANTEST_CTRL_GET_TX_TID,
+	WLANTEST_CTRL_GET_RX_TID,
 };
 
 enum wlantest_ctrl_attr {
@@ -56,6 +58,7 @@ enum wlantest_ctrl_attr {
 	WLANTEST_ATTR_TDLS_COUNTER,
 	WLANTEST_ATTR_STA2_ADDR,
 	WLANTEST_ATTR_WEPKEY,
+	WLANTEST_ATTR_TID,
 };
 
 enum wlantest_bss_counter {