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_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
537 print_help(argc > 0 ? argv[0] : NULL);
542 static char ** wpa_cli_complete_help(const char *str, int pos)
544 int arg = get_cmd_arg_num(str, pos);
549 res = wpa_list_cmd_list();
557 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
559 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
564 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
573 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
579 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
580 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
581 printf("Too long SET command.\n");
584 return wpa_ctrl_command(ctrl, cmd);
587 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
591 static char ** wpa_cli_complete_set(const char *str, int pos)
593 int arg = get_cmd_arg_num(str, pos);
594 const char *fields[] = {
596 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
597 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
598 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
599 "wps_fragment_size", "wps_version_number", "ampdu",
600 "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
601 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
603 /* global configuration parameters */
604 "eapol_version", "ap_scan", "disable_scan_offload",
605 "fast_reauth", "opensc_engine_path", "pkcs11_engine_path",
606 "pkcs11_module_path", "pcsc_reader", "pcsc_pin",
607 "driver_param", "dot11RSNAConfigPMKLifetime",
608 "dot11RSNAConfigPMKReauthThreshold",
609 "dot11RSNAConfigSATimeout",
610 "update_config", "load_dynamic_eap", "uuid", "device_name",
611 "manufacturer", "model_name", "model_number", "serial_number",
612 "device_type", "os_version", "config_methods",
613 "wps_cred_processing", "wps_vendor_ext_m1", "sec_device_type",
614 "p2p_listen_reg_class", "p2p_listen_channel",
615 "p2p_oper_reg_class", "p2p_oper_channel",
616 "p2p_go_intent", "p2p_ssid_postfix", "persistent_reconnect",
617 "p2p_intra_bss", "p2p_group_idle", "p2p_pref_chan",
619 "p2p_go_ht40", "p2p_disabled", "p2p_no_group_iface",
621 "p2p_ignore_shared_freq", "country", "bss_max_count",
622 "bss_expiration_age", "bss_expiration_scan_count",
623 "filter_ssids", "filter_rssi", "max_num_sta",
624 "disassoc_low_ack", "hs20", "interworking", "hessid",
625 "access_network_type", "pbc_in_m1", "autoscan",
626 "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", "wps_nfc_dh_privkey",
627 "wps_nfc_dev_pw", "ext_password_backend",
628 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
629 "sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
630 "ignore_old_scan_res", "freq_list", "external_sim",
631 "tdls_external_control"
633 int i, num_fields = ARRAY_SIZE(fields);
636 char **res = os_calloc(num_fields + 1, sizeof(char *));
639 for (i = 0; i < num_fields; i++) {
640 res[i] = os_strdup(fields[i]);
647 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
648 return cli_txt_list_array(&bsses);
654 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
656 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
660 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
662 return wpa_ctrl_command(ctrl, "LOGOFF");
666 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
668 return wpa_ctrl_command(ctrl, "LOGON");
672 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
675 return wpa_ctrl_command(ctrl, "REASSOCIATE");
679 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
682 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
686 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
688 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
692 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
695 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
699 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
702 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
706 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
709 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
713 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
719 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
721 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
722 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
723 printf("Too long BSS_FLUSH command.\n");
726 return wpa_ctrl_command(ctrl, cmd);
730 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
733 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
737 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
739 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
743 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
745 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
749 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
752 printf("Invalid WPS_PIN command: need one or two arguments:\n"
753 "- BSSID: use 'any' to select any\n"
754 "- PIN: optional, used only with devices that have no "
759 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
763 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
766 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
770 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
773 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
777 #ifdef CONFIG_WPS_NFC
779 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
781 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
785 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
788 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
792 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
795 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
799 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
807 printf("Invalid 'wps_nfc_tag_read' command - one argument "
812 buflen = 18 + os_strlen(argv[0]);
813 buf = os_malloc(buflen);
816 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
818 ret = wpa_ctrl_command(ctrl, buf);
825 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
828 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
832 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
835 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
839 static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl *ctrl, int argc,
847 printf("Invalid 'nfc_rx_handover_sel' command - one argument "
852 buflen = 21 + os_strlen(argv[0]);
853 buf = os_malloc(buflen);
856 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_SEL %s", argv[0]);
858 ret = wpa_ctrl_command(ctrl, buf);
865 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
868 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
871 #endif /* CONFIG_WPS_NFC */
874 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
880 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
882 else if (argc == 5 || argc == 6) {
883 char ssid_hex[2 * 32 + 1];
884 char key_hex[2 * 64 + 1];
888 for (i = 0; i < 32; i++) {
889 if (argv[2][i] == '\0')
891 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
896 for (i = 0; i < 64; i++) {
897 if (argv[5][i] == '\0')
899 os_snprintf(&key_hex[i * 2], 3, "%02x",
904 res = os_snprintf(cmd, sizeof(cmd),
905 "WPS_REG %s %s %s %s %s %s",
906 argv[0], argv[1], ssid_hex, argv[3], argv[4],
909 printf("Invalid WPS_REG command: need two arguments:\n"
910 "- BSSID of the target AP\n"
912 printf("Alternatively, six arguments can be used to "
913 "reconfigure the AP:\n"
914 "- BSSID of the target AP\n"
917 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
918 "- new encr (NONE, WEP, TKIP, CCMP)\n"
923 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
924 printf("Too long WPS_REG command.\n");
927 return wpa_ctrl_command(ctrl, cmd);
931 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
934 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
938 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
941 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
945 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
948 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
953 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
957 printf("Invalid WPS_ER_PIN command: need at least two "
959 "- UUID: use 'any' to select any\n"
960 "- PIN: Enrollee PIN\n"
961 "optional: - Enrollee MAC address\n");
965 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
969 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
972 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
976 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
980 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
981 "- UUID: specify which AP to use\n"
986 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
990 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
994 printf("Invalid WPS_ER_SET_CONFIG command: need two "
996 "- UUID: specify which AP to use\n"
997 "- Network configuration id\n");
1001 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
1005 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1011 if (argc == 5 || argc == 6) {
1012 char ssid_hex[2 * 32 + 1];
1013 char key_hex[2 * 64 + 1];
1017 for (i = 0; i < 32; i++) {
1018 if (argv[2][i] == '\0')
1020 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1025 for (i = 0; i < 64; i++) {
1026 if (argv[5][i] == '\0')
1028 os_snprintf(&key_hex[i * 2], 3, "%02x",
1033 res = os_snprintf(cmd, sizeof(cmd),
1034 "WPS_ER_CONFIG %s %s %s %s %s %s",
1035 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1038 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1042 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1043 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1048 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1049 printf("Too long WPS_ER_CONFIG command.\n");
1052 return wpa_ctrl_command(ctrl, cmd);
1056 #ifdef CONFIG_WPS_NFC
1057 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1061 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1063 "- WPS/NDEF: token format\n"
1064 "- UUID: specify which AP to use\n");
1068 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1070 #endif /* CONFIG_WPS_NFC */
1073 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1075 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1079 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1081 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1085 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1087 char cmd[256], *pos, *end;
1091 printf("Invalid IDENTITY command: needs two arguments "
1092 "(network id and identity)\n");
1096 end = cmd + sizeof(cmd);
1098 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1100 if (ret < 0 || ret >= end - pos) {
1101 printf("Too long IDENTITY command.\n");
1105 for (i = 2; i < argc; i++) {
1106 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1107 if (ret < 0 || ret >= end - pos) {
1108 printf("Too long IDENTITY command.\n");
1114 return wpa_ctrl_command(ctrl, cmd);
1118 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1120 char cmd[256], *pos, *end;
1124 printf("Invalid PASSWORD command: needs two arguments "
1125 "(network id and password)\n");
1129 end = cmd + sizeof(cmd);
1131 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1133 if (ret < 0 || ret >= end - pos) {
1134 printf("Too long PASSWORD command.\n");
1138 for (i = 2; i < argc; i++) {
1139 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1140 if (ret < 0 || ret >= end - pos) {
1141 printf("Too long PASSWORD command.\n");
1147 return wpa_ctrl_command(ctrl, cmd);
1151 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1154 char cmd[256], *pos, *end;
1158 printf("Invalid NEW_PASSWORD command: needs two arguments "
1159 "(network id and password)\n");
1163 end = cmd + sizeof(cmd);
1165 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1167 if (ret < 0 || ret >= end - pos) {
1168 printf("Too long NEW_PASSWORD command.\n");
1172 for (i = 2; i < argc; i++) {
1173 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1174 if (ret < 0 || ret >= end - pos) {
1175 printf("Too long NEW_PASSWORD command.\n");
1181 return wpa_ctrl_command(ctrl, cmd);
1185 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1187 char cmd[256], *pos, *end;
1191 printf("Invalid PIN command: needs two arguments "
1192 "(network id and pin)\n");
1196 end = cmd + sizeof(cmd);
1198 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1200 if (ret < 0 || ret >= end - pos) {
1201 printf("Too long PIN command.\n");
1205 for (i = 2; i < argc; i++) {
1206 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1207 if (ret < 0 || ret >= end - pos) {
1208 printf("Too long PIN command.\n");
1213 return wpa_ctrl_command(ctrl, cmd);
1217 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1219 char cmd[256], *pos, *end;
1223 printf("Invalid OTP command: needs two arguments (network "
1224 "id and password)\n");
1228 end = cmd + sizeof(cmd);
1230 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1232 if (ret < 0 || ret >= end - pos) {
1233 printf("Too long OTP command.\n");
1237 for (i = 2; i < argc; i++) {
1238 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1239 if (ret < 0 || ret >= end - pos) {
1240 printf("Too long OTP command.\n");
1246 return wpa_ctrl_command(ctrl, cmd);
1250 static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
1252 char cmd[256], *pos, *end;
1256 printf("Invalid SIM command: needs two arguments "
1257 "(network id and SIM operation response)\n");
1261 end = cmd + sizeof(cmd);
1263 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
1265 if (ret < 0 || ret >= end - pos) {
1266 printf("Too long SIM command.\n");
1270 for (i = 2; i < argc; i++) {
1271 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1272 if (ret < 0 || ret >= end - pos) {
1273 printf("Too long SIM command.\n");
1278 return wpa_ctrl_command(ctrl, cmd);
1282 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1285 char cmd[256], *pos, *end;
1289 printf("Invalid PASSPHRASE command: needs two arguments "
1290 "(network id and passphrase)\n");
1294 end = cmd + sizeof(cmd);
1296 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1298 if (ret < 0 || ret >= end - pos) {
1299 printf("Too long PASSPHRASE command.\n");
1303 for (i = 2; i < argc; i++) {
1304 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1305 if (ret < 0 || ret >= end - pos) {
1306 printf("Too long PASSPHRASE command.\n");
1312 return wpa_ctrl_command(ctrl, cmd);
1316 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1319 printf("Invalid BSSID command: needs two arguments (network "
1324 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1328 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1330 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1334 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1336 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1340 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1343 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1347 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1350 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1354 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1357 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1361 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1364 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1368 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1371 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1375 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1378 return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1382 static void wpa_cli_show_network_variables(void)
1384 printf("set_network variables:\n"
1385 " ssid (network name, SSID)\n"
1386 " psk (WPA passphrase or pre-shared key)\n"
1387 " key_mgmt (key management protocol)\n"
1388 " identity (EAP identity)\n"
1389 " password (EAP password)\n"
1392 "Note: Values are entered in the same format as the "
1393 "configuration file is using,\n"
1394 "i.e., strings values need to be inside double quotation "
1396 "For example: set_network 1 ssid \"network name\"\n"
1398 "Please see wpa_supplicant.conf documentation for full list "
1399 "of\navailable variables.\n");
1403 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1407 wpa_cli_show_network_variables();
1412 printf("Invalid SET_NETWORK command: needs three arguments\n"
1413 "(network id, variable name, and value)\n");
1417 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1421 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1425 wpa_cli_show_network_variables();
1430 printf("Invalid GET_NETWORK command: needs two arguments\n"
1431 "(network id and variable name)\n");
1435 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1439 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1442 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1446 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1448 return wpa_ctrl_command(ctrl, "ADD_CRED");
1452 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1455 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1459 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1462 printf("Invalid SET_CRED command: needs three arguments\n"
1463 "(cred id, variable name, and value)\n");
1467 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1471 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1474 return wpa_ctrl_command(ctrl, "DISCONNECT");
1478 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1481 return wpa_ctrl_command(ctrl, "RECONNECT");
1485 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1488 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1492 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1494 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1498 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1501 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1505 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1507 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1511 static char ** wpa_cli_complete_bss(const char *str, int pos)
1513 int arg = get_cmd_arg_num(str, pos);
1518 res = cli_txt_list_array(&bsses);
1526 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1529 if (argc < 1 || argc > 2) {
1530 printf("Invalid GET_CAPABILITY command: need either one or "
1535 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1536 printf("Invalid GET_CAPABILITY command: second argument, "
1537 "if any, must be 'strict'\n");
1541 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1545 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1547 printf("Available interfaces:\n");
1548 return wpa_ctrl_command(ctrl, "INTERFACES");
1552 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1555 wpa_cli_list_interfaces(ctrl);
1559 wpa_cli_close_connection();
1560 os_free(ctrl_ifname);
1561 ctrl_ifname = os_strdup(argv[0]);
1563 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1564 printf("Connected to interface '%s.\n", ctrl_ifname);
1566 printf("Could not connect to interface '%s' - re-trying\n",
1573 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1576 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1580 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1583 return wpa_ctrl_command(ctrl, "TERMINATE");
1587 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1594 printf("Invalid INTERFACE_ADD command: needs at least one "
1595 "argument (interface name)\n"
1596 "All arguments: ifname confname driver ctrl_interface "
1597 "driver_param bridge_name\n");
1602 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1603 * <driver_param>TAB<bridge_name>
1605 res = os_snprintf(cmd, sizeof(cmd),
1606 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1608 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1609 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1610 argc > 5 ? argv[5] : "");
1611 if (res < 0 || (size_t) res >= sizeof(cmd))
1613 cmd[sizeof(cmd) - 1] = '\0';
1614 return wpa_ctrl_command(ctrl, cmd);
1618 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1621 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1625 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1628 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1633 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1635 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1639 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1640 char *addr, size_t addr_len)
1642 char buf[4096], *pos;
1646 if (ctrl_conn == NULL) {
1647 printf("Not connected to hostapd - command dropped.\n");
1650 len = sizeof(buf) - 1;
1651 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1654 printf("'%s' command timed out.\n", cmd);
1656 } else if (ret < 0) {
1657 printf("'%s' command failed.\n", cmd);
1662 if (os_memcmp(buf, "FAIL", 4) == 0)
1667 while (*pos != '\0' && *pos != '\n')
1670 os_strlcpy(addr, buf, addr_len);
1675 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1677 char addr[32], cmd[64];
1679 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1682 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1683 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1689 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1692 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1696 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1699 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1702 static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
1705 return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
1708 #endif /* CONFIG_AP */
1711 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1713 return wpa_ctrl_command(ctrl, "SUSPEND");
1717 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1719 return wpa_ctrl_command(ctrl, "RESUME");
1723 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1725 return wpa_ctrl_command(ctrl, "DROP_SA");
1729 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1731 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1737 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1739 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1743 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1746 int arg = get_cmd_arg_num(str, pos);
1748 res = os_calloc(6, sizeof(char *));
1751 res[0] = os_strdup("type=social");
1752 if (res[0] == NULL) {
1756 res[1] = os_strdup("type=progressive");
1759 res[2] = os_strdup("delay=");
1762 res[3] = os_strdup("dev_id=");
1766 res[4] = os_strdup("[timeout]");
1772 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1775 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1779 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1782 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
1786 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1788 int arg = get_cmd_arg_num(str, pos);
1793 res = cli_txt_list_array(&p2p_peers);
1801 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1804 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
1808 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1811 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
1815 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
1817 int arg = get_cmd_arg_num(str, pos);
1822 res = cli_txt_list_array(&p2p_groups);
1830 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1833 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
1837 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1840 if (argc != 2 && argc != 3) {
1841 printf("Invalid P2P_PROV_DISC command: needs at least "
1842 "two arguments, address and config method\n"
1843 "(display, keypad, or pbc) and an optional join\n");
1847 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
1851 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1854 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1858 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1863 if (argc != 2 && argc != 4) {
1864 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1865 "arguments (address and TLVs) or four arguments "
1866 "(address, \"upnp\", version, search target "
1871 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
1873 return wpa_ctrl_command(ctrl, cmd);
1877 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1878 int argc, char *argv[])
1880 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
1884 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1891 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1892 "arguments (freq, address, dialog token, and TLVs)\n");
1896 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1897 argv[0], argv[1], argv[2], argv[3]);
1898 if (res < 0 || (size_t) res >= sizeof(cmd))
1900 cmd[sizeof(cmd) - 1] = '\0';
1901 return wpa_ctrl_command(ctrl, cmd);
1905 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1908 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1912 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1913 int argc, char *argv[])
1915 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
1919 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1922 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1926 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1932 if (argc != 3 && argc != 4) {
1933 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1939 res = os_snprintf(cmd, sizeof(cmd),
1940 "P2P_SERVICE_ADD %s %s %s %s",
1941 argv[0], argv[1], argv[2], argv[3]);
1943 res = os_snprintf(cmd, sizeof(cmd),
1944 "P2P_SERVICE_ADD %s %s %s",
1945 argv[0], argv[1], argv[2]);
1946 if (res < 0 || (size_t) res >= sizeof(cmd))
1948 cmd[sizeof(cmd) - 1] = '\0';
1949 return wpa_ctrl_command(ctrl, cmd);
1953 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1959 if (argc != 2 && argc != 3) {
1960 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1966 res = os_snprintf(cmd, sizeof(cmd),
1967 "P2P_SERVICE_DEL %s %s %s",
1968 argv[0], argv[1], argv[2]);
1970 res = os_snprintf(cmd, sizeof(cmd),
1971 "P2P_SERVICE_DEL %s %s",
1973 if (res < 0 || (size_t) res >= sizeof(cmd))
1975 cmd[sizeof(cmd) - 1] = '\0';
1976 return wpa_ctrl_command(ctrl, cmd);
1980 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1981 int argc, char *argv[])
1983 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
1987 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1988 int argc, char *argv[])
1990 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
1994 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
1996 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2000 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2002 int arg = get_cmd_arg_num(str, pos);
2007 res = cli_txt_list_array(&p2p_peers);
2015 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2016 char *addr, size_t addr_len,
2019 char buf[4096], *pos;
2023 if (ctrl_conn == NULL)
2025 len = sizeof(buf) - 1;
2026 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2029 printf("'%s' command timed out.\n", cmd);
2031 } else if (ret < 0) {
2032 printf("'%s' command failed.\n", cmd);
2037 if (os_memcmp(buf, "FAIL", 4) == 0)
2041 while (*pos != '\0' && *pos != '\n')
2044 os_strlcpy(addr, buf, addr_len);
2045 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2046 printf("%s\n", addr);
2051 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2053 char addr[32], cmd[64];
2056 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2058 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2059 addr, sizeof(addr), discovered))
2062 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2063 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2070 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2072 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2076 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
2078 int arg = get_cmd_arg_num(str, pos);
2079 const char *fields[] = {
2099 int i, num_fields = ARRAY_SIZE(fields);
2102 char **res = os_calloc(num_fields + 1, sizeof(char *));
2105 for (i = 0; i < num_fields; i++) {
2106 res[i] = os_strdup(fields[i]);
2113 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
2114 return cli_txt_list_array(&p2p_peers);
2120 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2122 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2126 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2129 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2133 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2136 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2140 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2143 if (argc != 0 && argc != 2 && argc != 4) {
2144 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2145 "(preferred duration, interval; in microsecods).\n"
2146 "Optional second pair can be used to provide "
2147 "acceptable values.\n");
2151 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2155 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2158 if (argc != 0 && argc != 2) {
2159 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2160 "(availability period, availability interval; in "
2162 "Extended Listen Timing can be cancelled with this "
2163 "command when used without parameters.\n");
2167 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2171 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
2174 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
2177 #endif /* CONFIG_P2P */
2179 #ifdef CONFIG_WIFI_DISPLAY
2181 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2187 if (argc != 1 && argc != 2) {
2188 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2189 "arguments (subelem, hexdump)\n");
2193 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2194 argv[0], argc > 1 ? argv[1] : "");
2195 if (res < 0 || (size_t) res >= sizeof(cmd))
2197 cmd[sizeof(cmd) - 1] = '\0';
2198 return wpa_ctrl_command(ctrl, cmd);
2202 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2209 printf("Invalid WFD_SUBELEM_GET command: needs one "
2210 "argument (subelem)\n");
2214 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2216 if (res < 0 || (size_t) res >= sizeof(cmd))
2218 cmd[sizeof(cmd) - 1] = '\0';
2219 return wpa_ctrl_command(ctrl, cmd);
2221 #endif /* CONFIG_WIFI_DISPLAY */
2224 #ifdef CONFIG_INTERWORKING
2225 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2228 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2232 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2235 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2239 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2242 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2246 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2249 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2253 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2255 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2259 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2262 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2266 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2269 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2271 #endif /* CONFIG_INTERWORKING */
2276 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2279 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2283 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2289 printf("Command needs one or two arguments (dst mac addr and "
2290 "optional home realm)\n");
2294 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2298 return wpa_ctrl_command(ctrl, cmd);
2301 #endif /* CONFIG_HS20 */
2304 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2307 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2311 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2314 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2318 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2321 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2325 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2328 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2332 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2335 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2339 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2342 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2346 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2349 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2353 #ifdef CONFIG_AUTOSCAN
2355 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2358 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2360 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2363 #endif /* CONFIG_AUTOSCAN */
2368 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2370 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2374 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2376 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2379 #endif /* CONFIG_WNM */
2382 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2386 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2391 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2393 return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
2395 #endif /* ANDROID */
2398 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2400 return wpa_ctrl_command(ctrl, "FLUSH");
2404 static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
2406 return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
2410 enum wpa_cli_cmd_flags {
2411 cli_cmd_flag_none = 0x00,
2412 cli_cmd_flag_sensitive = 0x01
2415 struct wpa_cli_cmd {
2417 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2418 char ** (*completion)(const char *str, int pos);
2419 enum wpa_cli_cmd_flags flags;
2423 static struct wpa_cli_cmd wpa_cli_commands[] = {
2424 { "status", wpa_cli_cmd_status, NULL,
2426 "[verbose] = get current WPA/EAPOL/EAP status" },
2427 { "ifname", wpa_cli_cmd_ifname, NULL,
2429 "= get current interface name" },
2430 { "ping", wpa_cli_cmd_ping, NULL,
2432 "= pings wpa_supplicant" },
2433 { "relog", wpa_cli_cmd_relog, NULL,
2435 "= re-open log-file (allow rolling logs)" },
2436 { "note", wpa_cli_cmd_note, NULL,
2438 "<text> = add a note to wpa_supplicant debug log" },
2439 { "mib", wpa_cli_cmd_mib, NULL,
2441 "= get MIB variables (dot1x, dot11)" },
2442 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2444 "[command] = show usage help" },
2445 { "interface", wpa_cli_cmd_interface, NULL,
2447 "[ifname] = show interfaces/select interface" },
2448 { "level", wpa_cli_cmd_level, NULL,
2450 "<debug level> = change debug level" },
2451 { "license", wpa_cli_cmd_license, NULL,
2453 "= show full wpa_cli license" },
2454 { "quit", wpa_cli_cmd_quit, NULL,
2457 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2459 "= set variables (shows list of variables when run without "
2461 { "get", wpa_cli_cmd_get, NULL,
2463 "<name> = get information" },
2464 { "logon", wpa_cli_cmd_logon, NULL,
2466 "= IEEE 802.1X EAPOL state machine logon" },
2467 { "logoff", wpa_cli_cmd_logoff, NULL,
2469 "= IEEE 802.1X EAPOL state machine logoff" },
2470 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2472 "= show PMKSA cache" },
2473 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2475 "= force reassociation" },
2476 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2478 "<BSSID> = force preauthentication" },
2479 { "identity", wpa_cli_cmd_identity, NULL,
2481 "<network id> <identity> = configure identity for an SSID" },
2482 { "password", wpa_cli_cmd_password, NULL,
2483 cli_cmd_flag_sensitive,
2484 "<network id> <password> = configure password for an SSID" },
2485 { "new_password", wpa_cli_cmd_new_password, NULL,
2486 cli_cmd_flag_sensitive,
2487 "<network id> <password> = change password for an SSID" },
2488 { "pin", wpa_cli_cmd_pin, NULL,
2489 cli_cmd_flag_sensitive,
2490 "<network id> <pin> = configure pin for an SSID" },
2491 { "otp", wpa_cli_cmd_otp, NULL,
2492 cli_cmd_flag_sensitive,
2493 "<network id> <password> = configure one-time-password for an SSID"
2495 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2496 cli_cmd_flag_sensitive,
2497 "<network id> <passphrase> = configure private key passphrase\n"
2499 { "sim", wpa_cli_cmd_sim, NULL,
2500 cli_cmd_flag_sensitive,
2501 "<network id> <pin> = report SIM operation result" },
2502 { "bssid", wpa_cli_cmd_bssid, NULL,
2504 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2505 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2507 "<BSSID> = add a BSSID to the blacklist\n"
2508 "blacklist clear = clear the blacklist\n"
2509 "blacklist = display the blacklist" },
2510 { "log_level", wpa_cli_cmd_log_level, NULL,
2512 "<level> [<timestamp>] = update the log level/timestamp\n"
2513 "log_level = display the current log level and log options" },
2514 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2516 "= list configured networks" },
2517 { "select_network", wpa_cli_cmd_select_network, NULL,
2519 "<network id> = select a network (disable others)" },
2520 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2522 "<network id> = enable a network" },
2523 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2525 "<network id> = disable a network" },
2526 { "add_network", wpa_cli_cmd_add_network, NULL,
2528 "= add a network" },
2529 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2531 "<network id> = remove a network" },
2532 { "set_network", wpa_cli_cmd_set_network, NULL,
2533 cli_cmd_flag_sensitive,
2534 "<network id> <variable> <value> = set network variables (shows\n"
2535 " list of variables when run without arguments)" },
2536 { "get_network", wpa_cli_cmd_get_network, NULL,
2538 "<network id> <variable> = get network variables" },
2539 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2541 "= list configured credentials" },
2542 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2544 "= add a credential" },
2545 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2547 "<cred id> = remove a credential" },
2548 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2549 cli_cmd_flag_sensitive,
2550 "<cred id> <variable> <value> = set credential variables" },
2551 { "save_config", wpa_cli_cmd_save_config, NULL,
2553 "= save the current configuration" },
2554 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2556 "= disconnect and wait for reassociate/reconnect command before\n"
2558 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2560 "= like reassociate, but only takes effect if already disconnected"
2562 { "scan", wpa_cli_cmd_scan, NULL,
2564 "= request new BSS scan" },
2565 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2567 "= get latest scan results" },
2568 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2570 "<<idx> | <bssid>> = get detailed scan result info" },
2571 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2573 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2574 "= get capabilies" },
2575 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2577 "= force wpa_supplicant to re-read its configuration file" },
2578 { "terminate", wpa_cli_cmd_terminate, NULL,
2580 "= terminate wpa_supplicant" },
2581 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2583 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2584 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2586 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2588 "<ifname> = removes the interface" },
2589 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2591 "= list available interfaces" },
2592 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2594 "<value> = set ap_scan parameter" },
2595 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2597 "<value> = set scan_interval parameter (in seconds)" },
2598 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2600 "<value> = set BSS expiration age parameter" },
2601 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2603 "<value> = set BSS expiration scan count parameter" },
2604 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2606 "<value> = set BSS flush age (0 by default)" },
2607 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2609 "<addr> = request STK negotiation with <addr>" },
2610 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2612 "<addr> = request over-the-DS FT with <addr>" },
2613 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2615 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2616 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2617 cli_cmd_flag_sensitive,
2618 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2620 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2621 cli_cmd_flag_sensitive,
2622 "<PIN> = verify PIN checksum" },
2623 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2624 "Cancels the pending WPS operation" },
2625 #ifdef CONFIG_WPS_NFC
2626 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2628 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2629 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
2631 "<WPS|NDEF> = build configuration token" },
2632 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
2634 "<WPS|NDEF> = create password token" },
2635 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
2636 cli_cmd_flag_sensitive,
2637 "<hexdump of payload> = report read NFC tag with WPS data" },
2638 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
2640 "<NDEF> <WPS> = create NFC handover request" },
2641 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
2643 "<NDEF> <WPS> = create NFC handover select" },
2644 { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL,
2646 "<hexdump of payload> = report received NFC handover select" },
2647 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
2649 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2651 #endif /* CONFIG_WPS_NFC */
2652 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
2653 cli_cmd_flag_sensitive,
2654 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2655 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
2656 cli_cmd_flag_sensitive,
2657 "[params..] = enable/disable AP PIN" },
2658 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
2660 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2661 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
2663 "= stop Wi-Fi Protected Setup External Registrar" },
2664 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
2665 cli_cmd_flag_sensitive,
2666 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2667 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
2669 "<UUID> = accept an Enrollee PBC using External Registrar" },
2670 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
2671 cli_cmd_flag_sensitive,
2672 "<UUID> <PIN> = learn AP configuration" },
2673 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
2675 "<UUID> <network id> = set AP configuration for enrolling" },
2676 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
2677 cli_cmd_flag_sensitive,
2678 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2679 #ifdef CONFIG_WPS_NFC
2680 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
2682 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2683 #endif /* CONFIG_WPS_NFC */
2684 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
2686 "<addr> = request RSN authentication with <addr> in IBSS" },
2688 { "sta", wpa_cli_cmd_sta, NULL,
2690 "<addr> = get information about an associated station (AP)" },
2691 { "all_sta", wpa_cli_cmd_all_sta, NULL,
2693 "= get information about all associated stations (AP)" },
2694 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
2696 "<addr> = deauthenticate a station" },
2697 { "disassociate", wpa_cli_cmd_disassociate, NULL,
2699 "<addr> = disassociate a station" },
2700 { "chan_switch", wpa_cli_cmd_chanswitch, NULL,
2702 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
2703 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
2704 " = CSA parameters" },
2705 #endif /* CONFIG_AP */
2706 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
2707 "= notification of suspend/hibernate" },
2708 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
2709 "= notification of resume/thaw" },
2710 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
2711 "= drop SA without deauth/disassoc (test command)" },
2712 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
2714 "<addr> = roam to the specified BSS" },
2716 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
2718 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2719 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
2720 "= stop P2P Devices search" },
2721 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
2723 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2724 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
2725 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2726 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
2727 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
2728 "<ifname> = remove P2P group interface (terminate group if GO)" },
2729 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
2730 "[ht40] = add a new P2P group (local end as GO)" },
2731 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
2732 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2733 "<addr> <method> = request provisioning discovery" },
2734 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
2736 "= get the passphrase for a group (GO only)" },
2737 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2738 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2739 "<addr> <TLVs> = schedule service discovery request" },
2740 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2741 NULL, cli_cmd_flag_none,
2742 "<id> = cancel pending service discovery request" },
2743 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
2745 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2746 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
2748 "= indicate change in local services" },
2749 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
2751 "<external> = set external processing of service discovery" },
2752 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
2754 "= remove all stored service entries" },
2755 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
2757 "<bonjour|upnp> <query|version> <response|service> = add a local "
2759 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
2761 "<bonjour|upnp> <query|version> [|service] = remove a local "
2763 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
2765 "<addr> = reject connection attempts from a specific peer" },
2766 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
2768 "<cmd> [peer=addr] = invite peer" },
2769 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
2770 "[discovered] = list known (optionally, only fully discovered) P2P "
2772 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
2774 "<address> = show information about known P2P peer" },
2775 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
2777 "<field> <value> = set a P2P parameter" },
2778 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
2779 "= flush P2P state" },
2780 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
2781 "= cancel P2P group formation" },
2782 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
2783 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2784 "<address> = unauthorize a peer" },
2785 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
2787 "[<duration> <interval>] [<duration> <interval>] = request GO "
2789 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
2791 "[<period> <interval>] = set extended listen timing" },
2792 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
2793 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2794 "<address|iface=address> = remove a peer from all groups" },
2795 #endif /* CONFIG_P2P */
2796 #ifdef CONFIG_WIFI_DISPLAY
2797 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
2799 "<subelem> [contents] = set Wi-Fi Display subelement" },
2800 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
2802 "<subelem> = get Wi-Fi Display subelement" },
2803 #endif /* CONFIG_WIFI_DISPLAY */
2804 #ifdef CONFIG_INTERWORKING
2805 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
2806 "= fetch ANQP information for all APs" },
2807 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
2809 "= stop fetch_anqp operation" },
2810 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
2812 "[auto] = perform Interworking network selection" },
2813 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2814 wpa_cli_complete_bss, cli_cmd_flag_none,
2815 "<BSSID> = connect using Interworking credentials" },
2816 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
2818 "<addr> <info id>[,<info id>]... = request ANQP information" },
2819 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
2821 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2822 { "gas_response_get", wpa_cli_cmd_gas_response_get,
2823 wpa_cli_complete_bss, cli_cmd_flag_none,
2824 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2825 #endif /* CONFIG_INTERWORKING */
2827 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
2829 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2831 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
2832 wpa_cli_complete_bss, cli_cmd_flag_none,
2833 "<addr> <home realm> = get HS20 nai home realm list" },
2834 #endif /* CONFIG_HS20 */
2835 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
2837 "<0/1> = disable/enable automatic reconnection" },
2838 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
2840 "<addr> = request TDLS discovery with <addr>" },
2841 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
2843 "<addr> = request TDLS setup with <addr>" },
2844 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
2846 "<addr> = tear down TDLS with <addr>" },
2847 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
2849 "= get signal parameters" },
2850 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
2852 "= get TX/RX packet counters" },
2853 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
2855 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2856 #ifdef CONFIG_AUTOSCAN
2857 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
2858 "[params] = Set or unset (if none) autoscan parameters" },
2859 #endif /* CONFIG_AUTOSCAN */
2861 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
2862 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
2863 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
2864 "<query reason> = Send BSS Transition Management Query" },
2865 #endif /* CONFIG_WNM */
2866 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
2867 "<params..> = Sent unprocessed command" },
2868 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
2869 "= flush wpa_supplicant state" },
2871 { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
2872 "<command> = driver private commands" },
2873 #endif /* ANDROID */
2874 { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
2875 "= radio_work <show/add/done>" },
2876 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
2881 * Prints command usage, lines are padded with the specified string.
2883 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2888 printf("%s%s ", pad, cmd->cmd);
2889 for (n = 0; (c = cmd->usage[n]); n++) {
2898 static void print_help(const char *cmd)
2901 printf("commands:\n");
2902 for (n = 0; wpa_cli_commands[n].cmd; n++) {
2903 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
2904 print_cmd_help(&wpa_cli_commands[n], " ");
2909 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2911 const char *c, *delim;
2915 delim = os_strchr(cmd, ' ');
2919 len = os_strlen(cmd);
2921 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2922 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2923 return (wpa_cli_commands[n].flags &
2924 cli_cmd_flag_sensitive);
2930 static char ** wpa_list_cmd_list(void)
2934 struct cli_txt_entry *e;
2936 count = ARRAY_SIZE(wpa_cli_commands);
2937 count += dl_list_len(&p2p_groups);
2938 count += dl_list_len(&ifnames);
2939 res = os_calloc(count + 1, sizeof(char *));
2943 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2944 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2949 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
2950 size_t len = 8 + os_strlen(e->txt);
2951 res[i] = os_malloc(len);
2954 os_snprintf(res[i], len, "ifname=%s", e->txt);
2958 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
2959 res[i] = os_strdup(e->txt);
2969 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2974 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2975 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2976 if (wpa_cli_commands[i].completion)
2977 return wpa_cli_commands[i].completion(str,
2980 printf("\r%s\n", wpa_cli_commands[i].usage);
2990 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2996 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
2997 end = os_strchr(str, ' ');
2998 if (end && pos > end - str) {
2999 pos -= end - str + 1;
3004 end = os_strchr(str, ' ');
3005 if (end == NULL || str + pos < end)
3006 return wpa_list_cmd_list();
3008 cmd = os_malloc(pos + 1);
3011 os_memcpy(cmd, str, pos);
3012 cmd[end - str] = '\0';
3013 res = wpa_cli_cmd_completion(cmd, str, pos);
3019 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3021 struct wpa_cli_cmd *cmd, *match = NULL;
3025 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
3026 ifname_prefix = argv[0] + 7;
3030 ifname_prefix = NULL;
3036 cmd = wpa_cli_commands;
3038 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3041 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3042 /* we have an exact match */
3052 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3053 cmd = wpa_cli_commands;
3055 if (os_strncasecmp(cmd->cmd, argv[0],
3056 os_strlen(argv[0])) == 0) {
3057 printf(" %s", cmd->cmd);
3063 } else if (count == 0) {
3064 printf("Unknown command '%s'\n", argv[0]);
3067 ret = match->handler(ctrl, argc - 1, &argv[1]);
3074 static int str_match(const char *a, const char *b)
3076 return os_strncmp(a, b, os_strlen(b)) == 0;
3080 static int wpa_cli_exec(const char *program, const char *arg1,
3088 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3089 cmd = os_malloc(len);
3092 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3093 if (res < 0 || (size_t) res >= len) {
3097 cmd[len - 1] = '\0';
3099 if (system(cmd) < 0)
3101 #endif /* _WIN32_WCE */
3108 static void wpa_cli_action_process(const char *msg)
3111 char *copy = NULL, *id, *pos2;
3116 pos = os_strchr(pos, '>');
3123 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3125 os_unsetenv("WPA_ID");
3126 os_unsetenv("WPA_ID_STR");
3127 os_unsetenv("WPA_CTRL_DIR");
3129 pos = os_strstr(pos, "[id=");
3131 copy = os_strdup(pos + 4);
3135 while (*pos2 && *pos2 != ' ')
3139 os_setenv("WPA_ID", id, 1);
3140 while (*pos2 && *pos2 != '=')
3145 while (*pos2 && *pos2 != ']')
3148 os_setenv("WPA_ID_STR", id, 1);
3152 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3154 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
3155 wpa_cli_connected = 1;
3156 wpa_cli_last_id = new_id;
3157 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3159 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3160 if (wpa_cli_connected) {
3161 wpa_cli_connected = 0;
3162 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3164 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3165 wpa_cli_exec(action_file, ctrl_ifname, pos);
3166 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3167 wpa_cli_exec(action_file, ctrl_ifname, pos);
3168 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3169 wpa_cli_exec(action_file, ctrl_ifname, pos);
3170 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3171 wpa_cli_exec(action_file, ctrl_ifname, pos);
3172 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3173 wpa_cli_exec(action_file, ctrl_ifname, pos);
3174 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3175 wpa_cli_exec(action_file, ctrl_ifname, pos);
3176 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3177 wpa_cli_exec(action_file, ctrl_ifname, pos);
3178 } else if (str_match(pos, AP_STA_CONNECTED)) {
3179 wpa_cli_exec(action_file, ctrl_ifname, pos);
3180 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3181 wpa_cli_exec(action_file, ctrl_ifname, pos);
3182 } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
3183 wpa_cli_exec(action_file, ctrl_ifname, pos);
3184 } else if (str_match(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
3185 wpa_cli_exec(action_file, ctrl_ifname, pos);
3186 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3187 printf("wpa_supplicant is terminating - stop monitoring\n");
3193 #ifndef CONFIG_ANSI_C_EXTRA
3194 static void wpa_cli_action_cb(char *msg, size_t len)
3196 wpa_cli_action_process(msg);
3198 #endif /* CONFIG_ANSI_C_EXTRA */
3201 static void wpa_cli_reconnect(void)
3203 wpa_cli_close_connection();
3204 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3209 printf("\rConnection to wpa_supplicant re-established\n");
3215 static void cli_event(const char *str)
3217 const char *start, *s;
3219 start = os_strchr(str, '>');
3225 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3226 s = os_strchr(start, ' ');
3229 s = os_strchr(s + 1, ' ');
3232 cli_txt_list_add(&bsses, s + 1);
3236 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3237 s = os_strchr(start, ' ');
3240 s = os_strchr(s + 1, ' ');
3243 cli_txt_list_del_addr(&bsses, s + 1);
3248 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3249 s = os_strstr(start, " p2p_dev_addr=");
3252 cli_txt_list_add_addr(&p2p_peers, s + 14);
3256 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3257 s = os_strstr(start, " p2p_dev_addr=");
3260 cli_txt_list_del_addr(&p2p_peers, s + 14);
3264 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3265 s = os_strchr(start, ' ');
3268 cli_txt_list_add_word(&p2p_groups, s + 1);
3272 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3273 s = os_strchr(start, ' ');
3276 cli_txt_list_del_word(&p2p_groups, s + 1);
3279 #endif /* CONFIG_P2P */
3283 static int check_terminating(const char *msg)
3285 const char *pos = msg;
3289 pos = os_strchr(pos, '>');
3296 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3298 printf("\rConnection to wpa_supplicant lost - trying to "
3301 wpa_cli_attached = 0;
3302 wpa_cli_close_connection();
3310 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3312 if (ctrl_conn == NULL) {
3313 wpa_cli_reconnect();
3316 while (wpa_ctrl_pending(ctrl) > 0) {
3318 size_t len = sizeof(buf) - 1;
3319 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3322 wpa_cli_action_process(buf);
3325 if (wpa_cli_show_event(buf)) {
3327 printf("\r%s\n", buf);
3331 if (interactive && check_terminating(buf) > 0)
3335 printf("Could not read pending message.\n");
3340 if (wpa_ctrl_pending(ctrl) < 0) {
3341 printf("Connection to wpa_supplicant lost - trying to "
3343 wpa_cli_reconnect();
3349 static int tokenize_cmd(char *cmd, char *argv[])
3362 if (argc == max_args)
3365 char *pos2 = os_strrchr(pos, '"');
3369 while (*pos != '\0' && *pos != ' ')
3379 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3381 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3382 printf("Connection to wpa_supplicant lost - trying to "
3384 wpa_cli_close_connection();
3387 wpa_cli_reconnect();
3388 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3392 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3394 wpa_cli_recv_pending(mon_conn, 0);
3398 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3400 char *argv[max_args];
3402 argc = tokenize_cmd(cmd, argv);
3404 wpa_request(ctrl_conn, argc, argv);
3408 static void wpa_cli_edit_eof_cb(void *ctx)
3414 static int warning_displayed = 0;
3415 static char *hfile = NULL;
3416 static int edit_started = 0;
3418 static void start_edit(void)
3423 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3424 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3425 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3427 home = getenv("HOME");
3429 const char *fname = ".wpa_cli_history";
3430 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3431 hfile = os_malloc(hfile_len);
3433 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3436 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3437 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3443 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3447 static void update_bssid_list(struct wpa_ctrl *ctrl)
3450 size_t len = sizeof(buf);
3452 char *cmd = "BSS RANGE=ALL MASK=0x2";
3457 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3464 pos = os_strstr(pos, "bssid=");
3468 end = os_strchr(pos, '\n');
3472 cli_txt_list_add(&bsses, pos);
3478 static void update_ifnames(struct wpa_ctrl *ctrl)
3481 size_t len = sizeof(buf);
3483 char *cmd = "INTERFACES";
3487 cli_txt_list_flush(&ifnames);
3491 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3498 end = os_strchr(pos, '\n');
3502 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
3503 if (ret > 0 && ret < (int) sizeof(txt))
3504 cli_txt_list_add(&ifnames, txt);
3510 static void try_connection(void *eloop_ctx, void *timeout_ctx)
3515 if (ctrl_ifname == NULL)
3516 ctrl_ifname = wpa_cli_get_default_ifname();
3518 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3519 if (!warning_displayed) {
3520 printf("Could not connect to wpa_supplicant: "
3521 "%s - re-trying\n", ctrl_ifname);
3522 warning_displayed = 1;
3524 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
3528 update_bssid_list(ctrl_conn);
3530 if (warning_displayed)
3531 printf("Connection established.\n");
3538 static void wpa_cli_interactive(void)
3540 printf("\nInteractive mode\n\n");
3542 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
3544 eloop_cancel_timeout(try_connection, NULL, NULL);
3546 cli_txt_list_flush(&p2p_peers);
3547 cli_txt_list_flush(&p2p_groups);
3548 cli_txt_list_flush(&bsses);
3549 cli_txt_list_flush(&ifnames);
3551 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3553 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3554 wpa_cli_close_connection();
3558 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3560 #ifdef CONFIG_ANSI_C_EXTRA
3561 /* TODO: ANSI C version(?) */
3562 printf("Action processing not supported in ANSI C build.\n");
3563 #else /* CONFIG_ANSI_C_EXTRA */
3567 char buf[256]; /* note: large enough to fit in unsolicited messages */
3570 fd = wpa_ctrl_get_fd(ctrl);
3572 while (!wpa_cli_quit) {
3575 tv.tv_sec = ping_interval;
3577 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3578 if (res < 0 && errno != EINTR) {
3583 if (FD_ISSET(fd, &rfds))
3584 wpa_cli_recv_pending(ctrl, 1);
3586 /* verify that connection is still working */
3587 len = sizeof(buf) - 1;
3588 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3589 wpa_cli_action_cb) < 0 ||
3590 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3591 printf("wpa_supplicant did not reply to PING "
3592 "command - exiting\n");
3597 #endif /* CONFIG_ANSI_C_EXTRA */
3601 static void wpa_cli_cleanup(void)
3603 wpa_cli_close_connection();
3605 os_daemonize_terminate(pid_file);
3607 os_program_deinit();
3611 static void wpa_cli_terminate(int sig, void *ctx)
3617 static char * wpa_cli_get_default_ifname(void)
3619 char *ifname = NULL;
3621 #ifdef CONFIG_CTRL_IFACE_UNIX
3622 struct dirent *dent;
3623 DIR *dir = opendir(ctrl_iface_dir);
3626 char ifprop[PROPERTY_VALUE_MAX];
3627 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3628 ifname = os_strdup(ifprop);
3629 printf("Using interface '%s'\n", ifname);
3632 #endif /* ANDROID */
3635 while ((dent = readdir(dir))) {
3636 #ifdef _DIRENT_HAVE_D_TYPE
3638 * Skip the file if it is not a socket. Also accept
3639 * DT_UNKNOWN (0) in case the C library or underlying
3640 * file system does not support d_type.
3642 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3644 #endif /* _DIRENT_HAVE_D_TYPE */
3645 if (os_strcmp(dent->d_name, ".") == 0 ||
3646 os_strcmp(dent->d_name, "..") == 0)
3648 printf("Selected interface '%s'\n", dent->d_name);
3649 ifname = os_strdup(dent->d_name);
3653 #endif /* CONFIG_CTRL_IFACE_UNIX */
3655 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3656 char buf[4096], *pos;
3658 struct wpa_ctrl *ctrl;
3661 ctrl = wpa_ctrl_open(NULL);
3665 len = sizeof(buf) - 1;
3666 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3669 pos = os_strchr(buf, '\n');
3672 ifname = os_strdup(buf);
3674 wpa_ctrl_close(ctrl);
3675 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3681 int main(int argc, char *argv[])
3686 const char *global = NULL;
3688 if (os_program_init())
3692 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3697 action_file = optarg;
3706 ping_interval = atoi(optarg);
3712 printf("%s\n", wpa_cli_version);
3715 os_free(ctrl_ifname);
3716 ctrl_ifname = os_strdup(optarg);
3719 ctrl_iface_dir = optarg;
3730 interactive = (argc == optind) && (action_file == NULL);
3733 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3739 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3740 ctrl_conn = wpa_ctrl_open(NULL);
3741 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3742 ctrl_conn = wpa_ctrl_open(global);
3743 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3744 if (ctrl_conn == NULL) {
3745 fprintf(stderr, "Failed to connect to wpa_supplicant "
3746 "global interface: %s error: %s\n",
3747 global, strerror(errno));
3752 update_ifnames(ctrl_conn);
3753 mon_conn = wpa_ctrl_open(global);
3755 if (wpa_ctrl_attach(mon_conn) == 0) {
3756 wpa_cli_attached = 1;
3757 eloop_register_read_sock(
3758 wpa_ctrl_get_fd(mon_conn),
3759 wpa_cli_mon_receive,
3762 printf("Failed to open monitor "
3763 "connection through global "
3764 "control interface\n");
3770 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
3772 if (ctrl_ifname == NULL)
3773 ctrl_ifname = wpa_cli_get_default_ifname();
3776 wpa_cli_interactive();
3779 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3780 fprintf(stderr, "Failed to connect to non-global "
3781 "ctrl_ifname: %s error: %s\n",
3782 ctrl_ifname, strerror(errno));
3787 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3788 wpa_cli_attached = 1;
3790 printf("Warning: Failed to attach to "
3791 "wpa_supplicant.\n");
3796 if (daemonize && os_daemonize(pid_file))
3800 wpa_cli_action(ctrl_conn);
3802 ret = wpa_request(ctrl_conn, argc - optind,
3806 os_free(ctrl_ifname);
3813 #else /* CONFIG_CTRL_IFACE */
3814 int main(int argc, char *argv[])
3816 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3819 #endif /* CONFIG_CTRL_IFACE */