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 *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 *wpa_cli_license =
35 "This software may be distributed under the terms of the BSD license.\n"
36 "See README for more details.\n";
38 static const char *wpa_cli_full_license =
39 "This software may be distributed under the terms of the BSD license.\n"
41 "Redistribution and use in source and binary forms, with or without\n"
42 "modification, are permitted provided that the following conditions are\n"
45 "1. Redistributions of source code must retain the above copyright\n"
46 " notice, this list of conditions and the following disclaimer.\n"
48 "2. Redistributions in binary form must reproduce the above copyright\n"
49 " notice, this list of conditions and the following disclaimer in the\n"
50 " documentation and/or other materials provided with the distribution.\n"
52 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
53 " names of its contributors may be used to endorse or promote products\n"
54 " derived from this software without specific prior written permission.\n"
56 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
57 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
58 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
59 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
60 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
61 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
62 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
63 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
64 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
65 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
66 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
69 static struct wpa_ctrl *ctrl_conn;
70 static struct wpa_ctrl *mon_conn;
71 static int wpa_cli_quit = 0;
72 static int wpa_cli_attached = 0;
73 static int wpa_cli_connected = -1;
74 static int wpa_cli_last_id = 0;
75 #ifndef CONFIG_CTRL_IFACE_DIR
76 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
77 #endif /* CONFIG_CTRL_IFACE_DIR */
78 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
79 static char *ctrl_ifname = NULL;
80 static const char *pid_file = NULL;
81 static const char *action_file = NULL;
82 static int ping_interval = 5;
83 static int interactive = 0;
84 static char *ifname_prefix = NULL;
86 struct cli_txt_entry {
91 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
92 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
93 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
94 static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */
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)
177 end = os_strchr(txt, ' ');
179 end = os_strchr(txt, '\t');
181 end = txt + os_strlen(txt);
182 buf = dup_binstr(txt, end - txt);
185 cli_txt_list_del(txt_list, buf);
188 #endif /* CONFIG_P2P */
191 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
193 struct cli_txt_entry *e;
194 e = cli_txt_list_get(txt_list, txt);
197 e = os_zalloc(sizeof(*e));
200 e->txt = os_strdup(txt);
201 if (e->txt == NULL) {
205 dl_list_add(txt_list, &e->list);
211 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
215 if (hwaddr_aton(txt, addr) < 0)
217 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
218 return cli_txt_list_add(txt_list, buf);
220 #endif /* CONFIG_P2P */
223 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
228 end = os_strchr(txt, ' ');
230 end = os_strchr(txt, '\t');
232 end = txt + os_strlen(txt);
233 buf = dup_binstr(txt, end - txt);
236 ret = cli_txt_list_add(txt_list, buf);
242 static char ** cli_txt_list_array(struct dl_list *txt_list)
244 unsigned int i, count = dl_list_len(txt_list);
246 struct cli_txt_entry *e;
248 res = os_calloc(count + 1, sizeof(char *));
253 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
254 res[i] = os_strdup(e->txt);
264 static int get_cmd_arg_num(const char *str, int pos)
268 for (i = 0; i <= pos; i++) {
271 while (i <= pos && str[i] != ' ')
282 static int str_starts(const char *src, const char *match)
284 return os_strncmp(src, match, os_strlen(match)) == 0;
288 static int wpa_cli_show_event(const char *event)
292 start = os_strchr(event, '>');
298 * Skip BSS added/removed events since they can be relatively frequent
299 * and are likely of not much use for an interactive user.
301 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
302 str_starts(start, WPA_EVENT_BSS_REMOVED))
309 static int wpa_cli_open_connection(const char *ifname, int attach)
311 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
312 ctrl_conn = wpa_ctrl_open(ifname);
313 if (ctrl_conn == NULL)
316 if (attach && interactive)
317 mon_conn = wpa_ctrl_open(ifname);
320 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
328 if (access(ctrl_iface_dir, F_OK) < 0) {
329 cfile = os_strdup(ifname);
336 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
337 cfile = os_malloc(flen);
340 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
342 if (os_snprintf_error(flen, res)) {
348 ctrl_conn = wpa_ctrl_open(cfile);
349 if (ctrl_conn == NULL) {
354 if (attach && interactive)
355 mon_conn = wpa_ctrl_open(cfile);
359 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
362 if (wpa_ctrl_attach(mon_conn) == 0) {
363 wpa_cli_attached = 1;
365 eloop_register_read_sock(
366 wpa_ctrl_get_fd(mon_conn),
367 wpa_cli_mon_receive, NULL, NULL);
369 printf("Warning: Failed to attach to "
370 "wpa_supplicant.\n");
371 wpa_cli_close_connection();
380 static void wpa_cli_close_connection(void)
382 if (ctrl_conn == NULL)
385 if (wpa_cli_attached) {
386 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
387 wpa_cli_attached = 0;
389 wpa_ctrl_close(ctrl_conn);
392 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
393 wpa_ctrl_close(mon_conn);
399 static void wpa_cli_msg_cb(char *msg, size_t len)
405 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
411 if (ctrl_conn == NULL) {
412 printf("Not connected to wpa_supplicant - command dropped.\n");
416 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
418 buf[sizeof(buf) - 1] = '\0';
421 len = sizeof(buf) - 1;
422 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
425 printf("'%s' command timed out.\n", cmd);
427 } else if (ret < 0) {
428 printf("'%s' command failed.\n", cmd);
434 if (interactive && len > 0 && buf[len - 1] != '\n')
441 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
443 return _wpa_ctrl_command(ctrl, cmd, 1);
447 static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
456 res = os_snprintf(pos, end - pos, "%s", cmd);
457 if (os_snprintf_error(end - pos, res))
461 for (i = 0; i < argc; i++) {
462 res = os_snprintf(pos, end - pos, " %s", argv[i]);
463 if (os_snprintf_error(end - pos, res))
468 buf[buflen - 1] = '\0';
472 printf("Too long command\n");
477 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
478 int argc, char *argv[])
481 if (argc < min_args) {
482 printf("Invalid %s command - at least %d argument%s "
483 "required.\n", cmd, min_args,
484 min_args > 1 ? "s are" : " is");
487 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
489 return wpa_ctrl_command(ctrl, buf);
493 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
495 return wpa_ctrl_command(ctrl, "IFNAME");
499 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
501 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
502 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
503 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
504 return wpa_ctrl_command(ctrl, "STATUS-WPS");
505 if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
506 return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
507 return wpa_ctrl_command(ctrl, "STATUS");
511 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
513 return wpa_ctrl_command(ctrl, "PING");
517 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
519 return wpa_ctrl_command(ctrl, "RELOG");
523 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
525 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
529 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
531 return wpa_ctrl_command(ctrl, "MIB");
535 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
537 return wpa_ctrl_command(ctrl, "PMKSA");
541 static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc,
544 return wpa_ctrl_command(ctrl, "PMKSA_FLUSH");
548 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
550 print_help(argc > 0 ? argv[0] : NULL);
555 static char ** wpa_cli_complete_help(const char *str, int pos)
557 int arg = get_cmd_arg_num(str, pos);
562 res = wpa_list_cmd_list();
570 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
572 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
577 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
586 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
592 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
593 if (os_snprintf_error(sizeof(cmd), res)) {
594 printf("Too long SET command.\n");
597 return wpa_ctrl_command(ctrl, cmd);
600 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
604 static char ** wpa_cli_complete_set(const char *str, int pos)
606 int arg = get_cmd_arg_num(str, pos);
607 const char *fields[] = {
609 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
610 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
611 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
612 "wps_fragment_size", "wps_version_number", "ampdu",
613 "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
614 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
616 /* global configuration parameters */
617 #ifdef CONFIG_CTRL_IFACE
618 "ctrl_interface", "no_ctrl_interface", "ctrl_interface_group",
619 #endif /* CONFIG_CTRL_IFACE */
620 "eapol_version", "ap_scan", "bgscan",
622 "user_mpm", "max_peer_links", "mesh_max_inactivity",
623 #endif /* CONFIG_MESH */
624 "disable_scan_offload", "fast_reauth", "opensc_engine_path",
625 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
626 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
627 "dot11RSNAConfigPMKLifetime",
628 "dot11RSNAConfigPMKReauthThreshold",
629 "dot11RSNAConfigSATimeout",
630 #ifndef CONFIG_NO_CONFIG_WRITE
632 #endif /* CONFIG_NO_CONFIG_WRITE */
635 "uuid", "device_name", "manufacturer", "model_name",
636 "model_number", "serial_number", "device_type", "os_version",
637 "config_methods", "wps_cred_processing", "wps_vendor_ext_m1",
638 #endif /* CONFIG_WPS */
641 "p2p_listen_reg_class", "p2p_listen_channel",
642 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
643 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
644 "p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan",
645 "p2p_no_go_freq", "p2p_add_cli_chan",
646 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
647 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
648 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
649 "ip_addr_start", "ip_addr_end",
650 #endif /* CONFIG_P2P */
651 "country", "bss_max_count", "bss_expiration_age",
652 "bss_expiration_scan_count", "filter_ssids", "filter_rssi",
653 "max_num_sta", "disassoc_low_ack",
656 #endif /* CONFIG_HS20 */
657 "interworking", "hessid", "access_network_type", "pbc_in_m1",
658 "autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey",
659 "wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend",
660 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
661 "sae_groups", "dtim_period", "beacon_int",
662 "ap_vendor_elements", "ignore_old_scan_res", "freq_list",
663 "scan_cur_freq", "sched_scan_interval",
664 "tdls_external_control", "osu_dir", "wowlan_triggers",
665 "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
666 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
667 "reassoc_same_bss_optim"
669 int i, num_fields = ARRAY_SIZE(fields);
672 char **res = os_calloc(num_fields + 1, sizeof(char *));
675 for (i = 0; i < num_fields; i++) {
676 res[i] = os_strdup(fields[i]);
683 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
684 return cli_txt_list_array(&bsses);
689 static int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[])
691 return wpa_ctrl_command(ctrl, "DUMP");
695 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
697 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
701 static char ** wpa_cli_complete_get(const char *str, int pos)
703 int arg = get_cmd_arg_num(str, pos);
704 const char *fields[] = {
705 #ifdef CONFIG_CTRL_IFACE
706 "ctrl_interface", "ctrl_interface_group",
707 #endif /* CONFIG_CTRL_IFACE */
708 "eapol_version", "ap_scan",
710 "user_mpm", "max_peer_links", "mesh_max_inactivity",
711 #endif /* CONFIG_MESH */
712 "disable_scan_offload", "fast_reauth", "opensc_engine_path",
713 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
714 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
715 "dot11RSNAConfigPMKLifetime",
716 "dot11RSNAConfigPMKReauthThreshold",
717 "dot11RSNAConfigSATimeout",
718 #ifndef CONFIG_NO_CONFIG_WRITE
720 #endif /* CONFIG_NO_CONFIG_WRITE */
722 "device_name", "manufacturer", "model_name", "model_number",
723 "serial_number", "config_methods", "wps_cred_processing",
724 #endif /* CONFIG_WPS */
726 "p2p_listen_reg_class", "p2p_listen_channel",
727 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
728 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
729 "p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan",
730 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
731 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
732 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
733 "ip_addr_start", "ip_addr_end",
734 #endif /* CONFIG_P2P */
735 "bss_max_count", "bss_expiration_age",
736 "bss_expiration_scan_count", "filter_ssids", "filter_rssi",
737 "max_num_sta", "disassoc_low_ack",
740 #endif /* CONFIG_HS20 */
741 "interworking", "access_network_type", "pbc_in_m1", "autoscan",
742 "wps_nfc_dev_pw_id", "ext_password_backend",
743 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
744 "dtim_period", "beacon_int", "ignore_old_scan_res",
745 "scan_cur_freq", "sched_scan_interval",
746 "tdls_external_control", "osu_dir", "wowlan_triggers",
747 "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
748 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
749 "reassoc_same_bss_optim"
751 int i, num_fields = ARRAY_SIZE(fields);
754 char **res = os_calloc(num_fields + 1, sizeof(char *));
757 for (i = 0; i < num_fields; i++) {
758 res[i] = os_strdup(fields[i]);
769 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
771 return wpa_ctrl_command(ctrl, "LOGOFF");
775 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
777 return wpa_ctrl_command(ctrl, "LOGON");
781 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
784 return wpa_ctrl_command(ctrl, "REASSOCIATE");
788 static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[])
790 return wpa_ctrl_command(ctrl, "REATTACH");
794 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
797 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
801 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
803 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
807 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
810 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
814 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
817 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
821 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
824 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
828 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
834 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
836 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
837 if (os_snprintf_error(sizeof(cmd), res)) {
838 printf("Too long BSS_FLUSH command.\n");
841 return wpa_ctrl_command(ctrl, cmd);
845 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
848 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
852 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
854 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
858 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
860 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
864 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
867 printf("Invalid WPS_PIN command: need one or two arguments:\n"
868 "- BSSID: use 'any' to select any\n"
869 "- PIN: optional, used only with devices that have no "
874 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
878 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
881 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
885 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
888 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
892 #ifdef CONFIG_WPS_NFC
894 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
896 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
900 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
903 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
907 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
910 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
914 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
922 printf("Invalid 'wps_nfc_tag_read' command - one argument "
927 buflen = 18 + os_strlen(argv[0]);
928 buf = os_malloc(buflen);
931 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
933 ret = wpa_ctrl_command(ctrl, buf);
940 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
943 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
947 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
950 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
954 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
957 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
960 #endif /* CONFIG_WPS_NFC */
963 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
969 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
971 else if (argc == 5 || argc == 6) {
972 char ssid_hex[2 * 32 + 1];
973 char key_hex[2 * 64 + 1];
977 for (i = 0; i < 32; i++) {
978 if (argv[2][i] == '\0')
980 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
985 for (i = 0; i < 64; i++) {
986 if (argv[5][i] == '\0')
988 os_snprintf(&key_hex[i * 2], 3, "%02x",
993 res = os_snprintf(cmd, sizeof(cmd),
994 "WPS_REG %s %s %s %s %s %s",
995 argv[0], argv[1], ssid_hex, argv[3], argv[4],
998 printf("Invalid WPS_REG command: need two arguments:\n"
999 "- BSSID of the target AP\n"
1001 printf("Alternatively, six arguments can be used to "
1002 "reconfigure the AP:\n"
1003 "- BSSID of the target AP\n"
1006 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1007 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1012 if (os_snprintf_error(sizeof(cmd), res)) {
1013 printf("Too long WPS_REG command.\n");
1016 return wpa_ctrl_command(ctrl, cmd);
1020 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
1023 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
1027 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
1030 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
1034 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
1037 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
1042 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
1046 printf("Invalid WPS_ER_PIN command: need at least two "
1048 "- UUID: use 'any' to select any\n"
1049 "- PIN: Enrollee PIN\n"
1050 "optional: - Enrollee MAC address\n");
1054 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
1058 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
1061 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
1065 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1069 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1070 "- UUID: specify which AP to use\n"
1075 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
1079 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1083 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1085 "- UUID: specify which AP to use\n"
1086 "- Network configuration id\n");
1090 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
1094 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1100 if (argc == 5 || argc == 6) {
1101 char ssid_hex[2 * 32 + 1];
1102 char key_hex[2 * 64 + 1];
1106 for (i = 0; i < 32; i++) {
1107 if (argv[2][i] == '\0')
1109 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1114 for (i = 0; i < 64; i++) {
1115 if (argv[5][i] == '\0')
1117 os_snprintf(&key_hex[i * 2], 3, "%02x",
1122 res = os_snprintf(cmd, sizeof(cmd),
1123 "WPS_ER_CONFIG %s %s %s %s %s %s",
1124 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1127 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1131 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1132 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1137 if (os_snprintf_error(sizeof(cmd), res)) {
1138 printf("Too long WPS_ER_CONFIG command.\n");
1141 return wpa_ctrl_command(ctrl, cmd);
1145 #ifdef CONFIG_WPS_NFC
1146 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1150 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1152 "- WPS/NDEF: token format\n"
1153 "- UUID: specify which AP to use\n");
1157 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1159 #endif /* CONFIG_WPS_NFC */
1162 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1164 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1168 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1170 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1174 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1176 char cmd[256], *pos, *end;
1180 printf("Invalid IDENTITY command: needs two arguments "
1181 "(network id and identity)\n");
1185 end = cmd + sizeof(cmd);
1187 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1189 if (os_snprintf_error(end - pos, ret)) {
1190 printf("Too long IDENTITY command.\n");
1194 for (i = 2; i < argc; i++) {
1195 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1196 if (os_snprintf_error(end - pos, ret)) {
1197 printf("Too long IDENTITY command.\n");
1203 return wpa_ctrl_command(ctrl, cmd);
1207 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1209 char cmd[256], *pos, *end;
1213 printf("Invalid PASSWORD command: needs two arguments "
1214 "(network id and password)\n");
1218 end = cmd + sizeof(cmd);
1220 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1222 if (os_snprintf_error(end - pos, ret)) {
1223 printf("Too long PASSWORD command.\n");
1227 for (i = 2; i < argc; i++) {
1228 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1229 if (os_snprintf_error(end - pos, ret)) {
1230 printf("Too long PASSWORD command.\n");
1236 return wpa_ctrl_command(ctrl, cmd);
1240 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1243 char cmd[256], *pos, *end;
1247 printf("Invalid NEW_PASSWORD command: needs two arguments "
1248 "(network id and password)\n");
1252 end = cmd + sizeof(cmd);
1254 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1256 if (os_snprintf_error(end - pos, ret)) {
1257 printf("Too long NEW_PASSWORD command.\n");
1261 for (i = 2; i < argc; i++) {
1262 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1263 if (os_snprintf_error(end - pos, ret)) {
1264 printf("Too long NEW_PASSWORD command.\n");
1270 return wpa_ctrl_command(ctrl, cmd);
1274 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1276 char cmd[256], *pos, *end;
1280 printf("Invalid PIN command: needs two arguments "
1281 "(network id and pin)\n");
1285 end = cmd + sizeof(cmd);
1287 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1289 if (os_snprintf_error(end - pos, ret)) {
1290 printf("Too long PIN command.\n");
1294 for (i = 2; i < argc; i++) {
1295 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1296 if (os_snprintf_error(end - pos, ret)) {
1297 printf("Too long PIN command.\n");
1302 return wpa_ctrl_command(ctrl, cmd);
1306 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1308 char cmd[256], *pos, *end;
1312 printf("Invalid OTP command: needs two arguments (network "
1313 "id and password)\n");
1317 end = cmd + sizeof(cmd);
1319 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1321 if (os_snprintf_error(end - pos, ret)) {
1322 printf("Too long OTP command.\n");
1326 for (i = 2; i < argc; i++) {
1327 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1328 if (os_snprintf_error(end - pos, ret)) {
1329 printf("Too long OTP command.\n");
1335 return wpa_ctrl_command(ctrl, cmd);
1339 static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
1341 char cmd[256], *pos, *end;
1345 printf("Invalid SIM command: needs two arguments "
1346 "(network id and SIM operation response)\n");
1350 end = cmd + sizeof(cmd);
1352 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
1354 if (os_snprintf_error(end - pos, ret)) {
1355 printf("Too long SIM command.\n");
1359 for (i = 2; i < argc; i++) {
1360 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1361 if (os_snprintf_error(end - pos, ret)) {
1362 printf("Too long SIM command.\n");
1367 return wpa_ctrl_command(ctrl, cmd);
1371 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1374 char cmd[256], *pos, *end;
1378 printf("Invalid PASSPHRASE command: needs two arguments "
1379 "(network id and passphrase)\n");
1383 end = cmd + sizeof(cmd);
1385 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1387 if (os_snprintf_error(end - pos, ret)) {
1388 printf("Too long PASSPHRASE command.\n");
1392 for (i = 2; i < argc; i++) {
1393 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1394 if (os_snprintf_error(end - pos, ret)) {
1395 printf("Too long PASSPHRASE command.\n");
1401 return wpa_ctrl_command(ctrl, cmd);
1405 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1408 printf("Invalid BSSID command: needs two arguments (network "
1413 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1417 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1419 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1423 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1425 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1429 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1432 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1436 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1439 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1443 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1446 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1450 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1453 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1457 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1460 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);
1470 update_networks(ctrl);
1475 static void wpa_cli_show_network_variables(void)
1477 printf("set_network variables:\n"
1478 " ssid (network name, SSID)\n"
1479 " psk (WPA passphrase or pre-shared key)\n"
1480 " key_mgmt (key management protocol)\n"
1481 " identity (EAP identity)\n"
1482 " password (EAP password)\n"
1485 "Note: Values are entered in the same format as the "
1486 "configuration file is using,\n"
1487 "i.e., strings values need to be inside double quotation "
1489 "For example: set_network 1 ssid \"network name\"\n"
1491 "Please see wpa_supplicant.conf documentation for full list "
1492 "of\navailable variables.\n");
1496 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1500 wpa_cli_show_network_variables();
1505 printf("Invalid SET_NETWORK command: needs three arguments\n"
1506 "(network id, variable name, and value)\n");
1510 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1514 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1518 wpa_cli_show_network_variables();
1523 printf("Invalid GET_NETWORK command: needs two arguments\n"
1524 "(network id and variable name)\n");
1528 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1532 static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc,
1536 wpa_cli_show_network_variables();
1541 printf("Invalid DUP_NETWORK command: needs three arguments\n"
1542 "(src netid, dest netid, and variable name)\n");
1546 return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv);
1550 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1553 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1557 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1559 return wpa_ctrl_command(ctrl, "ADD_CRED");
1563 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1566 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1570 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1573 printf("Invalid SET_CRED command: needs three arguments\n"
1574 "(cred id, variable name, and value)\n");
1578 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1582 static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1585 printf("Invalid GET_CRED command: needs two arguments\n"
1586 "(cred id, variable name)\n");
1590 return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv);
1594 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1597 return wpa_ctrl_command(ctrl, "DISCONNECT");
1601 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1604 return wpa_ctrl_command(ctrl, "RECONNECT");
1608 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1611 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1615 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1617 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1621 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1624 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1628 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1630 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1634 static char ** wpa_cli_complete_bss(const char *str, int pos)
1636 int arg = get_cmd_arg_num(str, pos);
1641 res = cli_txt_list_array(&bsses);
1649 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1652 if (argc < 1 || argc > 2) {
1653 printf("Invalid GET_CAPABILITY command: need either one or "
1658 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1659 printf("Invalid GET_CAPABILITY command: second argument, "
1660 "if any, must be 'strict'\n");
1664 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1668 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1670 printf("Available interfaces:\n");
1671 return wpa_ctrl_command(ctrl, "INTERFACES");
1675 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1678 wpa_cli_list_interfaces(ctrl);
1682 wpa_cli_close_connection();
1683 os_free(ctrl_ifname);
1684 ctrl_ifname = os_strdup(argv[0]);
1686 printf("Failed to allocate memory\n");
1690 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
1691 printf("Connected to interface '%s.\n", ctrl_ifname);
1693 printf("Could not connect to interface '%s' - re-trying\n",
1700 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1703 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1707 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1710 return wpa_ctrl_command(ctrl, "TERMINATE");
1714 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1721 printf("Invalid INTERFACE_ADD command: needs at least one "
1722 "argument (interface name)\n"
1723 "All arguments: ifname confname driver ctrl_interface "
1724 "driver_param bridge_name [create]\n");
1729 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1730 * <driver_param>TAB<bridge_name>[TAB<create>]
1732 res = os_snprintf(cmd, sizeof(cmd),
1733 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s",
1735 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1736 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1737 argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "");
1738 if (os_snprintf_error(sizeof(cmd), res))
1740 cmd[sizeof(cmd) - 1] = '\0';
1741 return wpa_ctrl_command(ctrl, cmd);
1745 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1748 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1752 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1755 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1760 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1762 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1766 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1767 char *addr, size_t addr_len)
1769 char buf[4096], *pos;
1773 if (ctrl_conn == NULL) {
1774 printf("Not connected to hostapd - command dropped.\n");
1777 len = sizeof(buf) - 1;
1778 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1781 printf("'%s' command timed out.\n", cmd);
1783 } else if (ret < 0) {
1784 printf("'%s' command failed.\n", cmd);
1789 if (os_memcmp(buf, "FAIL", 4) == 0)
1794 while (*pos != '\0' && *pos != '\n')
1797 os_strlcpy(addr, buf, addr_len);
1802 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1804 char addr[32], cmd[64];
1806 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1809 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1810 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1816 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1819 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1823 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1826 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1829 static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
1832 return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
1835 #endif /* CONFIG_AP */
1838 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1840 return wpa_ctrl_command(ctrl, "SUSPEND");
1844 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1846 return wpa_ctrl_command(ctrl, "RESUME");
1850 #ifdef CONFIG_TESTING_OPTIONS
1851 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1853 return wpa_ctrl_command(ctrl, "DROP_SA");
1855 #endif /* CONFIG_TESTING_OPTIONS */
1858 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1860 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1866 static int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc,
1869 return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv);
1873 static int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc,
1876 return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv);
1880 static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc,
1883 return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
1886 #endif /* CONFIG_MESH */
1891 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1893 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1897 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1900 int arg = get_cmd_arg_num(str, pos);
1902 res = os_calloc(6, sizeof(char *));
1905 res[0] = os_strdup("type=social");
1906 if (res[0] == NULL) {
1910 res[1] = os_strdup("type=progressive");
1913 res[2] = os_strdup("delay=");
1916 res[3] = os_strdup("dev_id=");
1920 res[4] = os_strdup("[timeout]");
1926 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1929 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1933 static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc,
1936 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv);
1940 static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc,
1943 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv);
1947 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1950 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
1954 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1956 int arg = get_cmd_arg_num(str, pos);
1961 res = cli_txt_list_array(&p2p_peers);
1969 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1972 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
1976 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1979 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
1983 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
1985 int arg = get_cmd_arg_num(str, pos);
1990 res = cli_txt_list_array(&p2p_groups);
1998 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2001 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
2005 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2008 if (argc != 2 && argc != 3) {
2009 printf("Invalid P2P_PROV_DISC command: needs at least "
2010 "two arguments, address and config method\n"
2011 "(display, keypad, or pbc) and an optional join\n");
2015 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
2019 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2022 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2026 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2032 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2033 "or more arguments (address and TLVs)\n");
2037 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
2039 return wpa_ctrl_command(ctrl, cmd);
2043 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2044 int argc, char *argv[])
2046 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
2050 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2057 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2058 "arguments (freq, address, dialog token, and TLVs)\n");
2062 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2063 argv[0], argv[1], argv[2], argv[3]);
2064 if (os_snprintf_error(sizeof(cmd), res))
2066 cmd[sizeof(cmd) - 1] = '\0';
2067 return wpa_ctrl_command(ctrl, cmd);
2071 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2074 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2078 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2079 int argc, char *argv[])
2081 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
2085 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2088 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2092 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2096 printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n");
2100 return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv);
2104 static int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc,
2107 if (argc < 5 || argc > 6) {
2108 printf("Invalid P2P_SERVICE_REP command: needs 5-6 "
2113 return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv);
2117 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2123 if (argc != 2 && argc != 3) {
2124 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2130 res = os_snprintf(cmd, sizeof(cmd),
2131 "P2P_SERVICE_DEL %s %s %s",
2132 argv[0], argv[1], argv[2]);
2134 res = os_snprintf(cmd, sizeof(cmd),
2135 "P2P_SERVICE_DEL %s %s",
2137 if (os_snprintf_error(sizeof(cmd), res))
2139 cmd[sizeof(cmd) - 1] = '\0';
2140 return wpa_ctrl_command(ctrl, cmd);
2144 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2145 int argc, char *argv[])
2147 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
2151 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2152 int argc, char *argv[])
2154 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
2158 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2160 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2164 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2166 int arg = get_cmd_arg_num(str, pos);
2171 res = cli_txt_list_array(&p2p_peers);
2179 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2180 char *addr, size_t addr_len,
2183 char buf[4096], *pos;
2187 if (ctrl_conn == NULL)
2189 len = sizeof(buf) - 1;
2190 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2193 printf("'%s' command timed out.\n", cmd);
2195 } else if (ret < 0) {
2196 printf("'%s' command failed.\n", cmd);
2201 if (os_memcmp(buf, "FAIL", 4) == 0)
2205 while (*pos != '\0' && *pos != '\n')
2208 os_strlcpy(addr, buf, addr_len);
2209 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2210 printf("%s\n", addr);
2215 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2217 char addr[32], cmd[64];
2220 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2222 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2223 addr, sizeof(addr), discovered))
2226 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2227 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2234 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2236 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2240 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
2242 int arg = get_cmd_arg_num(str, pos);
2243 const char *fields[] = {
2263 int i, num_fields = ARRAY_SIZE(fields);
2266 char **res = os_calloc(num_fields + 1, sizeof(char *));
2269 for (i = 0; i < num_fields; i++) {
2270 res[i] = os_strdup(fields[i]);
2277 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
2278 return cli_txt_list_array(&p2p_peers);
2284 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2286 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2290 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2293 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2297 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2300 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2304 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2307 if (argc != 0 && argc != 2 && argc != 4) {
2308 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2309 "(preferred duration, interval; in microsecods).\n"
2310 "Optional second pair can be used to provide "
2311 "acceptable values.\n");
2315 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2319 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2322 if (argc != 0 && argc != 2) {
2323 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2324 "(availability period, availability interval; in "
2326 "Extended Listen Timing can be cancelled with this "
2327 "command when used without parameters.\n");
2331 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2335 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
2338 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
2341 #endif /* CONFIG_P2P */
2343 #ifdef CONFIG_WIFI_DISPLAY
2345 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2351 if (argc != 1 && argc != 2) {
2352 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2353 "arguments (subelem, hexdump)\n");
2357 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2358 argv[0], argc > 1 ? argv[1] : "");
2359 if (os_snprintf_error(sizeof(cmd), res))
2361 cmd[sizeof(cmd) - 1] = '\0';
2362 return wpa_ctrl_command(ctrl, cmd);
2366 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2373 printf("Invalid WFD_SUBELEM_GET command: needs one "
2374 "argument (subelem)\n");
2378 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2380 if (os_snprintf_error(sizeof(cmd), res))
2382 cmd[sizeof(cmd) - 1] = '\0';
2383 return wpa_ctrl_command(ctrl, cmd);
2385 #endif /* CONFIG_WIFI_DISPLAY */
2388 #ifdef CONFIG_INTERWORKING
2389 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2392 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2396 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2399 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2403 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2406 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2410 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2413 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2417 static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc,
2420 return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv);
2424 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2426 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2430 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2433 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2437 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2440 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2442 #endif /* CONFIG_INTERWORKING */
2447 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2450 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2454 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2460 printf("Command needs one or two arguments (dst mac addr and "
2461 "optional home realm)\n");
2465 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2469 return wpa_ctrl_command(ctrl, cmd);
2473 static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc,
2479 printf("Command needs two arguments (dst mac addr and "
2484 if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0)
2487 return wpa_ctrl_command(ctrl, cmd);
2491 static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[])
2493 return wpa_ctrl_command(ctrl, "FETCH_OSU");
2497 static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc,
2500 return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU");
2503 #endif /* CONFIG_HS20 */
2506 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2509 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2513 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2516 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2520 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2523 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2527 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2530 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2534 static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc,
2537 return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv);
2541 static int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc,
2544 return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv);
2548 static int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc,
2551 return wpa_ctrl_command(ctrl, "WMM_AC_STATUS");
2555 static int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc,
2558 return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv);
2562 static int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc,
2565 return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv);
2569 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2572 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2576 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2579 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2583 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2586 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2590 #ifdef CONFIG_AUTOSCAN
2592 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2595 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2597 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2600 #endif /* CONFIG_AUTOSCAN */
2605 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2607 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2611 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2613 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2616 #endif /* CONFIG_WNM */
2619 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2623 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2628 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2630 return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
2632 #endif /* ANDROID */
2635 static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
2637 return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv);
2641 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2643 return wpa_ctrl_command(ctrl, "FLUSH");
2647 static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
2649 return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
2653 static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc,
2656 return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv);
2660 static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2662 return wpa_ctrl_command(ctrl, "ERP_FLUSH");
2666 static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc,
2669 return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv);
2673 enum wpa_cli_cmd_flags {
2674 cli_cmd_flag_none = 0x00,
2675 cli_cmd_flag_sensitive = 0x01
2678 struct wpa_cli_cmd {
2680 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2681 char ** (*completion)(const char *str, int pos);
2682 enum wpa_cli_cmd_flags flags;
2686 static struct wpa_cli_cmd wpa_cli_commands[] = {
2687 { "status", wpa_cli_cmd_status, NULL,
2689 "[verbose] = get current WPA/EAPOL/EAP status" },
2690 { "ifname", wpa_cli_cmd_ifname, NULL,
2692 "= get current interface name" },
2693 { "ping", wpa_cli_cmd_ping, NULL,
2695 "= pings wpa_supplicant" },
2696 { "relog", wpa_cli_cmd_relog, NULL,
2698 "= re-open log-file (allow rolling logs)" },
2699 { "note", wpa_cli_cmd_note, NULL,
2701 "<text> = add a note to wpa_supplicant debug log" },
2702 { "mib", wpa_cli_cmd_mib, NULL,
2704 "= get MIB variables (dot1x, dot11)" },
2705 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2707 "[command] = show usage help" },
2708 { "interface", wpa_cli_cmd_interface, NULL,
2710 "[ifname] = show interfaces/select interface" },
2711 { "level", wpa_cli_cmd_level, NULL,
2713 "<debug level> = change debug level" },
2714 { "license", wpa_cli_cmd_license, NULL,
2716 "= show full wpa_cli license" },
2717 { "quit", wpa_cli_cmd_quit, NULL,
2720 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2722 "= set variables (shows list of variables when run without "
2724 { "dump", wpa_cli_cmd_dump, NULL,
2726 "= dump config variables" },
2727 { "get", wpa_cli_cmd_get, wpa_cli_complete_get,
2729 "<name> = get information" },
2730 { "logon", wpa_cli_cmd_logon, NULL,
2732 "= IEEE 802.1X EAPOL state machine logon" },
2733 { "logoff", wpa_cli_cmd_logoff, NULL,
2735 "= IEEE 802.1X EAPOL state machine logoff" },
2736 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2738 "= show PMKSA cache" },
2739 { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL,
2741 "= flush PMKSA cache entries" },
2742 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2744 "= force reassociation" },
2745 { "reattach", wpa_cli_cmd_reattach, NULL,
2747 "= force reassociation back to the same BSS" },
2748 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2750 "<BSSID> = force preauthentication" },
2751 { "identity", wpa_cli_cmd_identity, NULL,
2753 "<network id> <identity> = configure identity for an SSID" },
2754 { "password", wpa_cli_cmd_password, NULL,
2755 cli_cmd_flag_sensitive,
2756 "<network id> <password> = configure password for an SSID" },
2757 { "new_password", wpa_cli_cmd_new_password, NULL,
2758 cli_cmd_flag_sensitive,
2759 "<network id> <password> = change password for an SSID" },
2760 { "pin", wpa_cli_cmd_pin, NULL,
2761 cli_cmd_flag_sensitive,
2762 "<network id> <pin> = configure pin for an SSID" },
2763 { "otp", wpa_cli_cmd_otp, NULL,
2764 cli_cmd_flag_sensitive,
2765 "<network id> <password> = configure one-time-password for an SSID"
2767 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2768 cli_cmd_flag_sensitive,
2769 "<network id> <passphrase> = configure private key passphrase\n"
2771 { "sim", wpa_cli_cmd_sim, NULL,
2772 cli_cmd_flag_sensitive,
2773 "<network id> <pin> = report SIM operation result" },
2774 { "bssid", wpa_cli_cmd_bssid, NULL,
2776 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2777 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2779 "<BSSID> = add a BSSID to the blacklist\n"
2780 "blacklist clear = clear the blacklist\n"
2781 "blacklist = display the blacklist" },
2782 { "log_level", wpa_cli_cmd_log_level, NULL,
2784 "<level> [<timestamp>] = update the log level/timestamp\n"
2785 "log_level = display the current log level and log options" },
2786 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2788 "= list configured networks" },
2789 { "select_network", wpa_cli_cmd_select_network, NULL,
2791 "<network id> = select a network (disable others)" },
2792 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2794 "<network id> = enable a network" },
2795 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2797 "<network id> = disable a network" },
2798 { "add_network", wpa_cli_cmd_add_network, NULL,
2800 "= add a network" },
2801 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2803 "<network id> = remove a network" },
2804 { "set_network", wpa_cli_cmd_set_network, NULL,
2805 cli_cmd_flag_sensitive,
2806 "<network id> <variable> <value> = set network variables (shows\n"
2807 " list of variables when run without arguments)" },
2808 { "get_network", wpa_cli_cmd_get_network, NULL,
2810 "<network id> <variable> = get network variables" },
2811 { "dup_network", wpa_cli_cmd_dup_network, NULL,
2813 "<src network id> <dst network id> <variable> = duplicate network variables"
2815 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2817 "= list configured credentials" },
2818 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2820 "= add a credential" },
2821 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2823 "<cred id> = remove a credential" },
2824 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2825 cli_cmd_flag_sensitive,
2826 "<cred id> <variable> <value> = set credential variables" },
2827 { "get_cred", wpa_cli_cmd_get_cred, NULL,
2829 "<cred id> <variable> = get credential variables" },
2830 { "save_config", wpa_cli_cmd_save_config, NULL,
2832 "= save the current configuration" },
2833 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2835 "= disconnect and wait for reassociate/reconnect command before\n"
2837 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2839 "= like reassociate, but only takes effect if already disconnected"
2841 { "scan", wpa_cli_cmd_scan, NULL,
2843 "= request new BSS scan" },
2844 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2846 "= get latest scan results" },
2847 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2849 "<<idx> | <bssid>> = get detailed scan result info" },
2850 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2852 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2853 "= get capabilies" },
2854 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2856 "= force wpa_supplicant to re-read its configuration file" },
2857 { "terminate", wpa_cli_cmd_terminate, NULL,
2859 "= terminate wpa_supplicant" },
2860 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2862 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2863 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2865 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2867 "<ifname> = removes the interface" },
2868 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2870 "= list available interfaces" },
2871 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2873 "<value> = set ap_scan parameter" },
2874 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2876 "<value> = set scan_interval parameter (in seconds)" },
2877 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2879 "<value> = set BSS expiration age parameter" },
2880 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2882 "<value> = set BSS expiration scan count parameter" },
2883 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2885 "<value> = set BSS flush age (0 by default)" },
2886 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2888 "<addr> = request STK negotiation with <addr>" },
2889 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2891 "<addr> = request over-the-DS FT with <addr>" },
2892 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2894 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2895 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2896 cli_cmd_flag_sensitive,
2897 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2899 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2900 cli_cmd_flag_sensitive,
2901 "<PIN> = verify PIN checksum" },
2902 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2903 "Cancels the pending WPS operation" },
2904 #ifdef CONFIG_WPS_NFC
2905 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2907 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2908 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
2910 "<WPS|NDEF> = build configuration token" },
2911 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
2913 "<WPS|NDEF> = create password token" },
2914 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
2915 cli_cmd_flag_sensitive,
2916 "<hexdump of payload> = report read NFC tag with WPS data" },
2917 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
2919 "<NDEF> <WPS> = create NFC handover request" },
2920 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
2922 "<NDEF> <WPS> = create NFC handover select" },
2923 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
2925 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2927 #endif /* CONFIG_WPS_NFC */
2928 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
2929 cli_cmd_flag_sensitive,
2930 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2931 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
2932 cli_cmd_flag_sensitive,
2933 "[params..] = enable/disable AP PIN" },
2934 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
2936 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2937 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
2939 "= stop Wi-Fi Protected Setup External Registrar" },
2940 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
2941 cli_cmd_flag_sensitive,
2942 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2943 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
2945 "<UUID> = accept an Enrollee PBC using External Registrar" },
2946 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
2947 cli_cmd_flag_sensitive,
2948 "<UUID> <PIN> = learn AP configuration" },
2949 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
2951 "<UUID> <network id> = set AP configuration for enrolling" },
2952 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
2953 cli_cmd_flag_sensitive,
2954 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2955 #ifdef CONFIG_WPS_NFC
2956 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
2958 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2959 #endif /* CONFIG_WPS_NFC */
2960 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
2962 "<addr> = request RSN authentication with <addr> in IBSS" },
2964 { "sta", wpa_cli_cmd_sta, NULL,
2966 "<addr> = get information about an associated station (AP)" },
2967 { "all_sta", wpa_cli_cmd_all_sta, NULL,
2969 "= get information about all associated stations (AP)" },
2970 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
2972 "<addr> = deauthenticate a station" },
2973 { "disassociate", wpa_cli_cmd_disassociate, NULL,
2975 "<addr> = disassociate a station" },
2976 { "chan_switch", wpa_cli_cmd_chanswitch, NULL,
2978 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
2979 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
2980 " = CSA parameters" },
2981 #endif /* CONFIG_AP */
2982 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
2983 "= notification of suspend/hibernate" },
2984 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
2985 "= notification of resume/thaw" },
2986 #ifdef CONFIG_TESTING_OPTIONS
2987 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
2988 "= drop SA without deauth/disassoc (test command)" },
2989 #endif /* CONFIG_TESTING_OPTIONS */
2990 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
2992 "<addr> = roam to the specified BSS" },
2994 { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL,
2996 "[ifname] = Create a new mesh interface" },
2997 { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL,
2999 "<network id> = join a mesh network (disable others)" },
3000 { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
3002 "<ifname> = Remove mesh group interface" },
3003 #endif /* CONFIG_MESH */
3005 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
3007 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3008 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
3009 "= stop P2P Devices search" },
3010 { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL,
3012 "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" },
3013 { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL,
3015 "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" },
3016 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
3018 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
3019 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
3020 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3021 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
3022 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
3023 "<ifname> = remove P2P group interface (terminate group if GO)" },
3024 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
3025 "[ht40] = add a new P2P group (local end as GO)" },
3026 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
3027 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3028 "<addr> <method> = request provisioning discovery" },
3029 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
3031 "= get the passphrase for a group (GO only)" },
3032 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
3033 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3034 "<addr> <TLVs> = schedule service discovery request" },
3035 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
3036 NULL, cli_cmd_flag_none,
3037 "<id> = cancel pending service discovery request" },
3038 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
3040 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3041 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
3043 "= indicate change in local services" },
3044 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
3046 "<external> = set external processing of service discovery" },
3047 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
3049 "= remove all stored service entries" },
3050 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
3052 "<bonjour|upnp|asp> <query|version> <response|service> = add a local "
3054 { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL,
3056 "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace "
3057 "local ASP service" },
3058 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
3060 "<bonjour|upnp> <query|version> [|service] = remove a local "
3062 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
3064 "<addr> = reject connection attempts from a specific peer" },
3065 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
3067 "<cmd> [peer=addr] = invite peer" },
3068 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
3069 "[discovered] = list known (optionally, only fully discovered) P2P "
3071 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
3073 "<address> = show information about known P2P peer" },
3074 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
3076 "<field> <value> = set a P2P parameter" },
3077 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
3078 "= flush P2P state" },
3079 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
3080 "= cancel P2P group formation" },
3081 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
3082 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3083 "<address> = unauthorize a peer" },
3084 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
3086 "[<duration> <interval>] [<duration> <interval>] = request GO "
3088 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
3090 "[<period> <interval>] = set extended listen timing" },
3091 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
3092 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3093 "<address|iface=address> = remove a peer from all groups" },
3094 #endif /* CONFIG_P2P */
3095 #ifdef CONFIG_WIFI_DISPLAY
3096 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
3098 "<subelem> [contents] = set Wi-Fi Display subelement" },
3099 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
3101 "<subelem> = get Wi-Fi Display subelement" },
3102 #endif /* CONFIG_WIFI_DISPLAY */
3103 #ifdef CONFIG_INTERWORKING
3104 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
3105 "= fetch ANQP information for all APs" },
3106 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
3108 "= stop fetch_anqp operation" },
3109 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
3111 "[auto] = perform Interworking network selection" },
3112 { "interworking_connect", wpa_cli_cmd_interworking_connect,
3113 wpa_cli_complete_bss, cli_cmd_flag_none,
3114 "<BSSID> = connect using Interworking credentials" },
3115 { "interworking_add_network", wpa_cli_cmd_interworking_add_network,
3116 wpa_cli_complete_bss, cli_cmd_flag_none,
3117 "<BSSID> = connect using Interworking credentials" },
3118 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
3120 "<addr> <info id>[,<info id>]... = request ANQP information" },
3121 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
3123 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
3124 { "gas_response_get", wpa_cli_cmd_gas_response_get,
3125 wpa_cli_complete_bss, cli_cmd_flag_none,
3126 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
3127 #endif /* CONFIG_INTERWORKING */
3129 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
3131 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3133 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
3134 wpa_cli_complete_bss, cli_cmd_flag_none,
3135 "<addr> <home realm> = get HS20 nai home realm list" },
3136 { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request,
3137 wpa_cli_complete_bss, cli_cmd_flag_none,
3138 "<addr> <icon name> = get Hotspot 2.0 OSU icon" },
3139 { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none,
3140 "= fetch OSU provider information from all APs" },
3141 { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL,
3143 "= cancel fetch_osu command" },
3144 #endif /* CONFIG_HS20 */
3145 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
3147 "<0/1> = disable/enable automatic reconnection" },
3148 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
3150 "<addr> = request TDLS discovery with <addr>" },
3151 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
3153 "<addr> = request TDLS setup with <addr>" },
3154 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
3156 "<addr> = tear down TDLS with <addr>" },
3157 { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
3159 "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
3160 "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] "
3161 "= add WMM-AC traffic stream" },
3162 { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL,
3164 "<tsid> = delete WMM-AC traffic stream" },
3165 { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL,
3167 "= show status for Wireless Multi-Media Admission-Control" },
3168 { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL,
3170 "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] "
3171 "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching "
3173 { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL,
3175 "<addr> = disable channel switching with TDLS peer <addr>" },
3176 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
3178 "= get signal parameters" },
3179 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
3181 "= get TX/RX packet counters" },
3182 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
3184 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3185 #ifdef CONFIG_AUTOSCAN
3186 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
3187 "[params] = Set or unset (if none) autoscan parameters" },
3188 #endif /* CONFIG_AUTOSCAN */
3190 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
3191 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
3192 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
3193 "<query reason> = Send BSS Transition Management Query" },
3194 #endif /* CONFIG_WNM */
3195 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
3196 "<params..> = Sent unprocessed command" },
3197 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
3198 "= flush wpa_supplicant state" },
3200 { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
3201 "<command> = driver private commands" },
3202 #endif /* ANDROID */
3203 { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
3204 "= radio_work <show/add/done>" },
3205 { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
3206 "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
3208 { "neighbor_rep_request",
3209 wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
3210 "[ssid=<SSID>] = Trigger request to AP for neighboring AP report "
3211 "(with optional given SSID, default: current SSID)"
3213 { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
3214 "= flush ERP keys" },
3216 wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none,
3217 "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
3218 "mask=mac-address-mask] = scan MAC randomization"
3220 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
3225 * Prints command usage, lines are padded with the specified string.
3227 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3232 printf("%s%s ", pad, cmd->cmd);
3233 for (n = 0; (c = cmd->usage[n]); n++) {
3242 static void print_help(const char *cmd)
3245 printf("commands:\n");
3246 for (n = 0; wpa_cli_commands[n].cmd; n++) {
3247 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
3248 print_cmd_help(&wpa_cli_commands[n], " ");
3253 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3255 const char *c, *delim;
3259 delim = os_strchr(cmd, ' ');
3263 len = os_strlen(cmd);
3265 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3266 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3267 return (wpa_cli_commands[n].flags &
3268 cli_cmd_flag_sensitive);
3274 static char ** wpa_list_cmd_list(void)
3278 struct cli_txt_entry *e;
3280 count = ARRAY_SIZE(wpa_cli_commands);
3281 count += dl_list_len(&p2p_groups);
3282 count += dl_list_len(&ifnames);
3283 res = os_calloc(count + 1, sizeof(char *));
3287 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3288 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3293 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
3294 size_t len = 8 + os_strlen(e->txt);
3295 res[i] = os_malloc(len);
3298 os_snprintf(res[i], len, "ifname=%s", e->txt);
3302 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
3303 res[i] = os_strdup(e->txt);
3313 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3318 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3319 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3320 if (wpa_cli_commands[i].completion)
3321 return wpa_cli_commands[i].completion(str,
3324 printf("\r%s\n", wpa_cli_commands[i].usage);
3334 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3340 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
3341 end = os_strchr(str, ' ');
3342 if (end && pos > end - str) {
3343 pos -= end - str + 1;
3348 end = os_strchr(str, ' ');
3349 if (end == NULL || str + pos < end)
3350 return wpa_list_cmd_list();
3352 cmd = os_malloc(pos + 1);
3355 os_memcpy(cmd, str, pos);
3356 cmd[end - str] = '\0';
3357 res = wpa_cli_cmd_completion(cmd, str, pos);
3363 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3365 struct wpa_cli_cmd *cmd, *match = NULL;
3369 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
3370 ifname_prefix = argv[0] + 7;
3374 ifname_prefix = NULL;
3380 cmd = wpa_cli_commands;
3382 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3385 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3386 /* we have an exact match */
3396 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3397 cmd = wpa_cli_commands;
3399 if (os_strncasecmp(cmd->cmd, argv[0],
3400 os_strlen(argv[0])) == 0) {
3401 printf(" %s", cmd->cmd);
3407 } else if (count == 0) {
3408 printf("Unknown command '%s'\n", argv[0]);
3411 ret = match->handler(ctrl, argc - 1, &argv[1]);
3418 static int str_match(const char *a, const char *b)
3420 return os_strncmp(a, b, os_strlen(b)) == 0;
3424 static int wpa_cli_exec(const char *program, const char *arg1,
3431 len = os_strlen(arg1) + os_strlen(arg2) + 2;
3432 arg = os_malloc(len);
3435 os_snprintf(arg, len, "%s %s", arg1, arg2);
3436 res = os_exec(program, arg, 1);
3443 static void wpa_cli_action_process(const char *msg)
3446 char *copy = NULL, *id, *pos2;
3447 const char *ifname = ctrl_ifname;
3448 char ifname_buf[100];
3451 if (os_strncmp(pos, "IFNAME=", 7) == 0) {
3453 end = os_strchr(pos + 7, ' ');
3454 if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) {
3456 os_memcpy(ifname_buf, pos, end - pos);
3457 ifname_buf[end - pos] = '\0';
3458 ifname = ifname_buf;
3463 const char *prev = pos;
3465 pos = os_strchr(pos, '>');
3472 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3474 os_unsetenv("WPA_ID");
3475 os_unsetenv("WPA_ID_STR");
3476 os_unsetenv("WPA_CTRL_DIR");
3478 pos = os_strstr(pos, "[id=");
3480 copy = os_strdup(pos + 4);
3484 while (*pos2 && *pos2 != ' ')
3488 os_setenv("WPA_ID", id, 1);
3489 while (*pos2 && *pos2 != '=')
3494 while (*pos2 && *pos2 != ']')
3497 os_setenv("WPA_ID_STR", id, 1);
3501 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3503 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
3504 wpa_cli_connected = 1;
3505 wpa_cli_last_id = new_id;
3506 wpa_cli_exec(action_file, ifname, "CONNECTED");
3508 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3509 if (wpa_cli_connected) {
3510 wpa_cli_connected = 0;
3511 wpa_cli_exec(action_file, ifname, "DISCONNECTED");
3513 } else if (str_match(pos, MESH_GROUP_STARTED)) {
3514 wpa_cli_exec(action_file, ctrl_ifname, pos);
3515 } else if (str_match(pos, MESH_GROUP_REMOVED)) {
3516 wpa_cli_exec(action_file, ctrl_ifname, pos);
3517 } else if (str_match(pos, MESH_PEER_CONNECTED)) {
3518 wpa_cli_exec(action_file, ctrl_ifname, pos);
3519 } else if (str_match(pos, MESH_PEER_DISCONNECTED)) {
3520 wpa_cli_exec(action_file, ctrl_ifname, pos);
3521 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3522 wpa_cli_exec(action_file, ifname, pos);
3523 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3524 wpa_cli_exec(action_file, ifname, pos);
3525 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3526 wpa_cli_exec(action_file, ifname, pos);
3527 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3528 wpa_cli_exec(action_file, ifname, pos);
3529 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3530 wpa_cli_exec(action_file, ifname, pos);
3531 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3532 wpa_cli_exec(action_file, ifname, pos);
3533 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3534 wpa_cli_exec(action_file, ifname, pos);
3535 } else if (str_match(pos, AP_STA_CONNECTED)) {
3536 wpa_cli_exec(action_file, ifname, pos);
3537 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3538 wpa_cli_exec(action_file, ifname, pos);
3539 } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
3540 wpa_cli_exec(action_file, ifname, pos);
3541 } else if (str_match(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
3542 wpa_cli_exec(action_file, ifname, pos);
3543 } else if (str_match(pos, HS20_DEAUTH_IMMINENT_NOTICE)) {
3544 wpa_cli_exec(action_file, ifname, pos);
3545 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3546 printf("wpa_supplicant is terminating - stop monitoring\n");
3552 #ifndef CONFIG_ANSI_C_EXTRA
3553 static void wpa_cli_action_cb(char *msg, size_t len)
3555 wpa_cli_action_process(msg);
3557 #endif /* CONFIG_ANSI_C_EXTRA */
3560 static void wpa_cli_reconnect(void)
3562 wpa_cli_close_connection();
3563 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3568 printf("\rConnection to wpa_supplicant re-established\n");
3574 static void cli_event(const char *str)
3576 const char *start, *s;
3578 start = os_strchr(str, '>');
3584 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3585 s = os_strchr(start, ' ');
3588 s = os_strchr(s + 1, ' ');
3591 cli_txt_list_add(&bsses, s + 1);
3595 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3596 s = os_strchr(start, ' ');
3599 s = os_strchr(s + 1, ' ');
3602 cli_txt_list_del_addr(&bsses, s + 1);
3607 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3608 s = os_strstr(start, " p2p_dev_addr=");
3611 cli_txt_list_add_addr(&p2p_peers, s + 14);
3615 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3616 s = os_strstr(start, " p2p_dev_addr=");
3619 cli_txt_list_del_addr(&p2p_peers, s + 14);
3623 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3624 s = os_strchr(start, ' ');
3627 cli_txt_list_add_word(&p2p_groups, s + 1);
3631 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3632 s = os_strchr(start, ' ');
3635 cli_txt_list_del_word(&p2p_groups, s + 1);
3638 #endif /* CONFIG_P2P */
3642 static int check_terminating(const char *msg)
3644 const char *pos = msg;
3648 pos = os_strchr(pos, '>');
3655 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3657 printf("\rConnection to wpa_supplicant lost - trying to "
3660 wpa_cli_attached = 0;
3661 wpa_cli_close_connection();
3669 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3671 if (ctrl_conn == NULL) {
3672 wpa_cli_reconnect();
3675 while (wpa_ctrl_pending(ctrl) > 0) {
3677 size_t len = sizeof(buf) - 1;
3678 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3681 wpa_cli_action_process(buf);
3684 if (wpa_cli_show_event(buf)) {
3686 printf("\r%s\n", buf);
3690 if (interactive && check_terminating(buf) > 0)
3694 printf("Could not read pending message.\n");
3699 if (wpa_ctrl_pending(ctrl) < 0) {
3700 printf("Connection to wpa_supplicant lost - trying to "
3702 wpa_cli_reconnect();
3708 static int tokenize_cmd(char *cmd, char *argv[])
3721 if (argc == max_args)
3724 char *pos2 = os_strrchr(pos, '"');
3728 while (*pos != '\0' && *pos != ' ')
3738 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3742 char *prefix = ifname_prefix;
3744 ifname_prefix = NULL;
3745 res = _wpa_ctrl_command(ctrl_conn, "PING", 0);
3746 ifname_prefix = prefix;
3748 printf("Connection to wpa_supplicant lost - trying to "
3750 wpa_cli_close_connection();
3754 wpa_cli_reconnect();
3755 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3759 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3761 wpa_cli_recv_pending(mon_conn, 0);
3765 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3767 char *argv[max_args];
3769 argc = tokenize_cmd(cmd, argv);
3771 wpa_request(ctrl_conn, argc, argv);
3775 static void wpa_cli_edit_eof_cb(void *ctx)
3781 static int warning_displayed = 0;
3782 static char *hfile = NULL;
3783 static int edit_started = 0;
3785 static void start_edit(void)
3790 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3791 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3792 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3794 #ifdef CONFIG_WPA_CLI_HISTORY_DIR
3795 home = CONFIG_WPA_CLI_HISTORY_DIR;
3796 #else /* CONFIG_WPA_CLI_HISTORY_DIR */
3797 home = getenv("HOME");
3798 #endif /* CONFIG_WPA_CLI_HISTORY_DIR */
3800 const char *fname = ".wpa_cli_history";
3801 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3802 hfile = os_malloc(hfile_len);
3804 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3807 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3808 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3814 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3818 static void update_bssid_list(struct wpa_ctrl *ctrl)
3821 size_t len = sizeof(buf);
3823 char *cmd = "BSS RANGE=ALL MASK=0x2";
3828 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3835 pos = os_strstr(pos, "bssid=");
3839 end = os_strchr(pos, '\n');
3843 cli_txt_list_add(&bsses, pos);
3849 static void update_ifnames(struct wpa_ctrl *ctrl)
3852 size_t len = sizeof(buf);
3854 char *cmd = "INTERFACES";
3858 cli_txt_list_flush(&ifnames);
3862 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3869 end = os_strchr(pos, '\n');
3873 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
3874 if (!os_snprintf_error(sizeof(txt), ret))
3875 cli_txt_list_add(&ifnames, txt);
3881 static void update_networks(struct wpa_ctrl *ctrl)
3884 size_t len = sizeof(buf);
3886 char *cmd = "LIST_NETWORKS";
3890 cli_txt_list_flush(&networks);
3894 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3901 end = os_strchr(pos, '\n');
3906 cli_txt_list_add_word(&networks, pos);
3913 static void try_connection(void *eloop_ctx, void *timeout_ctx)
3918 if (ctrl_ifname == NULL)
3919 ctrl_ifname = wpa_cli_get_default_ifname();
3921 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3922 if (!warning_displayed) {
3923 printf("Could not connect to wpa_supplicant: "
3925 ctrl_ifname ? ctrl_ifname : "(nil)");
3926 warning_displayed = 1;
3928 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
3932 update_bssid_list(ctrl_conn);
3933 update_networks(ctrl_conn);
3935 if (warning_displayed)
3936 printf("Connection established.\n");
3943 static void wpa_cli_interactive(void)
3945 printf("\nInteractive mode\n\n");
3947 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
3949 eloop_cancel_timeout(try_connection, NULL, NULL);
3951 cli_txt_list_flush(&p2p_peers);
3952 cli_txt_list_flush(&p2p_groups);
3953 cli_txt_list_flush(&bsses);
3954 cli_txt_list_flush(&ifnames);
3955 cli_txt_list_flush(&networks);
3957 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3959 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3960 wpa_cli_close_connection();
3964 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3966 #ifdef CONFIG_ANSI_C_EXTRA
3967 /* TODO: ANSI C version(?) */
3968 printf("Action processing not supported in ANSI C build.\n");
3969 #else /* CONFIG_ANSI_C_EXTRA */
3973 char buf[256]; /* note: large enough to fit in unsolicited messages */
3976 fd = wpa_ctrl_get_fd(ctrl);
3978 while (!wpa_cli_quit) {
3981 tv.tv_sec = ping_interval;
3983 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3984 if (res < 0 && errno != EINTR) {
3989 if (FD_ISSET(fd, &rfds))
3990 wpa_cli_recv_pending(ctrl, 1);
3992 /* verify that connection is still working */
3993 len = sizeof(buf) - 1;
3994 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3995 wpa_cli_action_cb) < 0 ||
3996 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3997 printf("wpa_supplicant did not reply to PING "
3998 "command - exiting\n");
4003 #endif /* CONFIG_ANSI_C_EXTRA */
4007 static void wpa_cli_cleanup(void)
4009 wpa_cli_close_connection();
4011 os_daemonize_terminate(pid_file);
4013 os_program_deinit();
4017 static void wpa_cli_terminate(int sig, void *ctx)
4023 static char * wpa_cli_get_default_ifname(void)
4025 char *ifname = NULL;
4027 #ifdef CONFIG_CTRL_IFACE_UNIX
4028 struct dirent *dent;
4029 DIR *dir = opendir(ctrl_iface_dir);
4032 char ifprop[PROPERTY_VALUE_MAX];
4033 if (property_get("wifi.interface", ifprop, NULL) != 0) {
4034 ifname = os_strdup(ifprop);
4035 printf("Using interface '%s'\n", ifname);
4038 #endif /* ANDROID */
4041 while ((dent = readdir(dir))) {
4042 #ifdef _DIRENT_HAVE_D_TYPE
4044 * Skip the file if it is not a socket. Also accept
4045 * DT_UNKNOWN (0) in case the C library or underlying
4046 * file system does not support d_type.
4048 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
4050 #endif /* _DIRENT_HAVE_D_TYPE */
4051 if (os_strcmp(dent->d_name, ".") == 0 ||
4052 os_strcmp(dent->d_name, "..") == 0)
4054 printf("Selected interface '%s'\n", dent->d_name);
4055 ifname = os_strdup(dent->d_name);
4059 #endif /* CONFIG_CTRL_IFACE_UNIX */
4061 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4062 char buf[4096], *pos;
4064 struct wpa_ctrl *ctrl;
4067 ctrl = wpa_ctrl_open(NULL);
4071 len = sizeof(buf) - 1;
4072 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
4075 pos = os_strchr(buf, '\n');
4078 ifname = os_strdup(buf);
4080 wpa_ctrl_close(ctrl);
4081 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4087 int main(int argc, char *argv[])
4092 const char *global = NULL;
4094 if (os_program_init())
4098 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
4103 action_file = optarg;
4112 ping_interval = atoi(optarg);
4118 printf("%s\n", wpa_cli_version);
4121 os_free(ctrl_ifname);
4122 ctrl_ifname = os_strdup(optarg);
4125 ctrl_iface_dir = optarg;
4136 interactive = (argc == optind) && (action_file == NULL);
4139 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
4145 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4146 ctrl_conn = wpa_ctrl_open(NULL);
4147 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4148 ctrl_conn = wpa_ctrl_open(global);
4149 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4150 if (ctrl_conn == NULL) {
4151 fprintf(stderr, "Failed to connect to wpa_supplicant "
4152 "global interface: %s error: %s\n",
4153 global, strerror(errno));
4158 update_ifnames(ctrl_conn);
4159 mon_conn = wpa_ctrl_open(global);
4161 if (wpa_ctrl_attach(mon_conn) == 0) {
4162 wpa_cli_attached = 1;
4163 eloop_register_read_sock(
4164 wpa_ctrl_get_fd(mon_conn),
4165 wpa_cli_mon_receive,
4168 printf("Failed to open monitor "
4169 "connection through global "
4170 "control interface\n");
4176 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
4178 if (ctrl_ifname == NULL)
4179 ctrl_ifname = wpa_cli_get_default_ifname();
4182 wpa_cli_interactive();
4185 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
4186 fprintf(stderr, "Failed to connect to non-global "
4187 "ctrl_ifname: %s error: %s\n",
4188 ctrl_ifname ? ctrl_ifname : "(nil)",
4194 if (wpa_ctrl_attach(ctrl_conn) == 0) {
4195 wpa_cli_attached = 1;
4197 printf("Warning: Failed to attach to "
4198 "wpa_supplicant.\n");
4203 if (daemonize && os_daemonize(pid_file))
4207 wpa_cli_action(ctrl_conn);
4209 ret = wpa_request(ctrl_conn, argc - optind,
4213 os_free(ctrl_ifname);
4220 #else /* CONFIG_CTRL_IFACE */
4221 int main(int argc, char *argv[])
4223 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
4226 #endif /* CONFIG_CTRL_IFACE */