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-2013, 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",
620 "p2p_ignore_shared_freq", "country", "bss_max_count",
621 "bss_expiration_age", "bss_expiration_scan_count",
622 "filter_ssids", "filter_rssi", "max_num_sta",
623 "disassoc_low_ack", "hs20", "interworking", "hessid",
624 "access_network_type", "pbc_in_m1", "autoscan",
625 "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", "wps_nfc_dh_privkey",
626 "wps_nfc_dev_pw", "ext_password_backend",
627 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
628 "sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
629 "ignore_old_scan_res", "freq_list", "external_sim"
631 int i, num_fields = ARRAY_SIZE(fields);
634 char **res = os_calloc(num_fields + 1, sizeof(char *));
637 for (i = 0; i < num_fields; i++) {
638 res[i] = os_strdup(fields[i]);
645 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
646 return cli_txt_list_array(&bsses);
652 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
654 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
658 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
660 return wpa_ctrl_command(ctrl, "LOGOFF");
664 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
666 return wpa_ctrl_command(ctrl, "LOGON");
670 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
673 return wpa_ctrl_command(ctrl, "REASSOCIATE");
677 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
680 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
684 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
686 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
690 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
693 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
697 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
700 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
704 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
707 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
711 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
717 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
719 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
720 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
721 printf("Too long BSS_FLUSH command.\n");
724 return wpa_ctrl_command(ctrl, cmd);
728 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
731 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
735 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
737 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
741 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
743 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
747 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
750 printf("Invalid WPS_PIN command: need one or two arguments:\n"
751 "- BSSID: use 'any' to select any\n"
752 "- PIN: optional, used only with devices that have no "
757 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
761 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
764 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
768 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
771 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
775 #ifdef CONFIG_WPS_NFC
777 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
779 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
783 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
786 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
790 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
793 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
797 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
805 printf("Invalid 'wps_nfc_tag_read' command - one argument "
810 buflen = 18 + os_strlen(argv[0]);
811 buf = os_malloc(buflen);
814 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
816 ret = wpa_ctrl_command(ctrl, buf);
823 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
826 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
830 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
833 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
837 static int wpa_cli_cmd_nfc_rx_handover_req(struct wpa_ctrl *ctrl, int argc,
845 printf("Invalid 'nfc_rx_handover_req' command - one argument "
850 buflen = 21 + os_strlen(argv[0]);
851 buf = os_malloc(buflen);
854 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_REQ %s", argv[0]);
856 ret = wpa_ctrl_command(ctrl, buf);
863 static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl *ctrl, int argc,
871 printf("Invalid 'nfc_rx_handover_sel' command - one argument "
876 buflen = 21 + os_strlen(argv[0]);
877 buf = os_malloc(buflen);
880 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_SEL %s", argv[0]);
882 ret = wpa_ctrl_command(ctrl, buf);
889 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
892 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
895 #endif /* CONFIG_WPS_NFC */
898 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
904 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
906 else if (argc == 5 || argc == 6) {
907 char ssid_hex[2 * 32 + 1];
908 char key_hex[2 * 64 + 1];
912 for (i = 0; i < 32; i++) {
913 if (argv[2][i] == '\0')
915 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
920 for (i = 0; i < 64; i++) {
921 if (argv[5][i] == '\0')
923 os_snprintf(&key_hex[i * 2], 3, "%02x",
928 res = os_snprintf(cmd, sizeof(cmd),
929 "WPS_REG %s %s %s %s %s %s",
930 argv[0], argv[1], ssid_hex, argv[3], argv[4],
933 printf("Invalid WPS_REG command: need two arguments:\n"
934 "- BSSID of the target AP\n"
936 printf("Alternatively, six arguments can be used to "
937 "reconfigure the AP:\n"
938 "- BSSID of the target AP\n"
941 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
942 "- new encr (NONE, WEP, TKIP, CCMP)\n"
947 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
948 printf("Too long WPS_REG command.\n");
951 return wpa_ctrl_command(ctrl, cmd);
955 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
958 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
962 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
965 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
969 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
972 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
977 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
981 printf("Invalid WPS_ER_PIN command: need at least two "
983 "- UUID: use 'any' to select any\n"
984 "- PIN: Enrollee PIN\n"
985 "optional: - Enrollee MAC address\n");
989 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
993 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
996 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
1000 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1004 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1005 "- UUID: specify which AP to use\n"
1010 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
1014 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1018 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1020 "- UUID: specify which AP to use\n"
1021 "- Network configuration id\n");
1025 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
1029 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1035 if (argc == 5 || argc == 6) {
1036 char ssid_hex[2 * 32 + 1];
1037 char key_hex[2 * 64 + 1];
1041 for (i = 0; i < 32; i++) {
1042 if (argv[2][i] == '\0')
1044 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1049 for (i = 0; i < 64; i++) {
1050 if (argv[5][i] == '\0')
1052 os_snprintf(&key_hex[i * 2], 3, "%02x",
1057 res = os_snprintf(cmd, sizeof(cmd),
1058 "WPS_ER_CONFIG %s %s %s %s %s %s",
1059 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1062 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1066 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1067 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1072 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1073 printf("Too long WPS_ER_CONFIG command.\n");
1076 return wpa_ctrl_command(ctrl, cmd);
1080 #ifdef CONFIG_WPS_NFC
1081 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1085 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1087 "- WPS/NDEF: token format\n"
1088 "- UUID: specify which AP to use\n");
1092 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1094 #endif /* CONFIG_WPS_NFC */
1097 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1099 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1103 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1105 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1109 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1111 char cmd[256], *pos, *end;
1115 printf("Invalid IDENTITY command: needs two arguments "
1116 "(network id and identity)\n");
1120 end = cmd + sizeof(cmd);
1122 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1124 if (ret < 0 || ret >= end - pos) {
1125 printf("Too long IDENTITY command.\n");
1129 for (i = 2; i < argc; i++) {
1130 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1131 if (ret < 0 || ret >= end - pos) {
1132 printf("Too long IDENTITY command.\n");
1138 return wpa_ctrl_command(ctrl, cmd);
1142 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1144 char cmd[256], *pos, *end;
1148 printf("Invalid PASSWORD command: needs two arguments "
1149 "(network id and password)\n");
1153 end = cmd + sizeof(cmd);
1155 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1157 if (ret < 0 || ret >= end - pos) {
1158 printf("Too long PASSWORD command.\n");
1162 for (i = 2; i < argc; i++) {
1163 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1164 if (ret < 0 || ret >= end - pos) {
1165 printf("Too long PASSWORD command.\n");
1171 return wpa_ctrl_command(ctrl, cmd);
1175 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1178 char cmd[256], *pos, *end;
1182 printf("Invalid NEW_PASSWORD command: needs two arguments "
1183 "(network id and password)\n");
1187 end = cmd + sizeof(cmd);
1189 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1191 if (ret < 0 || ret >= end - pos) {
1192 printf("Too long NEW_PASSWORD command.\n");
1196 for (i = 2; i < argc; i++) {
1197 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1198 if (ret < 0 || ret >= end - pos) {
1199 printf("Too long NEW_PASSWORD command.\n");
1205 return wpa_ctrl_command(ctrl, cmd);
1209 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1211 char cmd[256], *pos, *end;
1215 printf("Invalid PIN command: needs two arguments "
1216 "(network id and pin)\n");
1220 end = cmd + sizeof(cmd);
1222 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1224 if (ret < 0 || ret >= end - pos) {
1225 printf("Too long PIN command.\n");
1229 for (i = 2; i < argc; i++) {
1230 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1231 if (ret < 0 || ret >= end - pos) {
1232 printf("Too long PIN command.\n");
1237 return wpa_ctrl_command(ctrl, cmd);
1241 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1243 char cmd[256], *pos, *end;
1247 printf("Invalid OTP command: needs two arguments (network "
1248 "id and password)\n");
1252 end = cmd + sizeof(cmd);
1254 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1256 if (ret < 0 || ret >= end - pos) {
1257 printf("Too long OTP command.\n");
1261 for (i = 2; i < argc; i++) {
1262 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1263 if (ret < 0 || ret >= end - pos) {
1264 printf("Too long OTP command.\n");
1270 return wpa_ctrl_command(ctrl, cmd);
1274 static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
1276 char cmd[256], *pos, *end;
1280 printf("Invalid SIM command: needs two arguments "
1281 "(network id and SIM operation response)\n");
1285 end = cmd + sizeof(cmd);
1287 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
1289 if (ret < 0 || ret >= end - pos) {
1290 printf("Too long SIM command.\n");
1294 for (i = 2; i < argc; i++) {
1295 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1296 if (ret < 0 || ret >= end - pos) {
1297 printf("Too long SIM command.\n");
1302 return wpa_ctrl_command(ctrl, cmd);
1306 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1309 char cmd[256], *pos, *end;
1313 printf("Invalid PASSPHRASE command: needs two arguments "
1314 "(network id and passphrase)\n");
1318 end = cmd + sizeof(cmd);
1320 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1322 if (ret < 0 || ret >= end - pos) {
1323 printf("Too long PASSPHRASE command.\n");
1327 for (i = 2; i < argc; i++) {
1328 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1329 if (ret < 0 || ret >= end - pos) {
1330 printf("Too long PASSPHRASE command.\n");
1336 return wpa_ctrl_command(ctrl, cmd);
1340 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1343 printf("Invalid BSSID command: needs two arguments (network "
1348 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1352 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1354 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1358 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1360 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1364 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1367 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1371 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1374 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1378 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1381 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1385 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1388 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1392 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1395 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1399 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1402 return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1406 static void wpa_cli_show_network_variables(void)
1408 printf("set_network variables:\n"
1409 " ssid (network name, SSID)\n"
1410 " psk (WPA passphrase or pre-shared key)\n"
1411 " key_mgmt (key management protocol)\n"
1412 " identity (EAP identity)\n"
1413 " password (EAP password)\n"
1416 "Note: Values are entered in the same format as the "
1417 "configuration file is using,\n"
1418 "i.e., strings values need to be inside double quotation "
1420 "For example: set_network 1 ssid \"network name\"\n"
1422 "Please see wpa_supplicant.conf documentation for full list "
1423 "of\navailable variables.\n");
1427 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1431 wpa_cli_show_network_variables();
1436 printf("Invalid SET_NETWORK command: needs three arguments\n"
1437 "(network id, variable name, and value)\n");
1441 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1445 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1449 wpa_cli_show_network_variables();
1454 printf("Invalid GET_NETWORK command: needs two arguments\n"
1455 "(network id and variable name)\n");
1459 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1463 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1466 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1470 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1472 return wpa_ctrl_command(ctrl, "ADD_CRED");
1476 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1479 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1483 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1486 printf("Invalid SET_CRED command: needs three arguments\n"
1487 "(cred id, variable name, and value)\n");
1491 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1495 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1498 return wpa_ctrl_command(ctrl, "DISCONNECT");
1502 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1505 return wpa_ctrl_command(ctrl, "RECONNECT");
1509 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1512 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1516 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1518 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1522 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1525 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1529 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1531 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1535 static char ** wpa_cli_complete_bss(const char *str, int pos)
1537 int arg = get_cmd_arg_num(str, pos);
1542 res = cli_txt_list_array(&bsses);
1550 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1553 if (argc < 1 || argc > 2) {
1554 printf("Invalid GET_CAPABILITY command: need either one or "
1559 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1560 printf("Invalid GET_CAPABILITY command: second argument, "
1561 "if any, must be 'strict'\n");
1565 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1569 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1571 printf("Available interfaces:\n");
1572 return wpa_ctrl_command(ctrl, "INTERFACES");
1576 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1579 wpa_cli_list_interfaces(ctrl);
1583 wpa_cli_close_connection();
1584 os_free(ctrl_ifname);
1585 ctrl_ifname = os_strdup(argv[0]);
1587 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1588 printf("Connected to interface '%s.\n", ctrl_ifname);
1590 printf("Could not connect to interface '%s' - re-trying\n",
1597 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1600 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1604 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1607 return wpa_ctrl_command(ctrl, "TERMINATE");
1611 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1618 printf("Invalid INTERFACE_ADD command: needs at least one "
1619 "argument (interface name)\n"
1620 "All arguments: ifname confname driver ctrl_interface "
1621 "driver_param bridge_name\n");
1626 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1627 * <driver_param>TAB<bridge_name>
1629 res = os_snprintf(cmd, sizeof(cmd),
1630 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1632 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1633 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1634 argc > 5 ? argv[5] : "");
1635 if (res < 0 || (size_t) res >= sizeof(cmd))
1637 cmd[sizeof(cmd) - 1] = '\0';
1638 return wpa_ctrl_command(ctrl, cmd);
1642 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1645 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1649 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1652 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1657 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1659 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1663 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1664 char *addr, size_t addr_len)
1666 char buf[4096], *pos;
1670 if (ctrl_conn == NULL) {
1671 printf("Not connected to hostapd - command dropped.\n");
1674 len = sizeof(buf) - 1;
1675 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1678 printf("'%s' command timed out.\n", cmd);
1680 } else if (ret < 0) {
1681 printf("'%s' command failed.\n", cmd);
1686 if (os_memcmp(buf, "FAIL", 4) == 0)
1691 while (*pos != '\0' && *pos != '\n')
1694 os_strlcpy(addr, buf, addr_len);
1699 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1701 char addr[32], cmd[64];
1703 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1706 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1707 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1713 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1716 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1720 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1723 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, 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 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1742 return wpa_ctrl_command(ctrl, "DROP_SA");
1746 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1748 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1754 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1756 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1760 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1763 int arg = get_cmd_arg_num(str, pos);
1765 res = os_calloc(6, sizeof(char *));
1768 res[0] = os_strdup("type=social");
1769 if (res[0] == NULL) {
1773 res[1] = os_strdup("type=progressive");
1776 res[2] = os_strdup("delay=");
1779 res[3] = os_strdup("dev_id=");
1783 res[4] = os_strdup("[timeout]");
1789 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1792 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1796 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1799 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
1803 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1805 int arg = get_cmd_arg_num(str, pos);
1810 res = cli_txt_list_array(&p2p_peers);
1818 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1821 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
1825 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1828 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
1832 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
1834 int arg = get_cmd_arg_num(str, pos);
1839 res = cli_txt_list_array(&p2p_groups);
1847 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1850 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
1854 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1857 if (argc != 2 && argc != 3) {
1858 printf("Invalid P2P_PROV_DISC command: needs at least "
1859 "two arguments, address and config method\n"
1860 "(display, keypad, or pbc) and an optional join\n");
1864 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
1868 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1871 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1875 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1880 if (argc != 2 && argc != 4) {
1881 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1882 "arguments (address and TLVs) or four arguments "
1883 "(address, \"upnp\", version, search target "
1888 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
1890 return wpa_ctrl_command(ctrl, cmd);
1894 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1895 int argc, char *argv[])
1897 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
1901 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1908 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1909 "arguments (freq, address, dialog token, and TLVs)\n");
1913 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1914 argv[0], argv[1], argv[2], argv[3]);
1915 if (res < 0 || (size_t) res >= sizeof(cmd))
1917 cmd[sizeof(cmd) - 1] = '\0';
1918 return wpa_ctrl_command(ctrl, cmd);
1922 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1925 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1929 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1930 int argc, char *argv[])
1932 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
1936 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1939 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1943 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1949 if (argc != 3 && argc != 4) {
1950 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1956 res = os_snprintf(cmd, sizeof(cmd),
1957 "P2P_SERVICE_ADD %s %s %s %s",
1958 argv[0], argv[1], argv[2], argv[3]);
1960 res = os_snprintf(cmd, sizeof(cmd),
1961 "P2P_SERVICE_ADD %s %s %s",
1962 argv[0], argv[1], argv[2]);
1963 if (res < 0 || (size_t) res >= sizeof(cmd))
1965 cmd[sizeof(cmd) - 1] = '\0';
1966 return wpa_ctrl_command(ctrl, cmd);
1970 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1976 if (argc != 2 && argc != 3) {
1977 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1983 res = os_snprintf(cmd, sizeof(cmd),
1984 "P2P_SERVICE_DEL %s %s %s",
1985 argv[0], argv[1], argv[2]);
1987 res = os_snprintf(cmd, sizeof(cmd),
1988 "P2P_SERVICE_DEL %s %s",
1990 if (res < 0 || (size_t) res >= sizeof(cmd))
1992 cmd[sizeof(cmd) - 1] = '\0';
1993 return wpa_ctrl_command(ctrl, cmd);
1997 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1998 int argc, char *argv[])
2000 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
2004 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2005 int argc, char *argv[])
2007 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
2011 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2013 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2017 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2019 int arg = get_cmd_arg_num(str, pos);
2024 res = cli_txt_list_array(&p2p_peers);
2032 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2033 char *addr, size_t addr_len,
2036 char buf[4096], *pos;
2040 if (ctrl_conn == NULL)
2042 len = sizeof(buf) - 1;
2043 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2046 printf("'%s' command timed out.\n", cmd);
2048 } else if (ret < 0) {
2049 printf("'%s' command failed.\n", cmd);
2054 if (os_memcmp(buf, "FAIL", 4) == 0)
2058 while (*pos != '\0' && *pos != '\n')
2061 os_strlcpy(addr, buf, addr_len);
2062 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2063 printf("%s\n", addr);
2068 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2070 char addr[32], cmd[64];
2073 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2075 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2076 addr, sizeof(addr), discovered))
2079 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2080 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2087 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2089 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2093 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
2095 int arg = get_cmd_arg_num(str, pos);
2096 const char *fields[] = {
2116 int i, num_fields = ARRAY_SIZE(fields);
2119 char **res = os_calloc(num_fields + 1, sizeof(char *));
2122 for (i = 0; i < num_fields; i++) {
2123 res[i] = os_strdup(fields[i]);
2130 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
2131 return cli_txt_list_array(&p2p_peers);
2137 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2139 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2143 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2146 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2150 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2153 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2157 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2160 if (argc != 0 && argc != 2 && argc != 4) {
2161 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2162 "(preferred duration, interval; in microsecods).\n"
2163 "Optional second pair can be used to provide "
2164 "acceptable values.\n");
2168 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2172 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2175 if (argc != 0 && argc != 2) {
2176 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2177 "(availability period, availability interval; in "
2179 "Extended Listen Timing can be cancelled with this "
2180 "command when used without parameters.\n");
2184 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2188 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
2191 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
2194 #endif /* CONFIG_P2P */
2196 #ifdef CONFIG_WIFI_DISPLAY
2198 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2204 if (argc != 1 && argc != 2) {
2205 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2206 "arguments (subelem, hexdump)\n");
2210 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2211 argv[0], argc > 1 ? argv[1] : "");
2212 if (res < 0 || (size_t) res >= sizeof(cmd))
2214 cmd[sizeof(cmd) - 1] = '\0';
2215 return wpa_ctrl_command(ctrl, cmd);
2219 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2226 printf("Invalid WFD_SUBELEM_GET command: needs one "
2227 "argument (subelem)\n");
2231 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2233 if (res < 0 || (size_t) res >= sizeof(cmd))
2235 cmd[sizeof(cmd) - 1] = '\0';
2236 return wpa_ctrl_command(ctrl, cmd);
2238 #endif /* CONFIG_WIFI_DISPLAY */
2241 #ifdef CONFIG_INTERWORKING
2242 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2245 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2249 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2252 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2256 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2259 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2263 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2266 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2270 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2272 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2276 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2279 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2283 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2286 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2288 #endif /* CONFIG_INTERWORKING */
2293 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2296 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2300 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2306 printf("Command needs one or two arguments (dst mac addr and "
2307 "optional home realm)\n");
2311 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2315 return wpa_ctrl_command(ctrl, cmd);
2318 #endif /* CONFIG_HS20 */
2321 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2324 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2328 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2331 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2335 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2338 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2342 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2345 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2349 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2352 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2356 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2359 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2363 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2366 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2370 #ifdef CONFIG_AUTOSCAN
2372 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2375 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2377 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2380 #endif /* CONFIG_AUTOSCAN */
2385 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2387 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2391 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2393 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2396 #endif /* CONFIG_WNM */
2399 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2403 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2407 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2409 return wpa_ctrl_command(ctrl, "FLUSH");
2413 enum wpa_cli_cmd_flags {
2414 cli_cmd_flag_none = 0x00,
2415 cli_cmd_flag_sensitive = 0x01
2418 struct wpa_cli_cmd {
2420 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2421 char ** (*completion)(const char *str, int pos);
2422 enum wpa_cli_cmd_flags flags;
2426 static struct wpa_cli_cmd wpa_cli_commands[] = {
2427 { "status", wpa_cli_cmd_status, NULL,
2429 "[verbose] = get current WPA/EAPOL/EAP status" },
2430 { "ifname", wpa_cli_cmd_ifname, NULL,
2432 "= get current interface name" },
2433 { "ping", wpa_cli_cmd_ping, NULL,
2435 "= pings wpa_supplicant" },
2436 { "relog", wpa_cli_cmd_relog, NULL,
2438 "= re-open log-file (allow rolling logs)" },
2439 { "note", wpa_cli_cmd_note, NULL,
2441 "<text> = add a note to wpa_supplicant debug log" },
2442 { "mib", wpa_cli_cmd_mib, NULL,
2444 "= get MIB variables (dot1x, dot11)" },
2445 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2447 "[command] = show usage help" },
2448 { "interface", wpa_cli_cmd_interface, NULL,
2450 "[ifname] = show interfaces/select interface" },
2451 { "level", wpa_cli_cmd_level, NULL,
2453 "<debug level> = change debug level" },
2454 { "license", wpa_cli_cmd_license, NULL,
2456 "= show full wpa_cli license" },
2457 { "quit", wpa_cli_cmd_quit, NULL,
2460 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2462 "= set variables (shows list of variables when run without "
2464 { "get", wpa_cli_cmd_get, NULL,
2466 "<name> = get information" },
2467 { "logon", wpa_cli_cmd_logon, NULL,
2469 "= IEEE 802.1X EAPOL state machine logon" },
2470 { "logoff", wpa_cli_cmd_logoff, NULL,
2472 "= IEEE 802.1X EAPOL state machine logoff" },
2473 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2475 "= show PMKSA cache" },
2476 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2478 "= force reassociation" },
2479 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2481 "<BSSID> = force preauthentication" },
2482 { "identity", wpa_cli_cmd_identity, NULL,
2484 "<network id> <identity> = configure identity for an SSID" },
2485 { "password", wpa_cli_cmd_password, NULL,
2486 cli_cmd_flag_sensitive,
2487 "<network id> <password> = configure password for an SSID" },
2488 { "new_password", wpa_cli_cmd_new_password, NULL,
2489 cli_cmd_flag_sensitive,
2490 "<network id> <password> = change password for an SSID" },
2491 { "pin", wpa_cli_cmd_pin, NULL,
2492 cli_cmd_flag_sensitive,
2493 "<network id> <pin> = configure pin for an SSID" },
2494 { "otp", wpa_cli_cmd_otp, NULL,
2495 cli_cmd_flag_sensitive,
2496 "<network id> <password> = configure one-time-password for an SSID"
2498 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2499 cli_cmd_flag_sensitive,
2500 "<network id> <passphrase> = configure private key passphrase\n"
2502 { "sim", wpa_cli_cmd_sim, NULL,
2503 cli_cmd_flag_sensitive,
2504 "<network id> <pin> = report SIM operation result" },
2505 { "bssid", wpa_cli_cmd_bssid, NULL,
2507 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2508 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2510 "<BSSID> = add a BSSID to the blacklist\n"
2511 "blacklist clear = clear the blacklist\n"
2512 "blacklist = display the blacklist" },
2513 { "log_level", wpa_cli_cmd_log_level, NULL,
2515 "<level> [<timestamp>] = update the log level/timestamp\n"
2516 "log_level = display the current log level and log options" },
2517 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2519 "= list configured networks" },
2520 { "select_network", wpa_cli_cmd_select_network, NULL,
2522 "<network id> = select a network (disable others)" },
2523 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2525 "<network id> = enable a network" },
2526 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2528 "<network id> = disable a network" },
2529 { "add_network", wpa_cli_cmd_add_network, NULL,
2531 "= add a network" },
2532 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2534 "<network id> = remove a network" },
2535 { "set_network", wpa_cli_cmd_set_network, NULL,
2536 cli_cmd_flag_sensitive,
2537 "<network id> <variable> <value> = set network variables (shows\n"
2538 " list of variables when run without arguments)" },
2539 { "get_network", wpa_cli_cmd_get_network, NULL,
2541 "<network id> <variable> = get network variables" },
2542 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2544 "= list configured credentials" },
2545 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2547 "= add a credential" },
2548 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2550 "<cred id> = remove a credential" },
2551 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2552 cli_cmd_flag_sensitive,
2553 "<cred id> <variable> <value> = set credential variables" },
2554 { "save_config", wpa_cli_cmd_save_config, NULL,
2556 "= save the current configuration" },
2557 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2559 "= disconnect and wait for reassociate/reconnect command before\n"
2561 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2563 "= like reassociate, but only takes effect if already disconnected"
2565 { "scan", wpa_cli_cmd_scan, NULL,
2567 "= request new BSS scan" },
2568 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2570 "= get latest scan results" },
2571 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2573 "<<idx> | <bssid>> = get detailed scan result info" },
2574 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2576 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2577 "= get capabilies" },
2578 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2580 "= force wpa_supplicant to re-read its configuration file" },
2581 { "terminate", wpa_cli_cmd_terminate, NULL,
2583 "= terminate wpa_supplicant" },
2584 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2586 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2587 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2589 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2591 "<ifname> = removes the interface" },
2592 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2594 "= list available interfaces" },
2595 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2597 "<value> = set ap_scan parameter" },
2598 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2600 "<value> = set scan_interval parameter (in seconds)" },
2601 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2603 "<value> = set BSS expiration age parameter" },
2604 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2606 "<value> = set BSS expiration scan count parameter" },
2607 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2609 "<value> = set BSS flush age (0 by default)" },
2610 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2612 "<addr> = request STK negotiation with <addr>" },
2613 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2615 "<addr> = request over-the-DS FT with <addr>" },
2616 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2618 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2619 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2620 cli_cmd_flag_sensitive,
2621 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2623 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2624 cli_cmd_flag_sensitive,
2625 "<PIN> = verify PIN checksum" },
2626 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2627 "Cancels the pending WPS operation" },
2628 #ifdef CONFIG_WPS_NFC
2629 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2631 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2632 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
2634 "<WPS|NDEF> = build configuration token" },
2635 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
2637 "<WPS|NDEF> = create password token" },
2638 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
2639 cli_cmd_flag_sensitive,
2640 "<hexdump of payload> = report read NFC tag with WPS data" },
2641 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
2643 "<NDEF> <WPS> = create NFC handover request" },
2644 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
2646 "<NDEF> <WPS> = create NFC handover select" },
2647 { "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req, NULL,
2649 "<hexdump of payload> = report received NFC handover request" },
2650 { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL,
2652 "<hexdump of payload> = report received NFC handover select" },
2653 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
2655 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2657 #endif /* CONFIG_WPS_NFC */
2658 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
2659 cli_cmd_flag_sensitive,
2660 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2661 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
2662 cli_cmd_flag_sensitive,
2663 "[params..] = enable/disable AP PIN" },
2664 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
2666 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2667 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
2669 "= stop Wi-Fi Protected Setup External Registrar" },
2670 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
2671 cli_cmd_flag_sensitive,
2672 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2673 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
2675 "<UUID> = accept an Enrollee PBC using External Registrar" },
2676 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
2677 cli_cmd_flag_sensitive,
2678 "<UUID> <PIN> = learn AP configuration" },
2679 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
2681 "<UUID> <network id> = set AP configuration for enrolling" },
2682 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
2683 cli_cmd_flag_sensitive,
2684 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2685 #ifdef CONFIG_WPS_NFC
2686 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
2688 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2689 #endif /* CONFIG_WPS_NFC */
2690 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
2692 "<addr> = request RSN authentication with <addr> in IBSS" },
2694 { "sta", wpa_cli_cmd_sta, NULL,
2696 "<addr> = get information about an associated station (AP)" },
2697 { "all_sta", wpa_cli_cmd_all_sta, NULL,
2699 "= get information about all associated stations (AP)" },
2700 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
2702 "<addr> = deauthenticate a station" },
2703 { "disassociate", wpa_cli_cmd_disassociate, NULL,
2705 "<addr> = disassociate a station" },
2706 #endif /* CONFIG_AP */
2707 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
2708 "= notification of suspend/hibernate" },
2709 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
2710 "= notification of resume/thaw" },
2711 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
2712 "= drop SA without deauth/disassoc (test command)" },
2713 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
2715 "<addr> = roam to the specified BSS" },
2717 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
2719 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2720 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
2721 "= stop P2P Devices search" },
2722 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
2724 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2725 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
2726 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2727 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
2728 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
2729 "<ifname> = remove P2P group interface (terminate group if GO)" },
2730 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
2731 "[ht40] = add a new P2P group (local end as GO)" },
2732 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
2733 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2734 "<addr> <method> = request provisioning discovery" },
2735 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
2737 "= get the passphrase for a group (GO only)" },
2738 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2739 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2740 "<addr> <TLVs> = schedule service discovery request" },
2741 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2742 NULL, cli_cmd_flag_none,
2743 "<id> = cancel pending service discovery request" },
2744 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
2746 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2747 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
2749 "= indicate change in local services" },
2750 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
2752 "<external> = set external processing of service discovery" },
2753 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
2755 "= remove all stored service entries" },
2756 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
2758 "<bonjour|upnp> <query|version> <response|service> = add a local "
2760 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
2762 "<bonjour|upnp> <query|version> [|service] = remove a local "
2764 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
2766 "<addr> = reject connection attempts from a specific peer" },
2767 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
2769 "<cmd> [peer=addr] = invite peer" },
2770 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
2771 "[discovered] = list known (optionally, only fully discovered) P2P "
2773 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
2775 "<address> = show information about known P2P peer" },
2776 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
2778 "<field> <value> = set a P2P parameter" },
2779 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
2780 "= flush P2P state" },
2781 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
2782 "= cancel P2P group formation" },
2783 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
2784 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2785 "<address> = unauthorize a peer" },
2786 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
2788 "[<duration> <interval>] [<duration> <interval>] = request GO "
2790 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
2792 "[<period> <interval>] = set extended listen timing" },
2793 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
2794 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2795 "<address|iface=address> = remove a peer from all groups" },
2796 #endif /* CONFIG_P2P */
2797 #ifdef CONFIG_WIFI_DISPLAY
2798 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
2800 "<subelem> [contents] = set Wi-Fi Display subelement" },
2801 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
2803 "<subelem> = get Wi-Fi Display subelement" },
2804 #endif /* CONFIG_WIFI_DISPLAY */
2805 #ifdef CONFIG_INTERWORKING
2806 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
2807 "= fetch ANQP information for all APs" },
2808 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
2810 "= stop fetch_anqp operation" },
2811 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
2813 "[auto] = perform Interworking network selection" },
2814 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2815 wpa_cli_complete_bss, cli_cmd_flag_none,
2816 "<BSSID> = connect using Interworking credentials" },
2817 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
2819 "<addr> <info id>[,<info id>]... = request ANQP information" },
2820 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
2822 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2823 { "gas_response_get", wpa_cli_cmd_gas_response_get,
2824 wpa_cli_complete_bss, cli_cmd_flag_none,
2825 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2826 #endif /* CONFIG_INTERWORKING */
2828 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
2830 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2832 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
2833 wpa_cli_complete_bss, cli_cmd_flag_none,
2834 "<addr> <home realm> = get HS20 nai home realm list" },
2835 #endif /* CONFIG_HS20 */
2836 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
2838 "<0/1> = disable/enable automatic reconnection" },
2839 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
2841 "<addr> = request TDLS discovery with <addr>" },
2842 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
2844 "<addr> = request TDLS setup with <addr>" },
2845 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
2847 "<addr> = tear down TDLS with <addr>" },
2848 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
2850 "= get signal parameters" },
2851 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
2853 "= get TX/RX packet counters" },
2854 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
2856 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2857 #ifdef CONFIG_AUTOSCAN
2858 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
2859 "[params] = Set or unset (if none) autoscan parameters" },
2860 #endif /* CONFIG_AUTOSCAN */
2862 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
2863 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
2864 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
2865 "<query reason> = Send BSS Transition Management Query" },
2866 #endif /* CONFIG_WNM */
2867 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
2868 "<params..> = Sent unprocessed command" },
2869 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
2870 "= flush wpa_supplicant state" },
2871 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
2876 * Prints command usage, lines are padded with the specified string.
2878 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2883 printf("%s%s ", pad, cmd->cmd);
2884 for (n = 0; (c = cmd->usage[n]); n++) {
2893 static void print_help(const char *cmd)
2896 printf("commands:\n");
2897 for (n = 0; wpa_cli_commands[n].cmd; n++) {
2898 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
2899 print_cmd_help(&wpa_cli_commands[n], " ");
2904 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2906 const char *c, *delim;
2910 delim = os_strchr(cmd, ' ');
2914 len = os_strlen(cmd);
2916 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2917 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2918 return (wpa_cli_commands[n].flags &
2919 cli_cmd_flag_sensitive);
2925 static char ** wpa_list_cmd_list(void)
2929 struct cli_txt_entry *e;
2931 count = ARRAY_SIZE(wpa_cli_commands);
2932 count += dl_list_len(&p2p_groups);
2933 count += dl_list_len(&ifnames);
2934 res = os_calloc(count + 1, sizeof(char *));
2938 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2939 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2944 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
2945 size_t len = 8 + os_strlen(e->txt);
2946 res[i] = os_malloc(len);
2949 os_snprintf(res[i], len, "ifname=%s", e->txt);
2953 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
2954 res[i] = os_strdup(e->txt);
2964 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2969 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2970 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2971 if (wpa_cli_commands[i].completion)
2972 return wpa_cli_commands[i].completion(str,
2975 printf("\r%s\n", wpa_cli_commands[i].usage);
2985 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2991 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
2992 end = os_strchr(str, ' ');
2993 if (end && pos > end - str) {
2994 pos -= end - str + 1;
2999 end = os_strchr(str, ' ');
3000 if (end == NULL || str + pos < end)
3001 return wpa_list_cmd_list();
3003 cmd = os_malloc(pos + 1);
3006 os_memcpy(cmd, str, pos);
3007 cmd[end - str] = '\0';
3008 res = wpa_cli_cmd_completion(cmd, str, pos);
3014 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3016 struct wpa_cli_cmd *cmd, *match = NULL;
3020 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
3021 ifname_prefix = argv[0] + 7;
3025 ifname_prefix = NULL;
3031 cmd = wpa_cli_commands;
3033 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3036 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3037 /* we have an exact match */
3047 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3048 cmd = wpa_cli_commands;
3050 if (os_strncasecmp(cmd->cmd, argv[0],
3051 os_strlen(argv[0])) == 0) {
3052 printf(" %s", cmd->cmd);
3058 } else if (count == 0) {
3059 printf("Unknown command '%s'\n", argv[0]);
3062 ret = match->handler(ctrl, argc - 1, &argv[1]);
3069 static int str_match(const char *a, const char *b)
3071 return os_strncmp(a, b, os_strlen(b)) == 0;
3075 static int wpa_cli_exec(const char *program, const char *arg1,
3083 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3084 cmd = os_malloc(len);
3087 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3088 if (res < 0 || (size_t) res >= len) {
3092 cmd[len - 1] = '\0';
3094 if (system(cmd) < 0)
3096 #endif /* _WIN32_WCE */
3103 static void wpa_cli_action_process(const char *msg)
3106 char *copy = NULL, *id, *pos2;
3111 pos = os_strchr(pos, '>');
3118 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3120 os_unsetenv("WPA_ID");
3121 os_unsetenv("WPA_ID_STR");
3122 os_unsetenv("WPA_CTRL_DIR");
3124 pos = os_strstr(pos, "[id=");
3126 copy = os_strdup(pos + 4);
3130 while (*pos2 && *pos2 != ' ')
3134 os_setenv("WPA_ID", id, 1);
3135 while (*pos2 && *pos2 != '=')
3140 while (*pos2 && *pos2 != ']')
3143 os_setenv("WPA_ID_STR", id, 1);
3147 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3149 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
3150 wpa_cli_connected = 1;
3151 wpa_cli_last_id = new_id;
3152 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3154 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3155 if (wpa_cli_connected) {
3156 wpa_cli_connected = 0;
3157 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3159 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3160 wpa_cli_exec(action_file, ctrl_ifname, pos);
3161 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3162 wpa_cli_exec(action_file, ctrl_ifname, pos);
3163 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3164 wpa_cli_exec(action_file, ctrl_ifname, pos);
3165 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3166 wpa_cli_exec(action_file, ctrl_ifname, pos);
3167 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3168 wpa_cli_exec(action_file, ctrl_ifname, pos);
3169 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3170 wpa_cli_exec(action_file, ctrl_ifname, pos);
3171 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3172 wpa_cli_exec(action_file, ctrl_ifname, pos);
3173 } else if (str_match(pos, AP_STA_CONNECTED)) {
3174 wpa_cli_exec(action_file, ctrl_ifname, pos);
3175 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3176 wpa_cli_exec(action_file, ctrl_ifname, pos);
3177 } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
3178 wpa_cli_exec(action_file, ctrl_ifname, pos);
3179 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3180 printf("wpa_supplicant is terminating - stop monitoring\n");
3186 #ifndef CONFIG_ANSI_C_EXTRA
3187 static void wpa_cli_action_cb(char *msg, size_t len)
3189 wpa_cli_action_process(msg);
3191 #endif /* CONFIG_ANSI_C_EXTRA */
3194 static void wpa_cli_reconnect(void)
3196 wpa_cli_close_connection();
3197 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3202 printf("\rConnection to wpa_supplicant re-established\n");
3208 static void cli_event(const char *str)
3210 const char *start, *s;
3212 start = os_strchr(str, '>');
3218 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3219 s = os_strchr(start, ' ');
3222 s = os_strchr(s + 1, ' ');
3225 cli_txt_list_add(&bsses, s + 1);
3229 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3230 s = os_strchr(start, ' ');
3233 s = os_strchr(s + 1, ' ');
3236 cli_txt_list_del_addr(&bsses, s + 1);
3241 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3242 s = os_strstr(start, " p2p_dev_addr=");
3245 cli_txt_list_add_addr(&p2p_peers, s + 14);
3249 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3250 s = os_strstr(start, " p2p_dev_addr=");
3253 cli_txt_list_del_addr(&p2p_peers, s + 14);
3257 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3258 s = os_strchr(start, ' ');
3261 cli_txt_list_add_word(&p2p_groups, s + 1);
3265 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3266 s = os_strchr(start, ' ');
3269 cli_txt_list_del_word(&p2p_groups, s + 1);
3272 #endif /* CONFIG_P2P */
3276 static int check_terminating(const char *msg)
3278 const char *pos = msg;
3282 pos = os_strchr(pos, '>');
3289 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3291 printf("\rConnection to wpa_supplicant lost - trying to "
3294 wpa_cli_attached = 0;
3295 wpa_cli_close_connection();
3303 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3305 if (ctrl_conn == NULL) {
3306 wpa_cli_reconnect();
3309 while (wpa_ctrl_pending(ctrl) > 0) {
3311 size_t len = sizeof(buf) - 1;
3312 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3315 wpa_cli_action_process(buf);
3318 if (wpa_cli_show_event(buf)) {
3320 printf("\r%s\n", buf);
3324 if (interactive && check_terminating(buf) > 0)
3328 printf("Could not read pending message.\n");
3333 if (wpa_ctrl_pending(ctrl) < 0) {
3334 printf("Connection to wpa_supplicant lost - trying to "
3336 wpa_cli_reconnect();
3342 static int tokenize_cmd(char *cmd, char *argv[])
3355 if (argc == max_args)
3358 char *pos2 = os_strrchr(pos, '"');
3362 while (*pos != '\0' && *pos != ' ')
3372 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3374 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3375 printf("Connection to wpa_supplicant lost - trying to "
3377 wpa_cli_close_connection();
3380 wpa_cli_reconnect();
3381 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3385 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3387 wpa_cli_recv_pending(mon_conn, 0);
3391 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3393 char *argv[max_args];
3395 argc = tokenize_cmd(cmd, argv);
3397 wpa_request(ctrl_conn, argc, argv);
3401 static void wpa_cli_edit_eof_cb(void *ctx)
3407 static int warning_displayed = 0;
3408 static char *hfile = NULL;
3409 static int edit_started = 0;
3411 static void start_edit(void)
3416 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3417 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3418 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3420 home = getenv("HOME");
3422 const char *fname = ".wpa_cli_history";
3423 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3424 hfile = os_malloc(hfile_len);
3426 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3429 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3430 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3436 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3440 static void update_bssid_list(struct wpa_ctrl *ctrl)
3443 size_t len = sizeof(buf);
3445 char *cmd = "BSS RANGE=ALL MASK=0x2";
3450 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3457 pos = os_strstr(pos, "bssid=");
3461 end = os_strchr(pos, '\n');
3465 cli_txt_list_add(&bsses, pos);
3471 static void update_ifnames(struct wpa_ctrl *ctrl)
3474 size_t len = sizeof(buf);
3476 char *cmd = "INTERFACES";
3480 cli_txt_list_flush(&ifnames);
3484 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3491 end = os_strchr(pos, '\n');
3495 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
3496 if (ret > 0 && ret < (int) sizeof(txt))
3497 cli_txt_list_add(&ifnames, txt);
3503 static void try_connection(void *eloop_ctx, void *timeout_ctx)
3508 if (ctrl_ifname == NULL)
3509 ctrl_ifname = wpa_cli_get_default_ifname();
3511 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3512 if (!warning_displayed) {
3513 printf("Could not connect to wpa_supplicant: "
3514 "%s - re-trying\n", ctrl_ifname);
3515 warning_displayed = 1;
3517 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
3521 update_bssid_list(ctrl_conn);
3523 if (warning_displayed)
3524 printf("Connection established.\n");
3531 static void wpa_cli_interactive(void)
3533 printf("\nInteractive mode\n\n");
3535 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
3537 eloop_cancel_timeout(try_connection, NULL, NULL);
3539 cli_txt_list_flush(&p2p_peers);
3540 cli_txt_list_flush(&p2p_groups);
3541 cli_txt_list_flush(&bsses);
3542 cli_txt_list_flush(&ifnames);
3544 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3546 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3547 wpa_cli_close_connection();
3551 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3553 #ifdef CONFIG_ANSI_C_EXTRA
3554 /* TODO: ANSI C version(?) */
3555 printf("Action processing not supported in ANSI C build.\n");
3556 #else /* CONFIG_ANSI_C_EXTRA */
3560 char buf[256]; /* note: large enough to fit in unsolicited messages */
3563 fd = wpa_ctrl_get_fd(ctrl);
3565 while (!wpa_cli_quit) {
3568 tv.tv_sec = ping_interval;
3570 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3571 if (res < 0 && errno != EINTR) {
3576 if (FD_ISSET(fd, &rfds))
3577 wpa_cli_recv_pending(ctrl, 1);
3579 /* verify that connection is still working */
3580 len = sizeof(buf) - 1;
3581 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3582 wpa_cli_action_cb) < 0 ||
3583 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3584 printf("wpa_supplicant did not reply to PING "
3585 "command - exiting\n");
3590 #endif /* CONFIG_ANSI_C_EXTRA */
3594 static void wpa_cli_cleanup(void)
3596 wpa_cli_close_connection();
3598 os_daemonize_terminate(pid_file);
3600 os_program_deinit();
3604 static void wpa_cli_terminate(int sig, void *ctx)
3610 static char * wpa_cli_get_default_ifname(void)
3612 char *ifname = NULL;
3614 #ifdef CONFIG_CTRL_IFACE_UNIX
3615 struct dirent *dent;
3616 DIR *dir = opendir(ctrl_iface_dir);
3619 char ifprop[PROPERTY_VALUE_MAX];
3620 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3621 ifname = os_strdup(ifprop);
3622 printf("Using interface '%s'\n", ifname);
3625 #endif /* ANDROID */
3628 while ((dent = readdir(dir))) {
3629 #ifdef _DIRENT_HAVE_D_TYPE
3631 * Skip the file if it is not a socket. Also accept
3632 * DT_UNKNOWN (0) in case the C library or underlying
3633 * file system does not support d_type.
3635 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3637 #endif /* _DIRENT_HAVE_D_TYPE */
3638 if (os_strcmp(dent->d_name, ".") == 0 ||
3639 os_strcmp(dent->d_name, "..") == 0)
3641 printf("Selected interface '%s'\n", dent->d_name);
3642 ifname = os_strdup(dent->d_name);
3646 #endif /* CONFIG_CTRL_IFACE_UNIX */
3648 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3649 char buf[4096], *pos;
3651 struct wpa_ctrl *ctrl;
3654 ctrl = wpa_ctrl_open(NULL);
3658 len = sizeof(buf) - 1;
3659 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3662 pos = os_strchr(buf, '\n');
3665 ifname = os_strdup(buf);
3667 wpa_ctrl_close(ctrl);
3668 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3674 int main(int argc, char *argv[])
3679 const char *global = NULL;
3681 if (os_program_init())
3685 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3690 action_file = optarg;
3699 ping_interval = atoi(optarg);
3705 printf("%s\n", wpa_cli_version);
3708 os_free(ctrl_ifname);
3709 ctrl_ifname = os_strdup(optarg);
3712 ctrl_iface_dir = optarg;
3723 interactive = (argc == optind) && (action_file == NULL);
3726 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3732 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3733 ctrl_conn = wpa_ctrl_open(NULL);
3734 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3735 ctrl_conn = wpa_ctrl_open(global);
3736 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3737 if (ctrl_conn == NULL) {
3738 fprintf(stderr, "Failed to connect to wpa_supplicant "
3739 "global interface: %s error: %s\n",
3740 global, strerror(errno));
3745 update_ifnames(ctrl_conn);
3746 mon_conn = wpa_ctrl_open(global);
3748 if (wpa_ctrl_attach(mon_conn) == 0) {
3749 wpa_cli_attached = 1;
3750 eloop_register_read_sock(
3751 wpa_ctrl_get_fd(mon_conn),
3752 wpa_cli_mon_receive,
3755 printf("Failed to open monitor "
3756 "connection through global "
3757 "control interface\n");
3763 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
3765 if (ctrl_ifname == NULL)
3766 ctrl_ifname = wpa_cli_get_default_ifname();
3769 wpa_cli_interactive();
3772 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3773 fprintf(stderr, "Failed to connect to non-global "
3774 "ctrl_ifname: %s error: %s\n",
3775 ctrl_ifname, strerror(errno));
3780 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3781 wpa_cli_attached = 1;
3783 printf("Warning: Failed to attach to "
3784 "wpa_supplicant.\n");
3789 if (daemonize && os_daemonize(pid_file))
3793 wpa_cli_action(ctrl_conn);
3795 ret = wpa_request(ctrl_conn, argc - optind,
3799 os_free(ctrl_ifname);
3806 #else /* CONFIG_CTRL_IFACE */
3807 int main(int argc, char *argv[])
3809 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3812 #endif /* CONFIG_CTRL_IFACE */