static void ctrl_get_bss_counter(struct wlantest *wt, int sock, u8 *cmd, size_t clen) { u8 *addr; size_t addr_len; struct wlantest_bss *bss; u32 counter; u8 buf[4 + 12], *end, *pos; bss = ctrl_get_bss(wt, sock, cmd, clen); if (bss == NULL) return; addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_COUNTER, &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 >= NUM_WLANTEST_BSS_COUNTER) { 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, bss->counters[counter]); ctrl_send(wt, sock, buf, pos - buf); }
static int cmd_get_sta_counter(int s, int argc, char *argv[]) { u8 resp[WLANTEST_CTRL_MAX_RESP_LEN]; u8 buf[100], *end, *pos; int rlen, i; size_t len; if (argc != 3) { printf("get_sta_counter needs at three arguments: " "counter name, BSSID, and STA address\n"); return -1; } pos = buf; end = buf + sizeof(buf); WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_STA_COUNTER); pos += 4; for (i = 0; sta_counters[i].name; i++) { if (os_strcasecmp(sta_counters[i].name, argv[0]) == 0) break; } if (sta_counters[i].name == NULL) { printf("Unknown STA counter '%s'\n", argv[0]); printf("Counters:"); for (i = 0; sta_counters[i].name; i++) printf(" %s", sta_counters[i].name); printf("\n"); return -1; } pos = attr_add_be32(pos, end, WLANTEST_ATTR_STA_COUNTER, sta_counters[i].num); pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN); if (hwaddr_aton(argv[1], pos) < 0) { printf("Invalid BSSID '%s'\n", argv[1]); return -1; } pos += ETH_ALEN; pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN); if (hwaddr_aton(argv[2], pos) < 0) { printf("Invalid STA address '%s'\n", argv[2]); return -1; } pos += ETH_ALEN; 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_info_bss(int s, int argc, char *argv[]) { u8 resp[WLANTEST_CTRL_MAX_RESP_LEN]; u8 buf[100], *end, *pos; int rlen, i; size_t len; char info[100]; if (argc != 2) { printf("bss_info needs at two arguments: " "field name and BSSID\n"); return -1; } pos = buf; end = buf + sizeof(buf); WPA_PUT_BE32(pos, WLANTEST_CTRL_INFO_BSS); pos += 4; for (i = 0; bss_infos[i].name; i++) { if (os_strcasecmp(bss_infos[i].name, argv[0]) == 0) break; } if (bss_infos[i].name == NULL) { printf("Unknown BSS info '%s'\n", argv[0]); printf("Info fields:"); for (i = 0; bss_infos[i].name; i++) printf(" %s", bss_infos[i].name); printf("\n"); return -1; } pos = attr_add_be32(pos, end, WLANTEST_ATTR_BSS_INFO, bss_infos[i].num); pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN); if (hwaddr_aton(argv[1], pos) < 0) { printf("Invalid BSSID '%s'\n", argv[1]); return -1; } pos += ETH_ALEN; 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_INFO, &len); if (pos == NULL) return -1; if (len >= sizeof(info)) len = sizeof(info) - 1; os_memcpy(info, pos, len); info[len] = '\0'; printf("%s\n", info); return 0; }
static int cmd_send(int s, int argc, char *argv[]) { u8 resp[WLANTEST_CTRL_MAX_RESP_LEN]; u8 buf[WLANTEST_CTRL_MAX_CMD_LEN], *end, *pos, *len_pos; int rlen; enum wlantest_inject_protection prot; int arg; /* <prot> <raw frame as hex dump> */ if (argc < 2) { printf("send needs two arguments: protected/unprotected, " "raw frame as hex dump\n"); return -1; } pos = buf; end = buf + sizeof(buf); WPA_PUT_BE32(pos, WLANTEST_CTRL_SEND); pos += 4; if (os_strcasecmp(argv[0], "normal") == 0) prot = WLANTEST_INJECT_NORMAL; else if (os_strcasecmp(argv[0], "protected") == 0) prot = WLANTEST_INJECT_PROTECTED; else if (os_strcasecmp(argv[0], "unprotected") == 0) prot = WLANTEST_INJECT_UNPROTECTED; else if (os_strcasecmp(argv[0], "incorrect") == 0) prot = WLANTEST_INJECT_INCORRECT_KEY; else { printf("Unknown protection type '%s'\n", argv[1]); printf("Protection types: normal protected unprotected " "incorrect\n"); return -1; } pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_PROTECTION, prot); WPA_PUT_BE32(pos, WLANTEST_ATTR_FRAME); pos += 4; len_pos = pos; pos += 4; for (arg = 1; pos && arg < argc; arg++) pos = add_hex(pos, end, argv[arg]); if (pos == NULL) return -1; WPA_PUT_BE32(len_pos, pos - len_pos - 4); rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp)); if (rlen < 0) return -1; printf("OK\n"); return 0; }
static void ctrl_get_tdls_counter(struct wlantest *wt, int sock, u8 *cmd, size_t clen) { u8 *addr; size_t addr_len; struct wlantest_bss *bss; struct wlantest_sta *sta; struct wlantest_sta *sta2; struct wlantest_tdls *tdls; u32 counter; u8 buf[4 + 12], *end, *pos; int found = 0; bss = ctrl_get_bss(wt, sock, cmd, clen); sta = ctrl_get_sta(wt, sock, cmd, clen, bss); sta2 = ctrl_get_sta2(wt, sock, cmd, clen, bss); if (sta == NULL || sta2 == NULL) { ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE); return; } addr = attr_get(cmd, clen, WLANTEST_ATTR_TDLS_COUNTER, &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 >= NUM_WLANTEST_TDLS_COUNTER) { ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD); return; } dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) { if (tdls->init == sta && tdls->resp == sta2) { found = 1; break; } } if (!found) { ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE); 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, tdls->counters[counter]); ctrl_send(wt, sock, buf, pos - buf); }
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 int cmd_inject(int s, int argc, char *argv[]) { u8 resp[WLANTEST_CTRL_MAX_RESP_LEN]; u8 buf[100], *end, *pos; int rlen, i; enum wlantest_inject_protection prot; /* <frame> <prot> <sender> <BSSID> <STA/ff:ff:ff:ff:ff:ff> */ if (argc < 5) { printf("inject needs five arguments: frame, protection, " "sender, BSSID, STA/ff:ff:ff:ff:ff:ff\n"); return -1; } pos = buf; end = buf + sizeof(buf); WPA_PUT_BE32(pos, WLANTEST_CTRL_INJECT); pos += 4; for (i = 0; inject_frames[i].name; i++) { if (os_strcasecmp(inject_frames[i].name, argv[0]) == 0) break; } if (inject_frames[i].name == NULL) { printf("Unknown inject frame '%s'\n", argv[0]); printf("Frames:"); for (i = 0; inject_frames[i].name; i++) printf(" %s", inject_frames[i].name); printf("\n"); return -1; } pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_FRAME, inject_frames[i].frame); if (os_strcasecmp(argv[1], "normal") == 0) prot = WLANTEST_INJECT_NORMAL; else if (os_strcasecmp(argv[1], "protected") == 0) prot = WLANTEST_INJECT_PROTECTED; else if (os_strcasecmp(argv[1], "unprotected") == 0) prot = WLANTEST_INJECT_UNPROTECTED; else if (os_strcasecmp(argv[1], "incorrect") == 0) prot = WLANTEST_INJECT_INCORRECT_KEY; else { printf("Unknown protection type '%s'\n", argv[1]); printf("Protection types: normal protected unprotected " "incorrect\n"); return -1; } pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_PROTECTION, prot); if (os_strcasecmp(argv[2], "ap") == 0) { pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_SENDER_AP, 1); } else if (os_strcasecmp(argv[2], "sta") == 0) { pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_SENDER_AP, 0); } else { printf("Unknown sender '%s'\n", argv[2]); printf("Sender types: ap sta\n"); return -1; } pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN); if (hwaddr_aton(argv[3], pos) < 0) { printf("Invalid BSSID '%s'\n", argv[3]); return -1; } pos += ETH_ALEN; pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN); if (hwaddr_aton(argv[4], pos) < 0) { printf("Invalid STA '%s'\n", argv[4]); return -1; } pos += ETH_ALEN; rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp)); if (rlen < 0) return -1; printf("OK\n"); return 0; }