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 if (argc
> 0 && os_strcmp(argv
[0], "verbose") == 0)
458 return wpa_ctrl_command(ctrl
, "STATUS-VERBOSE");
459 if (argc
> 0 && os_strcmp(argv
[0], "wps") == 0)
460 return wpa_ctrl_command(ctrl
, "STATUS-WPS");
461 return wpa_ctrl_command(ctrl
, "STATUS");
465 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
467 return wpa_ctrl_command(ctrl
, "PING");
471 static int wpa_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
473 return wpa_ctrl_command(ctrl
, "RELOG");
477 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
483 ret
= os_snprintf(cmd
, sizeof(cmd
), "NOTE %s", argv
[0]);
484 if (ret
< 0 || (size_t) ret
>= sizeof(cmd
))
486 return wpa_ctrl_command(ctrl
, cmd
);
490 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
492 return wpa_ctrl_command(ctrl
, "MIB");
496 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
498 return wpa_ctrl_command(ctrl
, "PMKSA");
502 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
509 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
511 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
516 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
525 static void wpa_cli_show_variables(void)
527 printf("set variables:\n"
528 " EAPOL::heldPeriod (EAPOL state machine held period, "
530 " EAPOL::authPeriod (EAPOL state machine authentication "
531 "period, in seconds)\n"
532 " EAPOL::startPeriod (EAPOL state machine start period, in "
534 " EAPOL::maxStart (EAPOL state machine maximum start "
536 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
538 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
539 " threshold\n\tpercentage)\n"
540 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
541 "security\n\tassociation in seconds)\n");
545 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
551 wpa_cli_show_variables();
555 if (argc
!= 1 && argc
!= 2) {
556 printf("Invalid SET command: needs two arguments (variable "
557 "name and value)\n");
562 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s ", argv
[0]);
564 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s",
566 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
567 printf("Too long SET command.\n");
570 return wpa_ctrl_command(ctrl
, cmd
);
574 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
580 printf("Invalid GET command: need one argument (variable "
585 res
= os_snprintf(cmd
, sizeof(cmd
), "GET %s", argv
[0]);
586 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
587 printf("Too long GET command.\n");
590 return wpa_ctrl_command(ctrl
, cmd
);
594 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
596 return wpa_ctrl_command(ctrl
, "LOGOFF");
600 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
602 return wpa_ctrl_command(ctrl
, "LOGON");
606 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
609 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
613 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
620 printf("Invalid PREAUTH command: needs one argument "
625 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
626 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
627 printf("Too long PREAUTH command.\n");
630 return wpa_ctrl_command(ctrl
, cmd
);
634 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
640 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
644 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
645 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
646 printf("Too long AP_SCAN command.\n");
649 return wpa_ctrl_command(ctrl
, cmd
);
653 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl
*ctrl
, int argc
,
660 printf("Invalid SCAN_INTERVAL command: needs one argument "
661 "scan_interval value)\n");
664 res
= os_snprintf(cmd
, sizeof(cmd
), "SCAN_INTERVAL %s", argv
[0]);
665 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
666 printf("Too long SCAN_INTERVAL command.\n");
669 return wpa_ctrl_command(ctrl
, cmd
);
673 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl
*ctrl
, int argc
,
680 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
681 "(bss_expire_age value)\n");
684 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_EXPIRE_AGE %s", argv
[0]);
685 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
686 printf("Too long BSS_EXPIRE_AGE command.\n");
689 return wpa_ctrl_command(ctrl
, cmd
);
693 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl
*ctrl
, int argc
,
700 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
701 "(bss_expire_count value)\n");
704 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_EXPIRE_COUNT %s", argv
[0]);
705 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
706 printf("Too long BSS_EXPIRE_COUNT command.\n");
709 return wpa_ctrl_command(ctrl
, cmd
);
713 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
720 printf("Invalid STKSTART command: needs one argument "
721 "(Peer STA MAC address)\n");
725 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
726 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
727 printf("Too long STKSTART command.\n");
730 return wpa_ctrl_command(ctrl
, cmd
);
734 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
740 printf("Invalid FT_DS command: needs one argument "
741 "(Target AP MAC address)\n");
745 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
746 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
747 printf("Too long FT_DS command.\n");
750 return wpa_ctrl_command(ctrl
, cmd
);
754 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
761 return wpa_ctrl_command(ctrl
, "WPS_PBC");
765 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
766 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
767 printf("Too long WPS_PBC command.\n");
770 return wpa_ctrl_command(ctrl
, cmd
);
774 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
780 printf("Invalid WPS_PIN command: need one or two arguments:\n"
781 "- BSSID: use 'any' to select any\n"
782 "- PIN: optional, used only with devices that have no "
788 /* Use dynamically generated PIN (returned as reply) */
789 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
790 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
791 printf("Too long WPS_PIN command.\n");
794 return wpa_ctrl_command(ctrl
, cmd
);
797 /* Use hardcoded PIN from a label */
798 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
799 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
800 printf("Too long WPS_PIN command.\n");
803 return wpa_ctrl_command(ctrl
, cmd
);
807 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
813 if (argc
!= 1 && argc
!= 2) {
814 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
815 "- PIN to be verified\n");
820 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
823 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
825 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
826 printf("Too long WPS_CHECK_PIN command.\n");
829 return wpa_ctrl_command(ctrl
, cmd
);
833 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
836 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
840 #ifdef CONFIG_WPS_OOB
841 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
846 if (argc
!= 3 && argc
!= 4) {
847 printf("Invalid WPS_OOB command: need three or four "
849 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
850 "- PATH: path of OOB device like '/mnt'\n"
851 "- METHOD: OOB method 'pin-e' or 'pin-r', "
853 "- DEV_NAME: (only for NFC) device name like "
859 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
860 argv
[0], argv
[1], argv
[2]);
862 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
863 argv
[0], argv
[1], argv
[2], argv
[3]);
864 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
865 printf("Too long WPS_OOB command.\n");
868 return wpa_ctrl_command(ctrl
, cmd
);
870 #endif /* CONFIG_WPS_OOB */
873 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
879 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
881 else if (argc
== 5 || argc
== 6) {
882 char ssid_hex
[2 * 32 + 1];
883 char key_hex
[2 * 64 + 1];
887 for (i
= 0; i
< 32; i
++) {
888 if (argv
[2][i
] == '\0')
890 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
895 for (i
= 0; i
< 64; i
++) {
896 if (argv
[5][i
] == '\0')
898 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
903 res
= os_snprintf(cmd
, sizeof(cmd
),
904 "WPS_REG %s %s %s %s %s %s",
905 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
908 printf("Invalid WPS_REG command: need two arguments:\n"
909 "- BSSID of the target AP\n"
911 printf("Alternatively, six arguments can be used to "
912 "reconfigure the AP:\n"
913 "- BSSID of the target AP\n"
916 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
917 "- new encr (NONE, WEP, TKIP, CCMP)\n"
922 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
923 printf("Too long WPS_REG command.\n");
926 return wpa_ctrl_command(ctrl
, cmd
);
930 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
937 printf("Invalid WPS_AP_PIN command: needs at least one "
943 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s %s",
944 argv
[0], argv
[1], argv
[2]);
946 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s",
949 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s",
951 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
952 printf("Too long WPS_AP_PIN command.\n");
955 return wpa_ctrl_command(ctrl
, cmd
);
959 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
964 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
965 return wpa_ctrl_command(ctrl
, cmd
);
967 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
971 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
974 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
979 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
986 printf("Invalid WPS_ER_PIN command: need at least two "
988 "- UUID: use 'any' to select any\n"
989 "- PIN: Enrollee PIN\n"
990 "optional: - Enrollee MAC address\n");
995 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
996 argv
[0], argv
[1], argv
[2]);
998 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
1000 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1001 printf("Too long WPS_ER_PIN command.\n");
1004 return wpa_ctrl_command(ctrl
, cmd
);
1008 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
1015 printf("Invalid WPS_ER_PBC command: need one argument:\n"
1016 "- UUID: Specify the Enrollee\n");
1020 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
1022 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1023 printf("Too long WPS_ER_PBC command.\n");
1026 return wpa_ctrl_command(ctrl
, cmd
);
1030 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
1037 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1038 "- UUID: specify which AP to use\n"
1043 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
1045 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1046 printf("Too long WPS_ER_LEARN command.\n");
1049 return wpa_ctrl_command(ctrl
, cmd
);
1053 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
1060 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1062 "- UUID: specify which AP to use\n"
1063 "- Network configuration id\n");
1067 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_SET_CONFIG %s %s",
1069 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1070 printf("Too long WPS_ER_SET_CONFIG command.\n");
1073 return wpa_ctrl_command(ctrl
, cmd
);
1077 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
1083 if (argc
== 5 || argc
== 6) {
1084 char ssid_hex
[2 * 32 + 1];
1085 char key_hex
[2 * 64 + 1];
1089 for (i
= 0; i
< 32; i
++) {
1090 if (argv
[2][i
] == '\0')
1092 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
1097 for (i
= 0; i
< 64; i
++) {
1098 if (argv
[5][i
] == '\0')
1100 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
1105 res
= os_snprintf(cmd
, sizeof(cmd
),
1106 "WPS_ER_CONFIG %s %s %s %s %s %s",
1107 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
1110 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1114 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1115 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1120 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1121 printf("Too long WPS_ER_CONFIG command.\n");
1124 return wpa_ctrl_command(ctrl
, cmd
);
1128 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1134 printf("Invalid IBSS_RSN command: needs one argument "
1135 "(Peer STA MAC address)\n");
1139 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
1140 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1141 printf("Too long IBSS_RSN command.\n");
1144 return wpa_ctrl_command(ctrl
, cmd
);
1148 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1154 printf("Invalid LEVEL command: needs one argument (debug "
1158 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
1159 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1160 printf("Too long LEVEL command.\n");
1163 return wpa_ctrl_command(ctrl
, cmd
);
1167 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1169 char cmd
[256], *pos
, *end
;
1173 printf("Invalid IDENTITY command: needs two arguments "
1174 "(network id and identity)\n");
1178 end
= cmd
+ sizeof(cmd
);
1180 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
1182 if (ret
< 0 || ret
>= end
- pos
) {
1183 printf("Too long IDENTITY command.\n");
1187 for (i
= 2; i
< argc
; i
++) {
1188 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1189 if (ret
< 0 || ret
>= end
- pos
) {
1190 printf("Too long IDENTITY command.\n");
1196 return wpa_ctrl_command(ctrl
, cmd
);
1200 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1202 char cmd
[256], *pos
, *end
;
1206 printf("Invalid PASSWORD command: needs two arguments "
1207 "(network id and password)\n");
1211 end
= cmd
+ sizeof(cmd
);
1213 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1215 if (ret
< 0 || ret
>= end
- pos
) {
1216 printf("Too long PASSWORD command.\n");
1220 for (i
= 2; i
< argc
; i
++) {
1221 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1222 if (ret
< 0 || ret
>= end
- pos
) {
1223 printf("Too long PASSWORD command.\n");
1229 return wpa_ctrl_command(ctrl
, cmd
);
1233 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1236 char cmd
[256], *pos
, *end
;
1240 printf("Invalid NEW_PASSWORD command: needs two arguments "
1241 "(network id and password)\n");
1245 end
= cmd
+ sizeof(cmd
);
1247 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1249 if (ret
< 0 || ret
>= end
- pos
) {
1250 printf("Too long NEW_PASSWORD command.\n");
1254 for (i
= 2; i
< argc
; i
++) {
1255 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1256 if (ret
< 0 || ret
>= end
- pos
) {
1257 printf("Too long NEW_PASSWORD command.\n");
1263 return wpa_ctrl_command(ctrl
, cmd
);
1267 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1269 char cmd
[256], *pos
, *end
;
1273 printf("Invalid PIN command: needs two arguments "
1274 "(network id and pin)\n");
1278 end
= cmd
+ sizeof(cmd
);
1280 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1282 if (ret
< 0 || ret
>= end
- pos
) {
1283 printf("Too long PIN command.\n");
1287 for (i
= 2; i
< argc
; i
++) {
1288 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1289 if (ret
< 0 || ret
>= end
- pos
) {
1290 printf("Too long PIN command.\n");
1295 return wpa_ctrl_command(ctrl
, cmd
);
1299 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1301 char cmd
[256], *pos
, *end
;
1305 printf("Invalid OTP command: needs two arguments (network "
1306 "id and password)\n");
1310 end
= cmd
+ sizeof(cmd
);
1312 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1314 if (ret
< 0 || ret
>= end
- pos
) {
1315 printf("Too long OTP command.\n");
1319 for (i
= 2; i
< argc
; i
++) {
1320 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1321 if (ret
< 0 || ret
>= end
- pos
) {
1322 printf("Too long OTP command.\n");
1328 return wpa_ctrl_command(ctrl
, cmd
);
1332 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1335 char cmd
[256], *pos
, *end
;
1339 printf("Invalid PASSPHRASE command: needs two arguments "
1340 "(network id and passphrase)\n");
1344 end
= cmd
+ sizeof(cmd
);
1346 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1348 if (ret
< 0 || ret
>= end
- pos
) {
1349 printf("Too long PASSPHRASE command.\n");
1353 for (i
= 2; i
< argc
; i
++) {
1354 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1355 if (ret
< 0 || ret
>= end
- pos
) {
1356 printf("Too long PASSPHRASE command.\n");
1362 return wpa_ctrl_command(ctrl
, cmd
);
1366 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1368 char cmd
[256], *pos
, *end
;
1372 printf("Invalid BSSID command: needs two arguments (network "
1377 end
= cmd
+ sizeof(cmd
);
1379 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1380 if (ret
< 0 || ret
>= end
- pos
) {
1381 printf("Too long BSSID command.\n");
1385 for (i
= 0; i
< argc
; i
++) {
1386 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1387 if (ret
< 0 || ret
>= end
- pos
) {
1388 printf("Too long BSSID command.\n");
1394 return wpa_ctrl_command(ctrl
, cmd
);
1398 static int wpa_cli_cmd_blacklist(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1400 char cmd
[256], *pos
, *end
;
1403 end
= cmd
+ sizeof(cmd
);
1405 ret
= os_snprintf(pos
, end
- pos
, "BLACKLIST");
1406 if (ret
< 0 || ret
>= end
- pos
) {
1407 printf("Too long BLACKLIST command.\n");
1411 for (i
= 0; i
< argc
; i
++) {
1412 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1413 if (ret
< 0 || ret
>= end
- pos
) {
1414 printf("Too long BLACKLIST command.\n");
1420 return wpa_ctrl_command(ctrl
, cmd
);
1424 static int wpa_cli_cmd_log_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1426 char cmd
[256], *pos
, *end
;
1429 end
= cmd
+ sizeof(cmd
);
1431 ret
= os_snprintf(pos
, end
- pos
, "LOG_LEVEL");
1432 if (ret
< 0 || ret
>= end
- pos
) {
1433 printf("Too long LOG_LEVEL command.\n");
1437 for (i
= 0; i
< argc
; i
++) {
1438 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1439 if (ret
< 0 || ret
>= end
- pos
) {
1440 printf("Too long LOG_LEVEL command.\n");
1446 return wpa_ctrl_command(ctrl
, cmd
);
1450 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1453 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1457 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1464 printf("Invalid SELECT_NETWORK command: needs one argument "
1469 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1470 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1472 cmd
[sizeof(cmd
) - 1] = '\0';
1474 return wpa_ctrl_command(ctrl
, cmd
);
1478 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1485 printf("Invalid ENABLE_NETWORK command: needs one argument "
1490 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1491 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1493 cmd
[sizeof(cmd
) - 1] = '\0';
1495 return wpa_ctrl_command(ctrl
, cmd
);
1499 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1506 printf("Invalid DISABLE_NETWORK command: needs one argument "
1511 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1512 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1514 cmd
[sizeof(cmd
) - 1] = '\0';
1516 return wpa_ctrl_command(ctrl
, cmd
);
1520 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1523 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1527 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1534 printf("Invalid REMOVE_NETWORK command: needs one argument "
1539 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1540 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1542 cmd
[sizeof(cmd
) - 1] = '\0';
1544 return wpa_ctrl_command(ctrl
, cmd
);
1548 static void wpa_cli_show_network_variables(void)
1550 printf("set_network variables:\n"
1551 " ssid (network name, SSID)\n"
1552 " psk (WPA passphrase or pre-shared key)\n"
1553 " key_mgmt (key management protocol)\n"
1554 " identity (EAP identity)\n"
1555 " password (EAP password)\n"
1558 "Note: Values are entered in the same format as the "
1559 "configuration file is using,\n"
1560 "i.e., strings values need to be inside double quotation "
1562 "For example: set_network 1 ssid \"network name\"\n"
1564 "Please see wpa_supplicant.conf documentation for full list "
1565 "of\navailable variables.\n");
1569 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1576 wpa_cli_show_network_variables();
1581 printf("Invalid SET_NETWORK command: needs three arguments\n"
1582 "(network id, variable name, and value)\n");
1586 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1587 argv
[0], argv
[1], argv
[2]);
1588 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1589 printf("Too long SET_NETWORK command.\n");
1592 return wpa_ctrl_command(ctrl
, cmd
);
1596 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1603 wpa_cli_show_network_variables();
1608 printf("Invalid GET_NETWORK command: needs two arguments\n"
1609 "(network id and variable name)\n");
1613 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1615 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1616 printf("Too long GET_NETWORK command.\n");
1619 return wpa_ctrl_command(ctrl
, cmd
);
1623 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1626 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1630 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1633 return wpa_ctrl_command(ctrl
, "RECONNECT");
1637 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1640 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1644 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1646 return wpa_ctrl_command(ctrl
, "SCAN");
1650 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1653 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1657 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1663 printf("Invalid BSS command: need one argument (index or "
1668 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1669 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1671 cmd
[sizeof(cmd
) - 1] = '\0';
1673 return wpa_ctrl_command(ctrl
, cmd
);
1677 static char ** wpa_cli_complete_bss(const char *str
, int pos
)
1679 int arg
= get_cmd_arg_num(str
, pos
);
1684 res
= cli_txt_list_array(&bsses
);
1692 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1698 if (argc
< 1 || argc
> 2) {
1699 printf("Invalid GET_CAPABILITY command: need either one or "
1704 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1705 printf("Invalid GET_CAPABILITY command: second argument, "
1706 "if any, must be 'strict'\n");
1710 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1711 (argc
== 2) ? " strict" : "");
1712 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1714 cmd
[sizeof(cmd
) - 1] = '\0';
1716 return wpa_ctrl_command(ctrl
, cmd
);
1720 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1722 printf("Available interfaces:\n");
1723 return wpa_ctrl_command(ctrl
, "INTERFACES");
1727 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1730 wpa_cli_list_interfaces(ctrl
);
1734 wpa_cli_close_connection();
1735 os_free(ctrl_ifname
);
1736 ctrl_ifname
= os_strdup(argv
[0]);
1738 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1739 printf("Connected to interface '%s.\n", ctrl_ifname
);
1741 printf("Could not connect to interface '%s' - re-trying\n",
1748 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1751 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1755 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1758 return wpa_ctrl_command(ctrl
, "TERMINATE");
1762 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1769 printf("Invalid INTERFACE_ADD command: needs at least one "
1770 "argument (interface name)\n"
1771 "All arguments: ifname confname driver ctrl_interface "
1772 "driver_param bridge_name\n");
1777 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1778 * <driver_param>TAB<bridge_name>
1780 res
= os_snprintf(cmd
, sizeof(cmd
),
1781 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1783 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1784 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1785 argc
> 5 ? argv
[5] : "");
1786 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1788 cmd
[sizeof(cmd
) - 1] = '\0';
1789 return wpa_ctrl_command(ctrl
, cmd
);
1793 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1800 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1801 "(interface name)\n");
1805 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1806 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1808 cmd
[sizeof(cmd
) - 1] = '\0';
1809 return wpa_ctrl_command(ctrl
, cmd
);
1813 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1816 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1821 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1825 printf("Invalid 'sta' command - exactly one argument, STA "
1826 "address, is required.\n");
1829 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1830 return wpa_ctrl_command(ctrl
, buf
);
1834 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1835 char *addr
, size_t addr_len
)
1837 char buf
[4096], *pos
;
1841 if (ctrl_conn
== NULL
) {
1842 printf("Not connected to hostapd - command dropped.\n");
1845 len
= sizeof(buf
) - 1;
1846 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1849 printf("'%s' command timed out.\n", cmd
);
1851 } else if (ret
< 0) {
1852 printf("'%s' command failed.\n", cmd
);
1857 if (memcmp(buf
, "FAIL", 4) == 0)
1862 while (*pos
!= '\0' && *pos
!= '\n')
1865 os_strlcpy(addr
, buf
, addr_len
);
1870 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1872 char addr
[32], cmd
[64];
1874 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1877 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1878 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1882 #endif /* CONFIG_AP */
1885 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1887 return wpa_ctrl_command(ctrl
, "SUSPEND");
1891 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1893 return wpa_ctrl_command(ctrl
, "RESUME");
1897 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1899 return wpa_ctrl_command(ctrl
, "DROP_SA");
1903 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1909 printf("Invalid ROAM command: needs one argument "
1910 "(target AP's BSSID)\n");
1914 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
1915 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1916 printf("Too long ROAM command.\n");
1919 return wpa_ctrl_command(ctrl
, cmd
);
1925 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1931 return wpa_ctrl_command(ctrl
, "P2P_FIND");
1934 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
1937 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
1938 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1940 cmd
[sizeof(cmd
) - 1] = '\0';
1941 return wpa_ctrl_command(ctrl
, cmd
);
1945 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1948 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1952 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1959 printf("Invalid P2P_CONNECT command: needs at least two "
1960 "arguments (address and pbc/PIN)\n");
1965 res
= os_snprintf(cmd
, sizeof(cmd
),
1966 "P2P_CONNECT %s %s %s %s %s",
1967 argv
[0], argv
[1], argv
[2], argv
[3],
1970 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
1971 argv
[0], argv
[1], argv
[2], argv
[3]);
1973 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
1974 argv
[0], argv
[1], argv
[2]);
1976 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
1978 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1980 cmd
[sizeof(cmd
) - 1] = '\0';
1981 return wpa_ctrl_command(ctrl
, cmd
);
1985 static char ** wpa_cli_complete_p2p_connect(const char *str
, int pos
)
1987 int arg
= get_cmd_arg_num(str
, pos
);
1992 res
= cli_txt_list_array(&p2p_peers
);
2000 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
2007 return wpa_ctrl_command(ctrl
, "P2P_LISTEN");
2009 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_LISTEN %s", argv
[0]);
2010 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2012 cmd
[sizeof(cmd
) - 1] = '\0';
2013 return wpa_ctrl_command(ctrl
, cmd
);
2017 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
2024 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2025 "(interface name)\n");
2029 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
2030 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2032 cmd
[sizeof(cmd
) - 1] = '\0';
2033 return wpa_ctrl_command(ctrl
, cmd
);
2037 static char ** wpa_cli_complete_p2p_group_remove(const char *str
, int pos
)
2039 int arg
= get_cmd_arg_num(str
, pos
);
2044 res
= cli_txt_list_array(&p2p_groups
);
2052 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
2059 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
2062 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s %s",
2065 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s",
2067 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2069 cmd
[sizeof(cmd
) - 1] = '\0';
2070 return wpa_ctrl_command(ctrl
, cmd
);
2074 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
2081 printf("Invalid P2P_PROV_DISC command: needs two arguments "
2082 "(address and config method\n"
2083 "(display, keypad, or pbc)\n");
2087 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
2089 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2091 cmd
[sizeof(cmd
) - 1] = '\0';
2092 return wpa_ctrl_command(ctrl
, cmd
);
2096 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
2099 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
2103 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
2109 if (argc
!= 2 && argc
!= 4) {
2110 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2111 "arguments (address and TLVs) or four arguments "
2112 "(address, \"upnp\", version, search target "
2118 res
= os_snprintf(cmd
, sizeof(cmd
),
2119 "P2P_SERV_DISC_REQ %s %s %s %s",
2120 argv
[0], argv
[1], argv
[2], argv
[3]);
2122 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
2124 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2126 cmd
[sizeof(cmd
) - 1] = '\0';
2127 return wpa_ctrl_command(ctrl
, cmd
);
2131 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
2132 int argc
, char *argv
[])
2138 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2139 "argument (pending request identifier)\n");
2143 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
2145 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2147 cmd
[sizeof(cmd
) - 1] = '\0';
2148 return wpa_ctrl_command(ctrl
, cmd
);
2152 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
2159 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2160 "arguments (freq, address, dialog token, and TLVs)\n");
2164 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
2165 argv
[0], argv
[1], argv
[2], argv
[3]);
2166 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2168 cmd
[sizeof(cmd
) - 1] = '\0';
2169 return wpa_ctrl_command(ctrl
, cmd
);
2173 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
2176 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
2180 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
2181 int argc
, char *argv
[])
2187 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2188 "argument (external processing: 0/1)\n");
2192 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
2194 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2196 cmd
[sizeof(cmd
) - 1] = '\0';
2197 return wpa_ctrl_command(ctrl
, cmd
);
2201 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
2204 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
2208 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
2214 if (argc
!= 3 && argc
!= 4) {
2215 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2221 res
= os_snprintf(cmd
, sizeof(cmd
),
2222 "P2P_SERVICE_ADD %s %s %s %s",
2223 argv
[0], argv
[1], argv
[2], argv
[3]);
2225 res
= os_snprintf(cmd
, sizeof(cmd
),
2226 "P2P_SERVICE_ADD %s %s %s",
2227 argv
[0], argv
[1], argv
[2]);
2228 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2230 cmd
[sizeof(cmd
) - 1] = '\0';
2231 return wpa_ctrl_command(ctrl
, cmd
);
2235 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
2241 if (argc
!= 2 && argc
!= 3) {
2242 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2248 res
= os_snprintf(cmd
, sizeof(cmd
),
2249 "P2P_SERVICE_DEL %s %s %s",
2250 argv
[0], argv
[1], argv
[2]);
2252 res
= os_snprintf(cmd
, sizeof(cmd
),
2253 "P2P_SERVICE_DEL %s %s",
2255 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2257 cmd
[sizeof(cmd
) - 1] = '\0';
2258 return wpa_ctrl_command(ctrl
, cmd
);
2262 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
2263 int argc
, char *argv
[])
2269 printf("Invalid P2P_REJECT command: needs one argument "
2270 "(peer address)\n");
2274 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
2275 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2277 cmd
[sizeof(cmd
) - 1] = '\0';
2278 return wpa_ctrl_command(ctrl
, cmd
);
2282 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
2283 int argc
, char *argv
[])
2289 printf("Invalid P2P_INVITE command: needs at least one "
2295 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
2296 argv
[0], argv
[1], argv
[2]);
2298 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
2301 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
2302 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2304 cmd
[sizeof(cmd
) - 1] = '\0';
2305 return wpa_ctrl_command(ctrl
, cmd
);
2309 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2313 printf("Invalid 'p2p_peer' command - exactly one argument, "
2314 "P2P peer device address, is required.\n");
2317 os_snprintf(buf
, sizeof(buf
), "P2P_PEER %s", argv
[0]);
2318 return wpa_ctrl_command(ctrl
, buf
);
2322 static char ** wpa_cli_complete_p2p_peer(const char *str
, int pos
)
2324 int arg
= get_cmd_arg_num(str
, pos
);
2329 res
= cli_txt_list_array(&p2p_peers
);
2337 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
2338 char *addr
, size_t addr_len
,
2341 char buf
[4096], *pos
;
2345 if (ctrl_conn
== NULL
)
2347 len
= sizeof(buf
) - 1;
2348 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
2351 printf("'%s' command timed out.\n", cmd
);
2353 } else if (ret
< 0) {
2354 printf("'%s' command failed.\n", cmd
);
2359 if (memcmp(buf
, "FAIL", 4) == 0)
2363 while (*pos
!= '\0' && *pos
!= '\n')
2366 os_strlcpy(addr
, buf
, addr_len
);
2367 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2368 printf("%s\n", addr
);
2373 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2375 char addr
[32], cmd
[64];
2378 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2380 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2381 addr
, sizeof(addr
), discovered
))
2384 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2385 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2392 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2398 printf("Invalid P2P_SET command: needs two arguments (field, "
2403 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
2404 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2406 cmd
[sizeof(cmd
) - 1] = '\0';
2407 return wpa_ctrl_command(ctrl
, cmd
);
2411 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2413 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2417 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2420 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2424 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
2431 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2432 "(peer address)\n");
2436 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_UNAUTHORIZE %s", argv
[0]);
2438 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2441 cmd
[sizeof(cmd
) - 1] = '\0';
2442 return wpa_ctrl_command(ctrl
, cmd
);
2446 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2452 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2453 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2454 "(preferred duration, interval; in microsecods).\n"
2455 "Optional second pair can be used to provide "
2456 "acceptable values.\n");
2461 res
= os_snprintf(cmd
, sizeof(cmd
),
2462 "P2P_PRESENCE_REQ %s %s %s %s",
2463 argv
[0], argv
[1], argv
[2], argv
[3]);
2465 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2468 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
2469 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2471 cmd
[sizeof(cmd
) - 1] = '\0';
2472 return wpa_ctrl_command(ctrl
, cmd
);
2476 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2482 if (argc
!= 0 && argc
!= 2) {
2483 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2484 "(availability period, availability interval; in "
2486 "Extended Listen Timing can be cancelled with this "
2487 "command when used without parameters.\n");
2492 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2495 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2496 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2498 cmd
[sizeof(cmd
) - 1] = '\0';
2499 return wpa_ctrl_command(ctrl
, cmd
);
2502 #endif /* CONFIG_P2P */
2505 #ifdef CONFIG_INTERWORKING
2506 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2509 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
2513 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2516 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
2520 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl
*ctrl
, int argc
,
2527 return wpa_ctrl_command(ctrl
, "INTERWORKING_SELECT");
2529 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERWORKING_SELECT %s", argv
[0]);
2530 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2532 cmd
[sizeof(cmd
) - 1] = '\0';
2533 return wpa_ctrl_command(ctrl
, cmd
);
2537 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl
*ctrl
, int argc
,
2544 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2545 "argument (BSSID)\n");
2549 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERWORKING_CONNECT %s",
2551 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2553 cmd
[sizeof(cmd
) - 1] = '\0';
2554 return wpa_ctrl_command(ctrl
, cmd
);
2558 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2564 printf("Invalid ANQP_GET command: needs two arguments "
2565 "(addr and info id list)\n");
2569 res
= os_snprintf(cmd
, sizeof(cmd
), "ANQP_GET %s %s",
2571 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2573 cmd
[sizeof(cmd
) - 1] = '\0';
2574 return wpa_ctrl_command(ctrl
, cmd
);
2576 #endif /* CONFIG_INTERWORKING */
2579 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2586 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2587 "(0/1 = disable/enable automatic reconnection)\n");
2590 res
= os_snprintf(cmd
, sizeof(cmd
), "STA_AUTOCONNECT %s", argv
[0]);
2591 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2592 printf("Too long STA_AUTOCONNECT command.\n");
2595 return wpa_ctrl_command(ctrl
, cmd
);
2599 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2606 printf("Invalid TDLS_DISCOVER command: needs one argument "
2607 "(Peer STA MAC address)\n");
2611 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_DISCOVER %s", argv
[0]);
2612 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2613 printf("Too long TDLS_DISCOVER command.\n");
2616 return wpa_ctrl_command(ctrl
, cmd
);
2620 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2627 printf("Invalid TDLS_SETUP command: needs one argument "
2628 "(Peer STA MAC address)\n");
2632 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_SETUP %s", argv
[0]);
2633 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2634 printf("Too long TDLS_SETUP command.\n");
2637 return wpa_ctrl_command(ctrl
, cmd
);
2641 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2648 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2649 "(Peer STA MAC address)\n");
2653 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_TEARDOWN %s", argv
[0]);
2654 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2655 printf("Too long TDLS_TEARDOWN command.\n");
2658 return wpa_ctrl_command(ctrl
, cmd
);
2662 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2665 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2669 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
2672 return wpa_ctrl_command(ctrl
, "REAUTHENTICATE");
2676 enum wpa_cli_cmd_flags
{
2677 cli_cmd_flag_none
= 0x00,
2678 cli_cmd_flag_sensitive
= 0x01
2681 struct wpa_cli_cmd
{
2683 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2684 enum wpa_cli_cmd_flags flags
;
2688 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2689 { "status", wpa_cli_cmd_status
,
2691 "[verbose] = get current WPA/EAPOL/EAP status" },
2692 { "ping", wpa_cli_cmd_ping
,
2694 "= pings wpa_supplicant" },
2695 { "relog", wpa_cli_cmd_relog
,
2697 "= re-open log-file (allow rolling logs)" },
2698 { "note", wpa_cli_cmd_note
,
2700 "<text> = add a note to wpa_supplicant debug log" },
2701 { "mib", wpa_cli_cmd_mib
,
2703 "= get MIB variables (dot1x, dot11)" },
2704 { "help", wpa_cli_cmd_help
,
2706 "= show this usage help" },
2707 { "interface", wpa_cli_cmd_interface
,
2709 "[ifname] = show interfaces/select interface" },
2710 { "level", wpa_cli_cmd_level
,
2712 "<debug level> = change debug level" },
2713 { "license", wpa_cli_cmd_license
,
2715 "= show full wpa_cli license" },
2716 { "quit", wpa_cli_cmd_quit
,
2719 { "set", wpa_cli_cmd_set
,
2721 "= set variables (shows list of variables when run without "
2723 { "get", wpa_cli_cmd_get
,
2725 "<name> = get information" },
2726 { "logon", wpa_cli_cmd_logon
,
2728 "= IEEE 802.1X EAPOL state machine logon" },
2729 { "logoff", wpa_cli_cmd_logoff
,
2731 "= IEEE 802.1X EAPOL state machine logoff" },
2732 { "pmksa", wpa_cli_cmd_pmksa
,
2734 "= show PMKSA cache" },
2735 { "reassociate", wpa_cli_cmd_reassociate
,
2737 "= force reassociation" },
2738 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2740 "<BSSID> = force preauthentication" },
2741 { "identity", wpa_cli_cmd_identity
,
2743 "<network id> <identity> = configure identity for an SSID" },
2744 { "password", wpa_cli_cmd_password
,
2745 cli_cmd_flag_sensitive
,
2746 "<network id> <password> = configure password for an SSID" },
2747 { "new_password", wpa_cli_cmd_new_password
,
2748 cli_cmd_flag_sensitive
,
2749 "<network id> <password> = change password for an SSID" },
2750 { "pin", wpa_cli_cmd_pin
,
2751 cli_cmd_flag_sensitive
,
2752 "<network id> <pin> = configure pin for an SSID" },
2753 { "otp", wpa_cli_cmd_otp
,
2754 cli_cmd_flag_sensitive
,
2755 "<network id> <password> = configure one-time-password for an SSID"
2757 { "passphrase", wpa_cli_cmd_passphrase
,
2758 cli_cmd_flag_sensitive
,
2759 "<network id> <passphrase> = configure private key passphrase\n"
2761 { "bssid", wpa_cli_cmd_bssid
,
2763 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2764 { "blacklist", wpa_cli_cmd_blacklist
,
2766 "<BSSID> = add a BSSID to the blacklist\n"
2767 "blacklist clear = clear the blacklist\n"
2768 "blacklist = display the blacklist" },
2769 { "log_level", wpa_cli_cmd_log_level
,
2771 "<level> [<timestamp>] = update the log level/timestamp\n"
2772 "log_level = display the current log level and log options" },
2773 { "list_networks", wpa_cli_cmd_list_networks
,
2775 "= list configured networks" },
2776 { "select_network", wpa_cli_cmd_select_network
,
2778 "<network id> = select a network (disable others)" },
2779 { "enable_network", wpa_cli_cmd_enable_network
,
2781 "<network id> = enable a network" },
2782 { "disable_network", wpa_cli_cmd_disable_network
,
2784 "<network id> = disable a network" },
2785 { "add_network", wpa_cli_cmd_add_network
,
2787 "= add a network" },
2788 { "remove_network", wpa_cli_cmd_remove_network
,
2790 "<network id> = remove a network" },
2791 { "set_network", wpa_cli_cmd_set_network
,
2792 cli_cmd_flag_sensitive
,
2793 "<network id> <variable> <value> = set network variables (shows\n"
2794 " list of variables when run without arguments)" },
2795 { "get_network", wpa_cli_cmd_get_network
,
2797 "<network id> <variable> = get network variables" },
2798 { "save_config", wpa_cli_cmd_save_config
,
2800 "= save the current configuration" },
2801 { "disconnect", wpa_cli_cmd_disconnect
,
2803 "= disconnect and wait for reassociate/reconnect command before\n"
2805 { "reconnect", wpa_cli_cmd_reconnect
,
2807 "= like reassociate, but only takes effect if already disconnected"
2809 { "scan", wpa_cli_cmd_scan
,
2811 "= request new BSS scan" },
2812 { "scan_results", wpa_cli_cmd_scan_results
,
2814 "= get latest scan results" },
2815 { "bss", wpa_cli_cmd_bss
,
2817 "<<idx> | <bssid>> = get detailed scan result info" },
2818 { "get_capability", wpa_cli_cmd_get_capability
,
2820 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2821 { "reconfigure", wpa_cli_cmd_reconfigure
,
2823 "= force wpa_supplicant to re-read its configuration file" },
2824 { "terminate", wpa_cli_cmd_terminate
,
2826 "= terminate wpa_supplicant" },
2827 { "interface_add", wpa_cli_cmd_interface_add
,
2829 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2830 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2832 { "interface_remove", wpa_cli_cmd_interface_remove
,
2834 "<ifname> = removes the interface" },
2835 { "interface_list", wpa_cli_cmd_interface_list
,
2837 "= list available interfaces" },
2838 { "ap_scan", wpa_cli_cmd_ap_scan
,
2840 "<value> = set ap_scan parameter" },
2841 { "scan_interval", wpa_cli_cmd_scan_interval
,
2843 "<value> = set scan_interval parameter (in seconds)" },
2844 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
,
2846 "<value> = set BSS expiration age parameter" },
2847 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
,
2849 "<value> = set BSS expiration scan count parameter" },
2850 { "stkstart", wpa_cli_cmd_stkstart
,
2852 "<addr> = request STK negotiation with <addr>" },
2853 { "ft_ds", wpa_cli_cmd_ft_ds
,
2855 "<addr> = request over-the-DS FT with <addr>" },
2856 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
2858 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2859 { "wps_pin", wpa_cli_cmd_wps_pin
,
2860 cli_cmd_flag_sensitive
,
2861 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2863 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
2864 cli_cmd_flag_sensitive
,
2865 "<PIN> = verify PIN checksum" },
2866 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
2867 "Cancels the pending WPS operation" },
2868 #ifdef CONFIG_WPS_OOB
2869 { "wps_oob", wpa_cli_cmd_wps_oob
,
2870 cli_cmd_flag_sensitive
,
2871 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2872 #endif /* CONFIG_WPS_OOB */
2873 { "wps_reg", wpa_cli_cmd_wps_reg
,
2874 cli_cmd_flag_sensitive
,
2875 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2876 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
,
2877 cli_cmd_flag_sensitive
,
2878 "[params..] = enable/disable AP PIN" },
2879 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
2881 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2882 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
2884 "= stop Wi-Fi Protected Setup External Registrar" },
2885 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
2886 cli_cmd_flag_sensitive
,
2887 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2888 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
2890 "<UUID> = accept an Enrollee PBC using External Registrar" },
2891 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
2892 cli_cmd_flag_sensitive
,
2893 "<UUID> <PIN> = learn AP configuration" },
2894 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
,
2896 "<UUID> <network id> = set AP configuration for enrolling" },
2897 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
2898 cli_cmd_flag_sensitive
,
2899 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2900 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
2902 "<addr> = request RSN authentication with <addr> in IBSS" },
2904 { "sta", wpa_cli_cmd_sta
,
2906 "<addr> = get information about an associated station (AP)" },
2907 { "all_sta", wpa_cli_cmd_all_sta
,
2909 "= get information about all associated stations (AP)" },
2910 #endif /* CONFIG_AP */
2911 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
2912 "= notification of suspend/hibernate" },
2913 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
2914 "= notification of resume/thaw" },
2915 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
2916 "= drop SA without deauth/disassoc (test command)" },
2917 { "roam", wpa_cli_cmd_roam
,
2919 "<addr> = roam to the specified BSS" },
2921 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
2922 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2923 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
2924 "= stop P2P Devices search" },
2925 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
2926 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2927 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
2928 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2929 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
2930 "<ifname> = remove P2P group interface (terminate group if GO)" },
2931 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
2932 "= add a new P2P group (local end as GO)" },
2933 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
2934 "<addr> <method> = request provisioning discovery" },
2935 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
2937 "= get the passphrase for a group (GO only)" },
2938 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2940 "<addr> <TLVs> = schedule service discovery request" },
2941 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2943 "<id> = cancel pending service discovery request" },
2944 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2946 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2947 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2949 "= indicate change in local services" },
2950 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2952 "<external> = set external processing of service discovery" },
2953 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2955 "= remove all stored service entries" },
2956 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2958 "<bonjour|upnp> <query|version> <response|service> = add a local "
2960 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2962 "<bonjour|upnp> <query|version> [|service] = remove a local "
2964 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2966 "<addr> = reject connection attempts from a specific peer" },
2967 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
2969 "<cmd> [peer=addr] = invite peer" },
2970 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
2971 "[discovered] = list known (optionally, only fully discovered) P2P "
2973 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
2974 "<address> = show information about known P2P peer" },
2975 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
2976 "<field> <value> = set a P2P parameter" },
2977 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
2978 "= flush P2P state" },
2979 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
2980 "= cancel P2P group formation" },
2981 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
, cli_cmd_flag_none
,
2982 "<address> = unauthorize a peer" },
2983 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
2984 "[<duration> <interval>] [<duration> <interval>] = request GO "
2986 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
2987 "[<period> <interval>] = set extended listen timing" },
2988 #endif /* CONFIG_P2P */
2990 #ifdef CONFIG_INTERWORKING
2991 { "fetch_anqp", wpa_cli_cmd_fetch_anqp
, cli_cmd_flag_none
,
2992 "= fetch ANQP information for all APs" },
2993 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp
, cli_cmd_flag_none
,
2994 "= stop fetch_anqp operation" },
2995 { "interworking_select", wpa_cli_cmd_interworking_select
,
2997 "[auto] = perform Interworking network selection" },
2998 { "interworking_connect", wpa_cli_cmd_interworking_connect
,
3000 "<BSSID> = connect using Interworking credentials" },
3001 { "anqp_get", wpa_cli_cmd_anqp_get
, cli_cmd_flag_none
,
3002 "<addr> <info id>[,<info id>]... = request ANQP information" },
3003 #endif /* CONFIG_INTERWORKING */
3004 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
3005 "<0/1> = disable/enable automatic reconnection" },
3006 { "tdls_discover", wpa_cli_cmd_tdls_discover
,
3008 "<addr> = request TDLS discovery with <addr>" },
3009 { "tdls_setup", wpa_cli_cmd_tdls_setup
,
3011 "<addr> = request TDLS setup with <addr>" },
3012 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
,
3014 "<addr> = tear down TDLS with <addr>" },
3015 { "signal_poll", wpa_cli_cmd_signal_poll
,
3017 "= get signal parameters" },
3018 { "reauthenticate", wpa_cli_cmd_reauthenticate
, cli_cmd_flag_none
,
3019 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3020 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
3025 * Prints command usage, lines are padded with the specified string.
3027 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
3032 printf("%s%s ", pad
, cmd
->cmd
);
3033 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
3042 static void print_help(void)
3045 printf("commands:\n");
3046 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
3047 print_cmd_help(&wpa_cli_commands
[n
], " ");
3051 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
3053 const char *c
, *delim
;
3057 delim
= os_strchr(cmd
, ' ');
3061 len
= os_strlen(cmd
);
3063 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
3064 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
3065 return (wpa_cli_commands
[n
].flags
&
3066 cli_cmd_flag_sensitive
);
3072 static char ** wpa_list_cmd_list(void)
3077 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
3078 res
= os_zalloc(count
* sizeof(char *));
3082 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
3083 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
3092 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
3097 if (os_strcasecmp(cmd
, "bss") == 0)
3098 return wpa_cli_complete_bss(str
, pos
);
3100 if (os_strcasecmp(cmd
, "p2p_connect") == 0)
3101 return wpa_cli_complete_p2p_connect(str
, pos
);
3102 if (os_strcasecmp(cmd
, "p2p_peer") == 0)
3103 return wpa_cli_complete_p2p_peer(str
, pos
);
3104 if (os_strcasecmp(cmd
, "p2p_group_remove") == 0)
3105 return wpa_cli_complete_p2p_group_remove(str
, pos
);
3106 #endif /* CONFIG_P2P */
3108 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
3109 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
3111 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
3121 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
3127 end
= os_strchr(str
, ' ');
3128 if (end
== NULL
|| str
+ pos
< end
)
3129 return wpa_list_cmd_list();
3131 cmd
= os_malloc(pos
+ 1);
3134 os_memcpy(cmd
, str
, pos
);
3135 cmd
[end
- str
] = '\0';
3136 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
3142 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
3144 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
3149 cmd
= wpa_cli_commands
;
3151 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
3154 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
3155 /* we have an exact match */
3165 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
3166 cmd
= wpa_cli_commands
;
3168 if (os_strncasecmp(cmd
->cmd
, argv
[0],
3169 os_strlen(argv
[0])) == 0) {
3170 printf(" %s", cmd
->cmd
);
3176 } else if (count
== 0) {
3177 printf("Unknown command '%s'\n", argv
[0]);
3180 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
3187 static int str_match(const char *a
, const char *b
)
3189 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
3193 static int wpa_cli_exec(const char *program
, const char *arg1
,
3201 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
3202 cmd
= os_malloc(len
);
3205 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
3206 if (res
< 0 || (size_t) res
>= len
) {
3210 cmd
[len
- 1] = '\0';
3212 if (system(cmd
) < 0)
3214 #endif /* _WIN32_WCE */
3221 static void wpa_cli_action_process(const char *msg
)
3224 char *copy
= NULL
, *id
, *pos2
;
3229 pos
= os_strchr(pos
, '>');
3236 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
3238 os_unsetenv("WPA_ID");
3239 os_unsetenv("WPA_ID_STR");
3240 os_unsetenv("WPA_CTRL_DIR");
3242 pos
= os_strstr(pos
, "[id=");
3244 copy
= os_strdup(pos
+ 4);
3248 while (*pos2
&& *pos2
!= ' ')
3252 os_setenv("WPA_ID", id
, 1);
3253 while (*pos2
&& *pos2
!= '=')
3258 while (*pos2
&& *pos2
!= ']')
3261 os_setenv("WPA_ID_STR", id
, 1);
3265 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
3267 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
3268 wpa_cli_connected
= 1;
3269 wpa_cli_last_id
= new_id
;
3270 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
3272 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
3273 if (wpa_cli_connected
) {
3274 wpa_cli_connected
= 0;
3275 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
3277 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
3278 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3279 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
3280 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3281 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
3282 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3283 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
3284 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3285 } else if (str_match(pos
, P2P_EVENT_GO_NEG_FAILURE
)) {
3286 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3287 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
3288 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3289 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
3290 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3291 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
3292 printf("wpa_supplicant is terminating - stop monitoring\n");
3298 #ifndef CONFIG_ANSI_C_EXTRA
3299 static void wpa_cli_action_cb(char *msg
, size_t len
)
3301 wpa_cli_action_process(msg
);
3303 #endif /* CONFIG_ANSI_C_EXTRA */
3306 static void wpa_cli_reconnect(void)
3308 wpa_cli_close_connection();
3309 wpa_cli_open_connection(ctrl_ifname
, 1);
3313 static void cli_event(const char *str
)
3315 const char *start
, *s
;
3317 start
= os_strchr(str
, '>');
3323 if (str_starts(start
, WPA_EVENT_BSS_ADDED
)) {
3324 s
= os_strchr(start
, ' ');
3327 s
= os_strchr(s
+ 1, ' ');
3330 cli_txt_list_add(&bsses
, s
+ 1);
3334 if (str_starts(start
, WPA_EVENT_BSS_REMOVED
)) {
3335 s
= os_strchr(start
, ' ');
3338 s
= os_strchr(s
+ 1, ' ');
3341 cli_txt_list_del_addr(&bsses
, s
+ 1);
3346 if (str_starts(start
, P2P_EVENT_DEVICE_FOUND
)) {
3347 s
= os_strstr(start
, " p2p_dev_addr=");
3350 cli_txt_list_add_addr(&p2p_peers
, s
+ 14);
3354 if (str_starts(start
, P2P_EVENT_DEVICE_LOST
)) {
3355 s
= os_strstr(start
, " p2p_dev_addr=");
3358 cli_txt_list_del_addr(&p2p_peers
, s
+ 14);
3362 if (str_starts(start
, P2P_EVENT_GROUP_STARTED
)) {
3363 s
= os_strchr(start
, ' ');
3366 cli_txt_list_add_word(&p2p_groups
, s
+ 1);
3370 if (str_starts(start
, P2P_EVENT_GROUP_REMOVED
)) {
3371 s
= os_strchr(start
, ' ');
3374 cli_txt_list_del_word(&p2p_groups
, s
+ 1);
3377 #endif /* CONFIG_P2P */
3381 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
3383 if (ctrl_conn
== NULL
) {
3384 wpa_cli_reconnect();
3387 while (wpa_ctrl_pending(ctrl
) > 0) {
3389 size_t len
= sizeof(buf
) - 1;
3390 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
3393 wpa_cli_action_process(buf
);
3396 if (wpa_cli_show_event(buf
)) {
3398 printf("\r%s\n", buf
);
3403 printf("Could not read pending message.\n");
3408 if (wpa_ctrl_pending(ctrl
) < 0) {
3409 printf("Connection to wpa_supplicant lost - trying to "
3411 wpa_cli_reconnect();
3417 static int tokenize_cmd(char *cmd
, char *argv
[])
3430 if (argc
== max_args
)
3433 char *pos2
= os_strrchr(pos
, '"');
3437 while (*pos
!= '\0' && *pos
!= ' ')
3447 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
3449 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3450 printf("Connection to wpa_supplicant lost - trying to "
3452 wpa_cli_close_connection();
3455 wpa_cli_reconnect();
3456 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3460 static void wpa_cli_eloop_terminate(int sig
, void *signal_ctx
)
3466 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
3468 wpa_cli_recv_pending(mon_conn
, 0);
3472 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
3474 char *argv
[max_args
];
3476 argc
= tokenize_cmd(cmd
, argv
);
3478 wpa_request(ctrl_conn
, argc
, argv
);
3482 static void wpa_cli_edit_eof_cb(void *ctx
)
3488 static void wpa_cli_interactive(void)
3490 char *home
, *hfile
= NULL
;
3492 printf("\nInteractive mode\n\n");
3494 home
= getenv("HOME");
3496 const char *fname
= ".wpa_cli_history";
3497 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
3498 hfile
= os_malloc(hfile_len
);
3500 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
3503 eloop_register_signal_terminate(wpa_cli_eloop_terminate
, NULL
);
3504 edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
3505 wpa_cli_edit_completion_cb
, NULL
, hfile
);
3506 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3510 cli_txt_list_flush(&p2p_peers
);
3511 cli_txt_list_flush(&p2p_groups
);
3512 cli_txt_list_flush(&bsses
);
3513 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3515 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3516 wpa_cli_close_connection();
3520 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3522 #ifdef CONFIG_ANSI_C_EXTRA
3523 /* TODO: ANSI C version(?) */
3524 printf("Action processing not supported in ANSI C build.\n");
3525 #else /* CONFIG_ANSI_C_EXTRA */
3529 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3532 fd
= wpa_ctrl_get_fd(ctrl
);
3534 while (!wpa_cli_quit
) {
3537 tv
.tv_sec
= ping_interval
;
3539 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3540 if (res
< 0 && errno
!= EINTR
) {
3545 if (FD_ISSET(fd
, &rfds
))
3546 wpa_cli_recv_pending(ctrl
, 1);
3548 /* verify that connection is still working */
3549 len
= sizeof(buf
) - 1;
3550 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3551 wpa_cli_action_cb
) < 0 ||
3552 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3553 printf("wpa_supplicant did not reply to PING "
3554 "command - exiting\n");
3559 #endif /* CONFIG_ANSI_C_EXTRA */
3563 static void wpa_cli_cleanup(void)
3565 wpa_cli_close_connection();
3567 os_daemonize_terminate(pid_file
);
3569 os_program_deinit();
3572 static void wpa_cli_terminate(int sig
)
3579 static char * wpa_cli_get_default_ifname(void)
3581 char *ifname
= NULL
;
3583 #ifdef CONFIG_CTRL_IFACE_UNIX
3584 struct dirent
*dent
;
3585 DIR *dir
= opendir(ctrl_iface_dir
);
3588 char ifprop
[PROPERTY_VALUE_MAX
];
3589 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3590 ifname
= os_strdup(ifprop
);
3591 printf("Using interface '%s'\n", ifname
);
3594 #endif /* ANDROID */
3597 while ((dent
= readdir(dir
))) {
3598 #ifdef _DIRENT_HAVE_D_TYPE
3600 * Skip the file if it is not a socket. Also accept
3601 * DT_UNKNOWN (0) in case the C library or underlying
3602 * file system does not support d_type.
3604 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3606 #endif /* _DIRENT_HAVE_D_TYPE */
3607 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3608 os_strcmp(dent
->d_name
, "..") == 0)
3610 printf("Selected interface '%s'\n", dent
->d_name
);
3611 ifname
= os_strdup(dent
->d_name
);
3615 #endif /* CONFIG_CTRL_IFACE_UNIX */
3617 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3618 char buf
[2048], *pos
;
3620 struct wpa_ctrl
*ctrl
;
3623 ctrl
= wpa_ctrl_open(NULL
);
3627 len
= sizeof(buf
) - 1;
3628 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3631 pos
= os_strchr(buf
, '\n');
3634 ifname
= os_strdup(buf
);
3636 wpa_ctrl_close(ctrl
);
3637 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3643 int main(int argc
, char *argv
[])
3645 int warning_displayed
= 0;
3649 const char *global
= NULL
;
3651 if (os_program_init())
3655 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3660 action_file
= optarg
;
3669 ping_interval
= atoi(optarg
);
3675 printf("%s\n", wpa_cli_version
);
3678 os_free(ctrl_ifname
);
3679 ctrl_ifname
= os_strdup(optarg
);
3682 ctrl_iface_dir
= optarg
;
3693 interactive
= (argc
== optind
) && (action_file
== NULL
);
3696 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3702 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3703 ctrl_conn
= wpa_ctrl_open(NULL
);
3704 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3705 ctrl_conn
= wpa_ctrl_open(global
);
3706 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3707 if (ctrl_conn
== NULL
) {
3708 perror("Failed to connect to wpa_supplicant - "
3715 signal(SIGINT
, wpa_cli_terminate
);
3716 signal(SIGTERM
, wpa_cli_terminate
);
3717 #endif /* _WIN32_WCE */
3719 if (ctrl_ifname
== NULL
)
3720 ctrl_ifname
= wpa_cli_get_default_ifname();
3724 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3725 if (warning_displayed
)
3726 printf("Connection established.\n");
3730 if (!warning_displayed
) {
3731 printf("Could not connect to wpa_supplicant - "
3733 warning_displayed
= 1;
3740 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3741 perror("Failed to connect to wpa_supplicant - "
3747 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3748 wpa_cli_attached
= 1;
3750 printf("Warning: Failed to attach to "
3751 "wpa_supplicant.\n");
3757 if (daemonize
&& os_daemonize(pid_file
))
3761 wpa_cli_interactive();
3762 else if (action_file
)
3763 wpa_cli_action(ctrl_conn
);
3765 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
3767 os_free(ctrl_ifname
);
3774 #else /* CONFIG_CTRL_IFACE */
3775 int main(int argc
, char *argv
[])
3777 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3780 #endif /* CONFIG_CTRL_IFACE */