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
);
188 static void cli_txt_list_del_word(struct dl_list
*txt_list
, const char *txt
)
192 end
= os_strchr(txt
, ' ');
194 end
= txt
+ os_strlen(txt
);
195 buf
= os_malloc(end
- txt
+ 1);
198 os_memcpy(buf
, txt
, end
- txt
);
199 buf
[end
- txt
] = '\0';
200 cli_txt_list_del(txt_list
, buf
);
203 #endif /* CONFIG_P2P */
206 static int cli_txt_list_add(struct dl_list
*txt_list
, const char *txt
)
208 struct cli_txt_entry
*e
;
209 e
= cli_txt_list_get(txt_list
, txt
);
212 e
= os_zalloc(sizeof(*e
));
215 e
->txt
= os_strdup(txt
);
216 if (e
->txt
== NULL
) {
220 dl_list_add(txt_list
, &e
->list
);
226 static int cli_txt_list_add_addr(struct dl_list
*txt_list
, const char *txt
)
230 if (hwaddr_aton(txt
, addr
) < 0)
232 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
233 return cli_txt_list_add(txt_list
, buf
);
237 static int cli_txt_list_add_word(struct dl_list
*txt_list
, const char *txt
)
242 end
= os_strchr(txt
, ' ');
244 end
= txt
+ os_strlen(txt
);
245 buf
= os_malloc(end
- txt
+ 1);
248 os_memcpy(buf
, txt
, end
- txt
);
249 buf
[end
- txt
] = '\0';
250 ret
= cli_txt_list_add(txt_list
, buf
);
254 #endif /* CONFIG_P2P */
257 static char ** cli_txt_list_array(struct dl_list
*txt_list
)
259 unsigned int i
, count
= dl_list_len(txt_list
);
261 struct cli_txt_entry
*e
;
263 res
= os_zalloc((count
+ 1) * sizeof(char *));
268 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
269 res
[i
] = os_strdup(e
->txt
);
279 static int get_cmd_arg_num(const char *str
, int pos
)
283 for (i
= 0; i
<= pos
; i
++) {
286 while (i
<= pos
&& str
[i
] != ' ')
297 static int str_starts(const char *src
, const char *match
)
299 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
303 static int wpa_cli_show_event(const char *event
)
307 start
= os_strchr(event
, '>');
313 * Skip BSS added/removed events since they can be relatively frequent
314 * and are likely of not much use for an interactive user.
316 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
317 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
324 static int wpa_cli_open_connection(const char *ifname
, int attach
)
326 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
327 ctrl_conn
= wpa_ctrl_open(ifname
);
328 if (ctrl_conn
== NULL
)
331 if (attach
&& interactive
)
332 mon_conn
= wpa_ctrl_open(ifname
);
335 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
343 if (access(ctrl_iface_dir
, F_OK
) < 0) {
344 cfile
= os_strdup(ifname
);
351 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
352 cfile
= os_malloc(flen
);
355 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
,
357 if (res
< 0 || res
>= flen
) {
363 ctrl_conn
= wpa_ctrl_open(cfile
);
364 if (ctrl_conn
== NULL
) {
369 if (attach
&& interactive
)
370 mon_conn
= wpa_ctrl_open(cfile
);
374 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
377 if (wpa_ctrl_attach(mon_conn
) == 0) {
378 wpa_cli_attached
= 1;
380 eloop_register_read_sock(
381 wpa_ctrl_get_fd(mon_conn
),
382 wpa_cli_mon_receive
, NULL
, NULL
);
384 printf("Warning: Failed to attach to "
385 "wpa_supplicant.\n");
394 static void wpa_cli_close_connection(void)
396 if (ctrl_conn
== NULL
)
399 if (wpa_cli_attached
) {
400 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
401 wpa_cli_attached
= 0;
403 wpa_ctrl_close(ctrl_conn
);
406 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
407 wpa_ctrl_close(mon_conn
);
413 static void wpa_cli_msg_cb(char *msg
, size_t len
)
419 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
425 if (ctrl_conn
== NULL
) {
426 printf("Not connected to wpa_supplicant - command dropped.\n");
429 len
= sizeof(buf
) - 1;
430 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
433 printf("'%s' command timed out.\n", cmd
);
435 } else if (ret
< 0) {
436 printf("'%s' command failed.\n", cmd
);
442 if (interactive
&& len
> 0 && buf
[len
- 1] != '\n')
449 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
451 return _wpa_ctrl_command(ctrl
, cmd
, 1);
455 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
457 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
458 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
462 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
464 return wpa_ctrl_command(ctrl
, "PING");
468 static int wpa_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
470 return wpa_ctrl_command(ctrl
, "RELOG");
474 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
480 ret
= os_snprintf(cmd
, sizeof(cmd
), "NOTE %s", argv
[0]);
481 if (ret
< 0 || (size_t) ret
>= sizeof(cmd
))
483 return wpa_ctrl_command(ctrl
, cmd
);
487 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
489 return wpa_ctrl_command(ctrl
, "MIB");
493 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
495 return wpa_ctrl_command(ctrl
, "PMKSA");
499 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
506 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
508 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
513 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
522 static void wpa_cli_show_variables(void)
524 printf("set variables:\n"
525 " EAPOL::heldPeriod (EAPOL state machine held period, "
527 " EAPOL::authPeriod (EAPOL state machine authentication "
528 "period, in seconds)\n"
529 " EAPOL::startPeriod (EAPOL state machine start period, in "
531 " EAPOL::maxStart (EAPOL state machine maximum start "
533 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
535 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
536 " threshold\n\tpercentage)\n"
537 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
538 "security\n\tassociation in seconds)\n");
542 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
548 wpa_cli_show_variables();
552 if (argc
!= 1 && argc
!= 2) {
553 printf("Invalid SET command: needs two arguments (variable "
554 "name and value)\n");
559 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s ", argv
[0]);
561 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s",
563 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
564 printf("Too long SET command.\n");
567 return wpa_ctrl_command(ctrl
, cmd
);
571 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
577 printf("Invalid GET command: need one argument (variable "
582 res
= os_snprintf(cmd
, sizeof(cmd
), "GET %s", argv
[0]);
583 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
584 printf("Too long GET command.\n");
587 return wpa_ctrl_command(ctrl
, cmd
);
591 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
593 return wpa_ctrl_command(ctrl
, "LOGOFF");
597 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
599 return wpa_ctrl_command(ctrl
, "LOGON");
603 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
606 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
610 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
617 printf("Invalid PREAUTH command: needs one argument "
622 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
623 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
624 printf("Too long PREAUTH command.\n");
627 return wpa_ctrl_command(ctrl
, cmd
);
631 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
637 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
641 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
642 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
643 printf("Too long AP_SCAN command.\n");
646 return wpa_ctrl_command(ctrl
, cmd
);
650 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl
*ctrl
, int argc
,
657 printf("Invalid SCAN_INTERVAL command: needs one argument "
658 "scan_interval value)\n");
661 res
= os_snprintf(cmd
, sizeof(cmd
), "SCAN_INTERVAL %s", argv
[0]);
662 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
663 printf("Too long SCAN_INTERVAL command.\n");
666 return wpa_ctrl_command(ctrl
, cmd
);
670 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl
*ctrl
, int argc
,
677 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
678 "(bss_expire_age value)\n");
681 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_EXPIRE_AGE %s", argv
[0]);
682 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
683 printf("Too long BSS_EXPIRE_AGE command.\n");
686 return wpa_ctrl_command(ctrl
, cmd
);
690 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl
*ctrl
, int argc
,
697 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
698 "(bss_expire_count value)\n");
701 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_EXPIRE_COUNT %s", argv
[0]);
702 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
703 printf("Too long BSS_EXPIRE_COUNT command.\n");
706 return wpa_ctrl_command(ctrl
, cmd
);
710 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
717 printf("Invalid STKSTART command: needs one argument "
718 "(Peer STA MAC address)\n");
722 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
723 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
724 printf("Too long STKSTART command.\n");
727 return wpa_ctrl_command(ctrl
, cmd
);
731 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
737 printf("Invalid FT_DS command: needs one argument "
738 "(Target AP MAC address)\n");
742 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
743 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
744 printf("Too long FT_DS command.\n");
747 return wpa_ctrl_command(ctrl
, cmd
);
751 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
758 return wpa_ctrl_command(ctrl
, "WPS_PBC");
762 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
763 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
764 printf("Too long WPS_PBC command.\n");
767 return wpa_ctrl_command(ctrl
, cmd
);
771 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
777 printf("Invalid WPS_PIN command: need one or two arguments:\n"
778 "- BSSID: use 'any' to select any\n"
779 "- PIN: optional, used only with devices that have no "
785 /* Use dynamically generated PIN (returned as reply) */
786 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
787 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
788 printf("Too long WPS_PIN command.\n");
791 return wpa_ctrl_command(ctrl
, cmd
);
794 /* Use hardcoded PIN from a label */
795 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
796 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
797 printf("Too long WPS_PIN command.\n");
800 return wpa_ctrl_command(ctrl
, cmd
);
804 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
810 if (argc
!= 1 && argc
!= 2) {
811 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
812 "- PIN to be verified\n");
817 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
820 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
822 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
823 printf("Too long WPS_CHECK_PIN command.\n");
826 return wpa_ctrl_command(ctrl
, cmd
);
830 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
833 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
837 #ifdef CONFIG_WPS_OOB
838 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
843 if (argc
!= 3 && argc
!= 4) {
844 printf("Invalid WPS_OOB command: need three or four "
846 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
847 "- PATH: path of OOB device like '/mnt'\n"
848 "- METHOD: OOB method 'pin-e' or 'pin-r', "
850 "- DEV_NAME: (only for NFC) device name like "
856 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
857 argv
[0], argv
[1], argv
[2]);
859 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
860 argv
[0], argv
[1], argv
[2], argv
[3]);
861 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
862 printf("Too long WPS_OOB command.\n");
865 return wpa_ctrl_command(ctrl
, cmd
);
867 #endif /* CONFIG_WPS_OOB */
870 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
876 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
878 else if (argc
== 5 || argc
== 6) {
879 char ssid_hex
[2 * 32 + 1];
880 char key_hex
[2 * 64 + 1];
884 for (i
= 0; i
< 32; i
++) {
885 if (argv
[2][i
] == '\0')
887 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
892 for (i
= 0; i
< 64; i
++) {
893 if (argv
[5][i
] == '\0')
895 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
900 res
= os_snprintf(cmd
, sizeof(cmd
),
901 "WPS_REG %s %s %s %s %s %s",
902 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
905 printf("Invalid WPS_REG command: need two arguments:\n"
906 "- BSSID of the target AP\n"
908 printf("Alternatively, six arguments can be used to "
909 "reconfigure the AP:\n"
910 "- BSSID of the target AP\n"
913 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
914 "- new encr (NONE, WEP, TKIP, CCMP)\n"
919 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
920 printf("Too long WPS_REG command.\n");
923 return wpa_ctrl_command(ctrl
, cmd
);
927 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
934 printf("Invalid WPS_AP_PIN command: needs at least one "
940 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s %s",
941 argv
[0], argv
[1], argv
[2]);
943 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s",
946 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s",
948 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
949 printf("Too long WPS_AP_PIN command.\n");
952 return wpa_ctrl_command(ctrl
, cmd
);
956 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
961 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
962 return wpa_ctrl_command(ctrl
, cmd
);
964 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
968 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
971 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
976 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
983 printf("Invalid WPS_ER_PIN command: need at least two "
985 "- UUID: use 'any' to select any\n"
986 "- PIN: Enrollee PIN\n"
987 "optional: - Enrollee MAC address\n");
992 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
993 argv
[0], argv
[1], argv
[2]);
995 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
997 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
998 printf("Too long WPS_ER_PIN command.\n");
1001 return wpa_ctrl_command(ctrl
, cmd
);
1005 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
1012 printf("Invalid WPS_ER_PBC command: need one argument:\n"
1013 "- UUID: Specify the Enrollee\n");
1017 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
1019 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1020 printf("Too long WPS_ER_PBC command.\n");
1023 return wpa_ctrl_command(ctrl
, cmd
);
1027 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
1034 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1035 "- UUID: specify which AP to use\n"
1040 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
1042 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1043 printf("Too long WPS_ER_LEARN command.\n");
1046 return wpa_ctrl_command(ctrl
, cmd
);
1050 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
1057 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1059 "- UUID: specify which AP to use\n"
1060 "- Network configuration id\n");
1064 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_SET_CONFIG %s %s",
1066 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1067 printf("Too long WPS_ER_SET_CONFIG command.\n");
1070 return wpa_ctrl_command(ctrl
, cmd
);
1074 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
1080 if (argc
== 5 || argc
== 6) {
1081 char ssid_hex
[2 * 32 + 1];
1082 char key_hex
[2 * 64 + 1];
1086 for (i
= 0; i
< 32; i
++) {
1087 if (argv
[2][i
] == '\0')
1089 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
1094 for (i
= 0; i
< 64; i
++) {
1095 if (argv
[5][i
] == '\0')
1097 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
1102 res
= os_snprintf(cmd
, sizeof(cmd
),
1103 "WPS_ER_CONFIG %s %s %s %s %s %s",
1104 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
1107 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1111 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1112 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1117 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1118 printf("Too long WPS_ER_CONFIG command.\n");
1121 return wpa_ctrl_command(ctrl
, cmd
);
1125 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1131 printf("Invalid IBSS_RSN command: needs one argument "
1132 "(Peer STA MAC address)\n");
1136 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
1137 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1138 printf("Too long IBSS_RSN command.\n");
1141 return wpa_ctrl_command(ctrl
, cmd
);
1145 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1151 printf("Invalid LEVEL command: needs one argument (debug "
1155 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
1156 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1157 printf("Too long LEVEL command.\n");
1160 return wpa_ctrl_command(ctrl
, cmd
);
1164 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1166 char cmd
[256], *pos
, *end
;
1170 printf("Invalid IDENTITY command: needs two arguments "
1171 "(network id and identity)\n");
1175 end
= cmd
+ sizeof(cmd
);
1177 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
1179 if (ret
< 0 || ret
>= end
- pos
) {
1180 printf("Too long IDENTITY command.\n");
1184 for (i
= 2; i
< argc
; i
++) {
1185 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1186 if (ret
< 0 || ret
>= end
- pos
) {
1187 printf("Too long IDENTITY command.\n");
1193 return wpa_ctrl_command(ctrl
, cmd
);
1197 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1199 char cmd
[256], *pos
, *end
;
1203 printf("Invalid PASSWORD command: needs two arguments "
1204 "(network id and password)\n");
1208 end
= cmd
+ sizeof(cmd
);
1210 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1212 if (ret
< 0 || ret
>= end
- pos
) {
1213 printf("Too long PASSWORD command.\n");
1217 for (i
= 2; i
< argc
; i
++) {
1218 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1219 if (ret
< 0 || ret
>= end
- pos
) {
1220 printf("Too long PASSWORD command.\n");
1226 return wpa_ctrl_command(ctrl
, cmd
);
1230 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1233 char cmd
[256], *pos
, *end
;
1237 printf("Invalid NEW_PASSWORD command: needs two arguments "
1238 "(network id and password)\n");
1242 end
= cmd
+ sizeof(cmd
);
1244 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1246 if (ret
< 0 || ret
>= end
- pos
) {
1247 printf("Too long NEW_PASSWORD command.\n");
1251 for (i
= 2; i
< argc
; i
++) {
1252 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1253 if (ret
< 0 || ret
>= end
- pos
) {
1254 printf("Too long NEW_PASSWORD command.\n");
1260 return wpa_ctrl_command(ctrl
, cmd
);
1264 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1266 char cmd
[256], *pos
, *end
;
1270 printf("Invalid PIN command: needs two arguments "
1271 "(network id and pin)\n");
1275 end
= cmd
+ sizeof(cmd
);
1277 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1279 if (ret
< 0 || ret
>= end
- pos
) {
1280 printf("Too long PIN command.\n");
1284 for (i
= 2; i
< argc
; i
++) {
1285 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1286 if (ret
< 0 || ret
>= end
- pos
) {
1287 printf("Too long PIN command.\n");
1292 return wpa_ctrl_command(ctrl
, cmd
);
1296 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1298 char cmd
[256], *pos
, *end
;
1302 printf("Invalid OTP command: needs two arguments (network "
1303 "id and password)\n");
1307 end
= cmd
+ sizeof(cmd
);
1309 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1311 if (ret
< 0 || ret
>= end
- pos
) {
1312 printf("Too long OTP command.\n");
1316 for (i
= 2; i
< argc
; i
++) {
1317 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1318 if (ret
< 0 || ret
>= end
- pos
) {
1319 printf("Too long OTP command.\n");
1325 return wpa_ctrl_command(ctrl
, cmd
);
1329 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1332 char cmd
[256], *pos
, *end
;
1336 printf("Invalid PASSPHRASE command: needs two arguments "
1337 "(network id and passphrase)\n");
1341 end
= cmd
+ sizeof(cmd
);
1343 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1345 if (ret
< 0 || ret
>= end
- pos
) {
1346 printf("Too long PASSPHRASE command.\n");
1350 for (i
= 2; i
< argc
; i
++) {
1351 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1352 if (ret
< 0 || ret
>= end
- pos
) {
1353 printf("Too long PASSPHRASE command.\n");
1359 return wpa_ctrl_command(ctrl
, cmd
);
1363 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1365 char cmd
[256], *pos
, *end
;
1369 printf("Invalid BSSID command: needs two arguments (network "
1374 end
= cmd
+ sizeof(cmd
);
1376 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1377 if (ret
< 0 || ret
>= end
- pos
) {
1378 printf("Too long BSSID command.\n");
1382 for (i
= 0; i
< argc
; i
++) {
1383 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1384 if (ret
< 0 || ret
>= end
- pos
) {
1385 printf("Too long BSSID command.\n");
1391 return wpa_ctrl_command(ctrl
, cmd
);
1395 static int wpa_cli_cmd_blacklist(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1397 char cmd
[256], *pos
, *end
;
1400 end
= cmd
+ sizeof(cmd
);
1402 ret
= os_snprintf(pos
, end
- pos
, "BLACKLIST");
1403 if (ret
< 0 || ret
>= end
- pos
) {
1404 printf("Too long BLACKLIST command.\n");
1408 for (i
= 0; i
< argc
; i
++) {
1409 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1410 if (ret
< 0 || ret
>= end
- pos
) {
1411 printf("Too long BLACKLIST command.\n");
1417 return wpa_ctrl_command(ctrl
, cmd
);
1421 static int wpa_cli_cmd_log_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1423 char cmd
[256], *pos
, *end
;
1426 end
= cmd
+ sizeof(cmd
);
1428 ret
= os_snprintf(pos
, end
- pos
, "LOG_LEVEL");
1429 if (ret
< 0 || ret
>= end
- pos
) {
1430 printf("Too long LOG_LEVEL command.\n");
1434 for (i
= 0; i
< argc
; i
++) {
1435 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1436 if (ret
< 0 || ret
>= end
- pos
) {
1437 printf("Too long LOG_LEVEL command.\n");
1443 return wpa_ctrl_command(ctrl
, cmd
);
1447 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1450 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1454 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1461 printf("Invalid SELECT_NETWORK command: needs one argument "
1466 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1467 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1469 cmd
[sizeof(cmd
) - 1] = '\0';
1471 return wpa_ctrl_command(ctrl
, cmd
);
1475 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1482 printf("Invalid ENABLE_NETWORK command: needs one argument "
1487 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1488 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1490 cmd
[sizeof(cmd
) - 1] = '\0';
1492 return wpa_ctrl_command(ctrl
, cmd
);
1496 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1503 printf("Invalid DISABLE_NETWORK command: needs one argument "
1508 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1509 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1511 cmd
[sizeof(cmd
) - 1] = '\0';
1513 return wpa_ctrl_command(ctrl
, cmd
);
1517 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1520 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1524 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1531 printf("Invalid REMOVE_NETWORK command: needs one argument "
1536 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1537 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1539 cmd
[sizeof(cmd
) - 1] = '\0';
1541 return wpa_ctrl_command(ctrl
, cmd
);
1545 static void wpa_cli_show_network_variables(void)
1547 printf("set_network variables:\n"
1548 " ssid (network name, SSID)\n"
1549 " psk (WPA passphrase or pre-shared key)\n"
1550 " key_mgmt (key management protocol)\n"
1551 " identity (EAP identity)\n"
1552 " password (EAP password)\n"
1555 "Note: Values are entered in the same format as the "
1556 "configuration file is using,\n"
1557 "i.e., strings values need to be inside double quotation "
1559 "For example: set_network 1 ssid \"network name\"\n"
1561 "Please see wpa_supplicant.conf documentation for full list "
1562 "of\navailable variables.\n");
1566 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1573 wpa_cli_show_network_variables();
1578 printf("Invalid SET_NETWORK command: needs three arguments\n"
1579 "(network id, variable name, and value)\n");
1583 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1584 argv
[0], argv
[1], argv
[2]);
1585 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1586 printf("Too long SET_NETWORK command.\n");
1589 return wpa_ctrl_command(ctrl
, cmd
);
1593 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1600 wpa_cli_show_network_variables();
1605 printf("Invalid GET_NETWORK command: needs two arguments\n"
1606 "(network id and variable name)\n");
1610 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1612 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1613 printf("Too long GET_NETWORK command.\n");
1616 return wpa_ctrl_command(ctrl
, cmd
);
1620 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1623 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1627 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1630 return wpa_ctrl_command(ctrl
, "RECONNECT");
1634 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1637 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1641 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1643 return wpa_ctrl_command(ctrl
, "SCAN");
1647 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1650 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1654 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1660 printf("Invalid BSS command: need one argument (index or "
1665 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1666 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1668 cmd
[sizeof(cmd
) - 1] = '\0';
1670 return wpa_ctrl_command(ctrl
, cmd
);
1674 static char ** wpa_cli_complete_bss(const char *str
, int pos
)
1676 int arg
= get_cmd_arg_num(str
, pos
);
1681 res
= cli_txt_list_array(&bsses
);
1689 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1695 if (argc
< 1 || argc
> 2) {
1696 printf("Invalid GET_CAPABILITY command: need either one or "
1701 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1702 printf("Invalid GET_CAPABILITY command: second argument, "
1703 "if any, must be 'strict'\n");
1707 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1708 (argc
== 2) ? " strict" : "");
1709 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1711 cmd
[sizeof(cmd
) - 1] = '\0';
1713 return wpa_ctrl_command(ctrl
, cmd
);
1717 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1719 printf("Available interfaces:\n");
1720 return wpa_ctrl_command(ctrl
, "INTERFACES");
1724 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1727 wpa_cli_list_interfaces(ctrl
);
1731 wpa_cli_close_connection();
1732 os_free(ctrl_ifname
);
1733 ctrl_ifname
= os_strdup(argv
[0]);
1735 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1736 printf("Connected to interface '%s.\n", ctrl_ifname
);
1738 printf("Could not connect to interface '%s' - re-trying\n",
1745 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1748 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1752 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1755 return wpa_ctrl_command(ctrl
, "TERMINATE");
1759 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1766 printf("Invalid INTERFACE_ADD command: needs at least one "
1767 "argument (interface name)\n"
1768 "All arguments: ifname confname driver ctrl_interface "
1769 "driver_param bridge_name\n");
1774 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1775 * <driver_param>TAB<bridge_name>
1777 res
= os_snprintf(cmd
, sizeof(cmd
),
1778 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1780 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1781 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1782 argc
> 5 ? argv
[5] : "");
1783 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1785 cmd
[sizeof(cmd
) - 1] = '\0';
1786 return wpa_ctrl_command(ctrl
, cmd
);
1790 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1797 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1798 "(interface name)\n");
1802 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1803 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1805 cmd
[sizeof(cmd
) - 1] = '\0';
1806 return wpa_ctrl_command(ctrl
, cmd
);
1810 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1813 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1818 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1822 printf("Invalid 'sta' command - exactly one argument, STA "
1823 "address, is required.\n");
1826 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1827 return wpa_ctrl_command(ctrl
, buf
);
1831 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1832 char *addr
, size_t addr_len
)
1834 char buf
[4096], *pos
;
1838 if (ctrl_conn
== NULL
) {
1839 printf("Not connected to hostapd - command dropped.\n");
1842 len
= sizeof(buf
) - 1;
1843 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1846 printf("'%s' command timed out.\n", cmd
);
1848 } else if (ret
< 0) {
1849 printf("'%s' command failed.\n", cmd
);
1854 if (memcmp(buf
, "FAIL", 4) == 0)
1859 while (*pos
!= '\0' && *pos
!= '\n')
1862 os_strlcpy(addr
, buf
, addr_len
);
1867 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1869 char addr
[32], cmd
[64];
1871 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1874 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1875 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1879 #endif /* CONFIG_AP */
1882 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1884 return wpa_ctrl_command(ctrl
, "SUSPEND");
1888 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1890 return wpa_ctrl_command(ctrl
, "RESUME");
1894 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1896 return wpa_ctrl_command(ctrl
, "DROP_SA");
1900 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1906 printf("Invalid ROAM command: needs one argument "
1907 "(target AP's BSSID)\n");
1911 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
1912 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1913 printf("Too long ROAM command.\n");
1916 return wpa_ctrl_command(ctrl
, cmd
);
1922 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1928 return wpa_ctrl_command(ctrl
, "P2P_FIND");
1931 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
1934 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
1935 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1937 cmd
[sizeof(cmd
) - 1] = '\0';
1938 return wpa_ctrl_command(ctrl
, cmd
);
1942 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1945 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1949 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1956 printf("Invalid P2P_CONNECT command: needs at least two "
1957 "arguments (address and pbc/PIN)\n");
1962 res
= os_snprintf(cmd
, sizeof(cmd
),
1963 "P2P_CONNECT %s %s %s %s %s",
1964 argv
[0], argv
[1], argv
[2], argv
[3],
1967 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
1968 argv
[0], argv
[1], argv
[2], argv
[3]);
1970 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
1971 argv
[0], argv
[1], argv
[2]);
1973 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
1975 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1977 cmd
[sizeof(cmd
) - 1] = '\0';
1978 return wpa_ctrl_command(ctrl
, cmd
);
1982 static char ** wpa_cli_complete_p2p_connect(const char *str
, int pos
)
1984 int arg
= get_cmd_arg_num(str
, pos
);
1989 res
= cli_txt_list_array(&p2p_peers
);
1997 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
2004 return wpa_ctrl_command(ctrl
, "P2P_LISTEN");
2006 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_LISTEN %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_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
2021 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2022 "(interface name)\n");
2026 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
2027 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2029 cmd
[sizeof(cmd
) - 1] = '\0';
2030 return wpa_ctrl_command(ctrl
, cmd
);
2034 static char ** wpa_cli_complete_p2p_group_remove(const char *str
, int pos
)
2036 int arg
= get_cmd_arg_num(str
, pos
);
2041 res
= cli_txt_list_array(&p2p_groups
);
2049 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
2056 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
2059 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s %s",
2062 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s",
2064 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2066 cmd
[sizeof(cmd
) - 1] = '\0';
2067 return wpa_ctrl_command(ctrl
, cmd
);
2071 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
2078 printf("Invalid P2P_PROV_DISC command: needs two arguments "
2079 "(address and config method\n"
2080 "(display, keypad, or pbc)\n");
2084 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
2086 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2088 cmd
[sizeof(cmd
) - 1] = '\0';
2089 return wpa_ctrl_command(ctrl
, cmd
);
2093 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
2096 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
2100 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
2106 if (argc
!= 2 && argc
!= 4) {
2107 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2108 "arguments (address and TLVs) or four arguments "
2109 "(address, \"upnp\", version, search target "
2115 res
= os_snprintf(cmd
, sizeof(cmd
),
2116 "P2P_SERV_DISC_REQ %s %s %s %s",
2117 argv
[0], argv
[1], argv
[2], argv
[3]);
2119 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
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_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
2129 int argc
, char *argv
[])
2135 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2136 "argument (pending request identifier)\n");
2140 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
2142 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2144 cmd
[sizeof(cmd
) - 1] = '\0';
2145 return wpa_ctrl_command(ctrl
, cmd
);
2149 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
2156 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2157 "arguments (freq, address, dialog token, and TLVs)\n");
2161 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
2162 argv
[0], argv
[1], argv
[2], argv
[3]);
2163 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2165 cmd
[sizeof(cmd
) - 1] = '\0';
2166 return wpa_ctrl_command(ctrl
, cmd
);
2170 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
2173 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
2177 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
2178 int argc
, char *argv
[])
2184 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2185 "argument (external processing: 0/1)\n");
2189 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
2191 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2193 cmd
[sizeof(cmd
) - 1] = '\0';
2194 return wpa_ctrl_command(ctrl
, cmd
);
2198 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
2201 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
2205 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
2211 if (argc
!= 3 && argc
!= 4) {
2212 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2218 res
= os_snprintf(cmd
, sizeof(cmd
),
2219 "P2P_SERVICE_ADD %s %s %s %s",
2220 argv
[0], argv
[1], argv
[2], argv
[3]);
2222 res
= os_snprintf(cmd
, sizeof(cmd
),
2223 "P2P_SERVICE_ADD %s %s %s",
2224 argv
[0], argv
[1], argv
[2]);
2225 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2227 cmd
[sizeof(cmd
) - 1] = '\0';
2228 return wpa_ctrl_command(ctrl
, cmd
);
2232 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
2238 if (argc
!= 2 && argc
!= 3) {
2239 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2245 res
= os_snprintf(cmd
, sizeof(cmd
),
2246 "P2P_SERVICE_DEL %s %s %s",
2247 argv
[0], argv
[1], argv
[2]);
2249 res
= os_snprintf(cmd
, sizeof(cmd
),
2250 "P2P_SERVICE_DEL %s %s",
2252 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2254 cmd
[sizeof(cmd
) - 1] = '\0';
2255 return wpa_ctrl_command(ctrl
, cmd
);
2259 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
2260 int argc
, char *argv
[])
2266 printf("Invalid P2P_REJECT command: needs one argument "
2267 "(peer address)\n");
2271 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
2272 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2274 cmd
[sizeof(cmd
) - 1] = '\0';
2275 return wpa_ctrl_command(ctrl
, cmd
);
2279 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
2280 int argc
, char *argv
[])
2286 printf("Invalid P2P_INVITE command: needs at least one "
2292 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
2293 argv
[0], argv
[1], argv
[2]);
2295 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
2298 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
2299 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2301 cmd
[sizeof(cmd
) - 1] = '\0';
2302 return wpa_ctrl_command(ctrl
, cmd
);
2306 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2310 printf("Invalid 'p2p_peer' command - exactly one argument, "
2311 "P2P peer device address, is required.\n");
2314 os_snprintf(buf
, sizeof(buf
), "P2P_PEER %s", argv
[0]);
2315 return wpa_ctrl_command(ctrl
, buf
);
2319 static char ** wpa_cli_complete_p2p_peer(const char *str
, int pos
)
2321 int arg
= get_cmd_arg_num(str
, pos
);
2326 res
= cli_txt_list_array(&p2p_peers
);
2334 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
2335 char *addr
, size_t addr_len
,
2338 char buf
[4096], *pos
;
2342 if (ctrl_conn
== NULL
)
2344 len
= sizeof(buf
) - 1;
2345 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
2348 printf("'%s' command timed out.\n", cmd
);
2350 } else if (ret
< 0) {
2351 printf("'%s' command failed.\n", cmd
);
2356 if (memcmp(buf
, "FAIL", 4) == 0)
2360 while (*pos
!= '\0' && *pos
!= '\n')
2363 os_strlcpy(addr
, buf
, addr_len
);
2364 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2365 printf("%s\n", addr
);
2370 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2372 char addr
[32], cmd
[64];
2375 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2377 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2378 addr
, sizeof(addr
), discovered
))
2381 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2382 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2389 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2395 printf("Invalid P2P_SET command: needs two arguments (field, "
2400 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
2401 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2403 cmd
[sizeof(cmd
) - 1] = '\0';
2404 return wpa_ctrl_command(ctrl
, cmd
);
2408 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2410 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2414 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2417 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2421 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
2428 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2429 "(peer address)\n");
2433 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_UNAUTHORIZE %s", argv
[0]);
2435 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2438 cmd
[sizeof(cmd
) - 1] = '\0';
2439 return wpa_ctrl_command(ctrl
, cmd
);
2443 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2449 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2450 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2451 "(preferred duration, interval; in microsecods).\n"
2452 "Optional second pair can be used to provide "
2453 "acceptable values.\n");
2458 res
= os_snprintf(cmd
, sizeof(cmd
),
2459 "P2P_PRESENCE_REQ %s %s %s %s",
2460 argv
[0], argv
[1], argv
[2], argv
[3]);
2462 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2465 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
2466 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2468 cmd
[sizeof(cmd
) - 1] = '\0';
2469 return wpa_ctrl_command(ctrl
, cmd
);
2473 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2479 if (argc
!= 0 && argc
!= 2) {
2480 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2481 "(availability period, availability interval; in "
2483 "Extended Listen Timing can be cancelled with this "
2484 "command when used without parameters.\n");
2489 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2492 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2493 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2495 cmd
[sizeof(cmd
) - 1] = '\0';
2496 return wpa_ctrl_command(ctrl
, cmd
);
2499 #endif /* CONFIG_P2P */
2502 #ifdef CONFIG_INTERWORKING
2503 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2506 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
2510 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2513 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
2517 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl
*ctrl
, int argc
,
2524 return wpa_ctrl_command(ctrl
, "INTERWORKING_SELECT");
2526 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERWORKING_SELECT %s", argv
[0]);
2527 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2529 cmd
[sizeof(cmd
) - 1] = '\0';
2530 return wpa_ctrl_command(ctrl
, cmd
);
2534 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl
*ctrl
, int argc
,
2541 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2542 "argument (BSSID)\n");
2546 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERWORKING_CONNECT %s",
2548 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2550 cmd
[sizeof(cmd
) - 1] = '\0';
2551 return wpa_ctrl_command(ctrl
, cmd
);
2555 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2561 printf("Invalid ANQP_GET command: needs two arguments "
2562 "(addr and info id list)\n");
2566 res
= os_snprintf(cmd
, sizeof(cmd
), "ANQP_GET %s %s",
2568 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2570 cmd
[sizeof(cmd
) - 1] = '\0';
2571 return wpa_ctrl_command(ctrl
, cmd
);
2573 #endif /* CONFIG_INTERWORKING */
2576 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2583 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2584 "(0/1 = disable/enable automatic reconnection)\n");
2587 res
= os_snprintf(cmd
, sizeof(cmd
), "STA_AUTOCONNECT %s", argv
[0]);
2588 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2589 printf("Too long STA_AUTOCONNECT command.\n");
2592 return wpa_ctrl_command(ctrl
, cmd
);
2596 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2603 printf("Invalid TDLS_DISCOVER command: needs one argument "
2604 "(Peer STA MAC address)\n");
2608 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_DISCOVER %s", argv
[0]);
2609 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2610 printf("Too long TDLS_DISCOVER command.\n");
2613 return wpa_ctrl_command(ctrl
, cmd
);
2617 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2624 printf("Invalid TDLS_SETUP command: needs one argument "
2625 "(Peer STA MAC address)\n");
2629 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_SETUP %s", argv
[0]);
2630 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2631 printf("Too long TDLS_SETUP command.\n");
2634 return wpa_ctrl_command(ctrl
, cmd
);
2638 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2645 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2646 "(Peer STA MAC address)\n");
2650 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_TEARDOWN %s", argv
[0]);
2651 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2652 printf("Too long TDLS_TEARDOWN command.\n");
2655 return wpa_ctrl_command(ctrl
, cmd
);
2659 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2662 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2666 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
2669 return wpa_ctrl_command(ctrl
, "REAUTHENTICATE");
2673 enum wpa_cli_cmd_flags
{
2674 cli_cmd_flag_none
= 0x00,
2675 cli_cmd_flag_sensitive
= 0x01
2678 struct wpa_cli_cmd
{
2680 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2681 enum wpa_cli_cmd_flags flags
;
2685 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2686 { "status", wpa_cli_cmd_status
,
2688 "[verbose] = get current WPA/EAPOL/EAP status" },
2689 { "ping", wpa_cli_cmd_ping
,
2691 "= pings wpa_supplicant" },
2692 { "relog", wpa_cli_cmd_relog
,
2694 "= re-open log-file (allow rolling logs)" },
2695 { "note", wpa_cli_cmd_note
,
2697 "<text> = add a note to wpa_supplicant debug log" },
2698 { "mib", wpa_cli_cmd_mib
,
2700 "= get MIB variables (dot1x, dot11)" },
2701 { "help", wpa_cli_cmd_help
,
2703 "= show this usage help" },
2704 { "interface", wpa_cli_cmd_interface
,
2706 "[ifname] = show interfaces/select interface" },
2707 { "level", wpa_cli_cmd_level
,
2709 "<debug level> = change debug level" },
2710 { "license", wpa_cli_cmd_license
,
2712 "= show full wpa_cli license" },
2713 { "quit", wpa_cli_cmd_quit
,
2716 { "set", wpa_cli_cmd_set
,
2718 "= set variables (shows list of variables when run without "
2720 { "get", wpa_cli_cmd_get
,
2722 "<name> = get information" },
2723 { "logon", wpa_cli_cmd_logon
,
2725 "= IEEE 802.1X EAPOL state machine logon" },
2726 { "logoff", wpa_cli_cmd_logoff
,
2728 "= IEEE 802.1X EAPOL state machine logoff" },
2729 { "pmksa", wpa_cli_cmd_pmksa
,
2731 "= show PMKSA cache" },
2732 { "reassociate", wpa_cli_cmd_reassociate
,
2734 "= force reassociation" },
2735 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2737 "<BSSID> = force preauthentication" },
2738 { "identity", wpa_cli_cmd_identity
,
2740 "<network id> <identity> = configure identity for an SSID" },
2741 { "password", wpa_cli_cmd_password
,
2742 cli_cmd_flag_sensitive
,
2743 "<network id> <password> = configure password for an SSID" },
2744 { "new_password", wpa_cli_cmd_new_password
,
2745 cli_cmd_flag_sensitive
,
2746 "<network id> <password> = change password for an SSID" },
2747 { "pin", wpa_cli_cmd_pin
,
2748 cli_cmd_flag_sensitive
,
2749 "<network id> <pin> = configure pin for an SSID" },
2750 { "otp", wpa_cli_cmd_otp
,
2751 cli_cmd_flag_sensitive
,
2752 "<network id> <password> = configure one-time-password for an SSID"
2754 { "passphrase", wpa_cli_cmd_passphrase
,
2755 cli_cmd_flag_sensitive
,
2756 "<network id> <passphrase> = configure private key passphrase\n"
2758 { "bssid", wpa_cli_cmd_bssid
,
2760 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2761 { "blacklist", wpa_cli_cmd_blacklist
,
2763 "<BSSID> = add a BSSID to the blacklist\n"
2764 "blacklist clear = clear the blacklist\n"
2765 "blacklist = display the blacklist" },
2766 { "log_level", wpa_cli_cmd_log_level
,
2768 "<level> [<timestamp>] = update the log level/timestamp\n"
2769 "log_level = display the current log level and log options" },
2770 { "list_networks", wpa_cli_cmd_list_networks
,
2772 "= list configured networks" },
2773 { "select_network", wpa_cli_cmd_select_network
,
2775 "<network id> = select a network (disable others)" },
2776 { "enable_network", wpa_cli_cmd_enable_network
,
2778 "<network id> = enable a network" },
2779 { "disable_network", wpa_cli_cmd_disable_network
,
2781 "<network id> = disable a network" },
2782 { "add_network", wpa_cli_cmd_add_network
,
2784 "= add a network" },
2785 { "remove_network", wpa_cli_cmd_remove_network
,
2787 "<network id> = remove a network" },
2788 { "set_network", wpa_cli_cmd_set_network
,
2789 cli_cmd_flag_sensitive
,
2790 "<network id> <variable> <value> = set network variables (shows\n"
2791 " list of variables when run without arguments)" },
2792 { "get_network", wpa_cli_cmd_get_network
,
2794 "<network id> <variable> = get network variables" },
2795 { "save_config", wpa_cli_cmd_save_config
,
2797 "= save the current configuration" },
2798 { "disconnect", wpa_cli_cmd_disconnect
,
2800 "= disconnect and wait for reassociate/reconnect command before\n"
2802 { "reconnect", wpa_cli_cmd_reconnect
,
2804 "= like reassociate, but only takes effect if already disconnected"
2806 { "scan", wpa_cli_cmd_scan
,
2808 "= request new BSS scan" },
2809 { "scan_results", wpa_cli_cmd_scan_results
,
2811 "= get latest scan results" },
2812 { "bss", wpa_cli_cmd_bss
,
2814 "<<idx> | <bssid>> = get detailed scan result info" },
2815 { "get_capability", wpa_cli_cmd_get_capability
,
2817 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2818 { "reconfigure", wpa_cli_cmd_reconfigure
,
2820 "= force wpa_supplicant to re-read its configuration file" },
2821 { "terminate", wpa_cli_cmd_terminate
,
2823 "= terminate wpa_supplicant" },
2824 { "interface_add", wpa_cli_cmd_interface_add
,
2826 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2827 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2829 { "interface_remove", wpa_cli_cmd_interface_remove
,
2831 "<ifname> = removes the interface" },
2832 { "interface_list", wpa_cli_cmd_interface_list
,
2834 "= list available interfaces" },
2835 { "ap_scan", wpa_cli_cmd_ap_scan
,
2837 "<value> = set ap_scan parameter" },
2838 { "scan_interval", wpa_cli_cmd_scan_interval
,
2840 "<value> = set scan_interval parameter (in seconds)" },
2841 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
,
2843 "<value> = set BSS expiration age parameter" },
2844 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
,
2846 "<value> = set BSS expiration scan count parameter" },
2847 { "stkstart", wpa_cli_cmd_stkstart
,
2849 "<addr> = request STK negotiation with <addr>" },
2850 { "ft_ds", wpa_cli_cmd_ft_ds
,
2852 "<addr> = request over-the-DS FT with <addr>" },
2853 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
2855 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2856 { "wps_pin", wpa_cli_cmd_wps_pin
,
2857 cli_cmd_flag_sensitive
,
2858 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2860 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
2861 cli_cmd_flag_sensitive
,
2862 "<PIN> = verify PIN checksum" },
2863 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
2864 "Cancels the pending WPS operation" },
2865 #ifdef CONFIG_WPS_OOB
2866 { "wps_oob", wpa_cli_cmd_wps_oob
,
2867 cli_cmd_flag_sensitive
,
2868 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2869 #endif /* CONFIG_WPS_OOB */
2870 { "wps_reg", wpa_cli_cmd_wps_reg
,
2871 cli_cmd_flag_sensitive
,
2872 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2873 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
,
2874 cli_cmd_flag_sensitive
,
2875 "[params..] = enable/disable AP PIN" },
2876 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
2878 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2879 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
2881 "= stop Wi-Fi Protected Setup External Registrar" },
2882 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
2883 cli_cmd_flag_sensitive
,
2884 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2885 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
2887 "<UUID> = accept an Enrollee PBC using External Registrar" },
2888 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
2889 cli_cmd_flag_sensitive
,
2890 "<UUID> <PIN> = learn AP configuration" },
2891 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
,
2893 "<UUID> <network id> = set AP configuration for enrolling" },
2894 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
2895 cli_cmd_flag_sensitive
,
2896 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2897 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
2899 "<addr> = request RSN authentication with <addr> in IBSS" },
2901 { "sta", wpa_cli_cmd_sta
,
2903 "<addr> = get information about an associated station (AP)" },
2904 { "all_sta", wpa_cli_cmd_all_sta
,
2906 "= get information about all associated stations (AP)" },
2907 #endif /* CONFIG_AP */
2908 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
2909 "= notification of suspend/hibernate" },
2910 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
2911 "= notification of resume/thaw" },
2912 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
2913 "= drop SA without deauth/disassoc (test command)" },
2914 { "roam", wpa_cli_cmd_roam
,
2916 "<addr> = roam to the specified BSS" },
2918 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
2919 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2920 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
2921 "= stop P2P Devices search" },
2922 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
2923 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2924 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
2925 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2926 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
2927 "<ifname> = remove P2P group interface (terminate group if GO)" },
2928 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
2929 "= add a new P2P group (local end as GO)" },
2930 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
2931 "<addr> <method> = request provisioning discovery" },
2932 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
2934 "= get the passphrase for a group (GO only)" },
2935 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2937 "<addr> <TLVs> = schedule service discovery request" },
2938 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2940 "<id> = cancel pending service discovery request" },
2941 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2943 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2944 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2946 "= indicate change in local services" },
2947 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2949 "<external> = set external processing of service discovery" },
2950 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2952 "= remove all stored service entries" },
2953 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2955 "<bonjour|upnp> <query|version> <response|service> = add a local "
2957 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2959 "<bonjour|upnp> <query|version> [|service] = remove a local "
2961 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2963 "<addr> = reject connection attempts from a specific peer" },
2964 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
2966 "<cmd> [peer=addr] = invite peer" },
2967 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
2968 "[discovered] = list known (optionally, only fully discovered) P2P "
2970 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
2971 "<address> = show information about known P2P peer" },
2972 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
2973 "<field> <value> = set a P2P parameter" },
2974 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
2975 "= flush P2P state" },
2976 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
2977 "= cancel P2P group formation" },
2978 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
, cli_cmd_flag_none
,
2979 "<address> = unauthorize a peer" },
2980 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
2981 "[<duration> <interval>] [<duration> <interval>] = request GO "
2983 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
2984 "[<period> <interval>] = set extended listen timing" },
2985 #endif /* CONFIG_P2P */
2987 #ifdef CONFIG_INTERWORKING
2988 { "fetch_anqp", wpa_cli_cmd_fetch_anqp
, cli_cmd_flag_none
,
2989 "= fetch ANQP information for all APs" },
2990 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp
, cli_cmd_flag_none
,
2991 "= stop fetch_anqp operation" },
2992 { "interworking_select", wpa_cli_cmd_interworking_select
,
2994 "[auto] = perform Interworking network selection" },
2995 { "interworking_connect", wpa_cli_cmd_interworking_connect
,
2997 "<BSSID> = connect using Interworking credentials" },
2998 { "anqp_get", wpa_cli_cmd_anqp_get
, cli_cmd_flag_none
,
2999 "<addr> <info id>[,<info id>]... = request ANQP information" },
3000 #endif /* CONFIG_INTERWORKING */
3001 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
3002 "<0/1> = disable/enable automatic reconnection" },
3003 { "tdls_discover", wpa_cli_cmd_tdls_discover
,
3005 "<addr> = request TDLS discovery with <addr>" },
3006 { "tdls_setup", wpa_cli_cmd_tdls_setup
,
3008 "<addr> = request TDLS setup with <addr>" },
3009 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
,
3011 "<addr> = tear down TDLS with <addr>" },
3012 { "signal_poll", wpa_cli_cmd_signal_poll
,
3014 "= get signal parameters" },
3015 { "reauthenticate", wpa_cli_cmd_reauthenticate
, cli_cmd_flag_none
,
3016 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3017 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
3022 * Prints command usage, lines are padded with the specified string.
3024 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
3029 printf("%s%s ", pad
, cmd
->cmd
);
3030 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
3039 static void print_help(void)
3042 printf("commands:\n");
3043 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
3044 print_cmd_help(&wpa_cli_commands
[n
], " ");
3048 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
3050 const char *c
, *delim
;
3054 delim
= os_strchr(cmd
, ' ');
3058 len
= os_strlen(cmd
);
3060 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
3061 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
3062 return (wpa_cli_commands
[n
].flags
&
3063 cli_cmd_flag_sensitive
);
3069 static char ** wpa_list_cmd_list(void)
3074 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
3075 res
= os_zalloc(count
* sizeof(char *));
3079 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
3080 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
3089 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
3094 if (os_strcasecmp(cmd
, "bss") == 0)
3095 return wpa_cli_complete_bss(str
, pos
);
3097 if (os_strcasecmp(cmd
, "p2p_connect") == 0)
3098 return wpa_cli_complete_p2p_connect(str
, pos
);
3099 if (os_strcasecmp(cmd
, "p2p_peer") == 0)
3100 return wpa_cli_complete_p2p_peer(str
, pos
);
3101 if (os_strcasecmp(cmd
, "p2p_group_remove") == 0)
3102 return wpa_cli_complete_p2p_group_remove(str
, pos
);
3103 #endif /* CONFIG_P2P */
3105 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
3106 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
3108 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
3118 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
3124 end
= os_strchr(str
, ' ');
3125 if (end
== NULL
|| str
+ pos
< end
)
3126 return wpa_list_cmd_list();
3128 cmd
= os_malloc(pos
+ 1);
3131 os_memcpy(cmd
, str
, pos
);
3132 cmd
[end
- str
] = '\0';
3133 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
3139 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
3141 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
3146 cmd
= wpa_cli_commands
;
3148 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
3151 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
3152 /* we have an exact match */
3162 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
3163 cmd
= wpa_cli_commands
;
3165 if (os_strncasecmp(cmd
->cmd
, argv
[0],
3166 os_strlen(argv
[0])) == 0) {
3167 printf(" %s", cmd
->cmd
);
3173 } else if (count
== 0) {
3174 printf("Unknown command '%s'\n", argv
[0]);
3177 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
3184 static int str_match(const char *a
, const char *b
)
3186 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
3190 static int wpa_cli_exec(const char *program
, const char *arg1
,
3198 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
3199 cmd
= os_malloc(len
);
3202 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
3203 if (res
< 0 || (size_t) res
>= len
) {
3207 cmd
[len
- 1] = '\0';
3209 if (system(cmd
) < 0)
3211 #endif /* _WIN32_WCE */
3218 static void wpa_cli_action_process(const char *msg
)
3221 char *copy
= NULL
, *id
, *pos2
;
3226 pos
= os_strchr(pos
, '>');
3233 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
3235 os_unsetenv("WPA_ID");
3236 os_unsetenv("WPA_ID_STR");
3237 os_unsetenv("WPA_CTRL_DIR");
3239 pos
= os_strstr(pos
, "[id=");
3241 copy
= os_strdup(pos
+ 4);
3245 while (*pos2
&& *pos2
!= ' ')
3249 os_setenv("WPA_ID", id
, 1);
3250 while (*pos2
&& *pos2
!= '=')
3255 while (*pos2
&& *pos2
!= ']')
3258 os_setenv("WPA_ID_STR", id
, 1);
3262 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
3264 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
3265 wpa_cli_connected
= 1;
3266 wpa_cli_last_id
= new_id
;
3267 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
3269 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
3270 if (wpa_cli_connected
) {
3271 wpa_cli_connected
= 0;
3272 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
3274 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
3275 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3276 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
3277 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3278 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
3279 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3280 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
3281 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3282 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
3283 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3284 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
3285 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3286 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
3287 printf("wpa_supplicant is terminating - stop monitoring\n");
3293 #ifndef CONFIG_ANSI_C_EXTRA
3294 static void wpa_cli_action_cb(char *msg
, size_t len
)
3296 wpa_cli_action_process(msg
);
3298 #endif /* CONFIG_ANSI_C_EXTRA */
3301 static void wpa_cli_reconnect(void)
3303 wpa_cli_close_connection();
3304 wpa_cli_open_connection(ctrl_ifname
, 1);
3308 static void cli_event(const char *str
)
3310 const char *start
, *s
;
3312 start
= os_strchr(str
, '>');
3318 if (str_starts(start
, WPA_EVENT_BSS_ADDED
)) {
3319 s
= os_strchr(start
, ' ');
3322 s
= os_strchr(s
+ 1, ' ');
3325 cli_txt_list_add(&bsses
, s
+ 1);
3329 if (str_starts(start
, WPA_EVENT_BSS_REMOVED
)) {
3330 s
= os_strchr(start
, ' ');
3333 s
= os_strchr(s
+ 1, ' ');
3336 cli_txt_list_del_addr(&bsses
, s
+ 1);
3341 if (str_starts(start
, P2P_EVENT_DEVICE_FOUND
)) {
3342 s
= os_strstr(start
, " p2p_dev_addr=");
3345 cli_txt_list_add_addr(&p2p_peers
, s
+ 14);
3349 if (str_starts(start
, P2P_EVENT_DEVICE_LOST
)) {
3350 s
= os_strstr(start
, " p2p_dev_addr=");
3353 cli_txt_list_del_addr(&p2p_peers
, s
+ 14);
3357 if (str_starts(start
, P2P_EVENT_GROUP_STARTED
)) {
3358 s
= os_strchr(start
, ' ');
3361 cli_txt_list_add_word(&p2p_groups
, s
+ 1);
3365 if (str_starts(start
, P2P_EVENT_GROUP_REMOVED
)) {
3366 s
= os_strchr(start
, ' ');
3369 cli_txt_list_del_word(&p2p_groups
, s
+ 1);
3372 #endif /* CONFIG_P2P */
3376 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
3378 if (ctrl_conn
== NULL
) {
3379 wpa_cli_reconnect();
3382 while (wpa_ctrl_pending(ctrl
) > 0) {
3384 size_t len
= sizeof(buf
) - 1;
3385 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
3388 wpa_cli_action_process(buf
);
3391 if (wpa_cli_show_event(buf
)) {
3393 printf("\r%s\n", buf
);
3398 printf("Could not read pending message.\n");
3403 if (wpa_ctrl_pending(ctrl
) < 0) {
3404 printf("Connection to wpa_supplicant lost - trying to "
3406 wpa_cli_reconnect();
3412 static int tokenize_cmd(char *cmd
, char *argv
[])
3425 if (argc
== max_args
)
3428 char *pos2
= os_strrchr(pos
, '"');
3432 while (*pos
!= '\0' && *pos
!= ' ')
3442 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
3444 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3445 printf("Connection to wpa_supplicant lost - trying to "
3447 wpa_cli_close_connection();
3450 wpa_cli_reconnect();
3451 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3455 static void wpa_cli_eloop_terminate(int sig
, void *signal_ctx
)
3461 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
3463 wpa_cli_recv_pending(mon_conn
, 0);
3467 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
3469 char *argv
[max_args
];
3471 argc
= tokenize_cmd(cmd
, argv
);
3473 wpa_request(ctrl_conn
, argc
, argv
);
3477 static void wpa_cli_edit_eof_cb(void *ctx
)
3483 static void wpa_cli_interactive(void)
3485 char *home
, *hfile
= NULL
;
3487 printf("\nInteractive mode\n\n");
3489 home
= getenv("HOME");
3491 const char *fname
= ".wpa_cli_history";
3492 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
3493 hfile
= os_malloc(hfile_len
);
3495 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
3498 eloop_register_signal_terminate(wpa_cli_eloop_terminate
, NULL
);
3499 edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
3500 wpa_cli_edit_completion_cb
, NULL
, hfile
);
3501 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3505 cli_txt_list_flush(&p2p_peers
);
3506 cli_txt_list_flush(&p2p_groups
);
3507 cli_txt_list_flush(&bsses
);
3508 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3510 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3511 wpa_cli_close_connection();
3515 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3517 #ifdef CONFIG_ANSI_C_EXTRA
3518 /* TODO: ANSI C version(?) */
3519 printf("Action processing not supported in ANSI C build.\n");
3520 #else /* CONFIG_ANSI_C_EXTRA */
3524 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3527 fd
= wpa_ctrl_get_fd(ctrl
);
3529 while (!wpa_cli_quit
) {
3532 tv
.tv_sec
= ping_interval
;
3534 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3535 if (res
< 0 && errno
!= EINTR
) {
3540 if (FD_ISSET(fd
, &rfds
))
3541 wpa_cli_recv_pending(ctrl
, 1);
3543 /* verify that connection is still working */
3544 len
= sizeof(buf
) - 1;
3545 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3546 wpa_cli_action_cb
) < 0 ||
3547 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3548 printf("wpa_supplicant did not reply to PING "
3549 "command - exiting\n");
3554 #endif /* CONFIG_ANSI_C_EXTRA */
3558 static void wpa_cli_cleanup(void)
3560 wpa_cli_close_connection();
3562 os_daemonize_terminate(pid_file
);
3564 os_program_deinit();
3567 static void wpa_cli_terminate(int sig
)
3574 static char * wpa_cli_get_default_ifname(void)
3576 char *ifname
= NULL
;
3578 #ifdef CONFIG_CTRL_IFACE_UNIX
3579 struct dirent
*dent
;
3580 DIR *dir
= opendir(ctrl_iface_dir
);
3583 char ifprop
[PROPERTY_VALUE_MAX
];
3584 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3585 ifname
= os_strdup(ifprop
);
3586 printf("Using interface '%s'\n", ifname
);
3589 #endif /* ANDROID */
3592 while ((dent
= readdir(dir
))) {
3593 #ifdef _DIRENT_HAVE_D_TYPE
3595 * Skip the file if it is not a socket. Also accept
3596 * DT_UNKNOWN (0) in case the C library or underlying
3597 * file system does not support d_type.
3599 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3601 #endif /* _DIRENT_HAVE_D_TYPE */
3602 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3603 os_strcmp(dent
->d_name
, "..") == 0)
3605 printf("Selected interface '%s'\n", dent
->d_name
);
3606 ifname
= os_strdup(dent
->d_name
);
3610 #endif /* CONFIG_CTRL_IFACE_UNIX */
3612 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3613 char buf
[2048], *pos
;
3615 struct wpa_ctrl
*ctrl
;
3618 ctrl
= wpa_ctrl_open(NULL
);
3622 len
= sizeof(buf
) - 1;
3623 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3626 pos
= os_strchr(buf
, '\n');
3629 ifname
= os_strdup(buf
);
3631 wpa_ctrl_close(ctrl
);
3632 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3638 int main(int argc
, char *argv
[])
3640 int warning_displayed
= 0;
3644 const char *global
= NULL
;
3646 if (os_program_init())
3650 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3655 action_file
= optarg
;
3664 ping_interval
= atoi(optarg
);
3670 printf("%s\n", wpa_cli_version
);
3673 os_free(ctrl_ifname
);
3674 ctrl_ifname
= os_strdup(optarg
);
3677 ctrl_iface_dir
= optarg
;
3688 interactive
= (argc
== optind
) && (action_file
== NULL
);
3691 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3697 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3698 ctrl_conn
= wpa_ctrl_open(NULL
);
3699 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3700 ctrl_conn
= wpa_ctrl_open(global
);
3701 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3702 if (ctrl_conn
== NULL
) {
3703 perror("Failed to connect to wpa_supplicant - "
3710 signal(SIGINT
, wpa_cli_terminate
);
3711 signal(SIGTERM
, wpa_cli_terminate
);
3712 #endif /* _WIN32_WCE */
3714 if (ctrl_ifname
== NULL
)
3715 ctrl_ifname
= wpa_cli_get_default_ifname();
3719 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3720 if (warning_displayed
)
3721 printf("Connection established.\n");
3725 if (!warning_displayed
) {
3726 printf("Could not connect to wpa_supplicant - "
3728 warning_displayed
= 1;
3735 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3736 perror("Failed to connect to wpa_supplicant - "
3742 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3743 wpa_cli_attached
= 1;
3745 printf("Warning: Failed to attach to "
3746 "wpa_supplicant.\n");
3752 if (daemonize
&& os_daemonize(pid_file
))
3756 wpa_cli_interactive();
3757 else if (action_file
)
3758 wpa_cli_action(ctrl_conn
);
3760 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
3762 os_free(ctrl_ifname
);
3769 #else /* CONFIG_CTRL_IFACE */
3770 int main(int argc
, char *argv
[])
3772 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3775 #endif /* CONFIG_CTRL_IFACE */