2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
11 #ifdef CONFIG_CTRL_IFACE
13 #ifdef CONFIG_CTRL_IFACE_UNIX
15 #endif /* CONFIG_CTRL_IFACE_UNIX */
17 #include "common/wpa_ctrl.h"
18 #include "utils/common.h"
19 #include "utils/eloop.h"
20 #include "utils/edit.h"
21 #include "utils/list.h"
22 #include "common/version.h"
23 #include "common/ieee802_11_defs.h"
25 #include <cutils/properties.h>
29 static const char *wpa_cli_version
=
30 "wpa_cli v" VERSION_STR
"\n"
31 "Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors";
34 static const char *wpa_cli_license
=
35 "This software may be distributed under the terms of the BSD license.\n"
36 "See README for more details.\n";
38 static const char *wpa_cli_full_license
=
39 "This software may be distributed under the terms of the BSD license.\n"
41 "Redistribution and use in source and binary forms, with or without\n"
42 "modification, are permitted provided that the following conditions are\n"
45 "1. Redistributions of source code must retain the above copyright\n"
46 " notice, this list of conditions and the following disclaimer.\n"
48 "2. Redistributions in binary form must reproduce the above copyright\n"
49 " notice, this list of conditions and the following disclaimer in the\n"
50 " documentation and/or other materials provided with the distribution.\n"
52 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
53 " names of its contributors may be used to endorse or promote products\n"
54 " derived from this software without specific prior written permission.\n"
56 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
57 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
58 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
59 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
60 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
61 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
62 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
63 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
64 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
65 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
66 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
69 static struct wpa_ctrl
*ctrl_conn
;
70 static struct wpa_ctrl
*mon_conn
;
71 static int wpa_cli_quit
= 0;
72 static int wpa_cli_attached
= 0;
73 static int wpa_cli_connected
= 0;
74 static int wpa_cli_last_id
= 0;
75 #ifndef CONFIG_CTRL_IFACE_DIR
76 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
77 #endif /* CONFIG_CTRL_IFACE_DIR */
78 static const char *ctrl_iface_dir
= CONFIG_CTRL_IFACE_DIR
;
79 static char *ctrl_ifname
= NULL
;
80 static const char *pid_file
= NULL
;
81 static const char *action_file
= NULL
;
82 static int ping_interval
= 5;
83 static int interactive
= 0;
85 struct cli_txt_entry
{
90 static DEFINE_DL_LIST(bsses
); /* struct cli_txt_entry */
91 static DEFINE_DL_LIST(p2p_peers
); /* struct cli_txt_entry */
92 static DEFINE_DL_LIST(p2p_groups
); /* struct cli_txt_entry */
95 static void print_help(void);
96 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
);
99 static void usage(void)
101 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
102 "[-a<action file>] \\\n"
103 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
105 " -h = help (show this usage text)\n"
106 " -v = shown version information\n"
107 " -a = run in daemon mode executing the action file based on "
110 " -B = run a daemon in the background\n"
111 " default path: " CONFIG_CTRL_IFACE_DIR
"\n"
112 " default interface: first interface found in socket path\n");
117 static void cli_txt_list_free(struct cli_txt_entry
*e
)
119 dl_list_del(&e
->list
);
125 static void cli_txt_list_flush(struct dl_list
*list
)
127 struct cli_txt_entry
*e
;
128 while ((e
= dl_list_first(list
, struct cli_txt_entry
, list
)))
129 cli_txt_list_free(e
);
133 static struct cli_txt_entry
* cli_txt_list_get(struct dl_list
*txt_list
,
136 struct cli_txt_entry
*e
;
137 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
138 if (os_strcmp(e
->txt
, txt
) == 0)
145 static void cli_txt_list_del(struct dl_list
*txt_list
, const char *txt
)
147 struct cli_txt_entry
*e
;
148 e
= cli_txt_list_get(txt_list
, txt
);
150 cli_txt_list_free(e
);
154 static void cli_txt_list_del_addr(struct dl_list
*txt_list
, const char *txt
)
158 if (hwaddr_aton(txt
, addr
) < 0)
160 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
161 cli_txt_list_del(txt_list
, buf
);
166 static void cli_txt_list_del_word(struct dl_list
*txt_list
, const char *txt
)
170 end
= os_strchr(txt
, ' ');
172 end
= txt
+ os_strlen(txt
);
173 buf
= os_malloc(end
- txt
+ 1);
176 os_memcpy(buf
, txt
, end
- txt
);
177 buf
[end
- txt
] = '\0';
178 cli_txt_list_del(txt_list
, buf
);
181 #endif /* CONFIG_P2P */
184 static int cli_txt_list_add(struct dl_list
*txt_list
, const char *txt
)
186 struct cli_txt_entry
*e
;
187 e
= cli_txt_list_get(txt_list
, txt
);
190 e
= os_zalloc(sizeof(*e
));
193 e
->txt
= os_strdup(txt
);
194 if (e
->txt
== NULL
) {
198 dl_list_add(txt_list
, &e
->list
);
204 static int cli_txt_list_add_addr(struct dl_list
*txt_list
, const char *txt
)
208 if (hwaddr_aton(txt
, addr
) < 0)
210 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
211 return cli_txt_list_add(txt_list
, buf
);
215 static int cli_txt_list_add_word(struct dl_list
*txt_list
, const char *txt
)
220 end
= os_strchr(txt
, ' ');
222 end
= txt
+ os_strlen(txt
);
223 buf
= os_malloc(end
- txt
+ 1);
226 os_memcpy(buf
, txt
, end
- txt
);
227 buf
[end
- txt
] = '\0';
228 ret
= cli_txt_list_add(txt_list
, buf
);
232 #endif /* CONFIG_P2P */
235 static char ** cli_txt_list_array(struct dl_list
*txt_list
)
237 unsigned int i
, count
= dl_list_len(txt_list
);
239 struct cli_txt_entry
*e
;
241 res
= os_zalloc((count
+ 1) * sizeof(char *));
246 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
247 res
[i
] = os_strdup(e
->txt
);
257 static int get_cmd_arg_num(const char *str
, int pos
)
261 for (i
= 0; i
<= pos
; i
++) {
264 while (i
<= pos
&& str
[i
] != ' ')
275 static int str_starts(const char *src
, const char *match
)
277 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
281 static int wpa_cli_show_event(const char *event
)
285 start
= os_strchr(event
, '>');
291 * Skip BSS added/removed events since they can be relatively frequent
292 * and are likely of not much use for an interactive user.
294 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
295 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
302 static int wpa_cli_open_connection(const char *ifname
, int attach
)
304 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
305 ctrl_conn
= wpa_ctrl_open(ifname
);
306 if (ctrl_conn
== NULL
)
309 if (attach
&& interactive
)
310 mon_conn
= wpa_ctrl_open(ifname
);
313 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
321 if (access(ctrl_iface_dir
, F_OK
) < 0) {
322 cfile
= os_strdup(ifname
);
329 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
330 cfile
= os_malloc(flen
);
333 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
,
335 if (res
< 0 || res
>= flen
) {
341 ctrl_conn
= wpa_ctrl_open(cfile
);
342 if (ctrl_conn
== NULL
) {
347 if (attach
&& interactive
)
348 mon_conn
= wpa_ctrl_open(cfile
);
352 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
355 if (wpa_ctrl_attach(mon_conn
) == 0) {
356 wpa_cli_attached
= 1;
358 eloop_register_read_sock(
359 wpa_ctrl_get_fd(mon_conn
),
360 wpa_cli_mon_receive
, NULL
, NULL
);
362 printf("Warning: Failed to attach to "
363 "wpa_supplicant.\n");
372 static void wpa_cli_close_connection(void)
374 if (ctrl_conn
== NULL
)
377 if (wpa_cli_attached
) {
378 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
379 wpa_cli_attached
= 0;
381 wpa_ctrl_close(ctrl_conn
);
384 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
385 wpa_ctrl_close(mon_conn
);
391 static void wpa_cli_msg_cb(char *msg
, size_t len
)
397 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
403 if (ctrl_conn
== NULL
) {
404 printf("Not connected to wpa_supplicant - command dropped.\n");
407 len
= sizeof(buf
) - 1;
408 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
411 printf("'%s' command timed out.\n", cmd
);
413 } else if (ret
< 0) {
414 printf("'%s' command failed.\n", cmd
);
420 if (interactive
&& len
> 0 && buf
[len
- 1] != '\n')
427 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
429 return _wpa_ctrl_command(ctrl
, cmd
, 1);
433 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
435 if (argc
> 0 && os_strcmp(argv
[0], "verbose") == 0)
436 return wpa_ctrl_command(ctrl
, "STATUS-VERBOSE");
437 if (argc
> 0 && os_strcmp(argv
[0], "wps") == 0)
438 return wpa_ctrl_command(ctrl
, "STATUS-WPS");
439 return wpa_ctrl_command(ctrl
, "STATUS");
443 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
445 return wpa_ctrl_command(ctrl
, "PING");
449 static int wpa_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
451 return wpa_ctrl_command(ctrl
, "RELOG");
455 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
461 ret
= os_snprintf(cmd
, sizeof(cmd
), "NOTE %s", argv
[0]);
462 if (ret
< 0 || (size_t) ret
>= sizeof(cmd
))
464 return wpa_ctrl_command(ctrl
, cmd
);
468 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
470 return wpa_ctrl_command(ctrl
, "MIB");
474 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
476 return wpa_ctrl_command(ctrl
, "PMKSA");
480 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
487 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
489 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
494 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
503 static void wpa_cli_show_variables(void)
505 printf("set variables:\n"
506 " EAPOL::heldPeriod (EAPOL state machine held period, "
508 " EAPOL::authPeriod (EAPOL state machine authentication "
509 "period, in seconds)\n"
510 " EAPOL::startPeriod (EAPOL state machine start period, in "
512 " EAPOL::maxStart (EAPOL state machine maximum start "
514 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
516 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
517 " threshold\n\tpercentage)\n"
518 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
519 "security\n\tassociation in seconds)\n");
523 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
529 wpa_cli_show_variables();
533 if (argc
!= 1 && argc
!= 2) {
534 printf("Invalid SET command: needs two arguments (variable "
535 "name and value)\n");
540 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s ", argv
[0]);
542 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s",
544 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
545 printf("Too long SET command.\n");
548 return wpa_ctrl_command(ctrl
, cmd
);
552 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
558 printf("Invalid GET command: need one argument (variable "
563 res
= os_snprintf(cmd
, sizeof(cmd
), "GET %s", argv
[0]);
564 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
565 printf("Too long GET command.\n");
568 return wpa_ctrl_command(ctrl
, cmd
);
572 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
574 return wpa_ctrl_command(ctrl
, "LOGOFF");
578 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
580 return wpa_ctrl_command(ctrl
, "LOGON");
584 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
587 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
591 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
598 printf("Invalid PREAUTH command: needs one argument "
603 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
604 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
605 printf("Too long PREAUTH command.\n");
608 return wpa_ctrl_command(ctrl
, cmd
);
612 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
618 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
622 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
623 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
624 printf("Too long AP_SCAN command.\n");
627 return wpa_ctrl_command(ctrl
, cmd
);
631 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl
*ctrl
, int argc
,
638 printf("Invalid SCAN_INTERVAL command: needs one argument "
639 "scan_interval value)\n");
642 res
= os_snprintf(cmd
, sizeof(cmd
), "SCAN_INTERVAL %s", argv
[0]);
643 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
644 printf("Too long SCAN_INTERVAL command.\n");
647 return wpa_ctrl_command(ctrl
, cmd
);
651 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl
*ctrl
, int argc
,
658 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
659 "(bss_expire_age value)\n");
662 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_EXPIRE_AGE %s", argv
[0]);
663 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
664 printf("Too long BSS_EXPIRE_AGE command.\n");
667 return wpa_ctrl_command(ctrl
, cmd
);
671 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl
*ctrl
, int argc
,
678 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
679 "(bss_expire_count value)\n");
682 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_EXPIRE_COUNT %s", argv
[0]);
683 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
684 printf("Too long BSS_EXPIRE_COUNT command.\n");
687 return wpa_ctrl_command(ctrl
, cmd
);
691 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
698 printf("Invalid STKSTART command: needs one argument "
699 "(Peer STA MAC address)\n");
703 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
704 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
705 printf("Too long STKSTART command.\n");
708 return wpa_ctrl_command(ctrl
, cmd
);
712 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
718 printf("Invalid FT_DS command: needs one argument "
719 "(Target AP MAC address)\n");
723 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
724 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
725 printf("Too long FT_DS command.\n");
728 return wpa_ctrl_command(ctrl
, cmd
);
732 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
739 return wpa_ctrl_command(ctrl
, "WPS_PBC");
743 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
744 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
745 printf("Too long WPS_PBC command.\n");
748 return wpa_ctrl_command(ctrl
, cmd
);
752 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
758 printf("Invalid WPS_PIN command: need one or two arguments:\n"
759 "- BSSID: use 'any' to select any\n"
760 "- PIN: optional, used only with devices that have no "
766 /* Use dynamically generated PIN (returned as reply) */
767 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
768 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
769 printf("Too long WPS_PIN command.\n");
772 return wpa_ctrl_command(ctrl
, cmd
);
775 /* Use hardcoded PIN from a label */
776 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
777 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
778 printf("Too long WPS_PIN command.\n");
781 return wpa_ctrl_command(ctrl
, cmd
);
785 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
791 if (argc
!= 1 && argc
!= 2) {
792 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
793 "- PIN to be verified\n");
798 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
801 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
803 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
804 printf("Too long WPS_CHECK_PIN command.\n");
807 return wpa_ctrl_command(ctrl
, cmd
);
811 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
814 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
818 #ifdef CONFIG_WPS_OOB
819 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
824 if (argc
!= 3 && argc
!= 4) {
825 printf("Invalid WPS_OOB command: need three or four "
827 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
828 "- PATH: path of OOB device like '/mnt'\n"
829 "- METHOD: OOB method 'pin-e' or 'pin-r', "
831 "- DEV_NAME: (only for NFC) device name like "
837 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
838 argv
[0], argv
[1], argv
[2]);
840 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
841 argv
[0], argv
[1], argv
[2], argv
[3]);
842 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
843 printf("Too long WPS_OOB command.\n");
846 return wpa_ctrl_command(ctrl
, cmd
);
850 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
856 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_NFC %s",
859 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_NFC");
860 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
861 printf("Too long WPS_NFC command.\n");
864 return wpa_ctrl_command(ctrl
, cmd
);
868 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl
*ctrl
, int argc
,
875 printf("Invalid WPS_NFC_TOKEN command: need one argument:\n"
876 "format: WPS or NDEF\n");
880 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_NFC_TOKEN %s",
883 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_NFC_TOKEN");
884 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
885 printf("Too long WPS_NFC_TOKEN command.\n");
888 return wpa_ctrl_command(ctrl
, cmd
);
890 #endif /* CONFIG_WPS_OOB */
893 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
899 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
901 else if (argc
== 5 || argc
== 6) {
902 char ssid_hex
[2 * 32 + 1];
903 char key_hex
[2 * 64 + 1];
907 for (i
= 0; i
< 32; i
++) {
908 if (argv
[2][i
] == '\0')
910 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
915 for (i
= 0; i
< 64; i
++) {
916 if (argv
[5][i
] == '\0')
918 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
923 res
= os_snprintf(cmd
, sizeof(cmd
),
924 "WPS_REG %s %s %s %s %s %s",
925 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
928 printf("Invalid WPS_REG command: need two arguments:\n"
929 "- BSSID of the target AP\n"
931 printf("Alternatively, six arguments can be used to "
932 "reconfigure the AP:\n"
933 "- BSSID of the target AP\n"
936 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
937 "- new encr (NONE, WEP, TKIP, CCMP)\n"
942 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
943 printf("Too long WPS_REG command.\n");
946 return wpa_ctrl_command(ctrl
, cmd
);
950 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
957 printf("Invalid WPS_AP_PIN command: needs at least one "
963 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s %s",
964 argv
[0], argv
[1], argv
[2]);
966 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s",
969 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s",
971 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
972 printf("Too long WPS_AP_PIN command.\n");
975 return wpa_ctrl_command(ctrl
, cmd
);
979 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
984 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
985 return wpa_ctrl_command(ctrl
, cmd
);
987 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
991 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
994 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
999 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
1006 printf("Invalid WPS_ER_PIN command: need at least two "
1008 "- UUID: use 'any' to select any\n"
1009 "- PIN: Enrollee PIN\n"
1010 "optional: - Enrollee MAC address\n");
1015 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
1016 argv
[0], argv
[1], argv
[2]);
1018 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
1020 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1021 printf("Too long WPS_ER_PIN command.\n");
1024 return wpa_ctrl_command(ctrl
, cmd
);
1028 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
1035 printf("Invalid WPS_ER_PBC command: need one argument:\n"
1036 "- UUID: Specify the Enrollee\n");
1040 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
1042 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1043 printf("Too long WPS_ER_PBC command.\n");
1046 return wpa_ctrl_command(ctrl
, cmd
);
1050 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
1057 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1058 "- UUID: specify which AP to use\n"
1063 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
1065 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1066 printf("Too long WPS_ER_LEARN command.\n");
1069 return wpa_ctrl_command(ctrl
, cmd
);
1073 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
1080 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1082 "- UUID: specify which AP to use\n"
1083 "- Network configuration id\n");
1087 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_SET_CONFIG %s %s",
1089 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1090 printf("Too long WPS_ER_SET_CONFIG command.\n");
1093 return wpa_ctrl_command(ctrl
, cmd
);
1097 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
1103 if (argc
== 5 || argc
== 6) {
1104 char ssid_hex
[2 * 32 + 1];
1105 char key_hex
[2 * 64 + 1];
1109 for (i
= 0; i
< 32; i
++) {
1110 if (argv
[2][i
] == '\0')
1112 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
1117 for (i
= 0; i
< 64; i
++) {
1118 if (argv
[5][i
] == '\0')
1120 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
1125 res
= os_snprintf(cmd
, sizeof(cmd
),
1126 "WPS_ER_CONFIG %s %s %s %s %s %s",
1127 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
1130 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1134 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1135 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1140 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1141 printf("Too long WPS_ER_CONFIG command.\n");
1144 return wpa_ctrl_command(ctrl
, cmd
);
1148 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1154 printf("Invalid IBSS_RSN command: needs one argument "
1155 "(Peer STA MAC address)\n");
1159 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
1160 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1161 printf("Too long IBSS_RSN command.\n");
1164 return wpa_ctrl_command(ctrl
, cmd
);
1168 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1174 printf("Invalid LEVEL command: needs one argument (debug "
1178 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
1179 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1180 printf("Too long LEVEL command.\n");
1183 return wpa_ctrl_command(ctrl
, cmd
);
1187 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1189 char cmd
[256], *pos
, *end
;
1193 printf("Invalid IDENTITY command: needs two arguments "
1194 "(network id and identity)\n");
1198 end
= cmd
+ sizeof(cmd
);
1200 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
1202 if (ret
< 0 || ret
>= end
- pos
) {
1203 printf("Too long IDENTITY command.\n");
1207 for (i
= 2; i
< argc
; i
++) {
1208 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1209 if (ret
< 0 || ret
>= end
- pos
) {
1210 printf("Too long IDENTITY command.\n");
1216 return wpa_ctrl_command(ctrl
, cmd
);
1220 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1222 char cmd
[256], *pos
, *end
;
1226 printf("Invalid PASSWORD command: needs two arguments "
1227 "(network id and password)\n");
1231 end
= cmd
+ sizeof(cmd
);
1233 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1235 if (ret
< 0 || ret
>= end
- pos
) {
1236 printf("Too long PASSWORD command.\n");
1240 for (i
= 2; i
< argc
; i
++) {
1241 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1242 if (ret
< 0 || ret
>= end
- pos
) {
1243 printf("Too long PASSWORD command.\n");
1249 return wpa_ctrl_command(ctrl
, cmd
);
1253 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1256 char cmd
[256], *pos
, *end
;
1260 printf("Invalid NEW_PASSWORD command: needs two arguments "
1261 "(network id and password)\n");
1265 end
= cmd
+ sizeof(cmd
);
1267 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1269 if (ret
< 0 || ret
>= end
- pos
) {
1270 printf("Too long NEW_PASSWORD command.\n");
1274 for (i
= 2; i
< argc
; i
++) {
1275 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1276 if (ret
< 0 || ret
>= end
- pos
) {
1277 printf("Too long NEW_PASSWORD command.\n");
1283 return wpa_ctrl_command(ctrl
, cmd
);
1287 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1289 char cmd
[256], *pos
, *end
;
1293 printf("Invalid PIN command: needs two arguments "
1294 "(network id and pin)\n");
1298 end
= cmd
+ sizeof(cmd
);
1300 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1302 if (ret
< 0 || ret
>= end
- pos
) {
1303 printf("Too long PIN command.\n");
1307 for (i
= 2; i
< argc
; i
++) {
1308 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1309 if (ret
< 0 || ret
>= end
- pos
) {
1310 printf("Too long PIN command.\n");
1315 return wpa_ctrl_command(ctrl
, cmd
);
1319 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1321 char cmd
[256], *pos
, *end
;
1325 printf("Invalid OTP command: needs two arguments (network "
1326 "id and password)\n");
1330 end
= cmd
+ sizeof(cmd
);
1332 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1334 if (ret
< 0 || ret
>= end
- pos
) {
1335 printf("Too long OTP command.\n");
1339 for (i
= 2; i
< argc
; i
++) {
1340 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1341 if (ret
< 0 || ret
>= end
- pos
) {
1342 printf("Too long OTP command.\n");
1348 return wpa_ctrl_command(ctrl
, cmd
);
1352 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1355 char cmd
[256], *pos
, *end
;
1359 printf("Invalid PASSPHRASE command: needs two arguments "
1360 "(network id and passphrase)\n");
1364 end
= cmd
+ sizeof(cmd
);
1366 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1368 if (ret
< 0 || ret
>= end
- pos
) {
1369 printf("Too long PASSPHRASE command.\n");
1373 for (i
= 2; i
< argc
; i
++) {
1374 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1375 if (ret
< 0 || ret
>= end
- pos
) {
1376 printf("Too long PASSPHRASE command.\n");
1382 return wpa_ctrl_command(ctrl
, cmd
);
1386 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1388 char cmd
[256], *pos
, *end
;
1392 printf("Invalid BSSID command: needs two arguments (network "
1397 end
= cmd
+ sizeof(cmd
);
1399 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1400 if (ret
< 0 || ret
>= end
- pos
) {
1401 printf("Too long BSSID command.\n");
1405 for (i
= 0; i
< argc
; i
++) {
1406 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1407 if (ret
< 0 || ret
>= end
- pos
) {
1408 printf("Too long BSSID command.\n");
1414 return wpa_ctrl_command(ctrl
, cmd
);
1418 static int wpa_cli_cmd_blacklist(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1420 char cmd
[256], *pos
, *end
;
1423 end
= cmd
+ sizeof(cmd
);
1425 ret
= os_snprintf(pos
, end
- pos
, "BLACKLIST");
1426 if (ret
< 0 || ret
>= end
- pos
) {
1427 printf("Too long BLACKLIST command.\n");
1431 for (i
= 0; i
< argc
; i
++) {
1432 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1433 if (ret
< 0 || ret
>= end
- pos
) {
1434 printf("Too long BLACKLIST command.\n");
1440 return wpa_ctrl_command(ctrl
, cmd
);
1444 static int wpa_cli_cmd_log_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1446 char cmd
[256], *pos
, *end
;
1449 end
= cmd
+ sizeof(cmd
);
1451 ret
= os_snprintf(pos
, end
- pos
, "LOG_LEVEL");
1452 if (ret
< 0 || ret
>= end
- pos
) {
1453 printf("Too long LOG_LEVEL command.\n");
1457 for (i
= 0; i
< argc
; i
++) {
1458 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1459 if (ret
< 0 || ret
>= end
- pos
) {
1460 printf("Too long LOG_LEVEL command.\n");
1466 return wpa_ctrl_command(ctrl
, cmd
);
1470 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1473 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1477 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1484 printf("Invalid SELECT_NETWORK command: needs one argument "
1489 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1490 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1492 cmd
[sizeof(cmd
) - 1] = '\0';
1494 return wpa_ctrl_command(ctrl
, cmd
);
1498 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1505 printf("Invalid ENABLE_NETWORK command: needs one argument "
1511 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s %s",
1514 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s",
1516 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1518 cmd
[sizeof(cmd
) - 1] = '\0';
1520 return wpa_ctrl_command(ctrl
, cmd
);
1524 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1531 printf("Invalid DISABLE_NETWORK command: needs one argument "
1536 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_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 int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1548 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1552 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1559 printf("Invalid REMOVE_NETWORK command: needs one argument "
1564 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1565 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1567 cmd
[sizeof(cmd
) - 1] = '\0';
1569 return wpa_ctrl_command(ctrl
, cmd
);
1573 static void wpa_cli_show_network_variables(void)
1575 printf("set_network variables:\n"
1576 " ssid (network name, SSID)\n"
1577 " psk (WPA passphrase or pre-shared key)\n"
1578 " key_mgmt (key management protocol)\n"
1579 " identity (EAP identity)\n"
1580 " password (EAP password)\n"
1583 "Note: Values are entered in the same format as the "
1584 "configuration file is using,\n"
1585 "i.e., strings values need to be inside double quotation "
1587 "For example: set_network 1 ssid \"network name\"\n"
1589 "Please see wpa_supplicant.conf documentation for full list "
1590 "of\navailable variables.\n");
1594 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1601 wpa_cli_show_network_variables();
1606 printf("Invalid SET_NETWORK command: needs three arguments\n"
1607 "(network id, variable name, and value)\n");
1611 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1612 argv
[0], argv
[1], argv
[2]);
1613 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1614 printf("Too long SET_NETWORK command.\n");
1617 return wpa_ctrl_command(ctrl
, cmd
);
1621 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1628 wpa_cli_show_network_variables();
1633 printf("Invalid GET_NETWORK command: needs two arguments\n"
1634 "(network id and variable name)\n");
1638 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1640 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1641 printf("Too long GET_NETWORK command.\n");
1644 return wpa_ctrl_command(ctrl
, cmd
);
1648 static int wpa_cli_cmd_list_creds(struct wpa_ctrl
*ctrl
, int argc
,
1651 return wpa_ctrl_command(ctrl
, "LIST_CREDS");
1655 static int wpa_cli_cmd_add_cred(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1657 return wpa_ctrl_command(ctrl
, "ADD_CRED");
1661 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl
*ctrl
, int argc
,
1668 printf("Invalid REMOVE_CRED command: needs one argument "
1673 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_CRED %s", argv
[0]);
1674 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1676 cmd
[sizeof(cmd
) - 1] = '\0';
1678 return wpa_ctrl_command(ctrl
, cmd
);
1682 static int wpa_cli_cmd_set_cred(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1688 printf("Invalid SET_CRED command: needs three arguments\n"
1689 "(cred id, variable name, and value)\n");
1693 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_CRED %s %s %s",
1694 argv
[0], argv
[1], argv
[2]);
1695 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1696 printf("Too long SET_CRED command.\n");
1699 return wpa_ctrl_command(ctrl
, cmd
);
1703 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1706 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1710 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1713 return wpa_ctrl_command(ctrl
, "RECONNECT");
1717 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1720 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1724 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1726 return wpa_ctrl_command(ctrl
, "SCAN");
1730 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1733 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1737 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1743 printf("Invalid BSS command: need at least one argument"
1744 "(index or BSSID)\n");
1748 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s%s%s%s%s", argv
[0],
1749 argc
> 1 ? " " : "", argc
> 1 ? argv
[1] : "",
1750 argc
> 2 ? " " : "", argc
> 2 ? argv
[2] : "");
1752 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1754 cmd
[sizeof(cmd
) - 1] = '\0';
1756 return wpa_ctrl_command(ctrl
, cmd
);
1760 static char ** wpa_cli_complete_bss(const char *str
, int pos
)
1762 int arg
= get_cmd_arg_num(str
, pos
);
1767 res
= cli_txt_list_array(&bsses
);
1775 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1781 if (argc
< 1 || argc
> 2) {
1782 printf("Invalid GET_CAPABILITY command: need either one or "
1787 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1788 printf("Invalid GET_CAPABILITY command: second argument, "
1789 "if any, must be 'strict'\n");
1793 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1794 (argc
== 2) ? " strict" : "");
1795 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1797 cmd
[sizeof(cmd
) - 1] = '\0';
1799 return wpa_ctrl_command(ctrl
, cmd
);
1803 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1805 printf("Available interfaces:\n");
1806 return wpa_ctrl_command(ctrl
, "INTERFACES");
1810 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1813 wpa_cli_list_interfaces(ctrl
);
1817 wpa_cli_close_connection();
1818 os_free(ctrl_ifname
);
1819 ctrl_ifname
= os_strdup(argv
[0]);
1821 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1822 printf("Connected to interface '%s.\n", ctrl_ifname
);
1824 printf("Could not connect to interface '%s' - re-trying\n",
1831 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1834 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1838 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1841 return wpa_ctrl_command(ctrl
, "TERMINATE");
1845 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1852 printf("Invalid INTERFACE_ADD command: needs at least one "
1853 "argument (interface name)\n"
1854 "All arguments: ifname confname driver ctrl_interface "
1855 "driver_param bridge_name\n");
1860 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1861 * <driver_param>TAB<bridge_name>
1863 res
= os_snprintf(cmd
, sizeof(cmd
),
1864 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1866 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1867 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1868 argc
> 5 ? argv
[5] : "");
1869 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1871 cmd
[sizeof(cmd
) - 1] = '\0';
1872 return wpa_ctrl_command(ctrl
, cmd
);
1876 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1883 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1884 "(interface name)\n");
1888 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1889 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1891 cmd
[sizeof(cmd
) - 1] = '\0';
1892 return wpa_ctrl_command(ctrl
, cmd
);
1896 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1899 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1904 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1908 printf("Invalid 'sta' command - exactly one argument, STA "
1909 "address, is required.\n");
1912 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1913 return wpa_ctrl_command(ctrl
, buf
);
1917 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1918 char *addr
, size_t addr_len
)
1920 char buf
[4096], *pos
;
1924 if (ctrl_conn
== NULL
) {
1925 printf("Not connected to hostapd - command dropped.\n");
1928 len
= sizeof(buf
) - 1;
1929 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
1932 printf("'%s' command timed out.\n", cmd
);
1934 } else if (ret
< 0) {
1935 printf("'%s' command failed.\n", cmd
);
1940 if (os_memcmp(buf
, "FAIL", 4) == 0)
1945 while (*pos
!= '\0' && *pos
!= '\n')
1948 os_strlcpy(addr
, buf
, addr_len
);
1953 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1955 char addr
[32], cmd
[64];
1957 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1960 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1961 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1967 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
1972 printf("Invalid 'deauthenticate' command - exactly one "
1973 "argument, STA address, is required.\n");
1977 os_snprintf(buf
, sizeof(buf
), "DEAUTHENTICATE %s %s",
1980 os_snprintf(buf
, sizeof(buf
), "DEAUTHENTICATE %s", argv
[0]);
1981 return wpa_ctrl_command(ctrl
, buf
);
1985 static int wpa_cli_cmd_disassociate(struct wpa_ctrl
*ctrl
, int argc
,
1990 printf("Invalid 'disassociate' command - exactly one "
1991 "argument, STA address, is required.\n");
1995 os_snprintf(buf
, sizeof(buf
), "DISASSOCIATE %s %s",
1998 os_snprintf(buf
, sizeof(buf
), "DISASSOCIATE %s", argv
[0]);
1999 return wpa_ctrl_command(ctrl
, buf
);
2001 #endif /* CONFIG_AP */
2004 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2006 return wpa_ctrl_command(ctrl
, "SUSPEND");
2010 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2012 return wpa_ctrl_command(ctrl
, "RESUME");
2016 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2018 return wpa_ctrl_command(ctrl
, "DROP_SA");
2022 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2028 printf("Invalid ROAM command: needs one argument "
2029 "(target AP's BSSID)\n");
2033 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
2034 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2035 printf("Too long ROAM command.\n");
2038 return wpa_ctrl_command(ctrl
, cmd
);
2044 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2050 return wpa_ctrl_command(ctrl
, "P2P_FIND");
2053 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s %s",
2054 argv
[0], argv
[1], argv
[2]);
2056 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
2059 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
2060 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2062 cmd
[sizeof(cmd
) - 1] = '\0';
2063 return wpa_ctrl_command(ctrl
, cmd
);
2067 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
2070 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
2074 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
2081 printf("Invalid P2P_CONNECT command: needs at least two "
2082 "arguments (address and pbc/PIN)\n");
2087 res
= os_snprintf(cmd
, sizeof(cmd
),
2088 "P2P_CONNECT %s %s %s %s %s",
2089 argv
[0], argv
[1], argv
[2], argv
[3],
2092 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
2093 argv
[0], argv
[1], argv
[2], argv
[3]);
2095 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
2096 argv
[0], argv
[1], argv
[2]);
2098 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
2100 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2102 cmd
[sizeof(cmd
) - 1] = '\0';
2103 return wpa_ctrl_command(ctrl
, cmd
);
2107 static char ** wpa_cli_complete_p2p_connect(const char *str
, int pos
)
2109 int arg
= get_cmd_arg_num(str
, pos
);
2114 res
= cli_txt_list_array(&p2p_peers
);
2122 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
2129 return wpa_ctrl_command(ctrl
, "P2P_LISTEN");
2131 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_LISTEN %s", argv
[0]);
2132 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2134 cmd
[sizeof(cmd
) - 1] = '\0';
2135 return wpa_ctrl_command(ctrl
, cmd
);
2139 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
2146 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2147 "(interface name)\n");
2151 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
2152 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2154 cmd
[sizeof(cmd
) - 1] = '\0';
2155 return wpa_ctrl_command(ctrl
, cmd
);
2159 static char ** wpa_cli_complete_p2p_group_remove(const char *str
, int pos
)
2161 int arg
= get_cmd_arg_num(str
, pos
);
2166 res
= cli_txt_list_array(&p2p_groups
);
2174 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
2181 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
2184 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s %s",
2187 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s",
2189 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2191 cmd
[sizeof(cmd
) - 1] = '\0';
2192 return wpa_ctrl_command(ctrl
, cmd
);
2196 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
2202 if (argc
!= 2 && argc
!= 3) {
2203 printf("Invalid P2P_PROV_DISC command: needs at least "
2204 "two arguments, address and config method\n"
2205 "(display, keypad, or pbc) and an optional join\n");
2210 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s %s",
2211 argv
[0], argv
[1], argv
[2]);
2213 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
2215 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2217 cmd
[sizeof(cmd
) - 1] = '\0';
2218 return wpa_ctrl_command(ctrl
, cmd
);
2222 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
2225 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
2229 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
2235 if (argc
!= 2 && argc
!= 4) {
2236 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2237 "arguments (address and TLVs) or four arguments "
2238 "(address, \"upnp\", version, search target "
2244 res
= os_snprintf(cmd
, sizeof(cmd
),
2245 "P2P_SERV_DISC_REQ %s %s %s %s",
2246 argv
[0], argv
[1], argv
[2], argv
[3]);
2248 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
2250 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2252 cmd
[sizeof(cmd
) - 1] = '\0';
2253 return wpa_ctrl_command(ctrl
, cmd
);
2257 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
2258 int argc
, char *argv
[])
2264 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2265 "argument (pending request identifier)\n");
2269 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
2271 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2273 cmd
[sizeof(cmd
) - 1] = '\0';
2274 return wpa_ctrl_command(ctrl
, cmd
);
2278 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
2285 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2286 "arguments (freq, address, dialog token, and TLVs)\n");
2290 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
2291 argv
[0], argv
[1], argv
[2], argv
[3]);
2292 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2294 cmd
[sizeof(cmd
) - 1] = '\0';
2295 return wpa_ctrl_command(ctrl
, cmd
);
2299 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
2302 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
2306 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
2307 int argc
, char *argv
[])
2313 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2314 "argument (external processing: 0/1)\n");
2318 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
2320 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2322 cmd
[sizeof(cmd
) - 1] = '\0';
2323 return wpa_ctrl_command(ctrl
, cmd
);
2327 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
2330 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
2334 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
2340 if (argc
!= 3 && argc
!= 4) {
2341 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2347 res
= os_snprintf(cmd
, sizeof(cmd
),
2348 "P2P_SERVICE_ADD %s %s %s %s",
2349 argv
[0], argv
[1], argv
[2], argv
[3]);
2351 res
= os_snprintf(cmd
, sizeof(cmd
),
2352 "P2P_SERVICE_ADD %s %s %s",
2353 argv
[0], argv
[1], argv
[2]);
2354 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2356 cmd
[sizeof(cmd
) - 1] = '\0';
2357 return wpa_ctrl_command(ctrl
, cmd
);
2361 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
2367 if (argc
!= 2 && argc
!= 3) {
2368 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2374 res
= os_snprintf(cmd
, sizeof(cmd
),
2375 "P2P_SERVICE_DEL %s %s %s",
2376 argv
[0], argv
[1], argv
[2]);
2378 res
= os_snprintf(cmd
, sizeof(cmd
),
2379 "P2P_SERVICE_DEL %s %s",
2381 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2383 cmd
[sizeof(cmd
) - 1] = '\0';
2384 return wpa_ctrl_command(ctrl
, cmd
);
2388 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
2389 int argc
, char *argv
[])
2395 printf("Invalid P2P_REJECT command: needs one argument "
2396 "(peer address)\n");
2400 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
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_invite(struct wpa_ctrl
*ctrl
,
2409 int argc
, char *argv
[])
2415 printf("Invalid P2P_INVITE command: needs at least one "
2421 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
2422 argv
[0], argv
[1], argv
[2]);
2424 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
2427 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
2428 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2430 cmd
[sizeof(cmd
) - 1] = '\0';
2431 return wpa_ctrl_command(ctrl
, cmd
);
2435 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2439 printf("Invalid 'p2p_peer' command - exactly one argument, "
2440 "P2P peer device address, is required.\n");
2443 os_snprintf(buf
, sizeof(buf
), "P2P_PEER %s", argv
[0]);
2444 return wpa_ctrl_command(ctrl
, buf
);
2448 static char ** wpa_cli_complete_p2p_peer(const char *str
, int pos
)
2450 int arg
= get_cmd_arg_num(str
, pos
);
2455 res
= cli_txt_list_array(&p2p_peers
);
2463 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
2464 char *addr
, size_t addr_len
,
2467 char buf
[4096], *pos
;
2471 if (ctrl_conn
== NULL
)
2473 len
= sizeof(buf
) - 1;
2474 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
2477 printf("'%s' command timed out.\n", cmd
);
2479 } else if (ret
< 0) {
2480 printf("'%s' command failed.\n", cmd
);
2485 if (os_memcmp(buf
, "FAIL", 4) == 0)
2489 while (*pos
!= '\0' && *pos
!= '\n')
2492 os_strlcpy(addr
, buf
, addr_len
);
2493 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2494 printf("%s\n", addr
);
2499 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2501 char addr
[32], cmd
[64];
2504 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2506 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2507 addr
, sizeof(addr
), discovered
))
2510 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2511 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2518 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2524 printf("Invalid P2P_SET command: needs two arguments (field, "
2529 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
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_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2539 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2543 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2546 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2550 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
2557 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2558 "(peer address)\n");
2562 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_UNAUTHORIZE %s", argv
[0]);
2564 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2567 cmd
[sizeof(cmd
) - 1] = '\0';
2568 return wpa_ctrl_command(ctrl
, cmd
);
2572 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2578 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2579 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2580 "(preferred duration, interval; in microsecods).\n"
2581 "Optional second pair can be used to provide "
2582 "acceptable values.\n");
2587 res
= os_snprintf(cmd
, sizeof(cmd
),
2588 "P2P_PRESENCE_REQ %s %s %s %s",
2589 argv
[0], argv
[1], argv
[2], argv
[3]);
2591 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2594 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
2595 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2597 cmd
[sizeof(cmd
) - 1] = '\0';
2598 return wpa_ctrl_command(ctrl
, cmd
);
2602 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2608 if (argc
!= 0 && argc
!= 2) {
2609 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2610 "(availability period, availability interval; in "
2612 "Extended Listen Timing can be cancelled with this "
2613 "command when used without parameters.\n");
2618 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2621 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2622 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2624 cmd
[sizeof(cmd
) - 1] = '\0';
2625 return wpa_ctrl_command(ctrl
, cmd
);
2628 #endif /* CONFIG_P2P */
2631 #ifdef CONFIG_INTERWORKING
2632 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2635 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
2639 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2642 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
2646 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl
*ctrl
, int argc
,
2653 return wpa_ctrl_command(ctrl
, "INTERWORKING_SELECT");
2655 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERWORKING_SELECT %s", argv
[0]);
2656 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2658 cmd
[sizeof(cmd
) - 1] = '\0';
2659 return wpa_ctrl_command(ctrl
, cmd
);
2663 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl
*ctrl
, int argc
,
2670 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2671 "argument (BSSID)\n");
2675 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERWORKING_CONNECT %s",
2677 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2679 cmd
[sizeof(cmd
) - 1] = '\0';
2680 return wpa_ctrl_command(ctrl
, cmd
);
2684 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2690 printf("Invalid ANQP_GET command: needs two arguments "
2691 "(addr and info id list)\n");
2695 res
= os_snprintf(cmd
, sizeof(cmd
), "ANQP_GET %s %s",
2697 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2699 cmd
[sizeof(cmd
) - 1] = '\0';
2700 return wpa_ctrl_command(ctrl
, cmd
);
2702 #endif /* CONFIG_INTERWORKING */
2707 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl
*ctrl
, int argc
,
2714 printf("Invalid HS20_ANQP_GET command: needs two arguments "
2715 "(addr and subtype list)\n");
2719 res
= os_snprintf(cmd
, sizeof(cmd
), "HS20_ANQP_GET %s %s",
2721 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2723 cmd
[sizeof(cmd
) - 1] = '\0';
2724 return wpa_ctrl_command(ctrl
, cmd
);
2728 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl
*ctrl
, int argc
,
2735 printf("Command needs one or two arguments (dst mac addr and "
2736 "optional home realm)\n");
2741 res
= os_snprintf(cmd
, sizeof(cmd
),
2742 "HS20_GET_NAI_HOME_REALM_LIST %s",
2745 res
= os_snprintf(cmd
, sizeof(cmd
),
2746 "HS20_GET_NAI_HOME_REALM_LIST %s %s",
2748 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2749 printf("Too long command.\n");
2753 return wpa_ctrl_command(ctrl
, cmd
);
2756 #endif /* CONFIG_HS20 */
2759 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2766 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2767 "(0/1 = disable/enable automatic reconnection)\n");
2770 res
= os_snprintf(cmd
, sizeof(cmd
), "STA_AUTOCONNECT %s", argv
[0]);
2771 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2772 printf("Too long STA_AUTOCONNECT command.\n");
2775 return wpa_ctrl_command(ctrl
, cmd
);
2779 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2786 printf("Invalid TDLS_DISCOVER command: needs one argument "
2787 "(Peer STA MAC address)\n");
2791 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_DISCOVER %s", argv
[0]);
2792 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2793 printf("Too long TDLS_DISCOVER command.\n");
2796 return wpa_ctrl_command(ctrl
, cmd
);
2800 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2807 printf("Invalid TDLS_SETUP command: needs one argument "
2808 "(Peer STA MAC address)\n");
2812 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_SETUP %s", argv
[0]);
2813 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2814 printf("Too long TDLS_SETUP command.\n");
2817 return wpa_ctrl_command(ctrl
, cmd
);
2821 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2828 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2829 "(Peer STA MAC address)\n");
2833 res
= os_snprintf(cmd
, sizeof(cmd
), "TDLS_TEARDOWN %s", argv
[0]);
2834 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2835 printf("Too long TDLS_TEARDOWN command.\n");
2838 return wpa_ctrl_command(ctrl
, cmd
);
2842 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2845 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2849 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
2852 return wpa_ctrl_command(ctrl
, "REAUTHENTICATE");
2856 #ifdef CONFIG_AUTOSCAN
2858 static int wpa_cli_cmd_autoscan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2864 return wpa_ctrl_command(ctrl
, "AUTOSCAN ");
2866 res
= os_snprintf(cmd
, sizeof(cmd
), "AUTOSCAN %s", argv
[0]);
2867 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2868 printf("Too long AUTOSCAN command.\n");
2872 return wpa_ctrl_command(ctrl
, cmd
);
2875 #endif /* CONFIG_AUTOSCAN */
2878 enum wpa_cli_cmd_flags
{
2879 cli_cmd_flag_none
= 0x00,
2880 cli_cmd_flag_sensitive
= 0x01
2883 struct wpa_cli_cmd
{
2885 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2886 enum wpa_cli_cmd_flags flags
;
2890 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2891 { "status", wpa_cli_cmd_status
,
2893 "[verbose] = get current WPA/EAPOL/EAP status" },
2894 { "ping", wpa_cli_cmd_ping
,
2896 "= pings wpa_supplicant" },
2897 { "relog", wpa_cli_cmd_relog
,
2899 "= re-open log-file (allow rolling logs)" },
2900 { "note", wpa_cli_cmd_note
,
2902 "<text> = add a note to wpa_supplicant debug log" },
2903 { "mib", wpa_cli_cmd_mib
,
2905 "= get MIB variables (dot1x, dot11)" },
2906 { "help", wpa_cli_cmd_help
,
2908 "= show this usage help" },
2909 { "interface", wpa_cli_cmd_interface
,
2911 "[ifname] = show interfaces/select interface" },
2912 { "level", wpa_cli_cmd_level
,
2914 "<debug level> = change debug level" },
2915 { "license", wpa_cli_cmd_license
,
2917 "= show full wpa_cli license" },
2918 { "quit", wpa_cli_cmd_quit
,
2921 { "set", wpa_cli_cmd_set
,
2923 "= set variables (shows list of variables when run without "
2925 { "get", wpa_cli_cmd_get
,
2927 "<name> = get information" },
2928 { "logon", wpa_cli_cmd_logon
,
2930 "= IEEE 802.1X EAPOL state machine logon" },
2931 { "logoff", wpa_cli_cmd_logoff
,
2933 "= IEEE 802.1X EAPOL state machine logoff" },
2934 { "pmksa", wpa_cli_cmd_pmksa
,
2936 "= show PMKSA cache" },
2937 { "reassociate", wpa_cli_cmd_reassociate
,
2939 "= force reassociation" },
2940 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2942 "<BSSID> = force preauthentication" },
2943 { "identity", wpa_cli_cmd_identity
,
2945 "<network id> <identity> = configure identity for an SSID" },
2946 { "password", wpa_cli_cmd_password
,
2947 cli_cmd_flag_sensitive
,
2948 "<network id> <password> = configure password for an SSID" },
2949 { "new_password", wpa_cli_cmd_new_password
,
2950 cli_cmd_flag_sensitive
,
2951 "<network id> <password> = change password for an SSID" },
2952 { "pin", wpa_cli_cmd_pin
,
2953 cli_cmd_flag_sensitive
,
2954 "<network id> <pin> = configure pin for an SSID" },
2955 { "otp", wpa_cli_cmd_otp
,
2956 cli_cmd_flag_sensitive
,
2957 "<network id> <password> = configure one-time-password for an SSID"
2959 { "passphrase", wpa_cli_cmd_passphrase
,
2960 cli_cmd_flag_sensitive
,
2961 "<network id> <passphrase> = configure private key passphrase\n"
2963 { "bssid", wpa_cli_cmd_bssid
,
2965 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2966 { "blacklist", wpa_cli_cmd_blacklist
,
2968 "<BSSID> = add a BSSID to the blacklist\n"
2969 "blacklist clear = clear the blacklist\n"
2970 "blacklist = display the blacklist" },
2971 { "log_level", wpa_cli_cmd_log_level
,
2973 "<level> [<timestamp>] = update the log level/timestamp\n"
2974 "log_level = display the current log level and log options" },
2975 { "list_networks", wpa_cli_cmd_list_networks
,
2977 "= list configured networks" },
2978 { "select_network", wpa_cli_cmd_select_network
,
2980 "<network id> = select a network (disable others)" },
2981 { "enable_network", wpa_cli_cmd_enable_network
,
2983 "<network id> = enable a network" },
2984 { "disable_network", wpa_cli_cmd_disable_network
,
2986 "<network id> = disable a network" },
2987 { "add_network", wpa_cli_cmd_add_network
,
2989 "= add a network" },
2990 { "remove_network", wpa_cli_cmd_remove_network
,
2992 "<network id> = remove a network" },
2993 { "set_network", wpa_cli_cmd_set_network
,
2994 cli_cmd_flag_sensitive
,
2995 "<network id> <variable> <value> = set network variables (shows\n"
2996 " list of variables when run without arguments)" },
2997 { "get_network", wpa_cli_cmd_get_network
,
2999 "<network id> <variable> = get network variables" },
3000 { "list_creds", wpa_cli_cmd_list_creds
,
3002 "= list configured credentials" },
3003 { "add_cred", wpa_cli_cmd_add_cred
,
3005 "= add a credential" },
3006 { "remove_cred", wpa_cli_cmd_remove_cred
,
3008 "<cred id> = remove a credential" },
3009 { "set_cred", wpa_cli_cmd_set_cred
,
3010 cli_cmd_flag_sensitive
,
3011 "<cred id> <variable> <value> = set credential variables" },
3012 { "save_config", wpa_cli_cmd_save_config
,
3014 "= save the current configuration" },
3015 { "disconnect", wpa_cli_cmd_disconnect
,
3017 "= disconnect and wait for reassociate/reconnect command before\n"
3019 { "reconnect", wpa_cli_cmd_reconnect
,
3021 "= like reassociate, but only takes effect if already disconnected"
3023 { "scan", wpa_cli_cmd_scan
,
3025 "= request new BSS scan" },
3026 { "scan_results", wpa_cli_cmd_scan_results
,
3028 "= get latest scan results" },
3029 { "bss", wpa_cli_cmd_bss
,
3031 "<<idx> | <bssid>> = get detailed scan result info" },
3032 { "get_capability", wpa_cli_cmd_get_capability
,
3034 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
3035 { "reconfigure", wpa_cli_cmd_reconfigure
,
3037 "= force wpa_supplicant to re-read its configuration file" },
3038 { "terminate", wpa_cli_cmd_terminate
,
3040 "= terminate wpa_supplicant" },
3041 { "interface_add", wpa_cli_cmd_interface_add
,
3043 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
3044 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
3046 { "interface_remove", wpa_cli_cmd_interface_remove
,
3048 "<ifname> = removes the interface" },
3049 { "interface_list", wpa_cli_cmd_interface_list
,
3051 "= list available interfaces" },
3052 { "ap_scan", wpa_cli_cmd_ap_scan
,
3054 "<value> = set ap_scan parameter" },
3055 { "scan_interval", wpa_cli_cmd_scan_interval
,
3057 "<value> = set scan_interval parameter (in seconds)" },
3058 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
,
3060 "<value> = set BSS expiration age parameter" },
3061 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
,
3063 "<value> = set BSS expiration scan count parameter" },
3064 { "stkstart", wpa_cli_cmd_stkstart
,
3066 "<addr> = request STK negotiation with <addr>" },
3067 { "ft_ds", wpa_cli_cmd_ft_ds
,
3069 "<addr> = request over-the-DS FT with <addr>" },
3070 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
3072 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
3073 { "wps_pin", wpa_cli_cmd_wps_pin
,
3074 cli_cmd_flag_sensitive
,
3075 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
3077 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
3078 cli_cmd_flag_sensitive
,
3079 "<PIN> = verify PIN checksum" },
3080 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
3081 "Cancels the pending WPS operation" },
3082 #ifdef CONFIG_WPS_OOB
3083 { "wps_oob", wpa_cli_cmd_wps_oob
,
3084 cli_cmd_flag_sensitive
,
3085 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
3086 { "wps_nfc", wpa_cli_cmd_wps_nfc
,
3088 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
3089 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token
,
3091 "<WPS|NDEF> = create password token" },
3092 #endif /* CONFIG_WPS_OOB */
3093 { "wps_reg", wpa_cli_cmd_wps_reg
,
3094 cli_cmd_flag_sensitive
,
3095 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
3096 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
,
3097 cli_cmd_flag_sensitive
,
3098 "[params..] = enable/disable AP PIN" },
3099 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
3101 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
3102 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
3104 "= stop Wi-Fi Protected Setup External Registrar" },
3105 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
3106 cli_cmd_flag_sensitive
,
3107 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
3108 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
3110 "<UUID> = accept an Enrollee PBC using External Registrar" },
3111 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
3112 cli_cmd_flag_sensitive
,
3113 "<UUID> <PIN> = learn AP configuration" },
3114 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
,
3116 "<UUID> <network id> = set AP configuration for enrolling" },
3117 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
3118 cli_cmd_flag_sensitive
,
3119 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
3120 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
3122 "<addr> = request RSN authentication with <addr> in IBSS" },
3124 { "sta", wpa_cli_cmd_sta
,
3126 "<addr> = get information about an associated station (AP)" },
3127 { "all_sta", wpa_cli_cmd_all_sta
,
3129 "= get information about all associated stations (AP)" },
3130 { "deauthenticate", wpa_cli_cmd_deauthenticate
,
3132 "<addr> = deauthenticate a station" },
3133 { "disassociate", wpa_cli_cmd_disassociate
,
3135 "<addr> = disassociate a station" },
3136 #endif /* CONFIG_AP */
3137 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
3138 "= notification of suspend/hibernate" },
3139 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
3140 "= notification of resume/thaw" },
3141 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
3142 "= drop SA without deauth/disassoc (test command)" },
3143 { "roam", wpa_cli_cmd_roam
,
3145 "<addr> = roam to the specified BSS" },
3147 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
3148 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3149 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
3150 "= stop P2P Devices search" },
3151 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
3152 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
3153 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
3154 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3155 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
3156 "<ifname> = remove P2P group interface (terminate group if GO)" },
3157 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
3158 "= add a new P2P group (local end as GO)" },
3159 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
3160 "<addr> <method> = request provisioning discovery" },
3161 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
3163 "= get the passphrase for a group (GO only)" },
3164 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
3166 "<addr> <TLVs> = schedule service discovery request" },
3167 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
3169 "<id> = cancel pending service discovery request" },
3170 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
3172 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3173 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
3175 "= indicate change in local services" },
3176 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
3178 "<external> = set external processing of service discovery" },
3179 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
3181 "= remove all stored service entries" },
3182 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
3184 "<bonjour|upnp> <query|version> <response|service> = add a local "
3186 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
3188 "<bonjour|upnp> <query|version> [|service] = remove a local "
3190 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
3192 "<addr> = reject connection attempts from a specific peer" },
3193 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
3195 "<cmd> [peer=addr] = invite peer" },
3196 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
3197 "[discovered] = list known (optionally, only fully discovered) P2P "
3199 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
3200 "<address> = show information about known P2P peer" },
3201 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
3202 "<field> <value> = set a P2P parameter" },
3203 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
3204 "= flush P2P state" },
3205 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
3206 "= cancel P2P group formation" },
3207 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
, cli_cmd_flag_none
,
3208 "<address> = unauthorize a peer" },
3209 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
3210 "[<duration> <interval>] [<duration> <interval>] = request GO "
3212 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
3213 "[<period> <interval>] = set extended listen timing" },
3214 #endif /* CONFIG_P2P */
3216 #ifdef CONFIG_INTERWORKING
3217 { "fetch_anqp", wpa_cli_cmd_fetch_anqp
, cli_cmd_flag_none
,
3218 "= fetch ANQP information for all APs" },
3219 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp
, cli_cmd_flag_none
,
3220 "= stop fetch_anqp operation" },
3221 { "interworking_select", wpa_cli_cmd_interworking_select
,
3223 "[auto] = perform Interworking network selection" },
3224 { "interworking_connect", wpa_cli_cmd_interworking_connect
,
3226 "<BSSID> = connect using Interworking credentials" },
3227 { "anqp_get", wpa_cli_cmd_anqp_get
, cli_cmd_flag_none
,
3228 "<addr> <info id>[,<info id>]... = request ANQP information" },
3229 #endif /* CONFIG_INTERWORKING */
3231 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get
, cli_cmd_flag_none
,
3232 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3234 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list
,
3236 "<addr> <home realm> = get HS20 nai home realm list" },
3237 #endif /* CONFIG_HS20 */
3238 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
3239 "<0/1> = disable/enable automatic reconnection" },
3240 { "tdls_discover", wpa_cli_cmd_tdls_discover
,
3242 "<addr> = request TDLS discovery with <addr>" },
3243 { "tdls_setup", wpa_cli_cmd_tdls_setup
,
3245 "<addr> = request TDLS setup with <addr>" },
3246 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
,
3248 "<addr> = tear down TDLS with <addr>" },
3249 { "signal_poll", wpa_cli_cmd_signal_poll
,
3251 "= get signal parameters" },
3252 { "reauthenticate", wpa_cli_cmd_reauthenticate
, cli_cmd_flag_none
,
3253 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3254 #ifdef CONFIG_AUTOSCAN
3255 { "autoscan", wpa_cli_cmd_autoscan
, cli_cmd_flag_none
,
3256 "[params] = Set or unset (if none) autoscan parameters" },
3257 #endif /* CONFIG_AUTOSCAN */
3258 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
3263 * Prints command usage, lines are padded with the specified string.
3265 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
3270 printf("%s%s ", pad
, cmd
->cmd
);
3271 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
3280 static void print_help(void)
3283 printf("commands:\n");
3284 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
3285 print_cmd_help(&wpa_cli_commands
[n
], " ");
3289 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
3291 const char *c
, *delim
;
3295 delim
= os_strchr(cmd
, ' ');
3299 len
= os_strlen(cmd
);
3301 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
3302 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
3303 return (wpa_cli_commands
[n
].flags
&
3304 cli_cmd_flag_sensitive
);
3310 static char ** wpa_list_cmd_list(void)
3315 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
3316 res
= os_zalloc(count
* sizeof(char *));
3320 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
3321 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
3330 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
3335 if (os_strcasecmp(cmd
, "bss") == 0)
3336 return wpa_cli_complete_bss(str
, pos
);
3338 if (os_strcasecmp(cmd
, "p2p_connect") == 0)
3339 return wpa_cli_complete_p2p_connect(str
, pos
);
3340 if (os_strcasecmp(cmd
, "p2p_peer") == 0)
3341 return wpa_cli_complete_p2p_peer(str
, pos
);
3342 if (os_strcasecmp(cmd
, "p2p_group_remove") == 0)
3343 return wpa_cli_complete_p2p_group_remove(str
, pos
);
3344 #endif /* CONFIG_P2P */
3346 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
3347 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
3349 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
3359 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
3365 end
= os_strchr(str
, ' ');
3366 if (end
== NULL
|| str
+ pos
< end
)
3367 return wpa_list_cmd_list();
3369 cmd
= os_malloc(pos
+ 1);
3372 os_memcpy(cmd
, str
, pos
);
3373 cmd
[end
- str
] = '\0';
3374 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
3380 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
3382 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
3387 cmd
= wpa_cli_commands
;
3389 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
3392 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
3393 /* we have an exact match */
3403 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
3404 cmd
= wpa_cli_commands
;
3406 if (os_strncasecmp(cmd
->cmd
, argv
[0],
3407 os_strlen(argv
[0])) == 0) {
3408 printf(" %s", cmd
->cmd
);
3414 } else if (count
== 0) {
3415 printf("Unknown command '%s'\n", argv
[0]);
3418 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
3425 static int str_match(const char *a
, const char *b
)
3427 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
3431 static int wpa_cli_exec(const char *program
, const char *arg1
,
3439 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
3440 cmd
= os_malloc(len
);
3443 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
3444 if (res
< 0 || (size_t) res
>= len
) {
3448 cmd
[len
- 1] = '\0';
3450 if (system(cmd
) < 0)
3452 #endif /* _WIN32_WCE */
3459 static void wpa_cli_action_process(const char *msg
)
3462 char *copy
= NULL
, *id
, *pos2
;
3467 pos
= os_strchr(pos
, '>');
3474 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
3476 os_unsetenv("WPA_ID");
3477 os_unsetenv("WPA_ID_STR");
3478 os_unsetenv("WPA_CTRL_DIR");
3480 pos
= os_strstr(pos
, "[id=");
3482 copy
= os_strdup(pos
+ 4);
3486 while (*pos2
&& *pos2
!= ' ')
3490 os_setenv("WPA_ID", id
, 1);
3491 while (*pos2
&& *pos2
!= '=')
3496 while (*pos2
&& *pos2
!= ']')
3499 os_setenv("WPA_ID_STR", id
, 1);
3503 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
3505 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
3506 wpa_cli_connected
= 1;
3507 wpa_cli_last_id
= new_id
;
3508 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
3510 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
3511 if (wpa_cli_connected
) {
3512 wpa_cli_connected
= 0;
3513 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
3515 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
3516 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3517 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
3518 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3519 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
3520 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3521 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
3522 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3523 } else if (str_match(pos
, P2P_EVENT_GO_NEG_FAILURE
)) {
3524 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3525 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
3526 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3527 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
3528 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3529 } else if (str_match(pos
, AP_STA_CONNECTED
)) {
3530 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3531 } else if (str_match(pos
, AP_STA_DISCONNECTED
)) {
3532 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3533 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
3534 printf("wpa_supplicant is terminating - stop monitoring\n");
3540 #ifndef CONFIG_ANSI_C_EXTRA
3541 static void wpa_cli_action_cb(char *msg
, size_t len
)
3543 wpa_cli_action_process(msg
);
3545 #endif /* CONFIG_ANSI_C_EXTRA */
3548 static void wpa_cli_reconnect(void)
3550 wpa_cli_close_connection();
3551 wpa_cli_open_connection(ctrl_ifname
, 1);
3555 static void cli_event(const char *str
)
3557 const char *start
, *s
;
3559 start
= os_strchr(str
, '>');
3565 if (str_starts(start
, WPA_EVENT_BSS_ADDED
)) {
3566 s
= os_strchr(start
, ' ');
3569 s
= os_strchr(s
+ 1, ' ');
3572 cli_txt_list_add(&bsses
, s
+ 1);
3576 if (str_starts(start
, WPA_EVENT_BSS_REMOVED
)) {
3577 s
= os_strchr(start
, ' ');
3580 s
= os_strchr(s
+ 1, ' ');
3583 cli_txt_list_del_addr(&bsses
, s
+ 1);
3588 if (str_starts(start
, P2P_EVENT_DEVICE_FOUND
)) {
3589 s
= os_strstr(start
, " p2p_dev_addr=");
3592 cli_txt_list_add_addr(&p2p_peers
, s
+ 14);
3596 if (str_starts(start
, P2P_EVENT_DEVICE_LOST
)) {
3597 s
= os_strstr(start
, " p2p_dev_addr=");
3600 cli_txt_list_del_addr(&p2p_peers
, s
+ 14);
3604 if (str_starts(start
, P2P_EVENT_GROUP_STARTED
)) {
3605 s
= os_strchr(start
, ' ');
3608 cli_txt_list_add_word(&p2p_groups
, s
+ 1);
3612 if (str_starts(start
, P2P_EVENT_GROUP_REMOVED
)) {
3613 s
= os_strchr(start
, ' ');
3616 cli_txt_list_del_word(&p2p_groups
, s
+ 1);
3619 #endif /* CONFIG_P2P */
3623 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
3625 if (ctrl_conn
== NULL
) {
3626 wpa_cli_reconnect();
3629 while (wpa_ctrl_pending(ctrl
) > 0) {
3631 size_t len
= sizeof(buf
) - 1;
3632 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
3635 wpa_cli_action_process(buf
);
3638 if (wpa_cli_show_event(buf
)) {
3640 printf("\r%s\n", buf
);
3645 printf("Could not read pending message.\n");
3650 if (wpa_ctrl_pending(ctrl
) < 0) {
3651 printf("Connection to wpa_supplicant lost - trying to "
3653 wpa_cli_reconnect();
3659 static int tokenize_cmd(char *cmd
, char *argv
[])
3672 if (argc
== max_args
)
3675 char *pos2
= os_strrchr(pos
, '"');
3679 while (*pos
!= '\0' && *pos
!= ' ')
3689 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
3691 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3692 printf("Connection to wpa_supplicant lost - trying to "
3694 wpa_cli_close_connection();
3697 wpa_cli_reconnect();
3698 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3702 static void wpa_cli_eloop_terminate(int sig
, void *signal_ctx
)
3708 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
3710 wpa_cli_recv_pending(mon_conn
, 0);
3714 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
3716 char *argv
[max_args
];
3718 argc
= tokenize_cmd(cmd
, argv
);
3720 wpa_request(ctrl_conn
, argc
, argv
);
3724 static void wpa_cli_edit_eof_cb(void *ctx
)
3730 static void wpa_cli_interactive(void)
3732 char *home
, *hfile
= NULL
;
3734 printf("\nInteractive mode\n\n");
3736 home
= getenv("HOME");
3738 const char *fname
= ".wpa_cli_history";
3739 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
3740 hfile
= os_malloc(hfile_len
);
3742 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
3745 eloop_register_signal_terminate(wpa_cli_eloop_terminate
, NULL
);
3746 edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
3747 wpa_cli_edit_completion_cb
, NULL
, hfile
);
3748 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3752 cli_txt_list_flush(&p2p_peers
);
3753 cli_txt_list_flush(&p2p_groups
);
3754 cli_txt_list_flush(&bsses
);
3755 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3757 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3758 wpa_cli_close_connection();
3762 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3764 #ifdef CONFIG_ANSI_C_EXTRA
3765 /* TODO: ANSI C version(?) */
3766 printf("Action processing not supported in ANSI C build.\n");
3767 #else /* CONFIG_ANSI_C_EXTRA */
3771 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3774 fd
= wpa_ctrl_get_fd(ctrl
);
3776 while (!wpa_cli_quit
) {
3779 tv
.tv_sec
= ping_interval
;
3781 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3782 if (res
< 0 && errno
!= EINTR
) {
3787 if (FD_ISSET(fd
, &rfds
))
3788 wpa_cli_recv_pending(ctrl
, 1);
3790 /* verify that connection is still working */
3791 len
= sizeof(buf
) - 1;
3792 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3793 wpa_cli_action_cb
) < 0 ||
3794 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3795 printf("wpa_supplicant did not reply to PING "
3796 "command - exiting\n");
3801 #endif /* CONFIG_ANSI_C_EXTRA */
3805 static void wpa_cli_cleanup(void)
3807 wpa_cli_close_connection();
3809 os_daemonize_terminate(pid_file
);
3811 os_program_deinit();
3814 static void wpa_cli_terminate(int sig
)
3821 static char * wpa_cli_get_default_ifname(void)
3823 char *ifname
= NULL
;
3825 #ifdef CONFIG_CTRL_IFACE_UNIX
3826 struct dirent
*dent
;
3827 DIR *dir
= opendir(ctrl_iface_dir
);
3830 char ifprop
[PROPERTY_VALUE_MAX
];
3831 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3832 ifname
= os_strdup(ifprop
);
3833 printf("Using interface '%s'\n", ifname
);
3836 #endif /* ANDROID */
3839 while ((dent
= readdir(dir
))) {
3840 #ifdef _DIRENT_HAVE_D_TYPE
3842 * Skip the file if it is not a socket. Also accept
3843 * DT_UNKNOWN (0) in case the C library or underlying
3844 * file system does not support d_type.
3846 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3848 #endif /* _DIRENT_HAVE_D_TYPE */
3849 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3850 os_strcmp(dent
->d_name
, "..") == 0)
3852 printf("Selected interface '%s'\n", dent
->d_name
);
3853 ifname
= os_strdup(dent
->d_name
);
3857 #endif /* CONFIG_CTRL_IFACE_UNIX */
3859 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3860 char buf
[2048], *pos
;
3862 struct wpa_ctrl
*ctrl
;
3865 ctrl
= wpa_ctrl_open(NULL
);
3869 len
= sizeof(buf
) - 1;
3870 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3873 pos
= os_strchr(buf
, '\n');
3876 ifname
= os_strdup(buf
);
3878 wpa_ctrl_close(ctrl
);
3879 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3885 int main(int argc
, char *argv
[])
3887 int warning_displayed
= 0;
3891 const char *global
= NULL
;
3893 if (os_program_init())
3897 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3902 action_file
= optarg
;
3911 ping_interval
= atoi(optarg
);
3917 printf("%s\n", wpa_cli_version
);
3920 os_free(ctrl_ifname
);
3921 ctrl_ifname
= os_strdup(optarg
);
3924 ctrl_iface_dir
= optarg
;
3935 interactive
= (argc
== optind
) && (action_file
== NULL
);
3938 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3944 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3945 ctrl_conn
= wpa_ctrl_open(NULL
);
3946 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3947 ctrl_conn
= wpa_ctrl_open(global
);
3948 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3949 if (ctrl_conn
== NULL
) {
3950 fprintf(stderr
, "Failed to connect to wpa_supplicant "
3951 "global interface: %s error: %s\n",
3952 global
, strerror(errno
));
3958 signal(SIGINT
, wpa_cli_terminate
);
3959 signal(SIGTERM
, wpa_cli_terminate
);
3960 #endif /* _WIN32_WCE */
3962 if (ctrl_ifname
== NULL
)
3963 ctrl_ifname
= wpa_cli_get_default_ifname();
3967 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3968 if (warning_displayed
)
3969 printf("Connection established.\n");
3973 if (!warning_displayed
) {
3974 printf("Could not connect to wpa_supplicant: "
3975 "%s - re-trying\n", ctrl_ifname
);
3976 warning_displayed
= 1;
3983 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3984 fprintf(stderr
, "Failed to connect to non-global "
3985 "ctrl_ifname: %s error: %s\n",
3986 ctrl_ifname
, strerror(errno
));
3991 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3992 wpa_cli_attached
= 1;
3994 printf("Warning: Failed to attach to "
3995 "wpa_supplicant.\n");
4001 if (daemonize
&& os_daemonize(pid_file
))
4005 wpa_cli_interactive();
4006 else if (action_file
)
4007 wpa_cli_action(ctrl_conn
);
4009 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
4011 os_free(ctrl_ifname
);
4018 #else /* CONFIG_CTRL_IFACE */
4019 int main(int argc
, char *argv
[])
4021 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
4024 #endif /* CONFIG_CTRL_IFACE */