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);
2297 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2299 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2302 #endif /* CONFIG_WNM */
2305 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2309 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2313 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2315 return wpa_ctrl_command(ctrl, "FLUSH");
2319 enum wpa_cli_cmd_flags {
2320 cli_cmd_flag_none = 0x00,
2321 cli_cmd_flag_sensitive = 0x01
2324 struct wpa_cli_cmd {
2326 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2327 char ** (*completion)(const char *str, int pos);
2328 enum wpa_cli_cmd_flags flags;
2332 static struct wpa_cli_cmd wpa_cli_commands[] = {
2333 { "status", wpa_cli_cmd_status, NULL,
2335 "[verbose] = get current WPA/EAPOL/EAP status" },
2336 { "ifname", wpa_cli_cmd_ifname, NULL,
2338 "= get current interface name" },
2339 { "ping", wpa_cli_cmd_ping, NULL,
2341 "= pings wpa_supplicant" },
2342 { "relog", wpa_cli_cmd_relog, NULL,
2344 "= re-open log-file (allow rolling logs)" },
2345 { "note", wpa_cli_cmd_note, NULL,
2347 "<text> = add a note to wpa_supplicant debug log" },
2348 { "mib", wpa_cli_cmd_mib, NULL,
2350 "= get MIB variables (dot1x, dot11)" },
2351 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2353 "[command] = show usage help" },
2354 { "interface", wpa_cli_cmd_interface, NULL,
2356 "[ifname] = show interfaces/select interface" },
2357 { "level", wpa_cli_cmd_level, NULL,
2359 "<debug level> = change debug level" },
2360 { "license", wpa_cli_cmd_license, NULL,
2362 "= show full wpa_cli license" },
2363 { "quit", wpa_cli_cmd_quit, NULL,
2366 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2368 "= set variables (shows list of variables when run without "
2370 { "get", wpa_cli_cmd_get, NULL,
2372 "<name> = get information" },
2373 { "logon", wpa_cli_cmd_logon, NULL,
2375 "= IEEE 802.1X EAPOL state machine logon" },
2376 { "logoff", wpa_cli_cmd_logoff, NULL,
2378 "= IEEE 802.1X EAPOL state machine logoff" },
2379 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2381 "= show PMKSA cache" },
2382 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2384 "= force reassociation" },
2385 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2387 "<BSSID> = force preauthentication" },
2388 { "identity", wpa_cli_cmd_identity, NULL,
2390 "<network id> <identity> = configure identity for an SSID" },
2391 { "password", wpa_cli_cmd_password, NULL,
2392 cli_cmd_flag_sensitive,
2393 "<network id> <password> = configure password for an SSID" },
2394 { "new_password", wpa_cli_cmd_new_password, NULL,
2395 cli_cmd_flag_sensitive,
2396 "<network id> <password> = change password for an SSID" },
2397 { "pin", wpa_cli_cmd_pin, NULL,
2398 cli_cmd_flag_sensitive,
2399 "<network id> <pin> = configure pin for an SSID" },
2400 { "otp", wpa_cli_cmd_otp, NULL,
2401 cli_cmd_flag_sensitive,
2402 "<network id> <password> = configure one-time-password for an SSID"
2404 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2405 cli_cmd_flag_sensitive,
2406 "<network id> <passphrase> = configure private key passphrase\n"
2408 { "bssid", wpa_cli_cmd_bssid, NULL,
2410 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2411 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2413 "<BSSID> = add a BSSID to the blacklist\n"
2414 "blacklist clear = clear the blacklist\n"
2415 "blacklist = display the blacklist" },
2416 { "log_level", wpa_cli_cmd_log_level, NULL,
2418 "<level> [<timestamp>] = update the log level/timestamp\n"
2419 "log_level = display the current log level and log options" },
2420 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2422 "= list configured networks" },
2423 { "select_network", wpa_cli_cmd_select_network, NULL,
2425 "<network id> = select a network (disable others)" },
2426 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2428 "<network id> = enable a network" },
2429 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2431 "<network id> = disable a network" },
2432 { "add_network", wpa_cli_cmd_add_network, NULL,
2434 "= add a network" },
2435 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2437 "<network id> = remove a network" },
2438 { "set_network", wpa_cli_cmd_set_network, NULL,
2439 cli_cmd_flag_sensitive,
2440 "<network id> <variable> <value> = set network variables (shows\n"
2441 " list of variables when run without arguments)" },
2442 { "get_network", wpa_cli_cmd_get_network, NULL,
2444 "<network id> <variable> = get network variables" },
2445 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2447 "= list configured credentials" },
2448 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2450 "= add a credential" },
2451 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2453 "<cred id> = remove a credential" },
2454 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2455 cli_cmd_flag_sensitive,
2456 "<cred id> <variable> <value> = set credential variables" },
2457 { "save_config", wpa_cli_cmd_save_config, NULL,
2459 "= save the current configuration" },
2460 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2462 "= disconnect and wait for reassociate/reconnect command before\n"
2464 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2466 "= like reassociate, but only takes effect if already disconnected"
2468 { "scan", wpa_cli_cmd_scan, NULL,
2470 "= request new BSS scan" },
2471 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2473 "= get latest scan results" },
2474 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2476 "<<idx> | <bssid>> = get detailed scan result info" },
2477 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2479 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2480 "= get capabilies" },
2481 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2483 "= force wpa_supplicant to re-read its configuration file" },
2484 { "terminate", wpa_cli_cmd_terminate, NULL,
2486 "= terminate wpa_supplicant" },
2487 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2489 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2490 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2492 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2494 "<ifname> = removes the interface" },
2495 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2497 "= list available interfaces" },
2498 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2500 "<value> = set ap_scan parameter" },
2501 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2503 "<value> = set scan_interval parameter (in seconds)" },
2504 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2506 "<value> = set BSS expiration age parameter" },
2507 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2509 "<value> = set BSS expiration scan count parameter" },
2510 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2512 "<value> = set BSS flush age (0 by default)" },
2513 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2515 "<addr> = request STK negotiation with <addr>" },
2516 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2518 "<addr> = request over-the-DS FT with <addr>" },
2519 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2521 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2522 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2523 cli_cmd_flag_sensitive,
2524 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2526 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2527 cli_cmd_flag_sensitive,
2528 "<PIN> = verify PIN checksum" },
2529 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2530 "Cancels the pending WPS operation" },
2531 #ifdef CONFIG_WPS_NFC
2532 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2534 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2535 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
2537 "<WPS|NDEF> = build configuration token" },
2538 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
2540 "<WPS|NDEF> = create password token" },
2541 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
2542 cli_cmd_flag_sensitive,
2543 "<hexdump of payload> = report read NFC tag with WPS data" },
2544 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
2546 "<NDEF> <WPS> = create NFC handover request" },
2547 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
2549 "<NDEF> <WPS> = create NFC handover select" },
2550 { "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req, NULL,
2552 "<hexdump of payload> = report received NFC handover request" },
2553 { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL,
2555 "<hexdump of payload> = report received NFC handover select" },
2556 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
2558 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2560 #endif /* CONFIG_WPS_NFC */
2561 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
2562 cli_cmd_flag_sensitive,
2563 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2564 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
2565 cli_cmd_flag_sensitive,
2566 "[params..] = enable/disable AP PIN" },
2567 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
2569 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2570 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
2572 "= stop Wi-Fi Protected Setup External Registrar" },
2573 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
2574 cli_cmd_flag_sensitive,
2575 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2576 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
2578 "<UUID> = accept an Enrollee PBC using External Registrar" },
2579 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
2580 cli_cmd_flag_sensitive,
2581 "<UUID> <PIN> = learn AP configuration" },
2582 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
2584 "<UUID> <network id> = set AP configuration for enrolling" },
2585 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
2586 cli_cmd_flag_sensitive,
2587 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2588 #ifdef CONFIG_WPS_NFC
2589 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
2591 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2592 #endif /* CONFIG_WPS_NFC */
2593 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
2595 "<addr> = request RSN authentication with <addr> in IBSS" },
2597 { "sta", wpa_cli_cmd_sta, NULL,
2599 "<addr> = get information about an associated station (AP)" },
2600 { "all_sta", wpa_cli_cmd_all_sta, NULL,
2602 "= get information about all associated stations (AP)" },
2603 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
2605 "<addr> = deauthenticate a station" },
2606 { "disassociate", wpa_cli_cmd_disassociate, NULL,
2608 "<addr> = disassociate a station" },
2609 #endif /* CONFIG_AP */
2610 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
2611 "= notification of suspend/hibernate" },
2612 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
2613 "= notification of resume/thaw" },
2614 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
2615 "= drop SA without deauth/disassoc (test command)" },
2616 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
2618 "<addr> = roam to the specified BSS" },
2620 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
2622 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2623 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
2624 "= stop P2P Devices search" },
2625 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
2627 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2628 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
2629 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2630 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
2631 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
2632 "<ifname> = remove P2P group interface (terminate group if GO)" },
2633 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
2634 "[ht40] = add a new P2P group (local end as GO)" },
2635 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
2636 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2637 "<addr> <method> = request provisioning discovery" },
2638 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
2640 "= get the passphrase for a group (GO only)" },
2641 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2642 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2643 "<addr> <TLVs> = schedule service discovery request" },
2644 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2645 NULL, cli_cmd_flag_none,
2646 "<id> = cancel pending service discovery request" },
2647 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
2649 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2650 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
2652 "= indicate change in local services" },
2653 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
2655 "<external> = set external processing of service discovery" },
2656 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
2658 "= remove all stored service entries" },
2659 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
2661 "<bonjour|upnp> <query|version> <response|service> = add a local "
2663 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
2665 "<bonjour|upnp> <query|version> [|service] = remove a local "
2667 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
2669 "<addr> = reject connection attempts from a specific peer" },
2670 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
2672 "<cmd> [peer=addr] = invite peer" },
2673 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
2674 "[discovered] = list known (optionally, only fully discovered) P2P "
2676 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
2678 "<address> = show information about known P2P peer" },
2679 { "p2p_set", wpa_cli_cmd_p2p_set, NULL, cli_cmd_flag_none,
2680 "<field> <value> = set a P2P parameter" },
2681 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
2682 "= flush P2P state" },
2683 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
2684 "= cancel P2P group formation" },
2685 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
2686 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2687 "<address> = unauthorize a peer" },
2688 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
2690 "[<duration> <interval>] [<duration> <interval>] = request GO "
2692 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
2694 "[<period> <interval>] = set extended listen timing" },
2695 #endif /* CONFIG_P2P */
2696 #ifdef CONFIG_WIFI_DISPLAY
2697 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
2699 "<subelem> [contents] = set Wi-Fi Display subelement" },
2700 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
2702 "<subelem> = get Wi-Fi Display subelement" },
2703 #endif /* CONFIG_WIFI_DISPLAY */
2704 #ifdef CONFIG_INTERWORKING
2705 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
2706 "= fetch ANQP information for all APs" },
2707 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
2709 "= stop fetch_anqp operation" },
2710 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
2712 "[auto] = perform Interworking network selection" },
2713 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2714 wpa_cli_complete_bss, cli_cmd_flag_none,
2715 "<BSSID> = connect using Interworking credentials" },
2716 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
2718 "<addr> <info id>[,<info id>]... = request ANQP information" },
2719 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
2721 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2722 { "gas_response_get", wpa_cli_cmd_gas_response_get,
2723 wpa_cli_complete_bss, cli_cmd_flag_none,
2724 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2725 #endif /* CONFIG_INTERWORKING */
2727 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
2729 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2731 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
2732 wpa_cli_complete_bss, cli_cmd_flag_none,
2733 "<addr> <home realm> = get HS20 nai home realm list" },
2734 #endif /* CONFIG_HS20 */
2735 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
2737 "<0/1> = disable/enable automatic reconnection" },
2738 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
2740 "<addr> = request TDLS discovery with <addr>" },
2741 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
2743 "<addr> = request TDLS setup with <addr>" },
2744 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
2746 "<addr> = tear down TDLS with <addr>" },
2747 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
2749 "= get signal parameters" },
2750 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
2752 "= get TX/RX packet counters" },
2753 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
2755 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2756 #ifdef CONFIG_AUTOSCAN
2757 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
2758 "[params] = Set or unset (if none) autoscan parameters" },
2759 #endif /* CONFIG_AUTOSCAN */
2761 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
2762 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
2763 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
2764 "<query reason> = Send BSS Transition Management Query" },
2765 #endif /* CONFIG_WNM */
2766 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
2767 "<params..> = Sent unprocessed command" },
2768 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
2769 "= flush wpa_supplicant state" },
2770 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
2775 * Prints command usage, lines are padded with the specified string.
2777 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2782 printf("%s%s ", pad, cmd->cmd);
2783 for (n = 0; (c = cmd->usage[n]); n++) {
2792 static void print_help(const char *cmd)
2795 printf("commands:\n");
2796 for (n = 0; wpa_cli_commands[n].cmd; n++) {
2797 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
2798 print_cmd_help(&wpa_cli_commands[n], " ");
2803 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2805 const char *c, *delim;
2809 delim = os_strchr(cmd, ' ');
2813 len = os_strlen(cmd);
2815 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2816 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2817 return (wpa_cli_commands[n].flags &
2818 cli_cmd_flag_sensitive);
2824 static char ** wpa_list_cmd_list(void)
2829 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2830 res = os_calloc(count, sizeof(char *));
2834 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2835 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2844 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2849 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2850 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2851 if (wpa_cli_commands[i].completion)
2852 return wpa_cli_commands[i].completion(str,
2855 printf("\r%s\n", wpa_cli_commands[i].usage);
2865 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2871 end = os_strchr(str, ' ');
2872 if (end == NULL || str + pos < end)
2873 return wpa_list_cmd_list();
2875 cmd = os_malloc(pos + 1);
2878 os_memcpy(cmd, str, pos);
2879 cmd[end - str] = '\0';
2880 res = wpa_cli_cmd_completion(cmd, str, pos);
2886 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2888 struct wpa_cli_cmd *cmd, *match = NULL;
2893 cmd = wpa_cli_commands;
2895 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2898 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2899 /* we have an exact match */
2909 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2910 cmd = wpa_cli_commands;
2912 if (os_strncasecmp(cmd->cmd, argv[0],
2913 os_strlen(argv[0])) == 0) {
2914 printf(" %s", cmd->cmd);
2920 } else if (count == 0) {
2921 printf("Unknown command '%s'\n", argv[0]);
2924 ret = match->handler(ctrl, argc - 1, &argv[1]);
2931 static int str_match(const char *a, const char *b)
2933 return os_strncmp(a, b, os_strlen(b)) == 0;
2937 static int wpa_cli_exec(const char *program, const char *arg1,
2945 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2946 cmd = os_malloc(len);
2949 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2950 if (res < 0 || (size_t) res >= len) {
2954 cmd[len - 1] = '\0';
2956 if (system(cmd) < 0)
2958 #endif /* _WIN32_WCE */
2965 static void wpa_cli_action_process(const char *msg)
2968 char *copy = NULL, *id, *pos2;
2973 pos = os_strchr(pos, '>');
2980 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2982 os_unsetenv("WPA_ID");
2983 os_unsetenv("WPA_ID_STR");
2984 os_unsetenv("WPA_CTRL_DIR");
2986 pos = os_strstr(pos, "[id=");
2988 copy = os_strdup(pos + 4);
2992 while (*pos2 && *pos2 != ' ')
2996 os_setenv("WPA_ID", id, 1);
2997 while (*pos2 && *pos2 != '=')
3002 while (*pos2 && *pos2 != ']')
3005 os_setenv("WPA_ID_STR", id, 1);
3009 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3011 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3012 wpa_cli_connected = 1;
3013 wpa_cli_last_id = new_id;
3014 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3016 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3017 if (wpa_cli_connected) {
3018 wpa_cli_connected = 0;
3019 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3021 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3022 wpa_cli_exec(action_file, ctrl_ifname, pos);
3023 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3024 wpa_cli_exec(action_file, ctrl_ifname, pos);
3025 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3026 wpa_cli_exec(action_file, ctrl_ifname, pos);
3027 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3028 wpa_cli_exec(action_file, ctrl_ifname, pos);
3029 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3030 wpa_cli_exec(action_file, ctrl_ifname, pos);
3031 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3032 wpa_cli_exec(action_file, ctrl_ifname, pos);
3033 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3034 wpa_cli_exec(action_file, ctrl_ifname, pos);
3035 } else if (str_match(pos, AP_STA_CONNECTED)) {
3036 wpa_cli_exec(action_file, ctrl_ifname, pos);
3037 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3038 wpa_cli_exec(action_file, ctrl_ifname, pos);
3039 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3040 printf("wpa_supplicant is terminating - stop monitoring\n");
3046 #ifndef CONFIG_ANSI_C_EXTRA
3047 static void wpa_cli_action_cb(char *msg, size_t len)
3049 wpa_cli_action_process(msg);
3051 #endif /* CONFIG_ANSI_C_EXTRA */
3054 static void wpa_cli_reconnect(void)
3056 wpa_cli_close_connection();
3057 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3062 printf("\rConnection to wpa_supplicant re-established\n");
3068 static void cli_event(const char *str)
3070 const char *start, *s;
3072 start = os_strchr(str, '>');
3078 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3079 s = os_strchr(start, ' ');
3082 s = os_strchr(s + 1, ' ');
3085 cli_txt_list_add(&bsses, s + 1);
3089 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3090 s = os_strchr(start, ' ');
3093 s = os_strchr(s + 1, ' ');
3096 cli_txt_list_del_addr(&bsses, s + 1);
3101 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3102 s = os_strstr(start, " p2p_dev_addr=");
3105 cli_txt_list_add_addr(&p2p_peers, s + 14);
3109 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3110 s = os_strstr(start, " p2p_dev_addr=");
3113 cli_txt_list_del_addr(&p2p_peers, s + 14);
3117 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3118 s = os_strchr(start, ' ');
3121 cli_txt_list_add_word(&p2p_groups, s + 1);
3125 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3126 s = os_strchr(start, ' ');
3129 cli_txt_list_del_word(&p2p_groups, s + 1);
3132 #endif /* CONFIG_P2P */
3136 static int check_terminating(const char *msg)
3138 const char *pos = msg;
3142 pos = os_strchr(pos, '>');
3149 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3151 printf("\rConnection to wpa_supplicant lost - trying to "
3154 wpa_cli_attached = 0;
3155 wpa_cli_close_connection();
3163 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3165 if (ctrl_conn == NULL) {
3166 wpa_cli_reconnect();
3169 while (wpa_ctrl_pending(ctrl) > 0) {
3171 size_t len = sizeof(buf) - 1;
3172 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3175 wpa_cli_action_process(buf);
3178 if (wpa_cli_show_event(buf)) {
3180 printf("\r%s\n", buf);
3184 if (interactive && check_terminating(buf) > 0)
3188 printf("Could not read pending message.\n");
3193 if (wpa_ctrl_pending(ctrl) < 0) {
3194 printf("Connection to wpa_supplicant lost - trying to "
3196 wpa_cli_reconnect();
3202 static int tokenize_cmd(char *cmd, char *argv[])
3215 if (argc == max_args)
3218 char *pos2 = os_strrchr(pos, '"');
3222 while (*pos != '\0' && *pos != ' ')
3232 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3234 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3235 printf("Connection to wpa_supplicant lost - trying to "
3237 wpa_cli_close_connection();
3240 wpa_cli_reconnect();
3241 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3245 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3247 wpa_cli_recv_pending(mon_conn, 0);
3251 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3253 char *argv[max_args];
3255 argc = tokenize_cmd(cmd, argv);
3257 wpa_request(ctrl_conn, argc, argv);
3261 static void wpa_cli_edit_eof_cb(void *ctx)
3267 static int warning_displayed = 0;
3268 static char *hfile = NULL;
3269 static int edit_started = 0;
3271 static void start_edit(void)
3276 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3277 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3278 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3280 home = getenv("HOME");
3282 const char *fname = ".wpa_cli_history";
3283 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3284 hfile = os_malloc(hfile_len);
3286 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3289 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3290 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3296 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3300 static void update_bssid_list(struct wpa_ctrl *ctrl)
3303 size_t len = sizeof(buf);
3305 char *cmd = "BSS RANGE=ALL MASK=0x2";
3310 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3317 pos = os_strstr(pos, "bssid=");
3321 end = os_strchr(pos, '\n');
3325 cli_txt_list_add(&bsses, pos);
3331 static void try_connection(void *eloop_ctx, void *timeout_ctx)
3336 if (ctrl_ifname == NULL)
3337 ctrl_ifname = wpa_cli_get_default_ifname();
3339 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3340 if (!warning_displayed) {
3341 printf("Could not connect to wpa_supplicant: "
3342 "%s - re-trying\n", ctrl_ifname);
3343 warning_displayed = 1;
3345 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
3349 update_bssid_list(ctrl_conn);
3351 if (warning_displayed)
3352 printf("Connection established.\n");
3359 static void wpa_cli_interactive(void)
3361 printf("\nInteractive mode\n\n");
3363 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
3365 eloop_cancel_timeout(try_connection, NULL, NULL);
3367 cli_txt_list_flush(&p2p_peers);
3368 cli_txt_list_flush(&p2p_groups);
3369 cli_txt_list_flush(&bsses);
3371 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3373 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3374 wpa_cli_close_connection();
3378 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3380 #ifdef CONFIG_ANSI_C_EXTRA
3381 /* TODO: ANSI C version(?) */
3382 printf("Action processing not supported in ANSI C build.\n");
3383 #else /* CONFIG_ANSI_C_EXTRA */
3387 char buf[256]; /* note: large enough to fit in unsolicited messages */
3390 fd = wpa_ctrl_get_fd(ctrl);
3392 while (!wpa_cli_quit) {
3395 tv.tv_sec = ping_interval;
3397 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3398 if (res < 0 && errno != EINTR) {
3403 if (FD_ISSET(fd, &rfds))
3404 wpa_cli_recv_pending(ctrl, 1);
3406 /* verify that connection is still working */
3407 len = sizeof(buf) - 1;
3408 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3409 wpa_cli_action_cb) < 0 ||
3410 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3411 printf("wpa_supplicant did not reply to PING "
3412 "command - exiting\n");
3417 #endif /* CONFIG_ANSI_C_EXTRA */
3421 static void wpa_cli_cleanup(void)
3423 wpa_cli_close_connection();
3425 os_daemonize_terminate(pid_file);
3427 os_program_deinit();
3431 static void wpa_cli_terminate(int sig, void *ctx)
3437 static char * wpa_cli_get_default_ifname(void)
3439 char *ifname = NULL;
3441 #ifdef CONFIG_CTRL_IFACE_UNIX
3442 struct dirent *dent;
3443 DIR *dir = opendir(ctrl_iface_dir);
3446 char ifprop[PROPERTY_VALUE_MAX];
3447 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3448 ifname = os_strdup(ifprop);
3449 printf("Using interface '%s'\n", ifname);
3452 #endif /* ANDROID */
3455 while ((dent = readdir(dir))) {
3456 #ifdef _DIRENT_HAVE_D_TYPE
3458 * Skip the file if it is not a socket. Also accept
3459 * DT_UNKNOWN (0) in case the C library or underlying
3460 * file system does not support d_type.
3462 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3464 #endif /* _DIRENT_HAVE_D_TYPE */
3465 if (os_strcmp(dent->d_name, ".") == 0 ||
3466 os_strcmp(dent->d_name, "..") == 0)
3468 printf("Selected interface '%s'\n", dent->d_name);
3469 ifname = os_strdup(dent->d_name);
3473 #endif /* CONFIG_CTRL_IFACE_UNIX */
3475 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3476 char buf[4096], *pos;
3478 struct wpa_ctrl *ctrl;
3481 ctrl = wpa_ctrl_open(NULL);
3485 len = sizeof(buf) - 1;
3486 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3489 pos = os_strchr(buf, '\n');
3492 ifname = os_strdup(buf);
3494 wpa_ctrl_close(ctrl);
3495 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3501 int main(int argc, char *argv[])
3506 const char *global = NULL;
3508 if (os_program_init())
3512 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3517 action_file = optarg;
3526 ping_interval = atoi(optarg);
3532 printf("%s\n", wpa_cli_version);
3535 os_free(ctrl_ifname);
3536 ctrl_ifname = os_strdup(optarg);
3539 ctrl_iface_dir = optarg;
3550 interactive = (argc == optind) && (action_file == NULL);
3553 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3559 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3560 ctrl_conn = wpa_ctrl_open(NULL);
3561 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3562 ctrl_conn = wpa_ctrl_open(global);
3563 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3564 if (ctrl_conn == NULL) {
3565 fprintf(stderr, "Failed to connect to wpa_supplicant "
3566 "global interface: %s error: %s\n",
3567 global, strerror(errno));
3572 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
3574 if (ctrl_ifname == NULL)
3575 ctrl_ifname = wpa_cli_get_default_ifname();
3578 wpa_cli_interactive();
3581 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3582 fprintf(stderr, "Failed to connect to non-global "
3583 "ctrl_ifname: %s error: %s\n",
3584 ctrl_ifname, strerror(errno));
3589 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3590 wpa_cli_attached = 1;
3592 printf("Warning: Failed to attach to "
3593 "wpa_supplicant.\n");
3598 if (daemonize && os_daemonize(pid_file))
3602 wpa_cli_action(ctrl_conn);
3604 ret = wpa_request(ctrl_conn, argc - optind,
3608 os_free(ctrl_ifname);
3615 #else /* CONFIG_CTRL_IFACE */
3616 int main(int argc, char *argv[])
3618 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3621 #endif /* CONFIG_CTRL_IFACE */