}
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);
}
}
+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;
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;
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 "
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];
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;
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);
}
u8 gtk[32];
size_t gtk_len;
int gtk_idx;
+
+ u32 tx_tid[16 + 1];
+ u32 rx_tid[16 + 1];
};
struct wlantest_tdls {
}
+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[]);
"<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 }
};
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 {
WLANTEST_ATTR_TDLS_COUNTER,
WLANTEST_ATTR_STA2_ADDR,
WLANTEST_ATTR_WEPKEY,
+ WLANTEST_ATTR_TID,
};
enum wlantest_bss_counter {