2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
11 #ifdef CONFIG_CTRL_IFACE
13 #ifdef CONFIG_CTRL_IFACE_UNIX
15 #endif /* CONFIG_CTRL_IFACE_UNIX */
17 #include "common/wpa_ctrl.h"
18 #include "utils/common.h"
19 #include "utils/eloop.h"
20 #include "utils/edit.h"
21 #include "utils/list.h"
22 #include "common/version.h"
23 #include "common/ieee802_11_defs.h"
25 #include <cutils/properties.h>
29 static const char *wpa_cli_version =
30 "wpa_cli v" VERSION_STR "\n"
31 "Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi> and contributors";
34 static const char *wpa_cli_license =
35 "This software may be distributed under the terms of the BSD license.\n"
36 "See README for more details.\n";
38 static const char *wpa_cli_full_license =
39 "This software may be distributed under the terms of the BSD license.\n"
41 "Redistribution and use in source and binary forms, with or without\n"
42 "modification, are permitted provided that the following conditions are\n"
45 "1. Redistributions of source code must retain the above copyright\n"
46 " notice, this list of conditions and the following disclaimer.\n"
48 "2. Redistributions in binary form must reproduce the above copyright\n"
49 " notice, this list of conditions and the following disclaimer in the\n"
50 " documentation and/or other materials provided with the distribution.\n"
52 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
53 " names of its contributors may be used to endorse or promote products\n"
54 " derived from this software without specific prior written permission.\n"
56 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
57 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
58 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
59 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
60 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
61 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
62 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
63 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
64 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
65 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
66 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
69 static struct wpa_ctrl *ctrl_conn;
70 static struct wpa_ctrl *mon_conn;
71 static int wpa_cli_quit = 0;
72 static int wpa_cli_attached = 0;
73 static int wpa_cli_connected = -1;
74 static int wpa_cli_last_id = 0;
75 #ifndef CONFIG_CTRL_IFACE_DIR
76 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
77 #endif /* CONFIG_CTRL_IFACE_DIR */
78 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
79 static char *ctrl_ifname = NULL;
80 static const char *pid_file = NULL;
81 static const char *action_file = NULL;
82 static int ping_interval = 5;
83 static int interactive = 0;
84 static char *ifname_prefix = NULL;
86 struct cli_txt_entry {
91 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
92 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
93 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
94 static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */
97 static void print_help(const char *cmd);
98 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
99 static void wpa_cli_close_connection(void);
100 static char * wpa_cli_get_default_ifname(void);
101 static char ** wpa_list_cmd_list(void);
104 static void usage(void)
106 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
107 "[-a<action file>] \\\n"
108 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
110 " -h = help (show this usage text)\n"
111 " -v = shown version information\n"
112 " -a = run in daemon mode executing the action file based on "
115 " -B = run a daemon in the background\n"
116 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
117 " default interface: first interface found in socket path\n");
122 static void cli_txt_list_free(struct cli_txt_entry *e)
124 dl_list_del(&e->list);
130 static void cli_txt_list_flush(struct dl_list *list)
132 struct cli_txt_entry *e;
133 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
134 cli_txt_list_free(e);
138 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
141 struct cli_txt_entry *e;
142 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
143 if (os_strcmp(e->txt, txt) == 0)
150 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
152 struct cli_txt_entry *e;
153 e = cli_txt_list_get(txt_list, txt);
155 cli_txt_list_free(e);
159 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
163 if (hwaddr_aton(txt, addr) < 0)
165 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
166 cli_txt_list_del(txt_list, buf);
171 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
175 end = os_strchr(txt, ' ');
177 end = txt + os_strlen(txt);
178 buf = dup_binstr(txt, end - txt);
181 cli_txt_list_del(txt_list, buf);
184 #endif /* CONFIG_P2P */
187 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
189 struct cli_txt_entry *e;
190 e = cli_txt_list_get(txt_list, txt);
193 e = os_zalloc(sizeof(*e));
196 e->txt = os_strdup(txt);
197 if (e->txt == NULL) {
201 dl_list_add(txt_list, &e->list);
207 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
211 if (hwaddr_aton(txt, addr) < 0)
213 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
214 return cli_txt_list_add(txt_list, buf);
218 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
223 end = os_strchr(txt, ' ');
225 end = txt + os_strlen(txt);
226 buf = dup_binstr(txt, end - txt);
229 ret = cli_txt_list_add(txt_list, buf);
233 #endif /* CONFIG_P2P */
236 static char ** cli_txt_list_array(struct dl_list *txt_list)
238 unsigned int i, count = dl_list_len(txt_list);
240 struct cli_txt_entry *e;
242 res = os_calloc(count + 1, sizeof(char *));
247 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
248 res[i] = os_strdup(e->txt);
258 static int get_cmd_arg_num(const char *str, int pos)
262 for (i = 0; i <= pos; i++) {
265 while (i <= pos && str[i] != ' ')
276 static int str_starts(const char *src, const char *match)
278 return os_strncmp(src, match, os_strlen(match)) == 0;
282 static int wpa_cli_show_event(const char *event)
286 start = os_strchr(event, '>');
292 * Skip BSS added/removed events since they can be relatively frequent
293 * and are likely of not much use for an interactive user.
295 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
296 str_starts(start, WPA_EVENT_BSS_REMOVED))
303 static int wpa_cli_open_connection(const char *ifname, int attach)
305 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
306 ctrl_conn = wpa_ctrl_open(ifname);
307 if (ctrl_conn == NULL)
310 if (attach && interactive)
311 mon_conn = wpa_ctrl_open(ifname);
314 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
322 if (access(ctrl_iface_dir, F_OK) < 0) {
323 cfile = os_strdup(ifname);
330 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
331 cfile = os_malloc(flen);
334 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
336 if (res < 0 || res >= flen) {
342 ctrl_conn = wpa_ctrl_open(cfile);
343 if (ctrl_conn == NULL) {
348 if (attach && interactive)
349 mon_conn = wpa_ctrl_open(cfile);
353 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
356 if (wpa_ctrl_attach(mon_conn) == 0) {
357 wpa_cli_attached = 1;
359 eloop_register_read_sock(
360 wpa_ctrl_get_fd(mon_conn),
361 wpa_cli_mon_receive, NULL, NULL);
363 printf("Warning: Failed to attach to "
364 "wpa_supplicant.\n");
365 wpa_cli_close_connection();
374 static void wpa_cli_close_connection(void)
376 if (ctrl_conn == NULL)
379 if (wpa_cli_attached) {
380 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
381 wpa_cli_attached = 0;
383 wpa_ctrl_close(ctrl_conn);
386 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
387 wpa_ctrl_close(mon_conn);
393 static void wpa_cli_msg_cb(char *msg, size_t len)
399 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
405 if (ctrl_conn == NULL) {
406 printf("Not connected to wpa_supplicant - command dropped.\n");
410 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
412 buf[sizeof(buf) - 1] = '\0';
415 len = sizeof(buf) - 1;
416 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
419 printf("'%s' command timed out.\n", cmd);
421 } else if (ret < 0) {
422 printf("'%s' command failed.\n", cmd);
428 if (interactive && len > 0 && buf[len - 1] != '\n')
435 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
437 return _wpa_ctrl_command(ctrl, cmd, 1);
441 static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
450 res = os_snprintf(pos, end - pos, "%s", cmd);
451 if (res < 0 || res >= end - pos)
455 for (i = 0; i < argc; i++) {
456 res = os_snprintf(pos, end - pos, " %s", argv[i]);
457 if (res < 0 || res >= end - pos)
462 buf[buflen - 1] = '\0';
466 printf("Too long command\n");
471 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
472 int argc, char *argv[])
475 if (argc < min_args) {
476 printf("Invalid %s command - at least %d argument%s "
477 "required.\n", cmd, min_args,
478 min_args > 1 ? "s are" : " is");
481 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
483 return wpa_ctrl_command(ctrl, buf);
487 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
489 return wpa_ctrl_command(ctrl, "IFNAME");
493 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
495 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
496 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
497 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
498 return wpa_ctrl_command(ctrl, "STATUS-WPS");
499 if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
500 return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
501 return wpa_ctrl_command(ctrl, "STATUS");
505 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
507 return wpa_ctrl_command(ctrl, "PING");
511 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
513 return wpa_ctrl_command(ctrl, "RELOG");
517 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
519 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
523 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
525 return wpa_ctrl_command(ctrl, "MIB");
529 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
531 return wpa_ctrl_command(ctrl, "PMKSA");
535 static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc,
538 return wpa_ctrl_command(ctrl, "PMKSA_FLUSH");
542 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
544 print_help(argc > 0 ? argv[0] : NULL);
549 static char ** wpa_cli_complete_help(const char *str, int pos)
551 int arg = get_cmd_arg_num(str, pos);
556 res = wpa_list_cmd_list();
564 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
566 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
571 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
580 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
586 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
587 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
588 printf("Too long SET command.\n");
591 return wpa_ctrl_command(ctrl, cmd);
594 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
598 static char ** wpa_cli_complete_set(const char *str, int pos)
600 int arg = get_cmd_arg_num(str, pos);
601 const char *fields[] = {
603 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
604 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
605 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
606 "wps_fragment_size", "wps_version_number", "ampdu",
607 "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
608 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
610 /* global configuration parameters */
611 "eapol_version", "ap_scan", "disable_scan_offload",
612 "fast_reauth", "opensc_engine_path", "pkcs11_engine_path",
613 "pkcs11_module_path", "pcsc_reader", "pcsc_pin",
614 "driver_param", "dot11RSNAConfigPMKLifetime",
615 "dot11RSNAConfigPMKReauthThreshold",
616 "dot11RSNAConfigSATimeout",
617 "update_config", "load_dynamic_eap", "uuid", "device_name",
618 "manufacturer", "model_name", "model_number", "serial_number",
619 "device_type", "os_version", "config_methods",
620 "wps_cred_processing", "wps_vendor_ext_m1", "sec_device_type",
621 "p2p_listen_reg_class", "p2p_listen_channel",
622 "p2p_oper_reg_class", "p2p_oper_channel",
623 "p2p_go_intent", "p2p_ssid_postfix", "persistent_reconnect",
624 "p2p_intra_bss", "p2p_group_idle", "p2p_pref_chan",
626 "p2p_go_ht40", "p2p_disabled", "p2p_no_group_iface",
628 "p2p_ignore_shared_freq", "country", "bss_max_count",
629 "bss_expiration_age", "bss_expiration_scan_count",
630 "filter_ssids", "filter_rssi", "max_num_sta",
631 "disassoc_low_ack", "hs20", "interworking", "hessid",
632 "access_network_type", "pbc_in_m1", "autoscan",
633 "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", "wps_nfc_dh_privkey",
634 "wps_nfc_dev_pw", "ext_password_backend",
635 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
636 "sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
637 "ignore_old_scan_res", "freq_list", "external_sim",
638 "tdls_external_control", "p2p_search_delay"
640 int i, num_fields = ARRAY_SIZE(fields);
643 char **res = os_calloc(num_fields + 1, sizeof(char *));
646 for (i = 0; i < num_fields; i++) {
647 res[i] = os_strdup(fields[i]);
654 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
655 return cli_txt_list_array(&bsses);
661 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
663 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
667 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
669 return wpa_ctrl_command(ctrl, "LOGOFF");
673 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
675 return wpa_ctrl_command(ctrl, "LOGON");
679 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
682 return wpa_ctrl_command(ctrl, "REASSOCIATE");
686 static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[])
688 return wpa_ctrl_command(ctrl, "REATTACH");
692 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
695 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
699 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
701 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
705 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
708 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
712 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
715 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
719 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
722 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
726 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
732 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
734 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
735 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
736 printf("Too long BSS_FLUSH command.\n");
739 return wpa_ctrl_command(ctrl, cmd);
743 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
746 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
750 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
752 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
756 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
758 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
762 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
765 printf("Invalid WPS_PIN command: need one or two arguments:\n"
766 "- BSSID: use 'any' to select any\n"
767 "- PIN: optional, used only with devices that have no "
772 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
776 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
779 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
783 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
786 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
790 #ifdef CONFIG_WPS_NFC
792 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
794 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
798 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
801 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
805 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
808 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
812 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
820 printf("Invalid 'wps_nfc_tag_read' command - one argument "
825 buflen = 18 + os_strlen(argv[0]);
826 buf = os_malloc(buflen);
829 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
831 ret = wpa_ctrl_command(ctrl, buf);
838 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
841 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
845 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
848 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
852 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
855 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
858 #endif /* CONFIG_WPS_NFC */
861 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
867 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
869 else if (argc == 5 || argc == 6) {
870 char ssid_hex[2 * 32 + 1];
871 char key_hex[2 * 64 + 1];
875 for (i = 0; i < 32; i++) {
876 if (argv[2][i] == '\0')
878 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
883 for (i = 0; i < 64; i++) {
884 if (argv[5][i] == '\0')
886 os_snprintf(&key_hex[i * 2], 3, "%02x",
891 res = os_snprintf(cmd, sizeof(cmd),
892 "WPS_REG %s %s %s %s %s %s",
893 argv[0], argv[1], ssid_hex, argv[3], argv[4],
896 printf("Invalid WPS_REG command: need two arguments:\n"
897 "- BSSID of the target AP\n"
899 printf("Alternatively, six arguments can be used to "
900 "reconfigure the AP:\n"
901 "- BSSID of the target AP\n"
904 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
905 "- new encr (NONE, WEP, TKIP, CCMP)\n"
910 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
911 printf("Too long WPS_REG command.\n");
914 return wpa_ctrl_command(ctrl, cmd);
918 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
921 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
925 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
928 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
932 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
935 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
940 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
944 printf("Invalid WPS_ER_PIN command: need at least two "
946 "- UUID: use 'any' to select any\n"
947 "- PIN: Enrollee PIN\n"
948 "optional: - Enrollee MAC address\n");
952 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
956 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
959 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
963 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
967 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
968 "- UUID: specify which AP to use\n"
973 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
977 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
981 printf("Invalid WPS_ER_SET_CONFIG command: need two "
983 "- UUID: specify which AP to use\n"
984 "- Network configuration id\n");
988 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
992 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
998 if (argc == 5 || argc == 6) {
999 char ssid_hex[2 * 32 + 1];
1000 char key_hex[2 * 64 + 1];
1004 for (i = 0; i < 32; i++) {
1005 if (argv[2][i] == '\0')
1007 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1012 for (i = 0; i < 64; i++) {
1013 if (argv[5][i] == '\0')
1015 os_snprintf(&key_hex[i * 2], 3, "%02x",
1020 res = os_snprintf(cmd, sizeof(cmd),
1021 "WPS_ER_CONFIG %s %s %s %s %s %s",
1022 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1025 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1029 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1030 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1035 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1036 printf("Too long WPS_ER_CONFIG command.\n");
1039 return wpa_ctrl_command(ctrl, cmd);
1043 #ifdef CONFIG_WPS_NFC
1044 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1048 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1050 "- WPS/NDEF: token format\n"
1051 "- UUID: specify which AP to use\n");
1055 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1057 #endif /* CONFIG_WPS_NFC */
1060 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1062 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1066 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1068 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1072 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1074 char cmd[256], *pos, *end;
1078 printf("Invalid IDENTITY command: needs two arguments "
1079 "(network id and identity)\n");
1083 end = cmd + sizeof(cmd);
1085 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1087 if (ret < 0 || ret >= end - pos) {
1088 printf("Too long IDENTITY command.\n");
1092 for (i = 2; i < argc; i++) {
1093 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1094 if (ret < 0 || ret >= end - pos) {
1095 printf("Too long IDENTITY command.\n");
1101 return wpa_ctrl_command(ctrl, cmd);
1105 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1107 char cmd[256], *pos, *end;
1111 printf("Invalid PASSWORD command: needs two arguments "
1112 "(network id and password)\n");
1116 end = cmd + sizeof(cmd);
1118 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1120 if (ret < 0 || ret >= end - pos) {
1121 printf("Too long PASSWORD command.\n");
1125 for (i = 2; i < argc; i++) {
1126 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1127 if (ret < 0 || ret >= end - pos) {
1128 printf("Too long PASSWORD command.\n");
1134 return wpa_ctrl_command(ctrl, cmd);
1138 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1141 char cmd[256], *pos, *end;
1145 printf("Invalid NEW_PASSWORD command: needs two arguments "
1146 "(network id and password)\n");
1150 end = cmd + sizeof(cmd);
1152 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1154 if (ret < 0 || ret >= end - pos) {
1155 printf("Too long NEW_PASSWORD command.\n");
1159 for (i = 2; i < argc; i++) {
1160 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1161 if (ret < 0 || ret >= end - pos) {
1162 printf("Too long NEW_PASSWORD command.\n");
1168 return wpa_ctrl_command(ctrl, cmd);
1172 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1174 char cmd[256], *pos, *end;
1178 printf("Invalid PIN command: needs two arguments "
1179 "(network id and pin)\n");
1183 end = cmd + sizeof(cmd);
1185 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1187 if (ret < 0 || ret >= end - pos) {
1188 printf("Too long PIN command.\n");
1192 for (i = 2; i < argc; i++) {
1193 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1194 if (ret < 0 || ret >= end - pos) {
1195 printf("Too long PIN command.\n");
1200 return wpa_ctrl_command(ctrl, cmd);
1204 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1206 char cmd[256], *pos, *end;
1210 printf("Invalid OTP command: needs two arguments (network "
1211 "id and password)\n");
1215 end = cmd + sizeof(cmd);
1217 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1219 if (ret < 0 || ret >= end - pos) {
1220 printf("Too long OTP command.\n");
1224 for (i = 2; i < argc; i++) {
1225 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1226 if (ret < 0 || ret >= end - pos) {
1227 printf("Too long OTP command.\n");
1233 return wpa_ctrl_command(ctrl, cmd);
1237 static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
1239 char cmd[256], *pos, *end;
1243 printf("Invalid SIM command: needs two arguments "
1244 "(network id and SIM operation response)\n");
1248 end = cmd + sizeof(cmd);
1250 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
1252 if (ret < 0 || ret >= end - pos) {
1253 printf("Too long SIM command.\n");
1257 for (i = 2; i < argc; i++) {
1258 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1259 if (ret < 0 || ret >= end - pos) {
1260 printf("Too long SIM command.\n");
1265 return wpa_ctrl_command(ctrl, cmd);
1269 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1272 char cmd[256], *pos, *end;
1276 printf("Invalid PASSPHRASE command: needs two arguments "
1277 "(network id and passphrase)\n");
1281 end = cmd + sizeof(cmd);
1283 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1285 if (ret < 0 || ret >= end - pos) {
1286 printf("Too long PASSPHRASE command.\n");
1290 for (i = 2; i < argc; i++) {
1291 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1292 if (ret < 0 || ret >= end - pos) {
1293 printf("Too long PASSPHRASE command.\n");
1299 return wpa_ctrl_command(ctrl, cmd);
1303 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1306 printf("Invalid BSSID command: needs two arguments (network "
1311 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1315 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1317 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1321 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1323 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1327 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1330 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1334 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1337 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1341 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1344 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1348 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1351 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1355 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1358 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1362 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1365 return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1369 static void wpa_cli_show_network_variables(void)
1371 printf("set_network variables:\n"
1372 " ssid (network name, SSID)\n"
1373 " psk (WPA passphrase or pre-shared key)\n"
1374 " key_mgmt (key management protocol)\n"
1375 " identity (EAP identity)\n"
1376 " password (EAP password)\n"
1379 "Note: Values are entered in the same format as the "
1380 "configuration file is using,\n"
1381 "i.e., strings values need to be inside double quotation "
1383 "For example: set_network 1 ssid \"network name\"\n"
1385 "Please see wpa_supplicant.conf documentation for full list "
1386 "of\navailable variables.\n");
1390 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1394 wpa_cli_show_network_variables();
1399 printf("Invalid SET_NETWORK command: needs three arguments\n"
1400 "(network id, variable name, and value)\n");
1404 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1408 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1412 wpa_cli_show_network_variables();
1417 printf("Invalid GET_NETWORK command: needs two arguments\n"
1418 "(network id and variable name)\n");
1422 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1426 static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc,
1430 wpa_cli_show_network_variables();
1435 printf("Invalid DUP_NETWORK command: needs three arguments\n"
1436 "(src netid, dest netid, and variable name)\n");
1440 return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv);
1444 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1447 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1451 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1453 return wpa_ctrl_command(ctrl, "ADD_CRED");
1457 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1460 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1464 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1467 printf("Invalid SET_CRED command: needs three arguments\n"
1468 "(cred id, variable name, and value)\n");
1472 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1476 static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1479 printf("Invalid GET_CRED command: needs two arguments\n"
1480 "(cred id, variable name)\n");
1484 return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv);
1488 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1491 return wpa_ctrl_command(ctrl, "DISCONNECT");
1495 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1498 return wpa_ctrl_command(ctrl, "RECONNECT");
1502 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1505 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1509 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1511 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1515 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1518 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1522 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1524 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1528 static char ** wpa_cli_complete_bss(const char *str, int pos)
1530 int arg = get_cmd_arg_num(str, pos);
1535 res = cli_txt_list_array(&bsses);
1543 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1546 if (argc < 1 || argc > 2) {
1547 printf("Invalid GET_CAPABILITY command: need either one or "
1552 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1553 printf("Invalid GET_CAPABILITY command: second argument, "
1554 "if any, must be 'strict'\n");
1558 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1562 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1564 printf("Available interfaces:\n");
1565 return wpa_ctrl_command(ctrl, "INTERFACES");
1569 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1572 wpa_cli_list_interfaces(ctrl);
1576 wpa_cli_close_connection();
1577 os_free(ctrl_ifname);
1578 ctrl_ifname = os_strdup(argv[0]);
1580 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
1581 printf("Connected to interface '%s.\n", ctrl_ifname);
1583 printf("Could not connect to interface '%s' - re-trying\n",
1590 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1593 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1597 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1600 return wpa_ctrl_command(ctrl, "TERMINATE");
1604 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1611 printf("Invalid INTERFACE_ADD command: needs at least one "
1612 "argument (interface name)\n"
1613 "All arguments: ifname confname driver ctrl_interface "
1614 "driver_param bridge_name\n");
1619 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1620 * <driver_param>TAB<bridge_name>
1622 res = os_snprintf(cmd, sizeof(cmd),
1623 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1625 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1626 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1627 argc > 5 ? argv[5] : "");
1628 if (res < 0 || (size_t) res >= sizeof(cmd))
1630 cmd[sizeof(cmd) - 1] = '\0';
1631 return wpa_ctrl_command(ctrl, cmd);
1635 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1638 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1642 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1645 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1650 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1652 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1656 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1657 char *addr, size_t addr_len)
1659 char buf[4096], *pos;
1663 if (ctrl_conn == NULL) {
1664 printf("Not connected to hostapd - command dropped.\n");
1667 len = sizeof(buf) - 1;
1668 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1671 printf("'%s' command timed out.\n", cmd);
1673 } else if (ret < 0) {
1674 printf("'%s' command failed.\n", cmd);
1679 if (os_memcmp(buf, "FAIL", 4) == 0)
1684 while (*pos != '\0' && *pos != '\n')
1687 os_strlcpy(addr, buf, addr_len);
1692 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1694 char addr[32], cmd[64];
1696 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1699 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1700 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1706 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1709 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1713 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1716 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1719 static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
1722 return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
1725 #endif /* CONFIG_AP */
1728 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1730 return wpa_ctrl_command(ctrl, "SUSPEND");
1734 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1736 return wpa_ctrl_command(ctrl, "RESUME");
1740 #ifdef CONFIG_TESTING_OPTIONS
1741 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1743 return wpa_ctrl_command(ctrl, "DROP_SA");
1745 #endif /* CONFIG_TESTING_OPTIONS */
1748 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1750 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1756 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1758 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1762 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1765 int arg = get_cmd_arg_num(str, pos);
1767 res = os_calloc(6, sizeof(char *));
1770 res[0] = os_strdup("type=social");
1771 if (res[0] == NULL) {
1775 res[1] = os_strdup("type=progressive");
1778 res[2] = os_strdup("delay=");
1781 res[3] = os_strdup("dev_id=");
1785 res[4] = os_strdup("[timeout]");
1791 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1794 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1798 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1801 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
1805 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1807 int arg = get_cmd_arg_num(str, pos);
1812 res = cli_txt_list_array(&p2p_peers);
1820 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1823 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
1827 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1830 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
1834 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
1836 int arg = get_cmd_arg_num(str, pos);
1841 res = cli_txt_list_array(&p2p_groups);
1849 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1852 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
1856 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1859 if (argc != 2 && argc != 3) {
1860 printf("Invalid P2P_PROV_DISC command: needs at least "
1861 "two arguments, address and config method\n"
1862 "(display, keypad, or pbc) and an optional join\n");
1866 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
1870 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1873 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1877 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1882 if (argc != 2 && argc != 4) {
1883 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1884 "arguments (address and TLVs) or four arguments "
1885 "(address, \"upnp\", version, search target "
1890 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
1892 return wpa_ctrl_command(ctrl, cmd);
1896 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1897 int argc, char *argv[])
1899 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
1903 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1910 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1911 "arguments (freq, address, dialog token, and TLVs)\n");
1915 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1916 argv[0], argv[1], argv[2], argv[3]);
1917 if (res < 0 || (size_t) res >= sizeof(cmd))
1919 cmd[sizeof(cmd) - 1] = '\0';
1920 return wpa_ctrl_command(ctrl, cmd);
1924 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1927 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1931 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1932 int argc, char *argv[])
1934 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
1938 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1941 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1945 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1951 if (argc != 3 && argc != 4) {
1952 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1958 res = os_snprintf(cmd, sizeof(cmd),
1959 "P2P_SERVICE_ADD %s %s %s %s",
1960 argv[0], argv[1], argv[2], argv[3]);
1962 res = os_snprintf(cmd, sizeof(cmd),
1963 "P2P_SERVICE_ADD %s %s %s",
1964 argv[0], argv[1], argv[2]);
1965 if (res < 0 || (size_t) res >= sizeof(cmd))
1967 cmd[sizeof(cmd) - 1] = '\0';
1968 return wpa_ctrl_command(ctrl, cmd);
1972 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1978 if (argc != 2 && argc != 3) {
1979 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1985 res = os_snprintf(cmd, sizeof(cmd),
1986 "P2P_SERVICE_DEL %s %s %s",
1987 argv[0], argv[1], argv[2]);
1989 res = os_snprintf(cmd, sizeof(cmd),
1990 "P2P_SERVICE_DEL %s %s",
1992 if (res < 0 || (size_t) res >= sizeof(cmd))
1994 cmd[sizeof(cmd) - 1] = '\0';
1995 return wpa_ctrl_command(ctrl, cmd);
1999 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2000 int argc, char *argv[])
2002 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
2006 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2007 int argc, char *argv[])
2009 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
2013 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2015 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2019 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2021 int arg = get_cmd_arg_num(str, pos);
2026 res = cli_txt_list_array(&p2p_peers);
2034 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2035 char *addr, size_t addr_len,
2038 char buf[4096], *pos;
2042 if (ctrl_conn == NULL)
2044 len = sizeof(buf) - 1;
2045 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2048 printf("'%s' command timed out.\n", cmd);
2050 } else if (ret < 0) {
2051 printf("'%s' command failed.\n", cmd);
2056 if (os_memcmp(buf, "FAIL", 4) == 0)
2060 while (*pos != '\0' && *pos != '\n')
2063 os_strlcpy(addr, buf, addr_len);
2064 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2065 printf("%s\n", addr);
2070 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2072 char addr[32], cmd[64];
2075 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2077 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2078 addr, sizeof(addr), discovered))
2081 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2082 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2089 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2091 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2095 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
2097 int arg = get_cmd_arg_num(str, pos);
2098 const char *fields[] = {
2118 int i, num_fields = ARRAY_SIZE(fields);
2121 char **res = os_calloc(num_fields + 1, sizeof(char *));
2124 for (i = 0; i < num_fields; i++) {
2125 res[i] = os_strdup(fields[i]);
2132 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
2133 return cli_txt_list_array(&p2p_peers);
2139 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2141 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2145 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2148 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2152 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2155 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2159 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2162 if (argc != 0 && argc != 2 && argc != 4) {
2163 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2164 "(preferred duration, interval; in microsecods).\n"
2165 "Optional second pair can be used to provide "
2166 "acceptable values.\n");
2170 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2174 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2177 if (argc != 0 && argc != 2) {
2178 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2179 "(availability period, availability interval; in "
2181 "Extended Listen Timing can be cancelled with this "
2182 "command when used without parameters.\n");
2186 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2190 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
2193 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
2196 #endif /* CONFIG_P2P */
2198 #ifdef CONFIG_WIFI_DISPLAY
2200 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2206 if (argc != 1 && argc != 2) {
2207 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2208 "arguments (subelem, hexdump)\n");
2212 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2213 argv[0], argc > 1 ? argv[1] : "");
2214 if (res < 0 || (size_t) res >= sizeof(cmd))
2216 cmd[sizeof(cmd) - 1] = '\0';
2217 return wpa_ctrl_command(ctrl, cmd);
2221 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2228 printf("Invalid WFD_SUBELEM_GET command: needs one "
2229 "argument (subelem)\n");
2233 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2235 if (res < 0 || (size_t) res >= sizeof(cmd))
2237 cmd[sizeof(cmd) - 1] = '\0';
2238 return wpa_ctrl_command(ctrl, cmd);
2240 #endif /* CONFIG_WIFI_DISPLAY */
2243 #ifdef CONFIG_INTERWORKING
2244 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2247 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2251 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2254 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2258 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2261 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2265 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2268 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2272 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2274 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2278 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2281 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2285 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2288 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2290 #endif /* CONFIG_INTERWORKING */
2295 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2298 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2302 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2308 printf("Command needs one or two arguments (dst mac addr and "
2309 "optional home realm)\n");
2313 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2317 return wpa_ctrl_command(ctrl, cmd);
2321 static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc,
2327 printf("Command needs two arguments (dst mac addr and "
2332 if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0)
2335 return wpa_ctrl_command(ctrl, cmd);
2339 static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[])
2341 return wpa_ctrl_command(ctrl, "FETCH_OSU");
2345 static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc,
2348 return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU");
2351 #endif /* CONFIG_HS20 */
2354 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2357 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2361 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2364 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2368 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2371 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2375 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2378 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2382 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2385 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2389 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2392 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2396 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2399 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2403 #ifdef CONFIG_AUTOSCAN
2405 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2408 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2410 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2413 #endif /* CONFIG_AUTOSCAN */
2418 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2420 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2424 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2426 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2429 #endif /* CONFIG_WNM */
2432 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2436 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2441 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2443 return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
2445 #endif /* ANDROID */
2448 static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
2450 return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv);
2454 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2456 return wpa_ctrl_command(ctrl, "FLUSH");
2460 static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
2462 return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
2466 enum wpa_cli_cmd_flags {
2467 cli_cmd_flag_none = 0x00,
2468 cli_cmd_flag_sensitive = 0x01
2471 struct wpa_cli_cmd {
2473 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2474 char ** (*completion)(const char *str, int pos);
2475 enum wpa_cli_cmd_flags flags;
2479 static struct wpa_cli_cmd wpa_cli_commands[] = {
2480 { "status", wpa_cli_cmd_status, NULL,
2482 "[verbose] = get current WPA/EAPOL/EAP status" },
2483 { "ifname", wpa_cli_cmd_ifname, NULL,
2485 "= get current interface name" },
2486 { "ping", wpa_cli_cmd_ping, NULL,
2488 "= pings wpa_supplicant" },
2489 { "relog", wpa_cli_cmd_relog, NULL,
2491 "= re-open log-file (allow rolling logs)" },
2492 { "note", wpa_cli_cmd_note, NULL,
2494 "<text> = add a note to wpa_supplicant debug log" },
2495 { "mib", wpa_cli_cmd_mib, NULL,
2497 "= get MIB variables (dot1x, dot11)" },
2498 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2500 "[command] = show usage help" },
2501 { "interface", wpa_cli_cmd_interface, NULL,
2503 "[ifname] = show interfaces/select interface" },
2504 { "level", wpa_cli_cmd_level, NULL,
2506 "<debug level> = change debug level" },
2507 { "license", wpa_cli_cmd_license, NULL,
2509 "= show full wpa_cli license" },
2510 { "quit", wpa_cli_cmd_quit, NULL,
2513 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2515 "= set variables (shows list of variables when run without "
2517 { "get", wpa_cli_cmd_get, NULL,
2519 "<name> = get information" },
2520 { "logon", wpa_cli_cmd_logon, NULL,
2522 "= IEEE 802.1X EAPOL state machine logon" },
2523 { "logoff", wpa_cli_cmd_logoff, NULL,
2525 "= IEEE 802.1X EAPOL state machine logoff" },
2526 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2528 "= show PMKSA cache" },
2529 { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL,
2531 "= flush PMKSA cache entries" },
2532 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2534 "= force reassociation" },
2535 { "reattach", wpa_cli_cmd_reattach, NULL,
2537 "= force reassociation back to the same BSS" },
2538 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2540 "<BSSID> = force preauthentication" },
2541 { "identity", wpa_cli_cmd_identity, NULL,
2543 "<network id> <identity> = configure identity for an SSID" },
2544 { "password", wpa_cli_cmd_password, NULL,
2545 cli_cmd_flag_sensitive,
2546 "<network id> <password> = configure password for an SSID" },
2547 { "new_password", wpa_cli_cmd_new_password, NULL,
2548 cli_cmd_flag_sensitive,
2549 "<network id> <password> = change password for an SSID" },
2550 { "pin", wpa_cli_cmd_pin, NULL,
2551 cli_cmd_flag_sensitive,
2552 "<network id> <pin> = configure pin for an SSID" },
2553 { "otp", wpa_cli_cmd_otp, NULL,
2554 cli_cmd_flag_sensitive,
2555 "<network id> <password> = configure one-time-password for an SSID"
2557 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2558 cli_cmd_flag_sensitive,
2559 "<network id> <passphrase> = configure private key passphrase\n"
2561 { "sim", wpa_cli_cmd_sim, NULL,
2562 cli_cmd_flag_sensitive,
2563 "<network id> <pin> = report SIM operation result" },
2564 { "bssid", wpa_cli_cmd_bssid, NULL,
2566 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2567 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2569 "<BSSID> = add a BSSID to the blacklist\n"
2570 "blacklist clear = clear the blacklist\n"
2571 "blacklist = display the blacklist" },
2572 { "log_level", wpa_cli_cmd_log_level, NULL,
2574 "<level> [<timestamp>] = update the log level/timestamp\n"
2575 "log_level = display the current log level and log options" },
2576 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2578 "= list configured networks" },
2579 { "select_network", wpa_cli_cmd_select_network, NULL,
2581 "<network id> = select a network (disable others)" },
2582 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2584 "<network id> = enable a network" },
2585 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2587 "<network id> = disable a network" },
2588 { "add_network", wpa_cli_cmd_add_network, NULL,
2590 "= add a network" },
2591 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2593 "<network id> = remove a network" },
2594 { "set_network", wpa_cli_cmd_set_network, NULL,
2595 cli_cmd_flag_sensitive,
2596 "<network id> <variable> <value> = set network variables (shows\n"
2597 " list of variables when run without arguments)" },
2598 { "get_network", wpa_cli_cmd_get_network, NULL,
2600 "<network id> <variable> = get network variables" },
2601 { "dup_network", wpa_cli_cmd_dup_network, NULL,
2603 "<src network id> <dst network id> <variable> = duplicate network variables"
2605 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2607 "= list configured credentials" },
2608 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2610 "= add a credential" },
2611 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2613 "<cred id> = remove a credential" },
2614 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2615 cli_cmd_flag_sensitive,
2616 "<cred id> <variable> <value> = set credential variables" },
2617 { "get_cred", wpa_cli_cmd_get_cred, NULL,
2619 "<cred id> <variable> = get credential variables" },
2620 { "save_config", wpa_cli_cmd_save_config, NULL,
2622 "= save the current configuration" },
2623 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2625 "= disconnect and wait for reassociate/reconnect command before\n"
2627 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2629 "= like reassociate, but only takes effect if already disconnected"
2631 { "scan", wpa_cli_cmd_scan, NULL,
2633 "= request new BSS scan" },
2634 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2636 "= get latest scan results" },
2637 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2639 "<<idx> | <bssid>> = get detailed scan result info" },
2640 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2642 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2643 "= get capabilies" },
2644 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2646 "= force wpa_supplicant to re-read its configuration file" },
2647 { "terminate", wpa_cli_cmd_terminate, NULL,
2649 "= terminate wpa_supplicant" },
2650 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2652 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2653 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2655 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2657 "<ifname> = removes the interface" },
2658 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2660 "= list available interfaces" },
2661 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2663 "<value> = set ap_scan parameter" },
2664 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2666 "<value> = set scan_interval parameter (in seconds)" },
2667 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2669 "<value> = set BSS expiration age parameter" },
2670 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2672 "<value> = set BSS expiration scan count parameter" },
2673 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2675 "<value> = set BSS flush age (0 by default)" },
2676 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2678 "<addr> = request STK negotiation with <addr>" },
2679 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2681 "<addr> = request over-the-DS FT with <addr>" },
2682 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2684 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2685 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2686 cli_cmd_flag_sensitive,
2687 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2689 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2690 cli_cmd_flag_sensitive,
2691 "<PIN> = verify PIN checksum" },
2692 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2693 "Cancels the pending WPS operation" },
2694 #ifdef CONFIG_WPS_NFC
2695 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2697 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2698 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
2700 "<WPS|NDEF> = build configuration token" },
2701 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
2703 "<WPS|NDEF> = create password token" },
2704 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
2705 cli_cmd_flag_sensitive,
2706 "<hexdump of payload> = report read NFC tag with WPS data" },
2707 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
2709 "<NDEF> <WPS> = create NFC handover request" },
2710 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
2712 "<NDEF> <WPS> = create NFC handover select" },
2713 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
2715 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2717 #endif /* CONFIG_WPS_NFC */
2718 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
2719 cli_cmd_flag_sensitive,
2720 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2721 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
2722 cli_cmd_flag_sensitive,
2723 "[params..] = enable/disable AP PIN" },
2724 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
2726 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2727 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
2729 "= stop Wi-Fi Protected Setup External Registrar" },
2730 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
2731 cli_cmd_flag_sensitive,
2732 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2733 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
2735 "<UUID> = accept an Enrollee PBC using External Registrar" },
2736 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
2737 cli_cmd_flag_sensitive,
2738 "<UUID> <PIN> = learn AP configuration" },
2739 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
2741 "<UUID> <network id> = set AP configuration for enrolling" },
2742 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
2743 cli_cmd_flag_sensitive,
2744 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2745 #ifdef CONFIG_WPS_NFC
2746 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
2748 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2749 #endif /* CONFIG_WPS_NFC */
2750 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
2752 "<addr> = request RSN authentication with <addr> in IBSS" },
2754 { "sta", wpa_cli_cmd_sta, NULL,
2756 "<addr> = get information about an associated station (AP)" },
2757 { "all_sta", wpa_cli_cmd_all_sta, NULL,
2759 "= get information about all associated stations (AP)" },
2760 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
2762 "<addr> = deauthenticate a station" },
2763 { "disassociate", wpa_cli_cmd_disassociate, NULL,
2765 "<addr> = disassociate a station" },
2766 { "chan_switch", wpa_cli_cmd_chanswitch, NULL,
2768 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
2769 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
2770 " = CSA parameters" },
2771 #endif /* CONFIG_AP */
2772 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
2773 "= notification of suspend/hibernate" },
2774 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
2775 "= notification of resume/thaw" },
2776 #ifdef CONFIG_TESTING_OPTIONS
2777 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
2778 "= drop SA without deauth/disassoc (test command)" },
2779 #endif /* CONFIG_TESTING_OPTIONS */
2780 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
2782 "<addr> = roam to the specified BSS" },
2784 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
2786 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2787 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
2788 "= stop P2P Devices search" },
2789 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
2791 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2792 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
2793 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2794 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
2795 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
2796 "<ifname> = remove P2P group interface (terminate group if GO)" },
2797 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
2798 "[ht40] = add a new P2P group (local end as GO)" },
2799 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
2800 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2801 "<addr> <method> = request provisioning discovery" },
2802 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
2804 "= get the passphrase for a group (GO only)" },
2805 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2806 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2807 "<addr> <TLVs> = schedule service discovery request" },
2808 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2809 NULL, cli_cmd_flag_none,
2810 "<id> = cancel pending service discovery request" },
2811 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
2813 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2814 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
2816 "= indicate change in local services" },
2817 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
2819 "<external> = set external processing of service discovery" },
2820 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
2822 "= remove all stored service entries" },
2823 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
2825 "<bonjour|upnp> <query|version> <response|service> = add a local "
2827 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
2829 "<bonjour|upnp> <query|version> [|service] = remove a local "
2831 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
2833 "<addr> = reject connection attempts from a specific peer" },
2834 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
2836 "<cmd> [peer=addr] = invite peer" },
2837 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
2838 "[discovered] = list known (optionally, only fully discovered) P2P "
2840 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
2842 "<address> = show information about known P2P peer" },
2843 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
2845 "<field> <value> = set a P2P parameter" },
2846 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
2847 "= flush P2P state" },
2848 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
2849 "= cancel P2P group formation" },
2850 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
2851 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2852 "<address> = unauthorize a peer" },
2853 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
2855 "[<duration> <interval>] [<duration> <interval>] = request GO "
2857 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
2859 "[<period> <interval>] = set extended listen timing" },
2860 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
2861 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2862 "<address|iface=address> = remove a peer from all groups" },
2863 #endif /* CONFIG_P2P */
2864 #ifdef CONFIG_WIFI_DISPLAY
2865 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
2867 "<subelem> [contents] = set Wi-Fi Display subelement" },
2868 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
2870 "<subelem> = get Wi-Fi Display subelement" },
2871 #endif /* CONFIG_WIFI_DISPLAY */
2872 #ifdef CONFIG_INTERWORKING
2873 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
2874 "= fetch ANQP information for all APs" },
2875 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
2877 "= stop fetch_anqp operation" },
2878 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
2880 "[auto] = perform Interworking network selection" },
2881 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2882 wpa_cli_complete_bss, cli_cmd_flag_none,
2883 "<BSSID> = connect using Interworking credentials" },
2884 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
2886 "<addr> <info id>[,<info id>]... = request ANQP information" },
2887 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
2889 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2890 { "gas_response_get", wpa_cli_cmd_gas_response_get,
2891 wpa_cli_complete_bss, cli_cmd_flag_none,
2892 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2893 #endif /* CONFIG_INTERWORKING */
2895 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
2897 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2899 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
2900 wpa_cli_complete_bss, cli_cmd_flag_none,
2901 "<addr> <home realm> = get HS20 nai home realm list" },
2902 { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request,
2903 wpa_cli_complete_bss, cli_cmd_flag_none,
2904 "<addr> <icon name> = get Hotspot 2.0 OSU icon" },
2905 { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none,
2906 "= fetch OSU provider information from all APs" },
2907 { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL,
2909 "= cancel fetch_osu command" },
2910 #endif /* CONFIG_HS20 */
2911 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
2913 "<0/1> = disable/enable automatic reconnection" },
2914 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
2916 "<addr> = request TDLS discovery with <addr>" },
2917 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
2919 "<addr> = request TDLS setup with <addr>" },
2920 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
2922 "<addr> = tear down TDLS with <addr>" },
2923 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
2925 "= get signal parameters" },
2926 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
2928 "= get TX/RX packet counters" },
2929 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
2931 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2932 #ifdef CONFIG_AUTOSCAN
2933 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
2934 "[params] = Set or unset (if none) autoscan parameters" },
2935 #endif /* CONFIG_AUTOSCAN */
2937 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
2938 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
2939 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
2940 "<query reason> = Send BSS Transition Management Query" },
2941 #endif /* CONFIG_WNM */
2942 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
2943 "<params..> = Sent unprocessed command" },
2944 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
2945 "= flush wpa_supplicant state" },
2947 { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
2948 "<command> = driver private commands" },
2949 #endif /* ANDROID */
2950 { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
2951 "= radio_work <show/add/done>" },
2952 { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
2953 "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
2955 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
2960 * Prints command usage, lines are padded with the specified string.
2962 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2967 printf("%s%s ", pad, cmd->cmd);
2968 for (n = 0; (c = cmd->usage[n]); n++) {
2977 static void print_help(const char *cmd)
2980 printf("commands:\n");
2981 for (n = 0; wpa_cli_commands[n].cmd; n++) {
2982 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
2983 print_cmd_help(&wpa_cli_commands[n], " ");
2988 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2990 const char *c, *delim;
2994 delim = os_strchr(cmd, ' ');
2998 len = os_strlen(cmd);
3000 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3001 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3002 return (wpa_cli_commands[n].flags &
3003 cli_cmd_flag_sensitive);
3009 static char ** wpa_list_cmd_list(void)
3013 struct cli_txt_entry *e;
3015 count = ARRAY_SIZE(wpa_cli_commands);
3016 count += dl_list_len(&p2p_groups);
3017 count += dl_list_len(&ifnames);
3018 res = os_calloc(count + 1, sizeof(char *));
3022 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3023 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3028 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
3029 size_t len = 8 + os_strlen(e->txt);
3030 res[i] = os_malloc(len);
3033 os_snprintf(res[i], len, "ifname=%s", e->txt);
3037 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
3038 res[i] = os_strdup(e->txt);
3048 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3053 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3054 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3055 if (wpa_cli_commands[i].completion)
3056 return wpa_cli_commands[i].completion(str,
3059 printf("\r%s\n", wpa_cli_commands[i].usage);
3069 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3075 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
3076 end = os_strchr(str, ' ');
3077 if (end && pos > end - str) {
3078 pos -= end - str + 1;
3083 end = os_strchr(str, ' ');
3084 if (end == NULL || str + pos < end)
3085 return wpa_list_cmd_list();
3087 cmd = os_malloc(pos + 1);
3090 os_memcpy(cmd, str, pos);
3091 cmd[end - str] = '\0';
3092 res = wpa_cli_cmd_completion(cmd, str, pos);
3098 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3100 struct wpa_cli_cmd *cmd, *match = NULL;
3104 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
3105 ifname_prefix = argv[0] + 7;
3109 ifname_prefix = NULL;
3115 cmd = wpa_cli_commands;
3117 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3120 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3121 /* we have an exact match */
3131 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3132 cmd = wpa_cli_commands;
3134 if (os_strncasecmp(cmd->cmd, argv[0],
3135 os_strlen(argv[0])) == 0) {
3136 printf(" %s", cmd->cmd);
3142 } else if (count == 0) {
3143 printf("Unknown command '%s'\n", argv[0]);
3146 ret = match->handler(ctrl, argc - 1, &argv[1]);
3153 static int str_match(const char *a, const char *b)
3155 return os_strncmp(a, b, os_strlen(b)) == 0;
3159 static int wpa_cli_exec(const char *program, const char *arg1,
3167 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3168 cmd = os_malloc(len);
3171 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3172 if (res < 0 || (size_t) res >= len) {
3176 cmd[len - 1] = '\0';
3178 if (system(cmd) < 0)
3180 #endif /* _WIN32_WCE */
3187 static void wpa_cli_action_process(const char *msg)
3190 char *copy = NULL, *id, *pos2;
3191 const char *ifname = ctrl_ifname;
3192 char ifname_buf[100];
3195 if (os_strncmp(pos, "IFNAME=", 7) == 0) {
3197 end = os_strchr(pos + 7, ' ');
3198 if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) {
3200 os_memcpy(ifname_buf, pos, end - pos);
3201 ifname_buf[end - pos] = '\0';
3202 ifname = ifname_buf;
3207 const char *prev = pos;
3209 pos = os_strchr(pos, '>');
3216 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3218 os_unsetenv("WPA_ID");
3219 os_unsetenv("WPA_ID_STR");
3220 os_unsetenv("WPA_CTRL_DIR");
3222 pos = os_strstr(pos, "[id=");
3224 copy = os_strdup(pos + 4);
3228 while (*pos2 && *pos2 != ' ')
3232 os_setenv("WPA_ID", id, 1);
3233 while (*pos2 && *pos2 != '=')
3238 while (*pos2 && *pos2 != ']')
3241 os_setenv("WPA_ID_STR", id, 1);
3245 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3247 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
3248 wpa_cli_connected = 1;
3249 wpa_cli_last_id = new_id;
3250 wpa_cli_exec(action_file, ifname, "CONNECTED");
3252 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3253 if (wpa_cli_connected) {
3254 wpa_cli_connected = 0;
3255 wpa_cli_exec(action_file, ifname, "DISCONNECTED");
3257 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3258 wpa_cli_exec(action_file, ifname, pos);
3259 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3260 wpa_cli_exec(action_file, ifname, pos);
3261 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3262 wpa_cli_exec(action_file, ifname, pos);
3263 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3264 wpa_cli_exec(action_file, ifname, pos);
3265 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3266 wpa_cli_exec(action_file, ifname, pos);
3267 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3268 wpa_cli_exec(action_file, ifname, pos);
3269 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3270 wpa_cli_exec(action_file, ifname, pos);
3271 } else if (str_match(pos, AP_STA_CONNECTED)) {
3272 wpa_cli_exec(action_file, ifname, pos);
3273 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3274 wpa_cli_exec(action_file, ifname, pos);
3275 } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
3276 wpa_cli_exec(action_file, ifname, pos);
3277 } else if (str_match(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
3278 wpa_cli_exec(action_file, ifname, pos);
3279 } else if (str_match(pos, HS20_DEAUTH_IMMINENT_NOTICE)) {
3280 wpa_cli_exec(action_file, ifname, pos);
3281 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3282 printf("wpa_supplicant is terminating - stop monitoring\n");
3288 #ifndef CONFIG_ANSI_C_EXTRA
3289 static void wpa_cli_action_cb(char *msg, size_t len)
3291 wpa_cli_action_process(msg);
3293 #endif /* CONFIG_ANSI_C_EXTRA */
3296 static void wpa_cli_reconnect(void)
3298 wpa_cli_close_connection();
3299 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3304 printf("\rConnection to wpa_supplicant re-established\n");
3310 static void cli_event(const char *str)
3312 const char *start, *s;
3314 start = os_strchr(str, '>');
3320 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3321 s = os_strchr(start, ' ');
3324 s = os_strchr(s + 1, ' ');
3327 cli_txt_list_add(&bsses, s + 1);
3331 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3332 s = os_strchr(start, ' ');
3335 s = os_strchr(s + 1, ' ');
3338 cli_txt_list_del_addr(&bsses, s + 1);
3343 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3344 s = os_strstr(start, " p2p_dev_addr=");
3347 cli_txt_list_add_addr(&p2p_peers, s + 14);
3351 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3352 s = os_strstr(start, " p2p_dev_addr=");
3355 cli_txt_list_del_addr(&p2p_peers, s + 14);
3359 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3360 s = os_strchr(start, ' ');
3363 cli_txt_list_add_word(&p2p_groups, s + 1);
3367 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3368 s = os_strchr(start, ' ');
3371 cli_txt_list_del_word(&p2p_groups, s + 1);
3374 #endif /* CONFIG_P2P */
3378 static int check_terminating(const char *msg)
3380 const char *pos = msg;
3384 pos = os_strchr(pos, '>');
3391 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3393 printf("\rConnection to wpa_supplicant lost - trying to "
3396 wpa_cli_attached = 0;
3397 wpa_cli_close_connection();
3405 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3407 if (ctrl_conn == NULL) {
3408 wpa_cli_reconnect();
3411 while (wpa_ctrl_pending(ctrl) > 0) {
3413 size_t len = sizeof(buf) - 1;
3414 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3417 wpa_cli_action_process(buf);
3420 if (wpa_cli_show_event(buf)) {
3422 printf("\r%s\n", buf);
3426 if (interactive && check_terminating(buf) > 0)
3430 printf("Could not read pending message.\n");
3435 if (wpa_ctrl_pending(ctrl) < 0) {
3436 printf("Connection to wpa_supplicant lost - trying to "
3438 wpa_cli_reconnect();
3444 static int tokenize_cmd(char *cmd, char *argv[])
3457 if (argc == max_args)
3460 char *pos2 = os_strrchr(pos, '"');
3464 while (*pos != '\0' && *pos != ' ')
3474 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3478 char *prefix = ifname_prefix;
3480 ifname_prefix = NULL;
3481 res = _wpa_ctrl_command(ctrl_conn, "PING", 0);
3482 ifname_prefix = prefix;
3484 printf("Connection to wpa_supplicant lost - trying to "
3486 wpa_cli_close_connection();
3490 wpa_cli_reconnect();
3491 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3495 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3497 wpa_cli_recv_pending(mon_conn, 0);
3501 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3503 char *argv[max_args];
3505 argc = tokenize_cmd(cmd, argv);
3507 wpa_request(ctrl_conn, argc, argv);
3511 static void wpa_cli_edit_eof_cb(void *ctx)
3517 static int warning_displayed = 0;
3518 static char *hfile = NULL;
3519 static int edit_started = 0;
3521 static void start_edit(void)
3526 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3527 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3528 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3530 home = getenv("HOME");
3532 const char *fname = ".wpa_cli_history";
3533 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3534 hfile = os_malloc(hfile_len);
3536 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3539 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3540 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3546 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3550 static void update_bssid_list(struct wpa_ctrl *ctrl)
3553 size_t len = sizeof(buf);
3555 char *cmd = "BSS RANGE=ALL MASK=0x2";
3560 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3567 pos = os_strstr(pos, "bssid=");
3571 end = os_strchr(pos, '\n');
3575 cli_txt_list_add(&bsses, pos);
3581 static void update_ifnames(struct wpa_ctrl *ctrl)
3584 size_t len = sizeof(buf);
3586 char *cmd = "INTERFACES";
3590 cli_txt_list_flush(&ifnames);
3594 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3601 end = os_strchr(pos, '\n');
3605 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
3606 if (ret > 0 && ret < (int) sizeof(txt))
3607 cli_txt_list_add(&ifnames, txt);
3613 static void try_connection(void *eloop_ctx, void *timeout_ctx)
3618 if (ctrl_ifname == NULL)
3619 ctrl_ifname = wpa_cli_get_default_ifname();
3621 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3622 if (!warning_displayed) {
3623 printf("Could not connect to wpa_supplicant: "
3624 "%s - re-trying\n", ctrl_ifname);
3625 warning_displayed = 1;
3627 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
3631 update_bssid_list(ctrl_conn);
3633 if (warning_displayed)
3634 printf("Connection established.\n");
3641 static void wpa_cli_interactive(void)
3643 printf("\nInteractive mode\n\n");
3645 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
3647 eloop_cancel_timeout(try_connection, NULL, NULL);
3649 cli_txt_list_flush(&p2p_peers);
3650 cli_txt_list_flush(&p2p_groups);
3651 cli_txt_list_flush(&bsses);
3652 cli_txt_list_flush(&ifnames);
3654 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3656 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3657 wpa_cli_close_connection();
3661 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3663 #ifdef CONFIG_ANSI_C_EXTRA
3664 /* TODO: ANSI C version(?) */
3665 printf("Action processing not supported in ANSI C build.\n");
3666 #else /* CONFIG_ANSI_C_EXTRA */
3670 char buf[256]; /* note: large enough to fit in unsolicited messages */
3673 fd = wpa_ctrl_get_fd(ctrl);
3675 while (!wpa_cli_quit) {
3678 tv.tv_sec = ping_interval;
3680 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3681 if (res < 0 && errno != EINTR) {
3686 if (FD_ISSET(fd, &rfds))
3687 wpa_cli_recv_pending(ctrl, 1);
3689 /* verify that connection is still working */
3690 len = sizeof(buf) - 1;
3691 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3692 wpa_cli_action_cb) < 0 ||
3693 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3694 printf("wpa_supplicant did not reply to PING "
3695 "command - exiting\n");
3700 #endif /* CONFIG_ANSI_C_EXTRA */
3704 static void wpa_cli_cleanup(void)
3706 wpa_cli_close_connection();
3708 os_daemonize_terminate(pid_file);
3710 os_program_deinit();
3714 static void wpa_cli_terminate(int sig, void *ctx)
3720 static char * wpa_cli_get_default_ifname(void)
3722 char *ifname = NULL;
3724 #ifdef CONFIG_CTRL_IFACE_UNIX
3725 struct dirent *dent;
3726 DIR *dir = opendir(ctrl_iface_dir);
3729 char ifprop[PROPERTY_VALUE_MAX];
3730 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3731 ifname = os_strdup(ifprop);
3732 printf("Using interface '%s'\n", ifname);
3735 #endif /* ANDROID */
3738 while ((dent = readdir(dir))) {
3739 #ifdef _DIRENT_HAVE_D_TYPE
3741 * Skip the file if it is not a socket. Also accept
3742 * DT_UNKNOWN (0) in case the C library or underlying
3743 * file system does not support d_type.
3745 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3747 #endif /* _DIRENT_HAVE_D_TYPE */
3748 if (os_strcmp(dent->d_name, ".") == 0 ||
3749 os_strcmp(dent->d_name, "..") == 0)
3751 printf("Selected interface '%s'\n", dent->d_name);
3752 ifname = os_strdup(dent->d_name);
3756 #endif /* CONFIG_CTRL_IFACE_UNIX */
3758 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3759 char buf[4096], *pos;
3761 struct wpa_ctrl *ctrl;
3764 ctrl = wpa_ctrl_open(NULL);
3768 len = sizeof(buf) - 1;
3769 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3772 pos = os_strchr(buf, '\n');
3775 ifname = os_strdup(buf);
3777 wpa_ctrl_close(ctrl);
3778 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3784 int main(int argc, char *argv[])
3789 const char *global = NULL;
3791 if (os_program_init())
3795 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3800 action_file = optarg;
3809 ping_interval = atoi(optarg);
3815 printf("%s\n", wpa_cli_version);
3818 os_free(ctrl_ifname);
3819 ctrl_ifname = os_strdup(optarg);
3822 ctrl_iface_dir = optarg;
3833 interactive = (argc == optind) && (action_file == NULL);
3836 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3842 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3843 ctrl_conn = wpa_ctrl_open(NULL);
3844 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3845 ctrl_conn = wpa_ctrl_open(global);
3846 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3847 if (ctrl_conn == NULL) {
3848 fprintf(stderr, "Failed to connect to wpa_supplicant "
3849 "global interface: %s error: %s\n",
3850 global, strerror(errno));
3855 update_ifnames(ctrl_conn);
3856 mon_conn = wpa_ctrl_open(global);
3858 if (wpa_ctrl_attach(mon_conn) == 0) {
3859 wpa_cli_attached = 1;
3860 eloop_register_read_sock(
3861 wpa_ctrl_get_fd(mon_conn),
3862 wpa_cli_mon_receive,
3865 printf("Failed to open monitor "
3866 "connection through global "
3867 "control interface\n");
3873 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
3875 if (ctrl_ifname == NULL)
3876 ctrl_ifname = wpa_cli_get_default_ifname();
3879 wpa_cli_interactive();
3882 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3883 fprintf(stderr, "Failed to connect to non-global "
3884 "ctrl_ifname: %s error: %s\n",
3885 ctrl_ifname, strerror(errno));
3890 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3891 wpa_cli_attached = 1;
3893 printf("Warning: Failed to attach to "
3894 "wpa_supplicant.\n");
3899 if (daemonize && os_daemonize(pid_file))
3903 wpa_cli_action(ctrl_conn);
3905 ret = wpa_request(ctrl_conn, argc - optind,
3909 os_free(ctrl_ifname);
3916 #else /* CONFIG_CTRL_IFACE */
3917 int main(int argc, char *argv[])
3919 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3922 #endif /* CONFIG_CTRL_IFACE */