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_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
471 printf("Invalid GET command: need one argument (variable "
476 res
= os_snprintf(cmd
, sizeof(cmd
), "GET %s", argv
[0]);
477 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
478 printf("Too long GET command.\n");
481 return wpa_ctrl_command(ctrl
, cmd
);
485 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
487 return wpa_ctrl_command(ctrl
, "LOGOFF");
491 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
493 return wpa_ctrl_command(ctrl
, "LOGON");
497 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
500 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
504 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
511 printf("Invalid PREAUTH command: needs one argument "
516 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
517 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
518 printf("Too long PREAUTH command.\n");
521 return wpa_ctrl_command(ctrl
, cmd
);
525 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
531 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
535 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
536 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
537 printf("Too long AP_SCAN command.\n");
540 return wpa_ctrl_command(ctrl
, cmd
);
544 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
551 printf("Invalid STKSTART command: needs one argument "
552 "(Peer STA MAC address)\n");
556 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
557 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
558 printf("Too long STKSTART command.\n");
561 return wpa_ctrl_command(ctrl
, cmd
);
565 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
571 printf("Invalid FT_DS command: needs one argument "
572 "(Target AP MAC address)\n");
576 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
577 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
578 printf("Too long FT_DS command.\n");
581 return wpa_ctrl_command(ctrl
, cmd
);
585 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
592 return wpa_ctrl_command(ctrl
, "WPS_PBC");
596 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
597 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
598 printf("Too long WPS_PBC command.\n");
601 return wpa_ctrl_command(ctrl
, cmd
);
605 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
611 printf("Invalid WPS_PIN command: need one or two arguments:\n"
612 "- BSSID: use 'any' to select any\n"
613 "- PIN: optional, used only with devices that have no "
619 /* Use dynamically generated PIN (returned as reply) */
620 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
621 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
622 printf("Too long WPS_PIN command.\n");
625 return wpa_ctrl_command(ctrl
, cmd
);
628 /* Use hardcoded PIN from a label */
629 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
630 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
631 printf("Too long WPS_PIN command.\n");
634 return wpa_ctrl_command(ctrl
, cmd
);
638 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
644 if (argc
!= 1 && argc
!= 2) {
645 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
646 "- PIN to be verified\n");
651 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
654 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
656 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
657 printf("Too long WPS_CHECK_PIN command.\n");
660 return wpa_ctrl_command(ctrl
, cmd
);
664 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
667 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
671 #ifdef CONFIG_WPS_OOB
672 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
677 if (argc
!= 3 && argc
!= 4) {
678 printf("Invalid WPS_OOB command: need three or four "
680 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
681 "- PATH: path of OOB device like '/mnt'\n"
682 "- METHOD: OOB method 'pin-e' or 'pin-r', "
684 "- DEV_NAME: (only for NFC) device name like "
690 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
691 argv
[0], argv
[1], argv
[2]);
693 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
694 argv
[0], argv
[1], argv
[2], argv
[3]);
695 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
696 printf("Too long WPS_OOB command.\n");
699 return wpa_ctrl_command(ctrl
, cmd
);
701 #endif /* CONFIG_WPS_OOB */
704 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
710 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
712 else if (argc
== 5 || argc
== 6) {
713 char ssid_hex
[2 * 32 + 1];
714 char key_hex
[2 * 64 + 1];
718 for (i
= 0; i
< 32; i
++) {
719 if (argv
[2][i
] == '\0')
721 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
726 for (i
= 0; i
< 64; i
++) {
727 if (argv
[5][i
] == '\0')
729 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
734 res
= os_snprintf(cmd
, sizeof(cmd
),
735 "WPS_REG %s %s %s %s %s %s",
736 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
739 printf("Invalid WPS_REG command: need two arguments:\n"
740 "- BSSID of the target AP\n"
742 printf("Alternatively, six arguments can be used to "
743 "reconfigure the AP:\n"
744 "- BSSID of the target AP\n"
747 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
748 "- new encr (NONE, WEP, TKIP, CCMP)\n"
753 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
754 printf("Too long WPS_REG command.\n");
757 return wpa_ctrl_command(ctrl
, cmd
);
761 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
766 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
767 return wpa_ctrl_command(ctrl
, cmd
);
769 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
773 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
776 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
781 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
788 printf("Invalid WPS_ER_PIN command: need at least two "
790 "- UUID: use 'any' to select any\n"
791 "- PIN: Enrollee PIN\n"
792 "optional: - Enrollee MAC address\n");
797 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
798 argv
[0], argv
[1], argv
[2]);
800 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
802 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
803 printf("Too long WPS_ER_PIN command.\n");
806 return wpa_ctrl_command(ctrl
, cmd
);
810 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
817 printf("Invalid WPS_ER_PBC command: need one argument:\n"
818 "- UUID: Specify the Enrollee\n");
822 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
824 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
825 printf("Too long WPS_ER_PBC command.\n");
828 return wpa_ctrl_command(ctrl
, cmd
);
832 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
839 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
840 "- UUID: specify which AP to use\n"
845 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
847 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
848 printf("Too long WPS_ER_LEARN command.\n");
851 return wpa_ctrl_command(ctrl
, cmd
);
855 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
862 printf("Invalid WPS_ER_SET_CONFIG command: need two "
864 "- UUID: specify which AP to use\n"
865 "- Network configuration id\n");
869 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_SET_CONFIG %s %s",
871 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
872 printf("Too long WPS_ER_SET_CONFIG command.\n");
875 return wpa_ctrl_command(ctrl
, cmd
);
879 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
885 if (argc
== 5 || argc
== 6) {
886 char ssid_hex
[2 * 32 + 1];
887 char key_hex
[2 * 64 + 1];
891 for (i
= 0; i
< 32; i
++) {
892 if (argv
[2][i
] == '\0')
894 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
899 for (i
= 0; i
< 64; i
++) {
900 if (argv
[5][i
] == '\0')
902 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
907 res
= os_snprintf(cmd
, sizeof(cmd
),
908 "WPS_ER_CONFIG %s %s %s %s %s %s",
909 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
912 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
916 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
917 "- new encr (NONE, WEP, TKIP, CCMP)\n"
922 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
923 printf("Too long WPS_ER_CONFIG command.\n");
926 return wpa_ctrl_command(ctrl
, cmd
);
930 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
936 printf("Invalid IBSS_RSN command: needs one argument "
937 "(Peer STA MAC address)\n");
941 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
942 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
943 printf("Too long IBSS_RSN command.\n");
946 return wpa_ctrl_command(ctrl
, cmd
);
950 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
956 printf("Invalid LEVEL command: needs one argument (debug "
960 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
961 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
962 printf("Too long LEVEL command.\n");
965 return wpa_ctrl_command(ctrl
, cmd
);
969 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
971 char cmd
[256], *pos
, *end
;
975 printf("Invalid IDENTITY command: needs two arguments "
976 "(network id and identity)\n");
980 end
= cmd
+ sizeof(cmd
);
982 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
984 if (ret
< 0 || ret
>= end
- pos
) {
985 printf("Too long IDENTITY command.\n");
989 for (i
= 2; i
< argc
; i
++) {
990 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
991 if (ret
< 0 || ret
>= end
- pos
) {
992 printf("Too long IDENTITY command.\n");
998 return wpa_ctrl_command(ctrl
, cmd
);
1002 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1004 char cmd
[256], *pos
, *end
;
1008 printf("Invalid PASSWORD command: needs two arguments "
1009 "(network id and password)\n");
1013 end
= cmd
+ sizeof(cmd
);
1015 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1017 if (ret
< 0 || ret
>= end
- pos
) {
1018 printf("Too long PASSWORD command.\n");
1022 for (i
= 2; i
< argc
; i
++) {
1023 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1024 if (ret
< 0 || ret
>= end
- pos
) {
1025 printf("Too long PASSWORD command.\n");
1031 return wpa_ctrl_command(ctrl
, cmd
);
1035 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1038 char cmd
[256], *pos
, *end
;
1042 printf("Invalid NEW_PASSWORD command: needs two arguments "
1043 "(network id and password)\n");
1047 end
= cmd
+ sizeof(cmd
);
1049 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1051 if (ret
< 0 || ret
>= end
- pos
) {
1052 printf("Too long NEW_PASSWORD command.\n");
1056 for (i
= 2; i
< argc
; i
++) {
1057 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1058 if (ret
< 0 || ret
>= end
- pos
) {
1059 printf("Too long NEW_PASSWORD command.\n");
1065 return wpa_ctrl_command(ctrl
, cmd
);
1069 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1071 char cmd
[256], *pos
, *end
;
1075 printf("Invalid PIN command: needs two arguments "
1076 "(network id and pin)\n");
1080 end
= cmd
+ sizeof(cmd
);
1082 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1084 if (ret
< 0 || ret
>= end
- pos
) {
1085 printf("Too long PIN command.\n");
1089 for (i
= 2; i
< argc
; i
++) {
1090 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1091 if (ret
< 0 || ret
>= end
- pos
) {
1092 printf("Too long PIN command.\n");
1097 return wpa_ctrl_command(ctrl
, cmd
);
1101 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1103 char cmd
[256], *pos
, *end
;
1107 printf("Invalid OTP command: needs two arguments (network "
1108 "id and password)\n");
1112 end
= cmd
+ sizeof(cmd
);
1114 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1116 if (ret
< 0 || ret
>= end
- pos
) {
1117 printf("Too long OTP command.\n");
1121 for (i
= 2; i
< argc
; i
++) {
1122 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1123 if (ret
< 0 || ret
>= end
- pos
) {
1124 printf("Too long OTP command.\n");
1130 return wpa_ctrl_command(ctrl
, cmd
);
1134 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1137 char cmd
[256], *pos
, *end
;
1141 printf("Invalid PASSPHRASE command: needs two arguments "
1142 "(network id and passphrase)\n");
1146 end
= cmd
+ sizeof(cmd
);
1148 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1150 if (ret
< 0 || ret
>= end
- pos
) {
1151 printf("Too long PASSPHRASE command.\n");
1155 for (i
= 2; i
< argc
; i
++) {
1156 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1157 if (ret
< 0 || ret
>= end
- pos
) {
1158 printf("Too long PASSPHRASE command.\n");
1164 return wpa_ctrl_command(ctrl
, cmd
);
1168 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1170 char cmd
[256], *pos
, *end
;
1174 printf("Invalid BSSID command: needs two arguments (network "
1179 end
= cmd
+ sizeof(cmd
);
1181 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1182 if (ret
< 0 || ret
>= end
- pos
) {
1183 printf("Too long BSSID command.\n");
1187 for (i
= 0; i
< argc
; i
++) {
1188 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1189 if (ret
< 0 || ret
>= end
- pos
) {
1190 printf("Too long BSSID command.\n");
1196 return wpa_ctrl_command(ctrl
, cmd
);
1200 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1203 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1207 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1214 printf("Invalid SELECT_NETWORK command: needs one argument "
1219 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1220 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1222 cmd
[sizeof(cmd
) - 1] = '\0';
1224 return wpa_ctrl_command(ctrl
, cmd
);
1228 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1235 printf("Invalid ENABLE_NETWORK command: needs one argument "
1240 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1241 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1243 cmd
[sizeof(cmd
) - 1] = '\0';
1245 return wpa_ctrl_command(ctrl
, cmd
);
1249 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1256 printf("Invalid DISABLE_NETWORK command: needs one argument "
1261 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1262 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1264 cmd
[sizeof(cmd
) - 1] = '\0';
1266 return wpa_ctrl_command(ctrl
, cmd
);
1270 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1273 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1277 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1284 printf("Invalid REMOVE_NETWORK command: needs one argument "
1289 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1290 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1292 cmd
[sizeof(cmd
) - 1] = '\0';
1294 return wpa_ctrl_command(ctrl
, cmd
);
1298 static void wpa_cli_show_network_variables(void)
1300 printf("set_network variables:\n"
1301 " ssid (network name, SSID)\n"
1302 " psk (WPA passphrase or pre-shared key)\n"
1303 " key_mgmt (key management protocol)\n"
1304 " identity (EAP identity)\n"
1305 " password (EAP password)\n"
1308 "Note: Values are entered in the same format as the "
1309 "configuration file is using,\n"
1310 "i.e., strings values need to be inside double quotation "
1312 "For example: set_network 1 ssid \"network name\"\n"
1314 "Please see wpa_supplicant.conf documentation for full list "
1315 "of\navailable variables.\n");
1319 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1326 wpa_cli_show_network_variables();
1331 printf("Invalid SET_NETWORK command: needs three arguments\n"
1332 "(network id, variable name, and value)\n");
1336 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1337 argv
[0], argv
[1], argv
[2]);
1338 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1339 printf("Too long SET_NETWORK command.\n");
1342 return wpa_ctrl_command(ctrl
, cmd
);
1346 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1353 wpa_cli_show_network_variables();
1358 printf("Invalid GET_NETWORK command: needs two arguments\n"
1359 "(network id and variable name)\n");
1363 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1365 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1366 printf("Too long GET_NETWORK command.\n");
1369 return wpa_ctrl_command(ctrl
, cmd
);
1373 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1376 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1380 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1383 return wpa_ctrl_command(ctrl
, "RECONNECT");
1387 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1390 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1394 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1396 return wpa_ctrl_command(ctrl
, "SCAN");
1400 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1403 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1407 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1413 printf("Invalid BSS command: need one argument (index or "
1418 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1419 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1421 cmd
[sizeof(cmd
) - 1] = '\0';
1423 return wpa_ctrl_command(ctrl
, cmd
);
1427 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1433 if (argc
< 1 || argc
> 2) {
1434 printf("Invalid GET_CAPABILITY command: need either one or "
1439 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1440 printf("Invalid GET_CAPABILITY command: second argument, "
1441 "if any, must be 'strict'\n");
1445 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1446 (argc
== 2) ? " strict" : "");
1447 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1449 cmd
[sizeof(cmd
) - 1] = '\0';
1451 return wpa_ctrl_command(ctrl
, cmd
);
1455 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1457 printf("Available interfaces:\n");
1458 return wpa_ctrl_command(ctrl
, "INTERFACES");
1462 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1465 wpa_cli_list_interfaces(ctrl
);
1469 wpa_cli_close_connection();
1470 os_free(ctrl_ifname
);
1471 ctrl_ifname
= os_strdup(argv
[0]);
1473 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1474 printf("Connected to interface '%s.\n", ctrl_ifname
);
1476 printf("Could not connect to interface '%s' - re-trying\n",
1483 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1486 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1490 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1493 return wpa_ctrl_command(ctrl
, "TERMINATE");
1497 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1504 printf("Invalid INTERFACE_ADD command: needs at least one "
1505 "argument (interface name)\n"
1506 "All arguments: ifname confname driver ctrl_interface "
1507 "driver_param bridge_name\n");
1512 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1513 * <driver_param>TAB<bridge_name>
1515 res
= os_snprintf(cmd
, sizeof(cmd
),
1516 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1518 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1519 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1520 argc
> 5 ? argv
[5] : "");
1521 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1523 cmd
[sizeof(cmd
) - 1] = '\0';
1524 return wpa_ctrl_command(ctrl
, cmd
);
1528 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1535 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1536 "(interface name)\n");
1540 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1541 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1543 cmd
[sizeof(cmd
) - 1] = '\0';
1544 return wpa_ctrl_command(ctrl
, cmd
);
1548 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1551 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1556 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1560 printf("Invalid 'sta' command - exactly one argument, STA "
1561 "address, is required.\n");
1564 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1565 return wpa_ctrl_command(ctrl
, buf
);
1569 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1570 char *addr
, size_t addr_len
)
1572 char buf
[4096], *pos
;
1576 if (ctrl_conn
== NULL
) {
1577 printf("Not connected to hostapd - command dropped.\n");
1580 len
= sizeof(buf
) - 1;
1581 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1584 printf("'%s' command timed out.\n", cmd
);
1586 } else if (ret
< 0) {
1587 printf("'%s' command failed.\n", cmd
);
1592 if (memcmp(buf
, "FAIL", 4) == 0)
1597 while (*pos
!= '\0' && *pos
!= '\n')
1600 os_strlcpy(addr
, buf
, addr_len
);
1605 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1607 char addr
[32], cmd
[64];
1609 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1612 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1613 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1617 #endif /* CONFIG_AP */
1620 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1622 return wpa_ctrl_command(ctrl
, "SUSPEND");
1626 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1628 return wpa_ctrl_command(ctrl
, "RESUME");
1632 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1634 return wpa_ctrl_command(ctrl
, "DROP_SA");
1638 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1644 printf("Invalid ROAM command: needs one argument "
1645 "(target AP's BSSID)\n");
1649 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
1650 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1651 printf("Too long ROAM command.\n");
1654 return wpa_ctrl_command(ctrl
, cmd
);
1660 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1666 return wpa_ctrl_command(ctrl
, "P2P_FIND");
1669 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
1672 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
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_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1683 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1687 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1694 printf("Invalid P2P_CONNECT command: needs at least two "
1695 "arguments (address and pbc/PIN)\n");
1700 res
= os_snprintf(cmd
, sizeof(cmd
),
1701 "P2P_CONNECT %s %s %s %s %s",
1702 argv
[0], argv
[1], argv
[2], argv
[3],
1705 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
1706 argv
[0], argv
[1], argv
[2], argv
[3]);
1708 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
1709 argv
[0], argv
[1], argv
[2]);
1711 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
1713 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1715 cmd
[sizeof(cmd
) - 1] = '\0';
1716 return wpa_ctrl_command(ctrl
, cmd
);
1720 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1727 return wpa_ctrl_command(ctrl
, "P2P_LISTEN");
1729 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_LISTEN %s", argv
[0]);
1730 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1732 cmd
[sizeof(cmd
) - 1] = '\0';
1733 return wpa_ctrl_command(ctrl
, cmd
);
1737 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1744 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1745 "(interface name)\n");
1749 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
1750 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1752 cmd
[sizeof(cmd
) - 1] = '\0';
1753 return wpa_ctrl_command(ctrl
, cmd
);
1757 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1764 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
1766 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s", argv
[0]);
1767 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1769 cmd
[sizeof(cmd
) - 1] = '\0';
1770 return wpa_ctrl_command(ctrl
, cmd
);
1774 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1781 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1782 "(address and config method\n"
1783 "(display, keypad, or pbc)\n");
1787 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
1789 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1791 cmd
[sizeof(cmd
) - 1] = '\0';
1792 return wpa_ctrl_command(ctrl
, cmd
);
1796 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1799 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1803 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1809 if (argc
!= 2 && argc
!= 4) {
1810 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1811 "arguments (address and TLVs) or four arguments "
1812 "(address, \"upnp\", version, search target "
1818 res
= os_snprintf(cmd
, sizeof(cmd
),
1819 "P2P_SERV_DISC_REQ %s %s %s %s",
1820 argv
[0], argv
[1], argv
[2], argv
[3]);
1822 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
1824 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1826 cmd
[sizeof(cmd
) - 1] = '\0';
1827 return wpa_ctrl_command(ctrl
, cmd
);
1831 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1832 int argc
, char *argv
[])
1838 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1839 "argument (pending request identifier)\n");
1843 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
1845 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1847 cmd
[sizeof(cmd
) - 1] = '\0';
1848 return wpa_ctrl_command(ctrl
, cmd
);
1852 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1859 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1860 "arguments (freq, address, dialog token, and TLVs)\n");
1864 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1865 argv
[0], argv
[1], argv
[2], argv
[3]);
1866 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1868 cmd
[sizeof(cmd
) - 1] = '\0';
1869 return wpa_ctrl_command(ctrl
, cmd
);
1873 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1876 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1880 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1881 int argc
, char *argv
[])
1887 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1888 "argument (external processing: 0/1)\n");
1892 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
1894 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1896 cmd
[sizeof(cmd
) - 1] = '\0';
1897 return wpa_ctrl_command(ctrl
, cmd
);
1901 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1904 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1908 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1914 if (argc
!= 3 && argc
!= 4) {
1915 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1921 res
= os_snprintf(cmd
, sizeof(cmd
),
1922 "P2P_SERVICE_ADD %s %s %s %s",
1923 argv
[0], argv
[1], argv
[2], argv
[3]);
1925 res
= os_snprintf(cmd
, sizeof(cmd
),
1926 "P2P_SERVICE_ADD %s %s %s",
1927 argv
[0], argv
[1], argv
[2]);
1928 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1930 cmd
[sizeof(cmd
) - 1] = '\0';
1931 return wpa_ctrl_command(ctrl
, cmd
);
1935 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1941 if (argc
!= 2 && argc
!= 3) {
1942 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1948 res
= os_snprintf(cmd
, sizeof(cmd
),
1949 "P2P_SERVICE_DEL %s %s %s",
1950 argv
[0], argv
[1], argv
[2]);
1952 res
= os_snprintf(cmd
, sizeof(cmd
),
1953 "P2P_SERVICE_DEL %s %s",
1955 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1957 cmd
[sizeof(cmd
) - 1] = '\0';
1958 return wpa_ctrl_command(ctrl
, cmd
);
1962 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1963 int argc
, char *argv
[])
1969 printf("Invalid P2P_REJECT command: needs one argument "
1970 "(peer address)\n");
1974 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
1975 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1977 cmd
[sizeof(cmd
) - 1] = '\0';
1978 return wpa_ctrl_command(ctrl
, cmd
);
1982 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
1983 int argc
, char *argv
[])
1989 printf("Invalid P2P_INVITE command: needs at least one "
1995 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
1996 argv
[0], argv
[1], argv
[2]);
1998 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
2001 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
2002 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2004 cmd
[sizeof(cmd
) - 1] = '\0';
2005 return wpa_ctrl_command(ctrl
, cmd
);
2009 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2013 printf("Invalid 'p2p_peer' command - exactly one argument, "
2014 "P2P peer device address, is required.\n");
2017 os_snprintf(buf
, sizeof(buf
), "P2P_PEER %s", argv
[0]);
2018 return wpa_ctrl_command(ctrl
, buf
);
2022 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
2023 char *addr
, size_t addr_len
,
2026 char buf
[4096], *pos
;
2030 if (ctrl_conn
== NULL
)
2032 len
= sizeof(buf
) - 1;
2033 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
2036 printf("'%s' command timed out.\n", cmd
);
2038 } else if (ret
< 0) {
2039 printf("'%s' command failed.\n", cmd
);
2044 if (memcmp(buf
, "FAIL", 4) == 0)
2048 while (*pos
!= '\0' && *pos
!= '\n')
2051 os_strlcpy(addr
, buf
, addr_len
);
2052 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2053 printf("%s\n", addr
);
2058 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2060 char addr
[32], cmd
[64];
2063 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2065 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2066 addr
, sizeof(addr
), discovered
))
2069 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2070 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2077 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2083 printf("Invalid P2P_SET command: needs two arguments (field, "
2088 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
2089 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2091 cmd
[sizeof(cmd
) - 1] = '\0';
2092 return wpa_ctrl_command(ctrl
, cmd
);
2096 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2098 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2102 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2105 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2109 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2115 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2116 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2117 "(preferred duration, interval; in microsecods).\n"
2118 "Optional second pair can be used to provide "
2119 "acceptable values.\n");
2124 res
= os_snprintf(cmd
, sizeof(cmd
),
2125 "P2P_PRESENCE_REQ %s %s %s %s",
2126 argv
[0], argv
[1], argv
[2], argv
[3]);
2128 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2131 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
2132 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2134 cmd
[sizeof(cmd
) - 1] = '\0';
2135 return wpa_ctrl_command(ctrl
, cmd
);
2139 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2145 if (argc
!= 0 && argc
!= 2) {
2146 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2147 "(availability period, availability interval; in "
2149 "Extended Listen Timing can be cancelled with this "
2150 "command when used without parameters.\n");
2155 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2158 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2159 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2161 cmd
[sizeof(cmd
) - 1] = '\0';
2162 return wpa_ctrl_command(ctrl
, cmd
);
2165 #endif /* CONFIG_P2P */
2168 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2175 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2176 "(0/1 = disable/enable automatic reconnection)\n");
2179 res
= os_snprintf(cmd
, sizeof(cmd
), "STA_AUTOCONNECT %s", argv
[0]);
2180 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2181 printf("Too long STA_AUTOCONNECT command.\n");
2184 return wpa_ctrl_command(ctrl
, cmd
);
2188 enum wpa_cli_cmd_flags
{
2189 cli_cmd_flag_none
= 0x00,
2190 cli_cmd_flag_sensitive
= 0x01
2193 struct wpa_cli_cmd
{
2195 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2196 enum wpa_cli_cmd_flags flags
;
2200 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2201 { "status", wpa_cli_cmd_status
,
2203 "[verbose] = get current WPA/EAPOL/EAP status" },
2204 { "ping", wpa_cli_cmd_ping
,
2206 "= pings wpa_supplicant" },
2207 { "note", wpa_cli_cmd_note
,
2209 "<text> = add a note to wpa_supplicant debug log" },
2210 { "mib", wpa_cli_cmd_mib
,
2212 "= get MIB variables (dot1x, dot11)" },
2213 { "help", wpa_cli_cmd_help
,
2215 "= show this usage help" },
2216 { "interface", wpa_cli_cmd_interface
,
2218 "[ifname] = show interfaces/select interface" },
2219 { "level", wpa_cli_cmd_level
,
2221 "<debug level> = change debug level" },
2222 { "license", wpa_cli_cmd_license
,
2224 "= show full wpa_cli license" },
2225 { "quit", wpa_cli_cmd_quit
,
2228 { "set", wpa_cli_cmd_set
,
2230 "= set variables (shows list of variables when run without "
2232 { "get", wpa_cli_cmd_get
,
2234 "<name> = get information" },
2235 { "logon", wpa_cli_cmd_logon
,
2237 "= IEEE 802.1X EAPOL state machine logon" },
2238 { "logoff", wpa_cli_cmd_logoff
,
2240 "= IEEE 802.1X EAPOL state machine logoff" },
2241 { "pmksa", wpa_cli_cmd_pmksa
,
2243 "= show PMKSA cache" },
2244 { "reassociate", wpa_cli_cmd_reassociate
,
2246 "= force reassociation" },
2247 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2249 "<BSSID> = force preauthentication" },
2250 { "identity", wpa_cli_cmd_identity
,
2252 "<network id> <identity> = configure identity for an SSID" },
2253 { "password", wpa_cli_cmd_password
,
2254 cli_cmd_flag_sensitive
,
2255 "<network id> <password> = configure password for an SSID" },
2256 { "new_password", wpa_cli_cmd_new_password
,
2257 cli_cmd_flag_sensitive
,
2258 "<network id> <password> = change password for an SSID" },
2259 { "pin", wpa_cli_cmd_pin
,
2260 cli_cmd_flag_sensitive
,
2261 "<network id> <pin> = configure pin for an SSID" },
2262 { "otp", wpa_cli_cmd_otp
,
2263 cli_cmd_flag_sensitive
,
2264 "<network id> <password> = configure one-time-password for an SSID"
2266 { "passphrase", wpa_cli_cmd_passphrase
,
2267 cli_cmd_flag_sensitive
,
2268 "<network id> <passphrase> = configure private key passphrase\n"
2270 { "bssid", wpa_cli_cmd_bssid
,
2272 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2273 { "list_networks", wpa_cli_cmd_list_networks
,
2275 "= list configured networks" },
2276 { "select_network", wpa_cli_cmd_select_network
,
2278 "<network id> = select a network (disable others)" },
2279 { "enable_network", wpa_cli_cmd_enable_network
,
2281 "<network id> = enable a network" },
2282 { "disable_network", wpa_cli_cmd_disable_network
,
2284 "<network id> = disable a network" },
2285 { "add_network", wpa_cli_cmd_add_network
,
2287 "= add a network" },
2288 { "remove_network", wpa_cli_cmd_remove_network
,
2290 "<network id> = remove a network" },
2291 { "set_network", wpa_cli_cmd_set_network
,
2292 cli_cmd_flag_sensitive
,
2293 "<network id> <variable> <value> = set network variables (shows\n"
2294 " list of variables when run without arguments)" },
2295 { "get_network", wpa_cli_cmd_get_network
,
2297 "<network id> <variable> = get network variables" },
2298 { "save_config", wpa_cli_cmd_save_config
,
2300 "= save the current configuration" },
2301 { "disconnect", wpa_cli_cmd_disconnect
,
2303 "= disconnect and wait for reassociate/reconnect command before\n"
2305 { "reconnect", wpa_cli_cmd_reconnect
,
2307 "= like reassociate, but only takes effect if already disconnected"
2309 { "scan", wpa_cli_cmd_scan
,
2311 "= request new BSS scan" },
2312 { "scan_results", wpa_cli_cmd_scan_results
,
2314 "= get latest scan results" },
2315 { "bss", wpa_cli_cmd_bss
,
2317 "<<idx> | <bssid>> = get detailed scan result info" },
2318 { "get_capability", wpa_cli_cmd_get_capability
,
2320 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2321 { "reconfigure", wpa_cli_cmd_reconfigure
,
2323 "= force wpa_supplicant to re-read its configuration file" },
2324 { "terminate", wpa_cli_cmd_terminate
,
2326 "= terminate wpa_supplicant" },
2327 { "interface_add", wpa_cli_cmd_interface_add
,
2329 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2330 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2332 { "interface_remove", wpa_cli_cmd_interface_remove
,
2334 "<ifname> = removes the interface" },
2335 { "interface_list", wpa_cli_cmd_interface_list
,
2337 "= list available interfaces" },
2338 { "ap_scan", wpa_cli_cmd_ap_scan
,
2340 "<value> = set ap_scan parameter" },
2341 { "stkstart", wpa_cli_cmd_stkstart
,
2343 "<addr> = request STK negotiation with <addr>" },
2344 { "ft_ds", wpa_cli_cmd_ft_ds
,
2346 "<addr> = request over-the-DS FT with <addr>" },
2347 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
2349 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2350 { "wps_pin", wpa_cli_cmd_wps_pin
,
2351 cli_cmd_flag_sensitive
,
2352 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2354 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
2355 cli_cmd_flag_sensitive
,
2356 "<PIN> = verify PIN checksum" },
2357 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
2358 "Cancels the pending WPS operation" },
2359 #ifdef CONFIG_WPS_OOB
2360 { "wps_oob", wpa_cli_cmd_wps_oob
,
2361 cli_cmd_flag_sensitive
,
2362 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2363 #endif /* CONFIG_WPS_OOB */
2364 { "wps_reg", wpa_cli_cmd_wps_reg
,
2365 cli_cmd_flag_sensitive
,
2366 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2367 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
2369 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2370 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
2372 "= stop Wi-Fi Protected Setup External Registrar" },
2373 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
2374 cli_cmd_flag_sensitive
,
2375 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2376 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
2378 "<UUID> = accept an Enrollee PBC using External Registrar" },
2379 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
2380 cli_cmd_flag_sensitive
,
2381 "<UUID> <PIN> = learn AP configuration" },
2382 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
,
2384 "<UUID> <network id> = set AP configuration for enrolling" },
2385 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
2386 cli_cmd_flag_sensitive
,
2387 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2388 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
2390 "<addr> = request RSN authentication with <addr> in IBSS" },
2392 { "sta", wpa_cli_cmd_sta
,
2394 "<addr> = get information about an associated station (AP)" },
2395 { "all_sta", wpa_cli_cmd_all_sta
,
2397 "= get information about all associated stations (AP)" },
2398 #endif /* CONFIG_AP */
2399 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
2400 "= notification of suspend/hibernate" },
2401 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
2402 "= notification of resume/thaw" },
2403 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
2404 "= drop SA without deauth/disassoc (test command)" },
2405 { "roam", wpa_cli_cmd_roam
,
2407 "<addr> = roam to the specified BSS" },
2409 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
2410 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2411 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
2412 "= stop P2P Devices search" },
2413 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
2414 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2415 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
2416 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2417 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
2418 "<ifname> = remote P2P group interface (terminate group if GO)" },
2419 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
2420 "= add a new P2P group (local end as GO)" },
2421 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
2422 "<addr> <method> = request provisioning discovery" },
2423 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
2425 "= get the passphrase for a group (GO only)" },
2426 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2428 "<addr> <TLVs> = schedule service discovery request" },
2429 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2431 "<id> = cancel pending service discovery request" },
2432 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2434 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2435 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2437 "= indicate change in local services" },
2438 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2440 "<external> = set external processing of service discovery" },
2441 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2443 "= remove all stored service entries" },
2444 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2446 "<bonjour|upnp> <query|version> <response|service> = add a local "
2448 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2450 "<bonjour|upnp> <query|version> [|service] = remove a local "
2452 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2454 "<addr> = reject connection attempts from a specific peer" },
2455 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
2457 "<cmd> [peer=addr] = invite peer" },
2458 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
2459 "[discovered] = list known (optionally, only fully discovered) P2P "
2461 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
2462 "<address> = show information about known P2P peer" },
2463 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
2464 "<field> <value> = set a P2P parameter" },
2465 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
2466 "= flush P2P state" },
2467 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
2468 "= cancel P2P group formation" },
2469 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
2470 "[<duration> <interval>] [<duration> <interval>] = request GO "
2472 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
2473 "[<period> <interval>] = set extended listen timing" },
2474 #endif /* CONFIG_P2P */
2475 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
2476 "<0/1> = disable/enable automatic reconnection" },
2477 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2482 * Prints command usage, lines are padded with the specified string.
2484 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2489 printf("%s%s ", pad
, cmd
->cmd
);
2490 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2499 static void print_help(void)
2502 printf("commands:\n");
2503 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
2504 print_cmd_help(&wpa_cli_commands
[n
], " ");
2508 #ifdef CONFIG_READLINE
2509 static int cmd_has_sensitive_data(const char *cmd
)
2511 const char *c
, *delim
;
2515 delim
= os_strchr(cmd
, ' ');
2519 len
= os_strlen(cmd
);
2521 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2522 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2523 return (wpa_cli_commands
[n
].flags
&
2524 cli_cmd_flag_sensitive
);
2528 #endif /* CONFIG_READLINE */
2531 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2533 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2538 cmd
= wpa_cli_commands
;
2540 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2543 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2544 /* we have an exact match */
2554 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
2555 cmd
= wpa_cli_commands
;
2557 if (os_strncasecmp(cmd
->cmd
, argv
[0],
2558 os_strlen(argv
[0])) == 0) {
2559 printf(" %s", cmd
->cmd
);
2565 } else if (count
== 0) {
2566 printf("Unknown command '%s'\n", argv
[0]);
2569 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
2576 static int str_match(const char *a
, const char *b
)
2578 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
2582 static int wpa_cli_exec(const char *program
, const char *arg1
,
2590 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
2591 cmd
= os_malloc(len
);
2594 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
2595 if (res
< 0 || (size_t) res
>= len
) {
2599 cmd
[len
- 1] = '\0';
2601 if (system(cmd
) < 0)
2603 #endif /* _WIN32_WCE */
2610 static void wpa_cli_action_process(const char *msg
)
2613 char *copy
= NULL
, *id
, *pos2
;
2618 pos
= os_strchr(pos
, '>');
2625 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
2627 os_unsetenv("WPA_ID");
2628 os_unsetenv("WPA_ID_STR");
2629 os_unsetenv("WPA_CTRL_DIR");
2631 pos
= os_strstr(pos
, "[id=");
2633 copy
= os_strdup(pos
+ 4);
2637 while (*pos2
&& *pos2
!= ' ')
2641 os_setenv("WPA_ID", id
, 1);
2642 while (*pos2
&& *pos2
!= '=')
2647 while (*pos2
&& *pos2
!= ']')
2650 os_setenv("WPA_ID_STR", id
, 1);
2654 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
2656 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
2657 wpa_cli_connected
= 1;
2658 wpa_cli_last_id
= new_id
;
2659 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
2661 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
2662 if (wpa_cli_connected
) {
2663 wpa_cli_connected
= 0;
2664 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
2666 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
2667 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2668 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
2669 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2670 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
2671 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2672 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
2673 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2674 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
2675 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2676 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
2677 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2678 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
2679 printf("wpa_supplicant is terminating - stop monitoring\n");
2685 #ifndef CONFIG_ANSI_C_EXTRA
2686 static void wpa_cli_action_cb(char *msg
, size_t len
)
2688 wpa_cli_action_process(msg
);
2690 #endif /* CONFIG_ANSI_C_EXTRA */
2693 static void wpa_cli_reconnect(void)
2695 wpa_cli_close_connection();
2696 wpa_cli_open_connection(ctrl_ifname
, 1);
2700 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int in_read
,
2704 if (ctrl_conn
== NULL
) {
2705 wpa_cli_reconnect();
2708 while (wpa_ctrl_pending(ctrl
) > 0) {
2710 size_t len
= sizeof(buf
) - 1;
2711 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
2714 wpa_cli_action_process(buf
);
2716 if (wpa_cli_show_event(buf
)) {
2717 if (in_read
&& first
)
2720 printf("%s\n", buf
);
2725 printf("Could not read pending message.\n");
2730 if (wpa_ctrl_pending(ctrl
) < 0) {
2731 printf("Connection to wpa_supplicant lost - trying to "
2733 wpa_cli_reconnect();
2739 static int tokenize_cmd(char *cmd
, char *argv
[])
2752 if (argc
== max_args
)
2755 char *pos2
= os_strrchr(pos
, '"');
2759 while (*pos
!= '\0' && *pos
!= ' ')
2769 static void trunc_nl(char *str
)
2772 while (*pos
!= '\0') {
2782 #ifdef CONFIG_READLINE
2784 static char * wpa_cli_cmd_gen(const char *text
, int state
)
2791 len
= os_strlen(text
);
2794 while ((cmd
= wpa_cli_commands
[i
].cmd
)) {
2796 if (os_strncasecmp(cmd
, text
, len
) == 0)
2804 static char * wpa_cli_dummy_gen(const char *text
, int state
)
2808 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2809 const char *cmd
= wpa_cli_commands
[i
].cmd
;
2810 size_t len
= os_strlen(cmd
);
2811 if (os_strncasecmp(rl_line_buffer
, cmd
, len
) == 0 &&
2812 rl_line_buffer
[len
] == ' ') {
2813 printf("\n%s\n", wpa_cli_commands
[i
].usage
);
2819 rl_attempted_completion_over
= 1;
2824 static char * wpa_cli_status_gen(const char *text
, int state
)
2834 len
= os_strlen(text
);
2837 while ((t
= options
[i
])) {
2839 if (os_strncasecmp(t
, text
, len
) == 0)
2843 rl_attempted_completion_over
= 1;
2848 static char ** wpa_cli_completion(const char *text
, int start
, int end
)
2850 char * (*func
)(const char *text
, int state
);
2853 func
= wpa_cli_cmd_gen
;
2854 else if (os_strncasecmp(rl_line_buffer
, "status ", 7) == 0)
2855 func
= wpa_cli_status_gen
;
2857 func
= wpa_cli_dummy_gen
;
2858 return rl_completion_matches(text
, func
);
2862 static void wpa_cli_interactive(void)
2864 char cmdbuf
[256], *cmd
, *argv
[max_args
];
2866 char *home
, *hfile
= NULL
;
2868 printf("\nInteractive mode\n\n");
2870 rl_attempted_completion_function
= wpa_cli_completion
;
2871 home
= getenv("HOME");
2873 const char *fname
= ".wpa_cli_history";
2874 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
2875 hfile
= os_malloc(hfile_len
);
2878 res
= os_snprintf(hfile
, hfile_len
, "%s/%s", home
,
2880 if (res
>= 0 && res
< hfile_len
) {
2881 hfile
[hfile_len
- 1] = '\0';
2882 read_history(hfile
);
2883 stifle_history(100);
2889 wpa_cli_recv_pending(mon_conn
, 0, 0);
2890 #ifndef CONFIG_NATIVE_WINDOWS
2891 alarm(ping_interval
);
2892 #endif /* CONFIG_NATIVE_WINDOWS */
2893 #ifdef CONFIG_WPA_CLI_FORK
2895 kill(mon_pid
, SIGUSR1
);
2896 #endif /* CONFIG_WPA_CLI_FORK */
2897 cmd
= readline("> ");
2900 while (next_history())
2902 h
= previous_history();
2903 if (h
== NULL
|| os_strcmp(cmd
, h
->line
) != 0)
2907 #ifndef CONFIG_NATIVE_WINDOWS
2909 #endif /* CONFIG_NATIVE_WINDOWS */
2912 wpa_cli_recv_pending(mon_conn
, 0, 0);
2914 argc
= tokenize_cmd(cmd
, argv
);
2916 wpa_request(ctrl_conn
, argc
, argv
);
2920 #ifdef CONFIG_WPA_CLI_FORK
2922 kill(mon_pid
, SIGUSR2
);
2923 #endif /* CONFIG_WPA_CLI_FORK */
2924 } while (!wpa_cli_quit
);
2927 /* Save command history, excluding lines that may contain
2931 while ((h
= current_history())) {
2933 while (*p
== ' ' || *p
== '\t')
2935 if (cmd_has_sensitive_data(p
)) {
2936 h
= remove_history(where_history());
2946 write_history(hfile
);
2951 #else /* CONFIG_READLINE */
2953 static void wpa_cli_interactive(void)
2955 char cmdbuf
[256], *cmd
, *argv
[max_args
];
2958 printf("\nInteractive mode\n\n");
2961 wpa_cli_recv_pending(mon_conn
, 0, 0);
2962 #ifndef CONFIG_NATIVE_WINDOWS
2963 alarm(ping_interval
);
2964 #endif /* CONFIG_NATIVE_WINDOWS */
2965 #ifdef CONFIG_WPA_CLI_FORK
2967 kill(mon_pid
, SIGUSR1
);
2968 #endif /* CONFIG_WPA_CLI_FORK */
2970 cmd
= fgets(cmdbuf
, sizeof(cmdbuf
), stdin
);
2971 #ifndef CONFIG_NATIVE_WINDOWS
2973 #endif /* CONFIG_NATIVE_WINDOWS */
2976 wpa_cli_recv_pending(mon_conn
, 0, 0);
2978 argc
= tokenize_cmd(cmd
, argv
);
2980 wpa_request(ctrl_conn
, argc
, argv
);
2984 #ifdef CONFIG_WPA_CLI_FORK
2986 kill(mon_pid
, SIGUSR2
);
2987 #endif /* CONFIG_WPA_CLI_FORK */
2988 } while (!wpa_cli_quit
);
2991 #endif /* CONFIG_READLINE */
2994 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
2996 #ifdef CONFIG_ANSI_C_EXTRA
2997 /* TODO: ANSI C version(?) */
2998 printf("Action processing not supported in ANSI C build.\n");
2999 #else /* CONFIG_ANSI_C_EXTRA */
3003 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3006 fd
= wpa_ctrl_get_fd(ctrl
);
3008 while (!wpa_cli_quit
) {
3011 tv
.tv_sec
= ping_interval
;
3013 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3014 if (res
< 0 && errno
!= EINTR
) {
3019 if (FD_ISSET(fd
, &rfds
))
3020 wpa_cli_recv_pending(ctrl
, 0, 1);
3022 /* verify that connection is still working */
3023 len
= sizeof(buf
) - 1;
3024 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3025 wpa_cli_action_cb
) < 0 ||
3026 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3027 printf("wpa_supplicant did not reply to PING "
3028 "command - exiting\n");
3033 #endif /* CONFIG_ANSI_C_EXTRA */
3037 static void wpa_cli_cleanup(void)
3039 wpa_cli_close_connection();
3041 os_daemonize_terminate(pid_file
);
3043 os_program_deinit();
3046 static void wpa_cli_terminate(int sig
)
3053 #ifdef CONFIG_WPA_CLI_FORK
3054 static void wpa_cli_usr1(int sig
)
3058 #endif /* CONFIG_WPA_CLI_FORK */
3061 #ifndef CONFIG_NATIVE_WINDOWS
3062 static void wpa_cli_alarm(int sig
)
3064 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3065 printf("Connection to wpa_supplicant lost - trying to "
3067 wpa_cli_close_connection();
3070 wpa_cli_reconnect();
3072 wpa_cli_recv_pending(mon_conn
, 1, 0);
3073 alarm(ping_interval
);
3075 #endif /* CONFIG_NATIVE_WINDOWS */
3078 static char * wpa_cli_get_default_ifname(void)
3080 char *ifname
= NULL
;
3082 #ifdef CONFIG_CTRL_IFACE_UNIX
3083 struct dirent
*dent
;
3084 DIR *dir
= opendir(ctrl_iface_dir
);
3087 while ((dent
= readdir(dir
))) {
3088 #ifdef _DIRENT_HAVE_D_TYPE
3090 * Skip the file if it is not a socket. Also accept
3091 * DT_UNKNOWN (0) in case the C library or underlying
3092 * file system does not support d_type.
3094 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3096 #endif /* _DIRENT_HAVE_D_TYPE */
3097 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3098 os_strcmp(dent
->d_name
, "..") == 0)
3100 printf("Selected interface '%s'\n", dent
->d_name
);
3101 ifname
= os_strdup(dent
->d_name
);
3105 #endif /* CONFIG_CTRL_IFACE_UNIX */
3107 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3108 char buf
[2048], *pos
;
3110 struct wpa_ctrl
*ctrl
;
3113 ctrl
= wpa_ctrl_open(NULL
);
3117 len
= sizeof(buf
) - 1;
3118 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3121 pos
= os_strchr(buf
, '\n');
3124 ifname
= os_strdup(buf
);
3126 wpa_ctrl_close(ctrl
);
3127 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3133 int main(int argc
, char *argv
[])
3135 int warning_displayed
= 0;
3139 const char *global
= NULL
;
3141 if (os_program_init())
3145 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3150 action_file
= optarg
;
3159 ping_interval
= atoi(optarg
);
3165 printf("%s\n", wpa_cli_version
);
3168 os_free(ctrl_ifname
);
3169 ctrl_ifname
= os_strdup(optarg
);
3172 ctrl_iface_dir
= optarg
;
3183 interactive
= (argc
== optind
) && (action_file
== NULL
);
3186 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3189 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3190 ctrl_conn
= wpa_ctrl_open(NULL
);
3191 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3192 ctrl_conn
= wpa_ctrl_open(global
);
3193 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3194 if (ctrl_conn
== NULL
) {
3195 perror("Failed to connect to wpa_supplicant - "
3202 signal(SIGINT
, wpa_cli_terminate
);
3203 signal(SIGTERM
, wpa_cli_terminate
);
3204 #endif /* _WIN32_WCE */
3205 #ifndef CONFIG_NATIVE_WINDOWS
3206 signal(SIGALRM
, wpa_cli_alarm
);
3207 #endif /* CONFIG_NATIVE_WINDOWS */
3208 #ifdef CONFIG_WPA_CLI_FORK
3209 signal(SIGUSR1
, wpa_cli_usr1
);
3210 #endif /* CONFIG_WPA_CLI_FORK */
3212 if (ctrl_ifname
== NULL
)
3213 ctrl_ifname
= wpa_cli_get_default_ifname();
3217 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3218 if (warning_displayed
)
3219 printf("Connection established.\n");
3223 if (!warning_displayed
) {
3224 printf("Could not connect to wpa_supplicant - "
3226 warning_displayed
= 1;
3233 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3234 perror("Failed to connect to wpa_supplicant - "
3240 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3241 wpa_cli_attached
= 1;
3243 printf("Warning: Failed to attach to "
3244 "wpa_supplicant.\n");
3250 if (daemonize
&& os_daemonize(pid_file
))
3254 wpa_cli_interactive();
3255 else if (action_file
)
3256 wpa_cli_action(ctrl_conn
);
3258 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
3260 os_free(ctrl_ifname
);
3266 #else /* CONFIG_CTRL_IFACE */
3267 int main(int argc
, char *argv
[])
3269 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3272 #endif /* CONFIG_CTRL_IFACE */