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");
505 return wpa_ctrl_command(ctrl, "STATUS");
509 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
511 return wpa_ctrl_command(ctrl, "PING");
515 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
517 return wpa_ctrl_command(ctrl, "RELOG");
521 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
523 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
527 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
529 return wpa_ctrl_command(ctrl, "MIB");
533 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
535 return wpa_ctrl_command(ctrl, "PMKSA");
539 static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc,
542 return wpa_ctrl_command(ctrl, "PMKSA_FLUSH");
546 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
548 print_help(argc > 0 ? argv[0] : NULL);
553 static char ** wpa_cli_complete_help(const char *str, int pos)
555 int arg = get_cmd_arg_num(str, pos);
560 res = wpa_list_cmd_list();
568 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
570 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
575 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
584 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
590 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
591 if (os_snprintf_error(sizeof(cmd), res)) {
592 printf("Too long SET command.\n");
595 return wpa_ctrl_command(ctrl, cmd);
598 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
602 static char ** wpa_cli_complete_set(const char *str, int pos)
604 int arg = get_cmd_arg_num(str, pos);
605 const char *fields[] = {
607 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
608 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
609 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
610 "wps_fragment_size", "wps_version_number", "ampdu",
611 "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
612 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
614 /* global configuration parameters */
615 #ifdef CONFIG_CTRL_IFACE
616 "ctrl_interface", "no_ctrl_interface", "ctrl_interface_group",
617 #endif /* CONFIG_CTRL_IFACE */
618 "eapol_version", "ap_scan", "bgscan",
620 "user_mpm", "max_peer_links", "mesh_max_inactivity",
621 "dot11RSNASAERetransPeriod",
622 #endif /* CONFIG_MESH */
623 "disable_scan_offload", "fast_reauth", "opensc_engine_path",
624 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
625 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
626 "dot11RSNAConfigPMKLifetime",
627 "dot11RSNAConfigPMKReauthThreshold",
628 "dot11RSNAConfigSATimeout",
629 #ifndef CONFIG_NO_CONFIG_WRITE
631 #endif /* CONFIG_NO_CONFIG_WRITE */
634 "uuid", "device_name", "manufacturer", "model_name",
635 "model_number", "serial_number", "device_type", "os_version",
636 "config_methods", "wps_cred_processing", "wps_vendor_ext_m1",
637 #endif /* CONFIG_WPS */
640 "p2p_listen_reg_class", "p2p_listen_channel",
641 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
642 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
643 "p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan",
644 "p2p_no_go_freq", "p2p_add_cli_chan",
645 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
646 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
647 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
648 "ip_addr_start", "ip_addr_end",
649 #endif /* CONFIG_P2P */
650 "country", "bss_max_count", "bss_expiration_age",
651 "bss_expiration_scan_count", "filter_ssids", "filter_rssi",
652 "max_num_sta", "disassoc_low_ack",
655 #endif /* CONFIG_HS20 */
656 "interworking", "hessid", "access_network_type", "pbc_in_m1",
657 "autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey",
658 "wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend",
659 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
660 "sae_groups", "dtim_period", "beacon_int",
661 "ap_vendor_elements", "ignore_old_scan_res", "freq_list",
662 "scan_cur_freq", "sched_scan_interval",
663 "tdls_external_control", "osu_dir", "wowlan_triggers",
664 "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
665 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
666 "reassoc_same_bss_optim", "wps_priority"
668 int i, num_fields = ARRAY_SIZE(fields);
671 char **res = os_calloc(num_fields + 1, sizeof(char *));
674 for (i = 0; i < num_fields; i++) {
675 res[i] = os_strdup(fields[i]);
682 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
683 return cli_txt_list_array(&bsses);
688 static int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[])
690 return wpa_ctrl_command(ctrl, "DUMP");
694 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
696 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
700 static char ** wpa_cli_complete_get(const char *str, int pos)
702 int arg = get_cmd_arg_num(str, pos);
703 const char *fields[] = {
704 #ifdef CONFIG_CTRL_IFACE
705 "ctrl_interface", "ctrl_interface_group",
706 #endif /* CONFIG_CTRL_IFACE */
707 "eapol_version", "ap_scan",
709 "user_mpm", "max_peer_links", "mesh_max_inactivity",
710 #endif /* CONFIG_MESH */
711 "disable_scan_offload", "fast_reauth", "opensc_engine_path",
712 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
713 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
714 "dot11RSNAConfigPMKLifetime",
715 "dot11RSNAConfigPMKReauthThreshold",
716 "dot11RSNAConfigSATimeout",
717 #ifndef CONFIG_NO_CONFIG_WRITE
719 #endif /* CONFIG_NO_CONFIG_WRITE */
721 "device_name", "manufacturer", "model_name", "model_number",
722 "serial_number", "config_methods", "wps_cred_processing",
723 #endif /* CONFIG_WPS */
725 "p2p_listen_reg_class", "p2p_listen_channel",
726 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
727 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
728 "p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan",
729 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
730 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
731 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
732 "ip_addr_start", "ip_addr_end",
733 #endif /* CONFIG_P2P */
734 "bss_max_count", "bss_expiration_age",
735 "bss_expiration_scan_count", "filter_ssids", "filter_rssi",
736 "max_num_sta", "disassoc_low_ack",
739 #endif /* CONFIG_HS20 */
740 "interworking", "access_network_type", "pbc_in_m1", "autoscan",
741 "wps_nfc_dev_pw_id", "ext_password_backend",
742 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
743 "dtim_period", "beacon_int", "ignore_old_scan_res",
744 "scan_cur_freq", "sched_scan_interval",
745 "tdls_external_control", "osu_dir", "wowlan_triggers",
746 "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
747 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
748 "reassoc_same_bss_optim"
750 int i, num_fields = ARRAY_SIZE(fields);
753 char **res = os_calloc(num_fields + 1, sizeof(char *));
756 for (i = 0; i < num_fields; i++) {
757 res[i] = os_strdup(fields[i]);
768 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
770 return wpa_ctrl_command(ctrl, "LOGOFF");
774 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
776 return wpa_ctrl_command(ctrl, "LOGON");
780 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
783 return wpa_ctrl_command(ctrl, "REASSOCIATE");
787 static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[])
789 return wpa_ctrl_command(ctrl, "REATTACH");
793 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
796 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
800 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
802 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
806 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
809 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
813 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
816 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
820 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
823 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
827 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
833 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
835 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
836 if (os_snprintf_error(sizeof(cmd), res)) {
837 printf("Too long BSS_FLUSH command.\n");
840 return wpa_ctrl_command(ctrl, cmd);
844 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
847 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
851 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
853 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
857 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
859 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
863 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
866 printf("Invalid WPS_PIN command: need one or two arguments:\n"
867 "- BSSID: use 'any' to select any\n"
868 "- PIN: optional, used only with devices that have no "
873 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
877 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
880 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
884 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
887 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
891 #ifdef CONFIG_WPS_NFC
893 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
895 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
899 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
902 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
906 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
909 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
913 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
921 printf("Invalid 'wps_nfc_tag_read' command - one argument "
926 buflen = 18 + os_strlen(argv[0]);
927 buf = os_malloc(buflen);
930 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
932 ret = wpa_ctrl_command(ctrl, buf);
939 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
942 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
946 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
949 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
953 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
956 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
959 #endif /* CONFIG_WPS_NFC */
962 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
968 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
970 else if (argc == 5 || argc == 6) {
971 char ssid_hex[2 * SSID_MAX_LEN + 1];
972 char key_hex[2 * 64 + 1];
976 for (i = 0; i < SSID_MAX_LEN; i++) {
977 if (argv[2][i] == '\0')
979 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
984 for (i = 0; i < 64; i++) {
985 if (argv[5][i] == '\0')
987 os_snprintf(&key_hex[i * 2], 3, "%02x",
992 res = os_snprintf(cmd, sizeof(cmd),
993 "WPS_REG %s %s %s %s %s %s",
994 argv[0], argv[1], ssid_hex, argv[3], argv[4],
997 printf("Invalid WPS_REG command: need two arguments:\n"
998 "- BSSID of the target AP\n"
1000 printf("Alternatively, six arguments can be used to "
1001 "reconfigure the AP:\n"
1002 "- BSSID of the target AP\n"
1005 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1006 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1011 if (os_snprintf_error(sizeof(cmd), res)) {
1012 printf("Too long WPS_REG command.\n");
1015 return wpa_ctrl_command(ctrl, cmd);
1019 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
1022 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
1026 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
1029 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
1033 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
1036 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
1041 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
1045 printf("Invalid WPS_ER_PIN command: need at least two "
1047 "- UUID: use 'any' to select any\n"
1048 "- PIN: Enrollee PIN\n"
1049 "optional: - Enrollee MAC address\n");
1053 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
1057 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
1060 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
1064 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1068 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1069 "- UUID: specify which AP to use\n"
1074 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
1078 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1082 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1084 "- UUID: specify which AP to use\n"
1085 "- Network configuration id\n");
1089 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
1093 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1099 if (argc == 5 || argc == 6) {
1100 char ssid_hex[2 * SSID_MAX_LEN + 1];
1101 char key_hex[2 * 64 + 1];
1105 for (i = 0; i < SSID_MAX_LEN; i++) {
1106 if (argv[2][i] == '\0')
1108 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1113 for (i = 0; i < 64; i++) {
1114 if (argv[5][i] == '\0')
1116 os_snprintf(&key_hex[i * 2], 3, "%02x",
1121 res = os_snprintf(cmd, sizeof(cmd),
1122 "WPS_ER_CONFIG %s %s %s %s %s %s",
1123 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1126 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1130 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1131 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1136 if (os_snprintf_error(sizeof(cmd), res)) {
1137 printf("Too long WPS_ER_CONFIG command.\n");
1140 return wpa_ctrl_command(ctrl, cmd);
1144 #ifdef CONFIG_WPS_NFC
1145 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1149 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1151 "- WPS/NDEF: token format\n"
1152 "- UUID: specify which AP to use\n");
1156 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1158 #endif /* CONFIG_WPS_NFC */
1161 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1163 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1167 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1169 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1173 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1175 char cmd[256], *pos, *end;
1179 printf("Invalid IDENTITY command: needs two arguments "
1180 "(network id and identity)\n");
1184 end = cmd + sizeof(cmd);
1186 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1188 if (os_snprintf_error(end - pos, ret)) {
1189 printf("Too long IDENTITY command.\n");
1193 for (i = 2; i < argc; i++) {
1194 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1195 if (os_snprintf_error(end - pos, ret)) {
1196 printf("Too long IDENTITY command.\n");
1202 return wpa_ctrl_command(ctrl, cmd);
1206 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1208 char cmd[256], *pos, *end;
1212 printf("Invalid PASSWORD command: needs two arguments "
1213 "(network id and password)\n");
1217 end = cmd + sizeof(cmd);
1219 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1221 if (os_snprintf_error(end - pos, ret)) {
1222 printf("Too long PASSWORD command.\n");
1226 for (i = 2; i < argc; i++) {
1227 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1228 if (os_snprintf_error(end - pos, ret)) {
1229 printf("Too long PASSWORD command.\n");
1235 return wpa_ctrl_command(ctrl, cmd);
1239 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1242 char cmd[256], *pos, *end;
1246 printf("Invalid NEW_PASSWORD command: needs two arguments "
1247 "(network id and password)\n");
1251 end = cmd + sizeof(cmd);
1253 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1255 if (os_snprintf_error(end - pos, ret)) {
1256 printf("Too long NEW_PASSWORD command.\n");
1260 for (i = 2; i < argc; i++) {
1261 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1262 if (os_snprintf_error(end - pos, ret)) {
1263 printf("Too long NEW_PASSWORD command.\n");
1269 return wpa_ctrl_command(ctrl, cmd);
1273 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1275 char cmd[256], *pos, *end;
1279 printf("Invalid PIN command: needs two arguments "
1280 "(network id and pin)\n");
1284 end = cmd + sizeof(cmd);
1286 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1288 if (os_snprintf_error(end - pos, ret)) {
1289 printf("Too long PIN command.\n");
1293 for (i = 2; i < argc; i++) {
1294 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1295 if (os_snprintf_error(end - pos, ret)) {
1296 printf("Too long PIN command.\n");
1301 return wpa_ctrl_command(ctrl, cmd);
1305 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1307 char cmd[256], *pos, *end;
1311 printf("Invalid OTP command: needs two arguments (network "
1312 "id and password)\n");
1316 end = cmd + sizeof(cmd);
1318 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1320 if (os_snprintf_error(end - pos, ret)) {
1321 printf("Too long OTP command.\n");
1325 for (i = 2; i < argc; i++) {
1326 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1327 if (os_snprintf_error(end - pos, ret)) {
1328 printf("Too long OTP command.\n");
1334 return wpa_ctrl_command(ctrl, cmd);
1338 static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
1340 char cmd[256], *pos, *end;
1344 printf("Invalid SIM command: needs two arguments "
1345 "(network id and SIM operation response)\n");
1349 end = cmd + sizeof(cmd);
1351 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
1353 if (os_snprintf_error(end - pos, ret)) {
1354 printf("Too long SIM command.\n");
1358 for (i = 2; i < argc; i++) {
1359 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1360 if (os_snprintf_error(end - pos, ret)) {
1361 printf("Too long SIM command.\n");
1366 return wpa_ctrl_command(ctrl, cmd);
1370 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1373 char cmd[256], *pos, *end;
1377 printf("Invalid PASSPHRASE command: needs two arguments "
1378 "(network id and passphrase)\n");
1382 end = cmd + sizeof(cmd);
1384 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1386 if (os_snprintf_error(end - pos, ret)) {
1387 printf("Too long PASSPHRASE command.\n");
1391 for (i = 2; i < argc; i++) {
1392 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1393 if (os_snprintf_error(end - pos, ret)) {
1394 printf("Too long PASSPHRASE command.\n");
1400 return wpa_ctrl_command(ctrl, cmd);
1404 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1407 printf("Invalid BSSID command: needs two arguments (network "
1412 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1416 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1418 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1422 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1424 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1428 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1431 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1435 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1438 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1442 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1445 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1449 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1452 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1456 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1459 int res = wpa_ctrl_command(ctrl, "ADD_NETWORK");
1461 update_networks(ctrl);
1466 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1469 int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1471 update_networks(ctrl);
1476 static void wpa_cli_show_network_variables(void)
1478 printf("set_network variables:\n"
1479 " ssid (network name, SSID)\n"
1480 " psk (WPA passphrase or pre-shared key)\n"
1481 " key_mgmt (key management protocol)\n"
1482 " identity (EAP identity)\n"
1483 " password (EAP password)\n"
1486 "Note: Values are entered in the same format as the "
1487 "configuration file is using,\n"
1488 "i.e., strings values need to be inside double quotation "
1490 "For example: set_network 1 ssid \"network name\"\n"
1492 "Please see wpa_supplicant.conf documentation for full list "
1493 "of\navailable variables.\n");
1497 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1501 wpa_cli_show_network_variables();
1506 printf("Invalid SET_NETWORK command: needs three arguments\n"
1507 "(network id, variable name, and value)\n");
1511 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1515 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1519 wpa_cli_show_network_variables();
1524 printf("Invalid GET_NETWORK command: needs two arguments\n"
1525 "(network id and variable name)\n");
1529 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1533 static const char *network_fields[] = {
1534 "ssid", "scan_ssid", "bssid", "bssid_blacklist",
1535 "bssid_whitelist", "psk", "proto", "key_mgmt",
1536 "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
1538 #ifdef IEEE8021X_EAPOL
1539 "eap", "identity", "anonymous_identity", "password", "ca_cert",
1540 "ca_path", "client_cert", "private_key", "private_key_passwd",
1541 "dh_file", "subject_match", "altsubject_match",
1542 "domain_suffix_match", "domain_match", "ca_cert2", "ca_path2",
1543 "client_cert2", "private_key2", "private_key2_passwd",
1544 "dh_file2", "subject_match2", "altsubject_match2",
1545 "domain_suffix_match2", "domain_match2", "phase1", "phase2",
1546 "pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id",
1547 "pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id",
1548 "engine", "engine2", "eapol_flags", "sim_num",
1549 "openssl_ciphers", "erp",
1550 #endif /* IEEE8021X_EAPOL */
1551 "wep_key0", "wep_key1", "wep_key2", "wep_key3",
1552 "wep_tx_keyidx", "priority",
1553 #ifdef IEEE8021X_EAPOL
1554 "eap_workaround", "pac_file", "fragment_size", "ocsp",
1555 #endif /* IEEE8021X_EAPOL */
1557 "mode", "no_auto_peer",
1558 #else /* CONFIG_MESH */
1560 #endif /* CONFIG_MESH */
1561 "proactive_key_caching", "disabled", "id_str",
1562 #ifdef CONFIG_IEEE80211W
1564 #endif /* CONFIG_IEEE80211W */
1565 "peerkey", "mixed_cell", "frequency", "fixed_freq",
1567 "mesh_basic_rates", "dot11MeshMaxRetries",
1568 "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout",
1569 "dot11MeshHoldingTimeout",
1570 #endif /* CONFIG_MESH */
1571 "wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid",
1573 "go_p2p_dev_addr", "p2p_client_list", "psk_list",
1574 #endif /* CONFIG_P2P */
1575 #ifdef CONFIG_HT_OVERRIDES
1576 "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc",
1577 "ht40_intolerant", "disable_max_amsdu", "ampdu_factor",
1578 "ampdu_density", "ht_mcs",
1579 #endif /* CONFIG_HT_OVERRIDES */
1580 #ifdef CONFIG_VHT_OVERRIDES
1581 "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1",
1582 "vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4",
1583 "vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7",
1584 "vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2",
1585 "vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5",
1586 "vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8",
1587 #endif /* CONFIG_VHT_OVERRIDES */
1588 "ap_max_inactivity", "dtim_period", "beacon_int",
1589 #ifdef CONFIG_MACSEC
1591 #endif /* CONFIG_MACSEC */
1593 "update_identifier",
1594 #endif /* CONFIG_HS20 */
1599 static char ** wpa_cli_complete_network(const char *str, int pos)
1601 int arg = get_cmd_arg_num(str, pos);
1602 int i, num_fields = ARRAY_SIZE(network_fields);
1607 res = cli_txt_list_array(&networks);
1610 res = os_calloc(num_fields + 1, sizeof(char *));
1613 for (i = 0; i < num_fields; i++) {
1614 res[i] = os_strdup(network_fields[i]);
1623 static char ** wpa_cli_complete_network_id(const char *str, int pos)
1625 int arg = get_cmd_arg_num(str, pos);
1627 return cli_txt_list_array(&networks);
1632 static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc,
1636 wpa_cli_show_network_variables();
1641 printf("Invalid DUP_NETWORK command: needs three arguments\n"
1642 "(src netid, dest netid, and variable name)\n");
1646 return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv);
1650 static char ** wpa_cli_complete_dup_network(const char *str, int pos)
1652 int arg = get_cmd_arg_num(str, pos);
1653 int i, num_fields = ARRAY_SIZE(network_fields);
1659 res = cli_txt_list_array(&networks);
1662 res = os_calloc(num_fields + 1, sizeof(char *));
1665 for (i = 0; i < num_fields; i++) {
1666 res[i] = os_strdup(network_fields[i]);
1675 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1678 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1682 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1684 return wpa_ctrl_command(ctrl, "ADD_CRED");
1688 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1691 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1695 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1698 printf("Invalid SET_CRED command: needs three arguments\n"
1699 "(cred id, variable name, and value)\n");
1703 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1707 static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1710 printf("Invalid GET_CRED command: needs two arguments\n"
1711 "(cred id, variable name)\n");
1715 return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv);
1719 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1722 return wpa_ctrl_command(ctrl, "DISCONNECT");
1726 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1729 return wpa_ctrl_command(ctrl, "RECONNECT");
1733 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1736 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1740 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1742 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1746 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1749 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1753 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1755 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1759 static char ** wpa_cli_complete_bss(const char *str, int pos)
1761 int arg = get_cmd_arg_num(str, pos);
1766 res = cli_txt_list_array(&bsses);
1774 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1777 if (argc < 1 || argc > 2) {
1778 printf("Invalid GET_CAPABILITY command: need either one or "
1783 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1784 printf("Invalid GET_CAPABILITY command: second argument, "
1785 "if any, must be 'strict'\n");
1789 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1793 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1795 printf("Available interfaces:\n");
1796 return wpa_ctrl_command(ctrl, "INTERFACES");
1800 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1803 wpa_cli_list_interfaces(ctrl);
1807 wpa_cli_close_connection();
1808 os_free(ctrl_ifname);
1809 ctrl_ifname = os_strdup(argv[0]);
1811 printf("Failed to allocate memory\n");
1815 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
1816 printf("Connected to interface '%s.\n", ctrl_ifname);
1818 printf("Could not connect to interface '%s' - re-trying\n",
1825 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1828 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1832 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1835 return wpa_ctrl_command(ctrl, "TERMINATE");
1839 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1846 printf("Invalid INTERFACE_ADD command: needs at least one "
1847 "argument (interface name)\n"
1848 "All arguments: ifname confname driver ctrl_interface "
1849 "driver_param bridge_name [create]\n");
1854 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1855 * <driver_param>TAB<bridge_name>[TAB<create>]
1857 res = os_snprintf(cmd, sizeof(cmd),
1858 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s",
1860 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1861 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1862 argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "");
1863 if (os_snprintf_error(sizeof(cmd), res))
1865 cmd[sizeof(cmd) - 1] = '\0';
1866 return wpa_ctrl_command(ctrl, cmd);
1870 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1873 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1877 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1880 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1885 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1887 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1891 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1892 char *addr, size_t addr_len)
1894 char buf[4096], *pos;
1898 if (ctrl_conn == NULL) {
1899 printf("Not connected to hostapd - command dropped.\n");
1902 len = sizeof(buf) - 1;
1903 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1906 printf("'%s' command timed out.\n", cmd);
1908 } else if (ret < 0) {
1909 printf("'%s' command failed.\n", cmd);
1914 if (os_memcmp(buf, "FAIL", 4) == 0)
1919 while (*pos != '\0' && *pos != '\n')
1922 os_strlcpy(addr, buf, addr_len);
1927 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1929 char addr[32], cmd[64];
1931 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1934 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1935 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1941 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1944 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1948 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1951 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1954 static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
1957 return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
1960 #endif /* CONFIG_AP */
1963 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1965 return wpa_ctrl_command(ctrl, "SUSPEND");
1969 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1971 return wpa_ctrl_command(ctrl, "RESUME");
1975 #ifdef CONFIG_TESTING_OPTIONS
1976 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1978 return wpa_ctrl_command(ctrl, "DROP_SA");
1980 #endif /* CONFIG_TESTING_OPTIONS */
1983 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1985 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1991 static int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc,
1994 return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv);
1998 static int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc,
2001 return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv);
2005 static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc,
2008 return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
2011 #endif /* CONFIG_MESH */
2016 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
2018 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
2022 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
2025 int arg = get_cmd_arg_num(str, pos);
2027 res = os_calloc(6, sizeof(char *));
2030 res[0] = os_strdup("type=social");
2031 if (res[0] == NULL) {
2035 res[1] = os_strdup("type=progressive");
2038 res[2] = os_strdup("delay=");
2041 res[3] = os_strdup("dev_id=");
2045 res[4] = os_strdup("[timeout]");
2051 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
2054 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
2058 static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc,
2061 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv);
2065 static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc,
2068 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv);
2072 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
2075 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
2079 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
2081 int arg = get_cmd_arg_num(str, pos);
2086 res = cli_txt_list_array(&p2p_peers);
2094 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2097 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
2101 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2104 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
2108 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2110 int arg = get_cmd_arg_num(str, pos);
2115 res = cli_txt_list_array(&p2p_groups);
2123 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2126 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
2130 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2133 if (argc != 2 && argc != 3) {
2134 printf("Invalid P2P_PROV_DISC command: needs at least "
2135 "two arguments, address and config method\n"
2136 "(display, keypad, or pbc) and an optional join\n");
2140 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
2144 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2147 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2151 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2157 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2158 "or more arguments (address and TLVs)\n");
2162 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
2164 return wpa_ctrl_command(ctrl, cmd);
2168 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2169 int argc, char *argv[])
2171 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
2175 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2182 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2183 "arguments (freq, address, dialog token, and TLVs)\n");
2187 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2188 argv[0], argv[1], argv[2], argv[3]);
2189 if (os_snprintf_error(sizeof(cmd), res))
2191 cmd[sizeof(cmd) - 1] = '\0';
2192 return wpa_ctrl_command(ctrl, cmd);
2196 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2199 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2203 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2204 int argc, char *argv[])
2206 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
2210 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2213 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2217 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2221 printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n");
2225 return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv);
2229 static int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc,
2232 if (argc < 5 || argc > 6) {
2233 printf("Invalid P2P_SERVICE_REP command: needs 5-6 "
2238 return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv);
2242 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2248 if (argc != 2 && argc != 3) {
2249 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2255 res = os_snprintf(cmd, sizeof(cmd),
2256 "P2P_SERVICE_DEL %s %s %s",
2257 argv[0], argv[1], argv[2]);
2259 res = os_snprintf(cmd, sizeof(cmd),
2260 "P2P_SERVICE_DEL %s %s",
2262 if (os_snprintf_error(sizeof(cmd), res))
2264 cmd[sizeof(cmd) - 1] = '\0';
2265 return wpa_ctrl_command(ctrl, cmd);
2269 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2270 int argc, char *argv[])
2272 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
2276 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2277 int argc, char *argv[])
2279 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
2283 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2285 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2289 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2291 int arg = get_cmd_arg_num(str, pos);
2296 res = cli_txt_list_array(&p2p_peers);
2304 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2305 char *addr, size_t addr_len,
2308 char buf[4096], *pos;
2312 if (ctrl_conn == NULL)
2314 len = sizeof(buf) - 1;
2315 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2318 printf("'%s' command timed out.\n", cmd);
2320 } else if (ret < 0) {
2321 printf("'%s' command failed.\n", cmd);
2326 if (os_memcmp(buf, "FAIL", 4) == 0)
2330 while (*pos != '\0' && *pos != '\n')
2333 os_strlcpy(addr, buf, addr_len);
2334 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2335 printf("%s\n", addr);
2340 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2342 char addr[32], cmd[64];
2345 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2347 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2348 addr, sizeof(addr), discovered))
2351 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2352 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2359 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2361 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2365 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
2367 int arg = get_cmd_arg_num(str, pos);
2368 const char *fields[] = {
2388 int i, num_fields = ARRAY_SIZE(fields);
2391 char **res = os_calloc(num_fields + 1, sizeof(char *));
2394 for (i = 0; i < num_fields; i++) {
2395 res[i] = os_strdup(fields[i]);
2402 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
2403 return cli_txt_list_array(&p2p_peers);
2409 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2411 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2415 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2418 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2422 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2425 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2429 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2432 if (argc != 0 && argc != 2 && argc != 4) {
2433 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2434 "(preferred duration, interval; in microsecods).\n"
2435 "Optional second pair can be used to provide "
2436 "acceptable values.\n");
2440 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2444 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2447 if (argc != 0 && argc != 2) {
2448 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2449 "(availability period, availability interval; in "
2451 "Extended Listen Timing can be cancelled with this "
2452 "command when used without parameters.\n");
2456 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2460 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
2463 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
2466 #endif /* CONFIG_P2P */
2468 #ifdef CONFIG_WIFI_DISPLAY
2470 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2476 if (argc != 1 && argc != 2) {
2477 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2478 "arguments (subelem, hexdump)\n");
2482 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2483 argv[0], argc > 1 ? argv[1] : "");
2484 if (os_snprintf_error(sizeof(cmd), res))
2486 cmd[sizeof(cmd) - 1] = '\0';
2487 return wpa_ctrl_command(ctrl, cmd);
2491 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2498 printf("Invalid WFD_SUBELEM_GET command: needs one "
2499 "argument (subelem)\n");
2503 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2505 if (os_snprintf_error(sizeof(cmd), res))
2507 cmd[sizeof(cmd) - 1] = '\0';
2508 return wpa_ctrl_command(ctrl, cmd);
2510 #endif /* CONFIG_WIFI_DISPLAY */
2513 #ifdef CONFIG_INTERWORKING
2514 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2517 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2521 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2524 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2528 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2531 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2535 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2538 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2542 static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc,
2545 return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv);
2549 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2551 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2555 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2558 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2562 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2565 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2567 #endif /* CONFIG_INTERWORKING */
2572 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2575 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2579 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2585 printf("Command needs one or two arguments (dst mac addr and "
2586 "optional home realm)\n");
2590 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2594 return wpa_ctrl_command(ctrl, cmd);
2598 static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc,
2604 printf("Command needs two arguments (dst mac addr and "
2609 if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0)
2612 return wpa_ctrl_command(ctrl, cmd);
2616 static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[])
2618 return wpa_ctrl_command(ctrl, "FETCH_OSU");
2622 static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc,
2625 return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU");
2628 #endif /* CONFIG_HS20 */
2631 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2634 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2638 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2641 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2645 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2648 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2652 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2655 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2659 static int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc,
2662 return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv);
2666 static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc,
2669 return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv);
2673 static int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc,
2676 return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv);
2680 static int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc,
2683 return wpa_ctrl_command(ctrl, "WMM_AC_STATUS");
2687 static int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc,
2690 return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv);
2694 static int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc,
2697 return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv);
2701 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2704 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2708 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2711 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2715 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2718 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2722 #ifdef CONFIG_AUTOSCAN
2724 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2727 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2729 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2732 #endif /* CONFIG_AUTOSCAN */
2737 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2739 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2743 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2745 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2748 #endif /* CONFIG_WNM */
2751 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2755 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2760 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2762 return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
2764 #endif /* ANDROID */
2767 static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
2769 return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv);
2773 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2775 return wpa_ctrl_command(ctrl, "FLUSH");
2779 static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
2781 return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
2785 static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc,
2788 return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv);
2792 static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2794 return wpa_ctrl_command(ctrl, "ERP_FLUSH");
2798 static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc,
2801 return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv);
2805 static int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc,
2808 return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv);
2812 enum wpa_cli_cmd_flags {
2813 cli_cmd_flag_none = 0x00,
2814 cli_cmd_flag_sensitive = 0x01
2817 struct wpa_cli_cmd {
2819 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2820 char ** (*completion)(const char *str, int pos);
2821 enum wpa_cli_cmd_flags flags;
2825 static const struct wpa_cli_cmd wpa_cli_commands[] = {
2826 { "status", wpa_cli_cmd_status, NULL,
2828 "[verbose] = get current WPA/EAPOL/EAP status" },
2829 { "ifname", wpa_cli_cmd_ifname, NULL,
2831 "= get current interface name" },
2832 { "ping", wpa_cli_cmd_ping, NULL,
2834 "= pings wpa_supplicant" },
2835 { "relog", wpa_cli_cmd_relog, NULL,
2837 "= re-open log-file (allow rolling logs)" },
2838 { "note", wpa_cli_cmd_note, NULL,
2840 "<text> = add a note to wpa_supplicant debug log" },
2841 { "mib", wpa_cli_cmd_mib, NULL,
2843 "= get MIB variables (dot1x, dot11)" },
2844 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2846 "[command] = show usage help" },
2847 { "interface", wpa_cli_cmd_interface, NULL,
2849 "[ifname] = show interfaces/select interface" },
2850 { "level", wpa_cli_cmd_level, NULL,
2852 "<debug level> = change debug level" },
2853 { "license", wpa_cli_cmd_license, NULL,
2855 "= show full wpa_cli license" },
2856 { "quit", wpa_cli_cmd_quit, NULL,
2859 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2861 "= set variables (shows list of variables when run without "
2863 { "dump", wpa_cli_cmd_dump, NULL,
2865 "= dump config variables" },
2866 { "get", wpa_cli_cmd_get, wpa_cli_complete_get,
2868 "<name> = get information" },
2869 { "logon", wpa_cli_cmd_logon, NULL,
2871 "= IEEE 802.1X EAPOL state machine logon" },
2872 { "logoff", wpa_cli_cmd_logoff, NULL,
2874 "= IEEE 802.1X EAPOL state machine logoff" },
2875 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2877 "= show PMKSA cache" },
2878 { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL,
2880 "= flush PMKSA cache entries" },
2881 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2883 "= force reassociation" },
2884 { "reattach", wpa_cli_cmd_reattach, NULL,
2886 "= force reassociation back to the same BSS" },
2887 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2889 "<BSSID> = force preauthentication" },
2890 { "identity", wpa_cli_cmd_identity, NULL,
2892 "<network id> <identity> = configure identity for an SSID" },
2893 { "password", wpa_cli_cmd_password, NULL,
2894 cli_cmd_flag_sensitive,
2895 "<network id> <password> = configure password for an SSID" },
2896 { "new_password", wpa_cli_cmd_new_password, NULL,
2897 cli_cmd_flag_sensitive,
2898 "<network id> <password> = change password for an SSID" },
2899 { "pin", wpa_cli_cmd_pin, NULL,
2900 cli_cmd_flag_sensitive,
2901 "<network id> <pin> = configure pin for an SSID" },
2902 { "otp", wpa_cli_cmd_otp, NULL,
2903 cli_cmd_flag_sensitive,
2904 "<network id> <password> = configure one-time-password for an SSID"
2906 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2907 cli_cmd_flag_sensitive,
2908 "<network id> <passphrase> = configure private key passphrase\n"
2910 { "sim", wpa_cli_cmd_sim, NULL,
2911 cli_cmd_flag_sensitive,
2912 "<network id> <pin> = report SIM operation result" },
2913 { "bssid", wpa_cli_cmd_bssid, NULL,
2915 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2916 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2918 "<BSSID> = add a BSSID to the blacklist\n"
2919 "blacklist clear = clear the blacklist\n"
2920 "blacklist = display the blacklist" },
2921 { "log_level", wpa_cli_cmd_log_level, NULL,
2923 "<level> [<timestamp>] = update the log level/timestamp\n"
2924 "log_level = display the current log level and log options" },
2925 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2927 "= list configured networks" },
2928 { "select_network", wpa_cli_cmd_select_network,
2929 wpa_cli_complete_network_id,
2931 "<network id> = select a network (disable others)" },
2932 { "enable_network", wpa_cli_cmd_enable_network,
2933 wpa_cli_complete_network_id,
2935 "<network id> = enable a network" },
2936 { "disable_network", wpa_cli_cmd_disable_network,
2937 wpa_cli_complete_network_id,
2939 "<network id> = disable a network" },
2940 { "add_network", wpa_cli_cmd_add_network, NULL,
2942 "= add a network" },
2943 { "remove_network", wpa_cli_cmd_remove_network,
2944 wpa_cli_complete_network_id,
2946 "<network id> = remove a network" },
2947 { "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network,
2948 cli_cmd_flag_sensitive,
2949 "<network id> <variable> <value> = set network variables (shows\n"
2950 " list of variables when run without arguments)" },
2951 { "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network,
2953 "<network id> <variable> = get network variables" },
2954 { "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network,
2956 "<src network id> <dst network id> <variable> = duplicate network variables"
2958 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2960 "= list configured credentials" },
2961 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2963 "= add a credential" },
2964 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2966 "<cred id> = remove a credential" },
2967 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2968 cli_cmd_flag_sensitive,
2969 "<cred id> <variable> <value> = set credential variables" },
2970 { "get_cred", wpa_cli_cmd_get_cred, NULL,
2972 "<cred id> <variable> = get credential variables" },
2973 { "save_config", wpa_cli_cmd_save_config, NULL,
2975 "= save the current configuration" },
2976 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2978 "= disconnect and wait for reassociate/reconnect command before\n"
2980 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2982 "= like reassociate, but only takes effect if already disconnected"
2984 { "scan", wpa_cli_cmd_scan, NULL,
2986 "= request new BSS scan" },
2987 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2989 "= get latest scan results" },
2990 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2992 "<<idx> | <bssid>> = get detailed scan result info" },
2993 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2995 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2996 "= get capabilities" },
2997 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2999 "= force wpa_supplicant to re-read its configuration file" },
3000 { "terminate", wpa_cli_cmd_terminate, NULL,
3002 "= terminate wpa_supplicant" },
3003 { "interface_add", wpa_cli_cmd_interface_add, NULL,
3005 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
3006 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
3008 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
3010 "<ifname> = removes the interface" },
3011 { "interface_list", wpa_cli_cmd_interface_list, NULL,
3013 "= list available interfaces" },
3014 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
3016 "<value> = set ap_scan parameter" },
3017 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
3019 "<value> = set scan_interval parameter (in seconds)" },
3020 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
3022 "<value> = set BSS expiration age parameter" },
3023 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
3025 "<value> = set BSS expiration scan count parameter" },
3026 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
3028 "<value> = set BSS flush age (0 by default)" },
3029 { "stkstart", wpa_cli_cmd_stkstart, NULL,
3031 "<addr> = request STK negotiation with <addr>" },
3032 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
3034 "<addr> = request over-the-DS FT with <addr>" },
3035 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
3037 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
3038 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
3039 cli_cmd_flag_sensitive,
3040 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
3042 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
3043 cli_cmd_flag_sensitive,
3044 "<PIN> = verify PIN checksum" },
3045 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
3046 "Cancels the pending WPS operation" },
3047 #ifdef CONFIG_WPS_NFC
3048 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
3050 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
3051 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
3053 "<WPS|NDEF> = build configuration token" },
3054 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
3056 "<WPS|NDEF> = create password token" },
3057 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
3058 cli_cmd_flag_sensitive,
3059 "<hexdump of payload> = report read NFC tag with WPS data" },
3060 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
3062 "<NDEF> <WPS> = create NFC handover request" },
3063 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
3065 "<NDEF> <WPS> = create NFC handover select" },
3066 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
3068 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
3070 #endif /* CONFIG_WPS_NFC */
3071 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
3072 cli_cmd_flag_sensitive,
3073 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
3074 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
3075 cli_cmd_flag_sensitive,
3076 "[params..] = enable/disable AP PIN" },
3077 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
3079 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
3080 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
3082 "= stop Wi-Fi Protected Setup External Registrar" },
3083 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
3084 cli_cmd_flag_sensitive,
3085 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
3086 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
3088 "<UUID> = accept an Enrollee PBC using External Registrar" },
3089 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
3090 cli_cmd_flag_sensitive,
3091 "<UUID> <PIN> = learn AP configuration" },
3092 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
3094 "<UUID> <network id> = set AP configuration for enrolling" },
3095 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
3096 cli_cmd_flag_sensitive,
3097 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
3098 #ifdef CONFIG_WPS_NFC
3099 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
3101 "<WPS/NDEF> <UUID> = build NFC configuration token" },
3102 #endif /* CONFIG_WPS_NFC */
3103 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
3105 "<addr> = request RSN authentication with <addr> in IBSS" },
3107 { "sta", wpa_cli_cmd_sta, NULL,
3109 "<addr> = get information about an associated station (AP)" },
3110 { "all_sta", wpa_cli_cmd_all_sta, NULL,
3112 "= get information about all associated stations (AP)" },
3113 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
3115 "<addr> = deauthenticate a station" },
3116 { "disassociate", wpa_cli_cmd_disassociate, NULL,
3118 "<addr> = disassociate a station" },
3119 { "chan_switch", wpa_cli_cmd_chanswitch, NULL,
3121 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
3122 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
3123 " = CSA parameters" },
3124 #endif /* CONFIG_AP */
3125 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
3126 "= notification of suspend/hibernate" },
3127 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
3128 "= notification of resume/thaw" },
3129 #ifdef CONFIG_TESTING_OPTIONS
3130 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
3131 "= drop SA without deauth/disassoc (test command)" },
3132 #endif /* CONFIG_TESTING_OPTIONS */
3133 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
3135 "<addr> = roam to the specified BSS" },
3137 { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL,
3139 "[ifname] = Create a new mesh interface" },
3140 { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL,
3142 "<network id> = join a mesh network (disable others)" },
3143 { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
3145 "<ifname> = Remove mesh group interface" },
3146 #endif /* CONFIG_MESH */
3148 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
3150 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3151 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
3152 "= stop P2P Devices search" },
3153 { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL,
3155 "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" },
3156 { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL,
3158 "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" },
3159 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
3161 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
3162 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
3163 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3164 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
3165 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
3166 "<ifname> = remove P2P group interface (terminate group if GO)" },
3167 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
3168 "[ht40] = add a new P2P group (local end as GO)" },
3169 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
3170 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3171 "<addr> <method> = request provisioning discovery" },
3172 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
3174 "= get the passphrase for a group (GO only)" },
3175 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
3176 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3177 "<addr> <TLVs> = schedule service discovery request" },
3178 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
3179 NULL, cli_cmd_flag_none,
3180 "<id> = cancel pending service discovery request" },
3181 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
3183 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3184 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
3186 "= indicate change in local services" },
3187 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
3189 "<external> = set external processing of service discovery" },
3190 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
3192 "= remove all stored service entries" },
3193 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
3195 "<bonjour|upnp|asp> <query|version> <response|service> = add a local "
3197 { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL,
3199 "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace "
3200 "local ASP service" },
3201 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
3203 "<bonjour|upnp> <query|version> [|service] = remove a local "
3205 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
3207 "<addr> = reject connection attempts from a specific peer" },
3208 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
3210 "<cmd> [peer=addr] = invite peer" },
3211 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
3212 "[discovered] = list known (optionally, only fully discovered) P2P "
3214 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
3216 "<address> = show information about known P2P peer" },
3217 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
3219 "<field> <value> = set a P2P parameter" },
3220 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
3221 "= flush P2P state" },
3222 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
3223 "= cancel P2P group formation" },
3224 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
3225 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3226 "<address> = unauthorize a peer" },
3227 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
3229 "[<duration> <interval>] [<duration> <interval>] = request GO "
3231 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
3233 "[<period> <interval>] = set extended listen timing" },
3234 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
3235 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3236 "<address|iface=address> = remove a peer from all groups" },
3237 #endif /* CONFIG_P2P */
3238 #ifdef CONFIG_WIFI_DISPLAY
3239 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
3241 "<subelem> [contents] = set Wi-Fi Display subelement" },
3242 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
3244 "<subelem> = get Wi-Fi Display subelement" },
3245 #endif /* CONFIG_WIFI_DISPLAY */
3246 #ifdef CONFIG_INTERWORKING
3247 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
3248 "= fetch ANQP information for all APs" },
3249 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
3251 "= stop fetch_anqp operation" },
3252 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
3254 "[auto] = perform Interworking network selection" },
3255 { "interworking_connect", wpa_cli_cmd_interworking_connect,
3256 wpa_cli_complete_bss, cli_cmd_flag_none,
3257 "<BSSID> = connect using Interworking credentials" },
3258 { "interworking_add_network", wpa_cli_cmd_interworking_add_network,
3259 wpa_cli_complete_bss, cli_cmd_flag_none,
3260 "<BSSID> = connect using Interworking credentials" },
3261 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
3263 "<addr> <info id>[,<info id>]... = request ANQP information" },
3264 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
3266 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
3267 { "gas_response_get", wpa_cli_cmd_gas_response_get,
3268 wpa_cli_complete_bss, cli_cmd_flag_none,
3269 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
3270 #endif /* CONFIG_INTERWORKING */
3272 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
3274 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3276 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
3277 wpa_cli_complete_bss, cli_cmd_flag_none,
3278 "<addr> <home realm> = get HS20 nai home realm list" },
3279 { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request,
3280 wpa_cli_complete_bss, cli_cmd_flag_none,
3281 "<addr> <icon name> = get Hotspot 2.0 OSU icon" },
3282 { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none,
3283 "= fetch OSU provider information from all APs" },
3284 { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL,
3286 "= cancel fetch_osu command" },
3287 #endif /* CONFIG_HS20 */
3288 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
3290 "<0/1> = disable/enable automatic reconnection" },
3291 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
3293 "<addr> = request TDLS discovery with <addr>" },
3294 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
3296 "<addr> = request TDLS setup with <addr>" },
3297 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
3299 "<addr> = tear down TDLS with <addr>" },
3300 { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL,
3302 "<addr> = TDLS link status with <addr>" },
3303 { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
3305 "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
3306 "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] "
3307 "= add WMM-AC traffic stream" },
3308 { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL,
3310 "<tsid> = delete WMM-AC traffic stream" },
3311 { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL,
3313 "= show status for Wireless Multi-Media Admission-Control" },
3314 { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL,
3316 "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] "
3317 "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching "
3319 { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL,
3321 "<addr> = disable channel switching with TDLS peer <addr>" },
3322 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
3324 "= get signal parameters" },
3325 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
3327 "= get TX/RX packet counters" },
3328 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
3330 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3331 #ifdef CONFIG_AUTOSCAN
3332 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
3333 "[params] = Set or unset (if none) autoscan parameters" },
3334 #endif /* CONFIG_AUTOSCAN */
3336 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
3337 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
3338 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
3339 "<query reason> = Send BSS Transition Management Query" },
3340 #endif /* CONFIG_WNM */
3341 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
3342 "<params..> = Sent unprocessed command" },
3343 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
3344 "= flush wpa_supplicant state" },
3346 { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
3347 "<command> = driver private commands" },
3348 #endif /* ANDROID */
3349 { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
3350 "= radio_work <show/add/done>" },
3351 { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
3352 "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
3354 { "neighbor_rep_request",
3355 wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
3356 "[ssid=<SSID>] = Trigger request to AP for neighboring AP report "
3357 "(with optional given SSID, default: current SSID)"
3359 { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
3360 "= flush ERP keys" },
3362 wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none,
3363 "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
3364 "mask=mac-address-mask] = scan MAC randomization"
3366 { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL,
3368 "<interface type> = retrieve preferred freq list for the specified interface type" },
3369 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
3374 * Prints command usage, lines are padded with the specified string.
3376 static void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad)
3381 printf("%s%s ", pad, cmd->cmd);
3382 for (n = 0; (c = cmd->usage[n]); n++) {
3391 static void print_help(const char *cmd)
3394 printf("commands:\n");
3395 for (n = 0; wpa_cli_commands[n].cmd; n++) {
3396 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
3397 print_cmd_help(&wpa_cli_commands[n], " ");
3402 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3404 const char *c, *delim;
3408 delim = os_strchr(cmd, ' ');
3412 len = os_strlen(cmd);
3414 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3415 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3416 return (wpa_cli_commands[n].flags &
3417 cli_cmd_flag_sensitive);
3423 static char ** wpa_list_cmd_list(void)
3427 struct cli_txt_entry *e;
3429 count = ARRAY_SIZE(wpa_cli_commands);
3430 count += dl_list_len(&p2p_groups);
3431 count += dl_list_len(&ifnames);
3432 res = os_calloc(count + 1, sizeof(char *));
3436 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3437 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3442 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
3443 size_t len = 8 + os_strlen(e->txt);
3444 res[i] = os_malloc(len);
3447 os_snprintf(res[i], len, "ifname=%s", e->txt);
3451 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
3452 res[i] = os_strdup(e->txt);
3462 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3467 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3468 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3469 if (wpa_cli_commands[i].completion)
3470 return wpa_cli_commands[i].completion(str,
3473 printf("\r%s\n", wpa_cli_commands[i].usage);
3483 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3489 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
3490 end = os_strchr(str, ' ');
3491 if (end && pos > end - str) {
3492 pos -= end - str + 1;
3497 end = os_strchr(str, ' ');
3498 if (end == NULL || str + pos < end)
3499 return wpa_list_cmd_list();
3501 cmd = os_malloc(pos + 1);
3504 os_memcpy(cmd, str, pos);
3505 cmd[end - str] = '\0';
3506 res = wpa_cli_cmd_completion(cmd, str, pos);
3512 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3514 const struct wpa_cli_cmd *cmd, *match = NULL;
3518 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
3519 ifname_prefix = argv[0] + 7;
3523 ifname_prefix = NULL;
3529 cmd = wpa_cli_commands;
3531 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3534 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3535 /* we have an exact match */
3545 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3546 cmd = wpa_cli_commands;
3548 if (os_strncasecmp(cmd->cmd, argv[0],
3549 os_strlen(argv[0])) == 0) {
3550 printf(" %s", cmd->cmd);
3556 } else if (count == 0) {
3557 printf("Unknown command '%s'\n", argv[0]);
3560 ret = match->handler(ctrl, argc - 1, &argv[1]);
3567 static int str_match(const char *a, const char *b)
3569 return os_strncmp(a, b, os_strlen(b)) == 0;
3573 static int wpa_cli_exec(const char *program, const char *arg1,
3580 len = os_strlen(arg1) + os_strlen(arg2) + 2;
3581 arg = os_malloc(len);
3584 os_snprintf(arg, len, "%s %s", arg1, arg2);
3585 res = os_exec(program, arg, 1);
3592 static void wpa_cli_action_process(const char *msg)
3595 char *copy = NULL, *id, *pos2;
3596 const char *ifname = ctrl_ifname;
3597 char ifname_buf[100];
3599 if (eloop_terminated())
3603 if (os_strncmp(pos, "IFNAME=", 7) == 0) {
3605 end = os_strchr(pos + 7, ' ');
3606 if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) {
3608 os_memcpy(ifname_buf, pos, end - pos);
3609 ifname_buf[end - pos] = '\0';
3610 ifname = ifname_buf;
3615 const char *prev = pos;
3617 pos = os_strchr(pos, '>');
3624 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3626 os_unsetenv("WPA_ID");
3627 os_unsetenv("WPA_ID_STR");
3628 os_unsetenv("WPA_CTRL_DIR");
3630 pos = os_strstr(pos, "[id=");
3632 copy = os_strdup(pos + 4);
3636 while (*pos2 && *pos2 != ' ')
3640 os_setenv("WPA_ID", id, 1);
3641 while (*pos2 && *pos2 != '=')
3646 while (*pos2 && *pos2 != ']')
3649 os_setenv("WPA_ID_STR", id, 1);
3653 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3655 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
3656 wpa_cli_connected = 1;
3657 wpa_cli_last_id = new_id;
3658 wpa_cli_exec(action_file, ifname, "CONNECTED");
3660 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3661 if (wpa_cli_connected) {
3662 wpa_cli_connected = 0;
3663 wpa_cli_exec(action_file, ifname, "DISCONNECTED");
3665 } else if (str_match(pos, MESH_GROUP_STARTED)) {
3666 wpa_cli_exec(action_file, ctrl_ifname, pos);
3667 } else if (str_match(pos, MESH_GROUP_REMOVED)) {
3668 wpa_cli_exec(action_file, ctrl_ifname, pos);
3669 } else if (str_match(pos, MESH_PEER_CONNECTED)) {
3670 wpa_cli_exec(action_file, ctrl_ifname, pos);
3671 } else if (str_match(pos, MESH_PEER_DISCONNECTED)) {
3672 wpa_cli_exec(action_file, ctrl_ifname, pos);
3673 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3674 wpa_cli_exec(action_file, ifname, pos);
3675 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3676 wpa_cli_exec(action_file, ifname, pos);
3677 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3678 wpa_cli_exec(action_file, ifname, pos);
3679 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3680 wpa_cli_exec(action_file, ifname, pos);
3681 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3682 wpa_cli_exec(action_file, ifname, pos);
3683 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3684 wpa_cli_exec(action_file, ifname, pos);
3685 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3686 wpa_cli_exec(action_file, ifname, pos);
3687 } else if (str_match(pos, AP_STA_CONNECTED)) {
3688 wpa_cli_exec(action_file, ifname, pos);
3689 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3690 wpa_cli_exec(action_file, ifname, pos);
3691 } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
3692 wpa_cli_exec(action_file, ifname, pos);
3693 } else if (str_match(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
3694 wpa_cli_exec(action_file, ifname, pos);
3695 } else if (str_match(pos, HS20_DEAUTH_IMMINENT_NOTICE)) {
3696 wpa_cli_exec(action_file, ifname, pos);
3697 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3698 printf("wpa_supplicant is terminating - stop monitoring\n");
3704 #ifndef CONFIG_ANSI_C_EXTRA
3705 static void wpa_cli_action_cb(char *msg, size_t len)
3707 wpa_cli_action_process(msg);
3709 #endif /* CONFIG_ANSI_C_EXTRA */
3712 static void wpa_cli_reconnect(void)
3714 wpa_cli_close_connection();
3715 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3720 printf("\rConnection to wpa_supplicant re-established\n");
3726 static void cli_event(const char *str)
3728 const char *start, *s;
3730 start = os_strchr(str, '>');
3736 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3737 s = os_strchr(start, ' ');
3740 s = os_strchr(s + 1, ' ');
3743 cli_txt_list_add(&bsses, s + 1);
3747 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3748 s = os_strchr(start, ' ');
3751 s = os_strchr(s + 1, ' ');
3754 cli_txt_list_del_addr(&bsses, s + 1);
3759 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3760 s = os_strstr(start, " p2p_dev_addr=");
3763 cli_txt_list_add_addr(&p2p_peers, s + 14);
3767 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3768 s = os_strstr(start, " p2p_dev_addr=");
3771 cli_txt_list_del_addr(&p2p_peers, s + 14);
3775 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3776 s = os_strchr(start, ' ');
3779 cli_txt_list_add_word(&p2p_groups, s + 1, ' ');
3783 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3784 s = os_strchr(start, ' ');
3787 cli_txt_list_del_word(&p2p_groups, s + 1, ' ');
3790 #endif /* CONFIG_P2P */
3794 static int check_terminating(const char *msg)
3796 const char *pos = msg;
3800 pos = os_strchr(pos, '>');
3807 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3809 printf("\rConnection to wpa_supplicant lost - trying to "
3812 wpa_cli_attached = 0;
3813 wpa_cli_close_connection();
3821 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3823 if (ctrl_conn == NULL) {
3824 wpa_cli_reconnect();
3827 while (wpa_ctrl_pending(ctrl) > 0) {
3829 size_t len = sizeof(buf) - 1;
3830 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3833 wpa_cli_action_process(buf);
3836 if (wpa_cli_show_event(buf)) {
3838 printf("\r%s\n", buf);
3842 if (interactive && check_terminating(buf) > 0)
3846 printf("Could not read pending message.\n");
3851 if (wpa_ctrl_pending(ctrl) < 0) {
3852 printf("Connection to wpa_supplicant lost - trying to "
3854 wpa_cli_reconnect();
3860 static int tokenize_cmd(char *cmd, char *argv[])
3873 if (argc == max_args)
3876 char *pos2 = os_strrchr(pos, '"');
3880 while (*pos != '\0' && *pos != ' ')
3890 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3894 char *prefix = ifname_prefix;
3896 ifname_prefix = NULL;
3897 res = _wpa_ctrl_command(ctrl_conn, "PING", 0);
3898 ifname_prefix = prefix;
3900 printf("Connection to wpa_supplicant lost - trying to "
3902 wpa_cli_close_connection();
3906 wpa_cli_reconnect();
3907 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3911 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3913 wpa_cli_recv_pending(mon_conn, 0);
3917 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3919 char *argv[max_args];
3921 argc = tokenize_cmd(cmd, argv);
3923 wpa_request(ctrl_conn, argc, argv);
3927 static void wpa_cli_edit_eof_cb(void *ctx)
3933 static int warning_displayed = 0;
3934 static char *hfile = NULL;
3935 static int edit_started = 0;
3937 static void start_edit(void)
3942 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3943 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3944 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3946 #ifdef CONFIG_WPA_CLI_HISTORY_DIR
3947 home = CONFIG_WPA_CLI_HISTORY_DIR;
3948 #else /* CONFIG_WPA_CLI_HISTORY_DIR */
3949 home = getenv("HOME");
3950 #endif /* CONFIG_WPA_CLI_HISTORY_DIR */
3952 const char *fname = ".wpa_cli_history";
3953 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3954 hfile = os_malloc(hfile_len);
3956 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3959 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3960 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3966 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3970 static void update_bssid_list(struct wpa_ctrl *ctrl)
3973 size_t len = sizeof(buf);
3975 char *cmd = "BSS RANGE=ALL MASK=0x2";
3980 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3987 pos = os_strstr(pos, "bssid=");
3991 end = os_strchr(pos, '\n');
3995 cli_txt_list_add(&bsses, pos);
4001 static void update_ifnames(struct wpa_ctrl *ctrl)
4004 size_t len = sizeof(buf);
4006 char *cmd = "INTERFACES";
4010 cli_txt_list_flush(&ifnames);
4014 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
4021 end = os_strchr(pos, '\n');
4025 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
4026 if (!os_snprintf_error(sizeof(txt), ret))
4027 cli_txt_list_add(&ifnames, txt);
4033 static void update_networks(struct wpa_ctrl *ctrl)
4036 size_t len = sizeof(buf);
4038 char *cmd = "LIST_NETWORKS";
4042 cli_txt_list_flush(&networks);
4046 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
4053 end = os_strchr(pos, '\n');
4058 cli_txt_list_add_word(&networks, pos, '\t');
4065 static void try_connection(void *eloop_ctx, void *timeout_ctx)
4070 if (ctrl_ifname == NULL)
4071 ctrl_ifname = wpa_cli_get_default_ifname();
4073 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
4074 if (!warning_displayed) {
4075 printf("Could not connect to wpa_supplicant: "
4077 ctrl_ifname ? ctrl_ifname : "(nil)");
4078 warning_displayed = 1;
4080 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
4084 update_bssid_list(ctrl_conn);
4085 update_networks(ctrl_conn);
4087 if (warning_displayed)
4088 printf("Connection established.\n");
4095 static void wpa_cli_interactive(void)
4097 printf("\nInteractive mode\n\n");
4099 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
4101 eloop_cancel_timeout(try_connection, NULL, NULL);
4103 cli_txt_list_flush(&p2p_peers);
4104 cli_txt_list_flush(&p2p_groups);
4105 cli_txt_list_flush(&bsses);
4106 cli_txt_list_flush(&ifnames);
4107 cli_txt_list_flush(&networks);
4109 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
4111 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
4112 wpa_cli_close_connection();
4116 static void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx)
4118 struct wpa_ctrl *ctrl = eloop_ctx;
4122 /* verify that connection is still working */
4123 len = sizeof(buf) - 1;
4124 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
4125 wpa_cli_action_cb) < 0 ||
4126 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
4127 printf("wpa_supplicant did not reply to PING command - exiting\n");
4131 eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
4136 static void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx)
4138 struct wpa_ctrl *ctrl = eloop_ctx;
4140 wpa_cli_recv_pending(ctrl, 1);
4144 static void wpa_cli_action(struct wpa_ctrl *ctrl)
4146 #ifdef CONFIG_ANSI_C_EXTRA
4147 /* TODO: ANSI C version(?) */
4148 printf("Action processing not supported in ANSI C build.\n");
4149 #else /* CONFIG_ANSI_C_EXTRA */
4152 fd = wpa_ctrl_get_fd(ctrl);
4153 eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
4155 eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL);
4157 eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL);
4158 eloop_unregister_read_sock(fd);
4159 #endif /* CONFIG_ANSI_C_EXTRA */
4163 static void wpa_cli_cleanup(void)
4165 wpa_cli_close_connection();
4167 os_daemonize_terminate(pid_file);
4169 os_program_deinit();
4173 static void wpa_cli_terminate(int sig, void *ctx)
4179 static char * wpa_cli_get_default_ifname(void)
4181 char *ifname = NULL;
4184 char ifprop[PROPERTY_VALUE_MAX];
4185 if (property_get("wifi.interface", ifprop, NULL) != 0) {
4186 ifname = os_strdup(ifprop);
4187 printf("Using interface '%s'\n", ifname ? ifname : "N/A");
4190 #ifdef CONFIG_CTRL_IFACE_UNIX
4191 struct dirent *dent;
4192 DIR *dir = opendir(ctrl_iface_dir);
4196 while ((dent = readdir(dir))) {
4197 #ifdef _DIRENT_HAVE_D_TYPE
4199 * Skip the file if it is not a socket. Also accept
4200 * DT_UNKNOWN (0) in case the C library or underlying
4201 * file system does not support d_type.
4203 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
4205 #endif /* _DIRENT_HAVE_D_TYPE */
4206 if (os_strcmp(dent->d_name, ".") == 0 ||
4207 os_strcmp(dent->d_name, "..") == 0)
4209 printf("Selected interface '%s'\n", dent->d_name);
4210 ifname = os_strdup(dent->d_name);
4214 #endif /* CONFIG_CTRL_IFACE_UNIX */
4216 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4217 char buf[4096], *pos;
4219 struct wpa_ctrl *ctrl;
4222 ctrl = wpa_ctrl_open(NULL);
4226 len = sizeof(buf) - 1;
4227 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
4230 pos = os_strchr(buf, '\n');
4233 ifname = os_strdup(buf);
4235 wpa_ctrl_close(ctrl);
4236 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4237 #endif /* ANDROID */
4243 int main(int argc, char *argv[])
4248 const char *global = NULL;
4250 if (os_program_init())
4254 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
4259 action_file = optarg;
4268 ping_interval = atoi(optarg);
4274 printf("%s\n", wpa_cli_version);
4277 os_free(ctrl_ifname);
4278 ctrl_ifname = os_strdup(optarg);
4281 ctrl_iface_dir = optarg;
4292 interactive = (argc == optind) && (action_file == NULL);
4295 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
4301 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4302 ctrl_conn = wpa_ctrl_open(NULL);
4303 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4304 ctrl_conn = wpa_ctrl_open(global);
4305 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4306 if (ctrl_conn == NULL) {
4307 fprintf(stderr, "Failed to connect to wpa_supplicant "
4308 "global interface: %s error: %s\n",
4309 global, strerror(errno));
4314 update_ifnames(ctrl_conn);
4315 mon_conn = wpa_ctrl_open(global);
4317 if (wpa_ctrl_attach(mon_conn) == 0) {
4318 wpa_cli_attached = 1;
4319 eloop_register_read_sock(
4320 wpa_ctrl_get_fd(mon_conn),
4321 wpa_cli_mon_receive,
4324 printf("Failed to open monitor "
4325 "connection through global "
4326 "control interface\n");
4332 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
4334 if (ctrl_ifname == NULL)
4335 ctrl_ifname = wpa_cli_get_default_ifname();
4338 wpa_cli_interactive();
4341 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
4342 fprintf(stderr, "Failed to connect to non-global "
4343 "ctrl_ifname: %s error: %s\n",
4344 ctrl_ifname ? ctrl_ifname : "(nil)",
4350 if (wpa_ctrl_attach(ctrl_conn) == 0) {
4351 wpa_cli_attached = 1;
4353 printf("Warning: Failed to attach to "
4354 "wpa_supplicant.\n");
4359 if (daemonize && os_daemonize(pid_file))
4363 wpa_cli_action(ctrl_conn);
4365 ret = wpa_request(ctrl_conn, argc - optind,
4369 os_free(ctrl_ifname);
4376 #else /* CONFIG_CTRL_IFACE */
4377 int main(int argc, char *argv[])
4379 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
4382 #endif /* CONFIG_CTRL_IFACE */