2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2015, 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 *const wpa_cli_version =
30 "wpa_cli v" VERSION_STR "\n"
31 "Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> and contributors";
34 static const char *const 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 *const 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 */
95 static DEFINE_DL_LIST(networks); /* struct cli_txt_entry */
98 static void print_help(const char *cmd);
99 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
100 static void wpa_cli_close_connection(void);
101 static char * wpa_cli_get_default_ifname(void);
102 static char ** wpa_list_cmd_list(void);
103 static void update_networks(struct wpa_ctrl *ctrl);
106 static void usage(void)
108 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
109 "[-a<action file>] \\\n"
110 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
112 " -h = help (show this usage text)\n"
113 " -v = shown version information\n"
114 " -a = run in daemon mode executing the action file based on "
117 " -B = run a daemon in the background\n"
118 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
119 " default interface: first interface found in socket path\n");
124 static void cli_txt_list_free(struct cli_txt_entry *e)
126 dl_list_del(&e->list);
132 static void cli_txt_list_flush(struct dl_list *list)
134 struct cli_txt_entry *e;
135 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
136 cli_txt_list_free(e);
140 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
143 struct cli_txt_entry *e;
144 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
145 if (os_strcmp(e->txt, txt) == 0)
152 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
154 struct cli_txt_entry *e;
155 e = cli_txt_list_get(txt_list, txt);
157 cli_txt_list_free(e);
161 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
165 if (hwaddr_aton(txt, addr) < 0)
167 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
168 cli_txt_list_del(txt_list, buf);
173 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt,
178 end = os_strchr(txt, separator);
180 end = txt + os_strlen(txt);
181 buf = dup_binstr(txt, end - txt);
184 cli_txt_list_del(txt_list, buf);
187 #endif /* CONFIG_P2P */
190 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
192 struct cli_txt_entry *e;
193 e = cli_txt_list_get(txt_list, txt);
196 e = os_zalloc(sizeof(*e));
199 e->txt = os_strdup(txt);
200 if (e->txt == NULL) {
204 dl_list_add(txt_list, &e->list);
210 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
214 if (hwaddr_aton(txt, addr) < 0)
216 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
217 return cli_txt_list_add(txt_list, buf);
219 #endif /* CONFIG_P2P */
222 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt,
228 end = os_strchr(txt, separator);
230 end = txt + os_strlen(txt);
231 buf = dup_binstr(txt, end - txt);
234 ret = cli_txt_list_add(txt_list, buf);
240 static char ** cli_txt_list_array(struct dl_list *txt_list)
242 unsigned int i, count = dl_list_len(txt_list);
244 struct cli_txt_entry *e;
246 res = os_calloc(count + 1, sizeof(char *));
251 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
252 res[i] = os_strdup(e->txt);
262 static int get_cmd_arg_num(const char *str, int pos)
266 for (i = 0; i <= pos; i++) {
269 while (i <= pos && str[i] != ' ')
280 static int str_starts(const char *src, const char *match)
282 return os_strncmp(src, match, os_strlen(match)) == 0;
286 static int wpa_cli_show_event(const char *event)
290 start = os_strchr(event, '>');
296 * Skip BSS added/removed events since they can be relatively frequent
297 * and are likely of not much use for an interactive user.
299 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
300 str_starts(start, WPA_EVENT_BSS_REMOVED))
307 static int wpa_cli_open_connection(const char *ifname, int attach)
309 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
310 ctrl_conn = wpa_ctrl_open(ifname);
311 if (ctrl_conn == NULL)
314 if (attach && interactive)
315 mon_conn = wpa_ctrl_open(ifname);
318 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
326 if (access(ctrl_iface_dir, F_OK) < 0) {
327 cfile = os_strdup(ifname);
334 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
335 cfile = os_malloc(flen);
338 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
340 if (os_snprintf_error(flen, res)) {
346 ctrl_conn = wpa_ctrl_open(cfile);
347 if (ctrl_conn == NULL) {
352 if (attach && interactive)
353 mon_conn = wpa_ctrl_open(cfile);
357 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
360 if (wpa_ctrl_attach(mon_conn) == 0) {
361 wpa_cli_attached = 1;
363 eloop_register_read_sock(
364 wpa_ctrl_get_fd(mon_conn),
365 wpa_cli_mon_receive, NULL, NULL);
367 printf("Warning: Failed to attach to "
368 "wpa_supplicant.\n");
369 wpa_cli_close_connection();
378 static void wpa_cli_close_connection(void)
380 if (ctrl_conn == NULL)
383 if (wpa_cli_attached) {
384 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
385 wpa_cli_attached = 0;
387 wpa_ctrl_close(ctrl_conn);
390 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
391 wpa_ctrl_close(mon_conn);
397 static void wpa_cli_msg_cb(char *msg, size_t len)
403 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
409 if (ctrl_conn == NULL) {
410 printf("Not connected to wpa_supplicant - command dropped.\n");
414 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
416 buf[sizeof(buf) - 1] = '\0';
419 len = sizeof(buf) - 1;
420 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
423 printf("'%s' command timed out.\n", cmd);
425 } else if (ret < 0) {
426 printf("'%s' command failed.\n", cmd);
432 if (interactive && len > 0 && buf[len - 1] != '\n')
439 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
441 return _wpa_ctrl_command(ctrl, cmd, 1);
445 static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
454 res = os_snprintf(pos, end - pos, "%s", cmd);
455 if (os_snprintf_error(end - pos, res))
459 for (i = 0; i < argc; i++) {
460 res = os_snprintf(pos, end - pos, " %s", argv[i]);
461 if (os_snprintf_error(end - pos, res))
466 buf[buflen - 1] = '\0';
470 printf("Too long command\n");
475 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
476 int argc, char *argv[])
479 if (argc < min_args) {
480 printf("Invalid %s command - at least %d argument%s "
481 "required.\n", cmd, min_args,
482 min_args > 1 ? "s are" : " is");
485 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
487 return wpa_ctrl_command(ctrl, buf);
491 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
493 return wpa_ctrl_command(ctrl, "IFNAME");
497 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
499 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
500 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
501 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
502 return wpa_ctrl_command(ctrl, "STATUS-WPS");
503 if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
504 return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
506 if (argc > 0 && os_strcmp(argv[0], "no_events") == 0)
507 return wpa_ctrl_command(ctrl, "STATUS-NO_EVENTS");
509 return wpa_ctrl_command(ctrl, "STATUS");
513 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
515 return wpa_ctrl_command(ctrl, "PING");
519 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
521 return wpa_ctrl_command(ctrl, "RELOG");
525 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
527 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
531 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
533 return wpa_ctrl_command(ctrl, "MIB");
537 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
539 return wpa_ctrl_command(ctrl, "PMKSA");
543 static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc,
546 return wpa_ctrl_command(ctrl, "PMKSA_FLUSH");
550 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
552 print_help(argc > 0 ? argv[0] : NULL);
557 static char ** wpa_cli_complete_help(const char *str, int pos)
559 int arg = get_cmd_arg_num(str, pos);
564 res = wpa_list_cmd_list();
572 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
574 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
579 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
588 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
594 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
595 if (os_snprintf_error(sizeof(cmd), res)) {
596 printf("Too long SET command.\n");
599 return wpa_ctrl_command(ctrl, cmd);
602 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
606 static char ** wpa_cli_complete_set(const char *str, int pos)
608 int arg = get_cmd_arg_num(str, pos);
609 const char *fields[] = {
611 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
612 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
613 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
614 "wps_fragment_size", "wps_version_number", "ampdu",
615 "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
616 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
618 /* global configuration parameters */
619 #ifdef CONFIG_CTRL_IFACE
620 "ctrl_interface", "no_ctrl_interface", "ctrl_interface_group",
621 #endif /* CONFIG_CTRL_IFACE */
622 "eapol_version", "ap_scan", "bgscan",
624 "user_mpm", "max_peer_links", "mesh_max_inactivity",
625 "dot11RSNASAERetransPeriod",
626 #endif /* CONFIG_MESH */
627 "disable_scan_offload", "fast_reauth", "opensc_engine_path",
628 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
629 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
630 "dot11RSNAConfigPMKLifetime",
631 "dot11RSNAConfigPMKReauthThreshold",
632 "dot11RSNAConfigSATimeout",
633 #ifndef CONFIG_NO_CONFIG_WRITE
635 #endif /* CONFIG_NO_CONFIG_WRITE */
638 "uuid", "device_name", "manufacturer", "model_name",
639 "model_number", "serial_number", "device_type", "os_version",
640 "config_methods", "wps_cred_processing", "wps_vendor_ext_m1",
641 #endif /* CONFIG_WPS */
644 "p2p_listen_reg_class", "p2p_listen_channel",
645 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
646 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
647 "p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan",
648 "p2p_no_go_freq", "p2p_add_cli_chan",
649 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
650 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
651 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
652 "ip_addr_start", "ip_addr_end",
653 #endif /* CONFIG_P2P */
654 "country", "bss_max_count", "bss_expiration_age",
655 "bss_expiration_scan_count", "filter_ssids", "filter_rssi",
656 "max_num_sta", "disassoc_low_ack",
659 #endif /* CONFIG_HS20 */
660 "interworking", "hessid", "access_network_type", "pbc_in_m1",
661 "autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey",
662 "wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend",
663 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
664 "sae_groups", "dtim_period", "beacon_int",
665 "ap_vendor_elements", "ignore_old_scan_res", "freq_list",
666 "scan_cur_freq", "sched_scan_interval",
667 "tdls_external_control", "osu_dir", "wowlan_triggers",
668 "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
669 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
670 "reassoc_same_bss_optim", "wps_priority"
672 int i, num_fields = ARRAY_SIZE(fields);
675 char **res = os_calloc(num_fields + 1, sizeof(char *));
678 for (i = 0; i < num_fields; i++) {
679 res[i] = os_strdup(fields[i]);
686 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
687 return cli_txt_list_array(&bsses);
692 static int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[])
694 return wpa_ctrl_command(ctrl, "DUMP");
698 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
700 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
704 static char ** wpa_cli_complete_get(const char *str, int pos)
706 int arg = get_cmd_arg_num(str, pos);
707 const char *fields[] = {
708 #ifdef CONFIG_CTRL_IFACE
709 "ctrl_interface", "ctrl_interface_group",
710 #endif /* CONFIG_CTRL_IFACE */
711 "eapol_version", "ap_scan",
713 "user_mpm", "max_peer_links", "mesh_max_inactivity",
714 #endif /* CONFIG_MESH */
715 "disable_scan_offload", "fast_reauth", "opensc_engine_path",
716 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
717 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
718 "dot11RSNAConfigPMKLifetime",
719 "dot11RSNAConfigPMKReauthThreshold",
720 "dot11RSNAConfigSATimeout",
721 #ifndef CONFIG_NO_CONFIG_WRITE
723 #endif /* CONFIG_NO_CONFIG_WRITE */
725 "device_name", "manufacturer", "model_name", "model_number",
726 "serial_number", "config_methods", "wps_cred_processing",
727 #endif /* CONFIG_WPS */
729 "p2p_listen_reg_class", "p2p_listen_channel",
730 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
731 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
732 "p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan",
733 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
734 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
735 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
736 "ip_addr_start", "ip_addr_end",
737 #endif /* CONFIG_P2P */
738 "bss_max_count", "bss_expiration_age",
739 "bss_expiration_scan_count", "filter_ssids", "filter_rssi",
740 "max_num_sta", "disassoc_low_ack",
743 #endif /* CONFIG_HS20 */
744 "interworking", "access_network_type", "pbc_in_m1", "autoscan",
745 "wps_nfc_dev_pw_id", "ext_password_backend",
746 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
747 "dtim_period", "beacon_int", "ignore_old_scan_res",
748 "scan_cur_freq", "sched_scan_interval",
749 "tdls_external_control", "osu_dir", "wowlan_triggers",
750 "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
751 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
752 "reassoc_same_bss_optim"
754 int i, num_fields = ARRAY_SIZE(fields);
757 char **res = os_calloc(num_fields + 1, sizeof(char *));
760 for (i = 0; i < num_fields; i++) {
761 res[i] = os_strdup(fields[i]);
772 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
774 return wpa_ctrl_command(ctrl, "LOGOFF");
778 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
780 return wpa_ctrl_command(ctrl, "LOGON");
784 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
787 return wpa_ctrl_command(ctrl, "REASSOCIATE");
791 static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[])
793 return wpa_ctrl_command(ctrl, "REATTACH");
797 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
800 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
804 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
806 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
810 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
813 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
817 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
820 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
824 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
827 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
831 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
837 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
839 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
840 if (os_snprintf_error(sizeof(cmd), res)) {
841 printf("Too long BSS_FLUSH command.\n");
844 return wpa_ctrl_command(ctrl, cmd);
848 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
851 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
855 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
857 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
861 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
863 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
867 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
870 printf("Invalid WPS_PIN command: need one or two arguments:\n"
871 "- BSSID: use 'any' to select any\n"
872 "- PIN: optional, used only with devices that have no "
877 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
881 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
884 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
888 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
891 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
895 #ifdef CONFIG_WPS_NFC
897 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
899 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
903 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
906 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
910 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
913 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
917 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
925 printf("Invalid 'wps_nfc_tag_read' command - one argument "
930 buflen = 18 + os_strlen(argv[0]);
931 buf = os_malloc(buflen);
934 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
936 ret = wpa_ctrl_command(ctrl, buf);
943 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
946 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
950 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
953 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
957 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
960 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
963 #endif /* CONFIG_WPS_NFC */
966 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
972 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
974 else if (argc == 5 || argc == 6) {
975 char ssid_hex[2 * SSID_MAX_LEN + 1];
976 char key_hex[2 * 64 + 1];
980 for (i = 0; i < SSID_MAX_LEN; i++) {
981 if (argv[2][i] == '\0')
983 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
988 for (i = 0; i < 64; i++) {
989 if (argv[5][i] == '\0')
991 os_snprintf(&key_hex[i * 2], 3, "%02x",
996 res = os_snprintf(cmd, sizeof(cmd),
997 "WPS_REG %s %s %s %s %s %s",
998 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1001 printf("Invalid WPS_REG command: need two arguments:\n"
1002 "- BSSID of the target AP\n"
1004 printf("Alternatively, six arguments can be used to "
1005 "reconfigure the AP:\n"
1006 "- BSSID of the target AP\n"
1009 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1010 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1015 if (os_snprintf_error(sizeof(cmd), res)) {
1016 printf("Too long WPS_REG command.\n");
1019 return wpa_ctrl_command(ctrl, cmd);
1023 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
1026 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
1030 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
1033 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
1037 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
1040 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
1045 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
1049 printf("Invalid WPS_ER_PIN command: need at least two "
1051 "- UUID: use 'any' to select any\n"
1052 "- PIN: Enrollee PIN\n"
1053 "optional: - Enrollee MAC address\n");
1057 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
1061 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
1064 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
1068 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1072 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1073 "- UUID: specify which AP to use\n"
1078 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
1082 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1086 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1088 "- UUID: specify which AP to use\n"
1089 "- Network configuration id\n");
1093 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
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 * SSID_MAX_LEN + 1];
1105 char key_hex[2 * 64 + 1];
1109 for (i = 0; i < SSID_MAX_LEN; 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 (os_snprintf_error(sizeof(cmd), res)) {
1141 printf("Too long WPS_ER_CONFIG command.\n");
1144 return wpa_ctrl_command(ctrl, cmd);
1148 #ifdef CONFIG_WPS_NFC
1149 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1153 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1155 "- WPS/NDEF: token format\n"
1156 "- UUID: specify which AP to use\n");
1160 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1162 #endif /* CONFIG_WPS_NFC */
1165 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1167 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1171 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1173 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1177 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1179 char cmd[256], *pos, *end;
1183 printf("Invalid IDENTITY command: needs two arguments "
1184 "(network id and identity)\n");
1188 end = cmd + sizeof(cmd);
1190 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1192 if (os_snprintf_error(end - pos, ret)) {
1193 printf("Too long IDENTITY command.\n");
1197 for (i = 2; i < argc; i++) {
1198 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1199 if (os_snprintf_error(end - pos, ret)) {
1200 printf("Too long IDENTITY command.\n");
1206 return wpa_ctrl_command(ctrl, cmd);
1210 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1212 char cmd[256], *pos, *end;
1216 printf("Invalid PASSWORD command: needs two arguments "
1217 "(network id and password)\n");
1221 end = cmd + sizeof(cmd);
1223 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1225 if (os_snprintf_error(end - pos, ret)) {
1226 printf("Too long PASSWORD command.\n");
1230 for (i = 2; i < argc; i++) {
1231 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1232 if (os_snprintf_error(end - pos, ret)) {
1233 printf("Too long PASSWORD command.\n");
1239 return wpa_ctrl_command(ctrl, cmd);
1243 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1246 char cmd[256], *pos, *end;
1250 printf("Invalid NEW_PASSWORD command: needs two arguments "
1251 "(network id and password)\n");
1255 end = cmd + sizeof(cmd);
1257 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1259 if (os_snprintf_error(end - pos, ret)) {
1260 printf("Too long NEW_PASSWORD command.\n");
1264 for (i = 2; i < argc; i++) {
1265 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1266 if (os_snprintf_error(end - pos, ret)) {
1267 printf("Too long NEW_PASSWORD command.\n");
1273 return wpa_ctrl_command(ctrl, cmd);
1277 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1279 char cmd[256], *pos, *end;
1283 printf("Invalid PIN command: needs two arguments "
1284 "(network id and pin)\n");
1288 end = cmd + sizeof(cmd);
1290 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1292 if (os_snprintf_error(end - pos, ret)) {
1293 printf("Too long PIN command.\n");
1297 for (i = 2; i < argc; i++) {
1298 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1299 if (os_snprintf_error(end - pos, ret)) {
1300 printf("Too long PIN command.\n");
1305 return wpa_ctrl_command(ctrl, cmd);
1309 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1311 char cmd[256], *pos, *end;
1315 printf("Invalid OTP command: needs two arguments (network "
1316 "id and password)\n");
1320 end = cmd + sizeof(cmd);
1322 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1324 if (os_snprintf_error(end - pos, ret)) {
1325 printf("Too long OTP command.\n");
1329 for (i = 2; i < argc; i++) {
1330 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1331 if (os_snprintf_error(end - pos, ret)) {
1332 printf("Too long OTP command.\n");
1338 return wpa_ctrl_command(ctrl, cmd);
1342 static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
1344 char cmd[256], *pos, *end;
1348 printf("Invalid SIM command: needs two arguments "
1349 "(network id and SIM operation response)\n");
1353 end = cmd + sizeof(cmd);
1355 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
1357 if (os_snprintf_error(end - pos, ret)) {
1358 printf("Too long SIM command.\n");
1362 for (i = 2; i < argc; i++) {
1363 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1364 if (os_snprintf_error(end - pos, ret)) {
1365 printf("Too long SIM command.\n");
1370 return wpa_ctrl_command(ctrl, cmd);
1374 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1377 char cmd[256], *pos, *end;
1381 printf("Invalid PASSPHRASE command: needs two arguments "
1382 "(network id and passphrase)\n");
1386 end = cmd + sizeof(cmd);
1388 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1390 if (os_snprintf_error(end - pos, ret)) {
1391 printf("Too long PASSPHRASE command.\n");
1395 for (i = 2; i < argc; i++) {
1396 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1397 if (os_snprintf_error(end - pos, ret)) {
1398 printf("Too long PASSPHRASE command.\n");
1404 return wpa_ctrl_command(ctrl, cmd);
1408 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1411 printf("Invalid BSSID command: needs two arguments (network "
1416 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1420 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1422 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1426 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1428 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1432 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1435 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1439 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1442 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1446 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1449 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1453 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1456 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1460 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1463 int res = wpa_ctrl_command(ctrl, "ADD_NETWORK");
1465 update_networks(ctrl);
1470 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1473 int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1475 update_networks(ctrl);
1480 static void wpa_cli_show_network_variables(void)
1482 printf("set_network variables:\n"
1483 " ssid (network name, SSID)\n"
1484 " psk (WPA passphrase or pre-shared key)\n"
1485 " key_mgmt (key management protocol)\n"
1486 " identity (EAP identity)\n"
1487 " password (EAP password)\n"
1490 "Note: Values are entered in the same format as the "
1491 "configuration file is using,\n"
1492 "i.e., strings values need to be inside double quotation "
1494 "For example: set_network 1 ssid \"network name\"\n"
1496 "Please see wpa_supplicant.conf documentation for full list "
1497 "of\navailable variables.\n");
1501 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1505 wpa_cli_show_network_variables();
1510 printf("Invalid SET_NETWORK command: needs three arguments\n"
1511 "(network id, variable name, and value)\n");
1515 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1519 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1523 wpa_cli_show_network_variables();
1528 printf("Invalid GET_NETWORK command: needs two arguments\n"
1529 "(network id and variable name)\n");
1533 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1537 static const char *network_fields[] = {
1538 "ssid", "scan_ssid", "bssid", "bssid_blacklist",
1539 "bssid_whitelist", "psk", "proto", "key_mgmt",
1540 "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
1542 #ifdef IEEE8021X_EAPOL
1543 "eap", "identity", "anonymous_identity", "password", "ca_cert",
1544 "ca_path", "client_cert", "private_key", "private_key_passwd",
1545 "dh_file", "subject_match", "altsubject_match",
1546 "domain_suffix_match", "domain_match", "ca_cert2", "ca_path2",
1547 "client_cert2", "private_key2", "private_key2_passwd",
1548 "dh_file2", "subject_match2", "altsubject_match2",
1549 "domain_suffix_match2", "domain_match2", "phase1", "phase2",
1550 "pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id",
1551 "pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id",
1552 "engine", "engine2", "eapol_flags", "sim_num",
1553 "openssl_ciphers", "erp",
1554 #endif /* IEEE8021X_EAPOL */
1555 "wep_key0", "wep_key1", "wep_key2", "wep_key3",
1556 "wep_tx_keyidx", "priority",
1557 #ifdef IEEE8021X_EAPOL
1558 "eap_workaround", "pac_file", "fragment_size", "ocsp",
1559 #endif /* IEEE8021X_EAPOL */
1561 "mode", "no_auto_peer",
1562 #else /* CONFIG_MESH */
1564 #endif /* CONFIG_MESH */
1565 "proactive_key_caching", "disabled", "id_str",
1566 #ifdef CONFIG_IEEE80211W
1568 #endif /* CONFIG_IEEE80211W */
1569 "peerkey", "mixed_cell", "frequency", "fixed_freq",
1571 "mesh_basic_rates", "dot11MeshMaxRetries",
1572 "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout",
1573 "dot11MeshHoldingTimeout",
1574 #endif /* CONFIG_MESH */
1575 "wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid",
1577 "go_p2p_dev_addr", "p2p_client_list", "psk_list",
1578 #endif /* CONFIG_P2P */
1579 #ifdef CONFIG_HT_OVERRIDES
1580 "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc",
1581 "ht40_intolerant", "disable_max_amsdu", "ampdu_factor",
1582 "ampdu_density", "ht_mcs",
1583 #endif /* CONFIG_HT_OVERRIDES */
1584 #ifdef CONFIG_VHT_OVERRIDES
1585 "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1",
1586 "vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4",
1587 "vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7",
1588 "vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2",
1589 "vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5",
1590 "vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8",
1591 #endif /* CONFIG_VHT_OVERRIDES */
1592 "ap_max_inactivity", "dtim_period", "beacon_int",
1593 #ifdef CONFIG_MACSEC
1595 #endif /* CONFIG_MACSEC */
1597 "update_identifier",
1598 #endif /* CONFIG_HS20 */
1603 static char ** wpa_cli_complete_network(const char *str, int pos)
1605 int arg = get_cmd_arg_num(str, pos);
1606 int i, num_fields = ARRAY_SIZE(network_fields);
1611 res = cli_txt_list_array(&networks);
1614 res = os_calloc(num_fields + 1, sizeof(char *));
1617 for (i = 0; i < num_fields; i++) {
1618 res[i] = os_strdup(network_fields[i]);
1627 static char ** wpa_cli_complete_network_id(const char *str, int pos)
1629 int arg = get_cmd_arg_num(str, pos);
1631 return cli_txt_list_array(&networks);
1636 static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc,
1640 wpa_cli_show_network_variables();
1645 printf("Invalid DUP_NETWORK command: needs three arguments\n"
1646 "(src netid, dest netid, and variable name)\n");
1650 return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv);
1654 static char ** wpa_cli_complete_dup_network(const char *str, int pos)
1656 int arg = get_cmd_arg_num(str, pos);
1657 int i, num_fields = ARRAY_SIZE(network_fields);
1663 res = cli_txt_list_array(&networks);
1666 res = os_calloc(num_fields + 1, sizeof(char *));
1669 for (i = 0; i < num_fields; i++) {
1670 res[i] = os_strdup(network_fields[i]);
1679 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1682 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1686 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1688 return wpa_ctrl_command(ctrl, "ADD_CRED");
1692 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1695 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1699 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1702 printf("Invalid SET_CRED command: needs three arguments\n"
1703 "(cred id, variable name, and value)\n");
1707 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1711 static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1714 printf("Invalid GET_CRED command: needs two arguments\n"
1715 "(cred id, variable name)\n");
1719 return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv);
1723 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1726 return wpa_ctrl_command(ctrl, "DISCONNECT");
1730 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1733 return wpa_ctrl_command(ctrl, "RECONNECT");
1737 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1740 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1744 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1746 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1750 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1753 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1757 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1759 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1763 static char ** wpa_cli_complete_bss(const char *str, int pos)
1765 int arg = get_cmd_arg_num(str, pos);
1770 res = cli_txt_list_array(&bsses);
1778 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 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1797 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1799 printf("Available interfaces:\n");
1800 return wpa_ctrl_command(ctrl, "INTERFACES");
1804 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1807 wpa_cli_list_interfaces(ctrl);
1811 wpa_cli_close_connection();
1812 os_free(ctrl_ifname);
1813 ctrl_ifname = os_strdup(argv[0]);
1815 printf("Failed to allocate memory\n");
1819 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
1820 printf("Connected to interface '%s.\n", ctrl_ifname);
1822 printf("Could not connect to interface '%s' - re-trying\n",
1829 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1832 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1836 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1839 return wpa_ctrl_command(ctrl, "TERMINATE");
1843 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1850 printf("Invalid INTERFACE_ADD command: needs at least one "
1851 "argument (interface name)\n"
1852 "All arguments: ifname confname driver ctrl_interface "
1853 "driver_param bridge_name [create]\n");
1858 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1859 * <driver_param>TAB<bridge_name>[TAB<create>]
1861 res = os_snprintf(cmd, sizeof(cmd),
1862 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s",
1864 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1865 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1866 argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "");
1867 if (os_snprintf_error(sizeof(cmd), res))
1869 cmd[sizeof(cmd) - 1] = '\0';
1870 return wpa_ctrl_command(ctrl, cmd);
1874 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1877 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1881 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1884 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1889 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1891 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1895 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1896 char *addr, size_t addr_len)
1898 char buf[4096], *pos;
1902 if (ctrl_conn == NULL) {
1903 printf("Not connected to hostapd - command dropped.\n");
1906 len = sizeof(buf) - 1;
1907 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1910 printf("'%s' command timed out.\n", cmd);
1912 } else if (ret < 0) {
1913 printf("'%s' command failed.\n", cmd);
1918 if (os_memcmp(buf, "FAIL", 4) == 0)
1923 while (*pos != '\0' && *pos != '\n')
1926 os_strlcpy(addr, buf, addr_len);
1931 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1933 char addr[32], cmd[64];
1935 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1938 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1939 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1945 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1948 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1952 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1955 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1958 static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
1961 return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
1964 #endif /* CONFIG_AP */
1967 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1969 return wpa_ctrl_command(ctrl, "SUSPEND");
1973 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1975 return wpa_ctrl_command(ctrl, "RESUME");
1979 #ifdef CONFIG_TESTING_OPTIONS
1980 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1982 return wpa_ctrl_command(ctrl, "DROP_SA");
1984 #endif /* CONFIG_TESTING_OPTIONS */
1987 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1989 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1995 static int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc,
1998 return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv);
2002 static int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc,
2005 return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv);
2009 static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc,
2012 return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
2015 #endif /* CONFIG_MESH */
2020 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
2022 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
2026 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
2029 int arg = get_cmd_arg_num(str, pos);
2031 res = os_calloc(6, sizeof(char *));
2034 res[0] = os_strdup("type=social");
2035 if (res[0] == NULL) {
2039 res[1] = os_strdup("type=progressive");
2042 res[2] = os_strdup("delay=");
2045 res[3] = os_strdup("dev_id=");
2049 res[4] = os_strdup("[timeout]");
2055 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
2058 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
2062 static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc,
2065 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv);
2069 static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc,
2072 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv);
2076 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
2079 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
2083 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
2085 int arg = get_cmd_arg_num(str, pos);
2090 res = cli_txt_list_array(&p2p_peers);
2098 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2101 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
2105 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2108 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
2112 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2114 int arg = get_cmd_arg_num(str, pos);
2119 res = cli_txt_list_array(&p2p_groups);
2127 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2130 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
2134 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2137 if (argc != 2 && argc != 3) {
2138 printf("Invalid P2P_PROV_DISC command: needs at least "
2139 "two arguments, address and config method\n"
2140 "(display, keypad, or pbc) and an optional join\n");
2144 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
2148 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2151 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2155 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2161 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2162 "or more arguments (address and TLVs)\n");
2166 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
2168 return wpa_ctrl_command(ctrl, cmd);
2172 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2173 int argc, char *argv[])
2175 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
2179 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2186 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2187 "arguments (freq, address, dialog token, and TLVs)\n");
2191 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2192 argv[0], argv[1], argv[2], argv[3]);
2193 if (os_snprintf_error(sizeof(cmd), res))
2195 cmd[sizeof(cmd) - 1] = '\0';
2196 return wpa_ctrl_command(ctrl, cmd);
2200 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2203 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2207 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2208 int argc, char *argv[])
2210 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
2214 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2217 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2221 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2225 printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n");
2229 return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv);
2233 static int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc,
2236 if (argc < 5 || argc > 6) {
2237 printf("Invalid P2P_SERVICE_REP command: needs 5-6 "
2242 return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv);
2246 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2252 if (argc != 2 && argc != 3) {
2253 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2259 res = os_snprintf(cmd, sizeof(cmd),
2260 "P2P_SERVICE_DEL %s %s %s",
2261 argv[0], argv[1], argv[2]);
2263 res = os_snprintf(cmd, sizeof(cmd),
2264 "P2P_SERVICE_DEL %s %s",
2266 if (os_snprintf_error(sizeof(cmd), res))
2268 cmd[sizeof(cmd) - 1] = '\0';
2269 return wpa_ctrl_command(ctrl, cmd);
2273 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2274 int argc, char *argv[])
2276 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
2280 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2281 int argc, char *argv[])
2283 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
2287 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2289 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2293 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2295 int arg = get_cmd_arg_num(str, pos);
2300 res = cli_txt_list_array(&p2p_peers);
2308 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2309 char *addr, size_t addr_len,
2312 char buf[4096], *pos;
2316 if (ctrl_conn == NULL)
2318 len = sizeof(buf) - 1;
2319 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2322 printf("'%s' command timed out.\n", cmd);
2324 } else if (ret < 0) {
2325 printf("'%s' command failed.\n", cmd);
2330 if (os_memcmp(buf, "FAIL", 4) == 0)
2334 while (*pos != '\0' && *pos != '\n')
2337 os_strlcpy(addr, buf, addr_len);
2338 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2339 printf("%s\n", addr);
2344 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2346 char addr[32], cmd[64];
2349 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2351 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2352 addr, sizeof(addr), discovered))
2355 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2356 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2363 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2365 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2369 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
2371 int arg = get_cmd_arg_num(str, pos);
2372 const char *fields[] = {
2392 int i, num_fields = ARRAY_SIZE(fields);
2395 char **res = os_calloc(num_fields + 1, sizeof(char *));
2398 for (i = 0; i < num_fields; i++) {
2399 res[i] = os_strdup(fields[i]);
2406 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
2407 return cli_txt_list_array(&p2p_peers);
2413 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2415 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2419 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2422 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2426 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2429 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2433 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2436 if (argc != 0 && argc != 2 && argc != 4) {
2437 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2438 "(preferred duration, interval; in microsecods).\n"
2439 "Optional second pair can be used to provide "
2440 "acceptable values.\n");
2444 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2448 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2451 if (argc != 0 && argc != 2) {
2452 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2453 "(availability period, availability interval; in "
2455 "Extended Listen Timing can be cancelled with this "
2456 "command when used without parameters.\n");
2460 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2464 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
2467 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
2470 #endif /* CONFIG_P2P */
2472 #ifdef CONFIG_WIFI_DISPLAY
2474 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2480 if (argc != 1 && argc != 2) {
2481 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2482 "arguments (subelem, hexdump)\n");
2486 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2487 argv[0], argc > 1 ? argv[1] : "");
2488 if (os_snprintf_error(sizeof(cmd), res))
2490 cmd[sizeof(cmd) - 1] = '\0';
2491 return wpa_ctrl_command(ctrl, cmd);
2495 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2502 printf("Invalid WFD_SUBELEM_GET command: needs one "
2503 "argument (subelem)\n");
2507 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2509 if (os_snprintf_error(sizeof(cmd), res))
2511 cmd[sizeof(cmd) - 1] = '\0';
2512 return wpa_ctrl_command(ctrl, cmd);
2514 #endif /* CONFIG_WIFI_DISPLAY */
2517 #ifdef CONFIG_INTERWORKING
2518 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2521 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2525 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2528 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2532 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2535 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2539 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2542 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2546 static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc,
2549 return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv);
2553 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2555 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2559 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2562 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2566 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2569 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2571 #endif /* CONFIG_INTERWORKING */
2576 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2579 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2583 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2589 printf("Command needs one or two arguments (dst mac addr and "
2590 "optional home realm)\n");
2594 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2598 return wpa_ctrl_command(ctrl, cmd);
2602 static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc,
2608 printf("Command needs two arguments (dst mac addr and "
2613 if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0)
2616 return wpa_ctrl_command(ctrl, cmd);
2620 static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[])
2622 return wpa_ctrl_command(ctrl, "FETCH_OSU");
2626 static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc,
2629 return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU");
2632 #endif /* CONFIG_HS20 */
2635 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2638 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2642 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2645 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2649 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2652 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2656 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2659 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2663 static int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc,
2666 return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv);
2670 static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc,
2673 return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv);
2677 static int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc,
2680 return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv);
2684 static int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc,
2687 return wpa_ctrl_command(ctrl, "WMM_AC_STATUS");
2691 static int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc,
2694 return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv);
2698 static int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc,
2701 return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv);
2705 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2708 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2712 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2715 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2719 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2722 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2726 #ifdef CONFIG_AUTOSCAN
2728 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2731 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2733 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2736 #endif /* CONFIG_AUTOSCAN */
2741 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2743 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2747 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2749 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2752 #endif /* CONFIG_WNM */
2755 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2759 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2764 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2766 return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
2768 #endif /* ANDROID */
2771 static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
2773 return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv);
2777 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2779 return wpa_ctrl_command(ctrl, "FLUSH");
2783 static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
2785 return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
2789 static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc,
2792 return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv);
2796 static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2798 return wpa_ctrl_command(ctrl, "ERP_FLUSH");
2802 static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc,
2805 return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv);
2809 static int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc,
2812 return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv);
2816 enum wpa_cli_cmd_flags {
2817 cli_cmd_flag_none = 0x00,
2818 cli_cmd_flag_sensitive = 0x01
2821 struct wpa_cli_cmd {
2823 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2824 char ** (*completion)(const char *str, int pos);
2825 enum wpa_cli_cmd_flags flags;
2829 static const struct wpa_cli_cmd wpa_cli_commands[] = {
2830 { "status", wpa_cli_cmd_status, NULL,
2832 "[verbose] = get current WPA/EAPOL/EAP status" },
2833 { "ifname", wpa_cli_cmd_ifname, NULL,
2835 "= get current interface name" },
2836 { "ping", wpa_cli_cmd_ping, NULL,
2838 "= pings wpa_supplicant" },
2839 { "relog", wpa_cli_cmd_relog, NULL,
2841 "= re-open log-file (allow rolling logs)" },
2842 { "note", wpa_cli_cmd_note, NULL,
2844 "<text> = add a note to wpa_supplicant debug log" },
2845 { "mib", wpa_cli_cmd_mib, NULL,
2847 "= get MIB variables (dot1x, dot11)" },
2848 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2850 "[command] = show usage help" },
2851 { "interface", wpa_cli_cmd_interface, NULL,
2853 "[ifname] = show interfaces/select interface" },
2854 { "level", wpa_cli_cmd_level, NULL,
2856 "<debug level> = change debug level" },
2857 { "license", wpa_cli_cmd_license, NULL,
2859 "= show full wpa_cli license" },
2860 { "quit", wpa_cli_cmd_quit, NULL,
2863 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2865 "= set variables (shows list of variables when run without "
2867 { "dump", wpa_cli_cmd_dump, NULL,
2869 "= dump config variables" },
2870 { "get", wpa_cli_cmd_get, wpa_cli_complete_get,
2872 "<name> = get information" },
2873 { "logon", wpa_cli_cmd_logon, NULL,
2875 "= IEEE 802.1X EAPOL state machine logon" },
2876 { "logoff", wpa_cli_cmd_logoff, NULL,
2878 "= IEEE 802.1X EAPOL state machine logoff" },
2879 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2881 "= show PMKSA cache" },
2882 { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL,
2884 "= flush PMKSA cache entries" },
2885 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2887 "= force reassociation" },
2888 { "reattach", wpa_cli_cmd_reattach, NULL,
2890 "= force reassociation back to the same BSS" },
2891 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2893 "<BSSID> = force preauthentication" },
2894 { "identity", wpa_cli_cmd_identity, NULL,
2896 "<network id> <identity> = configure identity for an SSID" },
2897 { "password", wpa_cli_cmd_password, NULL,
2898 cli_cmd_flag_sensitive,
2899 "<network id> <password> = configure password for an SSID" },
2900 { "new_password", wpa_cli_cmd_new_password, NULL,
2901 cli_cmd_flag_sensitive,
2902 "<network id> <password> = change password for an SSID" },
2903 { "pin", wpa_cli_cmd_pin, NULL,
2904 cli_cmd_flag_sensitive,
2905 "<network id> <pin> = configure pin for an SSID" },
2906 { "otp", wpa_cli_cmd_otp, NULL,
2907 cli_cmd_flag_sensitive,
2908 "<network id> <password> = configure one-time-password for an SSID"
2910 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2911 cli_cmd_flag_sensitive,
2912 "<network id> <passphrase> = configure private key passphrase\n"
2914 { "sim", wpa_cli_cmd_sim, NULL,
2915 cli_cmd_flag_sensitive,
2916 "<network id> <pin> = report SIM operation result" },
2917 { "bssid", wpa_cli_cmd_bssid, NULL,
2919 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2920 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2922 "<BSSID> = add a BSSID to the blacklist\n"
2923 "blacklist clear = clear the blacklist\n"
2924 "blacklist = display the blacklist" },
2925 { "log_level", wpa_cli_cmd_log_level, NULL,
2927 "<level> [<timestamp>] = update the log level/timestamp\n"
2928 "log_level = display the current log level and log options" },
2929 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2931 "= list configured networks" },
2932 { "select_network", wpa_cli_cmd_select_network,
2933 wpa_cli_complete_network_id,
2935 "<network id> = select a network (disable others)" },
2936 { "enable_network", wpa_cli_cmd_enable_network,
2937 wpa_cli_complete_network_id,
2939 "<network id> = enable a network" },
2940 { "disable_network", wpa_cli_cmd_disable_network,
2941 wpa_cli_complete_network_id,
2943 "<network id> = disable a network" },
2944 { "add_network", wpa_cli_cmd_add_network, NULL,
2946 "= add a network" },
2947 { "remove_network", wpa_cli_cmd_remove_network,
2948 wpa_cli_complete_network_id,
2950 "<network id> = remove a network" },
2951 { "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network,
2952 cli_cmd_flag_sensitive,
2953 "<network id> <variable> <value> = set network variables (shows\n"
2954 " list of variables when run without arguments)" },
2955 { "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network,
2957 "<network id> <variable> = get network variables" },
2958 { "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network,
2960 "<src network id> <dst network id> <variable> = duplicate network variables"
2962 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2964 "= list configured credentials" },
2965 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2967 "= add a credential" },
2968 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2970 "<cred id> = remove a credential" },
2971 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2972 cli_cmd_flag_sensitive,
2973 "<cred id> <variable> <value> = set credential variables" },
2974 { "get_cred", wpa_cli_cmd_get_cred, NULL,
2976 "<cred id> <variable> = get credential variables" },
2977 { "save_config", wpa_cli_cmd_save_config, NULL,
2979 "= save the current configuration" },
2980 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2982 "= disconnect and wait for reassociate/reconnect command before\n"
2984 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2986 "= like reassociate, but only takes effect if already disconnected"
2988 { "scan", wpa_cli_cmd_scan, NULL,
2990 "= request new BSS scan" },
2991 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2993 "= get latest scan results" },
2994 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2996 "<<idx> | <bssid>> = get detailed scan result info" },
2997 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2999 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
3000 "= get capabilities" },
3001 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
3003 "= force wpa_supplicant to re-read its configuration file" },
3004 { "terminate", wpa_cli_cmd_terminate, NULL,
3006 "= terminate wpa_supplicant" },
3007 { "interface_add", wpa_cli_cmd_interface_add, NULL,
3009 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
3010 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
3012 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
3014 "<ifname> = removes the interface" },
3015 { "interface_list", wpa_cli_cmd_interface_list, NULL,
3017 "= list available interfaces" },
3018 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
3020 "<value> = set ap_scan parameter" },
3021 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
3023 "<value> = set scan_interval parameter (in seconds)" },
3024 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
3026 "<value> = set BSS expiration age parameter" },
3027 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
3029 "<value> = set BSS expiration scan count parameter" },
3030 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
3032 "<value> = set BSS flush age (0 by default)" },
3033 { "stkstart", wpa_cli_cmd_stkstart, NULL,
3035 "<addr> = request STK negotiation with <addr>" },
3036 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
3038 "<addr> = request over-the-DS FT with <addr>" },
3039 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
3041 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
3042 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
3043 cli_cmd_flag_sensitive,
3044 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
3046 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
3047 cli_cmd_flag_sensitive,
3048 "<PIN> = verify PIN checksum" },
3049 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
3050 "Cancels the pending WPS operation" },
3051 #ifdef CONFIG_WPS_NFC
3052 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
3054 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
3055 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
3057 "<WPS|NDEF> = build configuration token" },
3058 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
3060 "<WPS|NDEF> = create password token" },
3061 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
3062 cli_cmd_flag_sensitive,
3063 "<hexdump of payload> = report read NFC tag with WPS data" },
3064 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
3066 "<NDEF> <WPS> = create NFC handover request" },
3067 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
3069 "<NDEF> <WPS> = create NFC handover select" },
3070 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
3072 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
3074 #endif /* CONFIG_WPS_NFC */
3075 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
3076 cli_cmd_flag_sensitive,
3077 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
3078 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
3079 cli_cmd_flag_sensitive,
3080 "[params..] = enable/disable AP PIN" },
3081 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
3083 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
3084 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
3086 "= stop Wi-Fi Protected Setup External Registrar" },
3087 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
3088 cli_cmd_flag_sensitive,
3089 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
3090 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
3092 "<UUID> = accept an Enrollee PBC using External Registrar" },
3093 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
3094 cli_cmd_flag_sensitive,
3095 "<UUID> <PIN> = learn AP configuration" },
3096 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
3098 "<UUID> <network id> = set AP configuration for enrolling" },
3099 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
3100 cli_cmd_flag_sensitive,
3101 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
3102 #ifdef CONFIG_WPS_NFC
3103 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
3105 "<WPS/NDEF> <UUID> = build NFC configuration token" },
3106 #endif /* CONFIG_WPS_NFC */
3107 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
3109 "<addr> = request RSN authentication with <addr> in IBSS" },
3111 { "sta", wpa_cli_cmd_sta, NULL,
3113 "<addr> = get information about an associated station (AP)" },
3114 { "all_sta", wpa_cli_cmd_all_sta, NULL,
3116 "= get information about all associated stations (AP)" },
3117 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
3119 "<addr> = deauthenticate a station" },
3120 { "disassociate", wpa_cli_cmd_disassociate, NULL,
3122 "<addr> = disassociate a station" },
3123 { "chan_switch", wpa_cli_cmd_chanswitch, NULL,
3125 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
3126 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
3127 " = CSA parameters" },
3128 #endif /* CONFIG_AP */
3129 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
3130 "= notification of suspend/hibernate" },
3131 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
3132 "= notification of resume/thaw" },
3133 #ifdef CONFIG_TESTING_OPTIONS
3134 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
3135 "= drop SA without deauth/disassoc (test command)" },
3136 #endif /* CONFIG_TESTING_OPTIONS */
3137 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
3139 "<addr> = roam to the specified BSS" },
3141 { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL,
3143 "[ifname] = Create a new mesh interface" },
3144 { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL,
3146 "<network id> = join a mesh network (disable others)" },
3147 { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
3149 "<ifname> = Remove mesh group interface" },
3150 #endif /* CONFIG_MESH */
3152 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
3154 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3155 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
3156 "= stop P2P Devices search" },
3157 { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL,
3159 "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" },
3160 { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL,
3162 "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" },
3163 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
3165 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
3166 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
3167 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3168 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
3169 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
3170 "<ifname> = remove P2P group interface (terminate group if GO)" },
3171 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
3172 "[ht40] = add a new P2P group (local end as GO)" },
3173 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
3174 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3175 "<addr> <method> = request provisioning discovery" },
3176 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
3178 "= get the passphrase for a group (GO only)" },
3179 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
3180 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3181 "<addr> <TLVs> = schedule service discovery request" },
3182 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
3183 NULL, cli_cmd_flag_none,
3184 "<id> = cancel pending service discovery request" },
3185 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
3187 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3188 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
3190 "= indicate change in local services" },
3191 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
3193 "<external> = set external processing of service discovery" },
3194 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
3196 "= remove all stored service entries" },
3197 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
3199 "<bonjour|upnp|asp> <query|version> <response|service> = add a local "
3201 { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL,
3203 "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace "
3204 "local ASP service" },
3205 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
3207 "<bonjour|upnp> <query|version> [|service] = remove a local "
3209 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
3211 "<addr> = reject connection attempts from a specific peer" },
3212 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
3214 "<cmd> [peer=addr] = invite peer" },
3215 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
3216 "[discovered] = list known (optionally, only fully discovered) P2P "
3218 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
3220 "<address> = show information about known P2P peer" },
3221 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
3223 "<field> <value> = set a P2P parameter" },
3224 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
3225 "= flush P2P state" },
3226 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
3227 "= cancel P2P group formation" },
3228 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
3229 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3230 "<address> = unauthorize a peer" },
3231 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
3233 "[<duration> <interval>] [<duration> <interval>] = request GO "
3235 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
3237 "[<period> <interval>] = set extended listen timing" },
3238 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
3239 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3240 "<address|iface=address> = remove a peer from all groups" },
3241 #endif /* CONFIG_P2P */
3242 #ifdef CONFIG_WIFI_DISPLAY
3243 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
3245 "<subelem> [contents] = set Wi-Fi Display subelement" },
3246 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
3248 "<subelem> = get Wi-Fi Display subelement" },
3249 #endif /* CONFIG_WIFI_DISPLAY */
3250 #ifdef CONFIG_INTERWORKING
3251 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
3252 "= fetch ANQP information for all APs" },
3253 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
3255 "= stop fetch_anqp operation" },
3256 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
3258 "[auto] = perform Interworking network selection" },
3259 { "interworking_connect", wpa_cli_cmd_interworking_connect,
3260 wpa_cli_complete_bss, cli_cmd_flag_none,
3261 "<BSSID> = connect using Interworking credentials" },
3262 { "interworking_add_network", wpa_cli_cmd_interworking_add_network,
3263 wpa_cli_complete_bss, cli_cmd_flag_none,
3264 "<BSSID> = connect using Interworking credentials" },
3265 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
3267 "<addr> <info id>[,<info id>]... = request ANQP information" },
3268 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
3270 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
3271 { "gas_response_get", wpa_cli_cmd_gas_response_get,
3272 wpa_cli_complete_bss, cli_cmd_flag_none,
3273 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
3274 #endif /* CONFIG_INTERWORKING */
3276 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
3278 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3280 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
3281 wpa_cli_complete_bss, cli_cmd_flag_none,
3282 "<addr> <home realm> = get HS20 nai home realm list" },
3283 { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request,
3284 wpa_cli_complete_bss, cli_cmd_flag_none,
3285 "<addr> <icon name> = get Hotspot 2.0 OSU icon" },
3286 { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none,
3287 "= fetch OSU provider information from all APs" },
3288 { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL,
3290 "= cancel fetch_osu command" },
3291 #endif /* CONFIG_HS20 */
3292 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
3294 "<0/1> = disable/enable automatic reconnection" },
3295 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
3297 "<addr> = request TDLS discovery with <addr>" },
3298 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
3300 "<addr> = request TDLS setup with <addr>" },
3301 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
3303 "<addr> = tear down TDLS with <addr>" },
3304 { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL,
3306 "<addr> = TDLS link status with <addr>" },
3307 { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
3309 "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
3310 "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] "
3311 "= add WMM-AC traffic stream" },
3312 { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL,
3314 "<tsid> = delete WMM-AC traffic stream" },
3315 { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL,
3317 "= show status for Wireless Multi-Media Admission-Control" },
3318 { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL,
3320 "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] "
3321 "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching "
3323 { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL,
3325 "<addr> = disable channel switching with TDLS peer <addr>" },
3326 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
3328 "= get signal parameters" },
3329 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
3331 "= get TX/RX packet counters" },
3332 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
3334 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3335 #ifdef CONFIG_AUTOSCAN
3336 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
3337 "[params] = Set or unset (if none) autoscan parameters" },
3338 #endif /* CONFIG_AUTOSCAN */
3340 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
3341 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
3342 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
3343 "<query reason> = Send BSS Transition Management Query" },
3344 #endif /* CONFIG_WNM */
3345 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
3346 "<params..> = Sent unprocessed command" },
3347 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
3348 "= flush wpa_supplicant state" },
3350 { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
3351 "<command> = driver private commands" },
3352 #endif /* ANDROID */
3353 { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
3354 "= radio_work <show/add/done>" },
3355 { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
3356 "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
3358 { "neighbor_rep_request",
3359 wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
3360 "[ssid=<SSID>] = Trigger request to AP for neighboring AP report "
3361 "(with optional given SSID, default: current SSID)"
3363 { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
3364 "= flush ERP keys" },
3366 wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none,
3367 "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
3368 "mask=mac-address-mask] = scan MAC randomization"
3370 { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL,
3372 "<interface type> = retrieve preferred freq list for the specified interface type" },
3373 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
3378 * Prints command usage, lines are padded with the specified string.
3380 static void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad)
3385 printf("%s%s ", pad, cmd->cmd);
3386 for (n = 0; (c = cmd->usage[n]); n++) {
3395 static void print_help(const char *cmd)
3398 printf("commands:\n");
3399 for (n = 0; wpa_cli_commands[n].cmd; n++) {
3400 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
3401 print_cmd_help(&wpa_cli_commands[n], " ");
3406 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3408 const char *c, *delim;
3412 delim = os_strchr(cmd, ' ');
3416 len = os_strlen(cmd);
3418 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3419 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3420 return (wpa_cli_commands[n].flags &
3421 cli_cmd_flag_sensitive);
3427 static char ** wpa_list_cmd_list(void)
3431 struct cli_txt_entry *e;
3433 count = ARRAY_SIZE(wpa_cli_commands);
3434 count += dl_list_len(&p2p_groups);
3435 count += dl_list_len(&ifnames);
3436 res = os_calloc(count + 1, sizeof(char *));
3440 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3441 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3446 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
3447 size_t len = 8 + os_strlen(e->txt);
3448 res[i] = os_malloc(len);
3451 os_snprintf(res[i], len, "ifname=%s", e->txt);
3455 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
3456 res[i] = os_strdup(e->txt);
3466 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3471 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3472 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3473 if (wpa_cli_commands[i].completion)
3474 return wpa_cli_commands[i].completion(str,
3477 printf("\r%s\n", wpa_cli_commands[i].usage);
3487 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3493 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
3494 end = os_strchr(str, ' ');
3495 if (end && pos > end - str) {
3496 pos -= end - str + 1;
3501 end = os_strchr(str, ' ');
3502 if (end == NULL || str + pos < end)
3503 return wpa_list_cmd_list();
3505 cmd = os_malloc(pos + 1);
3508 os_memcpy(cmd, str, pos);
3509 cmd[end - str] = '\0';
3510 res = wpa_cli_cmd_completion(cmd, str, pos);
3516 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3518 const struct wpa_cli_cmd *cmd, *match = NULL;
3522 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
3523 ifname_prefix = argv[0] + 7;
3527 ifname_prefix = NULL;
3533 cmd = wpa_cli_commands;
3535 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3538 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3539 /* we have an exact match */
3549 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3550 cmd = wpa_cli_commands;
3552 if (os_strncasecmp(cmd->cmd, argv[0],
3553 os_strlen(argv[0])) == 0) {
3554 printf(" %s", cmd->cmd);
3560 } else if (count == 0) {
3561 printf("Unknown command '%s'\n", argv[0]);
3564 ret = match->handler(ctrl, argc - 1, &argv[1]);
3571 static int str_match(const char *a, const char *b)
3573 return os_strncmp(a, b, os_strlen(b)) == 0;
3577 static int wpa_cli_exec(const char *program, const char *arg1,
3584 len = os_strlen(arg1) + os_strlen(arg2) + 2;
3585 arg = os_malloc(len);
3588 os_snprintf(arg, len, "%s %s", arg1, arg2);
3589 res = os_exec(program, arg, 1);
3596 static void wpa_cli_action_process(const char *msg)
3599 char *copy = NULL, *id, *pos2;
3600 const char *ifname = ctrl_ifname;
3601 char ifname_buf[100];
3603 if (eloop_terminated())
3607 if (os_strncmp(pos, "IFNAME=", 7) == 0) {
3609 end = os_strchr(pos + 7, ' ');
3610 if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) {
3612 os_memcpy(ifname_buf, pos, end - pos);
3613 ifname_buf[end - pos] = '\0';
3614 ifname = ifname_buf;
3619 const char *prev = pos;
3621 pos = os_strchr(pos, '>');
3628 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3630 os_unsetenv("WPA_ID");
3631 os_unsetenv("WPA_ID_STR");
3632 os_unsetenv("WPA_CTRL_DIR");
3634 pos = os_strstr(pos, "[id=");
3636 copy = os_strdup(pos + 4);
3640 while (*pos2 && *pos2 != ' ')
3644 os_setenv("WPA_ID", id, 1);
3645 while (*pos2 && *pos2 != '=')
3650 while (*pos2 && *pos2 != ']')
3653 os_setenv("WPA_ID_STR", id, 1);
3657 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3659 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
3660 wpa_cli_connected = 1;
3661 wpa_cli_last_id = new_id;
3662 wpa_cli_exec(action_file, ifname, "CONNECTED");
3664 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3665 if (wpa_cli_connected) {
3666 wpa_cli_connected = 0;
3667 wpa_cli_exec(action_file, ifname, "DISCONNECTED");
3669 } else if (str_match(pos, MESH_GROUP_STARTED)) {
3670 wpa_cli_exec(action_file, ctrl_ifname, pos);
3671 } else if (str_match(pos, MESH_GROUP_REMOVED)) {
3672 wpa_cli_exec(action_file, ctrl_ifname, pos);
3673 } else if (str_match(pos, MESH_PEER_CONNECTED)) {
3674 wpa_cli_exec(action_file, ctrl_ifname, pos);
3675 } else if (str_match(pos, MESH_PEER_DISCONNECTED)) {
3676 wpa_cli_exec(action_file, ctrl_ifname, pos);
3677 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3678 wpa_cli_exec(action_file, ifname, pos);
3679 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3680 wpa_cli_exec(action_file, ifname, pos);
3681 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3682 wpa_cli_exec(action_file, ifname, pos);
3683 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3684 wpa_cli_exec(action_file, ifname, pos);
3685 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3686 wpa_cli_exec(action_file, ifname, pos);
3687 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3688 wpa_cli_exec(action_file, ifname, pos);
3689 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3690 wpa_cli_exec(action_file, ifname, pos);
3691 } else if (str_match(pos, AP_STA_CONNECTED)) {
3692 wpa_cli_exec(action_file, ifname, pos);
3693 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3694 wpa_cli_exec(action_file, ifname, pos);
3695 } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
3696 wpa_cli_exec(action_file, ifname, pos);
3697 } else if (str_match(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
3698 wpa_cli_exec(action_file, ifname, pos);
3699 } else if (str_match(pos, HS20_DEAUTH_IMMINENT_NOTICE)) {
3700 wpa_cli_exec(action_file, ifname, pos);
3701 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3702 printf("wpa_supplicant is terminating - stop monitoring\n");
3708 #ifndef CONFIG_ANSI_C_EXTRA
3709 static void wpa_cli_action_cb(char *msg, size_t len)
3711 wpa_cli_action_process(msg);
3713 #endif /* CONFIG_ANSI_C_EXTRA */
3716 static void wpa_cli_reconnect(void)
3718 wpa_cli_close_connection();
3719 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3724 printf("\rConnection to wpa_supplicant re-established\n");
3730 static void cli_event(const char *str)
3732 const char *start, *s;
3734 start = os_strchr(str, '>');
3740 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3741 s = os_strchr(start, ' ');
3744 s = os_strchr(s + 1, ' ');
3747 cli_txt_list_add(&bsses, s + 1);
3751 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3752 s = os_strchr(start, ' ');
3755 s = os_strchr(s + 1, ' ');
3758 cli_txt_list_del_addr(&bsses, s + 1);
3763 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3764 s = os_strstr(start, " p2p_dev_addr=");
3767 cli_txt_list_add_addr(&p2p_peers, s + 14);
3771 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3772 s = os_strstr(start, " p2p_dev_addr=");
3775 cli_txt_list_del_addr(&p2p_peers, s + 14);
3779 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3780 s = os_strchr(start, ' ');
3783 cli_txt_list_add_word(&p2p_groups, s + 1, ' ');
3787 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3788 s = os_strchr(start, ' ');
3791 cli_txt_list_del_word(&p2p_groups, s + 1, ' ');
3794 #endif /* CONFIG_P2P */
3798 static int check_terminating(const char *msg)
3800 const char *pos = msg;
3804 pos = os_strchr(pos, '>');
3811 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3813 printf("\rConnection to wpa_supplicant lost - trying to "
3816 wpa_cli_attached = 0;
3817 wpa_cli_close_connection();
3825 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3827 if (ctrl_conn == NULL) {
3828 wpa_cli_reconnect();
3831 while (wpa_ctrl_pending(ctrl) > 0) {
3833 size_t len = sizeof(buf) - 1;
3834 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3837 wpa_cli_action_process(buf);
3840 if (wpa_cli_show_event(buf)) {
3842 printf("\r%s\n", buf);
3846 if (interactive && check_terminating(buf) > 0)
3850 printf("Could not read pending message.\n");
3855 if (wpa_ctrl_pending(ctrl) < 0) {
3856 printf("Connection to wpa_supplicant lost - trying to "
3858 wpa_cli_reconnect();
3864 static int tokenize_cmd(char *cmd, char *argv[])
3877 if (argc == max_args)
3880 char *pos2 = os_strrchr(pos, '"');
3884 while (*pos != '\0' && *pos != ' ')
3894 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3898 char *prefix = ifname_prefix;
3900 ifname_prefix = NULL;
3901 res = _wpa_ctrl_command(ctrl_conn, "PING", 0);
3902 ifname_prefix = prefix;
3904 printf("Connection to wpa_supplicant lost - trying to "
3906 wpa_cli_close_connection();
3910 wpa_cli_reconnect();
3911 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3915 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3917 wpa_cli_recv_pending(mon_conn, 0);
3921 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3923 char *argv[max_args];
3925 argc = tokenize_cmd(cmd, argv);
3927 wpa_request(ctrl_conn, argc, argv);
3931 static void wpa_cli_edit_eof_cb(void *ctx)
3937 static int warning_displayed = 0;
3938 static char *hfile = NULL;
3939 static int edit_started = 0;
3941 static void start_edit(void)
3946 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3947 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3948 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3950 #ifdef CONFIG_WPA_CLI_HISTORY_DIR
3951 home = CONFIG_WPA_CLI_HISTORY_DIR;
3952 #else /* CONFIG_WPA_CLI_HISTORY_DIR */
3953 home = getenv("HOME");
3954 #endif /* CONFIG_WPA_CLI_HISTORY_DIR */
3956 const char *fname = ".wpa_cli_history";
3957 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3958 hfile = os_malloc(hfile_len);
3960 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3963 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3964 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3970 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3974 static void update_bssid_list(struct wpa_ctrl *ctrl)
3977 size_t len = sizeof(buf);
3979 char *cmd = "BSS RANGE=ALL MASK=0x2";
3984 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3991 pos = os_strstr(pos, "bssid=");
3995 end = os_strchr(pos, '\n');
3999 cli_txt_list_add(&bsses, pos);
4005 static void update_ifnames(struct wpa_ctrl *ctrl)
4008 size_t len = sizeof(buf);
4010 char *cmd = "INTERFACES";
4014 cli_txt_list_flush(&ifnames);
4018 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
4025 end = os_strchr(pos, '\n');
4029 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
4030 if (!os_snprintf_error(sizeof(txt), ret))
4031 cli_txt_list_add(&ifnames, txt);
4037 static void update_networks(struct wpa_ctrl *ctrl)
4040 size_t len = sizeof(buf);
4042 char *cmd = "LIST_NETWORKS";
4046 cli_txt_list_flush(&networks);
4050 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
4057 end = os_strchr(pos, '\n');
4062 cli_txt_list_add_word(&networks, pos, '\t');
4069 static void try_connection(void *eloop_ctx, void *timeout_ctx)
4074 if (ctrl_ifname == NULL)
4075 ctrl_ifname = wpa_cli_get_default_ifname();
4077 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
4078 if (!warning_displayed) {
4079 printf("Could not connect to wpa_supplicant: "
4081 ctrl_ifname ? ctrl_ifname : "(nil)");
4082 warning_displayed = 1;
4084 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
4088 update_bssid_list(ctrl_conn);
4089 update_networks(ctrl_conn);
4091 if (warning_displayed)
4092 printf("Connection established.\n");
4099 static void wpa_cli_interactive(void)
4101 printf("\nInteractive mode\n\n");
4103 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
4105 eloop_cancel_timeout(try_connection, NULL, NULL);
4107 cli_txt_list_flush(&p2p_peers);
4108 cli_txt_list_flush(&p2p_groups);
4109 cli_txt_list_flush(&bsses);
4110 cli_txt_list_flush(&ifnames);
4111 cli_txt_list_flush(&networks);
4113 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
4115 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
4116 wpa_cli_close_connection();
4120 static void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx)
4122 struct wpa_ctrl *ctrl = eloop_ctx;
4126 /* verify that connection is still working */
4127 len = sizeof(buf) - 1;
4128 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
4129 wpa_cli_action_cb) < 0 ||
4130 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
4131 printf("wpa_supplicant did not reply to PING command - exiting\n");
4135 eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
4140 static void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx)
4142 struct wpa_ctrl *ctrl = eloop_ctx;
4144 wpa_cli_recv_pending(ctrl, 1);
4148 static void wpa_cli_action(struct wpa_ctrl *ctrl)
4150 #ifdef CONFIG_ANSI_C_EXTRA
4151 /* TODO: ANSI C version(?) */
4152 printf("Action processing not supported in ANSI C build.\n");
4153 #else /* CONFIG_ANSI_C_EXTRA */
4156 fd = wpa_ctrl_get_fd(ctrl);
4157 eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
4159 eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL);
4161 eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL);
4162 eloop_unregister_read_sock(fd);
4163 #endif /* CONFIG_ANSI_C_EXTRA */
4167 static void wpa_cli_cleanup(void)
4169 wpa_cli_close_connection();
4171 os_daemonize_terminate(pid_file);
4173 os_program_deinit();
4177 static void wpa_cli_terminate(int sig, void *ctx)
4183 static char * wpa_cli_get_default_ifname(void)
4185 char *ifname = NULL;
4188 char ifprop[PROPERTY_VALUE_MAX];
4189 if (property_get("wifi.interface", ifprop, NULL) != 0) {
4190 ifname = os_strdup(ifprop);
4191 printf("Using interface '%s'\n", ifname ? ifname : "N/A");
4194 #ifdef CONFIG_CTRL_IFACE_UNIX
4195 struct dirent *dent;
4196 DIR *dir = opendir(ctrl_iface_dir);
4200 while ((dent = readdir(dir))) {
4201 #ifdef _DIRENT_HAVE_D_TYPE
4203 * Skip the file if it is not a socket. Also accept
4204 * DT_UNKNOWN (0) in case the C library or underlying
4205 * file system does not support d_type.
4207 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
4209 #endif /* _DIRENT_HAVE_D_TYPE */
4210 if (os_strcmp(dent->d_name, ".") == 0 ||
4211 os_strcmp(dent->d_name, "..") == 0)
4213 printf("Selected interface '%s'\n", dent->d_name);
4214 ifname = os_strdup(dent->d_name);
4218 #endif /* CONFIG_CTRL_IFACE_UNIX */
4220 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4221 char buf[4096], *pos;
4223 struct wpa_ctrl *ctrl;
4226 ctrl = wpa_ctrl_open(NULL);
4230 len = sizeof(buf) - 1;
4231 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
4234 pos = os_strchr(buf, '\n');
4237 ifname = os_strdup(buf);
4239 wpa_ctrl_close(ctrl);
4240 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4241 #endif /* ANDROID */
4247 int main(int argc, char *argv[])
4252 const char *global = NULL;
4254 if (os_program_init())
4258 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
4263 action_file = optarg;
4272 ping_interval = atoi(optarg);
4278 printf("%s\n", wpa_cli_version);
4281 os_free(ctrl_ifname);
4282 ctrl_ifname = os_strdup(optarg);
4285 ctrl_iface_dir = optarg;
4296 interactive = (argc == optind) && (action_file == NULL);
4299 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
4305 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4306 ctrl_conn = wpa_ctrl_open(NULL);
4307 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4308 ctrl_conn = wpa_ctrl_open(global);
4309 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4310 if (ctrl_conn == NULL) {
4311 fprintf(stderr, "Failed to connect to wpa_supplicant "
4312 "global interface: %s error: %s\n",
4313 global, strerror(errno));
4318 update_ifnames(ctrl_conn);
4319 mon_conn = wpa_ctrl_open(global);
4321 if (wpa_ctrl_attach(mon_conn) == 0) {
4322 wpa_cli_attached = 1;
4323 eloop_register_read_sock(
4324 wpa_ctrl_get_fd(mon_conn),
4325 wpa_cli_mon_receive,
4328 printf("Failed to open monitor "
4329 "connection through global "
4330 "control interface\n");
4336 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
4338 if (ctrl_ifname == NULL)
4339 ctrl_ifname = wpa_cli_get_default_ifname();
4342 wpa_cli_interactive();
4345 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
4346 fprintf(stderr, "Failed to connect to non-global "
4347 "ctrl_ifname: %s error: %s\n",
4348 ctrl_ifname ? ctrl_ifname : "(nil)",
4354 if (wpa_ctrl_attach(ctrl_conn) == 0) {
4355 wpa_cli_attached = 1;
4357 printf("Warning: Failed to attach to "
4358 "wpa_supplicant.\n");
4363 if (daemonize && os_daemonize(pid_file))
4367 wpa_cli_action(ctrl_conn);
4369 ret = wpa_request(ctrl_conn, argc - optind,
4373 os_free(ctrl_ifname);
4380 #else /* CONFIG_CTRL_IFACE */
4381 int main(int argc, char *argv[])
4383 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
4386 #endif /* CONFIG_CTRL_IFACE */