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