blob: a1db53a4fcb9590aa6739b4665803ef5ca00bf73 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15#include "includes.h"
16
17#ifdef CONFIG_CTRL_IFACE
18
19#ifdef CONFIG_CTRL_IFACE_UNIX
20#include <dirent.h>
21#endif /* CONFIG_CTRL_IFACE_UNIX */
22
23#include "common/wpa_ctrl.h"
24#include "utils/common.h"
25#include "utils/eloop.h"
26#include "utils/edit.h"
27#include "common/version.h"
28#ifdef ANDROID
29#include <cutils/properties.h>
30#endif /* ANDROID */
31
32
33static const char *wpa_cli_version =
34"wpa_cli v" VERSION_STR "\n"
35"Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> and contributors";
36
37
38static const char *wpa_cli_license =
39"This program is free software. You can distribute it and/or modify it\n"
40"under the terms of the GNU General Public License version 2.\n"
41"\n"
42"Alternatively, this software may be distributed under the terms of the\n"
43"BSD license. See README and COPYING for more details.\n";
44
45static const char *wpa_cli_full_license =
46"This program is free software; you can redistribute it and/or modify\n"
47"it under the terms of the GNU General Public License version 2 as\n"
48"published by the Free Software Foundation.\n"
49"\n"
50"This program is distributed in the hope that it will be useful,\n"
51"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
52"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
53"GNU General Public License for more details.\n"
54"\n"
55"You should have received a copy of the GNU General Public License\n"
56"along with this program; if not, write to the Free Software\n"
57"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
58"\n"
59"Alternatively, this software may be distributed under the terms of the\n"
60"BSD license.\n"
61"\n"
62"Redistribution and use in source and binary forms, with or without\n"
63"modification, are permitted provided that the following conditions are\n"
64"met:\n"
65"\n"
66"1. Redistributions of source code must retain the above copyright\n"
67" notice, this list of conditions and the following disclaimer.\n"
68"\n"
69"2. Redistributions in binary form must reproduce the above copyright\n"
70" notice, this list of conditions and the following disclaimer in the\n"
71" documentation and/or other materials provided with the distribution.\n"
72"\n"
73"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
74" names of its contributors may be used to endorse or promote products\n"
75" derived from this software without specific prior written permission.\n"
76"\n"
77"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
78"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
79"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
80"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
81"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
82"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
83"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
84"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
85"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
86"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
87"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
88"\n";
89
90static struct wpa_ctrl *ctrl_conn;
91static struct wpa_ctrl *mon_conn;
92static int wpa_cli_quit = 0;
93static int wpa_cli_attached = 0;
94static int wpa_cli_connected = 0;
95static int wpa_cli_last_id = 0;
96#ifndef CONFIG_CTRL_IFACE_DIR
97#define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
98#endif /* CONFIG_CTRL_IFACE_DIR */
99static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
100static char *ctrl_ifname = NULL;
101static const char *pid_file = NULL;
102static const char *action_file = NULL;
103static int ping_interval = 5;
104static int interactive = 0;
105
106
107static void print_help(void);
108static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
109
110
111static void usage(void)
112{
113 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
114 "[-a<action file>] \\\n"
115 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
116 "[command..]\n"
117 " -h = help (show this usage text)\n"
118 " -v = shown version information\n"
119 " -a = run in daemon mode executing the action file based on "
120 "events from\n"
121 " wpa_supplicant\n"
122 " -B = run a daemon in the background\n"
123 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
124 " default interface: first interface found in socket path\n");
125 print_help();
126}
127
128
129static int str_starts(const char *src, const char *match)
130{
131 return os_strncmp(src, match, os_strlen(match)) == 0;
132}
133
134
135static int wpa_cli_show_event(const char *event)
136{
137 const char *start;
138
139 start = os_strchr(event, '>');
140 if (start == NULL)
141 return 1;
142
143 start++;
144 /*
145 * Skip BSS added/removed events since they can be relatively frequent
146 * and are likely of not much use for an interactive user.
147 */
148 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
149 str_starts(start, WPA_EVENT_BSS_REMOVED))
150 return 0;
151
152 return 1;
153}
154
155
156static int wpa_cli_open_connection(const char *ifname, int attach)
157{
158#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
159 ctrl_conn = wpa_ctrl_open(ifname);
160 if (ctrl_conn == NULL)
161 return -1;
162
163 if (attach && interactive)
164 mon_conn = wpa_ctrl_open(ifname);
165 else
166 mon_conn = NULL;
167#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
168 char *cfile = NULL;
169 int flen, res;
170
171 if (ifname == NULL)
172 return -1;
173
174#ifdef ANDROID
175 if (access(ctrl_iface_dir, F_OK) < 0) {
176 cfile = os_strdup(ifname);
177 if (cfile == NULL)
178 return -1;
179 }
180#endif /* ANDROID */
181
182 if (cfile == NULL) {
183 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
184 cfile = os_malloc(flen);
185 if (cfile == NULL)
186 return -1;
187 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
188 ifname);
189 if (res < 0 || res >= flen) {
190 os_free(cfile);
191 return -1;
192 }
193 }
194
195 ctrl_conn = wpa_ctrl_open(cfile);
196 if (ctrl_conn == NULL) {
197 os_free(cfile);
198 return -1;
199 }
200
201 if (attach && interactive)
202 mon_conn = wpa_ctrl_open(cfile);
203 else
204 mon_conn = NULL;
205 os_free(cfile);
206#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
207
208 if (mon_conn) {
209 if (wpa_ctrl_attach(mon_conn) == 0) {
210 wpa_cli_attached = 1;
211 if (interactive)
212 eloop_register_read_sock(
213 wpa_ctrl_get_fd(mon_conn),
214 wpa_cli_mon_receive, NULL, NULL);
215 } else {
216 printf("Warning: Failed to attach to "
217 "wpa_supplicant.\n");
218 return -1;
219 }
220 }
221
222 return 0;
223}
224
225
226static void wpa_cli_close_connection(void)
227{
228 if (ctrl_conn == NULL)
229 return;
230
231 if (wpa_cli_attached) {
232 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
233 wpa_cli_attached = 0;
234 }
235 wpa_ctrl_close(ctrl_conn);
236 ctrl_conn = NULL;
237 if (mon_conn) {
238 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
239 wpa_ctrl_close(mon_conn);
240 mon_conn = NULL;
241 }
242}
243
244
245static void wpa_cli_msg_cb(char *msg, size_t len)
246{
247 printf("%s\n", msg);
248}
249
250
251static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
252{
253 char buf[2048];
254 size_t len;
255 int ret;
256
257 if (ctrl_conn == NULL) {
258 printf("Not connected to wpa_supplicant - command dropped.\n");
259 return -1;
260 }
261 len = sizeof(buf) - 1;
262 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
263 wpa_cli_msg_cb);
264 if (ret == -2) {
265 printf("'%s' command timed out.\n", cmd);
266 return -2;
267 } else if (ret < 0) {
268 printf("'%s' command failed.\n", cmd);
269 return -1;
270 }
271 if (print) {
272 buf[len] = '\0';
273 printf("%s", buf);
274 if (interactive && len > 0 && buf[len - 1] != '\n')
275 printf("\n");
276 }
277 return 0;
278}
279
280
281static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
282{
283 return _wpa_ctrl_command(ctrl, cmd, 1);
284}
285
286
287static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
288{
289 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
290 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
291}
292
293
294static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
295{
296 return wpa_ctrl_command(ctrl, "PING");
297}
298
299
300static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
301{
302 return wpa_ctrl_command(ctrl, "RELOG");
303}
304
305
306static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
307{
308 char cmd[256];
309 int ret;
310 if (argc == 0)
311 return -1;
312 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
313 if (ret < 0 || (size_t) ret >= sizeof(cmd))
314 return -1;
315 return wpa_ctrl_command(ctrl, cmd);
316}
317
318
319static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
320{
321 return wpa_ctrl_command(ctrl, "MIB");
322}
323
324
325static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
326{
327 return wpa_ctrl_command(ctrl, "PMKSA");
328}
329
330
331static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
332{
333 print_help();
334 return 0;
335}
336
337
338static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
339{
340 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
341 return 0;
342}
343
344
345static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
346{
347 wpa_cli_quit = 1;
348 if (interactive)
349 eloop_terminate();
350 return 0;
351}
352
353
354static void wpa_cli_show_variables(void)
355{
356 printf("set variables:\n"
357 " EAPOL::heldPeriod (EAPOL state machine held period, "
358 "in seconds)\n"
359 " EAPOL::authPeriod (EAPOL state machine authentication "
360 "period, in seconds)\n"
361 " EAPOL::startPeriod (EAPOL state machine start period, in "
362 "seconds)\n"
363 " EAPOL::maxStart (EAPOL state machine maximum start "
364 "attempts)\n");
365 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
366 "seconds)\n"
367 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
368 " threshold\n\tpercentage)\n"
369 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
370 "security\n\tassociation in seconds)\n");
371}
372
373
374static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
375{
376 char cmd[256];
377 int res;
378
379 if (argc == 0) {
380 wpa_cli_show_variables();
381 return 0;
382 }
383
384 if (argc != 2) {
385 printf("Invalid SET command: needs two arguments (variable "
386 "name and value)\n");
387 return -1;
388 }
389
390 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
391 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
392 printf("Too long SET command.\n");
393 return -1;
394 }
395 return wpa_ctrl_command(ctrl, cmd);
396}
397
398
399static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
400{
401 char cmd[256];
402 int res;
403
404 if (argc != 1) {
405 printf("Invalid GET command: need one argument (variable "
406 "name)\n");
407 return -1;
408 }
409
410 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
411 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
412 printf("Too long GET command.\n");
413 return -1;
414 }
415 return wpa_ctrl_command(ctrl, cmd);
416}
417
418
419static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
420{
421 return wpa_ctrl_command(ctrl, "LOGOFF");
422}
423
424
425static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
426{
427 return wpa_ctrl_command(ctrl, "LOGON");
428}
429
430
431static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
432 char *argv[])
433{
434 return wpa_ctrl_command(ctrl, "REASSOCIATE");
435}
436
437
438static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
439 char *argv[])
440{
441 char cmd[256];
442 int res;
443
444 if (argc != 1) {
445 printf("Invalid PREAUTH command: needs one argument "
446 "(BSSID)\n");
447 return -1;
448 }
449
450 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
451 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
452 printf("Too long PREAUTH command.\n");
453 return -1;
454 }
455 return wpa_ctrl_command(ctrl, cmd);
456}
457
458
459static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
460{
461 char cmd[256];
462 int res;
463
464 if (argc != 1) {
465 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
466 "value)\n");
467 return -1;
468 }
469 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
470 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
471 printf("Too long AP_SCAN command.\n");
472 return -1;
473 }
474 return wpa_ctrl_command(ctrl, cmd);
475}
476
477
478static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
479 char *argv[])
480{
481 char cmd[256];
482 int res;
483
484 if (argc != 1) {
485 printf("Invalid SCAN_INTERVAL command: needs one argument "
486 "scan_interval value)\n");
487 return -1;
488 }
489 res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
490 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
491 printf("Too long SCAN_INTERVAL command.\n");
492 return -1;
493 }
494 return wpa_ctrl_command(ctrl, cmd);
495}
496
497
498static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
499 char *argv[])
500{
501 char cmd[256];
502 int res;
503
504 if (argc != 1) {
505 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
506 "(bss_expire_age value)\n");
507 return -1;
508 }
509 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
510 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
511 printf("Too long BSS_EXPIRE_AGE command.\n");
512 return -1;
513 }
514 return wpa_ctrl_command(ctrl, cmd);
515}
516
517
518static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
519 char *argv[])
520{
521 char cmd[256];
522 int res;
523
524 if (argc != 1) {
525 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
526 "(bss_expire_count value)\n");
527 return -1;
528 }
529 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
530 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
531 printf("Too long BSS_EXPIRE_COUNT command.\n");
532 return -1;
533 }
534 return wpa_ctrl_command(ctrl, cmd);
535}
536
537
538static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
539 char *argv[])
540{
541 char cmd[256];
542 int res;
543
544 if (argc != 1) {
545 printf("Invalid STKSTART command: needs one argument "
546 "(Peer STA MAC address)\n");
547 return -1;
548 }
549
550 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
551 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
552 printf("Too long STKSTART command.\n");
553 return -1;
554 }
555 return wpa_ctrl_command(ctrl, cmd);
556}
557
558
559static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
560{
561 char cmd[256];
562 int res;
563
564 if (argc != 1) {
565 printf("Invalid FT_DS command: needs one argument "
566 "(Target AP MAC address)\n");
567 return -1;
568 }
569
570 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
571 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
572 printf("Too long FT_DS command.\n");
573 return -1;
574 }
575 return wpa_ctrl_command(ctrl, cmd);
576}
577
578
579static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
580{
581 char cmd[256];
582 int res;
583
584 if (argc == 0) {
585 /* Any BSSID */
586 return wpa_ctrl_command(ctrl, "WPS_PBC");
587 }
588
589 /* Specific BSSID */
590 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
591 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
592 printf("Too long WPS_PBC command.\n");
593 return -1;
594 }
595 return wpa_ctrl_command(ctrl, cmd);
596}
597
598
599static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
600{
601 char cmd[256];
602 int res;
603
604 if (argc == 0) {
605 printf("Invalid WPS_PIN command: need one or two arguments:\n"
606 "- BSSID: use 'any' to select any\n"
607 "- PIN: optional, used only with devices that have no "
608 "display\n");
609 return -1;
610 }
611
612 if (argc == 1) {
613 /* Use dynamically generated PIN (returned as reply) */
614 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
615 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
616 printf("Too long WPS_PIN command.\n");
617 return -1;
618 }
619 return wpa_ctrl_command(ctrl, cmd);
620 }
621
622 /* Use hardcoded PIN from a label */
623 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
624 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
625 printf("Too long WPS_PIN command.\n");
626 return -1;
627 }
628 return wpa_ctrl_command(ctrl, cmd);
629}
630
631
632static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
633 char *argv[])
634{
635 char cmd[256];
636 int res;
637
638 if (argc != 1 && argc != 2) {
639 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
640 "- PIN to be verified\n");
641 return -1;
642 }
643
644 if (argc == 2)
645 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
646 argv[0], argv[1]);
647 else
648 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
649 argv[0]);
650 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
651 printf("Too long WPS_CHECK_PIN command.\n");
652 return -1;
653 }
654 return wpa_ctrl_command(ctrl, cmd);
655}
656
657
658static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
659 char *argv[])
660{
661 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
662}
663
664
665#ifdef CONFIG_WPS_OOB
666static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
667{
668 char cmd[256];
669 int res;
670
671 if (argc != 3 && argc != 4) {
672 printf("Invalid WPS_OOB command: need three or four "
673 "arguments:\n"
674 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
675 "- PATH: path of OOB device like '/mnt'\n"
676 "- METHOD: OOB method 'pin-e' or 'pin-r', "
677 "'cred'\n"
678 "- DEV_NAME: (only for NFC) device name like "
679 "'pn531'\n");
680 return -1;
681 }
682
683 if (argc == 3)
684 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
685 argv[0], argv[1], argv[2]);
686 else
687 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
688 argv[0], argv[1], argv[2], argv[3]);
689 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
690 printf("Too long WPS_OOB command.\n");
691 return -1;
692 }
693 return wpa_ctrl_command(ctrl, cmd);
694}
695#endif /* CONFIG_WPS_OOB */
696
697
698static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
699{
700 char cmd[256];
701 int res;
702
703 if (argc == 2)
704 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
705 argv[0], argv[1]);
706 else if (argc == 5 || argc == 6) {
707 char ssid_hex[2 * 32 + 1];
708 char key_hex[2 * 64 + 1];
709 int i;
710
711 ssid_hex[0] = '\0';
712 for (i = 0; i < 32; i++) {
713 if (argv[2][i] == '\0')
714 break;
715 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
716 }
717
718 key_hex[0] = '\0';
719 if (argc == 6) {
720 for (i = 0; i < 64; i++) {
721 if (argv[5][i] == '\0')
722 break;
723 os_snprintf(&key_hex[i * 2], 3, "%02x",
724 argv[5][i]);
725 }
726 }
727
728 res = os_snprintf(cmd, sizeof(cmd),
729 "WPS_REG %s %s %s %s %s %s",
730 argv[0], argv[1], ssid_hex, argv[3], argv[4],
731 key_hex);
732 } else {
733 printf("Invalid WPS_REG command: need two arguments:\n"
734 "- BSSID of the target AP\n"
735 "- AP PIN\n");
736 printf("Alternatively, six arguments can be used to "
737 "reconfigure the AP:\n"
738 "- BSSID of the target AP\n"
739 "- AP PIN\n"
740 "- new SSID\n"
741 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
742 "- new encr (NONE, WEP, TKIP, CCMP)\n"
743 "- new key\n");
744 return -1;
745 }
746
747 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
748 printf("Too long WPS_REG command.\n");
749 return -1;
750 }
751 return wpa_ctrl_command(ctrl, cmd);
752}
753
754
755static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
756 char *argv[])
757{
758 char cmd[256];
759 int res;
760
761 if (argc < 1) {
762 printf("Invalid WPS_AP_PIN command: needs at least one "
763 "argument\n");
764 return -1;
765 }
766
767 if (argc > 2)
768 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
769 argv[0], argv[1], argv[2]);
770 else if (argc > 1)
771 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
772 argv[0], argv[1]);
773 else
774 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
775 argv[0]);
776 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
777 printf("Too long WPS_AP_PIN command.\n");
778 return -1;
779 }
780 return wpa_ctrl_command(ctrl, cmd);
781}
782
783
784static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
785 char *argv[])
786{
787 char cmd[100];
788 if (argc > 0) {
789 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
790 return wpa_ctrl_command(ctrl, cmd);
791 }
792 return wpa_ctrl_command(ctrl, "WPS_ER_START");
793}
794
795
796static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
797 char *argv[])
798{
799 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
800
801}
802
803
804static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
805 char *argv[])
806{
807 char cmd[256];
808 int res;
809
810 if (argc < 2) {
811 printf("Invalid WPS_ER_PIN command: need at least two "
812 "arguments:\n"
813 "- UUID: use 'any' to select any\n"
814 "- PIN: Enrollee PIN\n"
815 "optional: - Enrollee MAC address\n");
816 return -1;
817 }
818
819 if (argc > 2)
820 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
821 argv[0], argv[1], argv[2]);
822 else
823 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
824 argv[0], argv[1]);
825 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
826 printf("Too long WPS_ER_PIN command.\n");
827 return -1;
828 }
829 return wpa_ctrl_command(ctrl, cmd);
830}
831
832
833static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
834 char *argv[])
835{
836 char cmd[256];
837 int res;
838
839 if (argc != 1) {
840 printf("Invalid WPS_ER_PBC command: need one argument:\n"
841 "- UUID: Specify the Enrollee\n");
842 return -1;
843 }
844
845 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
846 argv[0]);
847 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
848 printf("Too long WPS_ER_PBC command.\n");
849 return -1;
850 }
851 return wpa_ctrl_command(ctrl, cmd);
852}
853
854
855static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
856 char *argv[])
857{
858 char cmd[256];
859 int res;
860
861 if (argc != 2) {
862 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
863 "- UUID: specify which AP to use\n"
864 "- PIN: AP PIN\n");
865 return -1;
866 }
867
868 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
869 argv[0], argv[1]);
870 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
871 printf("Too long WPS_ER_LEARN command.\n");
872 return -1;
873 }
874 return wpa_ctrl_command(ctrl, cmd);
875}
876
877
878static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
879 char *argv[])
880{
881 char cmd[256];
882 int res;
883
884 if (argc != 2) {
885 printf("Invalid WPS_ER_SET_CONFIG command: need two "
886 "arguments:\n"
887 "- UUID: specify which AP to use\n"
888 "- Network configuration id\n");
889 return -1;
890 }
891
892 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
893 argv[0], argv[1]);
894 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
895 printf("Too long WPS_ER_SET_CONFIG command.\n");
896 return -1;
897 }
898 return wpa_ctrl_command(ctrl, cmd);
899}
900
901
902static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
903 char *argv[])
904{
905 char cmd[256];
906 int res;
907
908 if (argc == 5 || argc == 6) {
909 char ssid_hex[2 * 32 + 1];
910 char key_hex[2 * 64 + 1];
911 int i;
912
913 ssid_hex[0] = '\0';
914 for (i = 0; i < 32; i++) {
915 if (argv[2][i] == '\0')
916 break;
917 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
918 }
919
920 key_hex[0] = '\0';
921 if (argc == 6) {
922 for (i = 0; i < 64; i++) {
923 if (argv[5][i] == '\0')
924 break;
925 os_snprintf(&key_hex[i * 2], 3, "%02x",
926 argv[5][i]);
927 }
928 }
929
930 res = os_snprintf(cmd, sizeof(cmd),
931 "WPS_ER_CONFIG %s %s %s %s %s %s",
932 argv[0], argv[1], ssid_hex, argv[3], argv[4],
933 key_hex);
934 } else {
935 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
936 "- AP UUID\n"
937 "- AP PIN\n"
938 "- new SSID\n"
939 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
940 "- new encr (NONE, WEP, TKIP, CCMP)\n"
941 "- new key\n");
942 return -1;
943 }
944
945 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
946 printf("Too long WPS_ER_CONFIG command.\n");
947 return -1;
948 }
949 return wpa_ctrl_command(ctrl, cmd);
950}
951
952
953static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
954{
955 char cmd[256];
956 int res;
957
958 if (argc != 1) {
959 printf("Invalid IBSS_RSN command: needs one argument "
960 "(Peer STA MAC address)\n");
961 return -1;
962 }
963
964 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
965 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
966 printf("Too long IBSS_RSN command.\n");
967 return -1;
968 }
969 return wpa_ctrl_command(ctrl, cmd);
970}
971
972
973static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
974{
975 char cmd[256];
976 int res;
977
978 if (argc != 1) {
979 printf("Invalid LEVEL command: needs one argument (debug "
980 "level)\n");
981 return -1;
982 }
983 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
984 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
985 printf("Too long LEVEL command.\n");
986 return -1;
987 }
988 return wpa_ctrl_command(ctrl, cmd);
989}
990
991
992static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
993{
994 char cmd[256], *pos, *end;
995 int i, ret;
996
997 if (argc < 2) {
998 printf("Invalid IDENTITY command: needs two arguments "
999 "(network id and identity)\n");
1000 return -1;
1001 }
1002
1003 end = cmd + sizeof(cmd);
1004 pos = cmd;
1005 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1006 argv[0], argv[1]);
1007 if (ret < 0 || ret >= end - pos) {
1008 printf("Too long IDENTITY command.\n");
1009 return -1;
1010 }
1011 pos += ret;
1012 for (i = 2; i < argc; i++) {
1013 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1014 if (ret < 0 || ret >= end - pos) {
1015 printf("Too long IDENTITY command.\n");
1016 return -1;
1017 }
1018 pos += ret;
1019 }
1020
1021 return wpa_ctrl_command(ctrl, cmd);
1022}
1023
1024
1025static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1026{
1027 char cmd[256], *pos, *end;
1028 int i, ret;
1029
1030 if (argc < 2) {
1031 printf("Invalid PASSWORD command: needs two arguments "
1032 "(network id and password)\n");
1033 return -1;
1034 }
1035
1036 end = cmd + sizeof(cmd);
1037 pos = cmd;
1038 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1039 argv[0], argv[1]);
1040 if (ret < 0 || ret >= end - pos) {
1041 printf("Too long PASSWORD command.\n");
1042 return -1;
1043 }
1044 pos += ret;
1045 for (i = 2; i < argc; i++) {
1046 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1047 if (ret < 0 || ret >= end - pos) {
1048 printf("Too long PASSWORD command.\n");
1049 return -1;
1050 }
1051 pos += ret;
1052 }
1053
1054 return wpa_ctrl_command(ctrl, cmd);
1055}
1056
1057
1058static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1059 char *argv[])
1060{
1061 char cmd[256], *pos, *end;
1062 int i, ret;
1063
1064 if (argc < 2) {
1065 printf("Invalid NEW_PASSWORD command: needs two arguments "
1066 "(network id and password)\n");
1067 return -1;
1068 }
1069
1070 end = cmd + sizeof(cmd);
1071 pos = cmd;
1072 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1073 argv[0], argv[1]);
1074 if (ret < 0 || ret >= end - pos) {
1075 printf("Too long NEW_PASSWORD command.\n");
1076 return -1;
1077 }
1078 pos += ret;
1079 for (i = 2; i < argc; i++) {
1080 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1081 if (ret < 0 || ret >= end - pos) {
1082 printf("Too long NEW_PASSWORD command.\n");
1083 return -1;
1084 }
1085 pos += ret;
1086 }
1087
1088 return wpa_ctrl_command(ctrl, cmd);
1089}
1090
1091
1092static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1093{
1094 char cmd[256], *pos, *end;
1095 int i, ret;
1096
1097 if (argc < 2) {
1098 printf("Invalid PIN command: needs two arguments "
1099 "(network id and pin)\n");
1100 return -1;
1101 }
1102
1103 end = cmd + sizeof(cmd);
1104 pos = cmd;
1105 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1106 argv[0], argv[1]);
1107 if (ret < 0 || ret >= end - pos) {
1108 printf("Too long PIN command.\n");
1109 return -1;
1110 }
1111 pos += ret;
1112 for (i = 2; i < argc; i++) {
1113 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1114 if (ret < 0 || ret >= end - pos) {
1115 printf("Too long PIN command.\n");
1116 return -1;
1117 }
1118 pos += ret;
1119 }
1120 return wpa_ctrl_command(ctrl, cmd);
1121}
1122
1123
1124static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1125{
1126 char cmd[256], *pos, *end;
1127 int i, ret;
1128
1129 if (argc < 2) {
1130 printf("Invalid OTP command: needs two arguments (network "
1131 "id and password)\n");
1132 return -1;
1133 }
1134
1135 end = cmd + sizeof(cmd);
1136 pos = cmd;
1137 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1138 argv[0], argv[1]);
1139 if (ret < 0 || ret >= end - pos) {
1140 printf("Too long OTP command.\n");
1141 return -1;
1142 }
1143 pos += ret;
1144 for (i = 2; i < argc; i++) {
1145 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1146 if (ret < 0 || ret >= end - pos) {
1147 printf("Too long OTP command.\n");
1148 return -1;
1149 }
1150 pos += ret;
1151 }
1152
1153 return wpa_ctrl_command(ctrl, cmd);
1154}
1155
1156
1157static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1158 char *argv[])
1159{
1160 char cmd[256], *pos, *end;
1161 int i, ret;
1162
1163 if (argc < 2) {
1164 printf("Invalid PASSPHRASE command: needs two arguments "
1165 "(network id and passphrase)\n");
1166 return -1;
1167 }
1168
1169 end = cmd + sizeof(cmd);
1170 pos = cmd;
1171 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1172 argv[0], argv[1]);
1173 if (ret < 0 || ret >= end - pos) {
1174 printf("Too long PASSPHRASE command.\n");
1175 return -1;
1176 }
1177 pos += ret;
1178 for (i = 2; i < argc; i++) {
1179 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1180 if (ret < 0 || ret >= end - pos) {
1181 printf("Too long PASSPHRASE command.\n");
1182 return -1;
1183 }
1184 pos += ret;
1185 }
1186
1187 return wpa_ctrl_command(ctrl, cmd);
1188}
1189
1190
1191static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1192{
1193 char cmd[256], *pos, *end;
1194 int i, ret;
1195
1196 if (argc < 2) {
1197 printf("Invalid BSSID command: needs two arguments (network "
1198 "id and BSSID)\n");
1199 return -1;
1200 }
1201
1202 end = cmd + sizeof(cmd);
1203 pos = cmd;
1204 ret = os_snprintf(pos, end - pos, "BSSID");
1205 if (ret < 0 || ret >= end - pos) {
1206 printf("Too long BSSID command.\n");
1207 return -1;
1208 }
1209 pos += ret;
1210 for (i = 0; i < argc; i++) {
1211 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1212 if (ret < 0 || ret >= end - pos) {
1213 printf("Too long BSSID command.\n");
1214 return -1;
1215 }
1216 pos += ret;
1217 }
1218
1219 return wpa_ctrl_command(ctrl, cmd);
1220}
1221
1222
1223static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1224 char *argv[])
1225{
1226 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1227}
1228
1229
1230static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1231 char *argv[])
1232{
1233 char cmd[32];
1234 int res;
1235
1236 if (argc < 1) {
1237 printf("Invalid SELECT_NETWORK command: needs one argument "
1238 "(network id)\n");
1239 return -1;
1240 }
1241
1242 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1243 if (res < 0 || (size_t) res >= sizeof(cmd))
1244 return -1;
1245 cmd[sizeof(cmd) - 1] = '\0';
1246
1247 return wpa_ctrl_command(ctrl, cmd);
1248}
1249
1250
1251static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1252 char *argv[])
1253{
1254 char cmd[32];
1255 int res;
1256
1257 if (argc < 1) {
1258 printf("Invalid ENABLE_NETWORK command: needs one argument "
1259 "(network id)\n");
1260 return -1;
1261 }
1262
1263 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1264 if (res < 0 || (size_t) res >= sizeof(cmd))
1265 return -1;
1266 cmd[sizeof(cmd) - 1] = '\0';
1267
1268 return wpa_ctrl_command(ctrl, cmd);
1269}
1270
1271
1272static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1273 char *argv[])
1274{
1275 char cmd[32];
1276 int res;
1277
1278 if (argc < 1) {
1279 printf("Invalid DISABLE_NETWORK command: needs one argument "
1280 "(network id)\n");
1281 return -1;
1282 }
1283
1284 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1285 if (res < 0 || (size_t) res >= sizeof(cmd))
1286 return -1;
1287 cmd[sizeof(cmd) - 1] = '\0';
1288
1289 return wpa_ctrl_command(ctrl, cmd);
1290}
1291
1292
1293static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1294 char *argv[])
1295{
1296 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1297}
1298
1299
1300static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1301 char *argv[])
1302{
1303 char cmd[32];
1304 int res;
1305
1306 if (argc < 1) {
1307 printf("Invalid REMOVE_NETWORK command: needs one argument "
1308 "(network id)\n");
1309 return -1;
1310 }
1311
1312 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1313 if (res < 0 || (size_t) res >= sizeof(cmd))
1314 return -1;
1315 cmd[sizeof(cmd) - 1] = '\0';
1316
1317 return wpa_ctrl_command(ctrl, cmd);
1318}
1319
1320
1321static void wpa_cli_show_network_variables(void)
1322{
1323 printf("set_network variables:\n"
1324 " ssid (network name, SSID)\n"
1325 " psk (WPA passphrase or pre-shared key)\n"
1326 " key_mgmt (key management protocol)\n"
1327 " identity (EAP identity)\n"
1328 " password (EAP password)\n"
1329 " ...\n"
1330 "\n"
1331 "Note: Values are entered in the same format as the "
1332 "configuration file is using,\n"
1333 "i.e., strings values need to be inside double quotation "
1334 "marks.\n"
1335 "For example: set_network 1 ssid \"network name\"\n"
1336 "\n"
1337 "Please see wpa_supplicant.conf documentation for full list "
1338 "of\navailable variables.\n");
1339}
1340
1341
1342static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1343 char *argv[])
1344{
1345 char cmd[256];
1346 int res;
1347
1348 if (argc == 0) {
1349 wpa_cli_show_network_variables();
1350 return 0;
1351 }
1352
1353 if (argc != 3) {
1354 printf("Invalid SET_NETWORK command: needs three arguments\n"
1355 "(network id, variable name, and value)\n");
1356 return -1;
1357 }
1358
1359 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1360 argv[0], argv[1], argv[2]);
1361 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1362 printf("Too long SET_NETWORK command.\n");
1363 return -1;
1364 }
1365 return wpa_ctrl_command(ctrl, cmd);
1366}
1367
1368
1369static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1370 char *argv[])
1371{
1372 char cmd[256];
1373 int res;
1374
1375 if (argc == 0) {
1376 wpa_cli_show_network_variables();
1377 return 0;
1378 }
1379
1380 if (argc != 2) {
1381 printf("Invalid GET_NETWORK command: needs two arguments\n"
1382 "(network id and variable name)\n");
1383 return -1;
1384 }
1385
1386 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1387 argv[0], argv[1]);
1388 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1389 printf("Too long GET_NETWORK command.\n");
1390 return -1;
1391 }
1392 return wpa_ctrl_command(ctrl, cmd);
1393}
1394
1395
1396static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1397 char *argv[])
1398{
1399 return wpa_ctrl_command(ctrl, "DISCONNECT");
1400}
1401
1402
1403static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1404 char *argv[])
1405{
1406 return wpa_ctrl_command(ctrl, "RECONNECT");
1407}
1408
1409
1410static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1411 char *argv[])
1412{
1413 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1414}
1415
1416
1417static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1418{
1419 return wpa_ctrl_command(ctrl, "SCAN");
1420}
1421
1422
1423static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1424 char *argv[])
1425{
1426 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1427}
1428
1429
1430static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1431{
1432 char cmd[64];
1433 int res;
1434
1435 if (argc != 1) {
1436 printf("Invalid BSS command: need one argument (index or "
1437 "BSSID)\n");
1438 return -1;
1439 }
1440
1441 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1442 if (res < 0 || (size_t) res >= sizeof(cmd))
1443 return -1;
1444 cmd[sizeof(cmd) - 1] = '\0';
1445
1446 return wpa_ctrl_command(ctrl, cmd);
1447}
1448
1449
1450static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1451 char *argv[])
1452{
1453 char cmd[64];
1454 int res;
1455
1456 if (argc < 1 || argc > 2) {
1457 printf("Invalid GET_CAPABILITY command: need either one or "
1458 "two arguments\n");
1459 return -1;
1460 }
1461
1462 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1463 printf("Invalid GET_CAPABILITY command: second argument, "
1464 "if any, must be 'strict'\n");
1465 return -1;
1466 }
1467
1468 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1469 (argc == 2) ? " strict" : "");
1470 if (res < 0 || (size_t) res >= sizeof(cmd))
1471 return -1;
1472 cmd[sizeof(cmd) - 1] = '\0';
1473
1474 return wpa_ctrl_command(ctrl, cmd);
1475}
1476
1477
1478static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1479{
1480 printf("Available interfaces:\n");
1481 return wpa_ctrl_command(ctrl, "INTERFACES");
1482}
1483
1484
1485static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1486{
1487 if (argc < 1) {
1488 wpa_cli_list_interfaces(ctrl);
1489 return 0;
1490 }
1491
1492 wpa_cli_close_connection();
1493 os_free(ctrl_ifname);
1494 ctrl_ifname = os_strdup(argv[0]);
1495
1496 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1497 printf("Connected to interface '%s.\n", ctrl_ifname);
1498 } else {
1499 printf("Could not connect to interface '%s' - re-trying\n",
1500 ctrl_ifname);
1501 }
1502 return 0;
1503}
1504
1505
1506static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1507 char *argv[])
1508{
1509 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1510}
1511
1512
1513static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1514 char *argv[])
1515{
1516 return wpa_ctrl_command(ctrl, "TERMINATE");
1517}
1518
1519
1520static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1521 char *argv[])
1522{
1523 char cmd[256];
1524 int res;
1525
1526 if (argc < 1) {
1527 printf("Invalid INTERFACE_ADD command: needs at least one "
1528 "argument (interface name)\n"
1529 "All arguments: ifname confname driver ctrl_interface "
1530 "driver_param bridge_name\n");
1531 return -1;
1532 }
1533
1534 /*
1535 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1536 * <driver_param>TAB<bridge_name>
1537 */
1538 res = os_snprintf(cmd, sizeof(cmd),
1539 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1540 argv[0],
1541 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1542 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1543 argc > 5 ? argv[5] : "");
1544 if (res < 0 || (size_t) res >= sizeof(cmd))
1545 return -1;
1546 cmd[sizeof(cmd) - 1] = '\0';
1547 return wpa_ctrl_command(ctrl, cmd);
1548}
1549
1550
1551static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1552 char *argv[])
1553{
1554 char cmd[128];
1555 int res;
1556
1557 if (argc != 1) {
1558 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1559 "(interface name)\n");
1560 return -1;
1561 }
1562
1563 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1564 if (res < 0 || (size_t) res >= sizeof(cmd))
1565 return -1;
1566 cmd[sizeof(cmd) - 1] = '\0';
1567 return wpa_ctrl_command(ctrl, cmd);
1568}
1569
1570
1571static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1572 char *argv[])
1573{
1574 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1575}
1576
1577
1578#ifdef CONFIG_AP
1579static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1580{
1581 char buf[64];
1582 if (argc != 1) {
1583 printf("Invalid 'sta' command - exactly one argument, STA "
1584 "address, is required.\n");
1585 return -1;
1586 }
1587 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1588 return wpa_ctrl_command(ctrl, buf);
1589}
1590
1591
1592static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1593 char *addr, size_t addr_len)
1594{
1595 char buf[4096], *pos;
1596 size_t len;
1597 int ret;
1598
1599 if (ctrl_conn == NULL) {
1600 printf("Not connected to hostapd - command dropped.\n");
1601 return -1;
1602 }
1603 len = sizeof(buf) - 1;
1604 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1605 wpa_cli_msg_cb);
1606 if (ret == -2) {
1607 printf("'%s' command timed out.\n", cmd);
1608 return -2;
1609 } else if (ret < 0) {
1610 printf("'%s' command failed.\n", cmd);
1611 return -1;
1612 }
1613
1614 buf[len] = '\0';
1615 if (memcmp(buf, "FAIL", 4) == 0)
1616 return -1;
1617 printf("%s", buf);
1618
1619 pos = buf;
1620 while (*pos != '\0' && *pos != '\n')
1621 pos++;
1622 *pos = '\0';
1623 os_strlcpy(addr, buf, addr_len);
1624 return 0;
1625}
1626
1627
1628static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1629{
1630 char addr[32], cmd[64];
1631
1632 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1633 return 0;
1634 do {
1635 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1636 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1637
1638 return -1;
1639}
1640#endif /* CONFIG_AP */
1641
1642
1643static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1644{
1645 return wpa_ctrl_command(ctrl, "SUSPEND");
1646}
1647
1648
1649static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1650{
1651 return wpa_ctrl_command(ctrl, "RESUME");
1652}
1653
1654
1655static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1656{
1657 return wpa_ctrl_command(ctrl, "DROP_SA");
1658}
1659
1660
1661static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1662{
1663 char cmd[128];
1664 int res;
1665
1666 if (argc != 1) {
1667 printf("Invalid ROAM command: needs one argument "
1668 "(target AP's BSSID)\n");
1669 return -1;
1670 }
1671
1672 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1673 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1674 printf("Too long ROAM command.\n");
1675 return -1;
1676 }
1677 return wpa_ctrl_command(ctrl, cmd);
1678}
1679
1680
1681#ifdef CONFIG_P2P
1682
1683static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1684{
1685 char cmd[128];
1686 int res;
1687
1688 if (argc == 0)
1689 return wpa_ctrl_command(ctrl, "P2P_FIND");
1690
1691 if (argc > 1)
1692 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1693 argv[0], argv[1]);
1694 else
1695 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1696 if (res < 0 || (size_t) res >= sizeof(cmd))
1697 return -1;
1698 cmd[sizeof(cmd) - 1] = '\0';
1699 return wpa_ctrl_command(ctrl, cmd);
1700}
1701
1702
1703static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1704 char *argv[])
1705{
1706 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1707}
1708
1709
1710static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1711 char *argv[])
1712{
1713 char cmd[128];
1714 int res;
1715
1716 if (argc < 2) {
1717 printf("Invalid P2P_CONNECT command: needs at least two "
1718 "arguments (address and pbc/PIN)\n");
1719 return -1;
1720 }
1721
1722 if (argc > 4)
1723 res = os_snprintf(cmd, sizeof(cmd),
1724 "P2P_CONNECT %s %s %s %s %s",
1725 argv[0], argv[1], argv[2], argv[3],
1726 argv[4]);
1727 else if (argc > 3)
1728 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1729 argv[0], argv[1], argv[2], argv[3]);
1730 else if (argc > 2)
1731 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1732 argv[0], argv[1], argv[2]);
1733 else
1734 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1735 argv[0], argv[1]);
1736 if (res < 0 || (size_t) res >= sizeof(cmd))
1737 return -1;
1738 cmd[sizeof(cmd) - 1] = '\0';
1739 return wpa_ctrl_command(ctrl, cmd);
1740}
1741
1742
1743static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1744 char *argv[])
1745{
1746 char cmd[128];
1747 int res;
1748
1749 if (argc == 0)
1750 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1751
1752 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1753 if (res < 0 || (size_t) res >= sizeof(cmd))
1754 return -1;
1755 cmd[sizeof(cmd) - 1] = '\0';
1756 return wpa_ctrl_command(ctrl, cmd);
1757}
1758
1759
1760static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1761 char *argv[])
1762{
1763 char cmd[128];
1764 int res;
1765
1766 if (argc != 1) {
1767 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1768 "(interface name)\n");
1769 return -1;
1770 }
1771
1772 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
1773 if (res < 0 || (size_t) res >= sizeof(cmd))
1774 return -1;
1775 cmd[sizeof(cmd) - 1] = '\0';
1776 return wpa_ctrl_command(ctrl, cmd);
1777}
1778
1779
1780static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1781 char *argv[])
1782{
1783 char cmd[128];
1784 int res;
1785
1786 if (argc == 0)
1787 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
1788
1789 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", argv[0]);
1790 if (res < 0 || (size_t) res >= sizeof(cmd))
1791 return -1;
1792 cmd[sizeof(cmd) - 1] = '\0';
1793 return wpa_ctrl_command(ctrl, cmd);
1794}
1795
1796
1797static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1798 char *argv[])
1799{
1800 char cmd[128];
1801 int res;
1802
1803 if (argc != 2) {
1804 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1805 "(address and config method\n"
1806 "(display, keypad, or pbc)\n");
1807 return -1;
1808 }
1809
1810 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
1811 argv[0], argv[1]);
1812 if (res < 0 || (size_t) res >= sizeof(cmd))
1813 return -1;
1814 cmd[sizeof(cmd) - 1] = '\0';
1815 return wpa_ctrl_command(ctrl, cmd);
1816}
1817
1818
1819static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1820 char *argv[])
1821{
1822 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1823}
1824
1825
1826static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1827 char *argv[])
1828{
1829 char cmd[4096];
1830 int res;
1831
1832 if (argc != 2 && argc != 4) {
1833 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1834 "arguments (address and TLVs) or four arguments "
1835 "(address, \"upnp\", version, search target "
1836 "(SSDP ST:)\n");
1837 return -1;
1838 }
1839
1840 if (argc == 4)
1841 res = os_snprintf(cmd, sizeof(cmd),
1842 "P2P_SERV_DISC_REQ %s %s %s %s",
1843 argv[0], argv[1], argv[2], argv[3]);
1844 else
1845 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
1846 argv[0], argv[1]);
1847 if (res < 0 || (size_t) res >= sizeof(cmd))
1848 return -1;
1849 cmd[sizeof(cmd) - 1] = '\0';
1850 return wpa_ctrl_command(ctrl, cmd);
1851}
1852
1853
1854static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1855 int argc, char *argv[])
1856{
1857 char cmd[128];
1858 int res;
1859
1860 if (argc != 1) {
1861 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1862 "argument (pending request identifier)\n");
1863 return -1;
1864 }
1865
1866 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
1867 argv[0]);
1868 if (res < 0 || (size_t) res >= sizeof(cmd))
1869 return -1;
1870 cmd[sizeof(cmd) - 1] = '\0';
1871 return wpa_ctrl_command(ctrl, cmd);
1872}
1873
1874
1875static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1876 char *argv[])
1877{
1878 char cmd[4096];
1879 int res;
1880
1881 if (argc != 4) {
1882 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1883 "arguments (freq, address, dialog token, and TLVs)\n");
1884 return -1;
1885 }
1886
1887 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1888 argv[0], argv[1], argv[2], argv[3]);
1889 if (res < 0 || (size_t) res >= sizeof(cmd))
1890 return -1;
1891 cmd[sizeof(cmd) - 1] = '\0';
1892 return wpa_ctrl_command(ctrl, cmd);
1893}
1894
1895
1896static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1897 char *argv[])
1898{
1899 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1900}
1901
1902
1903static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1904 int argc, char *argv[])
1905{
1906 char cmd[128];
1907 int res;
1908
1909 if (argc != 1) {
1910 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1911 "argument (external processing: 0/1)\n");
1912 return -1;
1913 }
1914
1915 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
1916 argv[0]);
1917 if (res < 0 || (size_t) res >= sizeof(cmd))
1918 return -1;
1919 cmd[sizeof(cmd) - 1] = '\0';
1920 return wpa_ctrl_command(ctrl, cmd);
1921}
1922
1923
1924static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1925 char *argv[])
1926{
1927 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1928}
1929
1930
1931static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1932 char *argv[])
1933{
1934 char cmd[4096];
1935 int res;
1936
1937 if (argc != 3 && argc != 4) {
1938 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1939 "arguments\n");
1940 return -1;
1941 }
1942
1943 if (argc == 4)
1944 res = os_snprintf(cmd, sizeof(cmd),
1945 "P2P_SERVICE_ADD %s %s %s %s",
1946 argv[0], argv[1], argv[2], argv[3]);
1947 else
1948 res = os_snprintf(cmd, sizeof(cmd),
1949 "P2P_SERVICE_ADD %s %s %s",
1950 argv[0], argv[1], argv[2]);
1951 if (res < 0 || (size_t) res >= sizeof(cmd))
1952 return -1;
1953 cmd[sizeof(cmd) - 1] = '\0';
1954 return wpa_ctrl_command(ctrl, cmd);
1955}
1956
1957
1958static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1959 char *argv[])
1960{
1961 char cmd[4096];
1962 int res;
1963
1964 if (argc != 2 && argc != 3) {
1965 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1966 "arguments\n");
1967 return -1;
1968 }
1969
1970 if (argc == 3)
1971 res = os_snprintf(cmd, sizeof(cmd),
1972 "P2P_SERVICE_DEL %s %s %s",
1973 argv[0], argv[1], argv[2]);
1974 else
1975 res = os_snprintf(cmd, sizeof(cmd),
1976 "P2P_SERVICE_DEL %s %s",
1977 argv[0], argv[1]);
1978 if (res < 0 || (size_t) res >= sizeof(cmd))
1979 return -1;
1980 cmd[sizeof(cmd) - 1] = '\0';
1981 return wpa_ctrl_command(ctrl, cmd);
1982}
1983
1984
1985static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1986 int argc, char *argv[])
1987{
1988 char cmd[128];
1989 int res;
1990
1991 if (argc != 1) {
1992 printf("Invalid P2P_REJECT command: needs one argument "
1993 "(peer address)\n");
1994 return -1;
1995 }
1996
1997 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
1998 if (res < 0 || (size_t) res >= sizeof(cmd))
1999 return -1;
2000 cmd[sizeof(cmd) - 1] = '\0';
2001 return wpa_ctrl_command(ctrl, cmd);
2002}
2003
2004
2005static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2006 int argc, char *argv[])
2007{
2008 char cmd[128];
2009 int res;
2010
2011 if (argc < 1) {
2012 printf("Invalid P2P_INVITE command: needs at least one "
2013 "argument\n");
2014 return -1;
2015 }
2016
2017 if (argc > 2)
2018 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2019 argv[0], argv[1], argv[2]);
2020 else if (argc > 1)
2021 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2022 argv[0], argv[1]);
2023 else
2024 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2025 if (res < 0 || (size_t) res >= sizeof(cmd))
2026 return -1;
2027 cmd[sizeof(cmd) - 1] = '\0';
2028 return wpa_ctrl_command(ctrl, cmd);
2029}
2030
2031
2032static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2033{
2034 char buf[64];
2035 if (argc != 1) {
2036 printf("Invalid 'p2p_peer' command - exactly one argument, "
2037 "P2P peer device address, is required.\n");
2038 return -1;
2039 }
2040 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2041 return wpa_ctrl_command(ctrl, buf);
2042}
2043
2044
2045static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2046 char *addr, size_t addr_len,
2047 int discovered)
2048{
2049 char buf[4096], *pos;
2050 size_t len;
2051 int ret;
2052
2053 if (ctrl_conn == NULL)
2054 return -1;
2055 len = sizeof(buf) - 1;
2056 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2057 wpa_cli_msg_cb);
2058 if (ret == -2) {
2059 printf("'%s' command timed out.\n", cmd);
2060 return -2;
2061 } else if (ret < 0) {
2062 printf("'%s' command failed.\n", cmd);
2063 return -1;
2064 }
2065
2066 buf[len] = '\0';
2067 if (memcmp(buf, "FAIL", 4) == 0)
2068 return -1;
2069
2070 pos = buf;
2071 while (*pos != '\0' && *pos != '\n')
2072 pos++;
2073 *pos++ = '\0';
2074 os_strlcpy(addr, buf, addr_len);
2075 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2076 printf("%s\n", addr);
2077 return 0;
2078}
2079
2080
2081static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2082{
2083 char addr[32], cmd[64];
2084 int discovered;
2085
2086 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2087
2088 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2089 addr, sizeof(addr), discovered))
2090 return 0;
2091 do {
2092 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2093 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2094 discovered) == 0);
2095
2096 return -1;
2097}
2098
2099
2100static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2101{
2102 char cmd[100];
2103 int res;
2104
2105 if (argc != 2) {
2106 printf("Invalid P2P_SET command: needs two arguments (field, "
2107 "value)\n");
2108 return -1;
2109 }
2110
2111 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2112 if (res < 0 || (size_t) res >= sizeof(cmd))
2113 return -1;
2114 cmd[sizeof(cmd) - 1] = '\0';
2115 return wpa_ctrl_command(ctrl, cmd);
2116}
2117
2118
2119static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2120{
2121 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2122}
2123
2124
2125static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2126 char *argv[])
2127{
2128 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2129}
2130
2131
2132static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2133 char *argv[])
2134{
2135 char cmd[100];
2136 int res;
2137
2138 if (argc != 1) {
2139 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2140 "(peer address)\n");
2141 return -1;
2142 }
2143
2144 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2145
2146 if (res < 0 || (size_t) res >= sizeof(cmd))
2147 return -1;
2148
2149 cmd[sizeof(cmd) - 1] = '\0';
2150 return wpa_ctrl_command(ctrl, cmd);
2151}
2152
2153
2154static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2155 char *argv[])
2156{
2157 char cmd[100];
2158 int res;
2159
2160 if (argc != 0 && argc != 2 && argc != 4) {
2161 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2162 "(preferred duration, interval; in microsecods).\n"
2163 "Optional second pair can be used to provide "
2164 "acceptable values.\n");
2165 return -1;
2166 }
2167
2168 if (argc == 4)
2169 res = os_snprintf(cmd, sizeof(cmd),
2170 "P2P_PRESENCE_REQ %s %s %s %s",
2171 argv[0], argv[1], argv[2], argv[3]);
2172 else if (argc == 2)
2173 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2174 argv[0], argv[1]);
2175 else
2176 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2177 if (res < 0 || (size_t) res >= sizeof(cmd))
2178 return -1;
2179 cmd[sizeof(cmd) - 1] = '\0';
2180 return wpa_ctrl_command(ctrl, cmd);
2181}
2182
2183
2184static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2185 char *argv[])
2186{
2187 char cmd[100];
2188 int res;
2189
2190 if (argc != 0 && argc != 2) {
2191 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2192 "(availability period, availability interval; in "
2193 "millisecods).\n"
2194 "Extended Listen Timing can be cancelled with this "
2195 "command when used without parameters.\n");
2196 return -1;
2197 }
2198
2199 if (argc == 2)
2200 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2201 argv[0], argv[1]);
2202 else
2203 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2204 if (res < 0 || (size_t) res >= sizeof(cmd))
2205 return -1;
2206 cmd[sizeof(cmd) - 1] = '\0';
2207 return wpa_ctrl_command(ctrl, cmd);
2208}
2209
2210#endif /* CONFIG_P2P */
2211
2212
2213static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2214 char *argv[])
2215{
2216 char cmd[256];
2217 int res;
2218
2219 if (argc != 1) {
2220 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2221 "(0/1 = disable/enable automatic reconnection)\n");
2222 return -1;
2223 }
2224 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2225 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2226 printf("Too long STA_AUTOCONNECT command.\n");
2227 return -1;
2228 }
2229 return wpa_ctrl_command(ctrl, cmd);
2230}
2231
2232
2233static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2234 char *argv[])
2235{
2236 char cmd[256];
2237 int res;
2238
2239 if (argc != 1) {
2240 printf("Invalid TDLS_DISCOVER command: needs one argument "
2241 "(Peer STA MAC address)\n");
2242 return -1;
2243 }
2244
2245 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2246 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2247 printf("Too long TDLS_DISCOVER command.\n");
2248 return -1;
2249 }
2250 return wpa_ctrl_command(ctrl, cmd);
2251}
2252
2253
2254static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2255 char *argv[])
2256{
2257 char cmd[256];
2258 int res;
2259
2260 if (argc != 1) {
2261 printf("Invalid TDLS_SETUP command: needs one argument "
2262 "(Peer STA MAC address)\n");
2263 return -1;
2264 }
2265
2266 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2267 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2268 printf("Too long TDLS_SETUP command.\n");
2269 return -1;
2270 }
2271 return wpa_ctrl_command(ctrl, cmd);
2272}
2273
2274
2275static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2276 char *argv[])
2277{
2278 char cmd[256];
2279 int res;
2280
2281 if (argc != 1) {
2282 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2283 "(Peer STA MAC address)\n");
2284 return -1;
2285 }
2286
2287 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2288 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2289 printf("Too long TDLS_TEARDOWN command.\n");
2290 return -1;
2291 }
2292 return wpa_ctrl_command(ctrl, cmd);
2293}
2294
2295
2296static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2297 char *argv[])
2298{
2299 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2300}
2301
2302
2303enum wpa_cli_cmd_flags {
2304 cli_cmd_flag_none = 0x00,
2305 cli_cmd_flag_sensitive = 0x01
2306};
2307
2308struct wpa_cli_cmd {
2309 const char *cmd;
2310 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2311 enum wpa_cli_cmd_flags flags;
2312 const char *usage;
2313};
2314
2315static struct wpa_cli_cmd wpa_cli_commands[] = {
2316 { "status", wpa_cli_cmd_status,
2317 cli_cmd_flag_none,
2318 "[verbose] = get current WPA/EAPOL/EAP status" },
2319 { "ping", wpa_cli_cmd_ping,
2320 cli_cmd_flag_none,
2321 "= pings wpa_supplicant" },
2322 { "relog", wpa_cli_cmd_relog,
2323 cli_cmd_flag_none,
2324 "= re-open log-file (allow rolling logs)" },
2325 { "note", wpa_cli_cmd_note,
2326 cli_cmd_flag_none,
2327 "<text> = add a note to wpa_supplicant debug log" },
2328 { "mib", wpa_cli_cmd_mib,
2329 cli_cmd_flag_none,
2330 "= get MIB variables (dot1x, dot11)" },
2331 { "help", wpa_cli_cmd_help,
2332 cli_cmd_flag_none,
2333 "= show this usage help" },
2334 { "interface", wpa_cli_cmd_interface,
2335 cli_cmd_flag_none,
2336 "[ifname] = show interfaces/select interface" },
2337 { "level", wpa_cli_cmd_level,
2338 cli_cmd_flag_none,
2339 "<debug level> = change debug level" },
2340 { "license", wpa_cli_cmd_license,
2341 cli_cmd_flag_none,
2342 "= show full wpa_cli license" },
2343 { "quit", wpa_cli_cmd_quit,
2344 cli_cmd_flag_none,
2345 "= exit wpa_cli" },
2346 { "set", wpa_cli_cmd_set,
2347 cli_cmd_flag_none,
2348 "= set variables (shows list of variables when run without "
2349 "arguments)" },
2350 { "get", wpa_cli_cmd_get,
2351 cli_cmd_flag_none,
2352 "<name> = get information" },
2353 { "logon", wpa_cli_cmd_logon,
2354 cli_cmd_flag_none,
2355 "= IEEE 802.1X EAPOL state machine logon" },
2356 { "logoff", wpa_cli_cmd_logoff,
2357 cli_cmd_flag_none,
2358 "= IEEE 802.1X EAPOL state machine logoff" },
2359 { "pmksa", wpa_cli_cmd_pmksa,
2360 cli_cmd_flag_none,
2361 "= show PMKSA cache" },
2362 { "reassociate", wpa_cli_cmd_reassociate,
2363 cli_cmd_flag_none,
2364 "= force reassociation" },
2365 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2366 cli_cmd_flag_none,
2367 "<BSSID> = force preauthentication" },
2368 { "identity", wpa_cli_cmd_identity,
2369 cli_cmd_flag_none,
2370 "<network id> <identity> = configure identity for an SSID" },
2371 { "password", wpa_cli_cmd_password,
2372 cli_cmd_flag_sensitive,
2373 "<network id> <password> = configure password for an SSID" },
2374 { "new_password", wpa_cli_cmd_new_password,
2375 cli_cmd_flag_sensitive,
2376 "<network id> <password> = change password for an SSID" },
2377 { "pin", wpa_cli_cmd_pin,
2378 cli_cmd_flag_sensitive,
2379 "<network id> <pin> = configure pin for an SSID" },
2380 { "otp", wpa_cli_cmd_otp,
2381 cli_cmd_flag_sensitive,
2382 "<network id> <password> = configure one-time-password for an SSID"
2383 },
2384 { "passphrase", wpa_cli_cmd_passphrase,
2385 cli_cmd_flag_sensitive,
2386 "<network id> <passphrase> = configure private key passphrase\n"
2387 " for an SSID" },
2388 { "bssid", wpa_cli_cmd_bssid,
2389 cli_cmd_flag_none,
2390 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2391 { "list_networks", wpa_cli_cmd_list_networks,
2392 cli_cmd_flag_none,
2393 "= list configured networks" },
2394 { "select_network", wpa_cli_cmd_select_network,
2395 cli_cmd_flag_none,
2396 "<network id> = select a network (disable others)" },
2397 { "enable_network", wpa_cli_cmd_enable_network,
2398 cli_cmd_flag_none,
2399 "<network id> = enable a network" },
2400 { "disable_network", wpa_cli_cmd_disable_network,
2401 cli_cmd_flag_none,
2402 "<network id> = disable a network" },
2403 { "add_network", wpa_cli_cmd_add_network,
2404 cli_cmd_flag_none,
2405 "= add a network" },
2406 { "remove_network", wpa_cli_cmd_remove_network,
2407 cli_cmd_flag_none,
2408 "<network id> = remove a network" },
2409 { "set_network", wpa_cli_cmd_set_network,
2410 cli_cmd_flag_sensitive,
2411 "<network id> <variable> <value> = set network variables (shows\n"
2412 " list of variables when run without arguments)" },
2413 { "get_network", wpa_cli_cmd_get_network,
2414 cli_cmd_flag_none,
2415 "<network id> <variable> = get network variables" },
2416 { "save_config", wpa_cli_cmd_save_config,
2417 cli_cmd_flag_none,
2418 "= save the current configuration" },
2419 { "disconnect", wpa_cli_cmd_disconnect,
2420 cli_cmd_flag_none,
2421 "= disconnect and wait for reassociate/reconnect command before\n"
2422 " connecting" },
2423 { "reconnect", wpa_cli_cmd_reconnect,
2424 cli_cmd_flag_none,
2425 "= like reassociate, but only takes effect if already disconnected"
2426 },
2427 { "scan", wpa_cli_cmd_scan,
2428 cli_cmd_flag_none,
2429 "= request new BSS scan" },
2430 { "scan_results", wpa_cli_cmd_scan_results,
2431 cli_cmd_flag_none,
2432 "= get latest scan results" },
2433 { "bss", wpa_cli_cmd_bss,
2434 cli_cmd_flag_none,
2435 "<<idx> | <bssid>> = get detailed scan result info" },
2436 { "get_capability", wpa_cli_cmd_get_capability,
2437 cli_cmd_flag_none,
2438 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2439 { "reconfigure", wpa_cli_cmd_reconfigure,
2440 cli_cmd_flag_none,
2441 "= force wpa_supplicant to re-read its configuration file" },
2442 { "terminate", wpa_cli_cmd_terminate,
2443 cli_cmd_flag_none,
2444 "= terminate wpa_supplicant" },
2445 { "interface_add", wpa_cli_cmd_interface_add,
2446 cli_cmd_flag_none,
2447 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2448 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2449 " are optional" },
2450 { "interface_remove", wpa_cli_cmd_interface_remove,
2451 cli_cmd_flag_none,
2452 "<ifname> = removes the interface" },
2453 { "interface_list", wpa_cli_cmd_interface_list,
2454 cli_cmd_flag_none,
2455 "= list available interfaces" },
2456 { "ap_scan", wpa_cli_cmd_ap_scan,
2457 cli_cmd_flag_none,
2458 "<value> = set ap_scan parameter" },
2459 { "scan_interval", wpa_cli_cmd_scan_interval,
2460 cli_cmd_flag_none,
2461 "<value> = set scan_interval parameter (in seconds)" },
2462 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2463 cli_cmd_flag_none,
2464 "<value> = set BSS expiration age parameter" },
2465 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2466 cli_cmd_flag_none,
2467 "<value> = set BSS expiration scan count parameter" },
2468 { "stkstart", wpa_cli_cmd_stkstart,
2469 cli_cmd_flag_none,
2470 "<addr> = request STK negotiation with <addr>" },
2471 { "ft_ds", wpa_cli_cmd_ft_ds,
2472 cli_cmd_flag_none,
2473 "<addr> = request over-the-DS FT with <addr>" },
2474 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2475 cli_cmd_flag_none,
2476 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2477 { "wps_pin", wpa_cli_cmd_wps_pin,
2478 cli_cmd_flag_sensitive,
2479 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2480 "hardcoded)" },
2481 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2482 cli_cmd_flag_sensitive,
2483 "<PIN> = verify PIN checksum" },
2484 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2485 "Cancels the pending WPS operation" },
2486#ifdef CONFIG_WPS_OOB
2487 { "wps_oob", wpa_cli_cmd_wps_oob,
2488 cli_cmd_flag_sensitive,
2489 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2490#endif /* CONFIG_WPS_OOB */
2491 { "wps_reg", wpa_cli_cmd_wps_reg,
2492 cli_cmd_flag_sensitive,
2493 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2494 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2495 cli_cmd_flag_sensitive,
2496 "[params..] = enable/disable AP PIN" },
2497 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2498 cli_cmd_flag_none,
2499 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2500 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2501 cli_cmd_flag_none,
2502 "= stop Wi-Fi Protected Setup External Registrar" },
2503 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2504 cli_cmd_flag_sensitive,
2505 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2506 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2507 cli_cmd_flag_none,
2508 "<UUID> = accept an Enrollee PBC using External Registrar" },
2509 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2510 cli_cmd_flag_sensitive,
2511 "<UUID> <PIN> = learn AP configuration" },
2512 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2513 cli_cmd_flag_none,
2514 "<UUID> <network id> = set AP configuration for enrolling" },
2515 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2516 cli_cmd_flag_sensitive,
2517 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2518 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2519 cli_cmd_flag_none,
2520 "<addr> = request RSN authentication with <addr> in IBSS" },
2521#ifdef CONFIG_AP
2522 { "sta", wpa_cli_cmd_sta,
2523 cli_cmd_flag_none,
2524 "<addr> = get information about an associated station (AP)" },
2525 { "all_sta", wpa_cli_cmd_all_sta,
2526 cli_cmd_flag_none,
2527 "= get information about all associated stations (AP)" },
2528#endif /* CONFIG_AP */
2529 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2530 "= notification of suspend/hibernate" },
2531 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2532 "= notification of resume/thaw" },
2533 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2534 "= drop SA without deauth/disassoc (test command)" },
2535 { "roam", wpa_cli_cmd_roam,
2536 cli_cmd_flag_none,
2537 "<addr> = roam to the specified BSS" },
2538#ifdef CONFIG_P2P
2539 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2540 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2541 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2542 "= stop P2P Devices search" },
2543 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2544 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2545 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2546 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2547 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2548 "<ifname> = remove P2P group interface (terminate group if GO)" },
2549 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2550 "= add a new P2P group (local end as GO)" },
2551 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2552 "<addr> <method> = request provisioning discovery" },
2553 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2554 cli_cmd_flag_none,
2555 "= get the passphrase for a group (GO only)" },
2556 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2557 cli_cmd_flag_none,
2558 "<addr> <TLVs> = schedule service discovery request" },
2559 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2560 cli_cmd_flag_none,
2561 "<id> = cancel pending service discovery request" },
2562 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2563 cli_cmd_flag_none,
2564 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2565 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2566 cli_cmd_flag_none,
2567 "= indicate change in local services" },
2568 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2569 cli_cmd_flag_none,
2570 "<external> = set external processing of service discovery" },
2571 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2572 cli_cmd_flag_none,
2573 "= remove all stored service entries" },
2574 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2575 cli_cmd_flag_none,
2576 "<bonjour|upnp> <query|version> <response|service> = add a local "
2577 "service" },
2578 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2579 cli_cmd_flag_none,
2580 "<bonjour|upnp> <query|version> [|service] = remove a local "
2581 "service" },
2582 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2583 cli_cmd_flag_none,
2584 "<addr> = reject connection attempts from a specific peer" },
2585 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2586 cli_cmd_flag_none,
2587 "<cmd> [peer=addr] = invite peer" },
2588 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2589 "[discovered] = list known (optionally, only fully discovered) P2P "
2590 "peers" },
2591 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2592 "<address> = show information about known P2P peer" },
2593 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2594 "<field> <value> = set a P2P parameter" },
2595 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2596 "= flush P2P state" },
2597 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2598 "= cancel P2P group formation" },
2599 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2600 "<address> = unauthorize a peer" },
2601 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2602 "[<duration> <interval>] [<duration> <interval>] = request GO "
2603 "presence" },
2604 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2605 "[<period> <interval>] = set extended listen timing" },
2606#endif /* CONFIG_P2P */
2607 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2608 "<0/1> = disable/enable automatic reconnection" },
2609 { "tdls_discover", wpa_cli_cmd_tdls_discover,
2610 cli_cmd_flag_none,
2611 "<addr> = request TDLS discovery with <addr>" },
2612 { "tdls_setup", wpa_cli_cmd_tdls_setup,
2613 cli_cmd_flag_none,
2614 "<addr> = request TDLS setup with <addr>" },
2615 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
2616 cli_cmd_flag_none,
2617 "<addr> = tear down TDLS with <addr>" },
2618 { "signal_poll", wpa_cli_cmd_signal_poll,
2619 cli_cmd_flag_none,
2620 "= get signal parameters" },
2621 { NULL, NULL, cli_cmd_flag_none, NULL }
2622};
2623
2624
2625/*
2626 * Prints command usage, lines are padded with the specified string.
2627 */
2628static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2629{
2630 char c;
2631 size_t n;
2632
2633 printf("%s%s ", pad, cmd->cmd);
2634 for (n = 0; (c = cmd->usage[n]); n++) {
2635 printf("%c", c);
2636 if (c == '\n')
2637 printf("%s", pad);
2638 }
2639 printf("\n");
2640}
2641
2642
2643static void print_help(void)
2644{
2645 int n;
2646 printf("commands:\n");
2647 for (n = 0; wpa_cli_commands[n].cmd; n++)
2648 print_cmd_help(&wpa_cli_commands[n], " ");
2649}
2650
2651
2652static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2653{
2654 const char *c, *delim;
2655 int n;
2656 size_t len;
2657
2658 delim = os_strchr(cmd, ' ');
2659 if (delim)
2660 len = delim - cmd;
2661 else
2662 len = os_strlen(cmd);
2663
2664 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2665 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2666 return (wpa_cli_commands[n].flags &
2667 cli_cmd_flag_sensitive);
2668 }
2669 return 0;
2670}
2671
2672
2673static char ** wpa_list_cmd_list(void)
2674{
2675 char **res;
2676 int i, count;
2677
2678 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2679 res = os_zalloc(count * sizeof(char *));
2680 if (res == NULL)
2681 return NULL;
2682
2683 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2684 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2685 if (res[i] == NULL)
2686 break;
2687 }
2688
2689 return res;
2690}
2691
2692
2693static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2694 int pos)
2695{
2696 int i;
2697
2698 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2699 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2700 edit_clear_line();
2701 printf("\r%s\n", wpa_cli_commands[i].usage);
2702 edit_redraw();
2703 break;
2704 }
2705 }
2706
2707 return NULL;
2708}
2709
2710
2711static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2712{
2713 char **res;
2714 const char *end;
2715 char *cmd;
2716
2717 end = os_strchr(str, ' ');
2718 if (end == NULL || str + pos < end)
2719 return wpa_list_cmd_list();
2720
2721 cmd = os_malloc(pos + 1);
2722 if (cmd == NULL)
2723 return NULL;
2724 os_memcpy(cmd, str, pos);
2725 cmd[end - str] = '\0';
2726 res = wpa_cli_cmd_completion(cmd, str, pos);
2727 os_free(cmd);
2728 return res;
2729}
2730
2731
2732static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2733{
2734 struct wpa_cli_cmd *cmd, *match = NULL;
2735 int count;
2736 int ret = 0;
2737
2738 count = 0;
2739 cmd = wpa_cli_commands;
2740 while (cmd->cmd) {
2741 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2742 {
2743 match = cmd;
2744 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2745 /* we have an exact match */
2746 count = 1;
2747 break;
2748 }
2749 count++;
2750 }
2751 cmd++;
2752 }
2753
2754 if (count > 1) {
2755 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2756 cmd = wpa_cli_commands;
2757 while (cmd->cmd) {
2758 if (os_strncasecmp(cmd->cmd, argv[0],
2759 os_strlen(argv[0])) == 0) {
2760 printf(" %s", cmd->cmd);
2761 }
2762 cmd++;
2763 }
2764 printf("\n");
2765 ret = 1;
2766 } else if (count == 0) {
2767 printf("Unknown command '%s'\n", argv[0]);
2768 ret = 1;
2769 } else {
2770 ret = match->handler(ctrl, argc - 1, &argv[1]);
2771 }
2772
2773 return ret;
2774}
2775
2776
2777static int str_match(const char *a, const char *b)
2778{
2779 return os_strncmp(a, b, os_strlen(b)) == 0;
2780}
2781
2782
2783static int wpa_cli_exec(const char *program, const char *arg1,
2784 const char *arg2)
2785{
2786 char *cmd;
2787 size_t len;
2788 int res;
2789 int ret = 0;
2790
2791 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2792 cmd = os_malloc(len);
2793 if (cmd == NULL)
2794 return -1;
2795 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2796 if (res < 0 || (size_t) res >= len) {
2797 os_free(cmd);
2798 return -1;
2799 }
2800 cmd[len - 1] = '\0';
2801#ifndef _WIN32_WCE
2802 if (system(cmd) < 0)
2803 ret = -1;
2804#endif /* _WIN32_WCE */
2805 os_free(cmd);
2806
2807 return ret;
2808}
2809
2810
2811static void wpa_cli_action_process(const char *msg)
2812{
2813 const char *pos;
2814 char *copy = NULL, *id, *pos2;
2815
2816 pos = msg;
2817 if (*pos == '<') {
2818 /* skip priority */
2819 pos = os_strchr(pos, '>');
2820 if (pos)
2821 pos++;
2822 else
2823 pos = msg;
2824 }
2825
2826 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2827 int new_id = -1;
2828 os_unsetenv("WPA_ID");
2829 os_unsetenv("WPA_ID_STR");
2830 os_unsetenv("WPA_CTRL_DIR");
2831
2832 pos = os_strstr(pos, "[id=");
2833 if (pos)
2834 copy = os_strdup(pos + 4);
2835
2836 if (copy) {
2837 pos2 = id = copy;
2838 while (*pos2 && *pos2 != ' ')
2839 pos2++;
2840 *pos2++ = '\0';
2841 new_id = atoi(id);
2842 os_setenv("WPA_ID", id, 1);
2843 while (*pos2 && *pos2 != '=')
2844 pos2++;
2845 if (*pos2 == '=')
2846 pos2++;
2847 id = pos2;
2848 while (*pos2 && *pos2 != ']')
2849 pos2++;
2850 *pos2 = '\0';
2851 os_setenv("WPA_ID_STR", id, 1);
2852 os_free(copy);
2853 }
2854
2855 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2856
2857 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2858 wpa_cli_connected = 1;
2859 wpa_cli_last_id = new_id;
2860 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2861 }
2862 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2863 if (wpa_cli_connected) {
2864 wpa_cli_connected = 0;
2865 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2866 }
2867 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2868 wpa_cli_exec(action_file, ctrl_ifname, pos);
2869 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2870 wpa_cli_exec(action_file, ctrl_ifname, pos);
2871 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2872 wpa_cli_exec(action_file, ctrl_ifname, pos);
2873 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2874 wpa_cli_exec(action_file, ctrl_ifname, pos);
2875 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2876 wpa_cli_exec(action_file, ctrl_ifname, pos);
2877 } else if (str_match(pos, WPS_EVENT_FAIL)) {
2878 wpa_cli_exec(action_file, ctrl_ifname, pos);
2879 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2880 printf("wpa_supplicant is terminating - stop monitoring\n");
2881 wpa_cli_quit = 1;
2882 }
2883}
2884
2885
2886#ifndef CONFIG_ANSI_C_EXTRA
2887static void wpa_cli_action_cb(char *msg, size_t len)
2888{
2889 wpa_cli_action_process(msg);
2890}
2891#endif /* CONFIG_ANSI_C_EXTRA */
2892
2893
2894static void wpa_cli_reconnect(void)
2895{
2896 wpa_cli_close_connection();
2897 wpa_cli_open_connection(ctrl_ifname, 1);
2898}
2899
2900
2901static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
2902{
2903 if (ctrl_conn == NULL) {
2904 wpa_cli_reconnect();
2905 return;
2906 }
2907 while (wpa_ctrl_pending(ctrl) > 0) {
2908 char buf[256];
2909 size_t len = sizeof(buf) - 1;
2910 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2911 buf[len] = '\0';
2912 if (action_monitor)
2913 wpa_cli_action_process(buf);
2914 else {
2915 if (wpa_cli_show_event(buf)) {
2916 edit_clear_line();
2917 printf("\r%s\n", buf);
2918 edit_redraw();
2919 }
2920 }
2921 } else {
2922 printf("Could not read pending message.\n");
2923 break;
2924 }
2925 }
2926
2927 if (wpa_ctrl_pending(ctrl) < 0) {
2928 printf("Connection to wpa_supplicant lost - trying to "
2929 "reconnect\n");
2930 wpa_cli_reconnect();
2931 }
2932}
2933
2934#define max_args 10
2935
2936static int tokenize_cmd(char *cmd, char *argv[])
2937{
2938 char *pos;
2939 int argc = 0;
2940
2941 pos = cmd;
2942 for (;;) {
2943 while (*pos == ' ')
2944 pos++;
2945 if (*pos == '\0')
2946 break;
2947 argv[argc] = pos;
2948 argc++;
2949 if (argc == max_args)
2950 break;
2951 if (*pos == '"') {
2952 char *pos2 = os_strrchr(pos, '"');
2953 if (pos2)
2954 pos = pos2 + 1;
2955 }
2956 while (*pos != '\0' && *pos != ' ')
2957 pos++;
2958 if (*pos == ' ')
2959 *pos++ = '\0';
2960 }
2961
2962 return argc;
2963}
2964
2965
2966static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
2967{
2968 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2969 printf("Connection to wpa_supplicant lost - trying to "
2970 "reconnect\n");
2971 wpa_cli_close_connection();
2972 }
2973 if (!ctrl_conn)
2974 wpa_cli_reconnect();
2975 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
2976}
2977
2978
2979static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
2980{
2981 eloop_terminate();
2982}
2983
2984
2985static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
2986{
2987 wpa_cli_recv_pending(mon_conn, 0);
2988}
2989
2990
2991static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
2992{
2993 char *argv[max_args];
2994 int argc;
2995 argc = tokenize_cmd(cmd, argv);
2996 if (argc)
2997 wpa_request(ctrl_conn, argc, argv);
2998}
2999
3000
3001static void wpa_cli_edit_eof_cb(void *ctx)
3002{
3003 eloop_terminate();
3004}
3005
3006
3007static void wpa_cli_interactive(void)
3008{
3009 char *home, *hfile = NULL;
3010
3011 printf("\nInteractive mode\n\n");
3012
3013 home = getenv("HOME");
3014 if (home) {
3015 const char *fname = ".wpa_cli_history";
3016 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3017 hfile = os_malloc(hfile_len);
3018 if (hfile)
3019 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3020 }
3021
3022 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3023 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3024 wpa_cli_edit_completion_cb, NULL, hfile);
3025 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3026
3027 eloop_run();
3028
3029 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3030 os_free(hfile);
3031 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3032 wpa_cli_close_connection();
3033}
3034
3035
3036static void wpa_cli_action(struct wpa_ctrl *ctrl)
3037{
3038#ifdef CONFIG_ANSI_C_EXTRA
3039 /* TODO: ANSI C version(?) */
3040 printf("Action processing not supported in ANSI C build.\n");
3041#else /* CONFIG_ANSI_C_EXTRA */
3042 fd_set rfds;
3043 int fd, res;
3044 struct timeval tv;
3045 char buf[256]; /* note: large enough to fit in unsolicited messages */
3046 size_t len;
3047
3048 fd = wpa_ctrl_get_fd(ctrl);
3049
3050 while (!wpa_cli_quit) {
3051 FD_ZERO(&rfds);
3052 FD_SET(fd, &rfds);
3053 tv.tv_sec = ping_interval;
3054 tv.tv_usec = 0;
3055 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3056 if (res < 0 && errno != EINTR) {
3057 perror("select");
3058 break;
3059 }
3060
3061 if (FD_ISSET(fd, &rfds))
3062 wpa_cli_recv_pending(ctrl, 1);
3063 else {
3064 /* verify that connection is still working */
3065 len = sizeof(buf) - 1;
3066 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3067 wpa_cli_action_cb) < 0 ||
3068 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3069 printf("wpa_supplicant did not reply to PING "
3070 "command - exiting\n");
3071 break;
3072 }
3073 }
3074 }
3075#endif /* CONFIG_ANSI_C_EXTRA */
3076}
3077
3078
3079static void wpa_cli_cleanup(void)
3080{
3081 wpa_cli_close_connection();
3082 if (pid_file)
3083 os_daemonize_terminate(pid_file);
3084
3085 os_program_deinit();
3086}
3087
3088static void wpa_cli_terminate(int sig)
3089{
3090 wpa_cli_cleanup();
3091 exit(0);
3092}
3093
3094
3095static char * wpa_cli_get_default_ifname(void)
3096{
3097 char *ifname = NULL;
3098
3099#ifdef CONFIG_CTRL_IFACE_UNIX
3100 struct dirent *dent;
3101 DIR *dir = opendir(ctrl_iface_dir);
3102 if (!dir) {
3103#ifdef ANDROID
3104 char ifprop[PROPERTY_VALUE_MAX];
3105 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3106 ifname = os_strdup(ifprop);
3107 printf("Using interface '%s'\n", ifname);
3108 return ifname;
3109 }
3110#endif /* ANDROID */
3111 return NULL;
3112 }
3113 while ((dent = readdir(dir))) {
3114#ifdef _DIRENT_HAVE_D_TYPE
3115 /*
3116 * Skip the file if it is not a socket. Also accept
3117 * DT_UNKNOWN (0) in case the C library or underlying
3118 * file system does not support d_type.
3119 */
3120 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3121 continue;
3122#endif /* _DIRENT_HAVE_D_TYPE */
3123 if (os_strcmp(dent->d_name, ".") == 0 ||
3124 os_strcmp(dent->d_name, "..") == 0)
3125 continue;
3126 printf("Selected interface '%s'\n", dent->d_name);
3127 ifname = os_strdup(dent->d_name);
3128 break;
3129 }
3130 closedir(dir);
3131#endif /* CONFIG_CTRL_IFACE_UNIX */
3132
3133#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3134 char buf[2048], *pos;
3135 size_t len;
3136 struct wpa_ctrl *ctrl;
3137 int ret;
3138
3139 ctrl = wpa_ctrl_open(NULL);
3140 if (ctrl == NULL)
3141 return NULL;
3142
3143 len = sizeof(buf) - 1;
3144 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3145 if (ret >= 0) {
3146 buf[len] = '\0';
3147 pos = os_strchr(buf, '\n');
3148 if (pos)
3149 *pos = '\0';
3150 ifname = os_strdup(buf);
3151 }
3152 wpa_ctrl_close(ctrl);
3153#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3154
3155 return ifname;
3156}
3157
3158
3159int main(int argc, char *argv[])
3160{
3161 int warning_displayed = 0;
3162 int c;
3163 int daemonize = 0;
3164 int ret = 0;
3165 const char *global = NULL;
3166
3167 if (os_program_init())
3168 return -1;
3169
3170 for (;;) {
3171 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3172 if (c < 0)
3173 break;
3174 switch (c) {
3175 case 'a':
3176 action_file = optarg;
3177 break;
3178 case 'B':
3179 daemonize = 1;
3180 break;
3181 case 'g':
3182 global = optarg;
3183 break;
3184 case 'G':
3185 ping_interval = atoi(optarg);
3186 break;
3187 case 'h':
3188 usage();
3189 return 0;
3190 case 'v':
3191 printf("%s\n", wpa_cli_version);
3192 return 0;
3193 case 'i':
3194 os_free(ctrl_ifname);
3195 ctrl_ifname = os_strdup(optarg);
3196 break;
3197 case 'p':
3198 ctrl_iface_dir = optarg;
3199 break;
3200 case 'P':
3201 pid_file = optarg;
3202 break;
3203 default:
3204 usage();
3205 return -1;
3206 }
3207 }
3208
3209 interactive = (argc == optind) && (action_file == NULL);
3210
3211 if (interactive)
3212 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3213
3214 if (eloop_init())
3215 return -1;
3216
3217 if (global) {
3218#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3219 ctrl_conn = wpa_ctrl_open(NULL);
3220#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3221 ctrl_conn = wpa_ctrl_open(global);
3222#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3223 if (ctrl_conn == NULL) {
3224 perror("Failed to connect to wpa_supplicant - "
3225 "wpa_ctrl_open");
3226 return -1;
3227 }
3228 }
3229
3230#ifndef _WIN32_WCE
3231 signal(SIGINT, wpa_cli_terminate);
3232 signal(SIGTERM, wpa_cli_terminate);
3233#endif /* _WIN32_WCE */
3234
3235 if (ctrl_ifname == NULL)
3236 ctrl_ifname = wpa_cli_get_default_ifname();
3237
3238 if (interactive) {
3239 for (; !global;) {
3240 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3241 if (warning_displayed)
3242 printf("Connection established.\n");
3243 break;
3244 }
3245
3246 if (!warning_displayed) {
3247 printf("Could not connect to wpa_supplicant - "
3248 "re-trying\n");
3249 warning_displayed = 1;
3250 }
3251 os_sleep(1, 0);
3252 continue;
3253 }
3254 } else {
3255 if (!global &&
3256 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3257 perror("Failed to connect to wpa_supplicant - "
3258 "wpa_ctrl_open");
3259 return -1;
3260 }
3261
3262 if (action_file) {
3263 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3264 wpa_cli_attached = 1;
3265 } else {
3266 printf("Warning: Failed to attach to "
3267 "wpa_supplicant.\n");
3268 return -1;
3269 }
3270 }
3271 }
3272
3273 if (daemonize && os_daemonize(pid_file))
3274 return -1;
3275
3276 if (interactive)
3277 wpa_cli_interactive();
3278 else if (action_file)
3279 wpa_cli_action(ctrl_conn);
3280 else
3281 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3282
3283 os_free(ctrl_ifname);
3284 eloop_destroy();
3285 wpa_cli_cleanup();
3286
3287 return ret;
3288}
3289
3290#else /* CONFIG_CTRL_IFACE */
3291int main(int argc, char *argv[])
3292{
3293 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3294 return -1;
3295}
3296#endif /* CONFIG_CTRL_IFACE */