2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2012, 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 = 0;
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;
85 struct cli_txt_entry {
90 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
91 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
92 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
95 static void print_help(const char *cmd);
96 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
97 static void wpa_cli_close_connection(void);
98 static char * wpa_cli_get_default_ifname(void);
99 static char ** wpa_list_cmd_list(void);
102 static void usage(void)
104 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
105 "[-a<action file>] \\\n"
106 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
108 " -h = help (show this usage text)\n"
109 " -v = shown version information\n"
110 " -a = run in daemon mode executing the action file based on "
113 " -B = run a daemon in the background\n"
114 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
115 " default interface: first interface found in socket path\n");
120 static void cli_txt_list_free(struct cli_txt_entry *e)
122 dl_list_del(&e->list);
128 static void cli_txt_list_flush(struct dl_list *list)
130 struct cli_txt_entry *e;
131 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
132 cli_txt_list_free(e);
136 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
139 struct cli_txt_entry *e;
140 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
141 if (os_strcmp(e->txt, txt) == 0)
148 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
150 struct cli_txt_entry *e;
151 e = cli_txt_list_get(txt_list, txt);
153 cli_txt_list_free(e);
157 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
161 if (hwaddr_aton(txt, addr) < 0)
163 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
164 cli_txt_list_del(txt_list, buf);
169 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
173 end = os_strchr(txt, ' ');
175 end = txt + os_strlen(txt);
176 buf = dup_binstr(txt, end - txt);
179 cli_txt_list_del(txt_list, buf);
182 #endif /* CONFIG_P2P */
185 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
187 struct cli_txt_entry *e;
188 e = cli_txt_list_get(txt_list, txt);
191 e = os_zalloc(sizeof(*e));
194 e->txt = os_strdup(txt);
195 if (e->txt == NULL) {
199 dl_list_add(txt_list, &e->list);
205 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
209 if (hwaddr_aton(txt, addr) < 0)
211 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
212 return cli_txt_list_add(txt_list, buf);
216 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
221 end = os_strchr(txt, ' ');
223 end = txt + os_strlen(txt);
224 buf = dup_binstr(txt, end - txt);
227 ret = cli_txt_list_add(txt_list, buf);
231 #endif /* CONFIG_P2P */
234 static char ** cli_txt_list_array(struct dl_list *txt_list)
236 unsigned int i, count = dl_list_len(txt_list);
238 struct cli_txt_entry *e;
240 res = os_calloc(count + 1, sizeof(char *));
245 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
246 res[i] = os_strdup(e->txt);
256 static int get_cmd_arg_num(const char *str, int pos)
260 for (i = 0; i <= pos; i++) {
263 while (i <= pos && str[i] != ' ')
274 static int str_starts(const char *src, const char *match)
276 return os_strncmp(src, match, os_strlen(match)) == 0;
280 static int wpa_cli_show_event(const char *event)
284 start = os_strchr(event, '>');
290 * Skip BSS added/removed events since they can be relatively frequent
291 * and are likely of not much use for an interactive user.
293 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
294 str_starts(start, WPA_EVENT_BSS_REMOVED))
301 static int wpa_cli_open_connection(const char *ifname, int attach)
303 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
304 ctrl_conn = wpa_ctrl_open(ifname);
305 if (ctrl_conn == NULL)
308 if (attach && interactive)
309 mon_conn = wpa_ctrl_open(ifname);
312 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
320 if (access(ctrl_iface_dir, F_OK) < 0) {
321 cfile = os_strdup(ifname);
328 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
329 cfile = os_malloc(flen);
332 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
334 if (res < 0 || res >= flen) {
340 ctrl_conn = wpa_ctrl_open(cfile);
341 if (ctrl_conn == NULL) {
346 if (attach && interactive)
347 mon_conn = wpa_ctrl_open(cfile);
351 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
354 if (wpa_ctrl_attach(mon_conn) == 0) {
355 wpa_cli_attached = 1;
357 eloop_register_read_sock(
358 wpa_ctrl_get_fd(mon_conn),
359 wpa_cli_mon_receive, NULL, NULL);
361 printf("Warning: Failed to attach to "
362 "wpa_supplicant.\n");
363 wpa_cli_close_connection();
372 static void wpa_cli_close_connection(void)
374 if (ctrl_conn == NULL)
377 if (wpa_cli_attached) {
378 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
379 wpa_cli_attached = 0;
381 wpa_ctrl_close(ctrl_conn);
384 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
385 wpa_ctrl_close(mon_conn);
391 static void wpa_cli_msg_cb(char *msg, size_t len)
397 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
403 if (ctrl_conn == NULL) {
404 printf("Not connected to wpa_supplicant - command dropped.\n");
407 len = sizeof(buf) - 1;
408 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
411 printf("'%s' command timed out.\n", cmd);
413 } else if (ret < 0) {
414 printf("'%s' command failed.\n", cmd);
420 if (interactive && len > 0 && buf[len - 1] != '\n')
427 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
429 return _wpa_ctrl_command(ctrl, cmd, 1);
433 static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
442 res = os_snprintf(pos, end - pos, "%s", cmd);
443 if (res < 0 || res >= end - pos)
447 for (i = 0; i < argc; i++) {
448 res = os_snprintf(pos, end - pos, " %s", argv[i]);
449 if (res < 0 || res >= end - pos)
454 buf[buflen - 1] = '\0';
458 printf("Too long command\n");
463 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
464 int argc, char *argv[])
467 if (argc < min_args) {
468 printf("Invalid %s command - at least %d argument%s "
469 "required.\n", cmd, min_args,
470 min_args > 1 ? "s are" : " is");
473 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
475 return wpa_ctrl_command(ctrl, buf);
479 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
481 return wpa_ctrl_command(ctrl, "IFNAME");
485 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
487 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
488 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
489 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
490 return wpa_ctrl_command(ctrl, "STATUS-WPS");
491 return wpa_ctrl_command(ctrl, "STATUS");
495 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
497 return wpa_ctrl_command(ctrl, "PING");
501 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
503 return wpa_ctrl_command(ctrl, "RELOG");
507 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
509 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
513 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
515 return wpa_ctrl_command(ctrl, "MIB");
519 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
521 return wpa_ctrl_command(ctrl, "PMKSA");
525 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
527 print_help(argc > 0 ? argv[0] : NULL);
532 static char ** wpa_cli_complete_help(const char *str, int pos)
534 int arg = get_cmd_arg_num(str, pos);
539 res = wpa_list_cmd_list();
547 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
549 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
554 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
563 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
569 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
570 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
571 printf("Too long SET command.\n");
574 return wpa_ctrl_command(ctrl, cmd);
577 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
581 static char ** wpa_cli_complete_set(const char *str, int pos)
583 int arg = get_cmd_arg_num(str, pos);
584 const char *fields[] = {
586 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
587 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
588 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
589 "wps_fragment_size", "wps_version_number", "ampdu",
590 "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
591 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
593 /* global configuration parameters */
594 "eapol_version", "ap_scan", "disable_scan_offload",
595 "fast_reauth", "opensc_engine_path", "pkcs11_engine_path",
596 "pkcs11_module_path", "pcsc_reader", "pcsc_pin",
597 "driver_param", "dot11RSNAConfigPMKLifetime",
598 "dot11RSNAConfigPMKReauthThreshold",
599 "dot11RSNAConfigSATimeout",
600 "update_config", "load_dynamic_eap", "uuid", "device_name",
601 "manufacturer", "model_name", "model_number", "serial_number",
602 "device_type", "os_version", "config_methods",
603 "wps_cred_processing", "wps_vendor_ext_m1", "sec_device_type",
604 "p2p_listen_reg_class", "p2p_listen_channel",
605 "p2p_oper_reg_class", "p2p_oper_channel",
606 "p2p_go_intent", "p2p_ssid_postfix", "persistent_reconnect",
607 "p2p_intra_bss", "p2p_group_idle", "p2p_pref_chan",
608 "p2p_go_ht40", "p2p_disabled", "p2p_no_group_iface",
609 "p2p_ignore_shared_freq", "country", "bss_max_count",
610 "bss_expiration_age", "bss_expiration_scan_count",
611 "filter_ssids", "filter_rssi", "max_num_sta",
612 "disassoc_low_ack", "hs20", "interworking", "hessid",
613 "access_network_type", "pbc_in_m1", "autoscan",
614 "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", "wps_nfc_dh_privkey",
615 "wps_nfc_dev_pw", "ext_password_backend",
616 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
617 "sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
618 "ignore_old_scan_res", "freq_list"
620 int i, num_fields = sizeof(fields) / sizeof(fields[0]);
623 char **res = os_calloc(num_fields + 1, sizeof(char *));
626 for (i = 0; i < num_fields; i++) {
627 res[i] = os_strdup(fields[i]);
634 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
635 return cli_txt_list_array(&bsses);
641 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
643 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
647 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
649 return wpa_ctrl_command(ctrl, "LOGOFF");
653 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
655 return wpa_ctrl_command(ctrl, "LOGON");
659 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
662 return wpa_ctrl_command(ctrl, "REASSOCIATE");
666 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
669 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
673 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
675 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
679 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
682 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
686 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
689 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
693 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
696 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
700 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
706 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
708 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
709 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
710 printf("Too long BSS_FLUSH command.\n");
713 return wpa_ctrl_command(ctrl, cmd);
717 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
720 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
724 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
726 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
730 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
732 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
736 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
739 printf("Invalid WPS_PIN command: need one or two arguments:\n"
740 "- BSSID: use 'any' to select any\n"
741 "- PIN: optional, used only with devices that have no "
746 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
750 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
753 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
757 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
760 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
764 #ifdef CONFIG_WPS_NFC
766 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
768 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
772 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
775 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
779 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
782 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
786 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
794 printf("Invalid 'wps_nfc_tag_read' command - one argument "
799 buflen = 18 + os_strlen(argv[0]);
800 buf = os_malloc(buflen);
803 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
805 ret = wpa_ctrl_command(ctrl, buf);
812 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
815 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
819 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
822 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
826 static int wpa_cli_cmd_nfc_rx_handover_req(struct wpa_ctrl *ctrl, int argc,
834 printf("Invalid 'nfc_rx_handover_req' command - one argument "
839 buflen = 21 + os_strlen(argv[0]);
840 buf = os_malloc(buflen);
843 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_REQ %s", argv[0]);
845 ret = wpa_ctrl_command(ctrl, buf);
852 static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl *ctrl, int argc,
860 printf("Invalid 'nfc_rx_handover_sel' command - one argument "
865 buflen = 21 + os_strlen(argv[0]);
866 buf = os_malloc(buflen);
869 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_SEL %s", argv[0]);
871 ret = wpa_ctrl_command(ctrl, buf);
878 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
881 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
884 #endif /* CONFIG_WPS_NFC */
887 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
893 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
895 else if (argc == 5 || argc == 6) {
896 char ssid_hex[2 * 32 + 1];
897 char key_hex[2 * 64 + 1];
901 for (i = 0; i < 32; i++) {
902 if (argv[2][i] == '\0')
904 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
909 for (i = 0; i < 64; i++) {
910 if (argv[5][i] == '\0')
912 os_snprintf(&key_hex[i * 2], 3, "%02x",
917 res = os_snprintf(cmd, sizeof(cmd),
918 "WPS_REG %s %s %s %s %s %s",
919 argv[0], argv[1], ssid_hex, argv[3], argv[4],
922 printf("Invalid WPS_REG command: need two arguments:\n"
923 "- BSSID of the target AP\n"
925 printf("Alternatively, six arguments can be used to "
926 "reconfigure the AP:\n"
927 "- BSSID of the target AP\n"
930 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
931 "- new encr (NONE, WEP, TKIP, CCMP)\n"
936 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
937 printf("Too long WPS_REG command.\n");
940 return wpa_ctrl_command(ctrl, cmd);
944 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
947 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
951 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
954 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
958 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
961 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
966 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
970 printf("Invalid WPS_ER_PIN command: need at least two "
972 "- UUID: use 'any' to select any\n"
973 "- PIN: Enrollee PIN\n"
974 "optional: - Enrollee MAC address\n");
978 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
982 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
985 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
989 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
993 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
994 "- UUID: specify which AP to use\n"
999 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
1003 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1007 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1009 "- UUID: specify which AP to use\n"
1010 "- Network configuration id\n");
1014 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
1018 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1024 if (argc == 5 || argc == 6) {
1025 char ssid_hex[2 * 32 + 1];
1026 char key_hex[2 * 64 + 1];
1030 for (i = 0; i < 32; i++) {
1031 if (argv[2][i] == '\0')
1033 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1038 for (i = 0; i < 64; i++) {
1039 if (argv[5][i] == '\0')
1041 os_snprintf(&key_hex[i * 2], 3, "%02x",
1046 res = os_snprintf(cmd, sizeof(cmd),
1047 "WPS_ER_CONFIG %s %s %s %s %s %s",
1048 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1051 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1055 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1056 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1061 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1062 printf("Too long WPS_ER_CONFIG command.\n");
1065 return wpa_ctrl_command(ctrl, cmd);
1069 #ifdef CONFIG_WPS_NFC
1070 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1074 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1076 "- WPS/NDEF: token format\n"
1077 "- UUID: specify which AP to use\n");
1081 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1083 #endif /* CONFIG_WPS_NFC */
1086 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1088 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1092 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1094 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1098 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1100 char cmd[256], *pos, *end;
1104 printf("Invalid IDENTITY command: needs two arguments "
1105 "(network id and identity)\n");
1109 end = cmd + sizeof(cmd);
1111 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1113 if (ret < 0 || ret >= end - pos) {
1114 printf("Too long IDENTITY command.\n");
1118 for (i = 2; i < argc; i++) {
1119 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1120 if (ret < 0 || ret >= end - pos) {
1121 printf("Too long IDENTITY command.\n");
1127 return wpa_ctrl_command(ctrl, cmd);
1131 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1133 char cmd[256], *pos, *end;
1137 printf("Invalid PASSWORD command: needs two arguments "
1138 "(network id and password)\n");
1142 end = cmd + sizeof(cmd);
1144 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1146 if (ret < 0 || ret >= end - pos) {
1147 printf("Too long PASSWORD command.\n");
1151 for (i = 2; i < argc; i++) {
1152 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1153 if (ret < 0 || ret >= end - pos) {
1154 printf("Too long PASSWORD command.\n");
1160 return wpa_ctrl_command(ctrl, cmd);
1164 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1167 char cmd[256], *pos, *end;
1171 printf("Invalid NEW_PASSWORD command: needs two arguments "
1172 "(network id and password)\n");
1176 end = cmd + sizeof(cmd);
1178 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1180 if (ret < 0 || ret >= end - pos) {
1181 printf("Too long NEW_PASSWORD command.\n");
1185 for (i = 2; i < argc; i++) {
1186 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1187 if (ret < 0 || ret >= end - pos) {
1188 printf("Too long NEW_PASSWORD command.\n");
1194 return wpa_ctrl_command(ctrl, cmd);
1198 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1200 char cmd[256], *pos, *end;
1204 printf("Invalid PIN command: needs two arguments "
1205 "(network id and pin)\n");
1209 end = cmd + sizeof(cmd);
1211 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1213 if (ret < 0 || ret >= end - pos) {
1214 printf("Too long PIN command.\n");
1218 for (i = 2; i < argc; i++) {
1219 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1220 if (ret < 0 || ret >= end - pos) {
1221 printf("Too long PIN command.\n");
1226 return wpa_ctrl_command(ctrl, cmd);
1230 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1232 char cmd[256], *pos, *end;
1236 printf("Invalid OTP command: needs two arguments (network "
1237 "id and password)\n");
1241 end = cmd + sizeof(cmd);
1243 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1245 if (ret < 0 || ret >= end - pos) {
1246 printf("Too long OTP command.\n");
1250 for (i = 2; i < argc; i++) {
1251 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1252 if (ret < 0 || ret >= end - pos) {
1253 printf("Too long OTP command.\n");
1259 return wpa_ctrl_command(ctrl, cmd);
1263 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1266 char cmd[256], *pos, *end;
1270 printf("Invalid PASSPHRASE command: needs two arguments "
1271 "(network id and passphrase)\n");
1275 end = cmd + sizeof(cmd);
1277 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1279 if (ret < 0 || ret >= end - pos) {
1280 printf("Too long PASSPHRASE command.\n");
1284 for (i = 2; i < argc; i++) {
1285 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1286 if (ret < 0 || ret >= end - pos) {
1287 printf("Too long PASSPHRASE command.\n");
1293 return wpa_ctrl_command(ctrl, cmd);
1297 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1300 printf("Invalid BSSID command: needs two arguments (network "
1305 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1309 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1311 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1315 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1317 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1321 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1324 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1328 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1331 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1335 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1338 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1342 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1345 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1349 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1352 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1356 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1359 return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1363 static void wpa_cli_show_network_variables(void)
1365 printf("set_network variables:\n"
1366 " ssid (network name, SSID)\n"
1367 " psk (WPA passphrase or pre-shared key)\n"
1368 " key_mgmt (key management protocol)\n"
1369 " identity (EAP identity)\n"
1370 " password (EAP password)\n"
1373 "Note: Values are entered in the same format as the "
1374 "configuration file is using,\n"
1375 "i.e., strings values need to be inside double quotation "
1377 "For example: set_network 1 ssid \"network name\"\n"
1379 "Please see wpa_supplicant.conf documentation for full list "
1380 "of\navailable variables.\n");
1384 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1388 wpa_cli_show_network_variables();
1393 printf("Invalid SET_NETWORK command: needs three arguments\n"
1394 "(network id, variable name, and value)\n");
1398 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1402 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1406 wpa_cli_show_network_variables();
1411 printf("Invalid GET_NETWORK command: needs two arguments\n"
1412 "(network id and variable name)\n");
1416 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1420 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1423 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1427 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1429 return wpa_ctrl_command(ctrl, "ADD_CRED");
1433 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1436 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1440 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1443 printf("Invalid SET_CRED command: needs three arguments\n"
1444 "(cred id, variable name, and value)\n");
1448 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1452 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1455 return wpa_ctrl_command(ctrl, "DISCONNECT");
1459 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1462 return wpa_ctrl_command(ctrl, "RECONNECT");
1466 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1469 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1473 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1475 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1479 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1482 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1486 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1488 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1492 static char ** wpa_cli_complete_bss(const char *str, int pos)
1494 int arg = get_cmd_arg_num(str, pos);
1499 res = cli_txt_list_array(&bsses);
1507 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1510 if (argc < 1 || argc > 2) {
1511 printf("Invalid GET_CAPABILITY command: need either one or "
1516 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1517 printf("Invalid GET_CAPABILITY command: second argument, "
1518 "if any, must be 'strict'\n");
1522 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1526 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1528 printf("Available interfaces:\n");
1529 return wpa_ctrl_command(ctrl, "INTERFACES");
1533 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1536 wpa_cli_list_interfaces(ctrl);
1540 wpa_cli_close_connection();
1541 os_free(ctrl_ifname);
1542 ctrl_ifname = os_strdup(argv[0]);
1544 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1545 printf("Connected to interface '%s.\n", ctrl_ifname);
1547 printf("Could not connect to interface '%s' - re-trying\n",
1554 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1557 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1561 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1564 return wpa_ctrl_command(ctrl, "TERMINATE");
1568 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1575 printf("Invalid INTERFACE_ADD command: needs at least one "
1576 "argument (interface name)\n"
1577 "All arguments: ifname confname driver ctrl_interface "
1578 "driver_param bridge_name\n");
1583 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1584 * <driver_param>TAB<bridge_name>
1586 res = os_snprintf(cmd, sizeof(cmd),
1587 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1589 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1590 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1591 argc > 5 ? argv[5] : "");
1592 if (res < 0 || (size_t) res >= sizeof(cmd))
1594 cmd[sizeof(cmd) - 1] = '\0';
1595 return wpa_ctrl_command(ctrl, cmd);
1599 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1602 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1606 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1609 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1614 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1616 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1620 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1621 char *addr, size_t addr_len)
1623 char buf[4096], *pos;
1627 if (ctrl_conn == NULL) {
1628 printf("Not connected to hostapd - command dropped.\n");
1631 len = sizeof(buf) - 1;
1632 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1635 printf("'%s' command timed out.\n", cmd);
1637 } else if (ret < 0) {
1638 printf("'%s' command failed.\n", cmd);
1643 if (os_memcmp(buf, "FAIL", 4) == 0)
1648 while (*pos != '\0' && *pos != '\n')
1651 os_strlcpy(addr, buf, addr_len);
1656 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1658 char addr[32], cmd[64];
1660 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1663 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1664 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1670 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1673 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1677 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1680 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1682 #endif /* CONFIG_AP */
1685 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1687 return wpa_ctrl_command(ctrl, "SUSPEND");
1691 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1693 return wpa_ctrl_command(ctrl, "RESUME");
1697 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1699 return wpa_ctrl_command(ctrl, "DROP_SA");
1703 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1705 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1711 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1713 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1717 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1720 int arg = get_cmd_arg_num(str, pos);
1722 res = os_calloc(6, sizeof(char *));
1725 res[0] = os_strdup("type=social");
1726 if (res[0] == NULL) {
1730 res[1] = os_strdup("type=progressive");
1733 res[2] = os_strdup("delay=");
1736 res[3] = os_strdup("dev_id=");
1740 res[4] = os_strdup("[timeout]");
1746 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1749 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1753 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1756 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
1760 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1762 int arg = get_cmd_arg_num(str, pos);
1767 res = cli_txt_list_array(&p2p_peers);
1775 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1778 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
1782 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1785 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
1789 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
1791 int arg = get_cmd_arg_num(str, pos);
1796 res = cli_txt_list_array(&p2p_groups);
1804 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1807 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
1811 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1814 if (argc != 2 && argc != 3) {
1815 printf("Invalid P2P_PROV_DISC command: needs at least "
1816 "two arguments, address and config method\n"
1817 "(display, keypad, or pbc) and an optional join\n");
1821 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
1825 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1828 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1832 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1837 if (argc != 2 && argc != 4) {
1838 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1839 "arguments (address and TLVs) or four arguments "
1840 "(address, \"upnp\", version, search target "
1845 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
1847 return wpa_ctrl_command(ctrl, cmd);
1851 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1852 int argc, char *argv[])
1854 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
1858 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1865 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1866 "arguments (freq, address, dialog token, and TLVs)\n");
1870 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1871 argv[0], argv[1], argv[2], argv[3]);
1872 if (res < 0 || (size_t) res >= sizeof(cmd))
1874 cmd[sizeof(cmd) - 1] = '\0';
1875 return wpa_ctrl_command(ctrl, cmd);
1879 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1882 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1886 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1887 int argc, char *argv[])
1889 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
1893 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1896 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1900 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1906 if (argc != 3 && argc != 4) {
1907 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1913 res = os_snprintf(cmd, sizeof(cmd),
1914 "P2P_SERVICE_ADD %s %s %s %s",
1915 argv[0], argv[1], argv[2], argv[3]);
1917 res = os_snprintf(cmd, sizeof(cmd),
1918 "P2P_SERVICE_ADD %s %s %s",
1919 argv[0], argv[1], argv[2]);
1920 if (res < 0 || (size_t) res >= sizeof(cmd))
1922 cmd[sizeof(cmd) - 1] = '\0';
1923 return wpa_ctrl_command(ctrl, cmd);
1927 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1933 if (argc != 2 && argc != 3) {
1934 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1940 res = os_snprintf(cmd, sizeof(cmd),
1941 "P2P_SERVICE_DEL %s %s %s",
1942 argv[0], argv[1], argv[2]);
1944 res = os_snprintf(cmd, sizeof(cmd),
1945 "P2P_SERVICE_DEL %s %s",
1947 if (res < 0 || (size_t) res >= sizeof(cmd))
1949 cmd[sizeof(cmd) - 1] = '\0';
1950 return wpa_ctrl_command(ctrl, cmd);
1954 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1955 int argc, char *argv[])
1957 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
1961 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1962 int argc, char *argv[])
1964 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
1968 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
1970 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
1974 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
1976 int arg = get_cmd_arg_num(str, pos);
1981 res = cli_txt_list_array(&p2p_peers);
1989 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
1990 char *addr, size_t addr_len,
1993 char buf[4096], *pos;
1997 if (ctrl_conn == NULL)
1999 len = sizeof(buf) - 1;
2000 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2003 printf("'%s' command timed out.\n", cmd);
2005 } else if (ret < 0) {
2006 printf("'%s' command failed.\n", cmd);
2011 if (os_memcmp(buf, "FAIL", 4) == 0)
2015 while (*pos != '\0' && *pos != '\n')
2018 os_strlcpy(addr, buf, addr_len);
2019 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2020 printf("%s\n", addr);
2025 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2027 char addr[32], cmd[64];
2030 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2032 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2033 addr, sizeof(addr), discovered))
2036 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2037 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2044 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2046 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2050 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2052 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2056 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2059 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2063 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2066 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2070 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2073 if (argc != 0 && argc != 2 && argc != 4) {
2074 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2075 "(preferred duration, interval; in microsecods).\n"
2076 "Optional second pair can be used to provide "
2077 "acceptable values.\n");
2081 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2085 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2088 if (argc != 0 && argc != 2) {
2089 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2090 "(availability period, availability interval; in "
2092 "Extended Listen Timing can be cancelled with this "
2093 "command when used without parameters.\n");
2097 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2100 #endif /* CONFIG_P2P */
2102 #ifdef CONFIG_WIFI_DISPLAY
2104 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2110 if (argc != 1 && argc != 2) {
2111 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2112 "arguments (subelem, hexdump)\n");
2116 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2117 argv[0], argc > 1 ? argv[1] : "");
2118 if (res < 0 || (size_t) res >= sizeof(cmd))
2120 cmd[sizeof(cmd) - 1] = '\0';
2121 return wpa_ctrl_command(ctrl, cmd);
2125 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2132 printf("Invalid WFD_SUBELEM_GET command: needs one "
2133 "argument (subelem)\n");
2137 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2139 if (res < 0 || (size_t) res >= sizeof(cmd))
2141 cmd[sizeof(cmd) - 1] = '\0';
2142 return wpa_ctrl_command(ctrl, cmd);
2144 #endif /* CONFIG_WIFI_DISPLAY */
2147 #ifdef CONFIG_INTERWORKING
2148 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2151 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2155 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2158 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2162 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2165 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2169 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2172 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2176 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2178 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2182 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2185 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2189 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2192 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2194 #endif /* CONFIG_INTERWORKING */
2199 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2202 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2206 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2212 printf("Command needs one or two arguments (dst mac addr and "
2213 "optional home realm)\n");
2217 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2221 return wpa_ctrl_command(ctrl, cmd);
2224 #endif /* CONFIG_HS20 */
2227 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2230 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2234 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2237 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2241 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2244 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2248 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2251 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2255 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2258 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2262 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2265 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2269 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2272 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2276 #ifdef CONFIG_AUTOSCAN
2278 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2281 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2283 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2286 #endif /* CONFIG_AUTOSCAN */
2291 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2293 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2296 #endif /* CONFIG_WNM */
2299 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2303 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2307 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2309 return wpa_ctrl_command(ctrl, "FLUSH");
2313 enum wpa_cli_cmd_flags {
2314 cli_cmd_flag_none = 0x00,
2315 cli_cmd_flag_sensitive = 0x01
2318 struct wpa_cli_cmd {
2320 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2321 char ** (*completion)(const char *str, int pos);
2322 enum wpa_cli_cmd_flags flags;
2326 static struct wpa_cli_cmd wpa_cli_commands[] = {
2327 { "status", wpa_cli_cmd_status, NULL,
2329 "[verbose] = get current WPA/EAPOL/EAP status" },
2330 { "ifname", wpa_cli_cmd_ifname, NULL,
2332 "= get current interface name" },
2333 { "ping", wpa_cli_cmd_ping, NULL,
2335 "= pings wpa_supplicant" },
2336 { "relog", wpa_cli_cmd_relog, NULL,
2338 "= re-open log-file (allow rolling logs)" },
2339 { "note", wpa_cli_cmd_note, NULL,
2341 "<text> = add a note to wpa_supplicant debug log" },
2342 { "mib", wpa_cli_cmd_mib, NULL,
2344 "= get MIB variables (dot1x, dot11)" },
2345 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2347 "[command] = show usage help" },
2348 { "interface", wpa_cli_cmd_interface, NULL,
2350 "[ifname] = show interfaces/select interface" },
2351 { "level", wpa_cli_cmd_level, NULL,
2353 "<debug level> = change debug level" },
2354 { "license", wpa_cli_cmd_license, NULL,
2356 "= show full wpa_cli license" },
2357 { "quit", wpa_cli_cmd_quit, NULL,
2360 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2362 "= set variables (shows list of variables when run without "
2364 { "get", wpa_cli_cmd_get, NULL,
2366 "<name> = get information" },
2367 { "logon", wpa_cli_cmd_logon, NULL,
2369 "= IEEE 802.1X EAPOL state machine logon" },
2370 { "logoff", wpa_cli_cmd_logoff, NULL,
2372 "= IEEE 802.1X EAPOL state machine logoff" },
2373 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2375 "= show PMKSA cache" },
2376 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2378 "= force reassociation" },
2379 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2381 "<BSSID> = force preauthentication" },
2382 { "identity", wpa_cli_cmd_identity, NULL,
2384 "<network id> <identity> = configure identity for an SSID" },
2385 { "password", wpa_cli_cmd_password, NULL,
2386 cli_cmd_flag_sensitive,
2387 "<network id> <password> = configure password for an SSID" },
2388 { "new_password", wpa_cli_cmd_new_password, NULL,
2389 cli_cmd_flag_sensitive,
2390 "<network id> <password> = change password for an SSID" },
2391 { "pin", wpa_cli_cmd_pin, NULL,
2392 cli_cmd_flag_sensitive,
2393 "<network id> <pin> = configure pin for an SSID" },
2394 { "otp", wpa_cli_cmd_otp, NULL,
2395 cli_cmd_flag_sensitive,
2396 "<network id> <password> = configure one-time-password for an SSID"
2398 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2399 cli_cmd_flag_sensitive,
2400 "<network id> <passphrase> = configure private key passphrase\n"
2402 { "bssid", wpa_cli_cmd_bssid, NULL,
2404 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2405 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2407 "<BSSID> = add a BSSID to the blacklist\n"
2408 "blacklist clear = clear the blacklist\n"
2409 "blacklist = display the blacklist" },
2410 { "log_level", wpa_cli_cmd_log_level, NULL,
2412 "<level> [<timestamp>] = update the log level/timestamp\n"
2413 "log_level = display the current log level and log options" },
2414 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2416 "= list configured networks" },
2417 { "select_network", wpa_cli_cmd_select_network, NULL,
2419 "<network id> = select a network (disable others)" },
2420 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2422 "<network id> = enable a network" },
2423 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2425 "<network id> = disable a network" },
2426 { "add_network", wpa_cli_cmd_add_network, NULL,
2428 "= add a network" },
2429 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2431 "<network id> = remove a network" },
2432 { "set_network", wpa_cli_cmd_set_network, NULL,
2433 cli_cmd_flag_sensitive,
2434 "<network id> <variable> <value> = set network variables (shows\n"
2435 " list of variables when run without arguments)" },
2436 { "get_network", wpa_cli_cmd_get_network, NULL,
2438 "<network id> <variable> = get network variables" },
2439 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2441 "= list configured credentials" },
2442 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2444 "= add a credential" },
2445 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2447 "<cred id> = remove a credential" },
2448 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2449 cli_cmd_flag_sensitive,
2450 "<cred id> <variable> <value> = set credential variables" },
2451 { "save_config", wpa_cli_cmd_save_config, NULL,
2453 "= save the current configuration" },
2454 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2456 "= disconnect and wait for reassociate/reconnect command before\n"
2458 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2460 "= like reassociate, but only takes effect if already disconnected"
2462 { "scan", wpa_cli_cmd_scan, NULL,
2464 "= request new BSS scan" },
2465 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2467 "= get latest scan results" },
2468 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2470 "<<idx> | <bssid>> = get detailed scan result info" },
2471 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2473 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2474 "= get capabilies" },
2475 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2477 "= force wpa_supplicant to re-read its configuration file" },
2478 { "terminate", wpa_cli_cmd_terminate, NULL,
2480 "= terminate wpa_supplicant" },
2481 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2483 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2484 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2486 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2488 "<ifname> = removes the interface" },
2489 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2491 "= list available interfaces" },
2492 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2494 "<value> = set ap_scan parameter" },
2495 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2497 "<value> = set scan_interval parameter (in seconds)" },
2498 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2500 "<value> = set BSS expiration age parameter" },
2501 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2503 "<value> = set BSS expiration scan count parameter" },
2504 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2506 "<value> = set BSS flush age (0 by default)" },
2507 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2509 "<addr> = request STK negotiation with <addr>" },
2510 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2512 "<addr> = request over-the-DS FT with <addr>" },
2513 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2515 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2516 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2517 cli_cmd_flag_sensitive,
2518 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2520 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2521 cli_cmd_flag_sensitive,
2522 "<PIN> = verify PIN checksum" },
2523 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2524 "Cancels the pending WPS operation" },
2525 #ifdef CONFIG_WPS_NFC
2526 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2528 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2529 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
2531 "<WPS|NDEF> = build configuration token" },
2532 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
2534 "<WPS|NDEF> = create password token" },
2535 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
2536 cli_cmd_flag_sensitive,
2537 "<hexdump of payload> = report read NFC tag with WPS data" },
2538 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
2540 "<NDEF> <WPS> = create NFC handover request" },
2541 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
2543 "<NDEF> <WPS> = create NFC handover select" },
2544 { "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req, NULL,
2546 "<hexdump of payload> = report received NFC handover request" },
2547 { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL,
2549 "<hexdump of payload> = report received NFC handover select" },
2550 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
2552 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2554 #endif /* CONFIG_WPS_NFC */
2555 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
2556 cli_cmd_flag_sensitive,
2557 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2558 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
2559 cli_cmd_flag_sensitive,
2560 "[params..] = enable/disable AP PIN" },
2561 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
2563 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2564 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
2566 "= stop Wi-Fi Protected Setup External Registrar" },
2567 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
2568 cli_cmd_flag_sensitive,
2569 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2570 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
2572 "<UUID> = accept an Enrollee PBC using External Registrar" },
2573 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
2574 cli_cmd_flag_sensitive,
2575 "<UUID> <PIN> = learn AP configuration" },
2576 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
2578 "<UUID> <network id> = set AP configuration for enrolling" },
2579 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
2580 cli_cmd_flag_sensitive,
2581 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2582 #ifdef CONFIG_WPS_NFC
2583 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
2585 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2586 #endif /* CONFIG_WPS_NFC */
2587 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
2589 "<addr> = request RSN authentication with <addr> in IBSS" },
2591 { "sta", wpa_cli_cmd_sta, NULL,
2593 "<addr> = get information about an associated station (AP)" },
2594 { "all_sta", wpa_cli_cmd_all_sta, NULL,
2596 "= get information about all associated stations (AP)" },
2597 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
2599 "<addr> = deauthenticate a station" },
2600 { "disassociate", wpa_cli_cmd_disassociate, NULL,
2602 "<addr> = disassociate a station" },
2603 #endif /* CONFIG_AP */
2604 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
2605 "= notification of suspend/hibernate" },
2606 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
2607 "= notification of resume/thaw" },
2608 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
2609 "= drop SA without deauth/disassoc (test command)" },
2610 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
2612 "<addr> = roam to the specified BSS" },
2614 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
2616 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2617 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
2618 "= stop P2P Devices search" },
2619 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
2621 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2622 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
2623 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2624 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
2625 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
2626 "<ifname> = remove P2P group interface (terminate group if GO)" },
2627 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
2628 "[ht40] = add a new P2P group (local end as GO)" },
2629 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
2630 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2631 "<addr> <method> = request provisioning discovery" },
2632 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
2634 "= get the passphrase for a group (GO only)" },
2635 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2636 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2637 "<addr> <TLVs> = schedule service discovery request" },
2638 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2639 NULL, cli_cmd_flag_none,
2640 "<id> = cancel pending service discovery request" },
2641 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
2643 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2644 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
2646 "= indicate change in local services" },
2647 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
2649 "<external> = set external processing of service discovery" },
2650 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
2652 "= remove all stored service entries" },
2653 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
2655 "<bonjour|upnp> <query|version> <response|service> = add a local "
2657 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
2659 "<bonjour|upnp> <query|version> [|service] = remove a local "
2661 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
2663 "<addr> = reject connection attempts from a specific peer" },
2664 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
2666 "<cmd> [peer=addr] = invite peer" },
2667 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
2668 "[discovered] = list known (optionally, only fully discovered) P2P "
2670 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
2672 "<address> = show information about known P2P peer" },
2673 { "p2p_set", wpa_cli_cmd_p2p_set, NULL, cli_cmd_flag_none,
2674 "<field> <value> = set a P2P parameter" },
2675 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
2676 "= flush P2P state" },
2677 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
2678 "= cancel P2P group formation" },
2679 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
2680 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2681 "<address> = unauthorize a peer" },
2682 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
2684 "[<duration> <interval>] [<duration> <interval>] = request GO "
2686 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
2688 "[<period> <interval>] = set extended listen timing" },
2689 #endif /* CONFIG_P2P */
2690 #ifdef CONFIG_WIFI_DISPLAY
2691 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
2693 "<subelem> [contents] = set Wi-Fi Display subelement" },
2694 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
2696 "<subelem> = get Wi-Fi Display subelement" },
2697 #endif /* CONFIG_WIFI_DISPLAY */
2698 #ifdef CONFIG_INTERWORKING
2699 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
2700 "= fetch ANQP information for all APs" },
2701 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
2703 "= stop fetch_anqp operation" },
2704 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
2706 "[auto] = perform Interworking network selection" },
2707 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2708 wpa_cli_complete_bss, cli_cmd_flag_none,
2709 "<BSSID> = connect using Interworking credentials" },
2710 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
2712 "<addr> <info id>[,<info id>]... = request ANQP information" },
2713 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
2715 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2716 { "gas_response_get", wpa_cli_cmd_gas_response_get,
2717 wpa_cli_complete_bss, cli_cmd_flag_none,
2718 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2719 #endif /* CONFIG_INTERWORKING */
2721 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
2723 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2725 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
2726 wpa_cli_complete_bss, cli_cmd_flag_none,
2727 "<addr> <home realm> = get HS20 nai home realm list" },
2728 #endif /* CONFIG_HS20 */
2729 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
2731 "<0/1> = disable/enable automatic reconnection" },
2732 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
2734 "<addr> = request TDLS discovery with <addr>" },
2735 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
2737 "<addr> = request TDLS setup with <addr>" },
2738 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
2740 "<addr> = tear down TDLS with <addr>" },
2741 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
2743 "= get signal parameters" },
2744 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
2746 "= get TX/RX packet counters" },
2747 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
2749 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2750 #ifdef CONFIG_AUTOSCAN
2751 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
2752 "[params] = Set or unset (if none) autoscan parameters" },
2753 #endif /* CONFIG_AUTOSCAN */
2755 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
2756 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
2757 #endif /* CONFIG_WNM */
2758 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
2759 "<params..> = Sent unprocessed command" },
2760 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
2761 "= flush wpa_supplicant state" },
2762 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
2767 * Prints command usage, lines are padded with the specified string.
2769 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2774 printf("%s%s ", pad, cmd->cmd);
2775 for (n = 0; (c = cmd->usage[n]); n++) {
2784 static void print_help(const char *cmd)
2787 printf("commands:\n");
2788 for (n = 0; wpa_cli_commands[n].cmd; n++) {
2789 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
2790 print_cmd_help(&wpa_cli_commands[n], " ");
2795 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2797 const char *c, *delim;
2801 delim = os_strchr(cmd, ' ');
2805 len = os_strlen(cmd);
2807 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2808 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2809 return (wpa_cli_commands[n].flags &
2810 cli_cmd_flag_sensitive);
2816 static char ** wpa_list_cmd_list(void)
2821 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2822 res = os_calloc(count, sizeof(char *));
2826 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2827 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2836 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2841 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2842 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2843 if (wpa_cli_commands[i].completion)
2844 return wpa_cli_commands[i].completion(str,
2847 printf("\r%s\n", wpa_cli_commands[i].usage);
2857 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2863 end = os_strchr(str, ' ');
2864 if (end == NULL || str + pos < end)
2865 return wpa_list_cmd_list();
2867 cmd = os_malloc(pos + 1);
2870 os_memcpy(cmd, str, pos);
2871 cmd[end - str] = '\0';
2872 res = wpa_cli_cmd_completion(cmd, str, pos);
2878 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2880 struct wpa_cli_cmd *cmd, *match = NULL;
2885 cmd = wpa_cli_commands;
2887 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2890 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2891 /* we have an exact match */
2901 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2902 cmd = wpa_cli_commands;
2904 if (os_strncasecmp(cmd->cmd, argv[0],
2905 os_strlen(argv[0])) == 0) {
2906 printf(" %s", cmd->cmd);
2912 } else if (count == 0) {
2913 printf("Unknown command '%s'\n", argv[0]);
2916 ret = match->handler(ctrl, argc - 1, &argv[1]);
2923 static int str_match(const char *a, const char *b)
2925 return os_strncmp(a, b, os_strlen(b)) == 0;
2929 static int wpa_cli_exec(const char *program, const char *arg1,
2937 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2938 cmd = os_malloc(len);
2941 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2942 if (res < 0 || (size_t) res >= len) {
2946 cmd[len - 1] = '\0';
2948 if (system(cmd) < 0)
2950 #endif /* _WIN32_WCE */
2957 static void wpa_cli_action_process(const char *msg)
2960 char *copy = NULL, *id, *pos2;
2965 pos = os_strchr(pos, '>');
2972 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2974 os_unsetenv("WPA_ID");
2975 os_unsetenv("WPA_ID_STR");
2976 os_unsetenv("WPA_CTRL_DIR");
2978 pos = os_strstr(pos, "[id=");
2980 copy = os_strdup(pos + 4);
2984 while (*pos2 && *pos2 != ' ')
2988 os_setenv("WPA_ID", id, 1);
2989 while (*pos2 && *pos2 != '=')
2994 while (*pos2 && *pos2 != ']')
2997 os_setenv("WPA_ID_STR", id, 1);
3001 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3003 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3004 wpa_cli_connected = 1;
3005 wpa_cli_last_id = new_id;
3006 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3008 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3009 if (wpa_cli_connected) {
3010 wpa_cli_connected = 0;
3011 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3013 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3014 wpa_cli_exec(action_file, ctrl_ifname, pos);
3015 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3016 wpa_cli_exec(action_file, ctrl_ifname, pos);
3017 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3018 wpa_cli_exec(action_file, ctrl_ifname, pos);
3019 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3020 wpa_cli_exec(action_file, ctrl_ifname, pos);
3021 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3022 wpa_cli_exec(action_file, ctrl_ifname, pos);
3023 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3024 wpa_cli_exec(action_file, ctrl_ifname, pos);
3025 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3026 wpa_cli_exec(action_file, ctrl_ifname, pos);
3027 } else if (str_match(pos, AP_STA_CONNECTED)) {
3028 wpa_cli_exec(action_file, ctrl_ifname, pos);
3029 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3030 wpa_cli_exec(action_file, ctrl_ifname, pos);
3031 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3032 printf("wpa_supplicant is terminating - stop monitoring\n");
3038 #ifndef CONFIG_ANSI_C_EXTRA
3039 static void wpa_cli_action_cb(char *msg, size_t len)
3041 wpa_cli_action_process(msg);
3043 #endif /* CONFIG_ANSI_C_EXTRA */
3046 static void wpa_cli_reconnect(void)
3048 wpa_cli_close_connection();
3049 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3054 printf("\rConnection to wpa_supplicant re-established\n");
3060 static void cli_event(const char *str)
3062 const char *start, *s;
3064 start = os_strchr(str, '>');
3070 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3071 s = os_strchr(start, ' ');
3074 s = os_strchr(s + 1, ' ');
3077 cli_txt_list_add(&bsses, s + 1);
3081 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3082 s = os_strchr(start, ' ');
3085 s = os_strchr(s + 1, ' ');
3088 cli_txt_list_del_addr(&bsses, s + 1);
3093 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3094 s = os_strstr(start, " p2p_dev_addr=");
3097 cli_txt_list_add_addr(&p2p_peers, s + 14);
3101 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3102 s = os_strstr(start, " p2p_dev_addr=");
3105 cli_txt_list_del_addr(&p2p_peers, s + 14);
3109 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3110 s = os_strchr(start, ' ');
3113 cli_txt_list_add_word(&p2p_groups, s + 1);
3117 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3118 s = os_strchr(start, ' ');
3121 cli_txt_list_del_word(&p2p_groups, s + 1);
3124 #endif /* CONFIG_P2P */
3128 static int check_terminating(const char *msg)
3130 const char *pos = msg;
3134 pos = os_strchr(pos, '>');
3141 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3143 printf("\rConnection to wpa_supplicant lost - trying to "
3146 wpa_cli_attached = 0;
3147 wpa_cli_close_connection();
3155 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3157 if (ctrl_conn == NULL) {
3158 wpa_cli_reconnect();
3161 while (wpa_ctrl_pending(ctrl) > 0) {
3163 size_t len = sizeof(buf) - 1;
3164 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3167 wpa_cli_action_process(buf);
3170 if (wpa_cli_show_event(buf)) {
3172 printf("\r%s\n", buf);
3176 if (interactive && check_terminating(buf) > 0)
3180 printf("Could not read pending message.\n");
3185 if (wpa_ctrl_pending(ctrl) < 0) {
3186 printf("Connection to wpa_supplicant lost - trying to "
3188 wpa_cli_reconnect();
3194 static int tokenize_cmd(char *cmd, char *argv[])
3207 if (argc == max_args)
3210 char *pos2 = os_strrchr(pos, '"');
3214 while (*pos != '\0' && *pos != ' ')
3224 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3226 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3227 printf("Connection to wpa_supplicant lost - trying to "
3229 wpa_cli_close_connection();
3232 wpa_cli_reconnect();
3233 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3237 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3239 wpa_cli_recv_pending(mon_conn, 0);
3243 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3245 char *argv[max_args];
3247 argc = tokenize_cmd(cmd, argv);
3249 wpa_request(ctrl_conn, argc, argv);
3253 static void wpa_cli_edit_eof_cb(void *ctx)
3259 static int warning_displayed = 0;
3260 static char *hfile = NULL;
3261 static int edit_started = 0;
3263 static void start_edit(void)
3268 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3269 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3270 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3272 home = getenv("HOME");
3274 const char *fname = ".wpa_cli_history";
3275 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3276 hfile = os_malloc(hfile_len);
3278 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3281 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3282 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3288 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3292 static void update_bssid_list(struct wpa_ctrl *ctrl)
3295 size_t len = sizeof(buf);
3297 char *cmd = "BSS RANGE=ALL MASK=0x2";
3302 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3309 pos = os_strstr(pos, "bssid=");
3313 end = os_strchr(pos, '\n');
3317 cli_txt_list_add(&bsses, pos);
3323 static void try_connection(void *eloop_ctx, void *timeout_ctx)
3325 if (ctrl_ifname == NULL)
3326 ctrl_ifname = wpa_cli_get_default_ifname();
3328 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3329 if (!warning_displayed) {
3330 printf("Could not connect to wpa_supplicant: "
3331 "%s - re-trying\n", ctrl_ifname);
3332 warning_displayed = 1;
3334 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
3338 update_bssid_list(ctrl_conn);
3340 if (warning_displayed)
3341 printf("Connection established.\n");
3347 static void wpa_cli_interactive(void)
3349 printf("\nInteractive mode\n\n");
3351 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
3353 eloop_cancel_timeout(try_connection, NULL, NULL);
3355 cli_txt_list_flush(&p2p_peers);
3356 cli_txt_list_flush(&p2p_groups);
3357 cli_txt_list_flush(&bsses);
3359 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3361 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3362 wpa_cli_close_connection();
3366 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3368 #ifdef CONFIG_ANSI_C_EXTRA
3369 /* TODO: ANSI C version(?) */
3370 printf("Action processing not supported in ANSI C build.\n");
3371 #else /* CONFIG_ANSI_C_EXTRA */
3375 char buf[256]; /* note: large enough to fit in unsolicited messages */
3378 fd = wpa_ctrl_get_fd(ctrl);
3380 while (!wpa_cli_quit) {
3383 tv.tv_sec = ping_interval;
3385 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3386 if (res < 0 && errno != EINTR) {
3391 if (FD_ISSET(fd, &rfds))
3392 wpa_cli_recv_pending(ctrl, 1);
3394 /* verify that connection is still working */
3395 len = sizeof(buf) - 1;
3396 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3397 wpa_cli_action_cb) < 0 ||
3398 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3399 printf("wpa_supplicant did not reply to PING "
3400 "command - exiting\n");
3405 #endif /* CONFIG_ANSI_C_EXTRA */
3409 static void wpa_cli_cleanup(void)
3411 wpa_cli_close_connection();
3413 os_daemonize_terminate(pid_file);
3415 os_program_deinit();
3419 static void wpa_cli_terminate(int sig, void *ctx)
3425 static char * wpa_cli_get_default_ifname(void)
3427 char *ifname = NULL;
3429 #ifdef CONFIG_CTRL_IFACE_UNIX
3430 struct dirent *dent;
3431 DIR *dir = opendir(ctrl_iface_dir);
3434 char ifprop[PROPERTY_VALUE_MAX];
3435 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3436 ifname = os_strdup(ifprop);
3437 printf("Using interface '%s'\n", ifname);
3440 #endif /* ANDROID */
3443 while ((dent = readdir(dir))) {
3444 #ifdef _DIRENT_HAVE_D_TYPE
3446 * Skip the file if it is not a socket. Also accept
3447 * DT_UNKNOWN (0) in case the C library or underlying
3448 * file system does not support d_type.
3450 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3452 #endif /* _DIRENT_HAVE_D_TYPE */
3453 if (os_strcmp(dent->d_name, ".") == 0 ||
3454 os_strcmp(dent->d_name, "..") == 0)
3456 printf("Selected interface '%s'\n", dent->d_name);
3457 ifname = os_strdup(dent->d_name);
3461 #endif /* CONFIG_CTRL_IFACE_UNIX */
3463 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3464 char buf[2048], *pos;
3466 struct wpa_ctrl *ctrl;
3469 ctrl = wpa_ctrl_open(NULL);
3473 len = sizeof(buf) - 1;
3474 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3477 pos = os_strchr(buf, '\n');
3480 ifname = os_strdup(buf);
3482 wpa_ctrl_close(ctrl);
3483 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3489 int main(int argc, char *argv[])
3494 const char *global = NULL;
3496 if (os_program_init())
3500 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3505 action_file = optarg;
3514 ping_interval = atoi(optarg);
3520 printf("%s\n", wpa_cli_version);
3523 os_free(ctrl_ifname);
3524 ctrl_ifname = os_strdup(optarg);
3527 ctrl_iface_dir = optarg;
3538 interactive = (argc == optind) && (action_file == NULL);
3541 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3547 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3548 ctrl_conn = wpa_ctrl_open(NULL);
3549 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3550 ctrl_conn = wpa_ctrl_open(global);
3551 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3552 if (ctrl_conn == NULL) {
3553 fprintf(stderr, "Failed to connect to wpa_supplicant "
3554 "global interface: %s error: %s\n",
3555 global, strerror(errno));
3560 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
3562 if (ctrl_ifname == NULL)
3563 ctrl_ifname = wpa_cli_get_default_ifname();
3566 wpa_cli_interactive();
3569 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3570 fprintf(stderr, "Failed to connect to non-global "
3571 "ctrl_ifname: %s error: %s\n",
3572 ctrl_ifname, strerror(errno));
3577 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3578 wpa_cli_attached = 1;
3580 printf("Warning: Failed to attach to "
3581 "wpa_supplicant.\n");
3586 if (daemonize && os_daemonize(pid_file))
3590 wpa_cli_action(ctrl_conn);
3592 ret = wpa_request(ctrl_conn, argc - optind,
3596 os_free(ctrl_ifname);
3603 #else /* CONFIG_CTRL_IFACE */
3604 int main(int argc, char *argv[])
3606 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3609 #endif /* CONFIG_CTRL_IFACE */