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 */
27 #include "common/wpa_ctrl.h"
28 #include "utils/common.h"
29 #include "utils/eloop.h"
30 #include "utils/edit.h"
31 #include "common/version.h"
34 static const char *wpa_cli_version
=
35 "wpa_cli v" VERSION_STR
"\n"
36 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
39 static const char *wpa_cli_license
=
40 "This program is free software. You can distribute it and/or modify it\n"
41 "under the terms of the GNU General Public License version 2.\n"
43 "Alternatively, this software may be distributed under the terms of the\n"
44 "BSD license. See README and COPYING for more details.\n";
46 static const char *wpa_cli_full_license
=
47 "This program is free software; you can redistribute it and/or modify\n"
48 "it under the terms of the GNU General Public License version 2 as\n"
49 "published by the Free Software Foundation.\n"
51 "This program is distributed in the hope that it will be useful,\n"
52 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
53 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
54 "GNU General Public License for more details.\n"
56 "You should have received a copy of the GNU General Public License\n"
57 "along with this program; if not, write to the Free Software\n"
58 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
60 "Alternatively, this software may be distributed under the terms of the\n"
63 "Redistribution and use in source and binary forms, with or without\n"
64 "modification, are permitted provided that the following conditions are\n"
67 "1. Redistributions of source code must retain the above copyright\n"
68 " notice, this list of conditions and the following disclaimer.\n"
70 "2. Redistributions in binary form must reproduce the above copyright\n"
71 " notice, this list of conditions and the following disclaimer in the\n"
72 " documentation and/or other materials provided with the distribution.\n"
74 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
75 " names of its contributors may be used to endorse or promote products\n"
76 " derived from this software without specific prior written permission.\n"
78 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
79 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
80 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
81 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
82 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
83 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
84 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
85 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
86 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
87 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
88 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
91 static struct wpa_ctrl
*ctrl_conn
;
92 static struct wpa_ctrl
*mon_conn
;
93 static int wpa_cli_quit
= 0;
94 static int wpa_cli_attached
= 0;
95 static int wpa_cli_connected
= 0;
96 static int wpa_cli_last_id
= 0;
97 static const char *ctrl_iface_dir
= "/var/run/wpa_supplicant";
98 static char *ctrl_ifname
= NULL
;
99 static const char *pid_file
= NULL
;
100 static const char *action_file
= NULL
;
101 static int ping_interval
= 5;
102 static int interactive
= 0;
105 static void print_help(void);
106 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
);
109 static void usage(void)
111 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
112 "[-a<action file>] \\\n"
113 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
115 " -h = help (show this usage text)\n"
116 " -v = shown version information\n"
117 " -a = run in daemon mode executing the action file based on "
120 " -B = run a daemon in the background\n"
121 " default path: /var/run/wpa_supplicant\n"
122 " default interface: first interface found in socket path\n");
127 static int str_starts(const char *src
, const char *match
)
129 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
133 static int wpa_cli_show_event(const char *event
)
137 start
= os_strchr(event
, '>');
143 * Skip BSS added/removed events since they can be relatively frequent
144 * and are likely of not much use for an interactive user.
146 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
147 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
154 static int wpa_cli_open_connection(const char *ifname
, int attach
)
156 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
157 ctrl_conn
= wpa_ctrl_open(ifname
);
158 if (ctrl_conn
== NULL
)
161 if (attach
&& interactive
)
162 mon_conn
= wpa_ctrl_open(ifname
);
165 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
172 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
173 cfile
= os_malloc(flen
);
176 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
, ifname
);
177 if (res
< 0 || res
>= flen
) {
182 ctrl_conn
= wpa_ctrl_open(cfile
);
183 if (ctrl_conn
== NULL
) {
188 if (attach
&& interactive
)
189 mon_conn
= wpa_ctrl_open(cfile
);
193 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
196 if (wpa_ctrl_attach(mon_conn
) == 0) {
197 wpa_cli_attached
= 1;
199 eloop_register_read_sock(
200 wpa_ctrl_get_fd(mon_conn
),
201 wpa_cli_mon_receive
, NULL
, NULL
);
203 printf("Warning: Failed to attach to "
204 "wpa_supplicant.\n");
213 static void wpa_cli_close_connection(void)
215 if (ctrl_conn
== NULL
)
218 if (wpa_cli_attached
) {
219 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
220 wpa_cli_attached
= 0;
222 wpa_ctrl_close(ctrl_conn
);
225 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
226 wpa_ctrl_close(mon_conn
);
232 static void wpa_cli_msg_cb(char *msg
, size_t len
)
238 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
244 if (ctrl_conn
== NULL
) {
245 printf("Not connected to wpa_supplicant - command dropped.\n");
248 len
= sizeof(buf
) - 1;
249 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
252 printf("'%s' command timed out.\n", cmd
);
254 } else if (ret
< 0) {
255 printf("'%s' command failed.\n", cmd
);
266 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
268 return _wpa_ctrl_command(ctrl
, cmd
, 1);
272 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
274 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
275 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
279 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
281 return wpa_ctrl_command(ctrl
, "PING");
285 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
291 ret
= os_snprintf(cmd
, sizeof(cmd
), "NOTE %s", argv
[0]);
292 if (ret
< 0 || (size_t) ret
>= sizeof(cmd
))
294 return wpa_ctrl_command(ctrl
, cmd
);
298 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
300 return wpa_ctrl_command(ctrl
, "MIB");
304 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
306 return wpa_ctrl_command(ctrl
, "PMKSA");
310 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
317 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
319 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
324 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
333 static void wpa_cli_show_variables(void)
335 printf("set variables:\n"
336 " EAPOL::heldPeriod (EAPOL state machine held period, "
338 " EAPOL::authPeriod (EAPOL state machine authentication "
339 "period, in seconds)\n"
340 " EAPOL::startPeriod (EAPOL state machine start period, in "
342 " EAPOL::maxStart (EAPOL state machine maximum start "
344 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
346 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
347 " threshold\n\tpercentage)\n"
348 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
349 "security\n\tassociation in seconds)\n");
353 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
359 wpa_cli_show_variables();
364 printf("Invalid SET command: needs two arguments (variable "
365 "name and value)\n");
369 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s", argv
[0], argv
[1]);
370 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
371 printf("Too long SET command.\n");
374 return wpa_ctrl_command(ctrl
, cmd
);
378 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
384 printf("Invalid GET command: need one argument (variable "
389 res
= os_snprintf(cmd
, sizeof(cmd
), "GET %s", argv
[0]);
390 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
391 printf("Too long GET command.\n");
394 return wpa_ctrl_command(ctrl
, cmd
);
398 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
400 return wpa_ctrl_command(ctrl
, "LOGOFF");
404 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
406 return wpa_ctrl_command(ctrl
, "LOGON");
410 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
413 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
417 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
424 printf("Invalid PREAUTH command: needs one argument "
429 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
430 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
431 printf("Too long PREAUTH command.\n");
434 return wpa_ctrl_command(ctrl
, cmd
);
438 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
444 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
448 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
449 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
450 printf("Too long AP_SCAN command.\n");
453 return wpa_ctrl_command(ctrl
, cmd
);
457 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
464 printf("Invalid STKSTART command: needs one argument "
465 "(Peer STA MAC address)\n");
469 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
470 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
471 printf("Too long STKSTART command.\n");
474 return wpa_ctrl_command(ctrl
, cmd
);
478 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
484 printf("Invalid FT_DS command: needs one argument "
485 "(Target AP MAC address)\n");
489 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
490 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
491 printf("Too long FT_DS command.\n");
494 return wpa_ctrl_command(ctrl
, cmd
);
498 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
505 return wpa_ctrl_command(ctrl
, "WPS_PBC");
509 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
510 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
511 printf("Too long WPS_PBC command.\n");
514 return wpa_ctrl_command(ctrl
, cmd
);
518 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
524 printf("Invalid WPS_PIN command: need one or two arguments:\n"
525 "- BSSID: use 'any' to select any\n"
526 "- PIN: optional, used only with devices that have no "
532 /* Use dynamically generated PIN (returned as reply) */
533 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
534 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
535 printf("Too long WPS_PIN command.\n");
538 return wpa_ctrl_command(ctrl
, cmd
);
541 /* Use hardcoded PIN from a label */
542 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
543 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
544 printf("Too long WPS_PIN command.\n");
547 return wpa_ctrl_command(ctrl
, cmd
);
551 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
557 if (argc
!= 1 && argc
!= 2) {
558 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
559 "- PIN to be verified\n");
564 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
567 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
569 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
570 printf("Too long WPS_CHECK_PIN command.\n");
573 return wpa_ctrl_command(ctrl
, cmd
);
577 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
580 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
584 #ifdef CONFIG_WPS_OOB
585 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
590 if (argc
!= 3 && argc
!= 4) {
591 printf("Invalid WPS_OOB command: need three or four "
593 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
594 "- PATH: path of OOB device like '/mnt'\n"
595 "- METHOD: OOB method 'pin-e' or 'pin-r', "
597 "- DEV_NAME: (only for NFC) device name like "
603 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
604 argv
[0], argv
[1], argv
[2]);
606 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
607 argv
[0], argv
[1], argv
[2], argv
[3]);
608 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
609 printf("Too long WPS_OOB command.\n");
612 return wpa_ctrl_command(ctrl
, cmd
);
614 #endif /* CONFIG_WPS_OOB */
617 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
623 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
625 else if (argc
== 5 || argc
== 6) {
626 char ssid_hex
[2 * 32 + 1];
627 char key_hex
[2 * 64 + 1];
631 for (i
= 0; i
< 32; i
++) {
632 if (argv
[2][i
] == '\0')
634 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
639 for (i
= 0; i
< 64; i
++) {
640 if (argv
[5][i
] == '\0')
642 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
647 res
= os_snprintf(cmd
, sizeof(cmd
),
648 "WPS_REG %s %s %s %s %s %s",
649 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
652 printf("Invalid WPS_REG command: need two arguments:\n"
653 "- BSSID of the target AP\n"
655 printf("Alternatively, six arguments can be used to "
656 "reconfigure the AP:\n"
657 "- BSSID of the target AP\n"
660 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
661 "- new encr (NONE, WEP, TKIP, CCMP)\n"
666 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
667 printf("Too long WPS_REG command.\n");
670 return wpa_ctrl_command(ctrl
, cmd
);
674 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
679 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
680 return wpa_ctrl_command(ctrl
, cmd
);
682 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
686 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
689 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
694 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
701 printf("Invalid WPS_ER_PIN command: need at least two "
703 "- UUID: use 'any' to select any\n"
704 "- PIN: Enrollee PIN\n"
705 "optional: - Enrollee MAC address\n");
710 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
711 argv
[0], argv
[1], argv
[2]);
713 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
715 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
716 printf("Too long WPS_ER_PIN command.\n");
719 return wpa_ctrl_command(ctrl
, cmd
);
723 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
730 printf("Invalid WPS_ER_PBC command: need one argument:\n"
731 "- UUID: Specify the Enrollee\n");
735 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
737 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
738 printf("Too long WPS_ER_PBC command.\n");
741 return wpa_ctrl_command(ctrl
, cmd
);
745 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
752 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
753 "- UUID: specify which AP to use\n"
758 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
760 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
761 printf("Too long WPS_ER_LEARN command.\n");
764 return wpa_ctrl_command(ctrl
, cmd
);
768 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
775 printf("Invalid WPS_ER_SET_CONFIG command: need two "
777 "- UUID: specify which AP to use\n"
778 "- Network configuration id\n");
782 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_SET_CONFIG %s %s",
784 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
785 printf("Too long WPS_ER_SET_CONFIG command.\n");
788 return wpa_ctrl_command(ctrl
, cmd
);
792 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
798 if (argc
== 5 || argc
== 6) {
799 char ssid_hex
[2 * 32 + 1];
800 char key_hex
[2 * 64 + 1];
804 for (i
= 0; i
< 32; i
++) {
805 if (argv
[2][i
] == '\0')
807 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
812 for (i
= 0; i
< 64; i
++) {
813 if (argv
[5][i
] == '\0')
815 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
820 res
= os_snprintf(cmd
, sizeof(cmd
),
821 "WPS_ER_CONFIG %s %s %s %s %s %s",
822 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
825 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
829 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
830 "- new encr (NONE, WEP, TKIP, CCMP)\n"
835 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
836 printf("Too long WPS_ER_CONFIG command.\n");
839 return wpa_ctrl_command(ctrl
, cmd
);
843 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
849 printf("Invalid IBSS_RSN command: needs one argument "
850 "(Peer STA MAC address)\n");
854 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
855 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
856 printf("Too long IBSS_RSN command.\n");
859 return wpa_ctrl_command(ctrl
, cmd
);
863 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
869 printf("Invalid LEVEL command: needs one argument (debug "
873 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
874 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
875 printf("Too long LEVEL command.\n");
878 return wpa_ctrl_command(ctrl
, cmd
);
882 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
884 char cmd
[256], *pos
, *end
;
888 printf("Invalid IDENTITY command: needs two arguments "
889 "(network id and identity)\n");
893 end
= cmd
+ sizeof(cmd
);
895 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
897 if (ret
< 0 || ret
>= end
- pos
) {
898 printf("Too long IDENTITY command.\n");
902 for (i
= 2; i
< argc
; i
++) {
903 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
904 if (ret
< 0 || ret
>= end
- pos
) {
905 printf("Too long IDENTITY command.\n");
911 return wpa_ctrl_command(ctrl
, cmd
);
915 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
917 char cmd
[256], *pos
, *end
;
921 printf("Invalid PASSWORD command: needs two arguments "
922 "(network id and password)\n");
926 end
= cmd
+ sizeof(cmd
);
928 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
930 if (ret
< 0 || ret
>= end
- pos
) {
931 printf("Too long PASSWORD command.\n");
935 for (i
= 2; i
< argc
; i
++) {
936 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
937 if (ret
< 0 || ret
>= end
- pos
) {
938 printf("Too long PASSWORD command.\n");
944 return wpa_ctrl_command(ctrl
, cmd
);
948 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
951 char cmd
[256], *pos
, *end
;
955 printf("Invalid NEW_PASSWORD command: needs two arguments "
956 "(network id and password)\n");
960 end
= cmd
+ sizeof(cmd
);
962 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
964 if (ret
< 0 || ret
>= end
- pos
) {
965 printf("Too long NEW_PASSWORD command.\n");
969 for (i
= 2; i
< argc
; i
++) {
970 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
971 if (ret
< 0 || ret
>= end
- pos
) {
972 printf("Too long NEW_PASSWORD command.\n");
978 return wpa_ctrl_command(ctrl
, cmd
);
982 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
984 char cmd
[256], *pos
, *end
;
988 printf("Invalid PIN command: needs two arguments "
989 "(network id and pin)\n");
993 end
= cmd
+ sizeof(cmd
);
995 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
997 if (ret
< 0 || ret
>= end
- pos
) {
998 printf("Too long PIN command.\n");
1002 for (i
= 2; i
< argc
; i
++) {
1003 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1004 if (ret
< 0 || ret
>= end
- pos
) {
1005 printf("Too long PIN command.\n");
1010 return wpa_ctrl_command(ctrl
, cmd
);
1014 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1016 char cmd
[256], *pos
, *end
;
1020 printf("Invalid OTP command: needs two arguments (network "
1021 "id and password)\n");
1025 end
= cmd
+ sizeof(cmd
);
1027 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1029 if (ret
< 0 || ret
>= end
- pos
) {
1030 printf("Too long OTP command.\n");
1034 for (i
= 2; i
< argc
; i
++) {
1035 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1036 if (ret
< 0 || ret
>= end
- pos
) {
1037 printf("Too long OTP command.\n");
1043 return wpa_ctrl_command(ctrl
, cmd
);
1047 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1050 char cmd
[256], *pos
, *end
;
1054 printf("Invalid PASSPHRASE command: needs two arguments "
1055 "(network id and passphrase)\n");
1059 end
= cmd
+ sizeof(cmd
);
1061 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1063 if (ret
< 0 || ret
>= end
- pos
) {
1064 printf("Too long PASSPHRASE command.\n");
1068 for (i
= 2; i
< argc
; i
++) {
1069 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1070 if (ret
< 0 || ret
>= end
- pos
) {
1071 printf("Too long PASSPHRASE command.\n");
1077 return wpa_ctrl_command(ctrl
, cmd
);
1081 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1083 char cmd
[256], *pos
, *end
;
1087 printf("Invalid BSSID command: needs two arguments (network "
1092 end
= cmd
+ sizeof(cmd
);
1094 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1095 if (ret
< 0 || ret
>= end
- pos
) {
1096 printf("Too long BSSID command.\n");
1100 for (i
= 0; i
< argc
; i
++) {
1101 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1102 if (ret
< 0 || ret
>= end
- pos
) {
1103 printf("Too long BSSID command.\n");
1109 return wpa_ctrl_command(ctrl
, cmd
);
1113 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1116 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1120 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1127 printf("Invalid SELECT_NETWORK command: needs one argument "
1132 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1133 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1135 cmd
[sizeof(cmd
) - 1] = '\0';
1137 return wpa_ctrl_command(ctrl
, cmd
);
1141 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1148 printf("Invalid ENABLE_NETWORK command: needs one argument "
1153 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1154 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1156 cmd
[sizeof(cmd
) - 1] = '\0';
1158 return wpa_ctrl_command(ctrl
, cmd
);
1162 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1169 printf("Invalid DISABLE_NETWORK command: needs one argument "
1174 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1175 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1177 cmd
[sizeof(cmd
) - 1] = '\0';
1179 return wpa_ctrl_command(ctrl
, cmd
);
1183 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1186 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1190 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1197 printf("Invalid REMOVE_NETWORK command: needs one argument "
1202 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1203 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1205 cmd
[sizeof(cmd
) - 1] = '\0';
1207 return wpa_ctrl_command(ctrl
, cmd
);
1211 static void wpa_cli_show_network_variables(void)
1213 printf("set_network variables:\n"
1214 " ssid (network name, SSID)\n"
1215 " psk (WPA passphrase or pre-shared key)\n"
1216 " key_mgmt (key management protocol)\n"
1217 " identity (EAP identity)\n"
1218 " password (EAP password)\n"
1221 "Note: Values are entered in the same format as the "
1222 "configuration file is using,\n"
1223 "i.e., strings values need to be inside double quotation "
1225 "For example: set_network 1 ssid \"network name\"\n"
1227 "Please see wpa_supplicant.conf documentation for full list "
1228 "of\navailable variables.\n");
1232 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1239 wpa_cli_show_network_variables();
1244 printf("Invalid SET_NETWORK command: needs three arguments\n"
1245 "(network id, variable name, and value)\n");
1249 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1250 argv
[0], argv
[1], argv
[2]);
1251 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1252 printf("Too long SET_NETWORK command.\n");
1255 return wpa_ctrl_command(ctrl
, cmd
);
1259 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1266 wpa_cli_show_network_variables();
1271 printf("Invalid GET_NETWORK command: needs two arguments\n"
1272 "(network id and variable name)\n");
1276 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1278 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1279 printf("Too long GET_NETWORK command.\n");
1282 return wpa_ctrl_command(ctrl
, cmd
);
1286 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1289 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1293 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1296 return wpa_ctrl_command(ctrl
, "RECONNECT");
1300 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1303 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1307 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1309 return wpa_ctrl_command(ctrl
, "SCAN");
1313 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1316 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1320 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1326 printf("Invalid BSS command: need one argument (index or "
1331 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1332 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1334 cmd
[sizeof(cmd
) - 1] = '\0';
1336 return wpa_ctrl_command(ctrl
, cmd
);
1340 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1346 if (argc
< 1 || argc
> 2) {
1347 printf("Invalid GET_CAPABILITY command: need either one or "
1352 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1353 printf("Invalid GET_CAPABILITY command: second argument, "
1354 "if any, must be 'strict'\n");
1358 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1359 (argc
== 2) ? " strict" : "");
1360 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1362 cmd
[sizeof(cmd
) - 1] = '\0';
1364 return wpa_ctrl_command(ctrl
, cmd
);
1368 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1370 printf("Available interfaces:\n");
1371 return wpa_ctrl_command(ctrl
, "INTERFACES");
1375 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1378 wpa_cli_list_interfaces(ctrl
);
1382 wpa_cli_close_connection();
1383 os_free(ctrl_ifname
);
1384 ctrl_ifname
= os_strdup(argv
[0]);
1386 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1387 printf("Connected to interface '%s.\n", ctrl_ifname
);
1389 printf("Could not connect to interface '%s' - re-trying\n",
1396 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1399 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1403 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1406 return wpa_ctrl_command(ctrl
, "TERMINATE");
1410 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1417 printf("Invalid INTERFACE_ADD command: needs at least one "
1418 "argument (interface name)\n"
1419 "All arguments: ifname confname driver ctrl_interface "
1420 "driver_param bridge_name\n");
1425 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1426 * <driver_param>TAB<bridge_name>
1428 res
= os_snprintf(cmd
, sizeof(cmd
),
1429 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1431 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1432 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1433 argc
> 5 ? argv
[5] : "");
1434 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1436 cmd
[sizeof(cmd
) - 1] = '\0';
1437 return wpa_ctrl_command(ctrl
, cmd
);
1441 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1448 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1449 "(interface name)\n");
1453 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1454 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1456 cmd
[sizeof(cmd
) - 1] = '\0';
1457 return wpa_ctrl_command(ctrl
, cmd
);
1461 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1464 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1469 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1473 printf("Invalid 'sta' command - exactly one argument, STA "
1474 "address, is required.\n");
1477 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1478 return wpa_ctrl_command(ctrl
, buf
);
1482 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1483 char *addr
, size_t addr_len
)
1485 char buf
[4096], *pos
;
1489 if (ctrl_conn
== NULL
) {
1490 printf("Not connected to hostapd - command dropped.\n");
1493 len
= sizeof(buf
) - 1;
1494 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1497 printf("'%s' command timed out.\n", cmd
);
1499 } else if (ret
< 0) {
1500 printf("'%s' command failed.\n", cmd
);
1505 if (memcmp(buf
, "FAIL", 4) == 0)
1510 while (*pos
!= '\0' && *pos
!= '\n')
1513 os_strlcpy(addr
, buf
, addr_len
);
1518 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1520 char addr
[32], cmd
[64];
1522 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1525 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1526 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1530 #endif /* CONFIG_AP */
1533 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1535 return wpa_ctrl_command(ctrl
, "SUSPEND");
1539 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1541 return wpa_ctrl_command(ctrl
, "RESUME");
1545 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1547 return wpa_ctrl_command(ctrl
, "DROP_SA");
1551 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1557 printf("Invalid ROAM command: needs one argument "
1558 "(target AP's BSSID)\n");
1562 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
1563 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1564 printf("Too long ROAM command.\n");
1567 return wpa_ctrl_command(ctrl
, cmd
);
1573 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1579 return wpa_ctrl_command(ctrl
, "P2P_FIND");
1582 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
1585 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
1586 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1588 cmd
[sizeof(cmd
) - 1] = '\0';
1589 return wpa_ctrl_command(ctrl
, cmd
);
1593 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1596 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1600 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1607 printf("Invalid P2P_CONNECT command: needs at least two "
1608 "arguments (address and pbc/PIN)\n");
1613 res
= os_snprintf(cmd
, sizeof(cmd
),
1614 "P2P_CONNECT %s %s %s %s %s",
1615 argv
[0], argv
[1], argv
[2], argv
[3],
1618 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
1619 argv
[0], argv
[1], argv
[2], argv
[3]);
1621 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
1622 argv
[0], argv
[1], argv
[2]);
1624 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
1626 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1628 cmd
[sizeof(cmd
) - 1] = '\0';
1629 return wpa_ctrl_command(ctrl
, cmd
);
1633 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1640 return wpa_ctrl_command(ctrl
, "P2P_LISTEN");
1642 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_LISTEN %s", argv
[0]);
1643 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1645 cmd
[sizeof(cmd
) - 1] = '\0';
1646 return wpa_ctrl_command(ctrl
, cmd
);
1650 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1657 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1658 "(interface name)\n");
1662 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
1663 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1665 cmd
[sizeof(cmd
) - 1] = '\0';
1666 return wpa_ctrl_command(ctrl
, cmd
);
1670 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1677 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
1679 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s", argv
[0]);
1680 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1682 cmd
[sizeof(cmd
) - 1] = '\0';
1683 return wpa_ctrl_command(ctrl
, cmd
);
1687 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1694 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1695 "(address and config method\n"
1696 "(display, keypad, or pbc)\n");
1700 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
1702 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1704 cmd
[sizeof(cmd
) - 1] = '\0';
1705 return wpa_ctrl_command(ctrl
, cmd
);
1709 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1712 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1716 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1722 if (argc
!= 2 && argc
!= 4) {
1723 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1724 "arguments (address and TLVs) or four arguments "
1725 "(address, \"upnp\", version, search target "
1731 res
= os_snprintf(cmd
, sizeof(cmd
),
1732 "P2P_SERV_DISC_REQ %s %s %s %s",
1733 argv
[0], argv
[1], argv
[2], argv
[3]);
1735 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
1737 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1739 cmd
[sizeof(cmd
) - 1] = '\0';
1740 return wpa_ctrl_command(ctrl
, cmd
);
1744 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1745 int argc
, char *argv
[])
1751 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1752 "argument (pending request identifier)\n");
1756 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
1758 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1760 cmd
[sizeof(cmd
) - 1] = '\0';
1761 return wpa_ctrl_command(ctrl
, cmd
);
1765 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1772 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1773 "arguments (freq, address, dialog token, and TLVs)\n");
1777 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1778 argv
[0], argv
[1], argv
[2], argv
[3]);
1779 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1781 cmd
[sizeof(cmd
) - 1] = '\0';
1782 return wpa_ctrl_command(ctrl
, cmd
);
1786 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1789 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1793 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1794 int argc
, char *argv
[])
1800 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1801 "argument (external processing: 0/1)\n");
1805 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
1807 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1809 cmd
[sizeof(cmd
) - 1] = '\0';
1810 return wpa_ctrl_command(ctrl
, cmd
);
1814 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1817 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1821 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1827 if (argc
!= 3 && argc
!= 4) {
1828 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1834 res
= os_snprintf(cmd
, sizeof(cmd
),
1835 "P2P_SERVICE_ADD %s %s %s %s",
1836 argv
[0], argv
[1], argv
[2], argv
[3]);
1838 res
= os_snprintf(cmd
, sizeof(cmd
),
1839 "P2P_SERVICE_ADD %s %s %s",
1840 argv
[0], argv
[1], argv
[2]);
1841 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1843 cmd
[sizeof(cmd
) - 1] = '\0';
1844 return wpa_ctrl_command(ctrl
, cmd
);
1848 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1854 if (argc
!= 2 && argc
!= 3) {
1855 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1861 res
= os_snprintf(cmd
, sizeof(cmd
),
1862 "P2P_SERVICE_DEL %s %s %s",
1863 argv
[0], argv
[1], argv
[2]);
1865 res
= os_snprintf(cmd
, sizeof(cmd
),
1866 "P2P_SERVICE_DEL %s %s",
1868 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1870 cmd
[sizeof(cmd
) - 1] = '\0';
1871 return wpa_ctrl_command(ctrl
, cmd
);
1875 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1876 int argc
, char *argv
[])
1882 printf("Invalid P2P_REJECT command: needs one argument "
1883 "(peer address)\n");
1887 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
1888 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1890 cmd
[sizeof(cmd
) - 1] = '\0';
1891 return wpa_ctrl_command(ctrl
, cmd
);
1895 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
1896 int argc
, char *argv
[])
1902 printf("Invalid P2P_INVITE command: needs at least one "
1908 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
1909 argv
[0], argv
[1], argv
[2]);
1911 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
1914 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
1915 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1917 cmd
[sizeof(cmd
) - 1] = '\0';
1918 return wpa_ctrl_command(ctrl
, cmd
);
1922 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1926 printf("Invalid 'p2p_peer' command - exactly one argument, "
1927 "P2P peer device address, is required.\n");
1930 os_snprintf(buf
, sizeof(buf
), "P2P_PEER %s", argv
[0]);
1931 return wpa_ctrl_command(ctrl
, buf
);
1935 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
1936 char *addr
, size_t addr_len
,
1939 char buf
[4096], *pos
;
1943 if (ctrl_conn
== NULL
)
1945 len
= sizeof(buf
) - 1;
1946 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1949 printf("'%s' command timed out.\n", cmd
);
1951 } else if (ret
< 0) {
1952 printf("'%s' command failed.\n", cmd
);
1957 if (memcmp(buf
, "FAIL", 4) == 0)
1961 while (*pos
!= '\0' && *pos
!= '\n')
1964 os_strlcpy(addr
, buf
, addr_len
);
1965 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
1966 printf("%s\n", addr
);
1971 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1973 char addr
[32], cmd
[64];
1976 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
1978 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
1979 addr
, sizeof(addr
), discovered
))
1982 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
1983 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
1990 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1996 printf("Invalid P2P_SET command: needs two arguments (field, "
2001 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
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_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2011 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2015 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2018 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2022 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2028 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2029 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2030 "(preferred duration, interval; in microsecods).\n"
2031 "Optional second pair can be used to provide "
2032 "acceptable values.\n");
2037 res
= os_snprintf(cmd
, sizeof(cmd
),
2038 "P2P_PRESENCE_REQ %s %s %s %s",
2039 argv
[0], argv
[1], argv
[2], argv
[3]);
2041 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2044 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
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_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2058 if (argc
!= 0 && argc
!= 2) {
2059 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2060 "(availability period, availability interval; in "
2062 "Extended Listen Timing can be cancelled with this "
2063 "command when used without parameters.\n");
2068 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2071 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2072 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2074 cmd
[sizeof(cmd
) - 1] = '\0';
2075 return wpa_ctrl_command(ctrl
, cmd
);
2078 #endif /* CONFIG_P2P */
2081 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2088 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2089 "(0/1 = disable/enable automatic reconnection)\n");
2092 res
= os_snprintf(cmd
, sizeof(cmd
), "STA_AUTOCONNECT %s", argv
[0]);
2093 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2094 printf("Too long STA_AUTOCONNECT command.\n");
2097 return wpa_ctrl_command(ctrl
, cmd
);
2101 enum wpa_cli_cmd_flags
{
2102 cli_cmd_flag_none
= 0x00,
2103 cli_cmd_flag_sensitive
= 0x01
2106 struct wpa_cli_cmd
{
2108 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2109 enum wpa_cli_cmd_flags flags
;
2113 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2114 { "status", wpa_cli_cmd_status
,
2116 "[verbose] = get current WPA/EAPOL/EAP status" },
2117 { "ping", wpa_cli_cmd_ping
,
2119 "= pings wpa_supplicant" },
2120 { "note", wpa_cli_cmd_note
,
2122 "<text> = add a note to wpa_supplicant debug log" },
2123 { "mib", wpa_cli_cmd_mib
,
2125 "= get MIB variables (dot1x, dot11)" },
2126 { "help", wpa_cli_cmd_help
,
2128 "= show this usage help" },
2129 { "interface", wpa_cli_cmd_interface
,
2131 "[ifname] = show interfaces/select interface" },
2132 { "level", wpa_cli_cmd_level
,
2134 "<debug level> = change debug level" },
2135 { "license", wpa_cli_cmd_license
,
2137 "= show full wpa_cli license" },
2138 { "quit", wpa_cli_cmd_quit
,
2141 { "set", wpa_cli_cmd_set
,
2143 "= set variables (shows list of variables when run without "
2145 { "get", wpa_cli_cmd_get
,
2147 "<name> = get information" },
2148 { "logon", wpa_cli_cmd_logon
,
2150 "= IEEE 802.1X EAPOL state machine logon" },
2151 { "logoff", wpa_cli_cmd_logoff
,
2153 "= IEEE 802.1X EAPOL state machine logoff" },
2154 { "pmksa", wpa_cli_cmd_pmksa
,
2156 "= show PMKSA cache" },
2157 { "reassociate", wpa_cli_cmd_reassociate
,
2159 "= force reassociation" },
2160 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2162 "<BSSID> = force preauthentication" },
2163 { "identity", wpa_cli_cmd_identity
,
2165 "<network id> <identity> = configure identity for an SSID" },
2166 { "password", wpa_cli_cmd_password
,
2167 cli_cmd_flag_sensitive
,
2168 "<network id> <password> = configure password for an SSID" },
2169 { "new_password", wpa_cli_cmd_new_password
,
2170 cli_cmd_flag_sensitive
,
2171 "<network id> <password> = change password for an SSID" },
2172 { "pin", wpa_cli_cmd_pin
,
2173 cli_cmd_flag_sensitive
,
2174 "<network id> <pin> = configure pin for an SSID" },
2175 { "otp", wpa_cli_cmd_otp
,
2176 cli_cmd_flag_sensitive
,
2177 "<network id> <password> = configure one-time-password for an SSID"
2179 { "passphrase", wpa_cli_cmd_passphrase
,
2180 cli_cmd_flag_sensitive
,
2181 "<network id> <passphrase> = configure private key passphrase\n"
2183 { "bssid", wpa_cli_cmd_bssid
,
2185 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2186 { "list_networks", wpa_cli_cmd_list_networks
,
2188 "= list configured networks" },
2189 { "select_network", wpa_cli_cmd_select_network
,
2191 "<network id> = select a network (disable others)" },
2192 { "enable_network", wpa_cli_cmd_enable_network
,
2194 "<network id> = enable a network" },
2195 { "disable_network", wpa_cli_cmd_disable_network
,
2197 "<network id> = disable a network" },
2198 { "add_network", wpa_cli_cmd_add_network
,
2200 "= add a network" },
2201 { "remove_network", wpa_cli_cmd_remove_network
,
2203 "<network id> = remove a network" },
2204 { "set_network", wpa_cli_cmd_set_network
,
2205 cli_cmd_flag_sensitive
,
2206 "<network id> <variable> <value> = set network variables (shows\n"
2207 " list of variables when run without arguments)" },
2208 { "get_network", wpa_cli_cmd_get_network
,
2210 "<network id> <variable> = get network variables" },
2211 { "save_config", wpa_cli_cmd_save_config
,
2213 "= save the current configuration" },
2214 { "disconnect", wpa_cli_cmd_disconnect
,
2216 "= disconnect and wait for reassociate/reconnect command before\n"
2218 { "reconnect", wpa_cli_cmd_reconnect
,
2220 "= like reassociate, but only takes effect if already disconnected"
2222 { "scan", wpa_cli_cmd_scan
,
2224 "= request new BSS scan" },
2225 { "scan_results", wpa_cli_cmd_scan_results
,
2227 "= get latest scan results" },
2228 { "bss", wpa_cli_cmd_bss
,
2230 "<<idx> | <bssid>> = get detailed scan result info" },
2231 { "get_capability", wpa_cli_cmd_get_capability
,
2233 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2234 { "reconfigure", wpa_cli_cmd_reconfigure
,
2236 "= force wpa_supplicant to re-read its configuration file" },
2237 { "terminate", wpa_cli_cmd_terminate
,
2239 "= terminate wpa_supplicant" },
2240 { "interface_add", wpa_cli_cmd_interface_add
,
2242 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2243 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2245 { "interface_remove", wpa_cli_cmd_interface_remove
,
2247 "<ifname> = removes the interface" },
2248 { "interface_list", wpa_cli_cmd_interface_list
,
2250 "= list available interfaces" },
2251 { "ap_scan", wpa_cli_cmd_ap_scan
,
2253 "<value> = set ap_scan parameter" },
2254 { "stkstart", wpa_cli_cmd_stkstart
,
2256 "<addr> = request STK negotiation with <addr>" },
2257 { "ft_ds", wpa_cli_cmd_ft_ds
,
2259 "<addr> = request over-the-DS FT with <addr>" },
2260 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
2262 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2263 { "wps_pin", wpa_cli_cmd_wps_pin
,
2264 cli_cmd_flag_sensitive
,
2265 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2267 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
2268 cli_cmd_flag_sensitive
,
2269 "<PIN> = verify PIN checksum" },
2270 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
2271 "Cancels the pending WPS operation" },
2272 #ifdef CONFIG_WPS_OOB
2273 { "wps_oob", wpa_cli_cmd_wps_oob
,
2274 cli_cmd_flag_sensitive
,
2275 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2276 #endif /* CONFIG_WPS_OOB */
2277 { "wps_reg", wpa_cli_cmd_wps_reg
,
2278 cli_cmd_flag_sensitive
,
2279 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2280 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
2282 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2283 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
2285 "= stop Wi-Fi Protected Setup External Registrar" },
2286 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
2287 cli_cmd_flag_sensitive
,
2288 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2289 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
2291 "<UUID> = accept an Enrollee PBC using External Registrar" },
2292 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
2293 cli_cmd_flag_sensitive
,
2294 "<UUID> <PIN> = learn AP configuration" },
2295 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
,
2297 "<UUID> <network id> = set AP configuration for enrolling" },
2298 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
2299 cli_cmd_flag_sensitive
,
2300 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2301 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
2303 "<addr> = request RSN authentication with <addr> in IBSS" },
2305 { "sta", wpa_cli_cmd_sta
,
2307 "<addr> = get information about an associated station (AP)" },
2308 { "all_sta", wpa_cli_cmd_all_sta
,
2310 "= get information about all associated stations (AP)" },
2311 #endif /* CONFIG_AP */
2312 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
2313 "= notification of suspend/hibernate" },
2314 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
2315 "= notification of resume/thaw" },
2316 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
2317 "= drop SA without deauth/disassoc (test command)" },
2318 { "roam", wpa_cli_cmd_roam
,
2320 "<addr> = roam to the specified BSS" },
2322 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
2323 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2324 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
2325 "= stop P2P Devices search" },
2326 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
2327 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2328 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
2329 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2330 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
2331 "<ifname> = remote P2P group interface (terminate group if GO)" },
2332 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
2333 "= add a new P2P group (local end as GO)" },
2334 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
2335 "<addr> <method> = request provisioning discovery" },
2336 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
2338 "= get the passphrase for a group (GO only)" },
2339 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2341 "<addr> <TLVs> = schedule service discovery request" },
2342 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2344 "<id> = cancel pending service discovery request" },
2345 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2347 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2348 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2350 "= indicate change in local services" },
2351 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2353 "<external> = set external processing of service discovery" },
2354 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2356 "= remove all stored service entries" },
2357 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2359 "<bonjour|upnp> <query|version> <response|service> = add a local "
2361 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2363 "<bonjour|upnp> <query|version> [|service] = remove a local "
2365 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2367 "<addr> = reject connection attempts from a specific peer" },
2368 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
2370 "<cmd> [peer=addr] = invite peer" },
2371 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
2372 "[discovered] = list known (optionally, only fully discovered) P2P "
2374 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
2375 "<address> = show information about known P2P peer" },
2376 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
2377 "<field> <value> = set a P2P parameter" },
2378 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
2379 "= flush P2P state" },
2380 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
2381 "= cancel P2P group formation" },
2382 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
2383 "[<duration> <interval>] [<duration> <interval>] = request GO "
2385 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
2386 "[<period> <interval>] = set extended listen timing" },
2387 #endif /* CONFIG_P2P */
2388 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
2389 "<0/1> = disable/enable automatic reconnection" },
2390 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2395 * Prints command usage, lines are padded with the specified string.
2397 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2402 printf("%s%s ", pad
, cmd
->cmd
);
2403 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2412 static void print_help(void)
2415 printf("commands:\n");
2416 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
2417 print_cmd_help(&wpa_cli_commands
[n
], " ");
2421 #ifdef CONFIG_READLINE
2422 static int cmd_has_sensitive_data(const char *cmd
)
2424 const char *c
, *delim
;
2428 delim
= os_strchr(cmd
, ' ');
2432 len
= os_strlen(cmd
);
2434 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2435 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2436 return (wpa_cli_commands
[n
].flags
&
2437 cli_cmd_flag_sensitive
);
2441 #endif /* CONFIG_READLINE */
2444 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2446 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2451 cmd
= wpa_cli_commands
;
2453 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2456 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2457 /* we have an exact match */
2467 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
2468 cmd
= wpa_cli_commands
;
2470 if (os_strncasecmp(cmd
->cmd
, argv
[0],
2471 os_strlen(argv
[0])) == 0) {
2472 printf(" %s", cmd
->cmd
);
2478 } else if (count
== 0) {
2479 printf("Unknown command '%s'\n", argv
[0]);
2482 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
2489 static int str_match(const char *a
, const char *b
)
2491 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
2495 static int wpa_cli_exec(const char *program
, const char *arg1
,
2503 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
2504 cmd
= os_malloc(len
);
2507 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
2508 if (res
< 0 || (size_t) res
>= len
) {
2512 cmd
[len
- 1] = '\0';
2514 if (system(cmd
) < 0)
2516 #endif /* _WIN32_WCE */
2523 static void wpa_cli_action_process(const char *msg
)
2526 char *copy
= NULL
, *id
, *pos2
;
2531 pos
= os_strchr(pos
, '>');
2538 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
2540 os_unsetenv("WPA_ID");
2541 os_unsetenv("WPA_ID_STR");
2542 os_unsetenv("WPA_CTRL_DIR");
2544 pos
= os_strstr(pos
, "[id=");
2546 copy
= os_strdup(pos
+ 4);
2550 while (*pos2
&& *pos2
!= ' ')
2554 os_setenv("WPA_ID", id
, 1);
2555 while (*pos2
&& *pos2
!= '=')
2560 while (*pos2
&& *pos2
!= ']')
2563 os_setenv("WPA_ID_STR", id
, 1);
2567 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
2569 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
2570 wpa_cli_connected
= 1;
2571 wpa_cli_last_id
= new_id
;
2572 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
2574 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
2575 if (wpa_cli_connected
) {
2576 wpa_cli_connected
= 0;
2577 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
2579 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
2580 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2581 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
2582 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2583 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
2584 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2585 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
2586 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2587 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
2588 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2589 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
2590 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2591 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
2592 printf("wpa_supplicant is terminating - stop monitoring\n");
2598 #ifndef CONFIG_ANSI_C_EXTRA
2599 static void wpa_cli_action_cb(char *msg
, size_t len
)
2601 wpa_cli_action_process(msg
);
2603 #endif /* CONFIG_ANSI_C_EXTRA */
2606 static void wpa_cli_reconnect(void)
2608 wpa_cli_close_connection();
2609 wpa_cli_open_connection(ctrl_ifname
, 1);
2613 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
2615 if (ctrl_conn
== NULL
) {
2616 wpa_cli_reconnect();
2619 while (wpa_ctrl_pending(ctrl
) > 0) {
2621 size_t len
= sizeof(buf
) - 1;
2622 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
2625 wpa_cli_action_process(buf
);
2627 if (wpa_cli_show_event(buf
)) {
2629 printf("\r%s\n", buf
);
2634 printf("Could not read pending message.\n");
2639 if (wpa_ctrl_pending(ctrl
) < 0) {
2640 printf("Connection to wpa_supplicant lost - trying to "
2642 wpa_cli_reconnect();
2648 static int tokenize_cmd(char *cmd
, char *argv
[])
2661 if (argc
== max_args
)
2664 char *pos2
= os_strrchr(pos
, '"');
2668 while (*pos
!= '\0' && *pos
!= ' ')
2678 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
2680 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
2681 printf("Connection to wpa_supplicant lost - trying to "
2683 wpa_cli_close_connection();
2686 wpa_cli_reconnect();
2687 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
2691 static void wpa_cli_eloop_terminate(int sig
, void *signal_ctx
)
2697 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
2699 wpa_cli_recv_pending(mon_conn
, 0);
2703 #ifdef CONFIG_READLINE
2705 static void *edit_cb_ctx
;
2706 static void (*edit_cmd_cb
)(void *ctx
, char *cmd
);
2707 static void (*edit_eof_cb
)(void *ctx
);
2710 static char * wpa_cli_cmd_gen(const char *text
, int state
)
2717 len
= os_strlen(text
);
2720 while ((cmd
= wpa_cli_commands
[i
].cmd
)) {
2722 if (os_strncasecmp(cmd
, text
, len
) == 0)
2730 static char * wpa_cli_dummy_gen(const char *text
, int state
)
2734 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2735 const char *cmd
= wpa_cli_commands
[i
].cmd
;
2736 size_t len
= os_strlen(cmd
);
2737 if (os_strncasecmp(rl_line_buffer
, cmd
, len
) == 0 &&
2738 rl_line_buffer
[len
] == ' ') {
2739 printf("\n%s\n", wpa_cli_commands
[i
].usage
);
2745 rl_attempted_completion_over
= 1;
2750 static char * wpa_cli_status_gen(const char *text
, int state
)
2760 len
= os_strlen(text
);
2763 while ((t
= options
[i
])) {
2765 if (os_strncasecmp(t
, text
, len
) == 0)
2769 rl_attempted_completion_over
= 1;
2774 static char ** wpa_cli_completion(const char *text
, int start
, int end
)
2776 char * (*func
)(const char *text
, int state
);
2779 func
= wpa_cli_cmd_gen
;
2780 else if (os_strncasecmp(rl_line_buffer
, "status ", 7) == 0)
2781 func
= wpa_cli_status_gen
;
2783 func
= wpa_cli_dummy_gen
;
2784 return rl_completion_matches(text
, func
);
2788 static void wpa_cli_read_char(int sock
, void *eloop_ctx
, void *sock_ctx
)
2790 rl_callback_read_char();
2794 static void trunc_nl(char *str
)
2797 while (*pos
!= '\0') {
2807 static void readline_cmd_handler(char *cmd
)
2811 while (next_history())
2813 h
= previous_history();
2814 if (h
== NULL
|| os_strcmp(cmd
, h
->line
) != 0)
2819 edit_eof_cb(edit_cb_ctx
);
2823 edit_cmd_cb(edit_cb_ctx
, cmd
);
2827 static char *readline_hfile
= NULL
;
2829 int edit_init(void (*cmd_cb
)(void *ctx
, char *cmd
),
2830 void (*eof_cb
)(void *ctx
),
2836 edit_cmd_cb
= cmd_cb
;
2837 edit_eof_cb
= eof_cb
;
2839 rl_attempted_completion_function
= wpa_cli_completion
;
2840 home
= getenv("HOME");
2842 const char *fname
= ".wpa_cli_history";
2843 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
2844 readline_hfile
= os_malloc(hfile_len
);
2845 if (readline_hfile
) {
2847 res
= os_snprintf(readline_hfile
, hfile_len
, "%s/%s",
2849 if (res
>= 0 && res
< hfile_len
) {
2850 readline_hfile
[hfile_len
- 1] = '\0';
2851 read_history(readline_hfile
);
2852 stifle_history(100);
2857 eloop_register_read_sock(STDIN_FILENO
, wpa_cli_read_char
, NULL
, NULL
);
2859 rl_callback_handler_install("> ", readline_cmd_handler
);
2865 void edit_deinit(void)
2867 rl_callback_handler_remove();
2869 eloop_unregister_read_sock(STDIN_FILENO
);
2871 if (readline_hfile
) {
2872 /* Save command history, excluding lines that may contain
2876 while ((h
= current_history())) {
2878 while (*p
== ' ' || *p
== '\t')
2880 if (cmd_has_sensitive_data(p
)) {
2881 h
= remove_history(where_history());
2891 write_history(readline_hfile
);
2892 os_free(readline_hfile
);
2893 readline_hfile
= NULL
;
2898 void edit_clear_line(void)
2903 void edit_redraw(void)
2909 #endif /* CONFIG_READLINE */
2912 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
2914 char *argv
[max_args
];
2916 argc
= tokenize_cmd(cmd
, argv
);
2918 wpa_request(ctrl_conn
, argc
, argv
);
2922 static void wpa_cli_edit_eof_cb(void *ctx
)
2928 static void wpa_cli_interactive(void)
2931 printf("\nInteractive mode\n\n");
2933 eloop_register_signal_terminate(wpa_cli_eloop_terminate
, NULL
);
2934 edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
, NULL
);
2935 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
2940 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
2941 wpa_cli_close_connection();
2945 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
2947 #ifdef CONFIG_ANSI_C_EXTRA
2948 /* TODO: ANSI C version(?) */
2949 printf("Action processing not supported in ANSI C build.\n");
2950 #else /* CONFIG_ANSI_C_EXTRA */
2954 char buf
[256]; /* note: large enough to fit in unsolicited messages */
2957 fd
= wpa_ctrl_get_fd(ctrl
);
2959 while (!wpa_cli_quit
) {
2962 tv
.tv_sec
= ping_interval
;
2964 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
2965 if (res
< 0 && errno
!= EINTR
) {
2970 if (FD_ISSET(fd
, &rfds
))
2971 wpa_cli_recv_pending(ctrl
, 1);
2973 /* verify that connection is still working */
2974 len
= sizeof(buf
) - 1;
2975 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
2976 wpa_cli_action_cb
) < 0 ||
2977 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
2978 printf("wpa_supplicant did not reply to PING "
2979 "command - exiting\n");
2984 #endif /* CONFIG_ANSI_C_EXTRA */
2988 static void wpa_cli_cleanup(void)
2990 wpa_cli_close_connection();
2992 os_daemonize_terminate(pid_file
);
2994 os_program_deinit();
2997 static void wpa_cli_terminate(int sig
)
3004 static char * wpa_cli_get_default_ifname(void)
3006 char *ifname
= NULL
;
3008 #ifdef CONFIG_CTRL_IFACE_UNIX
3009 struct dirent
*dent
;
3010 DIR *dir
= opendir(ctrl_iface_dir
);
3013 while ((dent
= readdir(dir
))) {
3014 #ifdef _DIRENT_HAVE_D_TYPE
3016 * Skip the file if it is not a socket. Also accept
3017 * DT_UNKNOWN (0) in case the C library or underlying
3018 * file system does not support d_type.
3020 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3022 #endif /* _DIRENT_HAVE_D_TYPE */
3023 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3024 os_strcmp(dent
->d_name
, "..") == 0)
3026 printf("Selected interface '%s'\n", dent
->d_name
);
3027 ifname
= os_strdup(dent
->d_name
);
3031 #endif /* CONFIG_CTRL_IFACE_UNIX */
3033 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3034 char buf
[2048], *pos
;
3036 struct wpa_ctrl
*ctrl
;
3039 ctrl
= wpa_ctrl_open(NULL
);
3043 len
= sizeof(buf
) - 1;
3044 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3047 pos
= os_strchr(buf
, '\n');
3050 ifname
= os_strdup(buf
);
3052 wpa_ctrl_close(ctrl
);
3053 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3059 int main(int argc
, char *argv
[])
3061 int warning_displayed
= 0;
3065 const char *global
= NULL
;
3067 if (os_program_init())
3071 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3076 action_file
= optarg
;
3085 ping_interval
= atoi(optarg
);
3091 printf("%s\n", wpa_cli_version
);
3094 os_free(ctrl_ifname
);
3095 ctrl_ifname
= os_strdup(optarg
);
3098 ctrl_iface_dir
= optarg
;
3109 interactive
= (argc
== optind
) && (action_file
== NULL
);
3112 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3118 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3119 ctrl_conn
= wpa_ctrl_open(NULL
);
3120 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3121 ctrl_conn
= wpa_ctrl_open(global
);
3122 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3123 if (ctrl_conn
== NULL
) {
3124 perror("Failed to connect to wpa_supplicant - "
3131 signal(SIGINT
, wpa_cli_terminate
);
3132 signal(SIGTERM
, wpa_cli_terminate
);
3133 #endif /* _WIN32_WCE */
3135 if (ctrl_ifname
== NULL
)
3136 ctrl_ifname
= wpa_cli_get_default_ifname();
3140 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3141 if (warning_displayed
)
3142 printf("Connection established.\n");
3146 if (!warning_displayed
) {
3147 printf("Could not connect to wpa_supplicant - "
3149 warning_displayed
= 1;
3156 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3157 perror("Failed to connect to wpa_supplicant - "
3163 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3164 wpa_cli_attached
= 1;
3166 printf("Warning: Failed to attach to "
3167 "wpa_supplicant.\n");
3173 if (daemonize
&& os_daemonize(pid_file
))
3177 wpa_cli_interactive();
3178 else if (action_file
)
3179 wpa_cli_action(ctrl_conn
);
3181 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
3183 os_free(ctrl_ifname
);
3190 #else /* CONFIG_CTRL_IFACE */
3191 int main(int argc
, char *argv
[])
3193 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3196 #endif /* CONFIG_CTRL_IFACE */