2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2013, 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-2013, 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
= -1;
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;
84 static char *ifname_prefix
= NULL
;
86 struct cli_txt_entry
{
91 static DEFINE_DL_LIST(bsses
); /* struct cli_txt_entry */
92 static DEFINE_DL_LIST(p2p_peers
); /* struct cli_txt_entry */
93 static DEFINE_DL_LIST(p2p_groups
); /* struct cli_txt_entry */
94 static DEFINE_DL_LIST(ifnames
); /* struct cli_txt_entry */
97 static void print_help(const char *cmd
);
98 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
);
99 static void wpa_cli_close_connection(void);
100 static char * wpa_cli_get_default_ifname(void);
101 static char ** wpa_list_cmd_list(void);
104 static void usage(void)
106 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
107 "[-a<action file>] \\\n"
108 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
110 " -h = help (show this usage text)\n"
111 " -v = shown version information\n"
112 " -a = run in daemon mode executing the action file based on "
115 " -B = run a daemon in the background\n"
116 " default path: " CONFIG_CTRL_IFACE_DIR
"\n"
117 " default interface: first interface found in socket path\n");
122 static void cli_txt_list_free(struct cli_txt_entry
*e
)
124 dl_list_del(&e
->list
);
130 static void cli_txt_list_flush(struct dl_list
*list
)
132 struct cli_txt_entry
*e
;
133 while ((e
= dl_list_first(list
, struct cli_txt_entry
, list
)))
134 cli_txt_list_free(e
);
138 static struct cli_txt_entry
* cli_txt_list_get(struct dl_list
*txt_list
,
141 struct cli_txt_entry
*e
;
142 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
143 if (os_strcmp(e
->txt
, txt
) == 0)
150 static void cli_txt_list_del(struct dl_list
*txt_list
, const char *txt
)
152 struct cli_txt_entry
*e
;
153 e
= cli_txt_list_get(txt_list
, txt
);
155 cli_txt_list_free(e
);
159 static void cli_txt_list_del_addr(struct dl_list
*txt_list
, const char *txt
)
163 if (hwaddr_aton(txt
, addr
) < 0)
165 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
166 cli_txt_list_del(txt_list
, buf
);
171 static void cli_txt_list_del_word(struct dl_list
*txt_list
, const char *txt
)
175 end
= os_strchr(txt
, ' ');
177 end
= txt
+ os_strlen(txt
);
178 buf
= dup_binstr(txt
, end
- txt
);
181 cli_txt_list_del(txt_list
, buf
);
184 #endif /* CONFIG_P2P */
187 static int cli_txt_list_add(struct dl_list
*txt_list
, const char *txt
)
189 struct cli_txt_entry
*e
;
190 e
= cli_txt_list_get(txt_list
, txt
);
193 e
= os_zalloc(sizeof(*e
));
196 e
->txt
= os_strdup(txt
);
197 if (e
->txt
== NULL
) {
201 dl_list_add(txt_list
, &e
->list
);
207 static int cli_txt_list_add_addr(struct dl_list
*txt_list
, const char *txt
)
211 if (hwaddr_aton(txt
, addr
) < 0)
213 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
214 return cli_txt_list_add(txt_list
, buf
);
218 static int cli_txt_list_add_word(struct dl_list
*txt_list
, const char *txt
)
223 end
= os_strchr(txt
, ' ');
225 end
= txt
+ os_strlen(txt
);
226 buf
= dup_binstr(txt
, end
- txt
);
229 ret
= cli_txt_list_add(txt_list
, buf
);
233 #endif /* CONFIG_P2P */
236 static char ** cli_txt_list_array(struct dl_list
*txt_list
)
238 unsigned int i
, count
= dl_list_len(txt_list
);
240 struct cli_txt_entry
*e
;
242 res
= os_calloc(count
+ 1, sizeof(char *));
247 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
248 res
[i
] = os_strdup(e
->txt
);
258 static int get_cmd_arg_num(const char *str
, int pos
)
262 for (i
= 0; i
<= pos
; i
++) {
265 while (i
<= pos
&& str
[i
] != ' ')
276 static int str_starts(const char *src
, const char *match
)
278 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
282 static int wpa_cli_show_event(const char *event
)
286 start
= os_strchr(event
, '>');
292 * Skip BSS added/removed events since they can be relatively frequent
293 * and are likely of not much use for an interactive user.
295 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
296 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
303 static int wpa_cli_open_connection(const char *ifname
, int attach
)
305 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
306 ctrl_conn
= wpa_ctrl_open(ifname
);
307 if (ctrl_conn
== NULL
)
310 if (attach
&& interactive
)
311 mon_conn
= wpa_ctrl_open(ifname
);
314 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
322 if (access(ctrl_iface_dir
, F_OK
) < 0) {
323 cfile
= os_strdup(ifname
);
330 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
331 cfile
= os_malloc(flen
);
334 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
,
336 if (res
< 0 || res
>= flen
) {
342 ctrl_conn
= wpa_ctrl_open(cfile
);
343 if (ctrl_conn
== NULL
) {
348 if (attach
&& interactive
)
349 mon_conn
= wpa_ctrl_open(cfile
);
353 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
356 if (wpa_ctrl_attach(mon_conn
) == 0) {
357 wpa_cli_attached
= 1;
359 eloop_register_read_sock(
360 wpa_ctrl_get_fd(mon_conn
),
361 wpa_cli_mon_receive
, NULL
, NULL
);
363 printf("Warning: Failed to attach to "
364 "wpa_supplicant.\n");
365 wpa_cli_close_connection();
374 static void wpa_cli_close_connection(void)
376 if (ctrl_conn
== NULL
)
379 if (wpa_cli_attached
) {
380 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
381 wpa_cli_attached
= 0;
383 wpa_ctrl_close(ctrl_conn
);
386 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
387 wpa_ctrl_close(mon_conn
);
393 static void wpa_cli_msg_cb(char *msg
, size_t len
)
399 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
405 if (ctrl_conn
== NULL
) {
406 printf("Not connected to wpa_supplicant - command dropped.\n");
410 os_snprintf(buf
, sizeof(buf
), "IFNAME=%s %s",
412 buf
[sizeof(buf
) - 1] = '\0';
415 len
= sizeof(buf
) - 1;
416 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
419 printf("'%s' command timed out.\n", cmd
);
421 } else if (ret
< 0) {
422 printf("'%s' command failed.\n", cmd
);
428 if (interactive
&& len
> 0 && buf
[len
- 1] != '\n')
435 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
437 return _wpa_ctrl_command(ctrl
, cmd
, 1);
441 static int write_cmd(char *buf
, size_t buflen
, const char *cmd
, int argc
,
450 res
= os_snprintf(pos
, end
- pos
, "%s", cmd
);
451 if (res
< 0 || res
>= end
- pos
)
455 for (i
= 0; i
< argc
; i
++) {
456 res
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
457 if (res
< 0 || res
>= end
- pos
)
462 buf
[buflen
- 1] = '\0';
466 printf("Too long command\n");
471 static int wpa_cli_cmd(struct wpa_ctrl
*ctrl
, const char *cmd
, int min_args
,
472 int argc
, char *argv
[])
475 if (argc
< min_args
) {
476 printf("Invalid %s command - at least %d argument%s "
477 "required.\n", cmd
, min_args
,
478 min_args
> 1 ? "s are" : " is");
481 if (write_cmd(buf
, sizeof(buf
), cmd
, argc
, argv
) < 0)
483 return wpa_ctrl_command(ctrl
, buf
);
487 static int wpa_cli_cmd_ifname(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
489 return wpa_ctrl_command(ctrl
, "IFNAME");
493 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
495 if (argc
> 0 && os_strcmp(argv
[0], "verbose") == 0)
496 return wpa_ctrl_command(ctrl
, "STATUS-VERBOSE");
497 if (argc
> 0 && os_strcmp(argv
[0], "wps") == 0)
498 return wpa_ctrl_command(ctrl
, "STATUS-WPS");
499 return wpa_ctrl_command(ctrl
, "STATUS");
503 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
505 return wpa_ctrl_command(ctrl
, "PING");
509 static int wpa_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
511 return wpa_ctrl_command(ctrl
, "RELOG");
515 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
517 return wpa_cli_cmd(ctrl
, "NOTE", 1, argc
, argv
);
521 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
523 return wpa_ctrl_command(ctrl
, "MIB");
527 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
529 return wpa_ctrl_command(ctrl
, "PMKSA");
533 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
535 print_help(argc
> 0 ? argv
[0] : NULL
);
540 static char ** wpa_cli_complete_help(const char *str
, int pos
)
542 int arg
= get_cmd_arg_num(str
, pos
);
547 res
= wpa_list_cmd_list();
555 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
557 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
562 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
571 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
577 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s ", argv
[0]);
578 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
579 printf("Too long SET command.\n");
582 return wpa_ctrl_command(ctrl
, cmd
);
585 return wpa_cli_cmd(ctrl
, "SET", 2, argc
, argv
);
589 static char ** wpa_cli_complete_set(const char *str
, int pos
)
591 int arg
= get_cmd_arg_num(str
, pos
);
592 const char *fields
[] = {
594 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
595 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
596 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
597 "wps_fragment_size", "wps_version_number", "ampdu",
598 "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
599 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
601 /* global configuration parameters */
602 "eapol_version", "ap_scan", "disable_scan_offload",
603 "fast_reauth", "opensc_engine_path", "pkcs11_engine_path",
604 "pkcs11_module_path", "pcsc_reader", "pcsc_pin",
605 "driver_param", "dot11RSNAConfigPMKLifetime",
606 "dot11RSNAConfigPMKReauthThreshold",
607 "dot11RSNAConfigSATimeout",
608 "update_config", "load_dynamic_eap", "uuid", "device_name",
609 "manufacturer", "model_name", "model_number", "serial_number",
610 "device_type", "os_version", "config_methods",
611 "wps_cred_processing", "wps_vendor_ext_m1", "sec_device_type",
612 "p2p_listen_reg_class", "p2p_listen_channel",
613 "p2p_oper_reg_class", "p2p_oper_channel",
614 "p2p_go_intent", "p2p_ssid_postfix", "persistent_reconnect",
615 "p2p_intra_bss", "p2p_group_idle", "p2p_pref_chan",
616 "p2p_go_ht40", "p2p_disabled", "p2p_no_group_iface",
617 "p2p_ignore_shared_freq", "country", "bss_max_count",
618 "bss_expiration_age", "bss_expiration_scan_count",
619 "filter_ssids", "filter_rssi", "max_num_sta",
620 "disassoc_low_ack", "hs20", "interworking", "hessid",
621 "access_network_type", "pbc_in_m1", "autoscan",
622 "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", "wps_nfc_dh_privkey",
623 "wps_nfc_dev_pw", "ext_password_backend",
624 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
625 "sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
626 "ignore_old_scan_res", "freq_list"
628 int i
, num_fields
= sizeof(fields
) / sizeof(fields
[0]);
631 char **res
= os_calloc(num_fields
+ 1, sizeof(char *));
634 for (i
= 0; i
< num_fields
; i
++) {
635 res
[i
] = os_strdup(fields
[i
]);
642 if (arg
> 1 && os_strncasecmp(str
, "set bssid_filter ", 17) == 0)
643 return cli_txt_list_array(&bsses
);
649 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
651 return wpa_cli_cmd(ctrl
, "GET", 1, argc
, argv
);
655 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
657 return wpa_ctrl_command(ctrl
, "LOGOFF");
661 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
663 return wpa_ctrl_command(ctrl
, "LOGON");
667 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
670 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
674 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
677 return wpa_cli_cmd(ctrl
, "PREAUTH", 1, argc
, argv
);
681 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
683 return wpa_cli_cmd(ctrl
, "AP_SCAN", 1, argc
, argv
);
687 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl
*ctrl
, int argc
,
690 return wpa_cli_cmd(ctrl
, "SCAN_INTERVAL", 1, argc
, argv
);
694 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl
*ctrl
, int argc
,
697 return wpa_cli_cmd(ctrl
, "BSS_EXPIRE_AGE", 1, argc
, argv
);
701 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl
*ctrl
, int argc
,
704 return wpa_cli_cmd(ctrl
, "BSS_EXPIRE_COUNT", 1, argc
, argv
);
708 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
714 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_FLUSH 0");
716 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_FLUSH %s", argv
[0]);
717 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
718 printf("Too long BSS_FLUSH command.\n");
721 return wpa_ctrl_command(ctrl
, cmd
);
725 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
728 return wpa_cli_cmd(ctrl
, "STKSTART", 1, argc
, argv
);
732 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
734 return wpa_cli_cmd(ctrl
, "FT_DS", 1, argc
, argv
);
738 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
740 return wpa_cli_cmd(ctrl
, "WPS_PBC", 0, argc
, argv
);
744 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
747 printf("Invalid WPS_PIN command: need one or two arguments:\n"
748 "- BSSID: use 'any' to select any\n"
749 "- PIN: optional, used only with devices that have no "
754 return wpa_cli_cmd(ctrl
, "WPS_PIN", 1, argc
, argv
);
758 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
761 return wpa_cli_cmd(ctrl
, "WPS_CHECK_PIN", 1, argc
, argv
);
765 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
768 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
772 #ifdef CONFIG_WPS_NFC
774 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
776 return wpa_cli_cmd(ctrl
, "WPS_NFC", 0, argc
, argv
);
780 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl
*ctrl
, int argc
,
783 return wpa_cli_cmd(ctrl
, "WPS_NFC_CONFIG_TOKEN", 1, argc
, argv
);
787 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl
*ctrl
, int argc
,
790 return wpa_cli_cmd(ctrl
, "WPS_NFC_TOKEN", 1, argc
, argv
);
794 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl
*ctrl
, int argc
,
802 printf("Invalid 'wps_nfc_tag_read' command - one argument "
807 buflen
= 18 + os_strlen(argv
[0]);
808 buf
= os_malloc(buflen
);
811 os_snprintf(buf
, buflen
, "WPS_NFC_TAG_READ %s", argv
[0]);
813 ret
= wpa_ctrl_command(ctrl
, buf
);
820 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl
*ctrl
, int argc
,
823 return wpa_cli_cmd(ctrl
, "NFC_GET_HANDOVER_REQ", 2, argc
, argv
);
827 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl
*ctrl
, int argc
,
830 return wpa_cli_cmd(ctrl
, "NFC_GET_HANDOVER_SEL", 2, argc
, argv
);
834 static int wpa_cli_cmd_nfc_rx_handover_req(struct wpa_ctrl
*ctrl
, int argc
,
842 printf("Invalid 'nfc_rx_handover_req' command - one argument "
847 buflen
= 21 + os_strlen(argv
[0]);
848 buf
= os_malloc(buflen
);
851 os_snprintf(buf
, buflen
, "NFC_RX_HANDOVER_REQ %s", argv
[0]);
853 ret
= wpa_ctrl_command(ctrl
, buf
);
860 static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl
*ctrl
, int argc
,
868 printf("Invalid 'nfc_rx_handover_sel' command - one argument "
873 buflen
= 21 + os_strlen(argv
[0]);
874 buf
= os_malloc(buflen
);
877 os_snprintf(buf
, buflen
, "NFC_RX_HANDOVER_SEL %s", argv
[0]);
879 ret
= wpa_ctrl_command(ctrl
, buf
);
886 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl
*ctrl
, int argc
,
889 return wpa_cli_cmd(ctrl
, "NFC_REPORT_HANDOVER", 4, argc
, argv
);
892 #endif /* CONFIG_WPS_NFC */
895 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
901 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
903 else if (argc
== 5 || argc
== 6) {
904 char ssid_hex
[2 * 32 + 1];
905 char key_hex
[2 * 64 + 1];
909 for (i
= 0; i
< 32; i
++) {
910 if (argv
[2][i
] == '\0')
912 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
917 for (i
= 0; i
< 64; i
++) {
918 if (argv
[5][i
] == '\0')
920 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
925 res
= os_snprintf(cmd
, sizeof(cmd
),
926 "WPS_REG %s %s %s %s %s %s",
927 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
930 printf("Invalid WPS_REG command: need two arguments:\n"
931 "- BSSID of the target AP\n"
933 printf("Alternatively, six arguments can be used to "
934 "reconfigure the AP:\n"
935 "- BSSID of the target AP\n"
938 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
939 "- new encr (NONE, WEP, TKIP, CCMP)\n"
944 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
945 printf("Too long WPS_REG command.\n");
948 return wpa_ctrl_command(ctrl
, cmd
);
952 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
955 return wpa_cli_cmd(ctrl
, "WPS_AP_PIN", 1, argc
, argv
);
959 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
962 return wpa_cli_cmd(ctrl
, "WPS_ER_START", 0, argc
, argv
);
966 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
969 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
974 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
978 printf("Invalid WPS_ER_PIN command: need at least two "
980 "- UUID: use 'any' to select any\n"
981 "- PIN: Enrollee PIN\n"
982 "optional: - Enrollee MAC address\n");
986 return wpa_cli_cmd(ctrl
, "WPS_ER_PIN", 2, argc
, argv
);
990 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
993 return wpa_cli_cmd(ctrl
, "WPS_ER_PBC", 1, argc
, argv
);
997 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
1001 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1002 "- UUID: specify which AP to use\n"
1007 return wpa_cli_cmd(ctrl
, "WPS_ER_LEARN", 2, argc
, argv
);
1011 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
1015 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1017 "- UUID: specify which AP to use\n"
1018 "- Network configuration id\n");
1022 return wpa_cli_cmd(ctrl
, "WPS_ER_SET_CONFIG", 2, argc
, argv
);
1026 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
1032 if (argc
== 5 || argc
== 6) {
1033 char ssid_hex
[2 * 32 + 1];
1034 char key_hex
[2 * 64 + 1];
1038 for (i
= 0; i
< 32; i
++) {
1039 if (argv
[2][i
] == '\0')
1041 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
1046 for (i
= 0; i
< 64; i
++) {
1047 if (argv
[5][i
] == '\0')
1049 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
1054 res
= os_snprintf(cmd
, sizeof(cmd
),
1055 "WPS_ER_CONFIG %s %s %s %s %s %s",
1056 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
1059 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1063 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1064 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1069 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1070 printf("Too long WPS_ER_CONFIG command.\n");
1073 return wpa_ctrl_command(ctrl
, cmd
);
1077 #ifdef CONFIG_WPS_NFC
1078 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl
*ctrl
, int argc
,
1082 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1084 "- WPS/NDEF: token format\n"
1085 "- UUID: specify which AP to use\n");
1089 return wpa_cli_cmd(ctrl
, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc
, argv
);
1091 #endif /* CONFIG_WPS_NFC */
1094 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1096 return wpa_cli_cmd(ctrl
, "IBSS_RSN", 1, argc
, argv
);
1100 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1102 return wpa_cli_cmd(ctrl
, "LEVEL", 1, argc
, argv
);
1106 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1108 char cmd
[256], *pos
, *end
;
1112 printf("Invalid IDENTITY command: needs two arguments "
1113 "(network id and identity)\n");
1117 end
= cmd
+ sizeof(cmd
);
1119 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
1121 if (ret
< 0 || ret
>= end
- pos
) {
1122 printf("Too long IDENTITY command.\n");
1126 for (i
= 2; i
< argc
; i
++) {
1127 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1128 if (ret
< 0 || ret
>= end
- pos
) {
1129 printf("Too long IDENTITY command.\n");
1135 return wpa_ctrl_command(ctrl
, cmd
);
1139 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1141 char cmd
[256], *pos
, *end
;
1145 printf("Invalid PASSWORD command: needs two arguments "
1146 "(network id and password)\n");
1150 end
= cmd
+ sizeof(cmd
);
1152 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1154 if (ret
< 0 || ret
>= end
- pos
) {
1155 printf("Too long PASSWORD command.\n");
1159 for (i
= 2; i
< argc
; i
++) {
1160 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1161 if (ret
< 0 || ret
>= end
- pos
) {
1162 printf("Too long PASSWORD command.\n");
1168 return wpa_ctrl_command(ctrl
, cmd
);
1172 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1175 char cmd
[256], *pos
, *end
;
1179 printf("Invalid NEW_PASSWORD command: needs two arguments "
1180 "(network id and password)\n");
1184 end
= cmd
+ sizeof(cmd
);
1186 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1188 if (ret
< 0 || ret
>= end
- pos
) {
1189 printf("Too long NEW_PASSWORD command.\n");
1193 for (i
= 2; i
< argc
; i
++) {
1194 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1195 if (ret
< 0 || ret
>= end
- pos
) {
1196 printf("Too long NEW_PASSWORD command.\n");
1202 return wpa_ctrl_command(ctrl
, cmd
);
1206 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1208 char cmd
[256], *pos
, *end
;
1212 printf("Invalid PIN command: needs two arguments "
1213 "(network id and pin)\n");
1217 end
= cmd
+ sizeof(cmd
);
1219 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1221 if (ret
< 0 || ret
>= end
- pos
) {
1222 printf("Too long PIN command.\n");
1226 for (i
= 2; i
< argc
; i
++) {
1227 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1228 if (ret
< 0 || ret
>= end
- pos
) {
1229 printf("Too long PIN command.\n");
1234 return wpa_ctrl_command(ctrl
, cmd
);
1238 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1240 char cmd
[256], *pos
, *end
;
1244 printf("Invalid OTP command: needs two arguments (network "
1245 "id and password)\n");
1249 end
= cmd
+ sizeof(cmd
);
1251 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1253 if (ret
< 0 || ret
>= end
- pos
) {
1254 printf("Too long OTP command.\n");
1258 for (i
= 2; i
< argc
; i
++) {
1259 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1260 if (ret
< 0 || ret
>= end
- pos
) {
1261 printf("Too long OTP command.\n");
1267 return wpa_ctrl_command(ctrl
, cmd
);
1271 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1274 char cmd
[256], *pos
, *end
;
1278 printf("Invalid PASSPHRASE command: needs two arguments "
1279 "(network id and passphrase)\n");
1283 end
= cmd
+ sizeof(cmd
);
1285 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1287 if (ret
< 0 || ret
>= end
- pos
) {
1288 printf("Too long PASSPHRASE command.\n");
1292 for (i
= 2; i
< argc
; i
++) {
1293 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1294 if (ret
< 0 || ret
>= end
- pos
) {
1295 printf("Too long PASSPHRASE command.\n");
1301 return wpa_ctrl_command(ctrl
, cmd
);
1305 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1308 printf("Invalid BSSID command: needs two arguments (network "
1313 return wpa_cli_cmd(ctrl
, "BSSID", 2, argc
, argv
);
1317 static int wpa_cli_cmd_blacklist(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1319 return wpa_cli_cmd(ctrl
, "BLACKLIST", 0, argc
, argv
);
1323 static int wpa_cli_cmd_log_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1325 return wpa_cli_cmd(ctrl
, "LOG_LEVEL", 0, argc
, argv
);
1329 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1332 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1336 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1339 return wpa_cli_cmd(ctrl
, "SELECT_NETWORK", 1, argc
, argv
);
1343 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1346 return wpa_cli_cmd(ctrl
, "ENABLE_NETWORK", 1, argc
, argv
);
1350 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1353 return wpa_cli_cmd(ctrl
, "DISABLE_NETWORK", 1, argc
, argv
);
1357 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1360 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1364 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1367 return wpa_cli_cmd(ctrl
, "REMOVE_NETWORK", 1, argc
, argv
);
1371 static void wpa_cli_show_network_variables(void)
1373 printf("set_network variables:\n"
1374 " ssid (network name, SSID)\n"
1375 " psk (WPA passphrase or pre-shared key)\n"
1376 " key_mgmt (key management protocol)\n"
1377 " identity (EAP identity)\n"
1378 " password (EAP password)\n"
1381 "Note: Values are entered in the same format as the "
1382 "configuration file is using,\n"
1383 "i.e., strings values need to be inside double quotation "
1385 "For example: set_network 1 ssid \"network name\"\n"
1387 "Please see wpa_supplicant.conf documentation for full list "
1388 "of\navailable variables.\n");
1392 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1396 wpa_cli_show_network_variables();
1401 printf("Invalid SET_NETWORK command: needs three arguments\n"
1402 "(network id, variable name, and value)\n");
1406 return wpa_cli_cmd(ctrl
, "SET_NETWORK", 3, argc
, argv
);
1410 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1414 wpa_cli_show_network_variables();
1419 printf("Invalid GET_NETWORK command: needs two arguments\n"
1420 "(network id and variable name)\n");
1424 return wpa_cli_cmd(ctrl
, "GET_NETWORK", 2, argc
, argv
);
1428 static int wpa_cli_cmd_list_creds(struct wpa_ctrl
*ctrl
, int argc
,
1431 return wpa_ctrl_command(ctrl
, "LIST_CREDS");
1435 static int wpa_cli_cmd_add_cred(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1437 return wpa_ctrl_command(ctrl
, "ADD_CRED");
1441 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl
*ctrl
, int argc
,
1444 return wpa_cli_cmd(ctrl
, "REMOVE_CRED", 1, argc
, argv
);
1448 static int wpa_cli_cmd_set_cred(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1451 printf("Invalid SET_CRED command: needs three arguments\n"
1452 "(cred id, variable name, and value)\n");
1456 return wpa_cli_cmd(ctrl
, "SET_CRED", 3, argc
, argv
);
1460 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1463 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1467 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1470 return wpa_ctrl_command(ctrl
, "RECONNECT");
1474 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1477 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1481 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1483 return wpa_cli_cmd(ctrl
, "SCAN", 0, argc
, argv
);
1487 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1490 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1494 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1496 return wpa_cli_cmd(ctrl
, "BSS", 1, argc
, argv
);
1500 static char ** wpa_cli_complete_bss(const char *str
, int pos
)
1502 int arg
= get_cmd_arg_num(str
, pos
);
1507 res
= cli_txt_list_array(&bsses
);
1515 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1518 if (argc
< 1 || argc
> 2) {
1519 printf("Invalid GET_CAPABILITY command: need either one or "
1524 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1525 printf("Invalid GET_CAPABILITY command: second argument, "
1526 "if any, must be 'strict'\n");
1530 return wpa_cli_cmd(ctrl
, "GET_CAPABILITY", 1, argc
, argv
);
1534 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1536 printf("Available interfaces:\n");
1537 return wpa_ctrl_command(ctrl
, "INTERFACES");
1541 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1544 wpa_cli_list_interfaces(ctrl
);
1548 wpa_cli_close_connection();
1549 os_free(ctrl_ifname
);
1550 ctrl_ifname
= os_strdup(argv
[0]);
1552 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1553 printf("Connected to interface '%s.\n", ctrl_ifname
);
1555 printf("Could not connect to interface '%s' - re-trying\n",
1562 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1565 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1569 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1572 return wpa_ctrl_command(ctrl
, "TERMINATE");
1576 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1583 printf("Invalid INTERFACE_ADD command: needs at least one "
1584 "argument (interface name)\n"
1585 "All arguments: ifname confname driver ctrl_interface "
1586 "driver_param bridge_name\n");
1591 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1592 * <driver_param>TAB<bridge_name>
1594 res
= os_snprintf(cmd
, sizeof(cmd
),
1595 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1597 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1598 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1599 argc
> 5 ? argv
[5] : "");
1600 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1602 cmd
[sizeof(cmd
) - 1] = '\0';
1603 return wpa_ctrl_command(ctrl
, cmd
);
1607 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1610 return wpa_cli_cmd(ctrl
, "INTERFACE_REMOVE", 1, argc
, argv
);
1614 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1617 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1622 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1624 return wpa_cli_cmd(ctrl
, "STA", 1, argc
, argv
);
1628 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1629 char *addr
, size_t addr_len
)
1631 char buf
[4096], *pos
;
1635 if (ctrl_conn
== NULL
) {
1636 printf("Not connected to hostapd - command dropped.\n");
1639 len
= sizeof(buf
) - 1;
1640 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
1643 printf("'%s' command timed out.\n", cmd
);
1645 } else if (ret
< 0) {
1646 printf("'%s' command failed.\n", cmd
);
1651 if (os_memcmp(buf
, "FAIL", 4) == 0)
1656 while (*pos
!= '\0' && *pos
!= '\n')
1659 os_strlcpy(addr
, buf
, addr_len
);
1664 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1666 char addr
[32], cmd
[64];
1668 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1671 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1672 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1678 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
1681 return wpa_cli_cmd(ctrl
, "DEAUTHENTICATE", 1, argc
, argv
);
1685 static int wpa_cli_cmd_disassociate(struct wpa_ctrl
*ctrl
, int argc
,
1688 return wpa_cli_cmd(ctrl
, "DISASSOCIATE", 1, argc
, argv
);
1690 #endif /* CONFIG_AP */
1693 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1695 return wpa_ctrl_command(ctrl
, "SUSPEND");
1699 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1701 return wpa_ctrl_command(ctrl
, "RESUME");
1705 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1707 return wpa_ctrl_command(ctrl
, "DROP_SA");
1711 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1713 return wpa_cli_cmd(ctrl
, "ROAM", 1, argc
, argv
);
1719 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1721 return wpa_cli_cmd(ctrl
, "P2P_FIND", 0, argc
, argv
);
1725 static char ** wpa_cli_complete_p2p_find(const char *str
, int pos
)
1728 int arg
= get_cmd_arg_num(str
, pos
);
1730 res
= os_calloc(6, sizeof(char *));
1733 res
[0] = os_strdup("type=social");
1734 if (res
[0] == NULL
) {
1738 res
[1] = os_strdup("type=progressive");
1741 res
[2] = os_strdup("delay=");
1744 res
[3] = os_strdup("dev_id=");
1748 res
[4] = os_strdup("[timeout]");
1754 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1757 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1761 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1764 return wpa_cli_cmd(ctrl
, "P2P_CONNECT", 2, argc
, argv
);
1768 static char ** wpa_cli_complete_p2p_connect(const char *str
, int pos
)
1770 int arg
= get_cmd_arg_num(str
, pos
);
1775 res
= cli_txt_list_array(&p2p_peers
);
1783 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1786 return wpa_cli_cmd(ctrl
, "P2P_LISTEN", 0, argc
, argv
);
1790 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1793 return wpa_cli_cmd(ctrl
, "P2P_GROUP_REMOVE", 1, argc
, argv
);
1797 static char ** wpa_cli_complete_p2p_group_remove(const char *str
, int pos
)
1799 int arg
= get_cmd_arg_num(str
, pos
);
1804 res
= cli_txt_list_array(&p2p_groups
);
1812 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1815 return wpa_cli_cmd(ctrl
, "P2P_GROUP_ADD", 0, argc
, argv
);
1819 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1822 if (argc
!= 2 && argc
!= 3) {
1823 printf("Invalid P2P_PROV_DISC command: needs at least "
1824 "two arguments, address and config method\n"
1825 "(display, keypad, or pbc) and an optional join\n");
1829 return wpa_cli_cmd(ctrl
, "P2P_PROV_DISC", 2, argc
, argv
);
1833 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1836 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1840 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1845 if (argc
!= 2 && argc
!= 4) {
1846 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1847 "arguments (address and TLVs) or four arguments "
1848 "(address, \"upnp\", version, search target "
1853 if (write_cmd(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ", argc
, argv
) < 0)
1855 return wpa_ctrl_command(ctrl
, cmd
);
1859 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1860 int argc
, char *argv
[])
1862 return wpa_cli_cmd(ctrl
, "P2P_SERV_DISC_CANCEL_REQ", 1, argc
, argv
);
1866 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1873 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1874 "arguments (freq, address, dialog token, and TLVs)\n");
1878 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1879 argv
[0], argv
[1], argv
[2], argv
[3]);
1880 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1882 cmd
[sizeof(cmd
) - 1] = '\0';
1883 return wpa_ctrl_command(ctrl
, cmd
);
1887 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1890 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1894 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1895 int argc
, char *argv
[])
1897 return wpa_cli_cmd(ctrl
, "P2P_SERV_DISC_EXTERNAL", 1, argc
, argv
);
1901 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1904 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1908 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1914 if (argc
!= 3 && argc
!= 4) {
1915 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1921 res
= os_snprintf(cmd
, sizeof(cmd
),
1922 "P2P_SERVICE_ADD %s %s %s %s",
1923 argv
[0], argv
[1], argv
[2], argv
[3]);
1925 res
= os_snprintf(cmd
, sizeof(cmd
),
1926 "P2P_SERVICE_ADD %s %s %s",
1927 argv
[0], argv
[1], argv
[2]);
1928 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1930 cmd
[sizeof(cmd
) - 1] = '\0';
1931 return wpa_ctrl_command(ctrl
, cmd
);
1935 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1941 if (argc
!= 2 && argc
!= 3) {
1942 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1948 res
= os_snprintf(cmd
, sizeof(cmd
),
1949 "P2P_SERVICE_DEL %s %s %s",
1950 argv
[0], argv
[1], argv
[2]);
1952 res
= os_snprintf(cmd
, sizeof(cmd
),
1953 "P2P_SERVICE_DEL %s %s",
1955 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1957 cmd
[sizeof(cmd
) - 1] = '\0';
1958 return wpa_ctrl_command(ctrl
, cmd
);
1962 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1963 int argc
, char *argv
[])
1965 return wpa_cli_cmd(ctrl
, "P2P_REJECT", 1, argc
, argv
);
1969 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
1970 int argc
, char *argv
[])
1972 return wpa_cli_cmd(ctrl
, "P2P_INVITE", 1, argc
, argv
);
1976 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1978 return wpa_cli_cmd(ctrl
, "P2P_PEER", 1, argc
, argv
);
1982 static char ** wpa_cli_complete_p2p_peer(const char *str
, int pos
)
1984 int arg
= get_cmd_arg_num(str
, pos
);
1989 res
= cli_txt_list_array(&p2p_peers
);
1997 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
1998 char *addr
, size_t addr_len
,
2001 char buf
[4096], *pos
;
2005 if (ctrl_conn
== NULL
)
2007 len
= sizeof(buf
) - 1;
2008 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
2011 printf("'%s' command timed out.\n", cmd
);
2013 } else if (ret
< 0) {
2014 printf("'%s' command failed.\n", cmd
);
2019 if (os_memcmp(buf
, "FAIL", 4) == 0)
2023 while (*pos
!= '\0' && *pos
!= '\n')
2026 os_strlcpy(addr
, buf
, addr_len
);
2027 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2028 printf("%s\n", addr
);
2033 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2035 char addr
[32], cmd
[64];
2038 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2040 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2041 addr
, sizeof(addr
), discovered
))
2044 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2045 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2052 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2054 return wpa_cli_cmd(ctrl
, "P2P_SET", 2, argc
, argv
);
2058 static char ** wpa_cli_complete_p2p_set(const char *str
, int pos
)
2060 int arg
= get_cmd_arg_num(str
, pos
);
2061 const char *fields
[] = {
2081 int i
, num_fields
= sizeof(fields
) / sizeof(fields
[0]);
2084 char **res
= os_calloc(num_fields
+ 1, sizeof(char *));
2087 for (i
= 0; i
< num_fields
; i
++) {
2088 res
[i
] = os_strdup(fields
[i
]);
2095 if (arg
== 2 && os_strncasecmp(str
, "p2p_set peer_filter ", 20) == 0)
2096 return cli_txt_list_array(&p2p_peers
);
2102 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2104 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2108 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2111 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2115 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
2118 return wpa_cli_cmd(ctrl
, "P2P_UNAUTHORIZE", 1, argc
, argv
);
2122 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2125 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2126 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2127 "(preferred duration, interval; in microsecods).\n"
2128 "Optional second pair can be used to provide "
2129 "acceptable values.\n");
2133 return wpa_cli_cmd(ctrl
, "P2P_PRESENCE_REQ", 0, argc
, argv
);
2137 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2140 if (argc
!= 0 && argc
!= 2) {
2141 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2142 "(availability period, availability interval; in "
2144 "Extended Listen Timing can be cancelled with this "
2145 "command when used without parameters.\n");
2149 return wpa_cli_cmd(ctrl
, "P2P_EXT_LISTEN", 0, argc
, argv
);
2153 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl
*ctrl
, int argc
,
2156 return wpa_cli_cmd(ctrl
, "P2P_REMOVE_CLIENT", 1, argc
, argv
);
2159 #endif /* CONFIG_P2P */
2161 #ifdef CONFIG_WIFI_DISPLAY
2163 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl
*ctrl
, int argc
,
2169 if (argc
!= 1 && argc
!= 2) {
2170 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2171 "arguments (subelem, hexdump)\n");
2175 res
= os_snprintf(cmd
, sizeof(cmd
), "WFD_SUBELEM_SET %s %s",
2176 argv
[0], argc
> 1 ? argv
[1] : "");
2177 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2179 cmd
[sizeof(cmd
) - 1] = '\0';
2180 return wpa_ctrl_command(ctrl
, cmd
);
2184 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl
*ctrl
, int argc
,
2191 printf("Invalid WFD_SUBELEM_GET command: needs one "
2192 "argument (subelem)\n");
2196 res
= os_snprintf(cmd
, sizeof(cmd
), "WFD_SUBELEM_GET %s",
2198 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2200 cmd
[sizeof(cmd
) - 1] = '\0';
2201 return wpa_ctrl_command(ctrl
, cmd
);
2203 #endif /* CONFIG_WIFI_DISPLAY */
2206 #ifdef CONFIG_INTERWORKING
2207 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2210 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
2214 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2217 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
2221 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl
*ctrl
, int argc
,
2224 return wpa_cli_cmd(ctrl
, "INTERWORKING_SELECT", 0, argc
, argv
);
2228 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl
*ctrl
, int argc
,
2231 return wpa_cli_cmd(ctrl
, "INTERWORKING_CONNECT", 1, argc
, argv
);
2235 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2237 return wpa_cli_cmd(ctrl
, "ANQP_GET", 2, argc
, argv
);
2241 static int wpa_cli_cmd_gas_request(struct wpa_ctrl
*ctrl
, int argc
,
2244 return wpa_cli_cmd(ctrl
, "GAS_REQUEST", 2, argc
, argv
);
2248 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl
*ctrl
, int argc
,
2251 return wpa_cli_cmd(ctrl
, "GAS_RESPONSE_GET", 2, argc
, argv
);
2253 #endif /* CONFIG_INTERWORKING */
2258 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl
*ctrl
, int argc
,
2261 return wpa_cli_cmd(ctrl
, "HS20_ANQP_GET", 2, argc
, argv
);
2265 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl
*ctrl
, int argc
,
2271 printf("Command needs one or two arguments (dst mac addr and "
2272 "optional home realm)\n");
2276 if (write_cmd(cmd
, sizeof(cmd
), "HS20_GET_NAI_HOME_REALM_LIST",
2280 return wpa_ctrl_command(ctrl
, cmd
);
2283 #endif /* CONFIG_HS20 */
2286 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2289 return wpa_cli_cmd(ctrl
, "STA_AUTOCONNECT", 1, argc
, argv
);
2293 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2296 return wpa_cli_cmd(ctrl
, "TDLS_DISCOVER", 1, argc
, argv
);
2300 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2303 return wpa_cli_cmd(ctrl
, "TDLS_SETUP", 1, argc
, argv
);
2307 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2310 return wpa_cli_cmd(ctrl
, "TDLS_TEARDOWN", 1, argc
, argv
);
2314 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2317 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2321 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl
*ctrl
, int argc
,
2324 return wpa_ctrl_command(ctrl
, "PKTCNT_POLL");
2328 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
2331 return wpa_ctrl_command(ctrl
, "REAUTHENTICATE");
2335 #ifdef CONFIG_AUTOSCAN
2337 static int wpa_cli_cmd_autoscan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2340 return wpa_ctrl_command(ctrl
, "AUTOSCAN ");
2342 return wpa_cli_cmd(ctrl
, "AUTOSCAN", 0, argc
, argv
);
2345 #endif /* CONFIG_AUTOSCAN */
2350 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2352 return wpa_cli_cmd(ctrl
, "WNM_SLEEP", 0, argc
, argv
);
2356 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2358 return wpa_cli_cmd(ctrl
, "WNM_BSS_QUERY", 1, argc
, argv
);
2361 #endif /* CONFIG_WNM */
2364 static int wpa_cli_cmd_raw(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2368 return wpa_cli_cmd(ctrl
, argv
[0], 0, argc
- 1, &argv
[1]);
2372 static int wpa_cli_cmd_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2374 return wpa_ctrl_command(ctrl
, "FLUSH");
2378 enum wpa_cli_cmd_flags
{
2379 cli_cmd_flag_none
= 0x00,
2380 cli_cmd_flag_sensitive
= 0x01
2383 struct wpa_cli_cmd
{
2385 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2386 char ** (*completion
)(const char *str
, int pos
);
2387 enum wpa_cli_cmd_flags flags
;
2391 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2392 { "status", wpa_cli_cmd_status
, NULL
,
2394 "[verbose] = get current WPA/EAPOL/EAP status" },
2395 { "ifname", wpa_cli_cmd_ifname
, NULL
,
2397 "= get current interface name" },
2398 { "ping", wpa_cli_cmd_ping
, NULL
,
2400 "= pings wpa_supplicant" },
2401 { "relog", wpa_cli_cmd_relog
, NULL
,
2403 "= re-open log-file (allow rolling logs)" },
2404 { "note", wpa_cli_cmd_note
, NULL
,
2406 "<text> = add a note to wpa_supplicant debug log" },
2407 { "mib", wpa_cli_cmd_mib
, NULL
,
2409 "= get MIB variables (dot1x, dot11)" },
2410 { "help", wpa_cli_cmd_help
, wpa_cli_complete_help
,
2412 "[command] = show usage help" },
2413 { "interface", wpa_cli_cmd_interface
, NULL
,
2415 "[ifname] = show interfaces/select interface" },
2416 { "level", wpa_cli_cmd_level
, NULL
,
2418 "<debug level> = change debug level" },
2419 { "license", wpa_cli_cmd_license
, NULL
,
2421 "= show full wpa_cli license" },
2422 { "quit", wpa_cli_cmd_quit
, NULL
,
2425 { "set", wpa_cli_cmd_set
, wpa_cli_complete_set
,
2427 "= set variables (shows list of variables when run without "
2429 { "get", wpa_cli_cmd_get
, NULL
,
2431 "<name> = get information" },
2432 { "logon", wpa_cli_cmd_logon
, NULL
,
2434 "= IEEE 802.1X EAPOL state machine logon" },
2435 { "logoff", wpa_cli_cmd_logoff
, NULL
,
2437 "= IEEE 802.1X EAPOL state machine logoff" },
2438 { "pmksa", wpa_cli_cmd_pmksa
, NULL
,
2440 "= show PMKSA cache" },
2441 { "reassociate", wpa_cli_cmd_reassociate
, NULL
,
2443 "= force reassociation" },
2444 { "preauthenticate", wpa_cli_cmd_preauthenticate
, wpa_cli_complete_bss
,
2446 "<BSSID> = force preauthentication" },
2447 { "identity", wpa_cli_cmd_identity
, NULL
,
2449 "<network id> <identity> = configure identity for an SSID" },
2450 { "password", wpa_cli_cmd_password
, NULL
,
2451 cli_cmd_flag_sensitive
,
2452 "<network id> <password> = configure password for an SSID" },
2453 { "new_password", wpa_cli_cmd_new_password
, NULL
,
2454 cli_cmd_flag_sensitive
,
2455 "<network id> <password> = change password for an SSID" },
2456 { "pin", wpa_cli_cmd_pin
, NULL
,
2457 cli_cmd_flag_sensitive
,
2458 "<network id> <pin> = configure pin for an SSID" },
2459 { "otp", wpa_cli_cmd_otp
, NULL
,
2460 cli_cmd_flag_sensitive
,
2461 "<network id> <password> = configure one-time-password for an SSID"
2463 { "passphrase", wpa_cli_cmd_passphrase
, NULL
,
2464 cli_cmd_flag_sensitive
,
2465 "<network id> <passphrase> = configure private key passphrase\n"
2467 { "bssid", wpa_cli_cmd_bssid
, NULL
,
2469 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2470 { "blacklist", wpa_cli_cmd_blacklist
, wpa_cli_complete_bss
,
2472 "<BSSID> = add a BSSID to the blacklist\n"
2473 "blacklist clear = clear the blacklist\n"
2474 "blacklist = display the blacklist" },
2475 { "log_level", wpa_cli_cmd_log_level
, NULL
,
2477 "<level> [<timestamp>] = update the log level/timestamp\n"
2478 "log_level = display the current log level and log options" },
2479 { "list_networks", wpa_cli_cmd_list_networks
, NULL
,
2481 "= list configured networks" },
2482 { "select_network", wpa_cli_cmd_select_network
, NULL
,
2484 "<network id> = select a network (disable others)" },
2485 { "enable_network", wpa_cli_cmd_enable_network
, NULL
,
2487 "<network id> = enable a network" },
2488 { "disable_network", wpa_cli_cmd_disable_network
, NULL
,
2490 "<network id> = disable a network" },
2491 { "add_network", wpa_cli_cmd_add_network
, NULL
,
2493 "= add a network" },
2494 { "remove_network", wpa_cli_cmd_remove_network
, NULL
,
2496 "<network id> = remove a network" },
2497 { "set_network", wpa_cli_cmd_set_network
, NULL
,
2498 cli_cmd_flag_sensitive
,
2499 "<network id> <variable> <value> = set network variables (shows\n"
2500 " list of variables when run without arguments)" },
2501 { "get_network", wpa_cli_cmd_get_network
, NULL
,
2503 "<network id> <variable> = get network variables" },
2504 { "list_creds", wpa_cli_cmd_list_creds
, NULL
,
2506 "= list configured credentials" },
2507 { "add_cred", wpa_cli_cmd_add_cred
, NULL
,
2509 "= add a credential" },
2510 { "remove_cred", wpa_cli_cmd_remove_cred
, NULL
,
2512 "<cred id> = remove a credential" },
2513 { "set_cred", wpa_cli_cmd_set_cred
, NULL
,
2514 cli_cmd_flag_sensitive
,
2515 "<cred id> <variable> <value> = set credential variables" },
2516 { "save_config", wpa_cli_cmd_save_config
, NULL
,
2518 "= save the current configuration" },
2519 { "disconnect", wpa_cli_cmd_disconnect
, NULL
,
2521 "= disconnect and wait for reassociate/reconnect command before\n"
2523 { "reconnect", wpa_cli_cmd_reconnect
, NULL
,
2525 "= like reassociate, but only takes effect if already disconnected"
2527 { "scan", wpa_cli_cmd_scan
, NULL
,
2529 "= request new BSS scan" },
2530 { "scan_results", wpa_cli_cmd_scan_results
, NULL
,
2532 "= get latest scan results" },
2533 { "bss", wpa_cli_cmd_bss
, wpa_cli_complete_bss
,
2535 "<<idx> | <bssid>> = get detailed scan result info" },
2536 { "get_capability", wpa_cli_cmd_get_capability
, NULL
,
2538 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2539 "= get capabilies" },
2540 { "reconfigure", wpa_cli_cmd_reconfigure
, NULL
,
2542 "= force wpa_supplicant to re-read its configuration file" },
2543 { "terminate", wpa_cli_cmd_terminate
, NULL
,
2545 "= terminate wpa_supplicant" },
2546 { "interface_add", wpa_cli_cmd_interface_add
, NULL
,
2548 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2549 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2551 { "interface_remove", wpa_cli_cmd_interface_remove
, NULL
,
2553 "<ifname> = removes the interface" },
2554 { "interface_list", wpa_cli_cmd_interface_list
, NULL
,
2556 "= list available interfaces" },
2557 { "ap_scan", wpa_cli_cmd_ap_scan
, NULL
,
2559 "<value> = set ap_scan parameter" },
2560 { "scan_interval", wpa_cli_cmd_scan_interval
, NULL
,
2562 "<value> = set scan_interval parameter (in seconds)" },
2563 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
, NULL
,
2565 "<value> = set BSS expiration age parameter" },
2566 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
, NULL
,
2568 "<value> = set BSS expiration scan count parameter" },
2569 { "bss_flush", wpa_cli_cmd_bss_flush
, NULL
,
2571 "<value> = set BSS flush age (0 by default)" },
2572 { "stkstart", wpa_cli_cmd_stkstart
, NULL
,
2574 "<addr> = request STK negotiation with <addr>" },
2575 { "ft_ds", wpa_cli_cmd_ft_ds
, wpa_cli_complete_bss
,
2577 "<addr> = request over-the-DS FT with <addr>" },
2578 { "wps_pbc", wpa_cli_cmd_wps_pbc
, wpa_cli_complete_bss
,
2580 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2581 { "wps_pin", wpa_cli_cmd_wps_pin
, wpa_cli_complete_bss
,
2582 cli_cmd_flag_sensitive
,
2583 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2585 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
, NULL
,
2586 cli_cmd_flag_sensitive
,
2587 "<PIN> = verify PIN checksum" },
2588 { "wps_cancel", wpa_cli_cmd_wps_cancel
, NULL
, cli_cmd_flag_none
,
2589 "Cancels the pending WPS operation" },
2590 #ifdef CONFIG_WPS_NFC
2591 { "wps_nfc", wpa_cli_cmd_wps_nfc
, wpa_cli_complete_bss
,
2593 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2594 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token
, NULL
,
2596 "<WPS|NDEF> = build configuration token" },
2597 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token
, NULL
,
2599 "<WPS|NDEF> = create password token" },
2600 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read
, NULL
,
2601 cli_cmd_flag_sensitive
,
2602 "<hexdump of payload> = report read NFC tag with WPS data" },
2603 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req
, NULL
,
2605 "<NDEF> <WPS> = create NFC handover request" },
2606 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel
, NULL
,
2608 "<NDEF> <WPS> = create NFC handover select" },
2609 { "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req
, NULL
,
2611 "<hexdump of payload> = report received NFC handover request" },
2612 { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel
, NULL
,
2614 "<hexdump of payload> = report received NFC handover select" },
2615 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover
, NULL
,
2617 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2619 #endif /* CONFIG_WPS_NFC */
2620 { "wps_reg", wpa_cli_cmd_wps_reg
, wpa_cli_complete_bss
,
2621 cli_cmd_flag_sensitive
,
2622 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2623 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
, NULL
,
2624 cli_cmd_flag_sensitive
,
2625 "[params..] = enable/disable AP PIN" },
2626 { "wps_er_start", wpa_cli_cmd_wps_er_start
, NULL
,
2628 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2629 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
, NULL
,
2631 "= stop Wi-Fi Protected Setup External Registrar" },
2632 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
, NULL
,
2633 cli_cmd_flag_sensitive
,
2634 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2635 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
, NULL
,
2637 "<UUID> = accept an Enrollee PBC using External Registrar" },
2638 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
, NULL
,
2639 cli_cmd_flag_sensitive
,
2640 "<UUID> <PIN> = learn AP configuration" },
2641 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
, NULL
,
2643 "<UUID> <network id> = set AP configuration for enrolling" },
2644 { "wps_er_config", wpa_cli_cmd_wps_er_config
, NULL
,
2645 cli_cmd_flag_sensitive
,
2646 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2647 #ifdef CONFIG_WPS_NFC
2648 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token
, NULL
,
2650 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2651 #endif /* CONFIG_WPS_NFC */
2652 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
, NULL
,
2654 "<addr> = request RSN authentication with <addr> in IBSS" },
2656 { "sta", wpa_cli_cmd_sta
, NULL
,
2658 "<addr> = get information about an associated station (AP)" },
2659 { "all_sta", wpa_cli_cmd_all_sta
, NULL
,
2661 "= get information about all associated stations (AP)" },
2662 { "deauthenticate", wpa_cli_cmd_deauthenticate
, NULL
,
2664 "<addr> = deauthenticate a station" },
2665 { "disassociate", wpa_cli_cmd_disassociate
, NULL
,
2667 "<addr> = disassociate a station" },
2668 #endif /* CONFIG_AP */
2669 { "suspend", wpa_cli_cmd_suspend
, NULL
, cli_cmd_flag_none
,
2670 "= notification of suspend/hibernate" },
2671 { "resume", wpa_cli_cmd_resume
, NULL
, cli_cmd_flag_none
,
2672 "= notification of resume/thaw" },
2673 { "drop_sa", wpa_cli_cmd_drop_sa
, NULL
, cli_cmd_flag_none
,
2674 "= drop SA without deauth/disassoc (test command)" },
2675 { "roam", wpa_cli_cmd_roam
, wpa_cli_complete_bss
,
2677 "<addr> = roam to the specified BSS" },
2679 { "p2p_find", wpa_cli_cmd_p2p_find
, wpa_cli_complete_p2p_find
,
2681 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2682 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, NULL
, cli_cmd_flag_none
,
2683 "= stop P2P Devices search" },
2684 { "p2p_connect", wpa_cli_cmd_p2p_connect
, wpa_cli_complete_p2p_connect
,
2686 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2687 { "p2p_listen", wpa_cli_cmd_p2p_listen
, NULL
, cli_cmd_flag_none
,
2688 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2689 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
,
2690 wpa_cli_complete_p2p_group_remove
, cli_cmd_flag_none
,
2691 "<ifname> = remove P2P group interface (terminate group if GO)" },
2692 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, NULL
, cli_cmd_flag_none
,
2693 "[ht40] = add a new P2P group (local end as GO)" },
2694 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
,
2695 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2696 "<addr> <method> = request provisioning discovery" },
2697 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
, NULL
,
2699 "= get the passphrase for a group (GO only)" },
2700 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2701 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2702 "<addr> <TLVs> = schedule service discovery request" },
2703 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2704 NULL
, cli_cmd_flag_none
,
2705 "<id> = cancel pending service discovery request" },
2706 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
, NULL
,
2708 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2709 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
, NULL
,
2711 "= indicate change in local services" },
2712 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
, NULL
,
2714 "<external> = set external processing of service discovery" },
2715 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
, NULL
,
2717 "= remove all stored service entries" },
2718 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
, NULL
,
2720 "<bonjour|upnp> <query|version> <response|service> = add a local "
2722 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
, NULL
,
2724 "<bonjour|upnp> <query|version> [|service] = remove a local "
2726 { "p2p_reject", wpa_cli_cmd_p2p_reject
, wpa_cli_complete_p2p_peer
,
2728 "<addr> = reject connection attempts from a specific peer" },
2729 { "p2p_invite", wpa_cli_cmd_p2p_invite
, NULL
,
2731 "<cmd> [peer=addr] = invite peer" },
2732 { "p2p_peers", wpa_cli_cmd_p2p_peers
, NULL
, cli_cmd_flag_none
,
2733 "[discovered] = list known (optionally, only fully discovered) P2P "
2735 { "p2p_peer", wpa_cli_cmd_p2p_peer
, wpa_cli_complete_p2p_peer
,
2737 "<address> = show information about known P2P peer" },
2738 { "p2p_set", wpa_cli_cmd_p2p_set
, wpa_cli_complete_p2p_set
,
2740 "<field> <value> = set a P2P parameter" },
2741 { "p2p_flush", wpa_cli_cmd_p2p_flush
, NULL
, cli_cmd_flag_none
,
2742 "= flush P2P state" },
2743 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, NULL
, cli_cmd_flag_none
,
2744 "= cancel P2P group formation" },
2745 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
,
2746 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2747 "<address> = unauthorize a peer" },
2748 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, NULL
,
2750 "[<duration> <interval>] [<duration> <interval>] = request GO "
2752 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, NULL
,
2754 "[<period> <interval>] = set extended listen timing" },
2755 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client
,
2756 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2757 "<address|iface=address> = remove a peer from all groups" },
2758 #endif /* CONFIG_P2P */
2759 #ifdef CONFIG_WIFI_DISPLAY
2760 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set
, NULL
,
2762 "<subelem> [contents] = set Wi-Fi Display subelement" },
2763 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get
, NULL
,
2765 "<subelem> = get Wi-Fi Display subelement" },
2766 #endif /* CONFIG_WIFI_DISPLAY */
2767 #ifdef CONFIG_INTERWORKING
2768 { "fetch_anqp", wpa_cli_cmd_fetch_anqp
, NULL
, cli_cmd_flag_none
,
2769 "= fetch ANQP information for all APs" },
2770 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp
, NULL
,
2772 "= stop fetch_anqp operation" },
2773 { "interworking_select", wpa_cli_cmd_interworking_select
, NULL
,
2775 "[auto] = perform Interworking network selection" },
2776 { "interworking_connect", wpa_cli_cmd_interworking_connect
,
2777 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2778 "<BSSID> = connect using Interworking credentials" },
2779 { "anqp_get", wpa_cli_cmd_anqp_get
, wpa_cli_complete_bss
,
2781 "<addr> <info id>[,<info id>]... = request ANQP information" },
2782 { "gas_request", wpa_cli_cmd_gas_request
, wpa_cli_complete_bss
,
2784 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2785 { "gas_response_get", wpa_cli_cmd_gas_response_get
,
2786 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2787 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2788 #endif /* CONFIG_INTERWORKING */
2790 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get
, wpa_cli_complete_bss
,
2792 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2794 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list
,
2795 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2796 "<addr> <home realm> = get HS20 nai home realm list" },
2797 #endif /* CONFIG_HS20 */
2798 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, NULL
,
2800 "<0/1> = disable/enable automatic reconnection" },
2801 { "tdls_discover", wpa_cli_cmd_tdls_discover
, NULL
,
2803 "<addr> = request TDLS discovery with <addr>" },
2804 { "tdls_setup", wpa_cli_cmd_tdls_setup
, NULL
,
2806 "<addr> = request TDLS setup with <addr>" },
2807 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
, NULL
,
2809 "<addr> = tear down TDLS with <addr>" },
2810 { "signal_poll", wpa_cli_cmd_signal_poll
, NULL
,
2812 "= get signal parameters" },
2813 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll
, NULL
,
2815 "= get TX/RX packet counters" },
2816 { "reauthenticate", wpa_cli_cmd_reauthenticate
, NULL
,
2818 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2819 #ifdef CONFIG_AUTOSCAN
2820 { "autoscan", wpa_cli_cmd_autoscan
, NULL
, cli_cmd_flag_none
,
2821 "[params] = Set or unset (if none) autoscan parameters" },
2822 #endif /* CONFIG_AUTOSCAN */
2824 { "wnm_sleep", wpa_cli_cmd_wnm_sleep
, NULL
, cli_cmd_flag_none
,
2825 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
2826 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query
, NULL
, cli_cmd_flag_none
,
2827 "<query reason> = Send BSS Transition Management Query" },
2828 #endif /* CONFIG_WNM */
2829 { "raw", wpa_cli_cmd_raw
, NULL
, cli_cmd_flag_sensitive
,
2830 "<params..> = Sent unprocessed command" },
2831 { "flush", wpa_cli_cmd_flush
, NULL
, cli_cmd_flag_none
,
2832 "= flush wpa_supplicant state" },
2833 { NULL
, NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2838 * Prints command usage, lines are padded with the specified string.
2840 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2845 printf("%s%s ", pad
, cmd
->cmd
);
2846 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2855 static void print_help(const char *cmd
)
2858 printf("commands:\n");
2859 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++) {
2860 if (cmd
== NULL
|| str_starts(wpa_cli_commands
[n
].cmd
, cmd
))
2861 print_cmd_help(&wpa_cli_commands
[n
], " ");
2866 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
2868 const char *c
, *delim
;
2872 delim
= os_strchr(cmd
, ' ');
2876 len
= os_strlen(cmd
);
2878 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2879 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2880 return (wpa_cli_commands
[n
].flags
&
2881 cli_cmd_flag_sensitive
);
2887 static char ** wpa_list_cmd_list(void)
2891 struct cli_txt_entry
*e
;
2893 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
2894 count
+= dl_list_len(&p2p_groups
);
2895 count
+= dl_list_len(&ifnames
);
2896 res
= os_calloc(count
+ 1, sizeof(char *));
2900 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2901 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
2906 dl_list_for_each(e
, &p2p_groups
, struct cli_txt_entry
, list
) {
2907 size_t len
= 8 + os_strlen(e
->txt
);
2908 res
[i
] = os_malloc(len
);
2911 os_snprintf(res
[i
], len
, "ifname=%s", e
->txt
);
2915 dl_list_for_each(e
, &ifnames
, struct cli_txt_entry
, list
) {
2916 res
[i
] = os_strdup(e
->txt
);
2926 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
2931 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2932 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
2933 if (wpa_cli_commands
[i
].completion
)
2934 return wpa_cli_commands
[i
].completion(str
,
2937 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
2947 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
2953 if (pos
> 7 && os_strncasecmp(str
, "IFNAME=", 7) == 0) {
2954 end
= os_strchr(str
, ' ');
2955 if (end
&& pos
> end
- str
) {
2956 pos
-= end
- str
+ 1;
2961 end
= os_strchr(str
, ' ');
2962 if (end
== NULL
|| str
+ pos
< end
)
2963 return wpa_list_cmd_list();
2965 cmd
= os_malloc(pos
+ 1);
2968 os_memcpy(cmd
, str
, pos
);
2969 cmd
[end
- str
] = '\0';
2970 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
2976 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2978 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2982 if (argc
> 1 && os_strncasecmp(argv
[0], "IFNAME=", 7) == 0) {
2983 ifname_prefix
= argv
[0] + 7;
2987 ifname_prefix
= NULL
;
2993 cmd
= wpa_cli_commands
;
2995 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2998 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2999 /* we have an exact match */
3009 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
3010 cmd
= wpa_cli_commands
;
3012 if (os_strncasecmp(cmd
->cmd
, argv
[0],
3013 os_strlen(argv
[0])) == 0) {
3014 printf(" %s", cmd
->cmd
);
3020 } else if (count
== 0) {
3021 printf("Unknown command '%s'\n", argv
[0]);
3024 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
3031 static int str_match(const char *a
, const char *b
)
3033 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
3037 static int wpa_cli_exec(const char *program
, const char *arg1
,
3045 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
3046 cmd
= os_malloc(len
);
3049 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
3050 if (res
< 0 || (size_t) res
>= len
) {
3054 cmd
[len
- 1] = '\0';
3056 if (system(cmd
) < 0)
3058 #endif /* _WIN32_WCE */
3065 static void wpa_cli_action_process(const char *msg
)
3068 char *copy
= NULL
, *id
, *pos2
;
3073 pos
= os_strchr(pos
, '>');
3080 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
3082 os_unsetenv("WPA_ID");
3083 os_unsetenv("WPA_ID_STR");
3084 os_unsetenv("WPA_CTRL_DIR");
3086 pos
= os_strstr(pos
, "[id=");
3088 copy
= os_strdup(pos
+ 4);
3092 while (*pos2
&& *pos2
!= ' ')
3096 os_setenv("WPA_ID", id
, 1);
3097 while (*pos2
&& *pos2
!= '=')
3102 while (*pos2
&& *pos2
!= ']')
3105 os_setenv("WPA_ID_STR", id
, 1);
3109 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
3111 if (wpa_cli_connected
<= 0 || new_id
!= wpa_cli_last_id
) {
3112 wpa_cli_connected
= 1;
3113 wpa_cli_last_id
= new_id
;
3114 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
3116 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
3117 if (wpa_cli_connected
) {
3118 wpa_cli_connected
= 0;
3119 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
3121 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
3122 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3123 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
3124 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3125 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
3126 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3127 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
3128 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3129 } else if (str_match(pos
, P2P_EVENT_GO_NEG_FAILURE
)) {
3130 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3131 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
3132 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3133 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
3134 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3135 } else if (str_match(pos
, AP_STA_CONNECTED
)) {
3136 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3137 } else if (str_match(pos
, AP_STA_DISCONNECTED
)) {
3138 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3139 } else if (str_match(pos
, ESS_DISASSOC_IMMINENT
)) {
3140 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3141 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
3142 printf("wpa_supplicant is terminating - stop monitoring\n");
3148 #ifndef CONFIG_ANSI_C_EXTRA
3149 static void wpa_cli_action_cb(char *msg
, size_t len
)
3151 wpa_cli_action_process(msg
);
3153 #endif /* CONFIG_ANSI_C_EXTRA */
3156 static void wpa_cli_reconnect(void)
3158 wpa_cli_close_connection();
3159 if (wpa_cli_open_connection(ctrl_ifname
, 1) < 0)
3164 printf("\rConnection to wpa_supplicant re-established\n");
3170 static void cli_event(const char *str
)
3172 const char *start
, *s
;
3174 start
= os_strchr(str
, '>');
3180 if (str_starts(start
, WPA_EVENT_BSS_ADDED
)) {
3181 s
= os_strchr(start
, ' ');
3184 s
= os_strchr(s
+ 1, ' ');
3187 cli_txt_list_add(&bsses
, s
+ 1);
3191 if (str_starts(start
, WPA_EVENT_BSS_REMOVED
)) {
3192 s
= os_strchr(start
, ' ');
3195 s
= os_strchr(s
+ 1, ' ');
3198 cli_txt_list_del_addr(&bsses
, s
+ 1);
3203 if (str_starts(start
, P2P_EVENT_DEVICE_FOUND
)) {
3204 s
= os_strstr(start
, " p2p_dev_addr=");
3207 cli_txt_list_add_addr(&p2p_peers
, s
+ 14);
3211 if (str_starts(start
, P2P_EVENT_DEVICE_LOST
)) {
3212 s
= os_strstr(start
, " p2p_dev_addr=");
3215 cli_txt_list_del_addr(&p2p_peers
, s
+ 14);
3219 if (str_starts(start
, P2P_EVENT_GROUP_STARTED
)) {
3220 s
= os_strchr(start
, ' ');
3223 cli_txt_list_add_word(&p2p_groups
, s
+ 1);
3227 if (str_starts(start
, P2P_EVENT_GROUP_REMOVED
)) {
3228 s
= os_strchr(start
, ' ');
3231 cli_txt_list_del_word(&p2p_groups
, s
+ 1);
3234 #endif /* CONFIG_P2P */
3238 static int check_terminating(const char *msg
)
3240 const char *pos
= msg
;
3244 pos
= os_strchr(pos
, '>');
3251 if (str_match(pos
, WPA_EVENT_TERMINATING
) && ctrl_conn
) {
3253 printf("\rConnection to wpa_supplicant lost - trying to "
3256 wpa_cli_attached
= 0;
3257 wpa_cli_close_connection();
3265 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
3267 if (ctrl_conn
== NULL
) {
3268 wpa_cli_reconnect();
3271 while (wpa_ctrl_pending(ctrl
) > 0) {
3273 size_t len
= sizeof(buf
) - 1;
3274 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
3277 wpa_cli_action_process(buf
);
3280 if (wpa_cli_show_event(buf
)) {
3282 printf("\r%s\n", buf
);
3286 if (interactive
&& check_terminating(buf
) > 0)
3290 printf("Could not read pending message.\n");
3295 if (wpa_ctrl_pending(ctrl
) < 0) {
3296 printf("Connection to wpa_supplicant lost - trying to "
3298 wpa_cli_reconnect();
3304 static int tokenize_cmd(char *cmd
, char *argv
[])
3317 if (argc
== max_args
)
3320 char *pos2
= os_strrchr(pos
, '"');
3324 while (*pos
!= '\0' && *pos
!= ' ')
3334 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
3336 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3337 printf("Connection to wpa_supplicant lost - trying to "
3339 wpa_cli_close_connection();
3342 wpa_cli_reconnect();
3343 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3347 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
3349 wpa_cli_recv_pending(mon_conn
, 0);
3353 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
3355 char *argv
[max_args
];
3357 argc
= tokenize_cmd(cmd
, argv
);
3359 wpa_request(ctrl_conn
, argc
, argv
);
3363 static void wpa_cli_edit_eof_cb(void *ctx
)
3369 static int warning_displayed
= 0;
3370 static char *hfile
= NULL
;
3371 static int edit_started
= 0;
3373 static void start_edit(void)
3378 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3379 ps
= wpa_ctrl_get_remote_ifname(ctrl_conn
);
3380 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3382 home
= getenv("HOME");
3384 const char *fname
= ".wpa_cli_history";
3385 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
3386 hfile
= os_malloc(hfile_len
);
3388 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
3391 if (edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
3392 wpa_cli_edit_completion_cb
, NULL
, hfile
, ps
) < 0) {
3398 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3402 static void update_bssid_list(struct wpa_ctrl
*ctrl
)
3405 size_t len
= sizeof(buf
);
3407 char *cmd
= "BSS RANGE=ALL MASK=0x2";
3412 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
, NULL
);
3419 pos
= os_strstr(pos
, "bssid=");
3423 end
= os_strchr(pos
, '\n');
3427 cli_txt_list_add(&bsses
, pos
);
3433 static void update_ifnames(struct wpa_ctrl
*ctrl
)
3436 size_t len
= sizeof(buf
);
3438 char *cmd
= "INTERFACES";
3442 cli_txt_list_flush(&ifnames
);
3446 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
, NULL
);
3453 end
= os_strchr(pos
, '\n');
3457 ret
= os_snprintf(txt
, sizeof(txt
), "ifname=%s", pos
);
3458 if (ret
> 0 && ret
< (int) sizeof(txt
))
3459 cli_txt_list_add(&ifnames
, txt
);
3465 static void try_connection(void *eloop_ctx
, void *timeout_ctx
)
3470 if (ctrl_ifname
== NULL
)
3471 ctrl_ifname
= wpa_cli_get_default_ifname();
3473 if (!wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3474 if (!warning_displayed
) {
3475 printf("Could not connect to wpa_supplicant: "
3476 "%s - re-trying\n", ctrl_ifname
);
3477 warning_displayed
= 1;
3479 eloop_register_timeout(1, 0, try_connection
, NULL
, NULL
);
3483 update_bssid_list(ctrl_conn
);
3485 if (warning_displayed
)
3486 printf("Connection established.\n");
3493 static void wpa_cli_interactive(void)
3495 printf("\nInteractive mode\n\n");
3497 eloop_register_timeout(0, 0, try_connection
, NULL
, NULL
);
3499 eloop_cancel_timeout(try_connection
, NULL
, NULL
);
3501 cli_txt_list_flush(&p2p_peers
);
3502 cli_txt_list_flush(&p2p_groups
);
3503 cli_txt_list_flush(&bsses
);
3504 cli_txt_list_flush(&ifnames
);
3506 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3508 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3509 wpa_cli_close_connection();
3513 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3515 #ifdef CONFIG_ANSI_C_EXTRA
3516 /* TODO: ANSI C version(?) */
3517 printf("Action processing not supported in ANSI C build.\n");
3518 #else /* CONFIG_ANSI_C_EXTRA */
3522 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3525 fd
= wpa_ctrl_get_fd(ctrl
);
3527 while (!wpa_cli_quit
) {
3530 tv
.tv_sec
= ping_interval
;
3532 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3533 if (res
< 0 && errno
!= EINTR
) {
3538 if (FD_ISSET(fd
, &rfds
))
3539 wpa_cli_recv_pending(ctrl
, 1);
3541 /* verify that connection is still working */
3542 len
= sizeof(buf
) - 1;
3543 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3544 wpa_cli_action_cb
) < 0 ||
3545 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3546 printf("wpa_supplicant did not reply to PING "
3547 "command - exiting\n");
3552 #endif /* CONFIG_ANSI_C_EXTRA */
3556 static void wpa_cli_cleanup(void)
3558 wpa_cli_close_connection();
3560 os_daemonize_terminate(pid_file
);
3562 os_program_deinit();
3566 static void wpa_cli_terminate(int sig
, void *ctx
)
3572 static char * wpa_cli_get_default_ifname(void)
3574 char *ifname
= NULL
;
3576 #ifdef CONFIG_CTRL_IFACE_UNIX
3577 struct dirent
*dent
;
3578 DIR *dir
= opendir(ctrl_iface_dir
);
3581 char ifprop
[PROPERTY_VALUE_MAX
];
3582 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3583 ifname
= os_strdup(ifprop
);
3584 printf("Using interface '%s'\n", ifname
);
3587 #endif /* ANDROID */
3590 while ((dent
= readdir(dir
))) {
3591 #ifdef _DIRENT_HAVE_D_TYPE
3593 * Skip the file if it is not a socket. Also accept
3594 * DT_UNKNOWN (0) in case the C library or underlying
3595 * file system does not support d_type.
3597 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3599 #endif /* _DIRENT_HAVE_D_TYPE */
3600 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3601 os_strcmp(dent
->d_name
, "..") == 0)
3603 printf("Selected interface '%s'\n", dent
->d_name
);
3604 ifname
= os_strdup(dent
->d_name
);
3608 #endif /* CONFIG_CTRL_IFACE_UNIX */
3610 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3611 char buf
[4096], *pos
;
3613 struct wpa_ctrl
*ctrl
;
3616 ctrl
= wpa_ctrl_open(NULL
);
3620 len
= sizeof(buf
) - 1;
3621 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3624 pos
= os_strchr(buf
, '\n');
3627 ifname
= os_strdup(buf
);
3629 wpa_ctrl_close(ctrl
);
3630 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3636 int main(int argc
, char *argv
[])
3641 const char *global
= NULL
;
3643 if (os_program_init())
3647 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3652 action_file
= optarg
;
3661 ping_interval
= atoi(optarg
);
3667 printf("%s\n", wpa_cli_version
);
3670 os_free(ctrl_ifname
);
3671 ctrl_ifname
= os_strdup(optarg
);
3674 ctrl_iface_dir
= optarg
;
3685 interactive
= (argc
== optind
) && (action_file
== NULL
);
3688 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3694 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3695 ctrl_conn
= wpa_ctrl_open(NULL
);
3696 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3697 ctrl_conn
= wpa_ctrl_open(global
);
3698 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3699 if (ctrl_conn
== NULL
) {
3700 fprintf(stderr
, "Failed to connect to wpa_supplicant "
3701 "global interface: %s error: %s\n",
3702 global
, strerror(errno
));
3707 update_ifnames(ctrl_conn
);
3708 mon_conn
= wpa_ctrl_open(global
);
3710 if (wpa_ctrl_attach(mon_conn
) == 0) {
3711 wpa_cli_attached
= 1;
3712 eloop_register_read_sock(
3713 wpa_ctrl_get_fd(mon_conn
),
3714 wpa_cli_mon_receive
,
3717 printf("Failed to open monitor "
3718 "connection through global "
3719 "control interface\n");
3725 eloop_register_signal_terminate(wpa_cli_terminate
, NULL
);
3727 if (ctrl_ifname
== NULL
)
3728 ctrl_ifname
= wpa_cli_get_default_ifname();
3731 wpa_cli_interactive();
3734 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3735 fprintf(stderr
, "Failed to connect to non-global "
3736 "ctrl_ifname: %s error: %s\n",
3737 ctrl_ifname
, strerror(errno
));
3742 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3743 wpa_cli_attached
= 1;
3745 printf("Warning: Failed to attach to "
3746 "wpa_supplicant.\n");
3751 if (daemonize
&& os_daemonize(pid_file
))
3755 wpa_cli_action(ctrl_conn
);
3757 ret
= wpa_request(ctrl_conn
, argc
- optind
,
3761 os_free(ctrl_ifname
);
3768 #else /* CONFIG_CTRL_IFACE */
3769 int main(int argc
, char *argv
[])
3771 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3774 #endif /* CONFIG_CTRL_IFACE */