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 "utils/list.h"
28 #include "common/version.h"
30 #include <cutils/properties.h>
34 static const char *wpa_cli_version
=
35 "wpa_cli v" VERSION_STR
"\n"
36 "Copyright (c) 2004-2011, 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 #ifndef CONFIG_CTRL_IFACE_DIR
98 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
99 #endif /* CONFIG_CTRL_IFACE_DIR */
100 static const char *ctrl_iface_dir
= CONFIG_CTRL_IFACE_DIR
;
101 static char *ctrl_ifname
= NULL
;
102 static const char *pid_file
= NULL
;
103 static const char *action_file
= NULL
;
104 static int ping_interval
= 5;
105 static int interactive
= 0;
107 struct cli_txt_entry
{
112 static DEFINE_DL_LIST(bsses
); /* struct cli_txt_entry */
113 static DEFINE_DL_LIST(p2p_peers
); /* struct cli_txt_entry */
114 static DEFINE_DL_LIST(p2p_groups
); /* struct cli_txt_entry */
117 static void print_help(void);
118 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
);
121 static void usage(void)
123 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
124 "[-a<action file>] \\\n"
125 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
127 " -h = help (show this usage text)\n"
128 " -v = shown version information\n"
129 " -a = run in daemon mode executing the action file based on "
132 " -B = run a daemon in the background\n"
133 " default path: " CONFIG_CTRL_IFACE_DIR
"\n"
134 " default interface: first interface found in socket path\n");
139 static void cli_txt_list_free(struct cli_txt_entry
*e
)
141 dl_list_del(&e
->list
);
147 static void cli_txt_list_flush(struct dl_list
*list
)
149 struct cli_txt_entry
*e
;
150 while ((e
= dl_list_first(list
, struct cli_txt_entry
, list
)))
151 cli_txt_list_free(e
);
155 static struct cli_txt_entry
* cli_txt_list_get(struct dl_list
*txt_list
,
158 struct cli_txt_entry
*e
;
159 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
160 if (os_strcmp(e
->txt
, txt
) == 0)
167 static void cli_txt_list_del(struct dl_list
*txt_list
, const char *txt
)
169 struct cli_txt_entry
*e
;
170 e
= cli_txt_list_get(txt_list
, txt
);
172 cli_txt_list_free(e
);
176 static void cli_txt_list_del_addr(struct dl_list
*txt_list
, const char *txt
)
180 if (hwaddr_aton(txt
, addr
) < 0)
182 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
183 cli_txt_list_del(txt_list
, buf
);
187 static void cli_txt_list_del_word(struct dl_list
*txt_list
, const char *txt
)
191 end
= os_strchr(txt
, ' ');
193 end
= txt
+ os_strlen(txt
);
194 buf
= os_malloc(end
- txt
+ 1);
197 os_memcpy(buf
, txt
, end
- txt
);
198 buf
[end
- txt
] = '\0';
199 cli_txt_list_del(txt_list
, buf
);
204 static int cli_txt_list_add(struct dl_list
*txt_list
, const char *txt
)
206 struct cli_txt_entry
*e
;
207 e
= cli_txt_list_get(txt_list
, txt
);
210 e
= os_zalloc(sizeof(*e
));
213 e
->txt
= os_strdup(txt
);
214 if (e
->txt
== NULL
) {
218 dl_list_add(txt_list
, &e
->list
);
223 static int cli_txt_list_add_addr(struct dl_list
*txt_list
, const char *txt
)
227 if (hwaddr_aton(txt
, addr
) < 0)
229 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
230 return cli_txt_list_add(txt_list
, buf
);
234 static int cli_txt_list_add_word(struct dl_list
*txt_list
, const char *txt
)
239 end
= os_strchr(txt
, ' ');
241 end
= txt
+ os_strlen(txt
);
242 buf
= os_malloc(end
- txt
+ 1);
245 os_memcpy(buf
, txt
, end
- txt
);
246 buf
[end
- txt
] = '\0';
247 ret
= cli_txt_list_add(txt_list
, buf
);
253 static char ** cli_txt_list_array(struct dl_list
*txt_list
)
255 unsigned int i
, count
= dl_list_len(txt_list
);
257 struct cli_txt_entry
*e
;
259 res
= os_zalloc((count
+ 1) * sizeof(char *));
264 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
265 res
[i
] = os_strdup(e
->txt
);
275 static int get_cmd_arg_num(const char *str
, int pos
)
279 for (i
= 0; i
<= pos
; i
++) {
282 while (i
<= pos
&& str
[i
] != ' ')
293 static int str_starts(const char *src
, const char *match
)
295 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
299 static int wpa_cli_show_event(const char *event
)
303 start
= os_strchr(event
, '>');
309 * Skip BSS added/removed events since they can be relatively frequent
310 * and are likely of not much use for an interactive user.
312 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
313 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
320 static int wpa_cli_open_connection(const char *ifname
, int attach
)
322 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
323 ctrl_conn
= wpa_ctrl_open(ifname
);
324 if (ctrl_conn
== NULL
)
327 if (attach
&& interactive
)
328 mon_conn
= wpa_ctrl_open(ifname
);
331 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
339 if (access(ctrl_iface_dir
, F_OK
) < 0) {
340 cfile
= os_strdup(ifname
);
347 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
348 cfile
= os_malloc(flen
);
351 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
,
353 if (res
< 0 || res
>= flen
) {
359 ctrl_conn
= wpa_ctrl_open(cfile
);
360 if (ctrl_conn
== NULL
) {
365 if (attach
&& interactive
)
366 mon_conn
= wpa_ctrl_open(cfile
);
370 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
373 if (wpa_ctrl_attach(mon_conn
) == 0) {
374 wpa_cli_attached
= 1;
376 eloop_register_read_sock(
377 wpa_ctrl_get_fd(mon_conn
),
378 wpa_cli_mon_receive
, NULL
, NULL
);
380 printf("Warning: Failed to attach to "
381 "wpa_supplicant.\n");
390 static void wpa_cli_close_connection(void)
392 if (ctrl_conn
== NULL
)
395 if (wpa_cli_attached
) {
396 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
397 wpa_cli_attached
= 0;
399 wpa_ctrl_close(ctrl_conn
);
402 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
403 wpa_ctrl_close(mon_conn
);
409 static void wpa_cli_msg_cb(char *msg
, size_t len
)
415 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
421 if (ctrl_conn
== NULL
) {
422 printf("Not connected to wpa_supplicant - command dropped.\n");
425 len
= sizeof(buf
) - 1;
426 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
429 printf("'%s' command timed out.\n", cmd
);
431 } else if (ret
< 0) {
432 printf("'%s' command failed.\n", cmd
);
438 if (interactive
&& len
> 0 && buf
[len
- 1] != '\n')
445 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
447 return _wpa_ctrl_command(ctrl
, cmd
, 1);
451 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
453 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
454 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
458 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
460 return wpa_ctrl_command(ctrl
, "PING");
464 static int wpa_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
466 return wpa_ctrl_command(ctrl
, "RELOG");
470 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
476 ret
= os_snprintf(cmd
, sizeof(cmd
), "NOTE %s", argv
[0]);
477 if (ret
< 0 || (size_t) ret
>= sizeof(cmd
))
479 return wpa_ctrl_command(ctrl
, cmd
);
483 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
485 return wpa_ctrl_command(ctrl
, "MIB");
489 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
491 return wpa_ctrl_command(ctrl
, "PMKSA");
495 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
502 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
504 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
509 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
518 static void wpa_cli_show_variables(void)
520 printf("set variables:\n"
521 " EAPOL::heldPeriod (EAPOL state machine held period, "
523 " EAPOL::authPeriod (EAPOL state machine authentication "
524 "period, in seconds)\n"
525 " EAPOL::startPeriod (EAPOL state machine start period, in "
527 " EAPOL::maxStart (EAPOL state machine maximum start "
529 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
531 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
532 " threshold\n\tpercentage)\n"
533 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
534 "security\n\tassociation in seconds)\n");
538 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
544 wpa_cli_show_variables();
548 if (argc
!= 1 && argc
!= 2) {
549 printf("Invalid SET command: needs two arguments (variable "
550 "name and value)\n");
555 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s ", argv
[0]);
557 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s",
559 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
560 printf("Too long SET command.\n");
563 return wpa_ctrl_command(ctrl
, cmd
);
567 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
573 printf("Invalid GET command: need one argument (variable "
578 res
= os_snprintf(cmd
, sizeof(cmd
), "GET %s", argv
[0]);
579 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
580 printf("Too long GET command.\n");
583 return wpa_ctrl_command(ctrl
, cmd
);
587 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
589 return wpa_ctrl_command(ctrl
, "LOGOFF");
593 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
595 return wpa_ctrl_command(ctrl
, "LOGON");
599 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
602 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
606 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
613 printf("Invalid PREAUTH command: needs one argument "
618 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
619 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
620 printf("Too long PREAUTH command.\n");
623 return wpa_ctrl_command(ctrl
, cmd
);
627 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
633 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
637 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
638 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
639 printf("Too long AP_SCAN command.\n");
642 return wpa_ctrl_command(ctrl
, cmd
);
646 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl
*ctrl
, int argc
,
653 printf("Invalid SCAN_INTERVAL command: needs one argument "
654 "scan_interval value)\n");
657 res
= os_snprintf(cmd
, sizeof(cmd
), "SCAN_INTERVAL %s", argv
[0]);
658 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
659 printf("Too long SCAN_INTERVAL command.\n");
662 return wpa_ctrl_command(ctrl
, cmd
);
666 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl
*ctrl
, int argc
,
673 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
674 "(bss_expire_age value)\n");
677 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_EXPIRE_AGE %s", argv
[0]);
678 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
679 printf("Too long BSS_EXPIRE_AGE command.\n");
682 return wpa_ctrl_command(ctrl
, cmd
);
686 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl
*ctrl
, int argc
,
693 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
694 "(bss_expire_count value)\n");
697 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_EXPIRE_COUNT %s", argv
[0]);
698 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
699 printf("Too long BSS_EXPIRE_COUNT command.\n");
702 return wpa_ctrl_command(ctrl
, cmd
);
706 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
713 printf("Invalid STKSTART command: needs one argument "
714 "(Peer STA MAC address)\n");
718 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
719 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
720 printf("Too long STKSTART command.\n");
723 return wpa_ctrl_command(ctrl
, cmd
);
727 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
733 printf("Invalid FT_DS command: needs one argument "
734 "(Target AP MAC address)\n");
738 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
739 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
740 printf("Too long FT_DS command.\n");
743 return wpa_ctrl_command(ctrl
, cmd
);
747 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
754 return wpa_ctrl_command(ctrl
, "WPS_PBC");
758 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
759 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
760 printf("Too long WPS_PBC command.\n");
763 return wpa_ctrl_command(ctrl
, cmd
);
767 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
773 printf("Invalid WPS_PIN command: need one or two arguments:\n"
774 "- BSSID: use 'any' to select any\n"
775 "- PIN: optional, used only with devices that have no "
781 /* Use dynamically generated PIN (returned as reply) */
782 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
783 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
784 printf("Too long WPS_PIN command.\n");
787 return wpa_ctrl_command(ctrl
, cmd
);
790 /* Use hardcoded PIN from a label */
791 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
792 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
793 printf("Too long WPS_PIN command.\n");
796 return wpa_ctrl_command(ctrl
, cmd
);
800 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
806 if (argc
!= 1 && argc
!= 2) {
807 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
808 "- PIN to be verified\n");
813 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
816 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
818 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
819 printf("Too long WPS_CHECK_PIN command.\n");
822 return wpa_ctrl_command(ctrl
, cmd
);
826 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
829 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
833 #ifdef CONFIG_WPS_OOB
834 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
839 if (argc
!= 3 && argc
!= 4) {
840 printf("Invalid WPS_OOB command: need three or four "
842 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
843 "- PATH: path of OOB device like '/mnt'\n"
844 "- METHOD: OOB method 'pin-e' or 'pin-r', "
846 "- DEV_NAME: (only for NFC) device name like "
852 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
853 argv
[0], argv
[1], argv
[2]);
855 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
856 argv
[0], argv
[1], argv
[2], argv
[3]);
857 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
858 printf("Too long WPS_OOB command.\n");
861 return wpa_ctrl_command(ctrl
, cmd
);
863 #endif /* CONFIG_WPS_OOB */
866 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
872 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
874 else if (argc
== 5 || argc
== 6) {
875 char ssid_hex
[2 * 32 + 1];
876 char key_hex
[2 * 64 + 1];
880 for (i
= 0; i
< 32; i
++) {
881 if (argv
[2][i
] == '\0')
883 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
888 for (i
= 0; i
< 64; i
++) {
889 if (argv
[5][i
] == '\0')
891 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
896 res
= os_snprintf(cmd
, sizeof(cmd
),
897 "WPS_REG %s %s %s %s %s %s",
898 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
901 printf("Invalid WPS_REG command: need two arguments:\n"
902 "- BSSID of the target AP\n"
904 printf("Alternatively, six arguments can be used to "
905 "reconfigure the AP:\n"
906 "- BSSID of the target AP\n"
909 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
910 "- new encr (NONE, WEP, TKIP, CCMP)\n"
915 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
916 printf("Too long WPS_REG command.\n");
919 return wpa_ctrl_command(ctrl
, cmd
);
923 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
930 printf("Invalid WPS_AP_PIN command: needs at least one "
936 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s %s",
937 argv
[0], argv
[1], argv
[2]);
939 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s",
942 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s",
944 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
945 printf("Too long WPS_AP_PIN command.\n");
948 return wpa_ctrl_command(ctrl
, cmd
);
952 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
957 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
958 return wpa_ctrl_command(ctrl
, cmd
);
960 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
964 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
967 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
972 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
979 printf("Invalid WPS_ER_PIN command: need at least two "
981 "- UUID: use 'any' to select any\n"
982 "- PIN: Enrollee PIN\n"
983 "optional: - Enrollee MAC address\n");
988 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
989 argv
[0], argv
[1], argv
[2]);
991 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
993 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
994 printf("Too long WPS_ER_PIN command.\n");
997 return wpa_ctrl_command(ctrl
, cmd
);
1001 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
1008 printf("Invalid WPS_ER_PBC command: need one argument:\n"
1009 "- UUID: Specify the Enrollee\n");
1013 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
1015 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1016 printf("Too long WPS_ER_PBC command.\n");
1019 return wpa_ctrl_command(ctrl
, cmd
);
1023 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
1030 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1031 "- UUID: specify which AP to use\n"
1036 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
1038 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1039 printf("Too long WPS_ER_LEARN command.\n");
1042 return wpa_ctrl_command(ctrl
, cmd
);
1046 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
1053 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1055 "- UUID: specify which AP to use\n"
1056 "- Network configuration id\n");
1060 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_SET_CONFIG %s %s",
1062 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1063 printf("Too long WPS_ER_SET_CONFIG command.\n");
1066 return wpa_ctrl_command(ctrl
, cmd
);
1070 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
1076 if (argc
== 5 || argc
== 6) {
1077 char ssid_hex
[2 * 32 + 1];
1078 char key_hex
[2 * 64 + 1];
1082 for (i
= 0; i
< 32; i
++) {
1083 if (argv
[2][i
] == '\0')
1085 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
1090 for (i
= 0; i
< 64; i
++) {
1091 if (argv
[5][i
] == '\0')
1093 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
1098 res
= os_snprintf(cmd
, sizeof(cmd
),
1099 "WPS_ER_CONFIG %s %s %s %s %s %s",
1100 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
1103 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1107 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1108 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1113 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1114 printf("Too long WPS_ER_CONFIG command.\n");
1117 return wpa_ctrl_command(ctrl
, cmd
);
1121 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1127 printf("Invalid IBSS_RSN command: needs one argument "
1128 "(Peer STA MAC address)\n");
1132 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
1133 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1134 printf("Too long IBSS_RSN command.\n");
1137 return wpa_ctrl_command(ctrl
, cmd
);
1141 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1147 printf("Invalid LEVEL command: needs one argument (debug "
1151 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
1152 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1153 printf("Too long LEVEL command.\n");
1156 return wpa_ctrl_command(ctrl
, cmd
);
1160 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1162 char cmd
[256], *pos
, *end
;
1166 printf("Invalid IDENTITY command: needs two arguments "
1167 "(network id and identity)\n");
1171 end
= cmd
+ sizeof(cmd
);
1173 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
1175 if (ret
< 0 || ret
>= end
- pos
) {
1176 printf("Too long IDENTITY command.\n");
1180 for (i
= 2; i
< argc
; i
++) {
1181 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1182 if (ret
< 0 || ret
>= end
- pos
) {
1183 printf("Too long IDENTITY command.\n");
1189 return wpa_ctrl_command(ctrl
, cmd
);
1193 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1195 char cmd
[256], *pos
, *end
;
1199 printf("Invalid PASSWORD command: needs two arguments "
1200 "(network id and password)\n");
1204 end
= cmd
+ sizeof(cmd
);
1206 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1208 if (ret
< 0 || ret
>= end
- pos
) {
1209 printf("Too long PASSWORD command.\n");
1213 for (i
= 2; i
< argc
; i
++) {
1214 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1215 if (ret
< 0 || ret
>= end
- pos
) {
1216 printf("Too long PASSWORD command.\n");
1222 return wpa_ctrl_command(ctrl
, cmd
);
1226 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1229 char cmd
[256], *pos
, *end
;
1233 printf("Invalid NEW_PASSWORD command: needs two arguments "
1234 "(network id and password)\n");
1238 end
= cmd
+ sizeof(cmd
);
1240 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1242 if (ret
< 0 || ret
>= end
- pos
) {
1243 printf("Too long NEW_PASSWORD command.\n");
1247 for (i
= 2; i
< argc
; i
++) {
1248 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1249 if (ret
< 0 || ret
>= end
- pos
) {
1250 printf("Too long NEW_PASSWORD command.\n");
1256 return wpa_ctrl_command(ctrl
, cmd
);
1260 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1262 char cmd
[256], *pos
, *end
;
1266 printf("Invalid PIN command: needs two arguments "
1267 "(network id and pin)\n");
1271 end
= cmd
+ sizeof(cmd
);
1273 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1275 if (ret
< 0 || ret
>= end
- pos
) {
1276 printf("Too long PIN command.\n");
1280 for (i
= 2; i
< argc
; i
++) {
1281 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1282 if (ret
< 0 || ret
>= end
- pos
) {
1283 printf("Too long PIN command.\n");
1288 return wpa_ctrl_command(ctrl
, cmd
);
1292 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1294 char cmd
[256], *pos
, *end
;
1298 printf("Invalid OTP command: needs two arguments (network "
1299 "id and password)\n");
1303 end
= cmd
+ sizeof(cmd
);
1305 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1307 if (ret
< 0 || ret
>= end
- pos
) {
1308 printf("Too long OTP command.\n");
1312 for (i
= 2; i
< argc
; i
++) {
1313 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1314 if (ret
< 0 || ret
>= end
- pos
) {
1315 printf("Too long OTP command.\n");
1321 return wpa_ctrl_command(ctrl
, cmd
);
1325 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1328 char cmd
[256], *pos
, *end
;
1332 printf("Invalid PASSPHRASE command: needs two arguments "
1333 "(network id and passphrase)\n");
1337 end
= cmd
+ sizeof(cmd
);
1339 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1341 if (ret
< 0 || ret
>= end
- pos
) {
1342 printf("Too long PASSPHRASE command.\n");
1346 for (i
= 2; i
< argc
; i
++) {
1347 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1348 if (ret
< 0 || ret
>= end
- pos
) {
1349 printf("Too long PASSPHRASE command.\n");
1355 return wpa_ctrl_command(ctrl
, cmd
);
1359 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1361 char cmd
[256], *pos
, *end
;
1365 printf("Invalid BSSID command: needs two arguments (network "
1370 end
= cmd
+ sizeof(cmd
);
1372 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1373 if (ret
< 0 || ret
>= end
- pos
) {
1374 printf("Too long BSSID command.\n");
1378 for (i
= 0; i
< argc
; i
++) {
1379 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1380 if (ret
< 0 || ret
>= end
- pos
) {
1381 printf("Too long BSSID command.\n");
1387 return wpa_ctrl_command(ctrl
, cmd
);
1391 static int wpa_cli_cmd_blacklist(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1393 char cmd
[256], *pos
, *end
;
1396 end
= cmd
+ sizeof(cmd
);
1398 ret
= os_snprintf(pos
, end
- pos
, "BLACKLIST");
1399 if (ret
< 0 || ret
>= end
- pos
) {
1400 printf("Too long BLACKLIST command.\n");
1404 for (i
= 0; i
< argc
; i
++) {
1405 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1406 if (ret
< 0 || ret
>= end
- pos
) {
1407 printf("Too long BLACKLIST command.\n");
1413 return wpa_ctrl_command(ctrl
, cmd
);
1417 static int wpa_cli_cmd_log_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1419 char cmd
[256], *pos
, *end
;
1422 end
= cmd
+ sizeof(cmd
);
1424 ret
= os_snprintf(pos
, end
- pos
, "LOG_LEVEL");
1425 if (ret
< 0 || ret
>= end
- pos
) {
1426 printf("Too long LOG_LEVEL command.\n");
1430 for (i
= 0; i
< argc
; i
++) {
1431 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1432 if (ret
< 0 || ret
>= end
- pos
) {
1433 printf("Too long LOG_LEVEL command.\n");
1439 return wpa_ctrl_command(ctrl
, cmd
);
1443 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1446 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1450 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1457 printf("Invalid SELECT_NETWORK command: needs one argument "
1462 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1463 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1465 cmd
[sizeof(cmd
) - 1] = '\0';
1467 return wpa_ctrl_command(ctrl
, cmd
);
1471 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1478 printf("Invalid ENABLE_NETWORK command: needs one argument "
1483 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1484 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1486 cmd
[sizeof(cmd
) - 1] = '\0';
1488 return wpa_ctrl_command(ctrl
, cmd
);
1492 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1499 printf("Invalid DISABLE_NETWORK command: needs one argument "
1504 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1505 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1507 cmd
[sizeof(cmd
) - 1] = '\0';
1509 return wpa_ctrl_command(ctrl
, cmd
);
1513 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1516 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1520 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1527 printf("Invalid REMOVE_NETWORK command: needs one argument "
1532 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1533 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1535 cmd
[sizeof(cmd
) - 1] = '\0';
1537 return wpa_ctrl_command(ctrl
, cmd
);
1541 static void wpa_cli_show_network_variables(void)
1543 printf("set_network variables:\n"
1544 " ssid (network name, SSID)\n"
1545 " psk (WPA passphrase or pre-shared key)\n"
1546 " key_mgmt (key management protocol)\n"
1547 " identity (EAP identity)\n"
1548 " password (EAP password)\n"
1551 "Note: Values are entered in the same format as the "
1552 "configuration file is using,\n"
1553 "i.e., strings values need to be inside double quotation "
1555 "For example: set_network 1 ssid \"network name\"\n"
1557 "Please see wpa_supplicant.conf documentation for full list "
1558 "of\navailable variables.\n");
1562 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1569 wpa_cli_show_network_variables();
1574 printf("Invalid SET_NETWORK command: needs three arguments\n"
1575 "(network id, variable name, and value)\n");
1579 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1580 argv
[0], argv
[1], argv
[2]);
1581 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1582 printf("Too long SET_NETWORK command.\n");
1585 return wpa_ctrl_command(ctrl
, cmd
);
1589 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1596 wpa_cli_show_network_variables();
1601 printf("Invalid GET_NETWORK command: needs two arguments\n"
1602 "(network id and variable name)\n");
1606 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1608 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1609 printf("Too long GET_NETWORK command.\n");
1612 return wpa_ctrl_command(ctrl
, cmd
);
1616 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1619 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1623 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1626 return wpa_ctrl_command(ctrl
, "RECONNECT");
1630 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1633 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1637 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1639 return wpa_ctrl_command(ctrl
, "SCAN");
1643 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1646 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1650 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1656 printf("Invalid BSS command: need one argument (index or "
1661 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1662 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1664 cmd
[sizeof(cmd
) - 1] = '\0';
1666 return wpa_ctrl_command(ctrl
, cmd
);
1670 static char ** wpa_cli_complete_bss(const char *str
, int pos
)
1672 int arg
= get_cmd_arg_num(str
, pos
);
1677 res
= cli_txt_list_array(&bsses
);
1685 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1691 if (argc
< 1 || argc
> 2) {
1692 printf("Invalid GET_CAPABILITY command: need either one or "
1697 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1698 printf("Invalid GET_CAPABILITY command: second argument, "
1699 "if any, must be 'strict'\n");
1703 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1704 (argc
== 2) ? " strict" : "");
1705 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1707 cmd
[sizeof(cmd
) - 1] = '\0';
1709 return wpa_ctrl_command(ctrl
, cmd
);
1713 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1715 printf("Available interfaces:\n");
1716 return wpa_ctrl_command(ctrl
, "INTERFACES");
1720 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1723 wpa_cli_list_interfaces(ctrl
);
1727 wpa_cli_close_connection();
1728 os_free(ctrl_ifname
);
1729 ctrl_ifname
= os_strdup(argv
[0]);
1731 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1732 printf("Connected to interface '%s.\n", ctrl_ifname
);
1734 printf("Could not connect to interface '%s' - re-trying\n",
1741 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1744 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1748 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1751 return wpa_ctrl_command(ctrl
, "TERMINATE");
1755 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1762 printf("Invalid INTERFACE_ADD command: needs at least one "
1763 "argument (interface name)\n"
1764 "All arguments: ifname confname driver ctrl_interface "
1765 "driver_param bridge_name\n");
1770 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1771 * <driver_param>TAB<bridge_name>
1773 res
= os_snprintf(cmd
, sizeof(cmd
),
1774 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1776 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1777 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1778 argc
> 5 ? argv
[5] : "");
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_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1793 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1794 "(interface name)\n");
1798 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
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_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1809 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1814 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1818 printf("Invalid 'sta' command - exactly one argument, STA "
1819 "address, is required.\n");
1822 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1823 return wpa_ctrl_command(ctrl
, buf
);
1827 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1828 char *addr
, size_t addr_len
)
1830 char buf
[4096], *pos
;
1834 if (ctrl_conn
== NULL
) {
1835 printf("Not connected to hostapd - command dropped.\n");
1838 len
= sizeof(buf
) - 1;
1839 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1842 printf("'%s' command timed out.\n", cmd
);
1844 } else if (ret
< 0) {
1845 printf("'%s' command failed.\n", cmd
);
1850 if (memcmp(buf
, "FAIL", 4) == 0)
1855 while (*pos
!= '\0' && *pos
!= '\n')
1858 os_strlcpy(addr
, buf
, addr_len
);
1863 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1865 char addr
[32], cmd
[64];
1867 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1870 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1871 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1875 #endif /* CONFIG_AP */
1878 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1880 return wpa_ctrl_command(ctrl
, "SUSPEND");
1884 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1886 return wpa_ctrl_command(ctrl
, "RESUME");
1890 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1892 return wpa_ctrl_command(ctrl
, "DROP_SA");
1896 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1902 printf("Invalid ROAM command: needs one argument "
1903 "(target AP's BSSID)\n");
1907 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
1908 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1909 printf("Too long ROAM command.\n");
1912 return wpa_ctrl_command(ctrl
, cmd
);
1918 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1924 return wpa_ctrl_command(ctrl
, "P2P_FIND");
1927 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
1930 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
1931 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1933 cmd
[sizeof(cmd
) - 1] = '\0';
1934 return wpa_ctrl_command(ctrl
, cmd
);
1938 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1941 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1945 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1952 printf("Invalid P2P_CONNECT command: needs at least two "
1953 "arguments (address and pbc/PIN)\n");
1958 res
= os_snprintf(cmd
, sizeof(cmd
),
1959 "P2P_CONNECT %s %s %s %s %s",
1960 argv
[0], argv
[1], argv
[2], argv
[3],
1963 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
1964 argv
[0], argv
[1], argv
[2], argv
[3]);
1966 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
1967 argv
[0], argv
[1], argv
[2]);
1969 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
1971 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1973 cmd
[sizeof(cmd
) - 1] = '\0';
1974 return wpa_ctrl_command(ctrl
, cmd
);
1978 static char ** wpa_cli_complete_p2p_connect(const char *str
, int pos
)
1980 int arg
= get_cmd_arg_num(str
, pos
);
1985 res
= cli_txt_list_array(&p2p_peers
);
1993 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
2000 return wpa_ctrl_command(ctrl
, "P2P_LISTEN");
2002 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_LISTEN %s", argv
[0]);
2003 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2005 cmd
[sizeof(cmd
) - 1] = '\0';
2006 return wpa_ctrl_command(ctrl
, cmd
);
2010 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
2017 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2018 "(interface name)\n");
2022 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
2023 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2025 cmd
[sizeof(cmd
) - 1] = '\0';
2026 return wpa_ctrl_command(ctrl
, cmd
);
2030 static char ** wpa_cli_complete_p2p_group_remove(const char *str
, int pos
)
2032 int arg
= get_cmd_arg_num(str
, pos
);
2037 res
= cli_txt_list_array(&p2p_groups
);
2045 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
2052 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
2055 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s %s",
2058 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s",
2060 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2062 cmd
[sizeof(cmd
) - 1] = '\0';
2063 return wpa_ctrl_command(ctrl
, cmd
);
2067 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
2074 printf("Invalid P2P_PROV_DISC command: needs two arguments "
2075 "(address and config method\n"
2076 "(display, keypad, or pbc)\n");
2080 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
2082 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2084 cmd
[sizeof(cmd
) - 1] = '\0';
2085 return wpa_ctrl_command(ctrl
, cmd
);
2089 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
2092 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
2096 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
2102 if (argc
!= 2 && argc
!= 4) {
2103 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2104 "arguments (address and TLVs) or four arguments "
2105 "(address, \"upnp\", version, search target "
2111 res
= os_snprintf(cmd
, sizeof(cmd
),
2112 "P2P_SERV_DISC_REQ %s %s %s %s",
2113 argv
[0], argv
[1], argv
[2], argv
[3]);
2115 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
2117 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2119 cmd
[sizeof(cmd
) - 1] = '\0';
2120 return wpa_ctrl_command(ctrl
, cmd
);
2124 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
2125 int argc
, char *argv
[])
2131 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2132 "argument (pending request identifier)\n");
2136 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
2138 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2140 cmd
[sizeof(cmd
) - 1] = '\0';
2141 return wpa_ctrl_command(ctrl
, cmd
);
2145 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
2152 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2153 "arguments (freq, address, dialog token, and TLVs)\n");
2157 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
2158 argv
[0], argv
[1], argv
[2], argv
[3]);
2159 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2161 cmd
[sizeof(cmd
) - 1] = '\0';
2162 return wpa_ctrl_command(ctrl
, cmd
);
2166 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
2169 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
2173 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
2174 int argc
, char *argv
[])
2180 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2181 "argument (external processing: 0/1)\n");
2185 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
2187 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2189 cmd
[sizeof(cmd
) - 1] = '\0';
2190 return wpa_ctrl_command(ctrl
, cmd
);
2194 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
2197 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
2201 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
2207 if (argc
!= 3 && argc
!= 4) {
2208 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2214 res
= os_snprintf(cmd
, sizeof(cmd
),
2215 "P2P_SERVICE_ADD %s %s %s %s",
2216 argv
[0], argv
[1], argv
[2], argv
[3]);
2218 res
= os_snprintf(cmd
, sizeof(cmd
),
2219 "P2P_SERVICE_ADD %s %s %s",
2220 argv
[0], argv
[1], argv
[2]);
2221 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2223 cmd
[sizeof(cmd
) - 1] = '\0';
2224 return wpa_ctrl_command(ctrl
, cmd
);
2228 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
2234 if (argc
!= 2 && argc
!= 3) {
2235 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2241 res
= os_snprintf(cmd
, sizeof(cmd
),
2242 "P2P_SERVICE_DEL %s %s %s",
2243 argv
[0], argv
[1], argv
[2]);
2245 res
= os_snprintf(cmd
, sizeof(cmd
),
2246 "P2P_SERVICE_DEL %s %s",
2248 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2250 cmd
[sizeof(cmd
) - 1] = '\0';
2251 return wpa_ctrl_command(ctrl
, cmd
);
2255 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
2256 int argc
, char *argv
[])
2262 printf("Invalid P2P_REJECT command: needs one argument "
2263 "(peer address)\n");
2267 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
2268 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2270 cmd
[sizeof(cmd
) - 1] = '\0';
2271 return wpa_ctrl_command(ctrl
, cmd
);
2275 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
2276 int argc
, char *argv
[])
2282 printf("Invalid P2P_INVITE command: needs at least one "
2288 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
2289 argv
[0], argv
[1], argv
[2]);
2291 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
2294 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
2295 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2297 cmd
[sizeof(cmd
) - 1] = '\0';
2298 return wpa_ctrl_command(ctrl
, cmd
);
2302 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2306 printf("Invalid 'p2p_peer' command - exactly one argument, "
2307 "P2P peer device address, is required.\n");
2310 os_snprintf(buf
, sizeof(buf
), "P2P_PEER %s", argv
[0]);
2311 return wpa_ctrl_command(ctrl
, buf
);
2315 static char ** wpa_cli_complete_p2p_peer(const char *str
, int pos
)
2317 int arg
= get_cmd_arg_num(str
, pos
);
2322 res
= cli_txt_list_array(&p2p_peers
);
2330 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
2331 char *addr
, size_t addr_len
,
2334 char buf
[4096], *pos
;
2338 if (ctrl_conn
== NULL
)
2340 len
= sizeof(buf
) - 1;
2341 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
2344 printf("'%s' command timed out.\n", cmd
);
2346 } else if (ret
< 0) {
2347 printf("'%s' command failed.\n", cmd
);
2352 if (memcmp(buf
, "FAIL", 4) == 0)
2356 while (*pos
!= '\0' && *pos
!= '\n')
2359 os_strlcpy(addr
, buf
, addr_len
);
2360 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2361 printf("%s\n", addr
);
2366 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2368 char addr
[32], cmd
[64];
2371 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2373 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2374 addr
, sizeof(addr
), discovered
))
2377 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2378 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2385 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2391 printf("Invalid P2P_SET command: needs two arguments (field, "
2396 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
2397 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2399 cmd
[sizeof(cmd
) - 1] = '\0';
2400 return wpa_ctrl_command(ctrl
, cmd
);
2404 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2406 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2410 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2413 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2417 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
2424 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2425 "(peer address)\n");
2429 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_UNAUTHORIZE %s", argv
[0]);
2431 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2434 cmd
[sizeof(cmd
) - 1] = '\0';
2435 return wpa_ctrl_command(ctrl
, cmd
);
2439 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2445 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2446 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2447 "(preferred duration, interval; in microsecods).\n"
2448 "Optional second pair can be used to provide "
2449 "acceptable values.\n");
2454 res
= os_snprintf(cmd
, sizeof(cmd
),
2455 "P2P_PRESENCE_REQ %s %s %s %s",
2456 argv
[0], argv
[1], argv
[2], argv
[3]);
2458 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2461 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
2462 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2464 cmd
[sizeof(cmd
) - 1] = '\0';
2465 return wpa_ctrl_command(ctrl
, cmd
);
2469 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2475 if (argc
!= 0 && argc
!= 2) {
2476 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2477 "(availability period, availability interval; in "
2479 "Extended Listen Timing can be cancelled with this "
2480 "command when used without parameters.\n");
2485 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2488 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2489 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2491 cmd
[sizeof(cmd
) - 1] = '\0';
2492 return wpa_ctrl_command(ctrl
, cmd
);
2495 #endif /* CONFIG_P2P */
2498 #ifdef CONFIG_INTERWORKING
2499 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2502 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
2506 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2509 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
2513 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl
*ctrl
, int argc
,
2520 return wpa_ctrl_command(ctrl
, "INTERWORKING_SELECT");
2522 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERWORKING_SELECT %s", argv
[0]);
2523 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2525 cmd
[sizeof(cmd
) - 1] = '\0';
2526 return wpa_ctrl_command(ctrl
, cmd
);
2530 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl
*ctrl
, int argc
,
2537 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2538 "argument (BSSID)\n");
2542 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERWORKING_CONNECT %s",
2544 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2546 cmd
[sizeof(cmd
) - 1] = '\0';
2547 return wpa_ctrl_command(ctrl
, cmd
);
2551 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2557 printf("Invalid ANQP_GET command: needs two arguments "
2558 "(addr and info id list)\n");
2562 res
= os_snprintf(cmd
, sizeof(cmd
), "ANQP_GET %s %s",
2564 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2566 cmd
[sizeof(cmd
) - 1] = '\0';
2567 return wpa_ctrl_command(ctrl
, cmd
);
2569 #endif /* CONFIG_INTERWORKING */
2572 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2579 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2580 "(0/1 = disable/enable automatic reconnection)\n");
2583 res
= os_snprintf(cmd
, sizeof(cmd
), "STA_AUTOCONNECT %s", argv
[0]);
2584 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2585 printf("Too long STA_AUTOCONNECT command.\n");
2588 return wpa_ctrl_command(ctrl
, cmd
);
2592 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2599 printf("Invalid TDLS_DISCOVER command: needs one argument "
2600 "(Peer STA MAC address)\n");
2604 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_DISCOVER %s", argv
[0]);
2605 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2606 printf("Too long TDLS_DISCOVER command.\n");
2609 return wpa_ctrl_command(ctrl
, cmd
);
2613 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2620 printf("Invalid TDLS_SETUP command: needs one argument "
2621 "(Peer STA MAC address)\n");
2625 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_SETUP %s", argv
[0]);
2626 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2627 printf("Too long TDLS_SETUP command.\n");
2630 return wpa_ctrl_command(ctrl
, cmd
);
2634 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2641 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2642 "(Peer STA MAC address)\n");
2646 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_TEARDOWN %s", argv
[0]);
2647 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2648 printf("Too long TDLS_TEARDOWN command.\n");
2651 return wpa_ctrl_command(ctrl
, cmd
);
2655 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2658 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2662 enum wpa_cli_cmd_flags
{
2663 cli_cmd_flag_none
= 0x00,
2664 cli_cmd_flag_sensitive
= 0x01
2667 struct wpa_cli_cmd
{
2669 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2670 enum wpa_cli_cmd_flags flags
;
2674 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2675 { "status", wpa_cli_cmd_status
,
2677 "[verbose] = get current WPA/EAPOL/EAP status" },
2678 { "ping", wpa_cli_cmd_ping
,
2680 "= pings wpa_supplicant" },
2681 { "relog", wpa_cli_cmd_relog
,
2683 "= re-open log-file (allow rolling logs)" },
2684 { "note", wpa_cli_cmd_note
,
2686 "<text> = add a note to wpa_supplicant debug log" },
2687 { "mib", wpa_cli_cmd_mib
,
2689 "= get MIB variables (dot1x, dot11)" },
2690 { "help", wpa_cli_cmd_help
,
2692 "= show this usage help" },
2693 { "interface", wpa_cli_cmd_interface
,
2695 "[ifname] = show interfaces/select interface" },
2696 { "level", wpa_cli_cmd_level
,
2698 "<debug level> = change debug level" },
2699 { "license", wpa_cli_cmd_license
,
2701 "= show full wpa_cli license" },
2702 { "quit", wpa_cli_cmd_quit
,
2705 { "set", wpa_cli_cmd_set
,
2707 "= set variables (shows list of variables when run without "
2709 { "get", wpa_cli_cmd_get
,
2711 "<name> = get information" },
2712 { "logon", wpa_cli_cmd_logon
,
2714 "= IEEE 802.1X EAPOL state machine logon" },
2715 { "logoff", wpa_cli_cmd_logoff
,
2717 "= IEEE 802.1X EAPOL state machine logoff" },
2718 { "pmksa", wpa_cli_cmd_pmksa
,
2720 "= show PMKSA cache" },
2721 { "reassociate", wpa_cli_cmd_reassociate
,
2723 "= force reassociation" },
2724 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2726 "<BSSID> = force preauthentication" },
2727 { "identity", wpa_cli_cmd_identity
,
2729 "<network id> <identity> = configure identity for an SSID" },
2730 { "password", wpa_cli_cmd_password
,
2731 cli_cmd_flag_sensitive
,
2732 "<network id> <password> = configure password for an SSID" },
2733 { "new_password", wpa_cli_cmd_new_password
,
2734 cli_cmd_flag_sensitive
,
2735 "<network id> <password> = change password for an SSID" },
2736 { "pin", wpa_cli_cmd_pin
,
2737 cli_cmd_flag_sensitive
,
2738 "<network id> <pin> = configure pin for an SSID" },
2739 { "otp", wpa_cli_cmd_otp
,
2740 cli_cmd_flag_sensitive
,
2741 "<network id> <password> = configure one-time-password for an SSID"
2743 { "passphrase", wpa_cli_cmd_passphrase
,
2744 cli_cmd_flag_sensitive
,
2745 "<network id> <passphrase> = configure private key passphrase\n"
2747 { "bssid", wpa_cli_cmd_bssid
,
2749 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2750 { "blacklist", wpa_cli_cmd_blacklist
,
2752 "<BSSID> = add a BSSID to the blacklist\n"
2753 "blacklist clear = clear the blacklist\n"
2754 "blacklist = display the blacklist" },
2755 { "log_level", wpa_cli_cmd_log_level
,
2757 "<level> [<timestamp>] = update the log level/timestamp\n"
2758 "log_level = display the current log level and log options" },
2759 { "list_networks", wpa_cli_cmd_list_networks
,
2761 "= list configured networks" },
2762 { "select_network", wpa_cli_cmd_select_network
,
2764 "<network id> = select a network (disable others)" },
2765 { "enable_network", wpa_cli_cmd_enable_network
,
2767 "<network id> = enable a network" },
2768 { "disable_network", wpa_cli_cmd_disable_network
,
2770 "<network id> = disable a network" },
2771 { "add_network", wpa_cli_cmd_add_network
,
2773 "= add a network" },
2774 { "remove_network", wpa_cli_cmd_remove_network
,
2776 "<network id> = remove a network" },
2777 { "set_network", wpa_cli_cmd_set_network
,
2778 cli_cmd_flag_sensitive
,
2779 "<network id> <variable> <value> = set network variables (shows\n"
2780 " list of variables when run without arguments)" },
2781 { "get_network", wpa_cli_cmd_get_network
,
2783 "<network id> <variable> = get network variables" },
2784 { "save_config", wpa_cli_cmd_save_config
,
2786 "= save the current configuration" },
2787 { "disconnect", wpa_cli_cmd_disconnect
,
2789 "= disconnect and wait for reassociate/reconnect command before\n"
2791 { "reconnect", wpa_cli_cmd_reconnect
,
2793 "= like reassociate, but only takes effect if already disconnected"
2795 { "scan", wpa_cli_cmd_scan
,
2797 "= request new BSS scan" },
2798 { "scan_results", wpa_cli_cmd_scan_results
,
2800 "= get latest scan results" },
2801 { "bss", wpa_cli_cmd_bss
,
2803 "<<idx> | <bssid>> = get detailed scan result info" },
2804 { "get_capability", wpa_cli_cmd_get_capability
,
2806 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2807 { "reconfigure", wpa_cli_cmd_reconfigure
,
2809 "= force wpa_supplicant to re-read its configuration file" },
2810 { "terminate", wpa_cli_cmd_terminate
,
2812 "= terminate wpa_supplicant" },
2813 { "interface_add", wpa_cli_cmd_interface_add
,
2815 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2816 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2818 { "interface_remove", wpa_cli_cmd_interface_remove
,
2820 "<ifname> = removes the interface" },
2821 { "interface_list", wpa_cli_cmd_interface_list
,
2823 "= list available interfaces" },
2824 { "ap_scan", wpa_cli_cmd_ap_scan
,
2826 "<value> = set ap_scan parameter" },
2827 { "scan_interval", wpa_cli_cmd_scan_interval
,
2829 "<value> = set scan_interval parameter (in seconds)" },
2830 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
,
2832 "<value> = set BSS expiration age parameter" },
2833 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
,
2835 "<value> = set BSS expiration scan count parameter" },
2836 { "stkstart", wpa_cli_cmd_stkstart
,
2838 "<addr> = request STK negotiation with <addr>" },
2839 { "ft_ds", wpa_cli_cmd_ft_ds
,
2841 "<addr> = request over-the-DS FT with <addr>" },
2842 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
2844 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2845 { "wps_pin", wpa_cli_cmd_wps_pin
,
2846 cli_cmd_flag_sensitive
,
2847 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2849 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
2850 cli_cmd_flag_sensitive
,
2851 "<PIN> = verify PIN checksum" },
2852 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
2853 "Cancels the pending WPS operation" },
2854 #ifdef CONFIG_WPS_OOB
2855 { "wps_oob", wpa_cli_cmd_wps_oob
,
2856 cli_cmd_flag_sensitive
,
2857 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2858 #endif /* CONFIG_WPS_OOB */
2859 { "wps_reg", wpa_cli_cmd_wps_reg
,
2860 cli_cmd_flag_sensitive
,
2861 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2862 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
,
2863 cli_cmd_flag_sensitive
,
2864 "[params..] = enable/disable AP PIN" },
2865 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
2867 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2868 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
2870 "= stop Wi-Fi Protected Setup External Registrar" },
2871 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
2872 cli_cmd_flag_sensitive
,
2873 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2874 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
2876 "<UUID> = accept an Enrollee PBC using External Registrar" },
2877 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
2878 cli_cmd_flag_sensitive
,
2879 "<UUID> <PIN> = learn AP configuration" },
2880 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
,
2882 "<UUID> <network id> = set AP configuration for enrolling" },
2883 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
2884 cli_cmd_flag_sensitive
,
2885 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2886 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
2888 "<addr> = request RSN authentication with <addr> in IBSS" },
2890 { "sta", wpa_cli_cmd_sta
,
2892 "<addr> = get information about an associated station (AP)" },
2893 { "all_sta", wpa_cli_cmd_all_sta
,
2895 "= get information about all associated stations (AP)" },
2896 #endif /* CONFIG_AP */
2897 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
2898 "= notification of suspend/hibernate" },
2899 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
2900 "= notification of resume/thaw" },
2901 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
2902 "= drop SA without deauth/disassoc (test command)" },
2903 { "roam", wpa_cli_cmd_roam
,
2905 "<addr> = roam to the specified BSS" },
2907 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
2908 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2909 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
2910 "= stop P2P Devices search" },
2911 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
2912 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2913 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
2914 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2915 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
2916 "<ifname> = remove P2P group interface (terminate group if GO)" },
2917 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
2918 "= add a new P2P group (local end as GO)" },
2919 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
2920 "<addr> <method> = request provisioning discovery" },
2921 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
2923 "= get the passphrase for a group (GO only)" },
2924 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2926 "<addr> <TLVs> = schedule service discovery request" },
2927 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2929 "<id> = cancel pending service discovery request" },
2930 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2932 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2933 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2935 "= indicate change in local services" },
2936 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2938 "<external> = set external processing of service discovery" },
2939 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2941 "= remove all stored service entries" },
2942 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2944 "<bonjour|upnp> <query|version> <response|service> = add a local "
2946 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2948 "<bonjour|upnp> <query|version> [|service] = remove a local "
2950 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2952 "<addr> = reject connection attempts from a specific peer" },
2953 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
2955 "<cmd> [peer=addr] = invite peer" },
2956 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
2957 "[discovered] = list known (optionally, only fully discovered) P2P "
2959 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
2960 "<address> = show information about known P2P peer" },
2961 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
2962 "<field> <value> = set a P2P parameter" },
2963 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
2964 "= flush P2P state" },
2965 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
2966 "= cancel P2P group formation" },
2967 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
, cli_cmd_flag_none
,
2968 "<address> = unauthorize a peer" },
2969 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
2970 "[<duration> <interval>] [<duration> <interval>] = request GO "
2972 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
2973 "[<period> <interval>] = set extended listen timing" },
2974 #endif /* CONFIG_P2P */
2976 #ifdef CONFIG_INTERWORKING
2977 { "fetch_anqp", wpa_cli_cmd_fetch_anqp
, cli_cmd_flag_none
,
2978 "= fetch ANQP information for all APs" },
2979 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp
, cli_cmd_flag_none
,
2980 "= stop fetch_anqp operation" },
2981 { "interworking_select", wpa_cli_cmd_interworking_select
,
2983 "[auto] = perform Interworking network selection" },
2984 { "interworking_connect", wpa_cli_cmd_interworking_connect
,
2986 "<BSSID> = connect using Interworking credentials" },
2987 { "anqp_get", wpa_cli_cmd_anqp_get
, cli_cmd_flag_none
,
2988 "<addr> <info id>[,<info id>]... = request ANQP information" },
2989 #endif /* CONFIG_INTERWORKING */
2990 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
2991 "<0/1> = disable/enable automatic reconnection" },
2992 { "tdls_discover", wpa_cli_cmd_tdls_discover
,
2994 "<addr> = request TDLS discovery with <addr>" },
2995 { "tdls_setup", wpa_cli_cmd_tdls_setup
,
2997 "<addr> = request TDLS setup with <addr>" },
2998 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
,
3000 "<addr> = tear down TDLS with <addr>" },
3001 { "signal_poll", wpa_cli_cmd_signal_poll
,
3003 "= get signal parameters" },
3004 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
3009 * Prints command usage, lines are padded with the specified string.
3011 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
3016 printf("%s%s ", pad
, cmd
->cmd
);
3017 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
3026 static void print_help(void)
3029 printf("commands:\n");
3030 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
3031 print_cmd_help(&wpa_cli_commands
[n
], " ");
3035 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
3037 const char *c
, *delim
;
3041 delim
= os_strchr(cmd
, ' ');
3045 len
= os_strlen(cmd
);
3047 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
3048 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
3049 return (wpa_cli_commands
[n
].flags
&
3050 cli_cmd_flag_sensitive
);
3056 static char ** wpa_list_cmd_list(void)
3061 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
3062 res
= os_zalloc(count
* sizeof(char *));
3066 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
3067 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
3076 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
3081 if (os_strcasecmp(cmd
, "bss") == 0)
3082 return wpa_cli_complete_bss(str
, pos
);
3084 if (os_strcasecmp(cmd
, "p2p_connect") == 0)
3085 return wpa_cli_complete_p2p_connect(str
, pos
);
3086 if (os_strcasecmp(cmd
, "p2p_peer") == 0)
3087 return wpa_cli_complete_p2p_peer(str
, pos
);
3088 if (os_strcasecmp(cmd
, "p2p_group_remove") == 0)
3089 return wpa_cli_complete_p2p_group_remove(str
, pos
);
3090 #endif /* CONFIG_P2P */
3092 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
3093 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
3095 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
3105 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
3111 end
= os_strchr(str
, ' ');
3112 if (end
== NULL
|| str
+ pos
< end
)
3113 return wpa_list_cmd_list();
3115 cmd
= os_malloc(pos
+ 1);
3118 os_memcpy(cmd
, str
, pos
);
3119 cmd
[end
- str
] = '\0';
3120 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
3126 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
3128 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
3133 cmd
= wpa_cli_commands
;
3135 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
3138 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
3139 /* we have an exact match */
3149 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
3150 cmd
= wpa_cli_commands
;
3152 if (os_strncasecmp(cmd
->cmd
, argv
[0],
3153 os_strlen(argv
[0])) == 0) {
3154 printf(" %s", cmd
->cmd
);
3160 } else if (count
== 0) {
3161 printf("Unknown command '%s'\n", argv
[0]);
3164 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
3171 static int str_match(const char *a
, const char *b
)
3173 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
3177 static int wpa_cli_exec(const char *program
, const char *arg1
,
3185 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
3186 cmd
= os_malloc(len
);
3189 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
3190 if (res
< 0 || (size_t) res
>= len
) {
3194 cmd
[len
- 1] = '\0';
3196 if (system(cmd
) < 0)
3198 #endif /* _WIN32_WCE */
3205 static void wpa_cli_action_process(const char *msg
)
3208 char *copy
= NULL
, *id
, *pos2
;
3213 pos
= os_strchr(pos
, '>');
3220 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
3222 os_unsetenv("WPA_ID");
3223 os_unsetenv("WPA_ID_STR");
3224 os_unsetenv("WPA_CTRL_DIR");
3226 pos
= os_strstr(pos
, "[id=");
3228 copy
= os_strdup(pos
+ 4);
3232 while (*pos2
&& *pos2
!= ' ')
3236 os_setenv("WPA_ID", id
, 1);
3237 while (*pos2
&& *pos2
!= '=')
3242 while (*pos2
&& *pos2
!= ']')
3245 os_setenv("WPA_ID_STR", id
, 1);
3249 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
3251 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
3252 wpa_cli_connected
= 1;
3253 wpa_cli_last_id
= new_id
;
3254 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
3256 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
3257 if (wpa_cli_connected
) {
3258 wpa_cli_connected
= 0;
3259 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
3261 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
3262 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3263 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
3264 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3265 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
3266 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3267 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
3268 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3269 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
3270 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3271 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
3272 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3273 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
3274 printf("wpa_supplicant is terminating - stop monitoring\n");
3280 #ifndef CONFIG_ANSI_C_EXTRA
3281 static void wpa_cli_action_cb(char *msg
, size_t len
)
3283 wpa_cli_action_process(msg
);
3285 #endif /* CONFIG_ANSI_C_EXTRA */
3288 static void wpa_cli_reconnect(void)
3290 wpa_cli_close_connection();
3291 wpa_cli_open_connection(ctrl_ifname
, 1);
3295 static void cli_event(const char *str
)
3297 const char *start
, *s
;
3299 start
= os_strchr(str
, '>');
3305 if (str_starts(start
, WPA_EVENT_BSS_ADDED
)) {
3306 s
= os_strchr(start
, ' ');
3309 s
= os_strchr(s
+ 1, ' ');
3312 cli_txt_list_add(&bsses
, s
+ 1);
3316 if (str_starts(start
, WPA_EVENT_BSS_REMOVED
)) {
3317 s
= os_strchr(start
, ' ');
3320 s
= os_strchr(s
+ 1, ' ');
3323 cli_txt_list_del_addr(&bsses
, s
+ 1);
3328 if (str_starts(start
, P2P_EVENT_DEVICE_FOUND
)) {
3329 s
= os_strstr(start
, " p2p_dev_addr=");
3332 cli_txt_list_add_addr(&p2p_peers
, s
+ 14);
3336 if (str_starts(start
, P2P_EVENT_DEVICE_LOST
)) {
3337 s
= os_strstr(start
, " p2p_dev_addr=");
3340 cli_txt_list_del_addr(&p2p_peers
, s
+ 14);
3344 if (str_starts(start
, P2P_EVENT_GROUP_STARTED
)) {
3345 s
= os_strchr(start
, ' ');
3348 cli_txt_list_add_word(&p2p_groups
, s
+ 1);
3352 if (str_starts(start
, P2P_EVENT_GROUP_REMOVED
)) {
3353 s
= os_strchr(start
, ' ');
3356 cli_txt_list_del_word(&p2p_groups
, s
+ 1);
3359 #endif /* CONFIG_P2P */
3363 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
3365 if (ctrl_conn
== NULL
) {
3366 wpa_cli_reconnect();
3369 while (wpa_ctrl_pending(ctrl
) > 0) {
3371 size_t len
= sizeof(buf
) - 1;
3372 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
3375 wpa_cli_action_process(buf
);
3378 if (wpa_cli_show_event(buf
)) {
3380 printf("\r%s\n", buf
);
3385 printf("Could not read pending message.\n");
3390 if (wpa_ctrl_pending(ctrl
) < 0) {
3391 printf("Connection to wpa_supplicant lost - trying to "
3393 wpa_cli_reconnect();
3399 static int tokenize_cmd(char *cmd
, char *argv
[])
3412 if (argc
== max_args
)
3415 char *pos2
= os_strrchr(pos
, '"');
3419 while (*pos
!= '\0' && *pos
!= ' ')
3429 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
3431 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3432 printf("Connection to wpa_supplicant lost - trying to "
3434 wpa_cli_close_connection();
3437 wpa_cli_reconnect();
3438 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3442 static void wpa_cli_eloop_terminate(int sig
, void *signal_ctx
)
3448 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
3450 wpa_cli_recv_pending(mon_conn
, 0);
3454 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
3456 char *argv
[max_args
];
3458 argc
= tokenize_cmd(cmd
, argv
);
3460 wpa_request(ctrl_conn
, argc
, argv
);
3464 static void wpa_cli_edit_eof_cb(void *ctx
)
3470 static void wpa_cli_interactive(void)
3472 char *home
, *hfile
= NULL
;
3474 printf("\nInteractive mode\n\n");
3476 home
= getenv("HOME");
3478 const char *fname
= ".wpa_cli_history";
3479 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
3480 hfile
= os_malloc(hfile_len
);
3482 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
3485 eloop_register_signal_terminate(wpa_cli_eloop_terminate
, NULL
);
3486 edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
3487 wpa_cli_edit_completion_cb
, NULL
, hfile
);
3488 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3492 cli_txt_list_flush(&p2p_peers
);
3493 cli_txt_list_flush(&p2p_groups
);
3494 cli_txt_list_flush(&bsses
);
3495 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3497 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3498 wpa_cli_close_connection();
3502 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3504 #ifdef CONFIG_ANSI_C_EXTRA
3505 /* TODO: ANSI C version(?) */
3506 printf("Action processing not supported in ANSI C build.\n");
3507 #else /* CONFIG_ANSI_C_EXTRA */
3511 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3514 fd
= wpa_ctrl_get_fd(ctrl
);
3516 while (!wpa_cli_quit
) {
3519 tv
.tv_sec
= ping_interval
;
3521 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3522 if (res
< 0 && errno
!= EINTR
) {
3527 if (FD_ISSET(fd
, &rfds
))
3528 wpa_cli_recv_pending(ctrl
, 1);
3530 /* verify that connection is still working */
3531 len
= sizeof(buf
) - 1;
3532 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3533 wpa_cli_action_cb
) < 0 ||
3534 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3535 printf("wpa_supplicant did not reply to PING "
3536 "command - exiting\n");
3541 #endif /* CONFIG_ANSI_C_EXTRA */
3545 static void wpa_cli_cleanup(void)
3547 wpa_cli_close_connection();
3549 os_daemonize_terminate(pid_file
);
3551 os_program_deinit();
3554 static void wpa_cli_terminate(int sig
)
3561 static char * wpa_cli_get_default_ifname(void)
3563 char *ifname
= NULL
;
3565 #ifdef CONFIG_CTRL_IFACE_UNIX
3566 struct dirent
*dent
;
3567 DIR *dir
= opendir(ctrl_iface_dir
);
3570 char ifprop
[PROPERTY_VALUE_MAX
];
3571 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3572 ifname
= os_strdup(ifprop
);
3573 printf("Using interface '%s'\n", ifname
);
3576 #endif /* ANDROID */
3579 while ((dent
= readdir(dir
))) {
3580 #ifdef _DIRENT_HAVE_D_TYPE
3582 * Skip the file if it is not a socket. Also accept
3583 * DT_UNKNOWN (0) in case the C library or underlying
3584 * file system does not support d_type.
3586 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3588 #endif /* _DIRENT_HAVE_D_TYPE */
3589 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3590 os_strcmp(dent
->d_name
, "..") == 0)
3592 printf("Selected interface '%s'\n", dent
->d_name
);
3593 ifname
= os_strdup(dent
->d_name
);
3597 #endif /* CONFIG_CTRL_IFACE_UNIX */
3599 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3600 char buf
[2048], *pos
;
3602 struct wpa_ctrl
*ctrl
;
3605 ctrl
= wpa_ctrl_open(NULL
);
3609 len
= sizeof(buf
) - 1;
3610 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3613 pos
= os_strchr(buf
, '\n');
3616 ifname
= os_strdup(buf
);
3618 wpa_ctrl_close(ctrl
);
3619 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3625 int main(int argc
, char *argv
[])
3627 int warning_displayed
= 0;
3631 const char *global
= NULL
;
3633 if (os_program_init())
3637 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3642 action_file
= optarg
;
3651 ping_interval
= atoi(optarg
);
3657 printf("%s\n", wpa_cli_version
);
3660 os_free(ctrl_ifname
);
3661 ctrl_ifname
= os_strdup(optarg
);
3664 ctrl_iface_dir
= optarg
;
3675 interactive
= (argc
== optind
) && (action_file
== NULL
);
3678 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3684 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3685 ctrl_conn
= wpa_ctrl_open(NULL
);
3686 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3687 ctrl_conn
= wpa_ctrl_open(global
);
3688 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3689 if (ctrl_conn
== NULL
) {
3690 perror("Failed to connect to wpa_supplicant - "
3697 signal(SIGINT
, wpa_cli_terminate
);
3698 signal(SIGTERM
, wpa_cli_terminate
);
3699 #endif /* _WIN32_WCE */
3701 if (ctrl_ifname
== NULL
)
3702 ctrl_ifname
= wpa_cli_get_default_ifname();
3706 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3707 if (warning_displayed
)
3708 printf("Connection established.\n");
3712 if (!warning_displayed
) {
3713 printf("Could not connect to wpa_supplicant - "
3715 warning_displayed
= 1;
3722 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3723 perror("Failed to connect to wpa_supplicant - "
3729 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3730 wpa_cli_attached
= 1;
3732 printf("Warning: Failed to attach to "
3733 "wpa_supplicant.\n");
3739 if (daemonize
&& os_daemonize(pid_file
))
3743 wpa_cli_interactive();
3744 else if (action_file
)
3745 wpa_cli_action(ctrl_conn
);
3747 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
3749 os_free(ctrl_ifname
);
3756 #else /* CONFIG_CTRL_IFACE */
3757 int main(int argc
, char *argv
[])
3759 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3762 #endif /* CONFIG_CTRL_IFACE */