2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
23 #include "common/wpa_ctrl.h"
24 #include "utils/common.h"
25 #include "utils/eloop.h"
26 #include "utils/edit.h"
27 #include "common/version.h"
29 #include <cutils/properties.h>
33 static const char *wpa_cli_version
=
34 "wpa_cli v" VERSION_STR
"\n"
35 "Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> and contributors";
38 static const char *wpa_cli_license
=
39 "This program is free software. You can distribute it and/or modify it\n"
40 "under the terms of the GNU General Public License version 2.\n"
42 "Alternatively, this software may be distributed under the terms of the\n"
43 "BSD license. See README and COPYING for more details.\n";
45 static const char *wpa_cli_full_license
=
46 "This program is free software; you can redistribute it and/or modify\n"
47 "it under the terms of the GNU General Public License version 2 as\n"
48 "published by the Free Software Foundation.\n"
50 "This program is distributed in the hope that it will be useful,\n"
51 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
52 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
53 "GNU General Public License for more details.\n"
55 "You should have received a copy of the GNU General Public License\n"
56 "along with this program; if not, write to the Free Software\n"
57 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
59 "Alternatively, this software may be distributed under the terms of the\n"
62 "Redistribution and use in source and binary forms, with or without\n"
63 "modification, are permitted provided that the following conditions are\n"
66 "1. Redistributions of source code must retain the above copyright\n"
67 " notice, this list of conditions and the following disclaimer.\n"
69 "2. Redistributions in binary form must reproduce the above copyright\n"
70 " notice, this list of conditions and the following disclaimer in the\n"
71 " documentation and/or other materials provided with the distribution.\n"
73 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
74 " names of its contributors may be used to endorse or promote products\n"
75 " derived from this software without specific prior written permission.\n"
77 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
78 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
79 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
80 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
81 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
82 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
83 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
84 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
85 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
86 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
87 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
90 static struct wpa_ctrl
*ctrl_conn
;
91 static struct wpa_ctrl
*mon_conn
;
92 static int wpa_cli_quit
= 0;
93 static int wpa_cli_attached
= 0;
94 static int wpa_cli_connected
= 0;
95 static int wpa_cli_last_id
= 0;
96 #ifndef CONFIG_CTRL_IFACE_DIR
97 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
98 #endif /* CONFIG_CTRL_IFACE_DIR */
99 static const char *ctrl_iface_dir
= CONFIG_CTRL_IFACE_DIR
;
100 static char *ctrl_ifname
= NULL
;
101 static const char *pid_file
= NULL
;
102 static const char *action_file
= NULL
;
103 static int ping_interval
= 5;
104 static int interactive
= 0;
107 static void print_help(void);
108 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
);
111 static void usage(void)
113 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
114 "[-a<action file>] \\\n"
115 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
117 " -h = help (show this usage text)\n"
118 " -v = shown version information\n"
119 " -a = run in daemon mode executing the action file based on "
122 " -B = run a daemon in the background\n"
123 " default path: " CONFIG_CTRL_IFACE_DIR
"\n"
124 " default interface: first interface found in socket path\n");
129 static int str_starts(const char *src
, const char *match
)
131 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
135 static int wpa_cli_show_event(const char *event
)
139 start
= os_strchr(event
, '>');
145 * Skip BSS added/removed events since they can be relatively frequent
146 * and are likely of not much use for an interactive user.
148 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
149 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
156 static int wpa_cli_open_connection(const char *ifname
, int attach
)
158 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
159 ctrl_conn
= wpa_ctrl_open(ifname
);
160 if (ctrl_conn
== NULL
)
163 if (attach
&& interactive
)
164 mon_conn
= wpa_ctrl_open(ifname
);
167 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
175 if (access(ctrl_iface_dir
, F_OK
) < 0) {
176 cfile
= os_strdup(ifname
);
183 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
184 cfile
= os_malloc(flen
);
187 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
,
189 if (res
< 0 || res
>= flen
) {
195 ctrl_conn
= wpa_ctrl_open(cfile
);
196 if (ctrl_conn
== NULL
) {
201 if (attach
&& interactive
)
202 mon_conn
= wpa_ctrl_open(cfile
);
206 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
209 if (wpa_ctrl_attach(mon_conn
) == 0) {
210 wpa_cli_attached
= 1;
212 eloop_register_read_sock(
213 wpa_ctrl_get_fd(mon_conn
),
214 wpa_cli_mon_receive
, NULL
, NULL
);
216 printf("Warning: Failed to attach to "
217 "wpa_supplicant.\n");
226 static void wpa_cli_close_connection(void)
228 if (ctrl_conn
== NULL
)
231 if (wpa_cli_attached
) {
232 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
233 wpa_cli_attached
= 0;
235 wpa_ctrl_close(ctrl_conn
);
238 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
239 wpa_ctrl_close(mon_conn
);
245 static void wpa_cli_msg_cb(char *msg
, size_t len
)
251 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
257 if (ctrl_conn
== NULL
) {
258 printf("Not connected to wpa_supplicant - command dropped.\n");
261 len
= sizeof(buf
) - 1;
262 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
265 printf("'%s' command timed out.\n", cmd
);
267 } else if (ret
< 0) {
268 printf("'%s' command failed.\n", cmd
);
274 if (interactive
&& len
> 0 && buf
[len
- 1] != '\n')
281 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
283 return _wpa_ctrl_command(ctrl
, cmd
, 1);
287 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
289 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
290 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
294 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
296 return wpa_ctrl_command(ctrl
, "PING");
300 static int wpa_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
302 return wpa_ctrl_command(ctrl
, "RELOG");
306 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
312 ret
= os_snprintf(cmd
, sizeof(cmd
), "NOTE %s", argv
[0]);
313 if (ret
< 0 || (size_t) ret
>= sizeof(cmd
))
315 return wpa_ctrl_command(ctrl
, cmd
);
319 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
321 return wpa_ctrl_command(ctrl
, "MIB");
325 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
327 return wpa_ctrl_command(ctrl
, "PMKSA");
331 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
338 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
340 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
345 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
354 static void wpa_cli_show_variables(void)
356 printf("set variables:\n"
357 " EAPOL::heldPeriod (EAPOL state machine held period, "
359 " EAPOL::authPeriod (EAPOL state machine authentication "
360 "period, in seconds)\n"
361 " EAPOL::startPeriod (EAPOL state machine start period, in "
363 " EAPOL::maxStart (EAPOL state machine maximum start "
365 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
367 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
368 " threshold\n\tpercentage)\n"
369 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
370 "security\n\tassociation in seconds)\n");
374 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
380 wpa_cli_show_variables();
384 if (argc
!= 1 && argc
!= 2) {
385 printf("Invalid SET command: needs two arguments (variable "
386 "name and value)\n");
391 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s ", argv
[0]);
393 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s",
395 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
396 printf("Too long SET command.\n");
399 return wpa_ctrl_command(ctrl
, cmd
);
403 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
409 printf("Invalid GET command: need one argument (variable "
414 res
= os_snprintf(cmd
, sizeof(cmd
), "GET %s", argv
[0]);
415 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
416 printf("Too long GET command.\n");
419 return wpa_ctrl_command(ctrl
, cmd
);
423 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
425 return wpa_ctrl_command(ctrl
, "LOGOFF");
429 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
431 return wpa_ctrl_command(ctrl
, "LOGON");
435 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
438 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
442 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
449 printf("Invalid PREAUTH command: needs one argument "
454 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
455 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
456 printf("Too long PREAUTH command.\n");
459 return wpa_ctrl_command(ctrl
, cmd
);
463 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
469 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
473 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
474 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
475 printf("Too long AP_SCAN command.\n");
478 return wpa_ctrl_command(ctrl
, cmd
);
482 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl
*ctrl
, int argc
,
489 printf("Invalid SCAN_INTERVAL command: needs one argument "
490 "scan_interval value)\n");
493 res
= os_snprintf(cmd
, sizeof(cmd
), "SCAN_INTERVAL %s", argv
[0]);
494 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
495 printf("Too long SCAN_INTERVAL command.\n");
498 return wpa_ctrl_command(ctrl
, cmd
);
502 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl
*ctrl
, int argc
,
509 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
510 "(bss_expire_age value)\n");
513 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_EXPIRE_AGE %s", argv
[0]);
514 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
515 printf("Too long BSS_EXPIRE_AGE command.\n");
518 return wpa_ctrl_command(ctrl
, cmd
);
522 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl
*ctrl
, int argc
,
529 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
530 "(bss_expire_count value)\n");
533 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_EXPIRE_COUNT %s", argv
[0]);
534 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
535 printf("Too long BSS_EXPIRE_COUNT command.\n");
538 return wpa_ctrl_command(ctrl
, cmd
);
542 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
549 printf("Invalid STKSTART command: needs one argument "
550 "(Peer STA MAC address)\n");
554 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
555 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
556 printf("Too long STKSTART command.\n");
559 return wpa_ctrl_command(ctrl
, cmd
);
563 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
569 printf("Invalid FT_DS command: needs one argument "
570 "(Target AP MAC address)\n");
574 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
575 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
576 printf("Too long FT_DS command.\n");
579 return wpa_ctrl_command(ctrl
, cmd
);
583 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
590 return wpa_ctrl_command(ctrl
, "WPS_PBC");
594 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
595 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
596 printf("Too long WPS_PBC command.\n");
599 return wpa_ctrl_command(ctrl
, cmd
);
603 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
609 printf("Invalid WPS_PIN command: need one or two arguments:\n"
610 "- BSSID: use 'any' to select any\n"
611 "- PIN: optional, used only with devices that have no "
617 /* Use dynamically generated PIN (returned as reply) */
618 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
619 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
620 printf("Too long WPS_PIN command.\n");
623 return wpa_ctrl_command(ctrl
, cmd
);
626 /* Use hardcoded PIN from a label */
627 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
628 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
629 printf("Too long WPS_PIN command.\n");
632 return wpa_ctrl_command(ctrl
, cmd
);
636 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
642 if (argc
!= 1 && argc
!= 2) {
643 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
644 "- PIN to be verified\n");
649 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
652 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
654 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
655 printf("Too long WPS_CHECK_PIN command.\n");
658 return wpa_ctrl_command(ctrl
, cmd
);
662 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
665 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
669 #ifdef CONFIG_WPS_OOB
670 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
675 if (argc
!= 3 && argc
!= 4) {
676 printf("Invalid WPS_OOB command: need three or four "
678 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
679 "- PATH: path of OOB device like '/mnt'\n"
680 "- METHOD: OOB method 'pin-e' or 'pin-r', "
682 "- DEV_NAME: (only for NFC) device name like "
688 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
689 argv
[0], argv
[1], argv
[2]);
691 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
692 argv
[0], argv
[1], argv
[2], argv
[3]);
693 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
694 printf("Too long WPS_OOB command.\n");
697 return wpa_ctrl_command(ctrl
, cmd
);
699 #endif /* CONFIG_WPS_OOB */
702 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
708 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
710 else if (argc
== 5 || argc
== 6) {
711 char ssid_hex
[2 * 32 + 1];
712 char key_hex
[2 * 64 + 1];
716 for (i
= 0; i
< 32; i
++) {
717 if (argv
[2][i
] == '\0')
719 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
724 for (i
= 0; i
< 64; i
++) {
725 if (argv
[5][i
] == '\0')
727 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
732 res
= os_snprintf(cmd
, sizeof(cmd
),
733 "WPS_REG %s %s %s %s %s %s",
734 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
737 printf("Invalid WPS_REG command: need two arguments:\n"
738 "- BSSID of the target AP\n"
740 printf("Alternatively, six arguments can be used to "
741 "reconfigure the AP:\n"
742 "- BSSID of the target AP\n"
745 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
746 "- new encr (NONE, WEP, TKIP, CCMP)\n"
751 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
752 printf("Too long WPS_REG command.\n");
755 return wpa_ctrl_command(ctrl
, cmd
);
759 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
766 printf("Invalid WPS_AP_PIN command: needs at least one "
772 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s %s",
773 argv
[0], argv
[1], argv
[2]);
775 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s",
778 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s",
780 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
781 printf("Too long WPS_AP_PIN command.\n");
784 return wpa_ctrl_command(ctrl
, cmd
);
788 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
793 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
794 return wpa_ctrl_command(ctrl
, cmd
);
796 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
800 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
803 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
808 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
815 printf("Invalid WPS_ER_PIN command: need at least two "
817 "- UUID: use 'any' to select any\n"
818 "- PIN: Enrollee PIN\n"
819 "optional: - Enrollee MAC address\n");
824 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
825 argv
[0], argv
[1], argv
[2]);
827 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
829 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
830 printf("Too long WPS_ER_PIN command.\n");
833 return wpa_ctrl_command(ctrl
, cmd
);
837 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
844 printf("Invalid WPS_ER_PBC command: need one argument:\n"
845 "- UUID: Specify the Enrollee\n");
849 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
851 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
852 printf("Too long WPS_ER_PBC command.\n");
855 return wpa_ctrl_command(ctrl
, cmd
);
859 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
866 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
867 "- UUID: specify which AP to use\n"
872 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
874 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
875 printf("Too long WPS_ER_LEARN command.\n");
878 return wpa_ctrl_command(ctrl
, cmd
);
882 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
889 printf("Invalid WPS_ER_SET_CONFIG command: need two "
891 "- UUID: specify which AP to use\n"
892 "- Network configuration id\n");
896 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_SET_CONFIG %s %s",
898 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
899 printf("Too long WPS_ER_SET_CONFIG command.\n");
902 return wpa_ctrl_command(ctrl
, cmd
);
906 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
912 if (argc
== 5 || argc
== 6) {
913 char ssid_hex
[2 * 32 + 1];
914 char key_hex
[2 * 64 + 1];
918 for (i
= 0; i
< 32; i
++) {
919 if (argv
[2][i
] == '\0')
921 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
926 for (i
= 0; i
< 64; i
++) {
927 if (argv
[5][i
] == '\0')
929 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
934 res
= os_snprintf(cmd
, sizeof(cmd
),
935 "WPS_ER_CONFIG %s %s %s %s %s %s",
936 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
939 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
943 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
944 "- new encr (NONE, WEP, TKIP, CCMP)\n"
949 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
950 printf("Too long WPS_ER_CONFIG command.\n");
953 return wpa_ctrl_command(ctrl
, cmd
);
957 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
963 printf("Invalid IBSS_RSN command: needs one argument "
964 "(Peer STA MAC address)\n");
968 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
969 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
970 printf("Too long IBSS_RSN command.\n");
973 return wpa_ctrl_command(ctrl
, cmd
);
977 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
983 printf("Invalid LEVEL command: needs one argument (debug "
987 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
988 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
989 printf("Too long LEVEL command.\n");
992 return wpa_ctrl_command(ctrl
, cmd
);
996 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
998 char cmd
[256], *pos
, *end
;
1002 printf("Invalid IDENTITY command: needs two arguments "
1003 "(network id and identity)\n");
1007 end
= cmd
+ sizeof(cmd
);
1009 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
1011 if (ret
< 0 || ret
>= end
- pos
) {
1012 printf("Too long IDENTITY command.\n");
1016 for (i
= 2; i
< argc
; i
++) {
1017 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1018 if (ret
< 0 || ret
>= end
- pos
) {
1019 printf("Too long IDENTITY command.\n");
1025 return wpa_ctrl_command(ctrl
, cmd
);
1029 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1031 char cmd
[256], *pos
, *end
;
1035 printf("Invalid PASSWORD command: needs two arguments "
1036 "(network id and password)\n");
1040 end
= cmd
+ sizeof(cmd
);
1042 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1044 if (ret
< 0 || ret
>= end
- pos
) {
1045 printf("Too long PASSWORD command.\n");
1049 for (i
= 2; i
< argc
; i
++) {
1050 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1051 if (ret
< 0 || ret
>= end
- pos
) {
1052 printf("Too long PASSWORD command.\n");
1058 return wpa_ctrl_command(ctrl
, cmd
);
1062 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1065 char cmd
[256], *pos
, *end
;
1069 printf("Invalid NEW_PASSWORD command: needs two arguments "
1070 "(network id and password)\n");
1074 end
= cmd
+ sizeof(cmd
);
1076 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1078 if (ret
< 0 || ret
>= end
- pos
) {
1079 printf("Too long NEW_PASSWORD command.\n");
1083 for (i
= 2; i
< argc
; i
++) {
1084 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1085 if (ret
< 0 || ret
>= end
- pos
) {
1086 printf("Too long NEW_PASSWORD command.\n");
1092 return wpa_ctrl_command(ctrl
, cmd
);
1096 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1098 char cmd
[256], *pos
, *end
;
1102 printf("Invalid PIN command: needs two arguments "
1103 "(network id and pin)\n");
1107 end
= cmd
+ sizeof(cmd
);
1109 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1111 if (ret
< 0 || ret
>= end
- pos
) {
1112 printf("Too long PIN command.\n");
1116 for (i
= 2; i
< argc
; i
++) {
1117 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1118 if (ret
< 0 || ret
>= end
- pos
) {
1119 printf("Too long PIN command.\n");
1124 return wpa_ctrl_command(ctrl
, cmd
);
1128 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1130 char cmd
[256], *pos
, *end
;
1134 printf("Invalid OTP command: needs two arguments (network "
1135 "id and password)\n");
1139 end
= cmd
+ sizeof(cmd
);
1141 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1143 if (ret
< 0 || ret
>= end
- pos
) {
1144 printf("Too long OTP command.\n");
1148 for (i
= 2; i
< argc
; i
++) {
1149 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1150 if (ret
< 0 || ret
>= end
- pos
) {
1151 printf("Too long OTP command.\n");
1157 return wpa_ctrl_command(ctrl
, cmd
);
1161 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1164 char cmd
[256], *pos
, *end
;
1168 printf("Invalid PASSPHRASE command: needs two arguments "
1169 "(network id and passphrase)\n");
1173 end
= cmd
+ sizeof(cmd
);
1175 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1177 if (ret
< 0 || ret
>= end
- pos
) {
1178 printf("Too long PASSPHRASE command.\n");
1182 for (i
= 2; i
< argc
; i
++) {
1183 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1184 if (ret
< 0 || ret
>= end
- pos
) {
1185 printf("Too long PASSPHRASE command.\n");
1191 return wpa_ctrl_command(ctrl
, cmd
);
1195 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1197 char cmd
[256], *pos
, *end
;
1201 printf("Invalid BSSID command: needs two arguments (network "
1206 end
= cmd
+ sizeof(cmd
);
1208 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1209 if (ret
< 0 || ret
>= end
- pos
) {
1210 printf("Too long BSSID command.\n");
1214 for (i
= 0; i
< argc
; i
++) {
1215 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1216 if (ret
< 0 || ret
>= end
- pos
) {
1217 printf("Too long BSSID command.\n");
1223 return wpa_ctrl_command(ctrl
, cmd
);
1227 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1230 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1234 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1241 printf("Invalid SELECT_NETWORK command: needs one argument "
1246 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1247 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1249 cmd
[sizeof(cmd
) - 1] = '\0';
1251 return wpa_ctrl_command(ctrl
, cmd
);
1255 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1262 printf("Invalid ENABLE_NETWORK command: needs one argument "
1267 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1268 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1270 cmd
[sizeof(cmd
) - 1] = '\0';
1272 return wpa_ctrl_command(ctrl
, cmd
);
1276 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1283 printf("Invalid DISABLE_NETWORK command: needs one argument "
1288 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1289 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1291 cmd
[sizeof(cmd
) - 1] = '\0';
1293 return wpa_ctrl_command(ctrl
, cmd
);
1297 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1300 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1304 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1311 printf("Invalid REMOVE_NETWORK command: needs one argument "
1316 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1317 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1319 cmd
[sizeof(cmd
) - 1] = '\0';
1321 return wpa_ctrl_command(ctrl
, cmd
);
1325 static void wpa_cli_show_network_variables(void)
1327 printf("set_network variables:\n"
1328 " ssid (network name, SSID)\n"
1329 " psk (WPA passphrase or pre-shared key)\n"
1330 " key_mgmt (key management protocol)\n"
1331 " identity (EAP identity)\n"
1332 " password (EAP password)\n"
1335 "Note: Values are entered in the same format as the "
1336 "configuration file is using,\n"
1337 "i.e., strings values need to be inside double quotation "
1339 "For example: set_network 1 ssid \"network name\"\n"
1341 "Please see wpa_supplicant.conf documentation for full list "
1342 "of\navailable variables.\n");
1346 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1353 wpa_cli_show_network_variables();
1358 printf("Invalid SET_NETWORK command: needs three arguments\n"
1359 "(network id, variable name, and value)\n");
1363 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1364 argv
[0], argv
[1], argv
[2]);
1365 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1366 printf("Too long SET_NETWORK command.\n");
1369 return wpa_ctrl_command(ctrl
, cmd
);
1373 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1380 wpa_cli_show_network_variables();
1385 printf("Invalid GET_NETWORK command: needs two arguments\n"
1386 "(network id and variable name)\n");
1390 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1392 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1393 printf("Too long GET_NETWORK command.\n");
1396 return wpa_ctrl_command(ctrl
, cmd
);
1400 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1403 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1407 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1410 return wpa_ctrl_command(ctrl
, "RECONNECT");
1414 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1417 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1421 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1423 return wpa_ctrl_command(ctrl
, "SCAN");
1427 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1430 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1434 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1440 printf("Invalid BSS command: need one argument (index or "
1445 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1446 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1448 cmd
[sizeof(cmd
) - 1] = '\0';
1450 return wpa_ctrl_command(ctrl
, cmd
);
1454 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1460 if (argc
< 1 || argc
> 2) {
1461 printf("Invalid GET_CAPABILITY command: need either one or "
1466 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1467 printf("Invalid GET_CAPABILITY command: second argument, "
1468 "if any, must be 'strict'\n");
1472 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1473 (argc
== 2) ? " strict" : "");
1474 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1476 cmd
[sizeof(cmd
) - 1] = '\0';
1478 return wpa_ctrl_command(ctrl
, cmd
);
1482 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1484 printf("Available interfaces:\n");
1485 return wpa_ctrl_command(ctrl
, "INTERFACES");
1489 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1492 wpa_cli_list_interfaces(ctrl
);
1496 wpa_cli_close_connection();
1497 os_free(ctrl_ifname
);
1498 ctrl_ifname
= os_strdup(argv
[0]);
1500 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1501 printf("Connected to interface '%s.\n", ctrl_ifname
);
1503 printf("Could not connect to interface '%s' - re-trying\n",
1510 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1513 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1517 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1520 return wpa_ctrl_command(ctrl
, "TERMINATE");
1524 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1531 printf("Invalid INTERFACE_ADD command: needs at least one "
1532 "argument (interface name)\n"
1533 "All arguments: ifname confname driver ctrl_interface "
1534 "driver_param bridge_name\n");
1539 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1540 * <driver_param>TAB<bridge_name>
1542 res
= os_snprintf(cmd
, sizeof(cmd
),
1543 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1545 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1546 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1547 argc
> 5 ? argv
[5] : "");
1548 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1550 cmd
[sizeof(cmd
) - 1] = '\0';
1551 return wpa_ctrl_command(ctrl
, cmd
);
1555 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1562 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1563 "(interface name)\n");
1567 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1568 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1570 cmd
[sizeof(cmd
) - 1] = '\0';
1571 return wpa_ctrl_command(ctrl
, cmd
);
1575 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1578 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1583 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1587 printf("Invalid 'sta' command - exactly one argument, STA "
1588 "address, is required.\n");
1591 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1592 return wpa_ctrl_command(ctrl
, buf
);
1596 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1597 char *addr
, size_t addr_len
)
1599 char buf
[4096], *pos
;
1603 if (ctrl_conn
== NULL
) {
1604 printf("Not connected to hostapd - command dropped.\n");
1607 len
= sizeof(buf
) - 1;
1608 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1611 printf("'%s' command timed out.\n", cmd
);
1613 } else if (ret
< 0) {
1614 printf("'%s' command failed.\n", cmd
);
1619 if (memcmp(buf
, "FAIL", 4) == 0)
1624 while (*pos
!= '\0' && *pos
!= '\n')
1627 os_strlcpy(addr
, buf
, addr_len
);
1632 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1634 char addr
[32], cmd
[64];
1636 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1639 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1640 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1644 #endif /* CONFIG_AP */
1647 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1649 return wpa_ctrl_command(ctrl
, "SUSPEND");
1653 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1655 return wpa_ctrl_command(ctrl
, "RESUME");
1659 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1661 return wpa_ctrl_command(ctrl
, "DROP_SA");
1665 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1671 printf("Invalid ROAM command: needs one argument "
1672 "(target AP's BSSID)\n");
1676 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
1677 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1678 printf("Too long ROAM command.\n");
1681 return wpa_ctrl_command(ctrl
, cmd
);
1687 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1693 return wpa_ctrl_command(ctrl
, "P2P_FIND");
1696 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
1699 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
1700 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1702 cmd
[sizeof(cmd
) - 1] = '\0';
1703 return wpa_ctrl_command(ctrl
, cmd
);
1707 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1710 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1714 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1721 printf("Invalid P2P_CONNECT command: needs at least two "
1722 "arguments (address and pbc/PIN)\n");
1727 res
= os_snprintf(cmd
, sizeof(cmd
),
1728 "P2P_CONNECT %s %s %s %s %s",
1729 argv
[0], argv
[1], argv
[2], argv
[3],
1732 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
1733 argv
[0], argv
[1], argv
[2], argv
[3]);
1735 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
1736 argv
[0], argv
[1], argv
[2]);
1738 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
1740 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1742 cmd
[sizeof(cmd
) - 1] = '\0';
1743 return wpa_ctrl_command(ctrl
, cmd
);
1747 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1754 return wpa_ctrl_command(ctrl
, "P2P_LISTEN");
1756 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_LISTEN %s", argv
[0]);
1757 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1759 cmd
[sizeof(cmd
) - 1] = '\0';
1760 return wpa_ctrl_command(ctrl
, cmd
);
1764 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1771 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1772 "(interface name)\n");
1776 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
1777 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1779 cmd
[sizeof(cmd
) - 1] = '\0';
1780 return wpa_ctrl_command(ctrl
, cmd
);
1784 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1791 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
1794 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s %s",
1797 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s",
1799 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1801 cmd
[sizeof(cmd
) - 1] = '\0';
1802 return wpa_ctrl_command(ctrl
, cmd
);
1806 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1813 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1814 "(address and config method\n"
1815 "(display, keypad, or pbc)\n");
1819 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
1821 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1823 cmd
[sizeof(cmd
) - 1] = '\0';
1824 return wpa_ctrl_command(ctrl
, cmd
);
1828 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1831 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1835 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1841 if (argc
!= 2 && argc
!= 4) {
1842 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1843 "arguments (address and TLVs) or four arguments "
1844 "(address, \"upnp\", version, search target "
1850 res
= os_snprintf(cmd
, sizeof(cmd
),
1851 "P2P_SERV_DISC_REQ %s %s %s %s",
1852 argv
[0], argv
[1], argv
[2], argv
[3]);
1854 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
1856 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1858 cmd
[sizeof(cmd
) - 1] = '\0';
1859 return wpa_ctrl_command(ctrl
, cmd
);
1863 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1864 int argc
, char *argv
[])
1870 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1871 "argument (pending request identifier)\n");
1875 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
1877 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1879 cmd
[sizeof(cmd
) - 1] = '\0';
1880 return wpa_ctrl_command(ctrl
, cmd
);
1884 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1891 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1892 "arguments (freq, address, dialog token, and TLVs)\n");
1896 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1897 argv
[0], argv
[1], argv
[2], argv
[3]);
1898 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1900 cmd
[sizeof(cmd
) - 1] = '\0';
1901 return wpa_ctrl_command(ctrl
, cmd
);
1905 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1908 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1912 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1913 int argc
, char *argv
[])
1919 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1920 "argument (external processing: 0/1)\n");
1924 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
1926 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1928 cmd
[sizeof(cmd
) - 1] = '\0';
1929 return wpa_ctrl_command(ctrl
, cmd
);
1933 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1936 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1940 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1946 if (argc
!= 3 && argc
!= 4) {
1947 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1953 res
= os_snprintf(cmd
, sizeof(cmd
),
1954 "P2P_SERVICE_ADD %s %s %s %s",
1955 argv
[0], argv
[1], argv
[2], argv
[3]);
1957 res
= os_snprintf(cmd
, sizeof(cmd
),
1958 "P2P_SERVICE_ADD %s %s %s",
1959 argv
[0], argv
[1], argv
[2]);
1960 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1962 cmd
[sizeof(cmd
) - 1] = '\0';
1963 return wpa_ctrl_command(ctrl
, cmd
);
1967 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1973 if (argc
!= 2 && argc
!= 3) {
1974 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1980 res
= os_snprintf(cmd
, sizeof(cmd
),
1981 "P2P_SERVICE_DEL %s %s %s",
1982 argv
[0], argv
[1], argv
[2]);
1984 res
= os_snprintf(cmd
, sizeof(cmd
),
1985 "P2P_SERVICE_DEL %s %s",
1987 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1989 cmd
[sizeof(cmd
) - 1] = '\0';
1990 return wpa_ctrl_command(ctrl
, cmd
);
1994 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1995 int argc
, char *argv
[])
2001 printf("Invalid P2P_REJECT command: needs one argument "
2002 "(peer address)\n");
2006 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
2007 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2009 cmd
[sizeof(cmd
) - 1] = '\0';
2010 return wpa_ctrl_command(ctrl
, cmd
);
2014 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
2015 int argc
, char *argv
[])
2021 printf("Invalid P2P_INVITE command: needs at least one "
2027 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
2028 argv
[0], argv
[1], argv
[2]);
2030 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
2033 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
2034 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2036 cmd
[sizeof(cmd
) - 1] = '\0';
2037 return wpa_ctrl_command(ctrl
, cmd
);
2041 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2045 printf("Invalid 'p2p_peer' command - exactly one argument, "
2046 "P2P peer device address, is required.\n");
2049 os_snprintf(buf
, sizeof(buf
), "P2P_PEER %s", argv
[0]);
2050 return wpa_ctrl_command(ctrl
, buf
);
2054 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
2055 char *addr
, size_t addr_len
,
2058 char buf
[4096], *pos
;
2062 if (ctrl_conn
== NULL
)
2064 len
= sizeof(buf
) - 1;
2065 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
2068 printf("'%s' command timed out.\n", cmd
);
2070 } else if (ret
< 0) {
2071 printf("'%s' command failed.\n", cmd
);
2076 if (memcmp(buf
, "FAIL", 4) == 0)
2080 while (*pos
!= '\0' && *pos
!= '\n')
2083 os_strlcpy(addr
, buf
, addr_len
);
2084 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2085 printf("%s\n", addr
);
2090 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2092 char addr
[32], cmd
[64];
2095 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2097 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2098 addr
, sizeof(addr
), discovered
))
2101 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2102 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2109 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2115 printf("Invalid P2P_SET command: needs two arguments (field, "
2120 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
2121 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2123 cmd
[sizeof(cmd
) - 1] = '\0';
2124 return wpa_ctrl_command(ctrl
, cmd
);
2128 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2130 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2134 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2137 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2141 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
2148 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2149 "(peer address)\n");
2153 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_UNAUTHORIZE %s", argv
[0]);
2155 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2158 cmd
[sizeof(cmd
) - 1] = '\0';
2159 return wpa_ctrl_command(ctrl
, cmd
);
2163 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2169 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2170 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2171 "(preferred duration, interval; in microsecods).\n"
2172 "Optional second pair can be used to provide "
2173 "acceptable values.\n");
2178 res
= os_snprintf(cmd
, sizeof(cmd
),
2179 "P2P_PRESENCE_REQ %s %s %s %s",
2180 argv
[0], argv
[1], argv
[2], argv
[3]);
2182 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2185 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
2186 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2188 cmd
[sizeof(cmd
) - 1] = '\0';
2189 return wpa_ctrl_command(ctrl
, cmd
);
2193 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2199 if (argc
!= 0 && argc
!= 2) {
2200 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2201 "(availability period, availability interval; in "
2203 "Extended Listen Timing can be cancelled with this "
2204 "command when used without parameters.\n");
2209 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2212 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2213 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2215 cmd
[sizeof(cmd
) - 1] = '\0';
2216 return wpa_ctrl_command(ctrl
, cmd
);
2219 #endif /* CONFIG_P2P */
2222 #ifdef CONFIG_INTERWORKING
2223 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2226 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
2230 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2233 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
2237 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2243 printf("Invalid ANQP_GET command: needs two arguments "
2244 "(addr and info id list)\n");
2248 res
= os_snprintf(cmd
, sizeof(cmd
), "ANQP_GET %s %s",
2250 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2252 cmd
[sizeof(cmd
) - 1] = '\0';
2253 return wpa_ctrl_command(ctrl
, cmd
);
2255 #endif /* CONFIG_INTERWORKING */
2258 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2265 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2266 "(0/1 = disable/enable automatic reconnection)\n");
2269 res
= os_snprintf(cmd
, sizeof(cmd
), "STA_AUTOCONNECT %s", argv
[0]);
2270 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2271 printf("Too long STA_AUTOCONNECT command.\n");
2274 return wpa_ctrl_command(ctrl
, cmd
);
2278 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2285 printf("Invalid TDLS_DISCOVER command: needs one argument "
2286 "(Peer STA MAC address)\n");
2290 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_DISCOVER %s", argv
[0]);
2291 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2292 printf("Too long TDLS_DISCOVER command.\n");
2295 return wpa_ctrl_command(ctrl
, cmd
);
2299 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2306 printf("Invalid TDLS_SETUP command: needs one argument "
2307 "(Peer STA MAC address)\n");
2311 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_SETUP %s", argv
[0]);
2312 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2313 printf("Too long TDLS_SETUP command.\n");
2316 return wpa_ctrl_command(ctrl
, cmd
);
2320 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2327 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2328 "(Peer STA MAC address)\n");
2332 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_TEARDOWN %s", argv
[0]);
2333 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2334 printf("Too long TDLS_TEARDOWN command.\n");
2337 return wpa_ctrl_command(ctrl
, cmd
);
2341 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2344 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2348 enum wpa_cli_cmd_flags
{
2349 cli_cmd_flag_none
= 0x00,
2350 cli_cmd_flag_sensitive
= 0x01
2353 struct wpa_cli_cmd
{
2355 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2356 enum wpa_cli_cmd_flags flags
;
2360 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2361 { "status", wpa_cli_cmd_status
,
2363 "[verbose] = get current WPA/EAPOL/EAP status" },
2364 { "ping", wpa_cli_cmd_ping
,
2366 "= pings wpa_supplicant" },
2367 { "relog", wpa_cli_cmd_relog
,
2369 "= re-open log-file (allow rolling logs)" },
2370 { "note", wpa_cli_cmd_note
,
2372 "<text> = add a note to wpa_supplicant debug log" },
2373 { "mib", wpa_cli_cmd_mib
,
2375 "= get MIB variables (dot1x, dot11)" },
2376 { "help", wpa_cli_cmd_help
,
2378 "= show this usage help" },
2379 { "interface", wpa_cli_cmd_interface
,
2381 "[ifname] = show interfaces/select interface" },
2382 { "level", wpa_cli_cmd_level
,
2384 "<debug level> = change debug level" },
2385 { "license", wpa_cli_cmd_license
,
2387 "= show full wpa_cli license" },
2388 { "quit", wpa_cli_cmd_quit
,
2391 { "set", wpa_cli_cmd_set
,
2393 "= set variables (shows list of variables when run without "
2395 { "get", wpa_cli_cmd_get
,
2397 "<name> = get information" },
2398 { "logon", wpa_cli_cmd_logon
,
2400 "= IEEE 802.1X EAPOL state machine logon" },
2401 { "logoff", wpa_cli_cmd_logoff
,
2403 "= IEEE 802.1X EAPOL state machine logoff" },
2404 { "pmksa", wpa_cli_cmd_pmksa
,
2406 "= show PMKSA cache" },
2407 { "reassociate", wpa_cli_cmd_reassociate
,
2409 "= force reassociation" },
2410 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2412 "<BSSID> = force preauthentication" },
2413 { "identity", wpa_cli_cmd_identity
,
2415 "<network id> <identity> = configure identity for an SSID" },
2416 { "password", wpa_cli_cmd_password
,
2417 cli_cmd_flag_sensitive
,
2418 "<network id> <password> = configure password for an SSID" },
2419 { "new_password", wpa_cli_cmd_new_password
,
2420 cli_cmd_flag_sensitive
,
2421 "<network id> <password> = change password for an SSID" },
2422 { "pin", wpa_cli_cmd_pin
,
2423 cli_cmd_flag_sensitive
,
2424 "<network id> <pin> = configure pin for an SSID" },
2425 { "otp", wpa_cli_cmd_otp
,
2426 cli_cmd_flag_sensitive
,
2427 "<network id> <password> = configure one-time-password for an SSID"
2429 { "passphrase", wpa_cli_cmd_passphrase
,
2430 cli_cmd_flag_sensitive
,
2431 "<network id> <passphrase> = configure private key passphrase\n"
2433 { "bssid", wpa_cli_cmd_bssid
,
2435 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2436 { "list_networks", wpa_cli_cmd_list_networks
,
2438 "= list configured networks" },
2439 { "select_network", wpa_cli_cmd_select_network
,
2441 "<network id> = select a network (disable others)" },
2442 { "enable_network", wpa_cli_cmd_enable_network
,
2444 "<network id> = enable a network" },
2445 { "disable_network", wpa_cli_cmd_disable_network
,
2447 "<network id> = disable a network" },
2448 { "add_network", wpa_cli_cmd_add_network
,
2450 "= add a network" },
2451 { "remove_network", wpa_cli_cmd_remove_network
,
2453 "<network id> = remove a network" },
2454 { "set_network", wpa_cli_cmd_set_network
,
2455 cli_cmd_flag_sensitive
,
2456 "<network id> <variable> <value> = set network variables (shows\n"
2457 " list of variables when run without arguments)" },
2458 { "get_network", wpa_cli_cmd_get_network
,
2460 "<network id> <variable> = get network variables" },
2461 { "save_config", wpa_cli_cmd_save_config
,
2463 "= save the current configuration" },
2464 { "disconnect", wpa_cli_cmd_disconnect
,
2466 "= disconnect and wait for reassociate/reconnect command before\n"
2468 { "reconnect", wpa_cli_cmd_reconnect
,
2470 "= like reassociate, but only takes effect if already disconnected"
2472 { "scan", wpa_cli_cmd_scan
,
2474 "= request new BSS scan" },
2475 { "scan_results", wpa_cli_cmd_scan_results
,
2477 "= get latest scan results" },
2478 { "bss", wpa_cli_cmd_bss
,
2480 "<<idx> | <bssid>> = get detailed scan result info" },
2481 { "get_capability", wpa_cli_cmd_get_capability
,
2483 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2484 { "reconfigure", wpa_cli_cmd_reconfigure
,
2486 "= force wpa_supplicant to re-read its configuration file" },
2487 { "terminate", wpa_cli_cmd_terminate
,
2489 "= terminate wpa_supplicant" },
2490 { "interface_add", wpa_cli_cmd_interface_add
,
2492 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2493 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2495 { "interface_remove", wpa_cli_cmd_interface_remove
,
2497 "<ifname> = removes the interface" },
2498 { "interface_list", wpa_cli_cmd_interface_list
,
2500 "= list available interfaces" },
2501 { "ap_scan", wpa_cli_cmd_ap_scan
,
2503 "<value> = set ap_scan parameter" },
2504 { "scan_interval", wpa_cli_cmd_scan_interval
,
2506 "<value> = set scan_interval parameter (in seconds)" },
2507 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
,
2509 "<value> = set BSS expiration age parameter" },
2510 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
,
2512 "<value> = set BSS expiration scan count parameter" },
2513 { "stkstart", wpa_cli_cmd_stkstart
,
2515 "<addr> = request STK negotiation with <addr>" },
2516 { "ft_ds", wpa_cli_cmd_ft_ds
,
2518 "<addr> = request over-the-DS FT with <addr>" },
2519 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
2521 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2522 { "wps_pin", wpa_cli_cmd_wps_pin
,
2523 cli_cmd_flag_sensitive
,
2524 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2526 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
2527 cli_cmd_flag_sensitive
,
2528 "<PIN> = verify PIN checksum" },
2529 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
2530 "Cancels the pending WPS operation" },
2531 #ifdef CONFIG_WPS_OOB
2532 { "wps_oob", wpa_cli_cmd_wps_oob
,
2533 cli_cmd_flag_sensitive
,
2534 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2535 #endif /* CONFIG_WPS_OOB */
2536 { "wps_reg", wpa_cli_cmd_wps_reg
,
2537 cli_cmd_flag_sensitive
,
2538 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2539 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
,
2540 cli_cmd_flag_sensitive
,
2541 "[params..] = enable/disable AP PIN" },
2542 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
2544 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2545 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
2547 "= stop Wi-Fi Protected Setup External Registrar" },
2548 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
2549 cli_cmd_flag_sensitive
,
2550 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2551 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
2553 "<UUID> = accept an Enrollee PBC using External Registrar" },
2554 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
2555 cli_cmd_flag_sensitive
,
2556 "<UUID> <PIN> = learn AP configuration" },
2557 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
,
2559 "<UUID> <network id> = set AP configuration for enrolling" },
2560 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
2561 cli_cmd_flag_sensitive
,
2562 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2563 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
2565 "<addr> = request RSN authentication with <addr> in IBSS" },
2567 { "sta", wpa_cli_cmd_sta
,
2569 "<addr> = get information about an associated station (AP)" },
2570 { "all_sta", wpa_cli_cmd_all_sta
,
2572 "= get information about all associated stations (AP)" },
2573 #endif /* CONFIG_AP */
2574 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
2575 "= notification of suspend/hibernate" },
2576 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
2577 "= notification of resume/thaw" },
2578 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
2579 "= drop SA without deauth/disassoc (test command)" },
2580 { "roam", wpa_cli_cmd_roam
,
2582 "<addr> = roam to the specified BSS" },
2584 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
2585 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2586 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
2587 "= stop P2P Devices search" },
2588 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
2589 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2590 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
2591 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2592 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
2593 "<ifname> = remove P2P group interface (terminate group if GO)" },
2594 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
2595 "= add a new P2P group (local end as GO)" },
2596 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
2597 "<addr> <method> = request provisioning discovery" },
2598 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
2600 "= get the passphrase for a group (GO only)" },
2601 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2603 "<addr> <TLVs> = schedule service discovery request" },
2604 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2606 "<id> = cancel pending service discovery request" },
2607 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2609 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2610 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2612 "= indicate change in local services" },
2613 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2615 "<external> = set external processing of service discovery" },
2616 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2618 "= remove all stored service entries" },
2619 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2621 "<bonjour|upnp> <query|version> <response|service> = add a local "
2623 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2625 "<bonjour|upnp> <query|version> [|service] = remove a local "
2627 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2629 "<addr> = reject connection attempts from a specific peer" },
2630 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
2632 "<cmd> [peer=addr] = invite peer" },
2633 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
2634 "[discovered] = list known (optionally, only fully discovered) P2P "
2636 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
2637 "<address> = show information about known P2P peer" },
2638 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
2639 "<field> <value> = set a P2P parameter" },
2640 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
2641 "= flush P2P state" },
2642 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
2643 "= cancel P2P group formation" },
2644 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
, cli_cmd_flag_none
,
2645 "<address> = unauthorize a peer" },
2646 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
2647 "[<duration> <interval>] [<duration> <interval>] = request GO "
2649 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
2650 "[<period> <interval>] = set extended listen timing" },
2651 #endif /* CONFIG_P2P */
2653 #ifdef CONFIG_INTERWORKING
2654 { "fetch_anqp", wpa_cli_cmd_fetch_anqp
, cli_cmd_flag_none
,
2655 "= fetch ANQP information for all APs" },
2656 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp
, cli_cmd_flag_none
,
2657 "= stop fetch_anqp operation" },
2658 { "anqp_get", wpa_cli_cmd_anqp_get
, cli_cmd_flag_none
,
2659 "<addr> <info id>[,<info id>]... = request ANQP information" },
2660 #endif /* CONFIG_INTERWORKING */
2661 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
2662 "<0/1> = disable/enable automatic reconnection" },
2663 { "tdls_discover", wpa_cli_cmd_tdls_discover
,
2665 "<addr> = request TDLS discovery with <addr>" },
2666 { "tdls_setup", wpa_cli_cmd_tdls_setup
,
2668 "<addr> = request TDLS setup with <addr>" },
2669 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
,
2671 "<addr> = tear down TDLS with <addr>" },
2672 { "signal_poll", wpa_cli_cmd_signal_poll
,
2674 "= get signal parameters" },
2675 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2680 * Prints command usage, lines are padded with the specified string.
2682 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2687 printf("%s%s ", pad
, cmd
->cmd
);
2688 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2697 static void print_help(void)
2700 printf("commands:\n");
2701 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
2702 print_cmd_help(&wpa_cli_commands
[n
], " ");
2706 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
2708 const char *c
, *delim
;
2712 delim
= os_strchr(cmd
, ' ');
2716 len
= os_strlen(cmd
);
2718 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2719 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2720 return (wpa_cli_commands
[n
].flags
&
2721 cli_cmd_flag_sensitive
);
2727 static char ** wpa_list_cmd_list(void)
2732 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
2733 res
= os_zalloc(count
* sizeof(char *));
2737 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2738 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
2747 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
2752 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2753 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
2755 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
2765 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
2771 end
= os_strchr(str
, ' ');
2772 if (end
== NULL
|| str
+ pos
< end
)
2773 return wpa_list_cmd_list();
2775 cmd
= os_malloc(pos
+ 1);
2778 os_memcpy(cmd
, str
, pos
);
2779 cmd
[end
- str
] = '\0';
2780 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
2786 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2788 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2793 cmd
= wpa_cli_commands
;
2795 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2798 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2799 /* we have an exact match */
2809 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
2810 cmd
= wpa_cli_commands
;
2812 if (os_strncasecmp(cmd
->cmd
, argv
[0],
2813 os_strlen(argv
[0])) == 0) {
2814 printf(" %s", cmd
->cmd
);
2820 } else if (count
== 0) {
2821 printf("Unknown command '%s'\n", argv
[0]);
2824 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
2831 static int str_match(const char *a
, const char *b
)
2833 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
2837 static int wpa_cli_exec(const char *program
, const char *arg1
,
2845 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
2846 cmd
= os_malloc(len
);
2849 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
2850 if (res
< 0 || (size_t) res
>= len
) {
2854 cmd
[len
- 1] = '\0';
2856 if (system(cmd
) < 0)
2858 #endif /* _WIN32_WCE */
2865 static void wpa_cli_action_process(const char *msg
)
2868 char *copy
= NULL
, *id
, *pos2
;
2873 pos
= os_strchr(pos
, '>');
2880 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
2882 os_unsetenv("WPA_ID");
2883 os_unsetenv("WPA_ID_STR");
2884 os_unsetenv("WPA_CTRL_DIR");
2886 pos
= os_strstr(pos
, "[id=");
2888 copy
= os_strdup(pos
+ 4);
2892 while (*pos2
&& *pos2
!= ' ')
2896 os_setenv("WPA_ID", id
, 1);
2897 while (*pos2
&& *pos2
!= '=')
2902 while (*pos2
&& *pos2
!= ']')
2905 os_setenv("WPA_ID_STR", id
, 1);
2909 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
2911 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
2912 wpa_cli_connected
= 1;
2913 wpa_cli_last_id
= new_id
;
2914 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
2916 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
2917 if (wpa_cli_connected
) {
2918 wpa_cli_connected
= 0;
2919 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
2921 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
2922 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2923 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
2924 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2925 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
2926 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2927 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
2928 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2929 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
2930 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2931 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
2932 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2933 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
2934 printf("wpa_supplicant is terminating - stop monitoring\n");
2940 #ifndef CONFIG_ANSI_C_EXTRA
2941 static void wpa_cli_action_cb(char *msg
, size_t len
)
2943 wpa_cli_action_process(msg
);
2945 #endif /* CONFIG_ANSI_C_EXTRA */
2948 static void wpa_cli_reconnect(void)
2950 wpa_cli_close_connection();
2951 wpa_cli_open_connection(ctrl_ifname
, 1);
2955 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
2957 if (ctrl_conn
== NULL
) {
2958 wpa_cli_reconnect();
2961 while (wpa_ctrl_pending(ctrl
) > 0) {
2963 size_t len
= sizeof(buf
) - 1;
2964 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
2967 wpa_cli_action_process(buf
);
2969 if (wpa_cli_show_event(buf
)) {
2971 printf("\r%s\n", buf
);
2976 printf("Could not read pending message.\n");
2981 if (wpa_ctrl_pending(ctrl
) < 0) {
2982 printf("Connection to wpa_supplicant lost - trying to "
2984 wpa_cli_reconnect();
2990 static int tokenize_cmd(char *cmd
, char *argv
[])
3003 if (argc
== max_args
)
3006 char *pos2
= os_strrchr(pos
, '"');
3010 while (*pos
!= '\0' && *pos
!= ' ')
3020 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
3022 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3023 printf("Connection to wpa_supplicant lost - trying to "
3025 wpa_cli_close_connection();
3028 wpa_cli_reconnect();
3029 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3033 static void wpa_cli_eloop_terminate(int sig
, void *signal_ctx
)
3039 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
3041 wpa_cli_recv_pending(mon_conn
, 0);
3045 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
3047 char *argv
[max_args
];
3049 argc
= tokenize_cmd(cmd
, argv
);
3051 wpa_request(ctrl_conn
, argc
, argv
);
3055 static void wpa_cli_edit_eof_cb(void *ctx
)
3061 static void wpa_cli_interactive(void)
3063 char *home
, *hfile
= NULL
;
3065 printf("\nInteractive mode\n\n");
3067 home
= getenv("HOME");
3069 const char *fname
= ".wpa_cli_history";
3070 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
3071 hfile
= os_malloc(hfile_len
);
3073 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
3076 eloop_register_signal_terminate(wpa_cli_eloop_terminate
, NULL
);
3077 edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
3078 wpa_cli_edit_completion_cb
, NULL
, hfile
);
3079 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3083 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3085 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3086 wpa_cli_close_connection();
3090 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3092 #ifdef CONFIG_ANSI_C_EXTRA
3093 /* TODO: ANSI C version(?) */
3094 printf("Action processing not supported in ANSI C build.\n");
3095 #else /* CONFIG_ANSI_C_EXTRA */
3099 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3102 fd
= wpa_ctrl_get_fd(ctrl
);
3104 while (!wpa_cli_quit
) {
3107 tv
.tv_sec
= ping_interval
;
3109 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3110 if (res
< 0 && errno
!= EINTR
) {
3115 if (FD_ISSET(fd
, &rfds
))
3116 wpa_cli_recv_pending(ctrl
, 1);
3118 /* verify that connection is still working */
3119 len
= sizeof(buf
) - 1;
3120 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3121 wpa_cli_action_cb
) < 0 ||
3122 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3123 printf("wpa_supplicant did not reply to PING "
3124 "command - exiting\n");
3129 #endif /* CONFIG_ANSI_C_EXTRA */
3133 static void wpa_cli_cleanup(void)
3135 wpa_cli_close_connection();
3137 os_daemonize_terminate(pid_file
);
3139 os_program_deinit();
3142 static void wpa_cli_terminate(int sig
)
3149 static char * wpa_cli_get_default_ifname(void)
3151 char *ifname
= NULL
;
3153 #ifdef CONFIG_CTRL_IFACE_UNIX
3154 struct dirent
*dent
;
3155 DIR *dir
= opendir(ctrl_iface_dir
);
3158 char ifprop
[PROPERTY_VALUE_MAX
];
3159 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3160 ifname
= os_strdup(ifprop
);
3161 printf("Using interface '%s'\n", ifname
);
3164 #endif /* ANDROID */
3167 while ((dent
= readdir(dir
))) {
3168 #ifdef _DIRENT_HAVE_D_TYPE
3170 * Skip the file if it is not a socket. Also accept
3171 * DT_UNKNOWN (0) in case the C library or underlying
3172 * file system does not support d_type.
3174 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3176 #endif /* _DIRENT_HAVE_D_TYPE */
3177 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3178 os_strcmp(dent
->d_name
, "..") == 0)
3180 printf("Selected interface '%s'\n", dent
->d_name
);
3181 ifname
= os_strdup(dent
->d_name
);
3185 #endif /* CONFIG_CTRL_IFACE_UNIX */
3187 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3188 char buf
[2048], *pos
;
3190 struct wpa_ctrl
*ctrl
;
3193 ctrl
= wpa_ctrl_open(NULL
);
3197 len
= sizeof(buf
) - 1;
3198 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3201 pos
= os_strchr(buf
, '\n');
3204 ifname
= os_strdup(buf
);
3206 wpa_ctrl_close(ctrl
);
3207 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3213 int main(int argc
, char *argv
[])
3215 int warning_displayed
= 0;
3219 const char *global
= NULL
;
3221 if (os_program_init())
3225 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3230 action_file
= optarg
;
3239 ping_interval
= atoi(optarg
);
3245 printf("%s\n", wpa_cli_version
);
3248 os_free(ctrl_ifname
);
3249 ctrl_ifname
= os_strdup(optarg
);
3252 ctrl_iface_dir
= optarg
;
3263 interactive
= (argc
== optind
) && (action_file
== NULL
);
3266 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3272 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3273 ctrl_conn
= wpa_ctrl_open(NULL
);
3274 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3275 ctrl_conn
= wpa_ctrl_open(global
);
3276 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3277 if (ctrl_conn
== NULL
) {
3278 perror("Failed to connect to wpa_supplicant - "
3285 signal(SIGINT
, wpa_cli_terminate
);
3286 signal(SIGTERM
, wpa_cli_terminate
);
3287 #endif /* _WIN32_WCE */
3289 if (ctrl_ifname
== NULL
)
3290 ctrl_ifname
= wpa_cli_get_default_ifname();
3294 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3295 if (warning_displayed
)
3296 printf("Connection established.\n");
3300 if (!warning_displayed
) {
3301 printf("Could not connect to wpa_supplicant - "
3303 warning_displayed
= 1;
3310 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3311 perror("Failed to connect to wpa_supplicant - "
3317 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3318 wpa_cli_attached
= 1;
3320 printf("Warning: Failed to attach to "
3321 "wpa_supplicant.\n");
3327 if (daemonize
&& os_daemonize(pid_file
))
3331 wpa_cli_interactive();
3332 else if (action_file
)
3333 wpa_cli_action(ctrl_conn
);
3335 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
3337 os_free(ctrl_ifname
);
3344 #else /* CONFIG_CTRL_IFACE */
3345 int main(int argc
, char *argv
[])
3347 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3350 #endif /* CONFIG_CTRL_IFACE */