2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
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"
29 #include <cutils/properties.h>
33 static const char *wpa_cli_version
=
34 "wpa_cli v" VERSION_STR
"\n"
35 "Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> and contributors";
38 static 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"
42 "Alternatively, this software may be distributed under the terms of the\n"
43 "BSD license. See README and COPYING for more details.\n";
45 static 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"
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"
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"
59 "Alternatively, this software may be distributed under the terms of the\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"
66 "1. Redistributions of source code must retain the above copyright\n"
67 " notice, this list of conditions and the following disclaimer.\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"
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"
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"
90 static struct wpa_ctrl
*ctrl_conn
;
91 static struct wpa_ctrl
*mon_conn
;
92 static int wpa_cli_quit
= 0;
93 static int wpa_cli_attached
= 0;
94 static int wpa_cli_connected
= 0;
95 static int wpa_cli_last_id
= 0;
96 static const char *ctrl_iface_dir
= "/var/run/wpa_supplicant";
97 static char *ctrl_ifname
= NULL
;
98 static const char *pid_file
= NULL
;
99 static const char *action_file
= NULL
;
100 static int ping_interval
= 5;
101 static int interactive
= 0;
104 static void print_help(void);
105 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
);
108 static void usage(void)
110 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
111 "[-a<action file>] \\\n"
112 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
114 " -h = help (show this usage text)\n"
115 " -v = shown version information\n"
116 " -a = run in daemon mode executing the action file based on "
119 " -B = run a daemon in the background\n"
120 " default path: /var/run/wpa_supplicant\n"
121 " default interface: first interface found in socket path\n");
126 static int str_starts(const char *src
, const char *match
)
128 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
132 static int wpa_cli_show_event(const char *event
)
136 start
= os_strchr(event
, '>');
142 * Skip BSS added/removed events since they can be relatively frequent
143 * and are likely of not much use for an interactive user.
145 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
146 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
153 static int wpa_cli_open_connection(const char *ifname
, int attach
)
155 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
156 ctrl_conn
= wpa_ctrl_open(ifname
);
157 if (ctrl_conn
== NULL
)
160 if (attach
&& interactive
)
161 mon_conn
= wpa_ctrl_open(ifname
);
164 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
172 if (access(ctrl_iface_dir
, F_OK
) < 0) {
173 cfile
= os_strdup(ifname
);
180 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
181 cfile
= os_malloc(flen
);
184 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
,
186 if (res
< 0 || res
>= flen
) {
192 ctrl_conn
= wpa_ctrl_open(cfile
);
193 if (ctrl_conn
== NULL
) {
198 if (attach
&& interactive
)
199 mon_conn
= wpa_ctrl_open(cfile
);
203 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
206 if (wpa_ctrl_attach(mon_conn
) == 0) {
207 wpa_cli_attached
= 1;
209 eloop_register_read_sock(
210 wpa_ctrl_get_fd(mon_conn
),
211 wpa_cli_mon_receive
, NULL
, NULL
);
213 printf("Warning: Failed to attach to "
214 "wpa_supplicant.\n");
223 static void wpa_cli_close_connection(void)
225 if (ctrl_conn
== NULL
)
228 if (wpa_cli_attached
) {
229 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
230 wpa_cli_attached
= 0;
232 wpa_ctrl_close(ctrl_conn
);
235 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
236 wpa_ctrl_close(mon_conn
);
242 static void wpa_cli_msg_cb(char *msg
, size_t len
)
248 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
254 if (ctrl_conn
== NULL
) {
255 printf("Not connected to wpa_supplicant - command dropped.\n");
258 len
= sizeof(buf
) - 1;
259 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
262 printf("'%s' command timed out.\n", cmd
);
264 } else if (ret
< 0) {
265 printf("'%s' command failed.\n", cmd
);
271 if (interactive
&& len
> 0 && buf
[len
- 1] != '\n')
278 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
280 return _wpa_ctrl_command(ctrl
, cmd
, 1);
284 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
286 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
287 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
291 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
293 return wpa_ctrl_command(ctrl
, "PING");
297 static int wpa_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
299 return wpa_ctrl_command(ctrl
, "RELOG");
303 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
309 ret
= os_snprintf(cmd
, sizeof(cmd
), "NOTE %s", argv
[0]);
310 if (ret
< 0 || (size_t) ret
>= sizeof(cmd
))
312 return wpa_ctrl_command(ctrl
, cmd
);
316 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
318 return wpa_ctrl_command(ctrl
, "MIB");
322 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
324 return wpa_ctrl_command(ctrl
, "PMKSA");
328 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
335 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
337 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
342 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
351 static void wpa_cli_show_variables(void)
353 printf("set variables:\n"
354 " EAPOL::heldPeriod (EAPOL state machine held period, "
356 " EAPOL::authPeriod (EAPOL state machine authentication "
357 "period, in seconds)\n"
358 " EAPOL::startPeriod (EAPOL state machine start period, in "
360 " EAPOL::maxStart (EAPOL state machine maximum start "
362 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
364 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
365 " threshold\n\tpercentage)\n"
366 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
367 "security\n\tassociation in seconds)\n");
371 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
377 wpa_cli_show_variables();
382 printf("Invalid SET command: needs two arguments (variable "
383 "name and value)\n");
387 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s", argv
[0], argv
[1]);
388 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
389 printf("Too long SET command.\n");
392 return wpa_ctrl_command(ctrl
, cmd
);
396 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
402 printf("Invalid GET command: need one argument (variable "
407 res
= os_snprintf(cmd
, sizeof(cmd
), "GET %s", argv
[0]);
408 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
409 printf("Too long GET command.\n");
412 return wpa_ctrl_command(ctrl
, cmd
);
416 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
418 return wpa_ctrl_command(ctrl
, "LOGOFF");
422 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
424 return wpa_ctrl_command(ctrl
, "LOGON");
428 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
431 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
435 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
442 printf("Invalid PREAUTH command: needs one argument "
447 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
448 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
449 printf("Too long PREAUTH command.\n");
452 return wpa_ctrl_command(ctrl
, cmd
);
456 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
462 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
466 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
467 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
468 printf("Too long AP_SCAN command.\n");
471 return wpa_ctrl_command(ctrl
, cmd
);
475 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
482 printf("Invalid STKSTART command: needs one argument "
483 "(Peer STA MAC address)\n");
487 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
488 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
489 printf("Too long STKSTART command.\n");
492 return wpa_ctrl_command(ctrl
, cmd
);
496 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
502 printf("Invalid FT_DS command: needs one argument "
503 "(Target AP MAC address)\n");
507 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
508 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
509 printf("Too long FT_DS command.\n");
512 return wpa_ctrl_command(ctrl
, cmd
);
516 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
523 return wpa_ctrl_command(ctrl
, "WPS_PBC");
527 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
528 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
529 printf("Too long WPS_PBC command.\n");
532 return wpa_ctrl_command(ctrl
, cmd
);
536 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
542 printf("Invalid WPS_PIN command: need one or two arguments:\n"
543 "- BSSID: use 'any' to select any\n"
544 "- PIN: optional, used only with devices that have no "
550 /* Use dynamically generated PIN (returned as reply) */
551 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
552 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
553 printf("Too long WPS_PIN command.\n");
556 return wpa_ctrl_command(ctrl
, cmd
);
559 /* Use hardcoded PIN from a label */
560 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
561 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
562 printf("Too long WPS_PIN command.\n");
565 return wpa_ctrl_command(ctrl
, cmd
);
569 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
575 if (argc
!= 1 && argc
!= 2) {
576 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
577 "- PIN to be verified\n");
582 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
585 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
587 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
588 printf("Too long WPS_CHECK_PIN command.\n");
591 return wpa_ctrl_command(ctrl
, cmd
);
595 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
598 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
602 #ifdef CONFIG_WPS_OOB
603 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
608 if (argc
!= 3 && argc
!= 4) {
609 printf("Invalid WPS_OOB command: need three or four "
611 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
612 "- PATH: path of OOB device like '/mnt'\n"
613 "- METHOD: OOB method 'pin-e' or 'pin-r', "
615 "- DEV_NAME: (only for NFC) device name like "
621 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
622 argv
[0], argv
[1], argv
[2]);
624 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
625 argv
[0], argv
[1], argv
[2], argv
[3]);
626 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
627 printf("Too long WPS_OOB command.\n");
630 return wpa_ctrl_command(ctrl
, cmd
);
632 #endif /* CONFIG_WPS_OOB */
635 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
641 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
643 else if (argc
== 5 || argc
== 6) {
644 char ssid_hex
[2 * 32 + 1];
645 char key_hex
[2 * 64 + 1];
649 for (i
= 0; i
< 32; i
++) {
650 if (argv
[2][i
] == '\0')
652 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
657 for (i
= 0; i
< 64; i
++) {
658 if (argv
[5][i
] == '\0')
660 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
665 res
= os_snprintf(cmd
, sizeof(cmd
),
666 "WPS_REG %s %s %s %s %s %s",
667 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
670 printf("Invalid WPS_REG command: need two arguments:\n"
671 "- BSSID of the target AP\n"
673 printf("Alternatively, six arguments can be used to "
674 "reconfigure the AP:\n"
675 "- BSSID of the target AP\n"
678 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
679 "- new encr (NONE, WEP, TKIP, CCMP)\n"
684 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
685 printf("Too long WPS_REG command.\n");
688 return wpa_ctrl_command(ctrl
, cmd
);
692 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
699 printf("Invalid WPS_AP_PIN command: needs at least one "
705 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s %s",
706 argv
[0], argv
[1], argv
[2]);
708 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s",
711 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s",
713 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
714 printf("Too long WPS_AP_PIN command.\n");
717 return wpa_ctrl_command(ctrl
, cmd
);
721 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
726 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
727 return wpa_ctrl_command(ctrl
, cmd
);
729 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
733 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
736 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
741 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
748 printf("Invalid WPS_ER_PIN command: need at least two "
750 "- UUID: use 'any' to select any\n"
751 "- PIN: Enrollee PIN\n"
752 "optional: - Enrollee MAC address\n");
757 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
758 argv
[0], argv
[1], argv
[2]);
760 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
762 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
763 printf("Too long WPS_ER_PIN command.\n");
766 return wpa_ctrl_command(ctrl
, cmd
);
770 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
777 printf("Invalid WPS_ER_PBC command: need one argument:\n"
778 "- UUID: Specify the Enrollee\n");
782 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
784 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
785 printf("Too long WPS_ER_PBC command.\n");
788 return wpa_ctrl_command(ctrl
, cmd
);
792 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
799 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
800 "- UUID: specify which AP to use\n"
805 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
807 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
808 printf("Too long WPS_ER_LEARN command.\n");
811 return wpa_ctrl_command(ctrl
, cmd
);
815 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
822 printf("Invalid WPS_ER_SET_CONFIG command: need two "
824 "- UUID: specify which AP to use\n"
825 "- Network configuration id\n");
829 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_SET_CONFIG %s %s",
831 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
832 printf("Too long WPS_ER_SET_CONFIG command.\n");
835 return wpa_ctrl_command(ctrl
, cmd
);
839 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
845 if (argc
== 5 || argc
== 6) {
846 char ssid_hex
[2 * 32 + 1];
847 char key_hex
[2 * 64 + 1];
851 for (i
= 0; i
< 32; i
++) {
852 if (argv
[2][i
] == '\0')
854 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
859 for (i
= 0; i
< 64; i
++) {
860 if (argv
[5][i
] == '\0')
862 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
867 res
= os_snprintf(cmd
, sizeof(cmd
),
868 "WPS_ER_CONFIG %s %s %s %s %s %s",
869 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
872 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
876 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
877 "- new encr (NONE, WEP, TKIP, CCMP)\n"
882 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
883 printf("Too long WPS_ER_CONFIG command.\n");
886 return wpa_ctrl_command(ctrl
, cmd
);
890 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
896 printf("Invalid IBSS_RSN command: needs one argument "
897 "(Peer STA MAC address)\n");
901 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
902 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
903 printf("Too long IBSS_RSN command.\n");
906 return wpa_ctrl_command(ctrl
, cmd
);
910 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
916 printf("Invalid LEVEL command: needs one argument (debug "
920 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
921 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
922 printf("Too long LEVEL command.\n");
925 return wpa_ctrl_command(ctrl
, cmd
);
929 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
931 char cmd
[256], *pos
, *end
;
935 printf("Invalid IDENTITY command: needs two arguments "
936 "(network id and identity)\n");
940 end
= cmd
+ sizeof(cmd
);
942 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
944 if (ret
< 0 || ret
>= end
- pos
) {
945 printf("Too long IDENTITY command.\n");
949 for (i
= 2; i
< argc
; i
++) {
950 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
951 if (ret
< 0 || ret
>= end
- pos
) {
952 printf("Too long IDENTITY command.\n");
958 return wpa_ctrl_command(ctrl
, cmd
);
962 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
964 char cmd
[256], *pos
, *end
;
968 printf("Invalid PASSWORD command: needs two arguments "
969 "(network id and password)\n");
973 end
= cmd
+ sizeof(cmd
);
975 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
977 if (ret
< 0 || ret
>= end
- pos
) {
978 printf("Too long PASSWORD command.\n");
982 for (i
= 2; i
< argc
; i
++) {
983 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
984 if (ret
< 0 || ret
>= end
- pos
) {
985 printf("Too long PASSWORD command.\n");
991 return wpa_ctrl_command(ctrl
, cmd
);
995 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
998 char cmd
[256], *pos
, *end
;
1002 printf("Invalid NEW_PASSWORD command: needs two arguments "
1003 "(network id and password)\n");
1007 end
= cmd
+ sizeof(cmd
);
1009 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1011 if (ret
< 0 || ret
>= end
- pos
) {
1012 printf("Too long NEW_PASSWORD command.\n");
1016 for (i
= 2; i
< argc
; i
++) {
1017 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1018 if (ret
< 0 || ret
>= end
- pos
) {
1019 printf("Too long NEW_PASSWORD command.\n");
1025 return wpa_ctrl_command(ctrl
, cmd
);
1029 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1031 char cmd
[256], *pos
, *end
;
1035 printf("Invalid PIN command: needs two arguments "
1036 "(network id and pin)\n");
1040 end
= cmd
+ sizeof(cmd
);
1042 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1044 if (ret
< 0 || ret
>= end
- pos
) {
1045 printf("Too long PIN command.\n");
1049 for (i
= 2; i
< argc
; i
++) {
1050 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1051 if (ret
< 0 || ret
>= end
- pos
) {
1052 printf("Too long PIN command.\n");
1057 return wpa_ctrl_command(ctrl
, cmd
);
1061 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1063 char cmd
[256], *pos
, *end
;
1067 printf("Invalid OTP command: needs two arguments (network "
1068 "id and password)\n");
1072 end
= cmd
+ sizeof(cmd
);
1074 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1076 if (ret
< 0 || ret
>= end
- pos
) {
1077 printf("Too long OTP command.\n");
1081 for (i
= 2; i
< argc
; i
++) {
1082 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1083 if (ret
< 0 || ret
>= end
- pos
) {
1084 printf("Too long OTP command.\n");
1090 return wpa_ctrl_command(ctrl
, cmd
);
1094 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1097 char cmd
[256], *pos
, *end
;
1101 printf("Invalid PASSPHRASE command: needs two arguments "
1102 "(network id and passphrase)\n");
1106 end
= cmd
+ sizeof(cmd
);
1108 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1110 if (ret
< 0 || ret
>= end
- pos
) {
1111 printf("Too long PASSPHRASE command.\n");
1115 for (i
= 2; i
< argc
; i
++) {
1116 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1117 if (ret
< 0 || ret
>= end
- pos
) {
1118 printf("Too long PASSPHRASE command.\n");
1124 return wpa_ctrl_command(ctrl
, cmd
);
1128 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1130 char cmd
[256], *pos
, *end
;
1134 printf("Invalid BSSID command: needs two arguments (network "
1139 end
= cmd
+ sizeof(cmd
);
1141 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1142 if (ret
< 0 || ret
>= end
- pos
) {
1143 printf("Too long BSSID command.\n");
1147 for (i
= 0; i
< argc
; i
++) {
1148 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1149 if (ret
< 0 || ret
>= end
- pos
) {
1150 printf("Too long BSSID command.\n");
1156 return wpa_ctrl_command(ctrl
, cmd
);
1160 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1163 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1167 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1174 printf("Invalid SELECT_NETWORK command: needs one argument "
1179 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1180 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1182 cmd
[sizeof(cmd
) - 1] = '\0';
1184 return wpa_ctrl_command(ctrl
, cmd
);
1188 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1195 printf("Invalid ENABLE_NETWORK command: needs one argument "
1200 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1201 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1203 cmd
[sizeof(cmd
) - 1] = '\0';
1205 return wpa_ctrl_command(ctrl
, cmd
);
1209 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1216 printf("Invalid DISABLE_NETWORK command: needs one argument "
1221 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1222 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1224 cmd
[sizeof(cmd
) - 1] = '\0';
1226 return wpa_ctrl_command(ctrl
, cmd
);
1230 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1233 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1237 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1244 printf("Invalid REMOVE_NETWORK command: needs one argument "
1249 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1250 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1252 cmd
[sizeof(cmd
) - 1] = '\0';
1254 return wpa_ctrl_command(ctrl
, cmd
);
1258 static void wpa_cli_show_network_variables(void)
1260 printf("set_network variables:\n"
1261 " ssid (network name, SSID)\n"
1262 " psk (WPA passphrase or pre-shared key)\n"
1263 " key_mgmt (key management protocol)\n"
1264 " identity (EAP identity)\n"
1265 " password (EAP password)\n"
1268 "Note: Values are entered in the same format as the "
1269 "configuration file is using,\n"
1270 "i.e., strings values need to be inside double quotation "
1272 "For example: set_network 1 ssid \"network name\"\n"
1274 "Please see wpa_supplicant.conf documentation for full list "
1275 "of\navailable variables.\n");
1279 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1286 wpa_cli_show_network_variables();
1291 printf("Invalid SET_NETWORK command: needs three arguments\n"
1292 "(network id, variable name, and value)\n");
1296 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1297 argv
[0], argv
[1], argv
[2]);
1298 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1299 printf("Too long SET_NETWORK command.\n");
1302 return wpa_ctrl_command(ctrl
, cmd
);
1306 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1313 wpa_cli_show_network_variables();
1318 printf("Invalid GET_NETWORK command: needs two arguments\n"
1319 "(network id and variable name)\n");
1323 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1325 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1326 printf("Too long GET_NETWORK command.\n");
1329 return wpa_ctrl_command(ctrl
, cmd
);
1333 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1336 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1340 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1343 return wpa_ctrl_command(ctrl
, "RECONNECT");
1347 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1350 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1354 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1356 return wpa_ctrl_command(ctrl
, "SCAN");
1360 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1363 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1367 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1373 printf("Invalid BSS command: need one argument (index or "
1378 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1379 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1381 cmd
[sizeof(cmd
) - 1] = '\0';
1383 return wpa_ctrl_command(ctrl
, cmd
);
1387 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1393 if (argc
< 1 || argc
> 2) {
1394 printf("Invalid GET_CAPABILITY command: need either one or "
1399 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1400 printf("Invalid GET_CAPABILITY command: second argument, "
1401 "if any, must be 'strict'\n");
1405 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1406 (argc
== 2) ? " strict" : "");
1407 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1409 cmd
[sizeof(cmd
) - 1] = '\0';
1411 return wpa_ctrl_command(ctrl
, cmd
);
1415 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1417 printf("Available interfaces:\n");
1418 return wpa_ctrl_command(ctrl
, "INTERFACES");
1422 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1425 wpa_cli_list_interfaces(ctrl
);
1429 wpa_cli_close_connection();
1430 os_free(ctrl_ifname
);
1431 ctrl_ifname
= os_strdup(argv
[0]);
1433 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1434 printf("Connected to interface '%s.\n", ctrl_ifname
);
1436 printf("Could not connect to interface '%s' - re-trying\n",
1443 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1446 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1450 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1453 return wpa_ctrl_command(ctrl
, "TERMINATE");
1457 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1464 printf("Invalid INTERFACE_ADD command: needs at least one "
1465 "argument (interface name)\n"
1466 "All arguments: ifname confname driver ctrl_interface "
1467 "driver_param bridge_name\n");
1472 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1473 * <driver_param>TAB<bridge_name>
1475 res
= os_snprintf(cmd
, sizeof(cmd
),
1476 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1478 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1479 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1480 argc
> 5 ? argv
[5] : "");
1481 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1483 cmd
[sizeof(cmd
) - 1] = '\0';
1484 return wpa_ctrl_command(ctrl
, cmd
);
1488 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1495 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1496 "(interface name)\n");
1500 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1501 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1503 cmd
[sizeof(cmd
) - 1] = '\0';
1504 return wpa_ctrl_command(ctrl
, cmd
);
1508 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1511 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1516 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1520 printf("Invalid 'sta' command - exactly one argument, STA "
1521 "address, is required.\n");
1524 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1525 return wpa_ctrl_command(ctrl
, buf
);
1529 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1530 char *addr
, size_t addr_len
)
1532 char buf
[4096], *pos
;
1536 if (ctrl_conn
== NULL
) {
1537 printf("Not connected to hostapd - command dropped.\n");
1540 len
= sizeof(buf
) - 1;
1541 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1544 printf("'%s' command timed out.\n", cmd
);
1546 } else if (ret
< 0) {
1547 printf("'%s' command failed.\n", cmd
);
1552 if (memcmp(buf
, "FAIL", 4) == 0)
1557 while (*pos
!= '\0' && *pos
!= '\n')
1560 os_strlcpy(addr
, buf
, addr_len
);
1565 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1567 char addr
[32], cmd
[64];
1569 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1572 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1573 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1577 #endif /* CONFIG_AP */
1580 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1582 return wpa_ctrl_command(ctrl
, "SUSPEND");
1586 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1588 return wpa_ctrl_command(ctrl
, "RESUME");
1592 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1594 return wpa_ctrl_command(ctrl
, "DROP_SA");
1598 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1604 printf("Invalid ROAM command: needs one argument "
1605 "(target AP's BSSID)\n");
1609 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
1610 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1611 printf("Too long ROAM command.\n");
1614 return wpa_ctrl_command(ctrl
, cmd
);
1620 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1626 return wpa_ctrl_command(ctrl
, "P2P_FIND");
1629 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
1632 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
1633 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1635 cmd
[sizeof(cmd
) - 1] = '\0';
1636 return wpa_ctrl_command(ctrl
, cmd
);
1640 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1643 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1647 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1654 printf("Invalid P2P_CONNECT command: needs at least two "
1655 "arguments (address and pbc/PIN)\n");
1660 res
= os_snprintf(cmd
, sizeof(cmd
),
1661 "P2P_CONNECT %s %s %s %s %s",
1662 argv
[0], argv
[1], argv
[2], argv
[3],
1665 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
1666 argv
[0], argv
[1], argv
[2], argv
[3]);
1668 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
1669 argv
[0], argv
[1], argv
[2]);
1671 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
1673 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1675 cmd
[sizeof(cmd
) - 1] = '\0';
1676 return wpa_ctrl_command(ctrl
, cmd
);
1680 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1687 return wpa_ctrl_command(ctrl
, "P2P_LISTEN");
1689 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_LISTEN %s", argv
[0]);
1690 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1692 cmd
[sizeof(cmd
) - 1] = '\0';
1693 return wpa_ctrl_command(ctrl
, cmd
);
1697 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1704 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1705 "(interface name)\n");
1709 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
1710 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1712 cmd
[sizeof(cmd
) - 1] = '\0';
1713 return wpa_ctrl_command(ctrl
, cmd
);
1717 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1724 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
1726 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s", argv
[0]);
1727 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1729 cmd
[sizeof(cmd
) - 1] = '\0';
1730 return wpa_ctrl_command(ctrl
, cmd
);
1734 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1741 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1742 "(address and config method\n"
1743 "(display, keypad, or pbc)\n");
1747 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
1749 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1751 cmd
[sizeof(cmd
) - 1] = '\0';
1752 return wpa_ctrl_command(ctrl
, cmd
);
1756 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1759 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1763 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1769 if (argc
!= 2 && argc
!= 4) {
1770 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1771 "arguments (address and TLVs) or four arguments "
1772 "(address, \"upnp\", version, search target "
1778 res
= os_snprintf(cmd
, sizeof(cmd
),
1779 "P2P_SERV_DISC_REQ %s %s %s %s",
1780 argv
[0], argv
[1], argv
[2], argv
[3]);
1782 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
1784 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1786 cmd
[sizeof(cmd
) - 1] = '\0';
1787 return wpa_ctrl_command(ctrl
, cmd
);
1791 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1792 int argc
, char *argv
[])
1798 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1799 "argument (pending request identifier)\n");
1803 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
1805 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1807 cmd
[sizeof(cmd
) - 1] = '\0';
1808 return wpa_ctrl_command(ctrl
, cmd
);
1812 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1819 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1820 "arguments (freq, address, dialog token, and TLVs)\n");
1824 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1825 argv
[0], argv
[1], argv
[2], argv
[3]);
1826 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1828 cmd
[sizeof(cmd
) - 1] = '\0';
1829 return wpa_ctrl_command(ctrl
, cmd
);
1833 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1836 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1840 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1841 int argc
, char *argv
[])
1847 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1848 "argument (external processing: 0/1)\n");
1852 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
1854 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1856 cmd
[sizeof(cmd
) - 1] = '\0';
1857 return wpa_ctrl_command(ctrl
, cmd
);
1861 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1864 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1868 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1874 if (argc
!= 3 && argc
!= 4) {
1875 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1881 res
= os_snprintf(cmd
, sizeof(cmd
),
1882 "P2P_SERVICE_ADD %s %s %s %s",
1883 argv
[0], argv
[1], argv
[2], argv
[3]);
1885 res
= os_snprintf(cmd
, sizeof(cmd
),
1886 "P2P_SERVICE_ADD %s %s %s",
1887 argv
[0], argv
[1], argv
[2]);
1888 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1890 cmd
[sizeof(cmd
) - 1] = '\0';
1891 return wpa_ctrl_command(ctrl
, cmd
);
1895 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1901 if (argc
!= 2 && argc
!= 3) {
1902 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1908 res
= os_snprintf(cmd
, sizeof(cmd
),
1909 "P2P_SERVICE_DEL %s %s %s",
1910 argv
[0], argv
[1], argv
[2]);
1912 res
= os_snprintf(cmd
, sizeof(cmd
),
1913 "P2P_SERVICE_DEL %s %s",
1915 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1917 cmd
[sizeof(cmd
) - 1] = '\0';
1918 return wpa_ctrl_command(ctrl
, cmd
);
1922 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1923 int argc
, char *argv
[])
1929 printf("Invalid P2P_REJECT command: needs one argument "
1930 "(peer address)\n");
1934 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
1935 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1937 cmd
[sizeof(cmd
) - 1] = '\0';
1938 return wpa_ctrl_command(ctrl
, cmd
);
1942 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
1943 int argc
, char *argv
[])
1949 printf("Invalid P2P_INVITE command: needs at least one "
1955 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
1956 argv
[0], argv
[1], argv
[2]);
1958 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
1961 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
1962 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1964 cmd
[sizeof(cmd
) - 1] = '\0';
1965 return wpa_ctrl_command(ctrl
, cmd
);
1969 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1973 printf("Invalid 'p2p_peer' command - exactly one argument, "
1974 "P2P peer device address, is required.\n");
1977 os_snprintf(buf
, sizeof(buf
), "P2P_PEER %s", argv
[0]);
1978 return wpa_ctrl_command(ctrl
, buf
);
1982 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
1983 char *addr
, size_t addr_len
,
1986 char buf
[4096], *pos
;
1990 if (ctrl_conn
== NULL
)
1992 len
= sizeof(buf
) - 1;
1993 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1996 printf("'%s' command timed out.\n", cmd
);
1998 } else if (ret
< 0) {
1999 printf("'%s' command failed.\n", cmd
);
2004 if (memcmp(buf
, "FAIL", 4) == 0)
2008 while (*pos
!= '\0' && *pos
!= '\n')
2011 os_strlcpy(addr
, buf
, addr_len
);
2012 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2013 printf("%s\n", addr
);
2018 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2020 char addr
[32], cmd
[64];
2023 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2025 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2026 addr
, sizeof(addr
), discovered
))
2029 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2030 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2037 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2043 printf("Invalid P2P_SET command: needs two arguments (field, "
2048 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
2049 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2051 cmd
[sizeof(cmd
) - 1] = '\0';
2052 return wpa_ctrl_command(ctrl
, cmd
);
2056 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2058 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2062 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2065 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2069 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
2076 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2077 "(peer address)\n");
2081 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_UNAUTHORIZE %s", argv
[0]);
2083 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2086 cmd
[sizeof(cmd
) - 1] = '\0';
2087 return wpa_ctrl_command(ctrl
, cmd
);
2091 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2097 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2098 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2099 "(preferred duration, interval; in microsecods).\n"
2100 "Optional second pair can be used to provide "
2101 "acceptable values.\n");
2106 res
= os_snprintf(cmd
, sizeof(cmd
),
2107 "P2P_PRESENCE_REQ %s %s %s %s",
2108 argv
[0], argv
[1], argv
[2], argv
[3]);
2110 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2113 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
2114 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2116 cmd
[sizeof(cmd
) - 1] = '\0';
2117 return wpa_ctrl_command(ctrl
, cmd
);
2121 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2127 if (argc
!= 0 && argc
!= 2) {
2128 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2129 "(availability period, availability interval; in "
2131 "Extended Listen Timing can be cancelled with this "
2132 "command when used without parameters.\n");
2137 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2140 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2141 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2143 cmd
[sizeof(cmd
) - 1] = '\0';
2144 return wpa_ctrl_command(ctrl
, cmd
);
2147 #endif /* CONFIG_P2P */
2150 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2157 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2158 "(0/1 = disable/enable automatic reconnection)\n");
2161 res
= os_snprintf(cmd
, sizeof(cmd
), "STA_AUTOCONNECT %s", argv
[0]);
2162 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2163 printf("Too long STA_AUTOCONNECT command.\n");
2166 return wpa_ctrl_command(ctrl
, cmd
);
2170 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2177 printf("Invalid TDLS_DISCOVER command: needs one argument "
2178 "(Peer STA MAC address)\n");
2182 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_DISCOVER %s", argv
[0]);
2183 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2184 printf("Too long TDLS_DISCOVER command.\n");
2187 return wpa_ctrl_command(ctrl
, cmd
);
2191 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2198 printf("Invalid TDLS_SETUP command: needs one argument "
2199 "(Peer STA MAC address)\n");
2203 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_SETUP %s", argv
[0]);
2204 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2205 printf("Too long TDLS_SETUP command.\n");
2208 return wpa_ctrl_command(ctrl
, cmd
);
2212 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2219 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2220 "(Peer STA MAC address)\n");
2224 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_TEARDOWN %s", argv
[0]);
2225 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2226 printf("Too long TDLS_TEARDOWN command.\n");
2229 return wpa_ctrl_command(ctrl
, cmd
);
2233 enum wpa_cli_cmd_flags
{
2234 cli_cmd_flag_none
= 0x00,
2235 cli_cmd_flag_sensitive
= 0x01
2238 struct wpa_cli_cmd
{
2240 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2241 enum wpa_cli_cmd_flags flags
;
2245 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2246 { "status", wpa_cli_cmd_status
,
2248 "[verbose] = get current WPA/EAPOL/EAP status" },
2249 { "ping", wpa_cli_cmd_ping
,
2251 "= pings wpa_supplicant" },
2252 { "relog", wpa_cli_cmd_relog
,
2254 "= re-open log-file (allow rolling logs)" },
2255 { "note", wpa_cli_cmd_note
,
2257 "<text> = add a note to wpa_supplicant debug log" },
2258 { "mib", wpa_cli_cmd_mib
,
2260 "= get MIB variables (dot1x, dot11)" },
2261 { "help", wpa_cli_cmd_help
,
2263 "= show this usage help" },
2264 { "interface", wpa_cli_cmd_interface
,
2266 "[ifname] = show interfaces/select interface" },
2267 { "level", wpa_cli_cmd_level
,
2269 "<debug level> = change debug level" },
2270 { "license", wpa_cli_cmd_license
,
2272 "= show full wpa_cli license" },
2273 { "quit", wpa_cli_cmd_quit
,
2276 { "set", wpa_cli_cmd_set
,
2278 "= set variables (shows list of variables when run without "
2280 { "get", wpa_cli_cmd_get
,
2282 "<name> = get information" },
2283 { "logon", wpa_cli_cmd_logon
,
2285 "= IEEE 802.1X EAPOL state machine logon" },
2286 { "logoff", wpa_cli_cmd_logoff
,
2288 "= IEEE 802.1X EAPOL state machine logoff" },
2289 { "pmksa", wpa_cli_cmd_pmksa
,
2291 "= show PMKSA cache" },
2292 { "reassociate", wpa_cli_cmd_reassociate
,
2294 "= force reassociation" },
2295 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2297 "<BSSID> = force preauthentication" },
2298 { "identity", wpa_cli_cmd_identity
,
2300 "<network id> <identity> = configure identity for an SSID" },
2301 { "password", wpa_cli_cmd_password
,
2302 cli_cmd_flag_sensitive
,
2303 "<network id> <password> = configure password for an SSID" },
2304 { "new_password", wpa_cli_cmd_new_password
,
2305 cli_cmd_flag_sensitive
,
2306 "<network id> <password> = change password for an SSID" },
2307 { "pin", wpa_cli_cmd_pin
,
2308 cli_cmd_flag_sensitive
,
2309 "<network id> <pin> = configure pin for an SSID" },
2310 { "otp", wpa_cli_cmd_otp
,
2311 cli_cmd_flag_sensitive
,
2312 "<network id> <password> = configure one-time-password for an SSID"
2314 { "passphrase", wpa_cli_cmd_passphrase
,
2315 cli_cmd_flag_sensitive
,
2316 "<network id> <passphrase> = configure private key passphrase\n"
2318 { "bssid", wpa_cli_cmd_bssid
,
2320 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2321 { "list_networks", wpa_cli_cmd_list_networks
,
2323 "= list configured networks" },
2324 { "select_network", wpa_cli_cmd_select_network
,
2326 "<network id> = select a network (disable others)" },
2327 { "enable_network", wpa_cli_cmd_enable_network
,
2329 "<network id> = enable a network" },
2330 { "disable_network", wpa_cli_cmd_disable_network
,
2332 "<network id> = disable a network" },
2333 { "add_network", wpa_cli_cmd_add_network
,
2335 "= add a network" },
2336 { "remove_network", wpa_cli_cmd_remove_network
,
2338 "<network id> = remove a network" },
2339 { "set_network", wpa_cli_cmd_set_network
,
2340 cli_cmd_flag_sensitive
,
2341 "<network id> <variable> <value> = set network variables (shows\n"
2342 " list of variables when run without arguments)" },
2343 { "get_network", wpa_cli_cmd_get_network
,
2345 "<network id> <variable> = get network variables" },
2346 { "save_config", wpa_cli_cmd_save_config
,
2348 "= save the current configuration" },
2349 { "disconnect", wpa_cli_cmd_disconnect
,
2351 "= disconnect and wait for reassociate/reconnect command before\n"
2353 { "reconnect", wpa_cli_cmd_reconnect
,
2355 "= like reassociate, but only takes effect if already disconnected"
2357 { "scan", wpa_cli_cmd_scan
,
2359 "= request new BSS scan" },
2360 { "scan_results", wpa_cli_cmd_scan_results
,
2362 "= get latest scan results" },
2363 { "bss", wpa_cli_cmd_bss
,
2365 "<<idx> | <bssid>> = get detailed scan result info" },
2366 { "get_capability", wpa_cli_cmd_get_capability
,
2368 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2369 { "reconfigure", wpa_cli_cmd_reconfigure
,
2371 "= force wpa_supplicant to re-read its configuration file" },
2372 { "terminate", wpa_cli_cmd_terminate
,
2374 "= terminate wpa_supplicant" },
2375 { "interface_add", wpa_cli_cmd_interface_add
,
2377 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2378 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2380 { "interface_remove", wpa_cli_cmd_interface_remove
,
2382 "<ifname> = removes the interface" },
2383 { "interface_list", wpa_cli_cmd_interface_list
,
2385 "= list available interfaces" },
2386 { "ap_scan", wpa_cli_cmd_ap_scan
,
2388 "<value> = set ap_scan parameter" },
2389 { "stkstart", wpa_cli_cmd_stkstart
,
2391 "<addr> = request STK negotiation with <addr>" },
2392 { "ft_ds", wpa_cli_cmd_ft_ds
,
2394 "<addr> = request over-the-DS FT with <addr>" },
2395 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
2397 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2398 { "wps_pin", wpa_cli_cmd_wps_pin
,
2399 cli_cmd_flag_sensitive
,
2400 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2402 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
2403 cli_cmd_flag_sensitive
,
2404 "<PIN> = verify PIN checksum" },
2405 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
2406 "Cancels the pending WPS operation" },
2407 #ifdef CONFIG_WPS_OOB
2408 { "wps_oob", wpa_cli_cmd_wps_oob
,
2409 cli_cmd_flag_sensitive
,
2410 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2411 #endif /* CONFIG_WPS_OOB */
2412 { "wps_reg", wpa_cli_cmd_wps_reg
,
2413 cli_cmd_flag_sensitive
,
2414 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2415 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
,
2416 cli_cmd_flag_sensitive
,
2417 "[params..] = enable/disable AP PIN" },
2418 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
2420 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2421 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
2423 "= stop Wi-Fi Protected Setup External Registrar" },
2424 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
2425 cli_cmd_flag_sensitive
,
2426 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2427 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
2429 "<UUID> = accept an Enrollee PBC using External Registrar" },
2430 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
2431 cli_cmd_flag_sensitive
,
2432 "<UUID> <PIN> = learn AP configuration" },
2433 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
,
2435 "<UUID> <network id> = set AP configuration for enrolling" },
2436 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
2437 cli_cmd_flag_sensitive
,
2438 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2439 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
2441 "<addr> = request RSN authentication with <addr> in IBSS" },
2443 { "sta", wpa_cli_cmd_sta
,
2445 "<addr> = get information about an associated station (AP)" },
2446 { "all_sta", wpa_cli_cmd_all_sta
,
2448 "= get information about all associated stations (AP)" },
2449 #endif /* CONFIG_AP */
2450 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
2451 "= notification of suspend/hibernate" },
2452 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
2453 "= notification of resume/thaw" },
2454 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
2455 "= drop SA without deauth/disassoc (test command)" },
2456 { "roam", wpa_cli_cmd_roam
,
2458 "<addr> = roam to the specified BSS" },
2460 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
2461 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2462 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
2463 "= stop P2P Devices search" },
2464 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
2465 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2466 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
2467 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2468 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
2469 "<ifname> = remove P2P group interface (terminate group if GO)" },
2470 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
2471 "= add a new P2P group (local end as GO)" },
2472 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
2473 "<addr> <method> = request provisioning discovery" },
2474 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
2476 "= get the passphrase for a group (GO only)" },
2477 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2479 "<addr> <TLVs> = schedule service discovery request" },
2480 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2482 "<id> = cancel pending service discovery request" },
2483 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2485 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2486 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2488 "= indicate change in local services" },
2489 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2491 "<external> = set external processing of service discovery" },
2492 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2494 "= remove all stored service entries" },
2495 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2497 "<bonjour|upnp> <query|version> <response|service> = add a local "
2499 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2501 "<bonjour|upnp> <query|version> [|service] = remove a local "
2503 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2505 "<addr> = reject connection attempts from a specific peer" },
2506 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
2508 "<cmd> [peer=addr] = invite peer" },
2509 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
2510 "[discovered] = list known (optionally, only fully discovered) P2P "
2512 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
2513 "<address> = show information about known P2P peer" },
2514 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
2515 "<field> <value> = set a P2P parameter" },
2516 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
2517 "= flush P2P state" },
2518 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
2519 "= cancel P2P group formation" },
2520 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
, cli_cmd_flag_none
,
2521 "<address> = unauthorize a peer" },
2522 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
2523 "[<duration> <interval>] [<duration> <interval>] = request GO "
2525 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
2526 "[<period> <interval>] = set extended listen timing" },
2527 #endif /* CONFIG_P2P */
2528 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
2529 "<0/1> = disable/enable automatic reconnection" },
2530 { "tdls_discover", wpa_cli_cmd_tdls_discover
,
2532 "<addr> = request TDLS discovery with <addr>" },
2533 { "tdls_setup", wpa_cli_cmd_tdls_setup
,
2535 "<addr> = request TDLS setup with <addr>" },
2536 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
,
2538 "<addr> = tear down TDLS with <addr>" },
2539 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2544 * Prints command usage, lines are padded with the specified string.
2546 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2551 printf("%s%s ", pad
, cmd
->cmd
);
2552 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2561 static void print_help(void)
2564 printf("commands:\n");
2565 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
2566 print_cmd_help(&wpa_cli_commands
[n
], " ");
2570 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
2572 const char *c
, *delim
;
2576 delim
= os_strchr(cmd
, ' ');
2580 len
= os_strlen(cmd
);
2582 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2583 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2584 return (wpa_cli_commands
[n
].flags
&
2585 cli_cmd_flag_sensitive
);
2591 static char ** wpa_list_cmd_list(void)
2596 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
2597 res
= os_zalloc(count
* sizeof(char *));
2601 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2602 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
2611 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
2616 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2617 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
2619 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
2629 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
2635 end
= os_strchr(str
, ' ');
2636 if (end
== NULL
|| str
+ pos
< end
)
2637 return wpa_list_cmd_list();
2639 cmd
= os_malloc(pos
+ 1);
2642 os_memcpy(cmd
, str
, pos
);
2643 cmd
[end
- str
] = '\0';
2644 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
2650 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2652 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2657 cmd
= wpa_cli_commands
;
2659 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2662 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2663 /* we have an exact match */
2673 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
2674 cmd
= wpa_cli_commands
;
2676 if (os_strncasecmp(cmd
->cmd
, argv
[0],
2677 os_strlen(argv
[0])) == 0) {
2678 printf(" %s", cmd
->cmd
);
2684 } else if (count
== 0) {
2685 printf("Unknown command '%s'\n", argv
[0]);
2688 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
2695 static int str_match(const char *a
, const char *b
)
2697 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
2701 static int wpa_cli_exec(const char *program
, const char *arg1
,
2709 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
2710 cmd
= os_malloc(len
);
2713 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
2714 if (res
< 0 || (size_t) res
>= len
) {
2718 cmd
[len
- 1] = '\0';
2720 if (system(cmd
) < 0)
2722 #endif /* _WIN32_WCE */
2729 static void wpa_cli_action_process(const char *msg
)
2732 char *copy
= NULL
, *id
, *pos2
;
2737 pos
= os_strchr(pos
, '>');
2744 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
2746 os_unsetenv("WPA_ID");
2747 os_unsetenv("WPA_ID_STR");
2748 os_unsetenv("WPA_CTRL_DIR");
2750 pos
= os_strstr(pos
, "[id=");
2752 copy
= os_strdup(pos
+ 4);
2756 while (*pos2
&& *pos2
!= ' ')
2760 os_setenv("WPA_ID", id
, 1);
2761 while (*pos2
&& *pos2
!= '=')
2766 while (*pos2
&& *pos2
!= ']')
2769 os_setenv("WPA_ID_STR", id
, 1);
2773 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
2775 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
2776 wpa_cli_connected
= 1;
2777 wpa_cli_last_id
= new_id
;
2778 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
2780 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
2781 if (wpa_cli_connected
) {
2782 wpa_cli_connected
= 0;
2783 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
2785 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
2786 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2787 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
2788 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2789 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
2790 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2791 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
2792 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2793 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
2794 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2795 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
2796 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2797 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
2798 printf("wpa_supplicant is terminating - stop monitoring\n");
2804 #ifndef CONFIG_ANSI_C_EXTRA
2805 static void wpa_cli_action_cb(char *msg
, size_t len
)
2807 wpa_cli_action_process(msg
);
2809 #endif /* CONFIG_ANSI_C_EXTRA */
2812 static void wpa_cli_reconnect(void)
2814 wpa_cli_close_connection();
2815 wpa_cli_open_connection(ctrl_ifname
, 1);
2819 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
2821 if (ctrl_conn
== NULL
) {
2822 wpa_cli_reconnect();
2825 while (wpa_ctrl_pending(ctrl
) > 0) {
2827 size_t len
= sizeof(buf
) - 1;
2828 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
2831 wpa_cli_action_process(buf
);
2833 if (wpa_cli_show_event(buf
)) {
2835 printf("\r%s\n", buf
);
2840 printf("Could not read pending message.\n");
2845 if (wpa_ctrl_pending(ctrl
) < 0) {
2846 printf("Connection to wpa_supplicant lost - trying to "
2848 wpa_cli_reconnect();
2854 static int tokenize_cmd(char *cmd
, char *argv
[])
2867 if (argc
== max_args
)
2870 char *pos2
= os_strrchr(pos
, '"');
2874 while (*pos
!= '\0' && *pos
!= ' ')
2884 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
2886 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
2887 printf("Connection to wpa_supplicant lost - trying to "
2889 wpa_cli_close_connection();
2892 wpa_cli_reconnect();
2893 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
2897 static void wpa_cli_eloop_terminate(int sig
, void *signal_ctx
)
2903 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
2905 wpa_cli_recv_pending(mon_conn
, 0);
2909 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
2911 char *argv
[max_args
];
2913 argc
= tokenize_cmd(cmd
, argv
);
2915 wpa_request(ctrl_conn
, argc
, argv
);
2919 static void wpa_cli_edit_eof_cb(void *ctx
)
2925 static void wpa_cli_interactive(void)
2927 char *home
, *hfile
= NULL
;
2929 printf("\nInteractive mode\n\n");
2931 home
= getenv("HOME");
2933 const char *fname
= ".wpa_cli_history";
2934 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
2935 hfile
= os_malloc(hfile_len
);
2937 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
2940 eloop_register_signal_terminate(wpa_cli_eloop_terminate
, NULL
);
2941 edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
2942 wpa_cli_edit_completion_cb
, NULL
, hfile
);
2943 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
2947 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
2949 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
2950 wpa_cli_close_connection();
2954 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
2956 #ifdef CONFIG_ANSI_C_EXTRA
2957 /* TODO: ANSI C version(?) */
2958 printf("Action processing not supported in ANSI C build.\n");
2959 #else /* CONFIG_ANSI_C_EXTRA */
2963 char buf
[256]; /* note: large enough to fit in unsolicited messages */
2966 fd
= wpa_ctrl_get_fd(ctrl
);
2968 while (!wpa_cli_quit
) {
2971 tv
.tv_sec
= ping_interval
;
2973 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
2974 if (res
< 0 && errno
!= EINTR
) {
2979 if (FD_ISSET(fd
, &rfds
))
2980 wpa_cli_recv_pending(ctrl
, 1);
2982 /* verify that connection is still working */
2983 len
= sizeof(buf
) - 1;
2984 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
2985 wpa_cli_action_cb
) < 0 ||
2986 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
2987 printf("wpa_supplicant did not reply to PING "
2988 "command - exiting\n");
2993 #endif /* CONFIG_ANSI_C_EXTRA */
2997 static void wpa_cli_cleanup(void)
2999 wpa_cli_close_connection();
3001 os_daemonize_terminate(pid_file
);
3003 os_program_deinit();
3006 static void wpa_cli_terminate(int sig
)
3013 static char * wpa_cli_get_default_ifname(void)
3015 char *ifname
= NULL
;
3017 #ifdef CONFIG_CTRL_IFACE_UNIX
3018 struct dirent
*dent
;
3019 DIR *dir
= opendir(ctrl_iface_dir
);
3022 char ifprop
[PROPERTY_VALUE_MAX
];
3023 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3024 ifname
= os_strdup(ifprop
);
3025 printf("Using interface '%s'\n", ifname
);
3028 #endif /* ANDROID */
3031 while ((dent
= readdir(dir
))) {
3032 #ifdef _DIRENT_HAVE_D_TYPE
3034 * Skip the file if it is not a socket. Also accept
3035 * DT_UNKNOWN (0) in case the C library or underlying
3036 * file system does not support d_type.
3038 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3040 #endif /* _DIRENT_HAVE_D_TYPE */
3041 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3042 os_strcmp(dent
->d_name
, "..") == 0)
3044 printf("Selected interface '%s'\n", dent
->d_name
);
3045 ifname
= os_strdup(dent
->d_name
);
3049 #endif /* CONFIG_CTRL_IFACE_UNIX */
3051 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3052 char buf
[2048], *pos
;
3054 struct wpa_ctrl
*ctrl
;
3057 ctrl
= wpa_ctrl_open(NULL
);
3061 len
= sizeof(buf
) - 1;
3062 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3065 pos
= os_strchr(buf
, '\n');
3068 ifname
= os_strdup(buf
);
3070 wpa_ctrl_close(ctrl
);
3071 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3077 int main(int argc
, char *argv
[])
3079 int warning_displayed
= 0;
3083 const char *global
= NULL
;
3085 if (os_program_init())
3089 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3094 action_file
= optarg
;
3103 ping_interval
= atoi(optarg
);
3109 printf("%s\n", wpa_cli_version
);
3112 os_free(ctrl_ifname
);
3113 ctrl_ifname
= os_strdup(optarg
);
3116 ctrl_iface_dir
= optarg
;
3127 interactive
= (argc
== optind
) && (action_file
== NULL
);
3130 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3136 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3137 ctrl_conn
= wpa_ctrl_open(NULL
);
3138 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3139 ctrl_conn
= wpa_ctrl_open(global
);
3140 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3141 if (ctrl_conn
== NULL
) {
3142 perror("Failed to connect to wpa_supplicant - "
3149 signal(SIGINT
, wpa_cli_terminate
);
3150 signal(SIGTERM
, wpa_cli_terminate
);
3151 #endif /* _WIN32_WCE */
3153 if (ctrl_ifname
== NULL
)
3154 ctrl_ifname
= wpa_cli_get_default_ifname();
3158 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3159 if (warning_displayed
)
3160 printf("Connection established.\n");
3164 if (!warning_displayed
) {
3165 printf("Could not connect to wpa_supplicant - "
3167 warning_displayed
= 1;
3174 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3175 perror("Failed to connect to wpa_supplicant - "
3181 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3182 wpa_cli_attached
= 1;
3184 printf("Warning: Failed to attach to "
3185 "wpa_supplicant.\n");
3191 if (daemonize
&& os_daemonize(pid_file
))
3195 wpa_cli_interactive();
3196 else if (action_file
)
3197 wpa_cli_action(ctrl_conn
);
3199 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
3201 os_free(ctrl_ifname
);
3208 #else /* CONFIG_CTRL_IFACE */
3209 int main(int argc
, char *argv
[])
3211 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3214 #endif /* CONFIG_CTRL_IFACE */