blob: dcf796f3eba7a62277a4fe0163573bbe0bdff742 [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (wlantest)
3 * Copyright (c) 2010-2011, Atheros Communications, Inc.
Jouni Malinen9d7e31d2017-12-22 18:55:04 +02004 * Copyright (c) 2011-2013, 2017, Qualcomm Atheros, Inc.
Jouni Malinen2feb9132021-11-16 00:53:06 +02005 * Copyright (c) 2019, The Linux Foundation
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006 * All Rights Reserved.
7 * Licensed under the Clear BSD license. See README for more details.
8 */
9
10#include "sigma_dut.h"
11#include <sys/un.h>
12#include "wlantest_ctrl.h"
13
14
15#ifndef ETH_ALEN
16#define ETH_ALEN 6
17#endif
18
19int hwaddr_aton(const char *txt, unsigned char *addr);
20
21
22static u8 * attr_get(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr,
23 size_t *len)
24{
25 u8 *pos = buf;
26
27 while (pos + 8 <= buf + buflen) {
28 enum wlantest_ctrl_attr a;
29 size_t alen;
30 a = WPA_GET_BE32(pos);
31 pos += 4;
32 alen = WPA_GET_BE32(pos);
33 pos += 4;
34 if (pos + alen > buf + buflen)
35 return NULL;
36 if (a == attr) {
37 *len = alen;
38 return pos;
39 }
40 pos += alen;
41 }
42
43 return NULL;
44}
45
46
47static u8 * attr_hdr_add(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
48 size_t len)
49{
50 if (pos == NULL || end - pos < (int) (8 + len))
51 return NULL;
52 WPA_PUT_BE32(pos, attr);
53 pos += 4;
54 WPA_PUT_BE32(pos, len);
55 pos += 4;
56 return pos;
57}
58
59
60static u8 * attr_add_str(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
61 const char *str)
62{
63 size_t len = strlen(str);
64
65 if (pos == NULL || end - pos < (int) (8 + len))
66 return NULL;
67 WPA_PUT_BE32(pos, attr);
68 pos += 4;
69 WPA_PUT_BE32(pos, len);
70 pos += 4;
71 memcpy(pos, str, len);
72 pos += len;
73 return pos;
74}
75
76
77static u8 * attr_add_be32(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
78 u32 val)
79{
80 if (pos == NULL || end - pos < 12)
81 return NULL;
82 WPA_PUT_BE32(pos, attr);
83 pos += 4;
84 WPA_PUT_BE32(pos, 4);
85 pos += 4;
86 WPA_PUT_BE32(pos, val);
87 pos += 4;
88 return pos;
89}
90
91
92static int open_wlantest(void)
93{
94 int s;
95 struct sockaddr_un addr;
96
97 s = socket(AF_UNIX, SOCK_SEQPACKET, 0);
98 if (s < 0) {
99 perror("socket");
100 return -1;
101 }
102
103 memset(&addr, 0, sizeof(addr));
104 addr.sun_family = AF_UNIX;
Peng Xub8fc5cc2017-05-10 17:27:28 -0700105 strlcpy(addr.sun_path + 1, WLANTEST_SOCK_NAME,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200106 sizeof(addr.sun_path) - 1);
107 if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
108 perror("connect");
109 close(s);
110 return -1;
111 }
112
113 return s;
114}
115
116
117static int cmd_send_and_recv(int s, const u8 *cmd, size_t cmd_len,
118 u8 *resp, size_t max_resp_len)
119{
120 int res;
121 enum wlantest_ctrl_cmd cmd_resp;
122
123 if (send(s, cmd, cmd_len, 0) < 0)
124 return -1;
125 res = recv(s, resp, max_resp_len, 0);
126 if (res < 4)
127 return -1;
128
129 cmd_resp = WPA_GET_BE32(resp);
130 if (cmd_resp == WLANTEST_CTRL_SUCCESS)
131 return res;
132
133 return -1;
134}
135
136
137static int cmd_simple(int s, enum wlantest_ctrl_cmd cmd)
138{
139 u8 buf[4];
140 int res;
141 WPA_PUT_BE32(buf, cmd);
142 res = cmd_send_and_recv(s, buf, sizeof(buf), buf, sizeof(buf));
143 return res < 0 ? -1 : 0;
144}
145
146
147static int run_wlantest_simple(struct sigma_dut *dut, struct sigma_conn *conn,
148 enum wlantest_ctrl_cmd cmd)
149{
150 int s, ret;
151
152 s = open_wlantest();
153 if (s < 0) {
154 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
155 "available");
156 return 0;
157 }
158
159 ret = cmd_simple(s, cmd);
160 close(s);
161
162 return ret < 0 ? -2 : 1;
163}
164
165
Jouni Malinenf7222712019-06-13 01:50:21 +0300166static enum sigma_cmd_result cmd_wlantest_version(struct sigma_dut *dut,
167 struct sigma_conn *conn,
168 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200169{
170 int s;
171 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
172 u8 buf[4];
173 char *version;
174 size_t len;
175 int rlen;
176 char *rbuf;
177
178 s = open_wlantest();
179 if (s < 0) {
180 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
181 "available");
182 return 0;
183 }
184
185 WPA_PUT_BE32(buf, WLANTEST_CTRL_VERSION);
186 rlen = cmd_send_and_recv(s, buf, sizeof(buf), resp, sizeof(resp));
187 close(s);
188 if (rlen < 0)
189 return -2;
190
191 version = (char *) attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_VERSION,
192 &len);
193 if (version == NULL)
194 return -2;
195
196 rbuf = malloc(9 + len);
197 if (rbuf == NULL)
198 return -2;
199 memcpy(rbuf, "version,", 8);
200 memcpy(rbuf + 8, version, len);
201 rbuf[8 + len] = '\0';
202 send_resp(dut, conn, SIGMA_COMPLETE, rbuf);
203 free(rbuf);
204 return 0;
205}
206
207
Jouni Malinenf7222712019-06-13 01:50:21 +0300208enum sigma_cmd_result cmd_wlantest_set_channel(struct sigma_dut *dut,
209 struct sigma_conn *conn,
210 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200211{
212 char buf[100];
213 const char *chan;
214
215 if (dut->sniffer_ifname == NULL) {
216 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Sniffer "
217 "interface not available");
218 return 0;
219 }
220
221 chan = get_param(cmd, "channel");
222 if (chan == NULL)
223 return -1;
224
225 snprintf(buf, sizeof(buf), "iw dev %s set type monitor",
226 dut->sniffer_ifname);
227 if (system(buf) != 0) {
228 snprintf(buf, sizeof(buf), "ifconfig %s down",
229 dut->sniffer_ifname);
230 if (system(buf) != 0) {
231 sigma_dut_print(dut, DUT_MSG_INFO,
232 "Failed to run '%s'", buf);
233 return -2;
234 }
235
236 snprintf(buf, sizeof(buf), "iw dev %s set type monitor",
237 dut->sniffer_ifname);
238 if (system(buf) != 0) {
239 sigma_dut_print(dut, DUT_MSG_INFO,
240 "Failed to run '%s'", buf);
241 return -2;
242 }
243 }
244
245 snprintf(buf, sizeof(buf), "iw dev %s set channel %d HT20",
246 dut->sniffer_ifname, atoi(chan));
247 if (system(buf) != 0) {
248 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s'", buf);
249 return -2;
250 }
251
252 snprintf(buf, sizeof(buf), "ifconfig %s up", dut->sniffer_ifname);
253 if (system(buf) != 0) {
254 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s'", buf);
255 return -2;
256 }
257
258 dut->mode = SIGMA_MODE_SNIFFER;
259
260 return 1;
261}
262
263
Jouni Malinenf7222712019-06-13 01:50:21 +0300264static enum sigma_cmd_result cmd_wlantest_flush(struct sigma_dut *dut,
265 struct sigma_conn *conn,
266 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200267{
268 return run_wlantest_simple(dut, conn, WLANTEST_CTRL_FLUSH);
269}
270
271
Jouni Malinenf7222712019-06-13 01:50:21 +0300272enum sigma_cmd_result cmd_wlantest_send_frame(struct sigma_dut *dut,
273 struct sigma_conn *conn,
274 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200275{
276 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
277 u8 buf[100], *end, *pos;
278 int rlen;
279 enum wlantest_inject_frame frame;
280 enum wlantest_inject_protection prot;
281 const char *val;
282 int s;
283
284 /* wlantest_send_frame,PMFFrameType,disassoc,PMFProtected,Unprotected,sender,AP,bssid,00:11:22:33:44:55,stationID,00:66:77:88:99:aa */
285
286 if (dut->mode == SIGMA_MODE_STATION) {
287 sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
288 "wlantest_send_frame to sta_send_frame");
289 return cmd_sta_send_frame(dut, conn, cmd);
290 }
291
292 if (dut->mode == SIGMA_MODE_AP) {
293 sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
294 "wlantest_send_frame to ap_send_frame");
295 return cmd_ap_send_frame(dut, conn, cmd);
296 }
297
298 pos = buf;
299 end = buf + sizeof(buf);
300 WPA_PUT_BE32(pos, WLANTEST_CTRL_INJECT);
301 pos += 4;
302
303 val = get_param(cmd, "Type");
304 if (val == NULL)
305 val = get_param(cmd, "PMFFrameType");
306 if (val == NULL)
307 return -1;
308 if (strcasecmp(val, "disassoc") == 0)
309 frame = WLANTEST_FRAME_DISASSOC;
310 else if (strcasecmp(val, "deauth") == 0)
311 frame = WLANTEST_FRAME_DEAUTH;
312 else if (strcasecmp(val, "saquery") == 0)
313 frame = WLANTEST_FRAME_SAQUERYREQ;
314 else if (strcasecmp(val, "auth") == 0)
315 frame = WLANTEST_FRAME_AUTH;
316 else if (strcasecmp(val, "assocreq") == 0)
317 frame = WLANTEST_FRAME_ASSOCREQ;
318 else if (strcasecmp(val, "reassocreq") == 0)
319 frame = WLANTEST_FRAME_REASSOCREQ;
320 else {
321 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
322 "PMFFrameType");
323 return 0;
324 }
325 pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_FRAME, frame);
326
327 val = get_param(cmd, "Protected");
328 if (val == NULL)
329 val = get_param(cmd, "PMFProtected");
330 if (val == NULL)
331 return -1;
332 if (strcasecmp(val, "CorrectKey") == 0)
333 prot = WLANTEST_INJECT_PROTECTED;
334 else if (strcasecmp(val, "IncorrectKey") == 0)
335 prot = WLANTEST_INJECT_INCORRECT_KEY;
336 else if (strcasecmp(val, "Unprotected") == 0)
337 prot = WLANTEST_INJECT_UNPROTECTED;
338 else {
339 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
340 "PMFProtected");
341 return 0;
342 }
343 pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_PROTECTION, prot);
344
345 val = get_param(cmd, "sender");
346 if (val == NULL)
347 return -1;
348 if (strcasecmp(val, "ap") == 0) {
349 pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_SENDER_AP,
350 1);
351 } else if (strcasecmp(val, "sta") == 0) {
352 pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_SENDER_AP,
353 0);
354 } else {
355 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
356 "sender");
357 return 0;
358 }
359
360 val = get_param(cmd, "bssid");
361 if (val == NULL)
362 return -1;
363 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
364 if (hwaddr_aton(val, pos) < 0) {
365 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid bssid");
366 return 0;
367 }
368 pos += ETH_ALEN;
369
370 val = get_param(cmd, "stationID");
371 if (val == NULL)
372 return -1;
373 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
374 if (hwaddr_aton(val, pos) < 0) {
375 send_resp(dut, conn, SIGMA_INVALID,
376 "errorCode,Invalid stationID");
377 return 0;
378 }
379 pos += ETH_ALEN;
380
381 s = open_wlantest();
382 if (s < 0) {
383 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
384 "available");
385 return 0;
386 }
387 rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
388 close(s);
389 if (rlen < 0)
390 return -2;
391 return 1;
392}
393
394
Jouni Malinenf7222712019-06-13 01:50:21 +0300395static enum sigma_cmd_result
396cmd_wlantest_add_passphrase(struct sigma_dut *dut, struct sigma_conn *conn,
397 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200398{
399 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
400 u8 buf[100], *end, *pos;
401 int rlen;
402 const char *val;
403 int s;
404
405 pos = buf;
406 end = buf + sizeof(buf);
407 WPA_PUT_BE32(pos, WLANTEST_CTRL_ADD_PASSPHRASE);
408 pos += 4;
409
410 val = get_param(cmd, "passphrase");
411 if (val) {
412 if (strlen(val) < 8 || strlen(val) > 63)
413 return -1;
414 pos = attr_add_str(pos, end, WLANTEST_ATTR_PASSPHRASE, val);
415 } else {
416 val = get_param(cmd, "wepkey");
417 if (!val)
418 return -1;
419 pos = attr_add_str(pos, end, WLANTEST_ATTR_WEPKEY, val);
420 }
421 val = get_param(cmd, "bssid");
422 if (val) {
423 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
424 if (hwaddr_aton(val, pos) < 0) {
425 send_resp(dut, conn, SIGMA_INVALID,
426 "errorCode,Invalid bssid");
427 return 0;
428 }
429 pos += ETH_ALEN;
430 }
431
432 s = open_wlantest();
433 if (s < 0) {
434 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
435 "available");
436 return 0;
437 }
438 rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
439 close(s);
440 if (rlen < 0)
441 return -2;
442 return 1;
443}
444
445
Jouni Malinenf7222712019-06-13 01:50:21 +0300446static enum sigma_cmd_result
447cmd_wlantest_clear_sta_counters(struct sigma_dut *dut, struct sigma_conn *conn,
448 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200449{
450 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
451 u8 buf[100], *end, *pos;
452 int rlen;
453 const char *val;
454 int s;
455
456 pos = buf;
457 end = buf + sizeof(buf);
458 WPA_PUT_BE32(pos, WLANTEST_CTRL_CLEAR_STA_COUNTERS);
459 pos += 4;
460
461 val = get_param(cmd, "bssid");
462 if (val == NULL)
463 return -1;
464 if (val) {
465 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
466 if (hwaddr_aton(val, pos) < 0) {
467 send_resp(dut, conn, SIGMA_INVALID,
468 "errorCode,Invalid bssid");
469 return 0;
470 }
471 pos += ETH_ALEN;
472 }
473
474 val = get_param(cmd, "stationID");
475 if (val == NULL)
476 return -1;
477 if (val) {
478 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
479 if (hwaddr_aton(val, pos) < 0) {
480 send_resp(dut, conn, SIGMA_INVALID,
481 "errorCode,Invalid stationID");
482 return 0;
483 }
484 pos += ETH_ALEN;
485 }
486
487 s = open_wlantest();
488 if (s < 0) {
489 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
490 "available");
491 return 0;
492 }
493 rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
494 close(s);
495 if (rlen < 0)
496 return -2;
497 return 1;
498}
499
500
Jouni Malinenf7222712019-06-13 01:50:21 +0300501static enum sigma_cmd_result
502cmd_wlantest_clear_bss_counters(struct sigma_dut *dut, struct sigma_conn *conn,
503 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200504{
505 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
506 u8 buf[100], *end, *pos;
507 int rlen;
508 const char *val;
509 int s;
510
511 pos = buf;
512 end = buf + sizeof(buf);
513 WPA_PUT_BE32(pos, WLANTEST_CTRL_CLEAR_BSS_COUNTERS);
514 pos += 4;
515
516 val = get_param(cmd, "bssid");
517 if (val == NULL)
518 return -1;
519 if (val) {
520 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
521 if (hwaddr_aton(val, pos) < 0) {
522 send_resp(dut, conn, SIGMA_INVALID,
523 "errorCode,Invalid bssid");
524 return 0;
525 }
526 pos += ETH_ALEN;
527 }
528
529 s = open_wlantest();
530 if (s < 0) {
531 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
532 "available");
533 return 0;
534 }
535 rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
536 close(s);
537 if (rlen < 0)
538 return -2;
539 return 1;
540}
541
542
Jouni Malinenf7222712019-06-13 01:50:21 +0300543static enum sigma_cmd_result
544cmd_wlantest_clear_tdls_counters(struct sigma_dut *dut, struct sigma_conn *conn,
545 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200546{
547 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
548 u8 buf[100], *end, *pos;
549 int rlen;
550 const char *val;
551 int s;
552
553 pos = buf;
554 end = buf + sizeof(buf);
555 WPA_PUT_BE32(pos, WLANTEST_CTRL_CLEAR_TDLS_COUNTERS);
556 pos += 4;
557
558 val = get_param(cmd, "bssid");
559 if (val == NULL)
560 return -1;
561 if (val) {
562 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
563 if (hwaddr_aton(val, pos) < 0) {
564 send_resp(dut, conn, SIGMA_INVALID,
565 "errorCode,Invalid bssid");
566 return 0;
567 }
568 pos += ETH_ALEN;
569 }
570
571 val = get_param(cmd, "stationID");
572 if (val == NULL)
573 return -1;
574 if (val) {
575 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
576 if (hwaddr_aton(val, pos) < 0) {
577 send_resp(dut, conn, SIGMA_INVALID,
578 "errorCode,Invalid stationID");
579 return 0;
580 }
581 pos += ETH_ALEN;
582 }
583
584 val = get_param(cmd, "stationID2");
585 if (val == NULL)
586 return -1;
587 if (val) {
588 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA2_ADDR,
589 ETH_ALEN);
590 if (hwaddr_aton(val, pos) < 0) {
591 send_resp(dut, conn, SIGMA_INVALID,
592 "errorCode,Invalid stationID2");
593 return 0;
594 }
595 pos += ETH_ALEN;
596 }
597
598 s = open_wlantest();
599 if (s < 0) {
600 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
601 "available");
602 return 0;
603 }
604 rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
605 close(s);
606 if (rlen < 0)
607 return -2;
608 return 1;
609}
610
611
612struct sta_counters {
613 const char *name;
614 enum wlantest_sta_counter num;
615};
616
617static const struct sta_counters sta_counters[] = {
618 { "auth_tx", WLANTEST_STA_COUNTER_AUTH_TX },
619 { "auth_rx", WLANTEST_STA_COUNTER_AUTH_RX },
620 { "assocreq_tx", WLANTEST_STA_COUNTER_ASSOCREQ_TX },
621 { "reassocreq_tx", WLANTEST_STA_COUNTER_REASSOCREQ_TX },
622 { "ptk_learned", WLANTEST_STA_COUNTER_PTK_LEARNED },
623 { "valid_deauth_tx", WLANTEST_STA_COUNTER_VALID_DEAUTH_TX },
624 { "valid_deauth_rx", WLANTEST_STA_COUNTER_VALID_DEAUTH_RX },
625 { "invalid_deauth_tx", WLANTEST_STA_COUNTER_INVALID_DEAUTH_TX },
626 { "invalid_deauth_rx", WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX },
627 { "valid_disassoc_tx", WLANTEST_STA_COUNTER_VALID_DISASSOC_TX },
628 { "valid_disassoc_rx", WLANTEST_STA_COUNTER_VALID_DISASSOC_RX },
629 { "invalid_disassoc_tx", WLANTEST_STA_COUNTER_INVALID_DISASSOC_TX },
630 { "invalid_disassoc_rx", WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX },
631 { "valid_saqueryreq_tx", WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_TX },
632 { "valid_saqueryreq_rx", WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_RX },
633 { "invalid_saqueryreq_tx",
634 WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_TX },
635 { "invalid_saqueryreq_rx",
636 WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_RX },
637 { "valid_saqueryresp_tx", WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_TX },
638 { "valid_saqueryresp_rx", WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_RX },
639 { "invalid_saqueryresp_tx",
640 WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_TX },
641 { "invalid_saqueryresp_rx",
642 WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_RX },
643 { "ping_ok", WLANTEST_STA_COUNTER_PING_OK },
644 { "assocresp_comeback", WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK },
645 { "reassocresp_comeback", WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK },
646 { "ping_ok_first_assoc", WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC },
647 { "valid_deauth_rx_ack", WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK },
648 { "valid_disassoc_rx_ack",
649 WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK },
650 { "invalid_deauth_rx_ack",
651 WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK },
652 { "invalid_disassoc_rx_ack",
653 WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK },
654 { "deauth_rx_asleep", WLANTEST_STA_COUNTER_DEAUTH_RX_ASLEEP },
655 { "deauth_rx_awake", WLANTEST_STA_COUNTER_DEAUTH_RX_AWAKE },
656 { "disassoc_rx_asleep", WLANTEST_STA_COUNTER_DISASSOC_RX_ASLEEP },
657 { "disassoc_rx_awake", WLANTEST_STA_COUNTER_DISASSOC_RX_AWAKE },
658 { "prot_data_tx", WLANTEST_STA_COUNTER_PROT_DATA_TX },
659 { "deauth_rx_rc6", WLANTEST_STA_COUNTER_DEAUTH_RX_RC6 },
660 { "deauth_rx_rc7", WLANTEST_STA_COUNTER_DEAUTH_RX_RC7 },
661 { "disassoc_rx_rc6", WLANTEST_STA_COUNTER_DISASSOC_RX_RC6 },
662 { "disassoc_rx_rc7", WLANTEST_STA_COUNTER_DISASSOC_RX_RC7 },
663 { NULL, 0 }
664};
665
Jouni Malinenf7222712019-06-13 01:50:21 +0300666static enum sigma_cmd_result
667cmd_wlantest_get_sta_counter(struct sigma_dut *dut, struct sigma_conn *conn,
668 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200669{
670 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
671 u8 buf[100], *end, *pos;
672 int rlen;
673 const char *val;
674 int s, i;
675 char ret[100];
676 size_t len;
677
678 pos = buf;
679 end = buf + sizeof(buf);
680 WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_STA_COUNTER);
681 pos += 4;
682
683 val = get_param(cmd, "bssid");
684 if (val == NULL)
685 return -1;
686 if (val) {
687 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
688 if (hwaddr_aton(val, pos) < 0) {
689 send_resp(dut, conn, SIGMA_INVALID,
690 "errorCode,Invalid bssid");
691 return 0;
692 }
693 pos += ETH_ALEN;
694 }
695
696 val = get_param(cmd, "stationID");
697 if (val == NULL)
698 return -1;
699 if (val) {
700 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
701 if (hwaddr_aton(val, pos) < 0) {
702 send_resp(dut, conn, SIGMA_INVALID,
703 "errorCode,Invalid stationID");
704 return 0;
705 }
706 pos += ETH_ALEN;
707 }
708
709 val = get_param(cmd, "field");
710 if (val == NULL)
711 return -1;
712 for (i = 0; sta_counters[i].name; i++) {
713 if (strcasecmp(sta_counters[i].name, val) == 0)
714 break;
715 }
716 if (sta_counters[i].name == NULL) {
717 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid field");
718 return 0;
719 }
720 pos = attr_add_be32(pos, end, WLANTEST_ATTR_STA_COUNTER,
721 sta_counters[i].num);
722
723 s = open_wlantest();
724 if (s < 0) {
725 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
726 "available");
727 return 0;
728 }
729 rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
730 close(s);
731
732
733 pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
734 if (pos == NULL || len != 4)
735 return -2;
736 snprintf(ret, sizeof(ret), "counter,%u", WPA_GET_BE32(pos));
737 send_resp(dut, conn, SIGMA_COMPLETE, ret);
738 return 0;
739}
740
741
742struct bss_counters {
743 const char *name;
744 enum wlantest_bss_counter num;
745};
746
747static const struct bss_counters bss_counters[] = {
748 { "valid_bip_mmie", WLANTEST_BSS_COUNTER_VALID_BIP_MMIE },
749 { "invalid_bip_mmie", WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE },
750 { "missing_bip_mmie", WLANTEST_BSS_COUNTER_MISSING_BIP_MMIE },
751 { "bip_deauth", WLANTEST_BSS_COUNTER_BIP_DEAUTH },
752 { "bip_disassoc", WLANTEST_BSS_COUNTER_BIP_DISASSOC },
753 { NULL, 0 }
754};
755
Jouni Malinenf7222712019-06-13 01:50:21 +0300756static enum sigma_cmd_result
757cmd_wlantest_get_bss_counter(struct sigma_dut *dut, struct sigma_conn *conn,
758 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200759{
760 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
761 u8 buf[100], *end, *pos;
762 int rlen;
763 const char *val;
764 int s, i;
765 char ret[100];
766 size_t len;
767
768 pos = buf;
769 end = buf + sizeof(buf);
770 WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_BSS_COUNTER);
771 pos += 4;
772
773 val = get_param(cmd, "bssid");
774 if (val == NULL)
775 return -1;
776 if (val) {
777 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
778 if (hwaddr_aton(val, pos) < 0) {
779 send_resp(dut, conn, SIGMA_INVALID,
780 "errorCode,Invalid bssid");
781 return 0;
782 }
783 pos += ETH_ALEN;
784 }
785
786 val = get_param(cmd, "field");
787 if (val == NULL)
788 return -1;
789 for (i = 0; bss_counters[i].name; i++) {
790 if (strcasecmp(bss_counters[i].name, val) == 0)
791 break;
792 }
793 if (bss_counters[i].name == NULL) {
794 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid field");
795 return 0;
796 }
797 pos = attr_add_be32(pos, end, WLANTEST_ATTR_BSS_COUNTER,
798 bss_counters[i].num);
799
800 s = open_wlantest();
801 if (s < 0) {
802 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
803 "available");
804 return 0;
805 }
806 rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
807 close(s);
808
809 pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
810 if (pos == NULL || len != 4)
811 return -2;
812 snprintf(ret, sizeof(ret), "counter,%u", WPA_GET_BE32(pos));
813 send_resp(dut, conn, SIGMA_COMPLETE, ret);
814 return 0;
815}
816
817
818struct tdls_counters {
819 const char *name;
820 enum wlantest_tdls_counter num;
821};
822
823static const struct tdls_counters tdls_counters[] = {
824 { "valid_direct_link", WLANTEST_TDLS_COUNTER_VALID_DIRECT_LINK },
825 { "invalid_direct_link", WLANTEST_TDLS_COUNTER_INVALID_DIRECT_LINK },
826 { "valid_ap_path", WLANTEST_TDLS_COUNTER_VALID_AP_PATH },
827 { "invalid_ap_path", WLANTEST_TDLS_COUNTER_INVALID_AP_PATH },
828 { "setup_req", WLANTEST_TDLS_COUNTER_SETUP_REQ },
829 { "setup_resp_ok", WLANTEST_TDLS_COUNTER_SETUP_RESP_OK },
830 { "setup_resp_fail", WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL },
831 { "setup_conf_ok", WLANTEST_TDLS_COUNTER_SETUP_CONF_OK },
832 { "setup_conf_fail", WLANTEST_TDLS_COUNTER_SETUP_CONF_FAIL },
833 { "teardown", WLANTEST_TDLS_COUNTER_TEARDOWN },
834 { NULL, 0 }
835};
836
Jouni Malinenf7222712019-06-13 01:50:21 +0300837static enum sigma_cmd_result
838cmd_wlantest_get_tdls_counter(struct sigma_dut *dut, struct sigma_conn *conn,
839 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200840{
841 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
842 u8 buf[100], *end, *pos;
843 int rlen;
844 const char *val;
845 int s, i;
846 char ret[100];
847 size_t len;
848
849 pos = buf;
850 end = buf + sizeof(buf);
851 WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_TDLS_COUNTER);
852 pos += 4;
853
854 val = get_param(cmd, "bssid");
855 if (val == NULL)
856 return -1;
857 if (val) {
858 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
859 if (hwaddr_aton(val, pos) < 0) {
860 send_resp(dut, conn, SIGMA_INVALID,
861 "errorCode,Invalid bssid");
862 return 0;
863 }
864 pos += ETH_ALEN;
865 }
866
867 val = get_param(cmd, "stationID");
868 if (val == NULL)
869 return -1;
870 if (val) {
871 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
872 if (hwaddr_aton(val, pos) < 0) {
873 send_resp(dut, conn, SIGMA_INVALID,
874 "errorCode,Invalid stationID");
875 return 0;
876 }
877 pos += ETH_ALEN;
878 }
879
880 val = get_param(cmd, "stationID2");
881 if (val == NULL)
882 return -1;
883 if (val) {
884 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA2_ADDR,
885 ETH_ALEN);
886 if (hwaddr_aton(val, pos) < 0) {
887 send_resp(dut, conn, SIGMA_INVALID,
888 "errorCode,Invalid stationID");
889 return 0;
890 }
891 pos += ETH_ALEN;
892 }
893
894 val = get_param(cmd, "field");
895 if (val == NULL)
896 return -1;
897 for (i = 0; tdls_counters[i].name; i++) {
898 if (strcasecmp(tdls_counters[i].name, val) == 0)
899 break;
900 }
901 if (tdls_counters[i].name == NULL) {
902 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid field");
903 return 0;
904 }
905 pos = attr_add_be32(pos, end, WLANTEST_ATTR_TDLS_COUNTER,
906 tdls_counters[i].num);
907
908 s = open_wlantest();
909 if (s < 0) {
910 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
911 "available");
912 return 0;
913 }
914 rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
915 close(s);
916
917
918 pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
919 if (pos == NULL || len != 4)
920 return -2;
921 snprintf(ret, sizeof(ret), "counter,%u", WPA_GET_BE32(pos));
922 send_resp(dut, conn, SIGMA_COMPLETE, ret);
923 return 0;
924}
925
926
927struct sta_infos {
928 const char *name;
929 enum wlantest_sta_info num;
930};
931
932static const struct sta_infos sta_infos[] = {
933 { "proto", WLANTEST_STA_INFO_PROTO },
934 { "pairwise", WLANTEST_STA_INFO_PAIRWISE },
935 { "key_mgmt", WLANTEST_STA_INFO_KEY_MGMT },
936 { "rsn_capab", WLANTEST_STA_INFO_RSN_CAPAB },
937 { "state", WLANTEST_STA_INFO_STATE },
938 { NULL, 0 }
939};
940
Jouni Malinenf7222712019-06-13 01:50:21 +0300941static enum sigma_cmd_result cmd_wlantest_info_sta(struct sigma_dut *dut,
942 struct sigma_conn *conn,
943 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200944{
945 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
946 u8 buf[100], *end, *pos;
947 int rlen;
948 const char *val;
949 int s, i;
950 char ret[120];
951 size_t len;
952 char info[100];
953
954 pos = buf;
955 end = buf + sizeof(buf);
956 WPA_PUT_BE32(pos, WLANTEST_CTRL_INFO_STA);
957 pos += 4;
958
959 val = get_param(cmd, "bssid");
960 if (val == NULL)
961 return -1;
962 if (val) {
963 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
964 if (hwaddr_aton(val, pos) < 0) {
965 send_resp(dut, conn, SIGMA_INVALID,
966 "errorCode,Invalid bssid");
967 return 0;
968 }
969 pos += ETH_ALEN;
970 }
971
972 val = get_param(cmd, "stationID");
973 if (val == NULL)
974 return -1;
975 if (val) {
976 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
977 if (hwaddr_aton(val, pos) < 0) {
978 send_resp(dut, conn, SIGMA_INVALID,
979 "errorCode,Invalid stationID");
980 return 0;
981 }
982 pos += ETH_ALEN;
983 }
984
985 val = get_param(cmd, "field");
986 if (val == NULL)
987 return -1;
988 for (i = 0; sta_infos[i].name; i++) {
989 if (strcasecmp(sta_infos[i].name, val) == 0)
990 break;
991 }
992 if (sta_infos[i].name == NULL) {
993 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid field");
994 return 0;
995 }
996 pos = attr_add_be32(pos, end, WLANTEST_ATTR_STA_INFO,
997 sta_infos[i].num);
998
999 s = open_wlantest();
1000 if (s < 0) {
1001 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
1002 "available");
1003 return 0;
1004 }
1005 rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
1006 close(s);
1007
1008
1009 pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_INFO, &len);
1010 if (pos == NULL)
1011 return -2;
1012 if (len >= sizeof(info))
1013 len = sizeof(info) - 1;
1014 memcpy(info, pos, len);
1015 info[len] = '\0';
1016 snprintf(ret, sizeof(ret), "info,%s", info);
1017 send_resp(dut, conn, SIGMA_COMPLETE, ret);
1018 return 0;
1019}
1020
1021
1022struct bss_infos {
1023 const char *name;
1024 enum wlantest_bss_info num;
1025};
1026
1027static const struct bss_infos bss_infos[] = {
1028 { "proto", WLANTEST_BSS_INFO_PROTO },
1029 { "pairwise", WLANTEST_BSS_INFO_PAIRWISE },
1030 { "group", WLANTEST_BSS_INFO_GROUP },
1031 { "group_mgmt", WLANTEST_BSS_INFO_GROUP_MGMT },
1032 { "key_mgmt", WLANTEST_BSS_INFO_KEY_MGMT },
1033 { "rsn_capab", WLANTEST_BSS_INFO_RSN_CAPAB },
1034 { NULL, 0 }
1035};
1036
Jouni Malinenf7222712019-06-13 01:50:21 +03001037static enum sigma_cmd_result cmd_wlantest_info_bss(struct sigma_dut *dut,
1038 struct sigma_conn *conn,
1039 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001040{
1041 u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
1042 u8 buf[100], *end, *pos;
1043 int rlen;
1044 const char *val;
1045 int s, i;
1046 char ret[120];
1047 size_t len;
1048 char info[100];
1049
1050 pos = buf;
1051 end = buf + sizeof(buf);
1052 WPA_PUT_BE32(pos, WLANTEST_CTRL_INFO_BSS);
1053 pos += 4;
1054
1055 val = get_param(cmd, "bssid");
1056 if (val == NULL)
1057 return -1;
1058 if (val) {
1059 pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
1060 if (hwaddr_aton(val, pos) < 0) {
1061 send_resp(dut, conn, SIGMA_INVALID,
1062 "errorCode,Invalid bssid");
1063 return 0;
1064 }
1065 pos += ETH_ALEN;
1066 }
1067
1068 val = get_param(cmd, "field");
1069 if (val == NULL)
1070 return -1;
1071 for (i = 0; bss_infos[i].name; i++) {
1072 if (strcasecmp(bss_infos[i].name, val) == 0)
1073 break;
1074 }
1075 if (bss_infos[i].name == NULL) {
1076 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid field");
1077 return 0;
1078 }
1079 pos = attr_add_be32(pos, end, WLANTEST_ATTR_BSS_INFO,
1080 bss_infos[i].num);
1081
1082 s = open_wlantest();
1083 if (s < 0) {
1084 send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
1085 "available");
1086 return 0;
1087 }
1088 rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
1089 close(s);
1090
1091
1092 pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_INFO, &len);
1093 if (pos == NULL)
1094 return -2;
1095 if (len >= sizeof(info))
1096 len = sizeof(info) - 1;
1097 memcpy(info, pos, len);
1098 info[len] = '\0';
1099 snprintf(ret, sizeof(ret), "info,%s", info);
1100 send_resp(dut, conn, SIGMA_COMPLETE, ret);
1101 return 0;
1102}
1103
1104
1105void wlantest_register_cmds(void)
1106{
1107 sigma_dut_reg_cmd("wlantest_version", NULL, cmd_wlantest_version);
1108 sigma_dut_reg_cmd("wlantest_set_channel", NULL,
1109 cmd_wlantest_set_channel);
1110 sigma_dut_reg_cmd("wlantest_flush", NULL, cmd_wlantest_flush);
1111 sigma_dut_reg_cmd("wlantest_send_frame", NULL,
1112 cmd_wlantest_send_frame);
1113 sigma_dut_reg_cmd("wlantest_add_passphrase", NULL,
1114 cmd_wlantest_add_passphrase);
1115 sigma_dut_reg_cmd("wlantest_clear_sta_counters", NULL,
1116 cmd_wlantest_clear_sta_counters);
1117 sigma_dut_reg_cmd("wlantest_clear_bss_counters", NULL,
1118 cmd_wlantest_clear_bss_counters);
1119 sigma_dut_reg_cmd("wlantest_clear_tdls_counters", NULL,
1120 cmd_wlantest_clear_tdls_counters);
1121 sigma_dut_reg_cmd("wlantest_get_sta_counter", NULL,
1122 cmd_wlantest_get_sta_counter);
1123 sigma_dut_reg_cmd("wlantest_get_bss_counter", NULL,
1124 cmd_wlantest_get_bss_counter);
1125 sigma_dut_reg_cmd("wlantest_get_tdls_counter", NULL,
1126 cmd_wlantest_get_tdls_counter);
1127 sigma_dut_reg_cmd("wlantest_info_sta", NULL, cmd_wlantest_info_sta);
1128 sigma_dut_reg_cmd("wlantest_info_bss", NULL, cmd_wlantest_info_bss);
1129}