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 const char *network_fields[] = {
1533 "ssid", "scan_ssid", "bssid", "bssid_blacklist",
1534 "bssid_whitelist", "psk", "proto", "key_mgmt",
1535 "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
1537 #ifdef IEEE8021X_EAPOL
1538 "eap", "identity", "anonymous_identity", "password", "ca_cert",
1539 "ca_path", "client_cert", "private_key", "private_key_passwd",
1540 "dh_file", "subject_match", "altsubject_match",
1541 "domain_suffix_match", "domain_match", "ca_cert2", "ca_path2",
1542 "client_cert2", "private_key2", "private_key2_passwd",
1543 "dh_file2", "subject_match2", "altsubject_match2",
1544 "domain_suffix_match2", "domain_match2", "phase1", "phase2",
1545 "pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id",
1546 "pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id",
1547 "engine", "engine2", "eapol_flags", "sim_num",
1548 "openssl_ciphers", "erp",
1549 #endif /* IEEE8021X_EAPOL */
1550 "wep_key0", "wep_key1", "wep_key2", "wep_key3",
1551 "wep_tx_keyidx", "priority",
1552 #ifdef IEEE8021X_EAPOL
1553 "eap_workaround", "pac_file", "fragment_size", "ocsp",
1554 #endif /* IEEE8021X_EAPOL */
1556 "mode", "no_auto_peer",
1557 #else /* CONFIG_MESH */
1559 #endif /* CONFIG_MESH */
1560 "proactive_key_caching", "disabled", "id_str",
1561 #ifdef CONFIG_IEEE80211W
1563 #endif /* CONFIG_IEEE80211W */
1564 "peerkey", "mixed_cell", "frequency", "fixed_freq",
1566 "mesh_basic_rates", "dot11MeshMaxRetries",
1567 "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout",
1568 "dot11MeshHoldingTimeout",
1569 #endif /* CONFIG_MESH */
1570 "wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid",
1572 "go_p2p_dev_addr", "p2p_client_list", "psk_list",
1573 #endif /* CONFIG_P2P */
1574 #ifdef CONFIG_HT_OVERRIDES
1575 "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc",
1576 "ht40_intolerant", "disable_max_amsdu", "ampdu_factor",
1577 "ampdu_density", "ht_mcs",
1578 #endif /* CONFIG_HT_OVERRIDES */
1579 #ifdef CONFIG_VHT_OVERRIDES
1580 "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1",
1581 "vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4",
1582 "vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7",
1583 "vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2",
1584 "vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5",
1585 "vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8",
1586 #endif /* CONFIG_VHT_OVERRIDES */
1587 "ap_max_inactivity", "dtim_period", "beacon_int",
1588 #ifdef CONFIG_MACSEC
1590 #endif /* CONFIG_MACSEC */
1592 "update_identifier",
1593 #endif /* CONFIG_HS20 */
1598 static char ** wpa_cli_complete_network(const char *str, int pos)
1600 int arg = get_cmd_arg_num(str, pos);
1601 int i, num_fields = ARRAY_SIZE(network_fields);
1606 res = cli_txt_list_array(&networks);
1609 res = os_calloc(num_fields + 1, sizeof(char *));
1612 for (i = 0; i < num_fields; i++) {
1613 res[i] = os_strdup(network_fields[i]);
1622 static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc,
1626 wpa_cli_show_network_variables();
1631 printf("Invalid DUP_NETWORK command: needs three arguments\n"
1632 "(src netid, dest netid, and variable name)\n");
1636 return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv);
1640 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1643 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1647 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1649 return wpa_ctrl_command(ctrl, "ADD_CRED");
1653 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1656 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1660 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1663 printf("Invalid SET_CRED command: needs three arguments\n"
1664 "(cred id, variable name, and value)\n");
1668 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1672 static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1675 printf("Invalid GET_CRED command: needs two arguments\n"
1676 "(cred id, variable name)\n");
1680 return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv);
1684 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1687 return wpa_ctrl_command(ctrl, "DISCONNECT");
1691 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1694 return wpa_ctrl_command(ctrl, "RECONNECT");
1698 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1701 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1705 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1707 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1711 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1714 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1718 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1720 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1724 static char ** wpa_cli_complete_bss(const char *str, int pos)
1726 int arg = get_cmd_arg_num(str, pos);
1731 res = cli_txt_list_array(&bsses);
1739 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1742 if (argc < 1 || argc > 2) {
1743 printf("Invalid GET_CAPABILITY command: need either one or "
1748 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1749 printf("Invalid GET_CAPABILITY command: second argument, "
1750 "if any, must be 'strict'\n");
1754 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1758 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1760 printf("Available interfaces:\n");
1761 return wpa_ctrl_command(ctrl, "INTERFACES");
1765 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1768 wpa_cli_list_interfaces(ctrl);
1772 wpa_cli_close_connection();
1773 os_free(ctrl_ifname);
1774 ctrl_ifname = os_strdup(argv[0]);
1776 printf("Failed to allocate memory\n");
1780 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
1781 printf("Connected to interface '%s.\n", ctrl_ifname);
1783 printf("Could not connect to interface '%s' - re-trying\n",
1790 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1793 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1797 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1800 return wpa_ctrl_command(ctrl, "TERMINATE");
1804 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1811 printf("Invalid INTERFACE_ADD command: needs at least one "
1812 "argument (interface name)\n"
1813 "All arguments: ifname confname driver ctrl_interface "
1814 "driver_param bridge_name [create]\n");
1819 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1820 * <driver_param>TAB<bridge_name>[TAB<create>]
1822 res = os_snprintf(cmd, sizeof(cmd),
1823 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s",
1825 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1826 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1827 argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "");
1828 if (os_snprintf_error(sizeof(cmd), res))
1830 cmd[sizeof(cmd) - 1] = '\0';
1831 return wpa_ctrl_command(ctrl, cmd);
1835 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1838 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1842 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1845 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1850 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1852 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1856 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1857 char *addr, size_t addr_len)
1859 char buf[4096], *pos;
1863 if (ctrl_conn == NULL) {
1864 printf("Not connected to hostapd - command dropped.\n");
1867 len = sizeof(buf) - 1;
1868 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1871 printf("'%s' command timed out.\n", cmd);
1873 } else if (ret < 0) {
1874 printf("'%s' command failed.\n", cmd);
1879 if (os_memcmp(buf, "FAIL", 4) == 0)
1884 while (*pos != '\0' && *pos != '\n')
1887 os_strlcpy(addr, buf, addr_len);
1892 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1894 char addr[32], cmd[64];
1896 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1899 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1900 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1906 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1909 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1913 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1916 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1919 static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
1922 return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
1925 #endif /* CONFIG_AP */
1928 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1930 return wpa_ctrl_command(ctrl, "SUSPEND");
1934 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1936 return wpa_ctrl_command(ctrl, "RESUME");
1940 #ifdef CONFIG_TESTING_OPTIONS
1941 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1943 return wpa_ctrl_command(ctrl, "DROP_SA");
1945 #endif /* CONFIG_TESTING_OPTIONS */
1948 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1950 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1956 static int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc,
1959 return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv);
1963 static int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc,
1966 return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv);
1970 static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc,
1973 return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
1976 #endif /* CONFIG_MESH */
1981 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1983 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1987 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1990 int arg = get_cmd_arg_num(str, pos);
1992 res = os_calloc(6, sizeof(char *));
1995 res[0] = os_strdup("type=social");
1996 if (res[0] == NULL) {
2000 res[1] = os_strdup("type=progressive");
2003 res[2] = os_strdup("delay=");
2006 res[3] = os_strdup("dev_id=");
2010 res[4] = os_strdup("[timeout]");
2016 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
2019 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
2023 static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc,
2026 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv);
2030 static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc,
2033 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv);
2037 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
2040 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
2044 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
2046 int arg = get_cmd_arg_num(str, pos);
2051 res = cli_txt_list_array(&p2p_peers);
2059 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2062 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
2066 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2069 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
2073 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2075 int arg = get_cmd_arg_num(str, pos);
2080 res = cli_txt_list_array(&p2p_groups);
2088 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2091 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
2095 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2098 if (argc != 2 && argc != 3) {
2099 printf("Invalid P2P_PROV_DISC command: needs at least "
2100 "two arguments, address and config method\n"
2101 "(display, keypad, or pbc) and an optional join\n");
2105 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
2109 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2112 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2116 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2122 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2123 "or more arguments (address and TLVs)\n");
2127 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
2129 return wpa_ctrl_command(ctrl, cmd);
2133 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2134 int argc, char *argv[])
2136 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
2140 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2147 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2148 "arguments (freq, address, dialog token, and TLVs)\n");
2152 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2153 argv[0], argv[1], argv[2], argv[3]);
2154 if (os_snprintf_error(sizeof(cmd), res))
2156 cmd[sizeof(cmd) - 1] = '\0';
2157 return wpa_ctrl_command(ctrl, cmd);
2161 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2164 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2168 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2169 int argc, char *argv[])
2171 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
2175 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2178 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2182 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2186 printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n");
2190 return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv);
2194 static int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc,
2197 if (argc < 5 || argc > 6) {
2198 printf("Invalid P2P_SERVICE_REP command: needs 5-6 "
2203 return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv);
2207 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2213 if (argc != 2 && argc != 3) {
2214 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2220 res = os_snprintf(cmd, sizeof(cmd),
2221 "P2P_SERVICE_DEL %s %s %s",
2222 argv[0], argv[1], argv[2]);
2224 res = os_snprintf(cmd, sizeof(cmd),
2225 "P2P_SERVICE_DEL %s %s",
2227 if (os_snprintf_error(sizeof(cmd), res))
2229 cmd[sizeof(cmd) - 1] = '\0';
2230 return wpa_ctrl_command(ctrl, cmd);
2234 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2235 int argc, char *argv[])
2237 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
2241 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2242 int argc, char *argv[])
2244 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
2248 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2250 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2254 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2256 int arg = get_cmd_arg_num(str, pos);
2261 res = cli_txt_list_array(&p2p_peers);
2269 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2270 char *addr, size_t addr_len,
2273 char buf[4096], *pos;
2277 if (ctrl_conn == NULL)
2279 len = sizeof(buf) - 1;
2280 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2283 printf("'%s' command timed out.\n", cmd);
2285 } else if (ret < 0) {
2286 printf("'%s' command failed.\n", cmd);
2291 if (os_memcmp(buf, "FAIL", 4) == 0)
2295 while (*pos != '\0' && *pos != '\n')
2298 os_strlcpy(addr, buf, addr_len);
2299 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2300 printf("%s\n", addr);
2305 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2307 char addr[32], cmd[64];
2310 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2312 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2313 addr, sizeof(addr), discovered))
2316 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2317 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2324 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2326 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2330 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
2332 int arg = get_cmd_arg_num(str, pos);
2333 const char *fields[] = {
2353 int i, num_fields = ARRAY_SIZE(fields);
2356 char **res = os_calloc(num_fields + 1, sizeof(char *));
2359 for (i = 0; i < num_fields; i++) {
2360 res[i] = os_strdup(fields[i]);
2367 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
2368 return cli_txt_list_array(&p2p_peers);
2374 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2376 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2380 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2383 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2387 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2390 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2394 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2397 if (argc != 0 && argc != 2 && argc != 4) {
2398 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2399 "(preferred duration, interval; in microsecods).\n"
2400 "Optional second pair can be used to provide "
2401 "acceptable values.\n");
2405 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2409 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2412 if (argc != 0 && argc != 2) {
2413 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2414 "(availability period, availability interval; in "
2416 "Extended Listen Timing can be cancelled with this "
2417 "command when used without parameters.\n");
2421 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2425 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
2428 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
2431 #endif /* CONFIG_P2P */
2433 #ifdef CONFIG_WIFI_DISPLAY
2435 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2441 if (argc != 1 && argc != 2) {
2442 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2443 "arguments (subelem, hexdump)\n");
2447 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2448 argv[0], argc > 1 ? argv[1] : "");
2449 if (os_snprintf_error(sizeof(cmd), res))
2451 cmd[sizeof(cmd) - 1] = '\0';
2452 return wpa_ctrl_command(ctrl, cmd);
2456 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2463 printf("Invalid WFD_SUBELEM_GET command: needs one "
2464 "argument (subelem)\n");
2468 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2470 if (os_snprintf_error(sizeof(cmd), res))
2472 cmd[sizeof(cmd) - 1] = '\0';
2473 return wpa_ctrl_command(ctrl, cmd);
2475 #endif /* CONFIG_WIFI_DISPLAY */
2478 #ifdef CONFIG_INTERWORKING
2479 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2482 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2486 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2489 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2493 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2496 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2500 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2503 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2507 static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc,
2510 return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv);
2514 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2516 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2520 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2523 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2527 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2530 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2532 #endif /* CONFIG_INTERWORKING */
2537 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2540 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2544 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2550 printf("Command needs one or two arguments (dst mac addr and "
2551 "optional home realm)\n");
2555 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2559 return wpa_ctrl_command(ctrl, cmd);
2563 static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc,
2569 printf("Command needs two arguments (dst mac addr and "
2574 if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0)
2577 return wpa_ctrl_command(ctrl, cmd);
2581 static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[])
2583 return wpa_ctrl_command(ctrl, "FETCH_OSU");
2587 static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc,
2590 return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU");
2593 #endif /* CONFIG_HS20 */
2596 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2599 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2603 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2606 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2610 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2613 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2617 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2620 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2624 static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc,
2627 return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv);
2631 static int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc,
2634 return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv);
2638 static int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc,
2641 return wpa_ctrl_command(ctrl, "WMM_AC_STATUS");
2645 static int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc,
2648 return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv);
2652 static int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc,
2655 return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv);
2659 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2662 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2666 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2669 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2673 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2676 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2680 #ifdef CONFIG_AUTOSCAN
2682 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2685 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2687 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2690 #endif /* CONFIG_AUTOSCAN */
2695 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2697 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2701 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2703 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2706 #endif /* CONFIG_WNM */
2709 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2713 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2718 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2720 return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
2722 #endif /* ANDROID */
2725 static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
2727 return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv);
2731 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2733 return wpa_ctrl_command(ctrl, "FLUSH");
2737 static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
2739 return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
2743 static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc,
2746 return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv);
2750 static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2752 return wpa_ctrl_command(ctrl, "ERP_FLUSH");
2756 static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc,
2759 return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv);
2763 enum wpa_cli_cmd_flags {
2764 cli_cmd_flag_none = 0x00,
2765 cli_cmd_flag_sensitive = 0x01
2768 struct wpa_cli_cmd {
2770 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2771 char ** (*completion)(const char *str, int pos);
2772 enum wpa_cli_cmd_flags flags;
2776 static struct wpa_cli_cmd wpa_cli_commands[] = {
2777 { "status", wpa_cli_cmd_status, NULL,
2779 "[verbose] = get current WPA/EAPOL/EAP status" },
2780 { "ifname", wpa_cli_cmd_ifname, NULL,
2782 "= get current interface name" },
2783 { "ping", wpa_cli_cmd_ping, NULL,
2785 "= pings wpa_supplicant" },
2786 { "relog", wpa_cli_cmd_relog, NULL,
2788 "= re-open log-file (allow rolling logs)" },
2789 { "note", wpa_cli_cmd_note, NULL,
2791 "<text> = add a note to wpa_supplicant debug log" },
2792 { "mib", wpa_cli_cmd_mib, NULL,
2794 "= get MIB variables (dot1x, dot11)" },
2795 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2797 "[command] = show usage help" },
2798 { "interface", wpa_cli_cmd_interface, NULL,
2800 "[ifname] = show interfaces/select interface" },
2801 { "level", wpa_cli_cmd_level, NULL,
2803 "<debug level> = change debug level" },
2804 { "license", wpa_cli_cmd_license, NULL,
2806 "= show full wpa_cli license" },
2807 { "quit", wpa_cli_cmd_quit, NULL,
2810 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2812 "= set variables (shows list of variables when run without "
2814 { "dump", wpa_cli_cmd_dump, NULL,
2816 "= dump config variables" },
2817 { "get", wpa_cli_cmd_get, wpa_cli_complete_get,
2819 "<name> = get information" },
2820 { "logon", wpa_cli_cmd_logon, NULL,
2822 "= IEEE 802.1X EAPOL state machine logon" },
2823 { "logoff", wpa_cli_cmd_logoff, NULL,
2825 "= IEEE 802.1X EAPOL state machine logoff" },
2826 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2828 "= show PMKSA cache" },
2829 { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL,
2831 "= flush PMKSA cache entries" },
2832 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2834 "= force reassociation" },
2835 { "reattach", wpa_cli_cmd_reattach, NULL,
2837 "= force reassociation back to the same BSS" },
2838 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2840 "<BSSID> = force preauthentication" },
2841 { "identity", wpa_cli_cmd_identity, NULL,
2843 "<network id> <identity> = configure identity for an SSID" },
2844 { "password", wpa_cli_cmd_password, NULL,
2845 cli_cmd_flag_sensitive,
2846 "<network id> <password> = configure password for an SSID" },
2847 { "new_password", wpa_cli_cmd_new_password, NULL,
2848 cli_cmd_flag_sensitive,
2849 "<network id> <password> = change password for an SSID" },
2850 { "pin", wpa_cli_cmd_pin, NULL,
2851 cli_cmd_flag_sensitive,
2852 "<network id> <pin> = configure pin for an SSID" },
2853 { "otp", wpa_cli_cmd_otp, NULL,
2854 cli_cmd_flag_sensitive,
2855 "<network id> <password> = configure one-time-password for an SSID"
2857 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2858 cli_cmd_flag_sensitive,
2859 "<network id> <passphrase> = configure private key passphrase\n"
2861 { "sim", wpa_cli_cmd_sim, NULL,
2862 cli_cmd_flag_sensitive,
2863 "<network id> <pin> = report SIM operation result" },
2864 { "bssid", wpa_cli_cmd_bssid, NULL,
2866 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2867 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2869 "<BSSID> = add a BSSID to the blacklist\n"
2870 "blacklist clear = clear the blacklist\n"
2871 "blacklist = display the blacklist" },
2872 { "log_level", wpa_cli_cmd_log_level, NULL,
2874 "<level> [<timestamp>] = update the log level/timestamp\n"
2875 "log_level = display the current log level and log options" },
2876 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2878 "= list configured networks" },
2879 { "select_network", wpa_cli_cmd_select_network, NULL,
2881 "<network id> = select a network (disable others)" },
2882 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2884 "<network id> = enable a network" },
2885 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2887 "<network id> = disable a network" },
2888 { "add_network", wpa_cli_cmd_add_network, NULL,
2890 "= add a network" },
2891 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2893 "<network id> = remove a network" },
2894 { "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network,
2895 cli_cmd_flag_sensitive,
2896 "<network id> <variable> <value> = set network variables (shows\n"
2897 " list of variables when run without arguments)" },
2898 { "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network,
2900 "<network id> <variable> = get network variables" },
2901 { "dup_network", wpa_cli_cmd_dup_network, NULL,
2903 "<src network id> <dst network id> <variable> = duplicate network variables"
2905 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2907 "= list configured credentials" },
2908 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2910 "= add a credential" },
2911 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2913 "<cred id> = remove a credential" },
2914 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2915 cli_cmd_flag_sensitive,
2916 "<cred id> <variable> <value> = set credential variables" },
2917 { "get_cred", wpa_cli_cmd_get_cred, NULL,
2919 "<cred id> <variable> = get credential variables" },
2920 { "save_config", wpa_cli_cmd_save_config, NULL,
2922 "= save the current configuration" },
2923 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2925 "= disconnect and wait for reassociate/reconnect command before\n"
2927 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2929 "= like reassociate, but only takes effect if already disconnected"
2931 { "scan", wpa_cli_cmd_scan, NULL,
2933 "= request new BSS scan" },
2934 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2936 "= get latest scan results" },
2937 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2939 "<<idx> | <bssid>> = get detailed scan result info" },
2940 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2942 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2943 "= get capabilies" },
2944 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2946 "= force wpa_supplicant to re-read its configuration file" },
2947 { "terminate", wpa_cli_cmd_terminate, NULL,
2949 "= terminate wpa_supplicant" },
2950 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2952 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2953 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2955 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2957 "<ifname> = removes the interface" },
2958 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2960 "= list available interfaces" },
2961 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2963 "<value> = set ap_scan parameter" },
2964 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2966 "<value> = set scan_interval parameter (in seconds)" },
2967 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2969 "<value> = set BSS expiration age parameter" },
2970 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2972 "<value> = set BSS expiration scan count parameter" },
2973 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2975 "<value> = set BSS flush age (0 by default)" },
2976 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2978 "<addr> = request STK negotiation with <addr>" },
2979 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2981 "<addr> = request over-the-DS FT with <addr>" },
2982 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2984 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2985 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2986 cli_cmd_flag_sensitive,
2987 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2989 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2990 cli_cmd_flag_sensitive,
2991 "<PIN> = verify PIN checksum" },
2992 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2993 "Cancels the pending WPS operation" },
2994 #ifdef CONFIG_WPS_NFC
2995 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2997 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2998 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
3000 "<WPS|NDEF> = build configuration token" },
3001 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
3003 "<WPS|NDEF> = create password token" },
3004 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
3005 cli_cmd_flag_sensitive,
3006 "<hexdump of payload> = report read NFC tag with WPS data" },
3007 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
3009 "<NDEF> <WPS> = create NFC handover request" },
3010 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
3012 "<NDEF> <WPS> = create NFC handover select" },
3013 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
3015 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
3017 #endif /* CONFIG_WPS_NFC */
3018 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
3019 cli_cmd_flag_sensitive,
3020 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
3021 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
3022 cli_cmd_flag_sensitive,
3023 "[params..] = enable/disable AP PIN" },
3024 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
3026 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
3027 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
3029 "= stop Wi-Fi Protected Setup External Registrar" },
3030 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
3031 cli_cmd_flag_sensitive,
3032 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
3033 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
3035 "<UUID> = accept an Enrollee PBC using External Registrar" },
3036 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
3037 cli_cmd_flag_sensitive,
3038 "<UUID> <PIN> = learn AP configuration" },
3039 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
3041 "<UUID> <network id> = set AP configuration for enrolling" },
3042 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
3043 cli_cmd_flag_sensitive,
3044 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
3045 #ifdef CONFIG_WPS_NFC
3046 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
3048 "<WPS/NDEF> <UUID> = build NFC configuration token" },
3049 #endif /* CONFIG_WPS_NFC */
3050 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
3052 "<addr> = request RSN authentication with <addr> in IBSS" },
3054 { "sta", wpa_cli_cmd_sta, NULL,
3056 "<addr> = get information about an associated station (AP)" },
3057 { "all_sta", wpa_cli_cmd_all_sta, NULL,
3059 "= get information about all associated stations (AP)" },
3060 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
3062 "<addr> = deauthenticate a station" },
3063 { "disassociate", wpa_cli_cmd_disassociate, NULL,
3065 "<addr> = disassociate a station" },
3066 { "chan_switch", wpa_cli_cmd_chanswitch, NULL,
3068 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
3069 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
3070 " = CSA parameters" },
3071 #endif /* CONFIG_AP */
3072 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
3073 "= notification of suspend/hibernate" },
3074 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
3075 "= notification of resume/thaw" },
3076 #ifdef CONFIG_TESTING_OPTIONS
3077 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
3078 "= drop SA without deauth/disassoc (test command)" },
3079 #endif /* CONFIG_TESTING_OPTIONS */
3080 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
3082 "<addr> = roam to the specified BSS" },
3084 { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL,
3086 "[ifname] = Create a new mesh interface" },
3087 { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL,
3089 "<network id> = join a mesh network (disable others)" },
3090 { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
3092 "<ifname> = Remove mesh group interface" },
3093 #endif /* CONFIG_MESH */
3095 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
3097 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3098 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
3099 "= stop P2P Devices search" },
3100 { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL,
3102 "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" },
3103 { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL,
3105 "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" },
3106 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
3108 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
3109 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
3110 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3111 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
3112 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
3113 "<ifname> = remove P2P group interface (terminate group if GO)" },
3114 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
3115 "[ht40] = add a new P2P group (local end as GO)" },
3116 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
3117 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3118 "<addr> <method> = request provisioning discovery" },
3119 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
3121 "= get the passphrase for a group (GO only)" },
3122 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
3123 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3124 "<addr> <TLVs> = schedule service discovery request" },
3125 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
3126 NULL, cli_cmd_flag_none,
3127 "<id> = cancel pending service discovery request" },
3128 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
3130 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3131 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
3133 "= indicate change in local services" },
3134 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
3136 "<external> = set external processing of service discovery" },
3137 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
3139 "= remove all stored service entries" },
3140 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
3142 "<bonjour|upnp|asp> <query|version> <response|service> = add a local "
3144 { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL,
3146 "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace "
3147 "local ASP service" },
3148 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
3150 "<bonjour|upnp> <query|version> [|service] = remove a local "
3152 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
3154 "<addr> = reject connection attempts from a specific peer" },
3155 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
3157 "<cmd> [peer=addr] = invite peer" },
3158 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
3159 "[discovered] = list known (optionally, only fully discovered) P2P "
3161 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
3163 "<address> = show information about known P2P peer" },
3164 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
3166 "<field> <value> = set a P2P parameter" },
3167 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
3168 "= flush P2P state" },
3169 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
3170 "= cancel P2P group formation" },
3171 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
3172 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3173 "<address> = unauthorize a peer" },
3174 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
3176 "[<duration> <interval>] [<duration> <interval>] = request GO "
3178 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
3180 "[<period> <interval>] = set extended listen timing" },
3181 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
3182 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3183 "<address|iface=address> = remove a peer from all groups" },
3184 #endif /* CONFIG_P2P */
3185 #ifdef CONFIG_WIFI_DISPLAY
3186 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
3188 "<subelem> [contents] = set Wi-Fi Display subelement" },
3189 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
3191 "<subelem> = get Wi-Fi Display subelement" },
3192 #endif /* CONFIG_WIFI_DISPLAY */
3193 #ifdef CONFIG_INTERWORKING
3194 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
3195 "= fetch ANQP information for all APs" },
3196 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
3198 "= stop fetch_anqp operation" },
3199 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
3201 "[auto] = perform Interworking network selection" },
3202 { "interworking_connect", wpa_cli_cmd_interworking_connect,
3203 wpa_cli_complete_bss, cli_cmd_flag_none,
3204 "<BSSID> = connect using Interworking credentials" },
3205 { "interworking_add_network", wpa_cli_cmd_interworking_add_network,
3206 wpa_cli_complete_bss, cli_cmd_flag_none,
3207 "<BSSID> = connect using Interworking credentials" },
3208 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
3210 "<addr> <info id>[,<info id>]... = request ANQP information" },
3211 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
3213 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
3214 { "gas_response_get", wpa_cli_cmd_gas_response_get,
3215 wpa_cli_complete_bss, cli_cmd_flag_none,
3216 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
3217 #endif /* CONFIG_INTERWORKING */
3219 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
3221 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3223 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
3224 wpa_cli_complete_bss, cli_cmd_flag_none,
3225 "<addr> <home realm> = get HS20 nai home realm list" },
3226 { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request,
3227 wpa_cli_complete_bss, cli_cmd_flag_none,
3228 "<addr> <icon name> = get Hotspot 2.0 OSU icon" },
3229 { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none,
3230 "= fetch OSU provider information from all APs" },
3231 { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL,
3233 "= cancel fetch_osu command" },
3234 #endif /* CONFIG_HS20 */
3235 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
3237 "<0/1> = disable/enable automatic reconnection" },
3238 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
3240 "<addr> = request TDLS discovery with <addr>" },
3241 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
3243 "<addr> = request TDLS setup with <addr>" },
3244 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
3246 "<addr> = tear down TDLS with <addr>" },
3247 { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
3249 "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
3250 "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] "
3251 "= add WMM-AC traffic stream" },
3252 { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL,
3254 "<tsid> = delete WMM-AC traffic stream" },
3255 { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL,
3257 "= show status for Wireless Multi-Media Admission-Control" },
3258 { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL,
3260 "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] "
3261 "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching "
3263 { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL,
3265 "<addr> = disable channel switching with TDLS peer <addr>" },
3266 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
3268 "= get signal parameters" },
3269 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
3271 "= get TX/RX packet counters" },
3272 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
3274 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3275 #ifdef CONFIG_AUTOSCAN
3276 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
3277 "[params] = Set or unset (if none) autoscan parameters" },
3278 #endif /* CONFIG_AUTOSCAN */
3280 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
3281 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
3282 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
3283 "<query reason> = Send BSS Transition Management Query" },
3284 #endif /* CONFIG_WNM */
3285 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
3286 "<params..> = Sent unprocessed command" },
3287 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
3288 "= flush wpa_supplicant state" },
3290 { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
3291 "<command> = driver private commands" },
3292 #endif /* ANDROID */
3293 { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
3294 "= radio_work <show/add/done>" },
3295 { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
3296 "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
3298 { "neighbor_rep_request",
3299 wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
3300 "[ssid=<SSID>] = Trigger request to AP for neighboring AP report "
3301 "(with optional given SSID, default: current SSID)"
3303 { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
3304 "= flush ERP keys" },
3306 wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none,
3307 "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
3308 "mask=mac-address-mask] = scan MAC randomization"
3310 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
3315 * Prints command usage, lines are padded with the specified string.
3317 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3322 printf("%s%s ", pad, cmd->cmd);
3323 for (n = 0; (c = cmd->usage[n]); n++) {
3332 static void print_help(const char *cmd)
3335 printf("commands:\n");
3336 for (n = 0; wpa_cli_commands[n].cmd; n++) {
3337 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
3338 print_cmd_help(&wpa_cli_commands[n], " ");
3343 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3345 const char *c, *delim;
3349 delim = os_strchr(cmd, ' ');
3353 len = os_strlen(cmd);
3355 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3356 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3357 return (wpa_cli_commands[n].flags &
3358 cli_cmd_flag_sensitive);
3364 static char ** wpa_list_cmd_list(void)
3368 struct cli_txt_entry *e;
3370 count = ARRAY_SIZE(wpa_cli_commands);
3371 count += dl_list_len(&p2p_groups);
3372 count += dl_list_len(&ifnames);
3373 res = os_calloc(count + 1, sizeof(char *));
3377 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3378 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3383 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
3384 size_t len = 8 + os_strlen(e->txt);
3385 res[i] = os_malloc(len);
3388 os_snprintf(res[i], len, "ifname=%s", e->txt);
3392 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
3393 res[i] = os_strdup(e->txt);
3403 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3408 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3409 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3410 if (wpa_cli_commands[i].completion)
3411 return wpa_cli_commands[i].completion(str,
3414 printf("\r%s\n", wpa_cli_commands[i].usage);
3424 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3430 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
3431 end = os_strchr(str, ' ');
3432 if (end && pos > end - str) {
3433 pos -= end - str + 1;
3438 end = os_strchr(str, ' ');
3439 if (end == NULL || str + pos < end)
3440 return wpa_list_cmd_list();
3442 cmd = os_malloc(pos + 1);
3445 os_memcpy(cmd, str, pos);
3446 cmd[end - str] = '\0';
3447 res = wpa_cli_cmd_completion(cmd, str, pos);
3453 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3455 struct wpa_cli_cmd *cmd, *match = NULL;
3459 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
3460 ifname_prefix = argv[0] + 7;
3464 ifname_prefix = NULL;
3470 cmd = wpa_cli_commands;
3472 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3475 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3476 /* we have an exact match */
3486 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3487 cmd = wpa_cli_commands;
3489 if (os_strncasecmp(cmd->cmd, argv[0],
3490 os_strlen(argv[0])) == 0) {
3491 printf(" %s", cmd->cmd);
3497 } else if (count == 0) {
3498 printf("Unknown command '%s'\n", argv[0]);
3501 ret = match->handler(ctrl, argc - 1, &argv[1]);
3508 static int str_match(const char *a, const char *b)
3510 return os_strncmp(a, b, os_strlen(b)) == 0;
3514 static int wpa_cli_exec(const char *program, const char *arg1,
3521 len = os_strlen(arg1) + os_strlen(arg2) + 2;
3522 arg = os_malloc(len);
3525 os_snprintf(arg, len, "%s %s", arg1, arg2);
3526 res = os_exec(program, arg, 1);
3533 static void wpa_cli_action_process(const char *msg)
3536 char *copy = NULL, *id, *pos2;
3537 const char *ifname = ctrl_ifname;
3538 char ifname_buf[100];
3541 if (os_strncmp(pos, "IFNAME=", 7) == 0) {
3543 end = os_strchr(pos + 7, ' ');
3544 if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) {
3546 os_memcpy(ifname_buf, pos, end - pos);
3547 ifname_buf[end - pos] = '\0';
3548 ifname = ifname_buf;
3553 const char *prev = pos;
3555 pos = os_strchr(pos, '>');
3562 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3564 os_unsetenv("WPA_ID");
3565 os_unsetenv("WPA_ID_STR");
3566 os_unsetenv("WPA_CTRL_DIR");
3568 pos = os_strstr(pos, "[id=");
3570 copy = os_strdup(pos + 4);
3574 while (*pos2 && *pos2 != ' ')
3578 os_setenv("WPA_ID", id, 1);
3579 while (*pos2 && *pos2 != '=')
3584 while (*pos2 && *pos2 != ']')
3587 os_setenv("WPA_ID_STR", id, 1);
3591 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3593 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
3594 wpa_cli_connected = 1;
3595 wpa_cli_last_id = new_id;
3596 wpa_cli_exec(action_file, ifname, "CONNECTED");
3598 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3599 if (wpa_cli_connected) {
3600 wpa_cli_connected = 0;
3601 wpa_cli_exec(action_file, ifname, "DISCONNECTED");
3603 } else if (str_match(pos, MESH_GROUP_STARTED)) {
3604 wpa_cli_exec(action_file, ctrl_ifname, pos);
3605 } else if (str_match(pos, MESH_GROUP_REMOVED)) {
3606 wpa_cli_exec(action_file, ctrl_ifname, pos);
3607 } else if (str_match(pos, MESH_PEER_CONNECTED)) {
3608 wpa_cli_exec(action_file, ctrl_ifname, pos);
3609 } else if (str_match(pos, MESH_PEER_DISCONNECTED)) {
3610 wpa_cli_exec(action_file, ctrl_ifname, pos);
3611 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3612 wpa_cli_exec(action_file, ifname, pos);
3613 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3614 wpa_cli_exec(action_file, ifname, pos);
3615 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3616 wpa_cli_exec(action_file, ifname, pos);
3617 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3618 wpa_cli_exec(action_file, ifname, pos);
3619 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3620 wpa_cli_exec(action_file, ifname, pos);
3621 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3622 wpa_cli_exec(action_file, ifname, pos);
3623 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3624 wpa_cli_exec(action_file, ifname, pos);
3625 } else if (str_match(pos, AP_STA_CONNECTED)) {
3626 wpa_cli_exec(action_file, ifname, pos);
3627 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3628 wpa_cli_exec(action_file, ifname, pos);
3629 } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
3630 wpa_cli_exec(action_file, ifname, pos);
3631 } else if (str_match(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
3632 wpa_cli_exec(action_file, ifname, pos);
3633 } else if (str_match(pos, HS20_DEAUTH_IMMINENT_NOTICE)) {
3634 wpa_cli_exec(action_file, ifname, pos);
3635 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3636 printf("wpa_supplicant is terminating - stop monitoring\n");
3642 #ifndef CONFIG_ANSI_C_EXTRA
3643 static void wpa_cli_action_cb(char *msg, size_t len)
3645 wpa_cli_action_process(msg);
3647 #endif /* CONFIG_ANSI_C_EXTRA */
3650 static void wpa_cli_reconnect(void)
3652 wpa_cli_close_connection();
3653 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3658 printf("\rConnection to wpa_supplicant re-established\n");
3664 static void cli_event(const char *str)
3666 const char *start, *s;
3668 start = os_strchr(str, '>');
3674 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3675 s = os_strchr(start, ' ');
3678 s = os_strchr(s + 1, ' ');
3681 cli_txt_list_add(&bsses, s + 1);
3685 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3686 s = os_strchr(start, ' ');
3689 s = os_strchr(s + 1, ' ');
3692 cli_txt_list_del_addr(&bsses, s + 1);
3697 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3698 s = os_strstr(start, " p2p_dev_addr=");
3701 cli_txt_list_add_addr(&p2p_peers, s + 14);
3705 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3706 s = os_strstr(start, " p2p_dev_addr=");
3709 cli_txt_list_del_addr(&p2p_peers, s + 14);
3713 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3714 s = os_strchr(start, ' ');
3717 cli_txt_list_add_word(&p2p_groups, s + 1);
3721 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3722 s = os_strchr(start, ' ');
3725 cli_txt_list_del_word(&p2p_groups, s + 1);
3728 #endif /* CONFIG_P2P */
3732 static int check_terminating(const char *msg)
3734 const char *pos = msg;
3738 pos = os_strchr(pos, '>');
3745 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3747 printf("\rConnection to wpa_supplicant lost - trying to "
3750 wpa_cli_attached = 0;
3751 wpa_cli_close_connection();
3759 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3761 if (ctrl_conn == NULL) {
3762 wpa_cli_reconnect();
3765 while (wpa_ctrl_pending(ctrl) > 0) {
3767 size_t len = sizeof(buf) - 1;
3768 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3771 wpa_cli_action_process(buf);
3774 if (wpa_cli_show_event(buf)) {
3776 printf("\r%s\n", buf);
3780 if (interactive && check_terminating(buf) > 0)
3784 printf("Could not read pending message.\n");
3789 if (wpa_ctrl_pending(ctrl) < 0) {
3790 printf("Connection to wpa_supplicant lost - trying to "
3792 wpa_cli_reconnect();
3798 static int tokenize_cmd(char *cmd, char *argv[])
3811 if (argc == max_args)
3814 char *pos2 = os_strrchr(pos, '"');
3818 while (*pos != '\0' && *pos != ' ')
3828 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3832 char *prefix = ifname_prefix;
3834 ifname_prefix = NULL;
3835 res = _wpa_ctrl_command(ctrl_conn, "PING", 0);
3836 ifname_prefix = prefix;
3838 printf("Connection to wpa_supplicant lost - trying to "
3840 wpa_cli_close_connection();
3844 wpa_cli_reconnect();
3845 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3849 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3851 wpa_cli_recv_pending(mon_conn, 0);
3855 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3857 char *argv[max_args];
3859 argc = tokenize_cmd(cmd, argv);
3861 wpa_request(ctrl_conn, argc, argv);
3865 static void wpa_cli_edit_eof_cb(void *ctx)
3871 static int warning_displayed = 0;
3872 static char *hfile = NULL;
3873 static int edit_started = 0;
3875 static void start_edit(void)
3880 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3881 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3882 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3884 #ifdef CONFIG_WPA_CLI_HISTORY_DIR
3885 home = CONFIG_WPA_CLI_HISTORY_DIR;
3886 #else /* CONFIG_WPA_CLI_HISTORY_DIR */
3887 home = getenv("HOME");
3888 #endif /* CONFIG_WPA_CLI_HISTORY_DIR */
3890 const char *fname = ".wpa_cli_history";
3891 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3892 hfile = os_malloc(hfile_len);
3894 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3897 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3898 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3904 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3908 static void update_bssid_list(struct wpa_ctrl *ctrl)
3911 size_t len = sizeof(buf);
3913 char *cmd = "BSS RANGE=ALL MASK=0x2";
3918 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3925 pos = os_strstr(pos, "bssid=");
3929 end = os_strchr(pos, '\n');
3933 cli_txt_list_add(&bsses, pos);
3939 static void update_ifnames(struct wpa_ctrl *ctrl)
3942 size_t len = sizeof(buf);
3944 char *cmd = "INTERFACES";
3948 cli_txt_list_flush(&ifnames);
3952 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3959 end = os_strchr(pos, '\n');
3963 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
3964 if (!os_snprintf_error(sizeof(txt), ret))
3965 cli_txt_list_add(&ifnames, txt);
3971 static void update_networks(struct wpa_ctrl *ctrl)
3974 size_t len = sizeof(buf);
3976 char *cmd = "LIST_NETWORKS";
3980 cli_txt_list_flush(&networks);
3984 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3991 end = os_strchr(pos, '\n');
3996 cli_txt_list_add_word(&networks, pos);
4003 static void try_connection(void *eloop_ctx, void *timeout_ctx)
4008 if (ctrl_ifname == NULL)
4009 ctrl_ifname = wpa_cli_get_default_ifname();
4011 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
4012 if (!warning_displayed) {
4013 printf("Could not connect to wpa_supplicant: "
4015 ctrl_ifname ? ctrl_ifname : "(nil)");
4016 warning_displayed = 1;
4018 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
4022 update_bssid_list(ctrl_conn);
4023 update_networks(ctrl_conn);
4025 if (warning_displayed)
4026 printf("Connection established.\n");
4033 static void wpa_cli_interactive(void)
4035 printf("\nInteractive mode\n\n");
4037 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
4039 eloop_cancel_timeout(try_connection, NULL, NULL);
4041 cli_txt_list_flush(&p2p_peers);
4042 cli_txt_list_flush(&p2p_groups);
4043 cli_txt_list_flush(&bsses);
4044 cli_txt_list_flush(&ifnames);
4045 cli_txt_list_flush(&networks);
4047 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
4049 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
4050 wpa_cli_close_connection();
4054 static void wpa_cli_action(struct wpa_ctrl *ctrl)
4056 #ifdef CONFIG_ANSI_C_EXTRA
4057 /* TODO: ANSI C version(?) */
4058 printf("Action processing not supported in ANSI C build.\n");
4059 #else /* CONFIG_ANSI_C_EXTRA */
4063 char buf[256]; /* note: large enough to fit in unsolicited messages */
4066 fd = wpa_ctrl_get_fd(ctrl);
4068 while (!wpa_cli_quit) {
4071 tv.tv_sec = ping_interval;
4073 res = select(fd + 1, &rfds, NULL, NULL, &tv);
4074 if (res < 0 && errno != EINTR) {
4079 if (FD_ISSET(fd, &rfds))
4080 wpa_cli_recv_pending(ctrl, 1);
4082 /* verify that connection is still working */
4083 len = sizeof(buf) - 1;
4084 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
4085 wpa_cli_action_cb) < 0 ||
4086 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
4087 printf("wpa_supplicant did not reply to PING "
4088 "command - exiting\n");
4093 #endif /* CONFIG_ANSI_C_EXTRA */
4097 static void wpa_cli_cleanup(void)
4099 wpa_cli_close_connection();
4101 os_daemonize_terminate(pid_file);
4103 os_program_deinit();
4107 static void wpa_cli_terminate(int sig, void *ctx)
4113 static char * wpa_cli_get_default_ifname(void)
4115 char *ifname = NULL;
4117 #ifdef CONFIG_CTRL_IFACE_UNIX
4118 struct dirent *dent;
4119 DIR *dir = opendir(ctrl_iface_dir);
4122 char ifprop[PROPERTY_VALUE_MAX];
4123 if (property_get("wifi.interface", ifprop, NULL) != 0) {
4124 ifname = os_strdup(ifprop);
4125 printf("Using interface '%s'\n", ifname);
4128 #endif /* ANDROID */
4131 while ((dent = readdir(dir))) {
4132 #ifdef _DIRENT_HAVE_D_TYPE
4134 * Skip the file if it is not a socket. Also accept
4135 * DT_UNKNOWN (0) in case the C library or underlying
4136 * file system does not support d_type.
4138 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
4140 #endif /* _DIRENT_HAVE_D_TYPE */
4141 if (os_strcmp(dent->d_name, ".") == 0 ||
4142 os_strcmp(dent->d_name, "..") == 0)
4144 printf("Selected interface '%s'\n", dent->d_name);
4145 ifname = os_strdup(dent->d_name);
4149 #endif /* CONFIG_CTRL_IFACE_UNIX */
4151 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4152 char buf[4096], *pos;
4154 struct wpa_ctrl *ctrl;
4157 ctrl = wpa_ctrl_open(NULL);
4161 len = sizeof(buf) - 1;
4162 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
4165 pos = os_strchr(buf, '\n');
4168 ifname = os_strdup(buf);
4170 wpa_ctrl_close(ctrl);
4171 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4177 int main(int argc, char *argv[])
4182 const char *global = NULL;
4184 if (os_program_init())
4188 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
4193 action_file = optarg;
4202 ping_interval = atoi(optarg);
4208 printf("%s\n", wpa_cli_version);
4211 os_free(ctrl_ifname);
4212 ctrl_ifname = os_strdup(optarg);
4215 ctrl_iface_dir = optarg;
4226 interactive = (argc == optind) && (action_file == NULL);
4229 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
4235 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4236 ctrl_conn = wpa_ctrl_open(NULL);
4237 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4238 ctrl_conn = wpa_ctrl_open(global);
4239 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4240 if (ctrl_conn == NULL) {
4241 fprintf(stderr, "Failed to connect to wpa_supplicant "
4242 "global interface: %s error: %s\n",
4243 global, strerror(errno));
4248 update_ifnames(ctrl_conn);
4249 mon_conn = wpa_ctrl_open(global);
4251 if (wpa_ctrl_attach(mon_conn) == 0) {
4252 wpa_cli_attached = 1;
4253 eloop_register_read_sock(
4254 wpa_ctrl_get_fd(mon_conn),
4255 wpa_cli_mon_receive,
4258 printf("Failed to open monitor "
4259 "connection through global "
4260 "control interface\n");
4266 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
4268 if (ctrl_ifname == NULL)
4269 ctrl_ifname = wpa_cli_get_default_ifname();
4272 wpa_cli_interactive();
4275 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
4276 fprintf(stderr, "Failed to connect to non-global "
4277 "ctrl_ifname: %s error: %s\n",
4278 ctrl_ifname ? ctrl_ifname : "(nil)",
4284 if (wpa_ctrl_attach(ctrl_conn) == 0) {
4285 wpa_cli_attached = 1;
4287 printf("Warning: Failed to attach to "
4288 "wpa_supplicant.\n");
4293 if (daemonize && os_daemonize(pid_file))
4297 wpa_cli_action(ctrl_conn);
4299 ret = wpa_request(ctrl_conn, argc - optind,
4303 os_free(ctrl_ifname);
4310 #else /* CONFIG_CTRL_IFACE */
4311 int main(int argc, char *argv[])
4313 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
4316 #endif /* CONFIG_CTRL_IFACE */