2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2010, 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 */
22 #ifdef CONFIG_READLINE
23 #include <readline/readline.h>
24 #include <readline/history.h>
25 #endif /* CONFIG_READLINE */
26 #ifdef CONFIG_WPA_CLI_FORK
28 #endif /* CONFIG_WPA_CLI_FORK */
30 #include "common/wpa_ctrl.h"
32 #include "common/version.h"
35 static const char *wpa_cli_version
=
36 "wpa_cli v" VERSION_STR
"\n"
37 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
40 static const char *wpa_cli_license
=
41 "This program is free software. You can distribute it and/or modify it\n"
42 "under the terms of the GNU General Public License version 2.\n"
44 "Alternatively, this software may be distributed under the terms of the\n"
45 "BSD license. See README and COPYING for more details.\n";
47 static const char *wpa_cli_full_license
=
48 "This program is free software; you can redistribute it and/or modify\n"
49 "it under the terms of the GNU General Public License version 2 as\n"
50 "published by the Free Software Foundation.\n"
52 "This program is distributed in the hope that it will be useful,\n"
53 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
54 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
55 "GNU General Public License for more details.\n"
57 "You should have received a copy of the GNU General Public License\n"
58 "along with this program; if not, write to the Free Software\n"
59 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
61 "Alternatively, this software may be distributed under the terms of the\n"
64 "Redistribution and use in source and binary forms, with or without\n"
65 "modification, are permitted provided that the following conditions are\n"
68 "1. Redistributions of source code must retain the above copyright\n"
69 " notice, this list of conditions and the following disclaimer.\n"
71 "2. Redistributions in binary form must reproduce the above copyright\n"
72 " notice, this list of conditions and the following disclaimer in the\n"
73 " documentation and/or other materials provided with the distribution.\n"
75 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
76 " names of its contributors may be used to endorse or promote products\n"
77 " derived from this software without specific prior written permission.\n"
79 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
80 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
81 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
82 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
83 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
84 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
85 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
86 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
87 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
88 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
89 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
92 static struct wpa_ctrl
*ctrl_conn
;
93 static struct wpa_ctrl
*mon_conn
;
94 #ifdef CONFIG_WPA_CLI_FORK
95 static pid_t mon_pid
= 0;
96 #endif /* CONFIG_WPA_CLI_FORK */
97 static int wpa_cli_quit
= 0;
98 static int wpa_cli_attached
= 0;
99 static int wpa_cli_connected
= 0;
100 static int wpa_cli_last_id
= 0;
101 static const char *ctrl_iface_dir
= "/var/run/wpa_supplicant";
102 static char *ctrl_ifname
= NULL
;
103 static const char *pid_file
= NULL
;
104 static const char *action_file
= NULL
;
105 static int ping_interval
= 5;
106 static int interactive
= 0;
109 static void print_help();
112 static void usage(void)
114 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
115 "[-a<action file>] \\\n"
116 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
118 " -h = help (show this usage text)\n"
119 " -v = shown version information\n"
120 " -a = run in daemon mode executing the action file based on "
123 " -B = run a daemon in the background\n"
124 " default path: /var/run/wpa_supplicant\n"
125 " default interface: first interface found in socket path\n");
130 static void readline_redraw()
132 #ifdef CONFIG_READLINE
135 #endif /* CONFIG_READLINE */
139 static int str_starts(const char *src
, const char *match
)
141 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
145 static int wpa_cli_show_event(const char *event
)
149 start
= os_strchr(event
, '>');
155 * Skip BSS added/removed events since they can be relatively frequent
156 * and are likely of not much use for an interactive user.
158 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
159 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
166 #ifdef CONFIG_WPA_CLI_FORK
167 static int in_query
= 0;
169 static void wpa_cli_monitor_sig(int sig
)
173 else if (sig
== SIGUSR2
)
178 static void wpa_cli_monitor(void)
181 size_t len
= sizeof(buf
) - 1;
186 signal(SIGUSR1
, wpa_cli_monitor_sig
);
187 signal(SIGUSR2
, wpa_cli_monitor_sig
);
191 int s
= wpa_ctrl_get_fd(mon_conn
);
196 if (select(s
+ 1, &rfds
, NULL
, NULL
, &tv
) < 0) {
202 if (mon_conn
== NULL
)
204 if (FD_ISSET(s
, &rfds
)) {
205 len
= sizeof(buf
) - 1;
206 int res
= wpa_ctrl_recv(mon_conn
, buf
, &len
);
208 perror("wpa_ctrl_recv");
212 if (wpa_cli_show_event(buf
)) {
221 #endif /* CONFIG_WPA_CLI_FORK */
224 static int wpa_cli_open_connection(const char *ifname
, int attach
)
226 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
227 ctrl_conn
= wpa_ctrl_open(ifname
);
228 if (ctrl_conn
== NULL
)
231 if (attach
&& interactive
)
232 mon_conn
= wpa_ctrl_open(ifname
);
235 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
242 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
243 cfile
= os_malloc(flen
);
246 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
, ifname
);
247 if (res
< 0 || res
>= flen
) {
252 ctrl_conn
= wpa_ctrl_open(cfile
);
253 if (ctrl_conn
== NULL
) {
258 if (attach
&& interactive
)
259 mon_conn
= wpa_ctrl_open(cfile
);
263 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
266 if (wpa_ctrl_attach(mon_conn
) == 0) {
267 wpa_cli_attached
= 1;
269 printf("Warning: Failed to attach to "
270 "wpa_supplicant.\n");
274 #ifdef CONFIG_WPA_CLI_FORK
287 #endif /* CONFIG_WPA_CLI_FORK */
294 static void wpa_cli_close_connection(void)
296 if (ctrl_conn
== NULL
)
299 #ifdef CONFIG_WPA_CLI_FORK
302 kill(mon_pid
, SIGPIPE
);
306 #endif /* CONFIG_WPA_CLI_FORK */
308 if (wpa_cli_attached
) {
309 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
310 wpa_cli_attached
= 0;
312 wpa_ctrl_close(ctrl_conn
);
315 wpa_ctrl_close(mon_conn
);
321 static void wpa_cli_msg_cb(char *msg
, size_t len
)
327 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
333 if (ctrl_conn
== NULL
) {
334 printf("Not connected to wpa_supplicant - command dropped.\n");
337 len
= sizeof(buf
) - 1;
338 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
341 printf("'%s' command timed out.\n", cmd
);
343 } else if (ret
< 0) {
344 printf("'%s' command failed.\n", cmd
);
355 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
357 return _wpa_ctrl_command(ctrl
, cmd
, 1);
361 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
363 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
364 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
368 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
370 return wpa_ctrl_command(ctrl
, "PING");
374 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
380 ret
= os_snprintf(cmd
, sizeof(cmd
), "NOTE %s", argv
[0]);
381 if (ret
< 0 || (size_t) ret
>= sizeof(cmd
))
383 return wpa_ctrl_command(ctrl
, cmd
);
387 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
389 return wpa_ctrl_command(ctrl
, "MIB");
393 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
395 return wpa_ctrl_command(ctrl
, "PMKSA");
399 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
406 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
408 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
413 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
420 static void wpa_cli_show_variables(void)
422 printf("set variables:\n"
423 " EAPOL::heldPeriod (EAPOL state machine held period, "
425 " EAPOL::authPeriod (EAPOL state machine authentication "
426 "period, in seconds)\n"
427 " EAPOL::startPeriod (EAPOL state machine start period, in "
429 " EAPOL::maxStart (EAPOL state machine maximum start "
431 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
433 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
434 " threshold\n\tpercentage)\n"
435 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
436 "security\n\tassociation in seconds)\n");
440 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
446 wpa_cli_show_variables();
451 printf("Invalid SET command: needs two arguments (variable "
452 "name and value)\n");
456 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s", argv
[0], argv
[1]);
457 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
458 printf("Too long SET command.\n");
461 return wpa_ctrl_command(ctrl
, cmd
);
465 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
467 return wpa_ctrl_command(ctrl
, "LOGOFF");
471 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
473 return wpa_ctrl_command(ctrl
, "LOGON");
477 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
480 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
484 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
491 printf("Invalid PREAUTH command: needs one argument "
496 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
497 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
498 printf("Too long PREAUTH command.\n");
501 return wpa_ctrl_command(ctrl
, cmd
);
505 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
511 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
515 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
516 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
517 printf("Too long AP_SCAN command.\n");
520 return wpa_ctrl_command(ctrl
, cmd
);
524 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
531 printf("Invalid STKSTART command: needs one argument "
532 "(Peer STA MAC address)\n");
536 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
537 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
538 printf("Too long STKSTART command.\n");
541 return wpa_ctrl_command(ctrl
, cmd
);
545 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
551 printf("Invalid FT_DS command: needs one argument "
552 "(Target AP MAC address)\n");
556 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
557 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
558 printf("Too long FT_DS command.\n");
561 return wpa_ctrl_command(ctrl
, cmd
);
565 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
572 return wpa_ctrl_command(ctrl
, "WPS_PBC");
576 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
577 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
578 printf("Too long WPS_PBC command.\n");
581 return wpa_ctrl_command(ctrl
, cmd
);
585 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
591 printf("Invalid WPS_PIN command: need one or two arguments:\n"
592 "- BSSID: use 'any' to select any\n"
593 "- PIN: optional, used only with devices that have no "
599 /* Use dynamically generated PIN (returned as reply) */
600 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
601 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
602 printf("Too long WPS_PIN command.\n");
605 return wpa_ctrl_command(ctrl
, cmd
);
608 /* Use hardcoded PIN from a label */
609 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
610 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
611 printf("Too long WPS_PIN command.\n");
614 return wpa_ctrl_command(ctrl
, cmd
);
618 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
624 if (argc
!= 1 && argc
!= 2) {
625 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
626 "- PIN to be verified\n");
631 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
634 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
636 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
637 printf("Too long WPS_CHECK_PIN command.\n");
640 return wpa_ctrl_command(ctrl
, cmd
);
644 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
647 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
651 #ifdef CONFIG_WPS_OOB
652 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
657 if (argc
!= 3 && argc
!= 4) {
658 printf("Invalid WPS_OOB command: need three or four "
660 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
661 "- PATH: path of OOB device like '/mnt'\n"
662 "- METHOD: OOB method 'pin-e' or 'pin-r', "
664 "- DEV_NAME: (only for NFC) device name like "
670 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
671 argv
[0], argv
[1], argv
[2]);
673 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
674 argv
[0], argv
[1], argv
[2], argv
[3]);
675 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
676 printf("Too long WPS_OOB command.\n");
679 return wpa_ctrl_command(ctrl
, cmd
);
681 #endif /* CONFIG_WPS_OOB */
684 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
690 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
692 else if (argc
== 5 || argc
== 6) {
693 char ssid_hex
[2 * 32 + 1];
694 char key_hex
[2 * 64 + 1];
698 for (i
= 0; i
< 32; i
++) {
699 if (argv
[2][i
] == '\0')
701 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
706 for (i
= 0; i
< 64; i
++) {
707 if (argv
[5][i
] == '\0')
709 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
714 res
= os_snprintf(cmd
, sizeof(cmd
),
715 "WPS_REG %s %s %s %s %s %s",
716 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
719 printf("Invalid WPS_REG command: need two arguments:\n"
720 "- BSSID: use 'any' to select any\n"
722 printf("Alternatively, six arguments can be used to "
723 "reconfigure the AP:\n"
724 "- BSSID: use 'any' to select any\n"
727 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
728 "- new encr (NONE, WEP, TKIP, CCMP)\n"
733 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
734 printf("Too long WPS_REG command.\n");
737 return wpa_ctrl_command(ctrl
, cmd
);
741 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
746 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
747 return wpa_ctrl_command(ctrl
, cmd
);
749 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
753 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
756 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
761 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
768 printf("Invalid WPS_ER_PIN command: need at least two "
770 "- UUID: use 'any' to select any\n"
771 "- PIN: Enrollee PIN\n"
772 "optional: - Enrollee MAC address\n");
777 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
778 argv
[0], argv
[1], argv
[2]);
780 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
782 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
783 printf("Too long WPS_ER_PIN command.\n");
786 return wpa_ctrl_command(ctrl
, cmd
);
790 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
797 printf("Invalid WPS_ER_PBC command: need one argument:\n"
798 "- UUID: Specify the Enrollee\n");
802 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
804 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
805 printf("Too long WPS_ER_PBC command.\n");
808 return wpa_ctrl_command(ctrl
, cmd
);
812 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
819 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
820 "- UUID: specify which AP to use\n"
825 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
827 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
828 printf("Too long WPS_ER_LEARN command.\n");
831 return wpa_ctrl_command(ctrl
, cmd
);
835 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
841 if (argc
== 5 || argc
== 6) {
842 char ssid_hex
[2 * 32 + 1];
843 char key_hex
[2 * 64 + 1];
847 for (i
= 0; i
< 32; i
++) {
848 if (argv
[2][i
] == '\0')
850 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
855 for (i
= 0; i
< 64; i
++) {
856 if (argv
[5][i
] == '\0')
858 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
863 res
= os_snprintf(cmd
, sizeof(cmd
),
864 "WPS_ER_CONFIG %s %s %s %s %s %s",
865 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
868 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
872 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
873 "- new encr (NONE, WEP, TKIP, CCMP)\n"
878 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
879 printf("Too long WPS_ER_CONFIG command.\n");
882 return wpa_ctrl_command(ctrl
, cmd
);
886 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
892 printf("Invalid IBSS_RSN command: needs one argument "
893 "(Peer STA MAC address)\n");
897 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
898 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
899 printf("Too long IBSS_RSN command.\n");
902 return wpa_ctrl_command(ctrl
, cmd
);
906 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
912 printf("Invalid LEVEL command: needs one argument (debug "
916 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
917 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
918 printf("Too long LEVEL command.\n");
921 return wpa_ctrl_command(ctrl
, cmd
);
925 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
927 char cmd
[256], *pos
, *end
;
931 printf("Invalid IDENTITY command: needs two arguments "
932 "(network id and identity)\n");
936 end
= cmd
+ sizeof(cmd
);
938 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
940 if (ret
< 0 || ret
>= end
- pos
) {
941 printf("Too long IDENTITY command.\n");
945 for (i
= 2; i
< argc
; i
++) {
946 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
947 if (ret
< 0 || ret
>= end
- pos
) {
948 printf("Too long IDENTITY command.\n");
954 return wpa_ctrl_command(ctrl
, cmd
);
958 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
960 char cmd
[256], *pos
, *end
;
964 printf("Invalid PASSWORD command: needs two arguments "
965 "(network id and password)\n");
969 end
= cmd
+ sizeof(cmd
);
971 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
973 if (ret
< 0 || ret
>= end
- pos
) {
974 printf("Too long PASSWORD command.\n");
978 for (i
= 2; i
< argc
; i
++) {
979 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
980 if (ret
< 0 || ret
>= end
- pos
) {
981 printf("Too long PASSWORD command.\n");
987 return wpa_ctrl_command(ctrl
, cmd
);
991 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
994 char cmd
[256], *pos
, *end
;
998 printf("Invalid NEW_PASSWORD command: needs two arguments "
999 "(network id and password)\n");
1003 end
= cmd
+ sizeof(cmd
);
1005 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1007 if (ret
< 0 || ret
>= end
- pos
) {
1008 printf("Too long NEW_PASSWORD command.\n");
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 NEW_PASSWORD command.\n");
1021 return wpa_ctrl_command(ctrl
, cmd
);
1025 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1027 char cmd
[256], *pos
, *end
;
1031 printf("Invalid PIN command: needs two arguments "
1032 "(network id and pin)\n");
1036 end
= cmd
+ sizeof(cmd
);
1038 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1040 if (ret
< 0 || ret
>= end
- pos
) {
1041 printf("Too long PIN command.\n");
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 PIN command.\n");
1053 return wpa_ctrl_command(ctrl
, cmd
);
1057 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1059 char cmd
[256], *pos
, *end
;
1063 printf("Invalid OTP command: needs two arguments (network "
1064 "id and password)\n");
1068 end
= cmd
+ sizeof(cmd
);
1070 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1072 if (ret
< 0 || ret
>= end
- pos
) {
1073 printf("Too long OTP command.\n");
1077 for (i
= 2; i
< argc
; i
++) {
1078 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1079 if (ret
< 0 || ret
>= end
- pos
) {
1080 printf("Too long OTP command.\n");
1086 return wpa_ctrl_command(ctrl
, cmd
);
1090 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1093 char cmd
[256], *pos
, *end
;
1097 printf("Invalid PASSPHRASE command: needs two arguments "
1098 "(network id and passphrase)\n");
1102 end
= cmd
+ sizeof(cmd
);
1104 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1106 if (ret
< 0 || ret
>= end
- pos
) {
1107 printf("Too long PASSPHRASE command.\n");
1111 for (i
= 2; i
< argc
; i
++) {
1112 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1113 if (ret
< 0 || ret
>= end
- pos
) {
1114 printf("Too long PASSPHRASE command.\n");
1120 return wpa_ctrl_command(ctrl
, cmd
);
1124 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1126 char cmd
[256], *pos
, *end
;
1130 printf("Invalid BSSID command: needs two arguments (network "
1135 end
= cmd
+ sizeof(cmd
);
1137 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1138 if (ret
< 0 || ret
>= end
- pos
) {
1139 printf("Too long BSSID command.\n");
1143 for (i
= 0; i
< argc
; i
++) {
1144 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1145 if (ret
< 0 || ret
>= end
- pos
) {
1146 printf("Too long BSSID command.\n");
1152 return wpa_ctrl_command(ctrl
, cmd
);
1156 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1159 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1163 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1170 printf("Invalid SELECT_NETWORK command: needs one argument "
1175 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1176 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1178 cmd
[sizeof(cmd
) - 1] = '\0';
1180 return wpa_ctrl_command(ctrl
, cmd
);
1184 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1191 printf("Invalid ENABLE_NETWORK command: needs one argument "
1196 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1197 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1199 cmd
[sizeof(cmd
) - 1] = '\0';
1201 return wpa_ctrl_command(ctrl
, cmd
);
1205 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1212 printf("Invalid DISABLE_NETWORK command: needs one argument "
1217 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1218 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1220 cmd
[sizeof(cmd
) - 1] = '\0';
1222 return wpa_ctrl_command(ctrl
, cmd
);
1226 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1229 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1233 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1240 printf("Invalid REMOVE_NETWORK command: needs one argument "
1245 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1246 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1248 cmd
[sizeof(cmd
) - 1] = '\0';
1250 return wpa_ctrl_command(ctrl
, cmd
);
1254 static void wpa_cli_show_network_variables(void)
1256 printf("set_network variables:\n"
1257 " ssid (network name, SSID)\n"
1258 " psk (WPA passphrase or pre-shared key)\n"
1259 " key_mgmt (key management protocol)\n"
1260 " identity (EAP identity)\n"
1261 " password (EAP password)\n"
1264 "Note: Values are entered in the same format as the "
1265 "configuration file is using,\n"
1266 "i.e., strings values need to be inside double quotation "
1268 "For example: set_network 1 ssid \"network name\"\n"
1270 "Please see wpa_supplicant.conf documentation for full list "
1271 "of\navailable variables.\n");
1275 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1282 wpa_cli_show_network_variables();
1287 printf("Invalid SET_NETWORK command: needs three arguments\n"
1288 "(network id, variable name, and value)\n");
1292 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1293 argv
[0], argv
[1], argv
[2]);
1294 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1295 printf("Too long SET_NETWORK command.\n");
1298 return wpa_ctrl_command(ctrl
, cmd
);
1302 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1309 wpa_cli_show_network_variables();
1314 printf("Invalid GET_NETWORK command: needs two arguments\n"
1315 "(network id and variable name)\n");
1319 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1321 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1322 printf("Too long GET_NETWORK command.\n");
1325 return wpa_ctrl_command(ctrl
, cmd
);
1329 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1332 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1336 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1339 return wpa_ctrl_command(ctrl
, "RECONNECT");
1343 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1346 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1350 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1352 return wpa_ctrl_command(ctrl
, "SCAN");
1356 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1359 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1363 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1369 printf("Invalid BSS command: need one argument (index or "
1374 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1375 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1377 cmd
[sizeof(cmd
) - 1] = '\0';
1379 return wpa_ctrl_command(ctrl
, cmd
);
1383 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1389 if (argc
< 1 || argc
> 2) {
1390 printf("Invalid GET_CAPABILITY command: need either one or "
1395 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1396 printf("Invalid GET_CAPABILITY command: second argument, "
1397 "if any, must be 'strict'\n");
1401 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1402 (argc
== 2) ? " strict" : "");
1403 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1405 cmd
[sizeof(cmd
) - 1] = '\0';
1407 return wpa_ctrl_command(ctrl
, cmd
);
1411 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1413 printf("Available interfaces:\n");
1414 return wpa_ctrl_command(ctrl
, "INTERFACES");
1418 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1421 wpa_cli_list_interfaces(ctrl
);
1425 wpa_cli_close_connection();
1426 os_free(ctrl_ifname
);
1427 ctrl_ifname
= os_strdup(argv
[0]);
1429 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1430 printf("Connected to interface '%s.\n", ctrl_ifname
);
1432 printf("Could not connect to interface '%s' - re-trying\n",
1439 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1442 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1446 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1449 return wpa_ctrl_command(ctrl
, "TERMINATE");
1453 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1460 printf("Invalid INTERFACE_ADD command: needs at least one "
1461 "argument (interface name)\n"
1462 "All arguments: ifname confname driver ctrl_interface "
1463 "driver_param bridge_name\n");
1468 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1469 * <driver_param>TAB<bridge_name>
1471 res
= os_snprintf(cmd
, sizeof(cmd
),
1472 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1474 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1475 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1476 argc
> 5 ? argv
[5] : "");
1477 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1479 cmd
[sizeof(cmd
) - 1] = '\0';
1480 return wpa_ctrl_command(ctrl
, cmd
);
1484 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1491 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1492 "(interface name)\n");
1496 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1497 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1499 cmd
[sizeof(cmd
) - 1] = '\0';
1500 return wpa_ctrl_command(ctrl
, cmd
);
1504 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1507 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1512 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1516 printf("Invalid 'sta' command - exactly one argument, STA "
1517 "address, is required.\n");
1520 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1521 return wpa_ctrl_command(ctrl
, buf
);
1525 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1526 char *addr
, size_t addr_len
)
1528 char buf
[4096], *pos
;
1532 if (ctrl_conn
== NULL
) {
1533 printf("Not connected to hostapd - command dropped.\n");
1536 len
= sizeof(buf
) - 1;
1537 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1540 printf("'%s' command timed out.\n", cmd
);
1542 } else if (ret
< 0) {
1543 printf("'%s' command failed.\n", cmd
);
1548 if (memcmp(buf
, "FAIL", 4) == 0)
1553 while (*pos
!= '\0' && *pos
!= '\n')
1556 os_strlcpy(addr
, buf
, addr_len
);
1561 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1563 char addr
[32], cmd
[64];
1565 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1568 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1569 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1573 #endif /* CONFIG_AP */
1576 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1578 return wpa_ctrl_command(ctrl
, "SUSPEND");
1582 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1584 return wpa_ctrl_command(ctrl
, "RESUME");
1588 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1590 return wpa_ctrl_command(ctrl
, "DROP_SA");
1594 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1600 printf("Invalid ROAM command: needs one argument "
1601 "(target AP's BSSID)\n");
1605 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
1606 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1607 printf("Too long ROAM command.\n");
1610 return wpa_ctrl_command(ctrl
, cmd
);
1616 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1622 return wpa_ctrl_command(ctrl
, "P2P_FIND");
1625 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
1628 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
1629 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1631 cmd
[sizeof(cmd
) - 1] = '\0';
1632 return wpa_ctrl_command(ctrl
, cmd
);
1636 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1639 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1643 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1650 printf("Invalid P2P_CONNECT command: needs at least two "
1651 "arguments (address and pbc/PIN)\n");
1656 res
= os_snprintf(cmd
, sizeof(cmd
),
1657 "P2P_CONNECT %s %s %s %s %s",
1658 argv
[0], argv
[1], argv
[2], argv
[3],
1661 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
1662 argv
[0], argv
[1], argv
[2], argv
[3]);
1664 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
1665 argv
[0], argv
[1], argv
[2]);
1667 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
1669 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1671 cmd
[sizeof(cmd
) - 1] = '\0';
1672 return wpa_ctrl_command(ctrl
, cmd
);
1676 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1683 return wpa_ctrl_command(ctrl
, "P2P_LISTEN");
1685 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_LISTEN %s", argv
[0]);
1686 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1688 cmd
[sizeof(cmd
) - 1] = '\0';
1689 return wpa_ctrl_command(ctrl
, cmd
);
1693 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1700 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1701 "(interface name)\n");
1705 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
1706 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1708 cmd
[sizeof(cmd
) - 1] = '\0';
1709 return wpa_ctrl_command(ctrl
, cmd
);
1713 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1720 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
1722 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s", argv
[0]);
1723 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1725 cmd
[sizeof(cmd
) - 1] = '\0';
1726 return wpa_ctrl_command(ctrl
, cmd
);
1730 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1737 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1738 "(address and config method\n"
1739 "(display, keypad, or pbc)\n");
1743 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
1745 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1747 cmd
[sizeof(cmd
) - 1] = '\0';
1748 return wpa_ctrl_command(ctrl
, cmd
);
1752 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1755 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1759 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1765 if (argc
!= 2 && argc
!= 4) {
1766 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1767 "arguments (address and TLVs) or four arguments "
1768 "(address, \"upnp\", version, search target "
1774 res
= os_snprintf(cmd
, sizeof(cmd
),
1775 "P2P_SERV_DISC_REQ %s %s %s %s",
1776 argv
[0], argv
[1], argv
[2], argv
[3]);
1778 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
1780 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1782 cmd
[sizeof(cmd
) - 1] = '\0';
1783 return wpa_ctrl_command(ctrl
, cmd
);
1787 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1788 int argc
, char *argv
[])
1794 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1795 "argument (pending request identifier)\n");
1799 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
1801 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1803 cmd
[sizeof(cmd
) - 1] = '\0';
1804 return wpa_ctrl_command(ctrl
, cmd
);
1808 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1815 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1816 "arguments (freq, address, dialog token, and TLVs)\n");
1820 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1821 argv
[0], argv
[1], argv
[2], argv
[3]);
1822 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1824 cmd
[sizeof(cmd
) - 1] = '\0';
1825 return wpa_ctrl_command(ctrl
, cmd
);
1829 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1832 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1836 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1837 int argc
, char *argv
[])
1843 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1844 "argument (external processing: 0/1)\n");
1848 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
1850 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1852 cmd
[sizeof(cmd
) - 1] = '\0';
1853 return wpa_ctrl_command(ctrl
, cmd
);
1857 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1860 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1864 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1870 if (argc
!= 3 && argc
!= 4) {
1871 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1877 res
= os_snprintf(cmd
, sizeof(cmd
),
1878 "P2P_SERVICE_ADD %s %s %s %s",
1879 argv
[0], argv
[1], argv
[2], argv
[3]);
1881 res
= os_snprintf(cmd
, sizeof(cmd
),
1882 "P2P_SERVICE_ADD %s %s %s",
1883 argv
[0], argv
[1], argv
[2]);
1884 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1886 cmd
[sizeof(cmd
) - 1] = '\0';
1887 return wpa_ctrl_command(ctrl
, cmd
);
1891 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1897 if (argc
!= 2 && argc
!= 3) {
1898 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1904 res
= os_snprintf(cmd
, sizeof(cmd
),
1905 "P2P_SERVICE_DEL %s %s %s",
1906 argv
[0], argv
[1], argv
[2]);
1908 res
= os_snprintf(cmd
, sizeof(cmd
),
1909 "P2P_SERVICE_DEL %s %s",
1911 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1913 cmd
[sizeof(cmd
) - 1] = '\0';
1914 return wpa_ctrl_command(ctrl
, cmd
);
1918 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1919 int argc
, char *argv
[])
1925 printf("Invalid P2P_REJECT command: needs one argument "
1926 "(peer address)\n");
1930 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
1931 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1933 cmd
[sizeof(cmd
) - 1] = '\0';
1934 return wpa_ctrl_command(ctrl
, cmd
);
1938 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
1939 int argc
, char *argv
[])
1945 printf("Invalid P2P_INVITE command: needs at least one "
1951 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
1952 argv
[0], argv
[1], argv
[2]);
1954 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
1957 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
1958 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1960 cmd
[sizeof(cmd
) - 1] = '\0';
1961 return wpa_ctrl_command(ctrl
, cmd
);
1965 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1969 printf("Invalid 'p2p_peer' command - exactly one argument, "
1970 "P2P peer device address, is required.\n");
1973 os_snprintf(buf
, sizeof(buf
), "P2P_PEER %s", argv
[0]);
1974 return wpa_ctrl_command(ctrl
, buf
);
1978 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
1979 char *addr
, size_t addr_len
,
1982 char buf
[4096], *pos
;
1986 if (ctrl_conn
== NULL
)
1988 len
= sizeof(buf
) - 1;
1989 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1992 printf("'%s' command timed out.\n", cmd
);
1994 } else if (ret
< 0) {
1995 printf("'%s' command failed.\n", cmd
);
2000 if (memcmp(buf
, "FAIL", 4) == 0)
2004 while (*pos
!= '\0' && *pos
!= '\n')
2007 os_strlcpy(addr
, buf
, addr_len
);
2008 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2009 printf("%s\n", addr
);
2014 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2016 char addr
[32], cmd
[64];
2019 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2021 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2022 addr
, sizeof(addr
), discovered
))
2025 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2026 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2033 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2039 printf("Invalid P2P_SET command: needs two arguments (field, "
2044 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
2045 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2047 cmd
[sizeof(cmd
) - 1] = '\0';
2048 return wpa_ctrl_command(ctrl
, cmd
);
2052 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2054 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2058 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2061 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2065 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2071 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2072 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2073 "(preferred duration, interval; in microsecods).\n"
2074 "Optional second pair can be used to provide "
2075 "acceptable values.\n");
2080 res
= os_snprintf(cmd
, sizeof(cmd
),
2081 "P2P_PRESENCE_REQ %s %s %s %s",
2082 argv
[0], argv
[1], argv
[2], argv
[3]);
2084 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2087 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
2088 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2090 cmd
[sizeof(cmd
) - 1] = '\0';
2091 return wpa_ctrl_command(ctrl
, cmd
);
2095 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2101 if (argc
!= 0 && argc
!= 2) {
2102 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2103 "(availability period, availability interval; in "
2105 "Extended Listen Timing can be cancelled with this "
2106 "command when used without parameters.\n");
2111 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2114 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2115 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2117 cmd
[sizeof(cmd
) - 1] = '\0';
2118 return wpa_ctrl_command(ctrl
, cmd
);
2121 #endif /* CONFIG_P2P */
2124 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2131 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2132 "(0/1 = disable/enable automatic reconnection)\n");
2135 res
= os_snprintf(cmd
, sizeof(cmd
), "STA_AUTOCONNECT %s", argv
[0]);
2136 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2137 printf("Too long STA_AUTOCONNECT command.\n");
2140 return wpa_ctrl_command(ctrl
, cmd
);
2144 enum wpa_cli_cmd_flags
{
2145 cli_cmd_flag_none
= 0x00,
2146 cli_cmd_flag_sensitive
= 0x01
2149 struct wpa_cli_cmd
{
2151 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2152 enum wpa_cli_cmd_flags flags
;
2156 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2157 { "status", wpa_cli_cmd_status
,
2159 "[verbose] = get current WPA/EAPOL/EAP status" },
2160 { "ping", wpa_cli_cmd_ping
,
2162 "= pings wpa_supplicant" },
2163 { "note", wpa_cli_cmd_note
,
2165 "<text> = add a note to wpa_supplicant debug log" },
2166 { "mib", wpa_cli_cmd_mib
,
2168 "= get MIB variables (dot1x, dot11)" },
2169 { "help", wpa_cli_cmd_help
,
2171 "= show this usage help" },
2172 { "interface", wpa_cli_cmd_interface
,
2174 "[ifname] = show interfaces/select interface" },
2175 { "level", wpa_cli_cmd_level
,
2177 "<debug level> = change debug level" },
2178 { "license", wpa_cli_cmd_license
,
2180 "= show full wpa_cli license" },
2181 { "quit", wpa_cli_cmd_quit
,
2184 { "set", wpa_cli_cmd_set
,
2186 "= set variables (shows list of variables when run without "
2188 { "logon", wpa_cli_cmd_logon
,
2190 "= IEEE 802.1X EAPOL state machine logon" },
2191 { "logoff", wpa_cli_cmd_logoff
,
2193 "= IEEE 802.1X EAPOL state machine logoff" },
2194 { "pmksa", wpa_cli_cmd_pmksa
,
2196 "= show PMKSA cache" },
2197 { "reassociate", wpa_cli_cmd_reassociate
,
2199 "= force reassociation" },
2200 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2202 "<BSSID> = force preauthentication" },
2203 { "identity", wpa_cli_cmd_identity
,
2205 "<network id> <identity> = configure identity for an SSID" },
2206 { "password", wpa_cli_cmd_password
,
2207 cli_cmd_flag_sensitive
,
2208 "<network id> <password> = configure password for an SSID" },
2209 { "new_password", wpa_cli_cmd_new_password
,
2210 cli_cmd_flag_sensitive
,
2211 "<network id> <password> = change password for an SSID" },
2212 { "pin", wpa_cli_cmd_pin
,
2213 cli_cmd_flag_sensitive
,
2214 "<network id> <pin> = configure pin for an SSID" },
2215 { "otp", wpa_cli_cmd_otp
,
2216 cli_cmd_flag_sensitive
,
2217 "<network id> <password> = configure one-time-password for an SSID"
2219 { "passphrase", wpa_cli_cmd_passphrase
,
2220 cli_cmd_flag_sensitive
,
2221 "<network id> <passphrase> = configure private key passphrase\n"
2223 { "bssid", wpa_cli_cmd_bssid
,
2225 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2226 { "list_networks", wpa_cli_cmd_list_networks
,
2228 "= list configured networks" },
2229 { "select_network", wpa_cli_cmd_select_network
,
2231 "<network id> = select a network (disable others)" },
2232 { "enable_network", wpa_cli_cmd_enable_network
,
2234 "<network id> = enable a network" },
2235 { "disable_network", wpa_cli_cmd_disable_network
,
2237 "<network id> = disable a network" },
2238 { "add_network", wpa_cli_cmd_add_network
,
2240 "= add a network" },
2241 { "remove_network", wpa_cli_cmd_remove_network
,
2243 "<network id> = remove a network" },
2244 { "set_network", wpa_cli_cmd_set_network
,
2245 cli_cmd_flag_sensitive
,
2246 "<network id> <variable> <value> = set network variables (shows\n"
2247 " list of variables when run without arguments)" },
2248 { "get_network", wpa_cli_cmd_get_network
,
2250 "<network id> <variable> = get network variables" },
2251 { "save_config", wpa_cli_cmd_save_config
,
2253 "= save the current configuration" },
2254 { "disconnect", wpa_cli_cmd_disconnect
,
2256 "= disconnect and wait for reassociate/reconnect command before\n"
2258 { "reconnect", wpa_cli_cmd_reconnect
,
2260 "= like reassociate, but only takes effect if already disconnected"
2262 { "scan", wpa_cli_cmd_scan
,
2264 "= request new BSS scan" },
2265 { "scan_results", wpa_cli_cmd_scan_results
,
2267 "= get latest scan results" },
2268 { "bss", wpa_cli_cmd_bss
,
2270 "<<idx> | <bssid>> = get detailed scan result info" },
2271 { "get_capability", wpa_cli_cmd_get_capability
,
2273 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2274 { "reconfigure", wpa_cli_cmd_reconfigure
,
2276 "= force wpa_supplicant to re-read its configuration file" },
2277 { "terminate", wpa_cli_cmd_terminate
,
2279 "= terminate wpa_supplicant" },
2280 { "interface_add", wpa_cli_cmd_interface_add
,
2282 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2283 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2285 { "interface_remove", wpa_cli_cmd_interface_remove
,
2287 "<ifname> = removes the interface" },
2288 { "interface_list", wpa_cli_cmd_interface_list
,
2290 "= list available interfaces" },
2291 { "ap_scan", wpa_cli_cmd_ap_scan
,
2293 "<value> = set ap_scan parameter" },
2294 { "stkstart", wpa_cli_cmd_stkstart
,
2296 "<addr> = request STK negotiation with <addr>" },
2297 { "ft_ds", wpa_cli_cmd_ft_ds
,
2299 "<addr> = request over-the-DS FT with <addr>" },
2300 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
2302 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2303 { "wps_pin", wpa_cli_cmd_wps_pin
,
2304 cli_cmd_flag_sensitive
,
2305 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2307 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
2308 cli_cmd_flag_sensitive
,
2309 "<PIN> = verify PIN checksum" },
2310 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
2311 "Cancels the pending WPS operation" },
2312 #ifdef CONFIG_WPS_OOB
2313 { "wps_oob", wpa_cli_cmd_wps_oob
,
2314 cli_cmd_flag_sensitive
,
2315 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2316 #endif /* CONFIG_WPS_OOB */
2317 { "wps_reg", wpa_cli_cmd_wps_reg
,
2318 cli_cmd_flag_sensitive
,
2319 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2320 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
2322 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2323 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
2325 "= stop Wi-Fi Protected Setup External Registrar" },
2326 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
2327 cli_cmd_flag_sensitive
,
2328 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2329 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
2331 "<UUID> = accept an Enrollee PBC using External Registrar" },
2332 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
2333 cli_cmd_flag_sensitive
,
2334 "<UUID> <PIN> = learn AP configuration" },
2335 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
2336 cli_cmd_flag_sensitive
,
2337 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2338 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
2340 "<addr> = request RSN authentication with <addr> in IBSS" },
2342 { "sta", wpa_cli_cmd_sta
,
2344 "<addr> = get information about an associated station (AP)" },
2345 { "all_sta", wpa_cli_cmd_all_sta
,
2347 "= get information about all associated stations (AP)" },
2348 #endif /* CONFIG_AP */
2349 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
2350 "= notification of suspend/hibernate" },
2351 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
2352 "= notification of resume/thaw" },
2353 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
2354 "= drop SA without deauth/disassoc (test command)" },
2355 { "roam", wpa_cli_cmd_roam
,
2357 "<addr> = roam to the specified BSS" },
2359 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
2360 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2361 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
2362 "= stop P2P Devices search" },
2363 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
2364 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2365 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
2366 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2367 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
2368 "<ifname> = remote P2P group interface (terminate group if GO)" },
2369 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
2370 "= add a new P2P group (local end as GO)" },
2371 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
2372 "<addr> <method> = request provisioning discovery" },
2373 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
2375 "= get the passphrase for a group (GO only)" },
2376 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2378 "<addr> <TLVs> = schedule service discovery request" },
2379 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2381 "<id> = cancel pending service discovery request" },
2382 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2384 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2385 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2387 "= indicate change in local services" },
2388 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2390 "<external> = set external processing of service discovery" },
2391 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2393 "= remove all stored service entries" },
2394 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2396 "<bonjour|upnp> <query|version> <response|service> = add a local "
2398 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2400 "<bonjour|upnp> <query|version> [|service] = remove a local "
2402 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2404 "<addr> = reject connection attempts from a specific peer" },
2405 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
2407 "<cmd> [peer=addr] = invite peer" },
2408 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
2409 "[discovered] = list known (optionally, only fully discovered) P2P "
2411 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
2412 "<address> = show information about known P2P peer" },
2413 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
2414 "<field> <value> = set a P2P parameter" },
2415 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
2416 "= flush P2P state" },
2417 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
2418 "= cancel P2P group formation" },
2419 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
2420 "[<duration> <interval>] [<duration> <interval>] = request GO "
2422 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
2423 "[<period> <interval>] = set extended listen timing" },
2424 #endif /* CONFIG_P2P */
2425 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
2426 "<0/1> = disable/enable automatic reconnection" },
2427 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2432 * Prints command usage, lines are padded with the specified string.
2434 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2439 printf("%s%s ", pad
, cmd
->cmd
);
2440 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2449 static void print_help(void)
2452 printf("commands:\n");
2453 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
2454 print_cmd_help(&wpa_cli_commands
[n
], " ");
2458 #ifdef CONFIG_READLINE
2459 static int cmd_has_sensitive_data(const char *cmd
)
2461 const char *c
, *delim
;
2465 delim
= os_strchr(cmd
, ' ');
2469 len
= os_strlen(cmd
);
2471 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2472 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2473 return (wpa_cli_commands
[n
].flags
&
2474 cli_cmd_flag_sensitive
);
2478 #endif /* CONFIG_READLINE */
2481 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2483 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2488 cmd
= wpa_cli_commands
;
2490 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2493 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2494 /* we have an exact match */
2504 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
2505 cmd
= wpa_cli_commands
;
2507 if (os_strncasecmp(cmd
->cmd
, argv
[0],
2508 os_strlen(argv
[0])) == 0) {
2509 printf(" %s", cmd
->cmd
);
2515 } else if (count
== 0) {
2516 printf("Unknown command '%s'\n", argv
[0]);
2519 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
2526 static int str_match(const char *a
, const char *b
)
2528 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
2532 static int wpa_cli_exec(const char *program
, const char *arg1
,
2540 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
2541 cmd
= os_malloc(len
);
2544 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
2545 if (res
< 0 || (size_t) res
>= len
) {
2549 cmd
[len
- 1] = '\0';
2551 if (system(cmd
) < 0)
2553 #endif /* _WIN32_WCE */
2560 static void wpa_cli_action_process(const char *msg
)
2563 char *copy
= NULL
, *id
, *pos2
;
2568 pos
= os_strchr(pos
, '>');
2575 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
2577 os_unsetenv("WPA_ID");
2578 os_unsetenv("WPA_ID_STR");
2579 os_unsetenv("WPA_CTRL_DIR");
2581 pos
= os_strstr(pos
, "[id=");
2583 copy
= os_strdup(pos
+ 4);
2587 while (*pos2
&& *pos2
!= ' ')
2591 os_setenv("WPA_ID", id
, 1);
2592 while (*pos2
&& *pos2
!= '=')
2597 while (*pos2
&& *pos2
!= ']')
2600 os_setenv("WPA_ID_STR", id
, 1);
2604 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
2606 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
2607 wpa_cli_connected
= 1;
2608 wpa_cli_last_id
= new_id
;
2609 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
2611 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
2612 if (wpa_cli_connected
) {
2613 wpa_cli_connected
= 0;
2614 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
2616 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
2617 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2618 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
2619 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2620 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
2621 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2622 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
2623 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2624 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
2625 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2626 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
2627 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2628 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
2629 printf("wpa_supplicant is terminating - stop monitoring\n");
2635 #ifndef CONFIG_ANSI_C_EXTRA
2636 static void wpa_cli_action_cb(char *msg
, size_t len
)
2638 wpa_cli_action_process(msg
);
2640 #endif /* CONFIG_ANSI_C_EXTRA */
2643 static void wpa_cli_reconnect(void)
2645 wpa_cli_close_connection();
2646 wpa_cli_open_connection(ctrl_ifname
, 1);
2650 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int in_read
,
2654 if (ctrl_conn
== NULL
) {
2655 wpa_cli_reconnect();
2658 while (wpa_ctrl_pending(ctrl
) > 0) {
2660 size_t len
= sizeof(buf
) - 1;
2661 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
2664 wpa_cli_action_process(buf
);
2666 if (wpa_cli_show_event(buf
)) {
2667 if (in_read
&& first
)
2670 printf("%s\n", buf
);
2675 printf("Could not read pending message.\n");
2680 if (wpa_ctrl_pending(ctrl
) < 0) {
2681 printf("Connection to wpa_supplicant lost - trying to "
2683 wpa_cli_reconnect();
2688 #ifdef CONFIG_READLINE
2689 static char * wpa_cli_cmd_gen(const char *text
, int state
)
2696 len
= os_strlen(text
);
2699 while ((cmd
= wpa_cli_commands
[i
].cmd
)) {
2701 if (os_strncasecmp(cmd
, text
, len
) == 0)
2709 static char * wpa_cli_dummy_gen(const char *text
, int state
)
2713 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2714 const char *cmd
= wpa_cli_commands
[i
].cmd
;
2715 size_t len
= os_strlen(cmd
);
2716 if (os_strncasecmp(rl_line_buffer
, cmd
, len
) == 0 &&
2717 rl_line_buffer
[len
] == ' ') {
2718 printf("\n%s\n", wpa_cli_commands
[i
].usage
);
2724 rl_attempted_completion_over
= 1;
2729 static char * wpa_cli_status_gen(const char *text
, int state
)
2739 len
= os_strlen(text
);
2742 while ((t
= options
[i
])) {
2744 if (os_strncasecmp(t
, text
, len
) == 0)
2748 rl_attempted_completion_over
= 1;
2753 static char ** wpa_cli_completion(const char *text
, int start
, int end
)
2755 char * (*func
)(const char *text
, int state
);
2758 func
= wpa_cli_cmd_gen
;
2759 else if (os_strncasecmp(rl_line_buffer
, "status ", 7) == 0)
2760 func
= wpa_cli_status_gen
;
2762 func
= wpa_cli_dummy_gen
;
2763 return rl_completion_matches(text
, func
);
2765 #endif /* CONFIG_READLINE */
2768 static void wpa_cli_interactive(void)
2771 char cmdbuf
[256], *cmd
, *argv
[max_args
], *pos
;
2773 #ifdef CONFIG_READLINE
2774 char *home
, *hfile
= NULL
;
2775 #endif /* CONFIG_READLINE */
2777 printf("\nInteractive mode\n\n");
2779 #ifdef CONFIG_READLINE
2780 rl_attempted_completion_function
= wpa_cli_completion
;
2781 home
= getenv("HOME");
2783 const char *fname
= ".wpa_cli_history";
2784 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
2785 hfile
= os_malloc(hfile_len
);
2788 res
= os_snprintf(hfile
, hfile_len
, "%s/%s", home
,
2790 if (res
>= 0 && res
< hfile_len
) {
2791 hfile
[hfile_len
- 1] = '\0';
2792 read_history(hfile
);
2793 stifle_history(100);
2797 #endif /* CONFIG_READLINE */
2800 wpa_cli_recv_pending(mon_conn
, 0, 0);
2801 #ifndef CONFIG_NATIVE_WINDOWS
2802 alarm(ping_interval
);
2803 #endif /* CONFIG_NATIVE_WINDOWS */
2804 #ifdef CONFIG_WPA_CLI_FORK
2806 kill(mon_pid
, SIGUSR1
);
2807 #endif /* CONFIG_WPA_CLI_FORK */
2808 #ifdef CONFIG_READLINE
2809 cmd
= readline("> ");
2812 while (next_history())
2814 h
= previous_history();
2815 if (h
== NULL
|| os_strcmp(cmd
, h
->line
) != 0)
2819 #else /* CONFIG_READLINE */
2821 cmd
= fgets(cmdbuf
, sizeof(cmdbuf
), stdin
);
2822 #endif /* CONFIG_READLINE */
2823 #ifndef CONFIG_NATIVE_WINDOWS
2825 #endif /* CONFIG_NATIVE_WINDOWS */
2828 wpa_cli_recv_pending(mon_conn
, 0, 0);
2830 while (*pos
!= '\0') {
2846 if (argc
== max_args
)
2849 char *pos2
= os_strrchr(pos
, '"');
2853 while (*pos
!= '\0' && *pos
!= ' ')
2859 wpa_request(ctrl_conn
, argc
, argv
);
2863 #ifdef CONFIG_WPA_CLI_FORK
2865 kill(mon_pid
, SIGUSR2
);
2866 #endif /* CONFIG_WPA_CLI_FORK */
2867 } while (!wpa_cli_quit
);
2869 #ifdef CONFIG_READLINE
2871 /* Save command history, excluding lines that may contain
2875 while ((h
= current_history())) {
2877 while (*p
== ' ' || *p
== '\t')
2879 if (cmd_has_sensitive_data(p
)) {
2880 h
= remove_history(where_history());
2890 write_history(hfile
);
2893 #endif /* CONFIG_READLINE */
2897 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
2899 #ifdef CONFIG_ANSI_C_EXTRA
2900 /* TODO: ANSI C version(?) */
2901 printf("Action processing not supported in ANSI C build.\n");
2902 #else /* CONFIG_ANSI_C_EXTRA */
2906 char buf
[256]; /* note: large enough to fit in unsolicited messages */
2909 fd
= wpa_ctrl_get_fd(ctrl
);
2911 while (!wpa_cli_quit
) {
2914 tv
.tv_sec
= ping_interval
;
2916 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
2917 if (res
< 0 && errno
!= EINTR
) {
2922 if (FD_ISSET(fd
, &rfds
))
2923 wpa_cli_recv_pending(ctrl
, 0, 1);
2925 /* verify that connection is still working */
2926 len
= sizeof(buf
) - 1;
2927 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
2928 wpa_cli_action_cb
) < 0 ||
2929 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
2930 printf("wpa_supplicant did not reply to PING "
2931 "command - exiting\n");
2936 #endif /* CONFIG_ANSI_C_EXTRA */
2940 static void wpa_cli_cleanup(void)
2942 wpa_cli_close_connection();
2944 os_daemonize_terminate(pid_file
);
2946 os_program_deinit();
2949 static void wpa_cli_terminate(int sig
)
2956 #ifdef CONFIG_WPA_CLI_FORK
2957 static void wpa_cli_usr1(int sig
)
2961 #endif /* CONFIG_WPA_CLI_FORK */
2964 #ifndef CONFIG_NATIVE_WINDOWS
2965 static void wpa_cli_alarm(int sig
)
2967 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
2968 printf("Connection to wpa_supplicant lost - trying to "
2970 wpa_cli_close_connection();
2973 wpa_cli_reconnect();
2975 wpa_cli_recv_pending(mon_conn
, 1, 0);
2976 alarm(ping_interval
);
2978 #endif /* CONFIG_NATIVE_WINDOWS */
2981 static char * wpa_cli_get_default_ifname(void)
2983 char *ifname
= NULL
;
2985 #ifdef CONFIG_CTRL_IFACE_UNIX
2986 struct dirent
*dent
;
2987 DIR *dir
= opendir(ctrl_iface_dir
);
2990 while ((dent
= readdir(dir
))) {
2991 #ifdef _DIRENT_HAVE_D_TYPE
2993 * Skip the file if it is not a socket. Also accept
2994 * DT_UNKNOWN (0) in case the C library or underlying
2995 * file system does not support d_type.
2997 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
2999 #endif /* _DIRENT_HAVE_D_TYPE */
3000 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3001 os_strcmp(dent
->d_name
, "..") == 0)
3003 printf("Selected interface '%s'\n", dent
->d_name
);
3004 ifname
= os_strdup(dent
->d_name
);
3008 #endif /* CONFIG_CTRL_IFACE_UNIX */
3010 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3011 char buf
[2048], *pos
;
3013 struct wpa_ctrl
*ctrl
;
3016 ctrl
= wpa_ctrl_open(NULL
);
3020 len
= sizeof(buf
) - 1;
3021 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3024 pos
= os_strchr(buf
, '\n');
3027 ifname
= os_strdup(buf
);
3029 wpa_ctrl_close(ctrl
);
3030 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3036 int main(int argc
, char *argv
[])
3038 int warning_displayed
= 0;
3042 const char *global
= NULL
;
3044 if (os_program_init())
3048 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3053 action_file
= optarg
;
3062 ping_interval
= atoi(optarg
);
3068 printf("%s\n", wpa_cli_version
);
3071 os_free(ctrl_ifname
);
3072 ctrl_ifname
= os_strdup(optarg
);
3075 ctrl_iface_dir
= optarg
;
3086 interactive
= (argc
== optind
) && (action_file
== NULL
);
3089 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3092 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3093 ctrl_conn
= wpa_ctrl_open(NULL
);
3094 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3095 ctrl_conn
= wpa_ctrl_open(global
);
3096 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3097 if (ctrl_conn
== NULL
) {
3098 perror("Failed to connect to wpa_supplicant - "
3105 signal(SIGINT
, wpa_cli_terminate
);
3106 signal(SIGTERM
, wpa_cli_terminate
);
3107 #endif /* _WIN32_WCE */
3108 #ifndef CONFIG_NATIVE_WINDOWS
3109 signal(SIGALRM
, wpa_cli_alarm
);
3110 #endif /* CONFIG_NATIVE_WINDOWS */
3111 #ifdef CONFIG_WPA_CLI_FORK
3112 signal(SIGUSR1
, wpa_cli_usr1
);
3113 #endif /* CONFIG_WPA_CLI_FORK */
3115 if (ctrl_ifname
== NULL
)
3116 ctrl_ifname
= wpa_cli_get_default_ifname();
3120 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3121 if (warning_displayed
)
3122 printf("Connection established.\n");
3126 if (!warning_displayed
) {
3127 printf("Could not connect to wpa_supplicant - "
3129 warning_displayed
= 1;
3136 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3137 perror("Failed to connect to wpa_supplicant - "
3143 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3144 wpa_cli_attached
= 1;
3146 printf("Warning: Failed to attach to "
3147 "wpa_supplicant.\n");
3153 if (daemonize
&& os_daemonize(pid_file
))
3157 wpa_cli_interactive();
3158 else if (action_file
)
3159 wpa_cli_action(ctrl_conn
);
3161 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
3163 os_free(ctrl_ifname
);
3169 #else /* CONFIG_CTRL_IFACE */
3170 int main(int argc
, char *argv
[])
3172 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3175 #endif /* CONFIG_CTRL_IFACE */