2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
23 #include "common/wpa_ctrl.h"
24 #include "utils/common.h"
25 #include "utils/eloop.h"
26 #include "utils/edit.h"
27 #include "utils/list.h"
28 #include "common/version.h"
30 #include <cutils/properties.h>
34 static const char *wpa_cli_version =
35 "wpa_cli v" VERSION_STR "\n"
36 "Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors";
39 static const char *wpa_cli_license =
40 "This program is free software. You can distribute it and/or modify it\n"
41 "under the terms of the GNU General Public License version 2.\n"
43 "Alternatively, this software may be distributed under the terms of the\n"
44 "BSD license. See README and COPYING for more details.\n";
46 static const char *wpa_cli_full_license =
47 "This program is free software; you can redistribute it and/or modify\n"
48 "it under the terms of the GNU General Public License version 2 as\n"
49 "published by the Free Software Foundation.\n"
51 "This program is distributed in the hope that it will be useful,\n"
52 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
53 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
54 "GNU General Public License for more details.\n"
56 "You should have received a copy of the GNU General Public License\n"
57 "along with this program; if not, write to the Free Software\n"
58 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
60 "Alternatively, this software may be distributed under the terms of the\n"
63 "Redistribution and use in source and binary forms, with or without\n"
64 "modification, are permitted provided that the following conditions are\n"
67 "1. Redistributions of source code must retain the above copyright\n"
68 " notice, this list of conditions and the following disclaimer.\n"
70 "2. Redistributions in binary form must reproduce the above copyright\n"
71 " notice, this list of conditions and the following disclaimer in the\n"
72 " documentation and/or other materials provided with the distribution.\n"
74 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
75 " names of its contributors may be used to endorse or promote products\n"
76 " derived from this software without specific prior written permission.\n"
78 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
79 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
80 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
81 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
82 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
83 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
84 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
85 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
86 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
87 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
88 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
91 static struct wpa_ctrl *ctrl_conn;
92 static struct wpa_ctrl *mon_conn;
93 static int wpa_cli_quit = 0;
94 static int wpa_cli_attached = 0;
95 static int wpa_cli_connected = 0;
96 static int wpa_cli_last_id = 0;
97 #ifndef CONFIG_CTRL_IFACE_DIR
98 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
99 #endif /* CONFIG_CTRL_IFACE_DIR */
100 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
101 static char *ctrl_ifname = NULL;
102 static const char *pid_file = NULL;
103 static const char *action_file = NULL;
104 static int ping_interval = 5;
105 static int interactive = 0;
107 struct cli_txt_entry {
112 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
113 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
114 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
117 static void print_help(void);
118 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
121 static void usage(void)
123 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
124 "[-a<action file>] \\\n"
125 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
127 " -h = help (show this usage text)\n"
128 " -v = shown version information\n"
129 " -a = run in daemon mode executing the action file based on "
132 " -B = run a daemon in the background\n"
133 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
134 " default interface: first interface found in socket path\n");
139 static void cli_txt_list_free(struct cli_txt_entry *e)
141 dl_list_del(&e->list);
147 static void cli_txt_list_flush(struct dl_list *list)
149 struct cli_txt_entry *e;
150 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
151 cli_txt_list_free(e);
155 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
158 struct cli_txt_entry *e;
159 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
160 if (os_strcmp(e->txt, txt) == 0)
167 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
169 struct cli_txt_entry *e;
170 e = cli_txt_list_get(txt_list, txt);
172 cli_txt_list_free(e);
176 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
180 if (hwaddr_aton(txt, addr) < 0)
182 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
183 cli_txt_list_del(txt_list, buf);
188 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
192 end = os_strchr(txt, ' ');
194 end = txt + os_strlen(txt);
195 buf = os_malloc(end - txt + 1);
198 os_memcpy(buf, txt, end - txt);
199 buf[end - txt] = '\0';
200 cli_txt_list_del(txt_list, buf);
203 #endif /* CONFIG_P2P */
206 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
208 struct cli_txt_entry *e;
209 e = cli_txt_list_get(txt_list, txt);
212 e = os_zalloc(sizeof(*e));
215 e->txt = os_strdup(txt);
216 if (e->txt == NULL) {
220 dl_list_add(txt_list, &e->list);
226 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
230 if (hwaddr_aton(txt, addr) < 0)
232 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
233 return cli_txt_list_add(txt_list, buf);
237 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
242 end = os_strchr(txt, ' ');
244 end = txt + os_strlen(txt);
245 buf = os_malloc(end - txt + 1);
248 os_memcpy(buf, txt, end - txt);
249 buf[end - txt] = '\0';
250 ret = cli_txt_list_add(txt_list, buf);
254 #endif /* CONFIG_P2P */
257 static char ** cli_txt_list_array(struct dl_list *txt_list)
259 unsigned int i, count = dl_list_len(txt_list);
261 struct cli_txt_entry *e;
263 res = os_zalloc((count + 1) * sizeof(char *));
268 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
269 res[i] = os_strdup(e->txt);
279 static int get_cmd_arg_num(const char *str, int pos)
283 for (i = 0; i <= pos; i++) {
286 while (i <= pos && str[i] != ' ')
297 static int str_starts(const char *src, const char *match)
299 return os_strncmp(src, match, os_strlen(match)) == 0;
303 static int wpa_cli_show_event(const char *event)
307 start = os_strchr(event, '>');
313 * Skip BSS added/removed events since they can be relatively frequent
314 * and are likely of not much use for an interactive user.
316 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
317 str_starts(start, WPA_EVENT_BSS_REMOVED))
324 static int wpa_cli_open_connection(const char *ifname, int attach)
326 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
327 ctrl_conn = wpa_ctrl_open(ifname);
328 if (ctrl_conn == NULL)
331 if (attach && interactive)
332 mon_conn = wpa_ctrl_open(ifname);
335 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
343 if (access(ctrl_iface_dir, F_OK) < 0) {
344 cfile = os_strdup(ifname);
351 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
352 cfile = os_malloc(flen);
355 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
357 if (res < 0 || res >= flen) {
363 ctrl_conn = wpa_ctrl_open(cfile);
364 if (ctrl_conn == NULL) {
369 if (attach && interactive)
370 mon_conn = wpa_ctrl_open(cfile);
374 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
377 if (wpa_ctrl_attach(mon_conn) == 0) {
378 wpa_cli_attached = 1;
380 eloop_register_read_sock(
381 wpa_ctrl_get_fd(mon_conn),
382 wpa_cli_mon_receive, NULL, NULL);
384 printf("Warning: Failed to attach to "
385 "wpa_supplicant.\n");
394 static void wpa_cli_close_connection(void)
396 if (ctrl_conn == NULL)
399 if (wpa_cli_attached) {
400 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
401 wpa_cli_attached = 0;
403 wpa_ctrl_close(ctrl_conn);
406 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
407 wpa_ctrl_close(mon_conn);
413 static void wpa_cli_msg_cb(char *msg, size_t len)
419 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
425 if (ctrl_conn == NULL) {
426 printf("Not connected to wpa_supplicant - command dropped.\n");
429 len = sizeof(buf) - 1;
430 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
433 printf("'%s' command timed out.\n", cmd);
435 } else if (ret < 0) {
436 printf("'%s' command failed.\n", cmd);
442 if (interactive && len > 0 && buf[len - 1] != '\n')
449 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
451 return _wpa_ctrl_command(ctrl, cmd, 1);
455 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
457 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
458 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
459 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
460 return wpa_ctrl_command(ctrl, "STATUS-WPS");
461 return wpa_ctrl_command(ctrl, "STATUS");
465 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
467 return wpa_ctrl_command(ctrl, "PING");
471 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
473 return wpa_ctrl_command(ctrl, "RELOG");
477 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
483 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
484 if (ret < 0 || (size_t) ret >= sizeof(cmd))
486 return wpa_ctrl_command(ctrl, cmd);
490 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
492 return wpa_ctrl_command(ctrl, "MIB");
496 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
498 return wpa_ctrl_command(ctrl, "PMKSA");
502 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
509 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
511 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
516 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
525 static void wpa_cli_show_variables(void)
527 printf("set variables:\n"
528 " EAPOL::heldPeriod (EAPOL state machine held period, "
530 " EAPOL::authPeriod (EAPOL state machine authentication "
531 "period, in seconds)\n"
532 " EAPOL::startPeriod (EAPOL state machine start period, in "
534 " EAPOL::maxStart (EAPOL state machine maximum start "
536 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
538 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
539 " threshold\n\tpercentage)\n"
540 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
541 "security\n\tassociation in seconds)\n");
545 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
551 wpa_cli_show_variables();
555 if (argc != 1 && argc != 2) {
556 printf("Invalid SET command: needs two arguments (variable "
557 "name and value)\n");
562 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
564 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s",
566 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
567 printf("Too long SET command.\n");
570 return wpa_ctrl_command(ctrl, cmd);
574 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
580 printf("Invalid GET command: need one argument (variable "
585 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
586 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
587 printf("Too long GET command.\n");
590 return wpa_ctrl_command(ctrl, cmd);
594 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
596 return wpa_ctrl_command(ctrl, "LOGOFF");
600 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
602 return wpa_ctrl_command(ctrl, "LOGON");
606 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
609 return wpa_ctrl_command(ctrl, "REASSOCIATE");
613 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
620 printf("Invalid PREAUTH command: needs one argument "
625 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
626 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
627 printf("Too long PREAUTH command.\n");
630 return wpa_ctrl_command(ctrl, cmd);
634 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
640 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
644 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
645 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
646 printf("Too long AP_SCAN command.\n");
649 return wpa_ctrl_command(ctrl, cmd);
653 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
660 printf("Invalid SCAN_INTERVAL command: needs one argument "
661 "scan_interval value)\n");
664 res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
665 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
666 printf("Too long SCAN_INTERVAL command.\n");
669 return wpa_ctrl_command(ctrl, cmd);
673 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
680 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
681 "(bss_expire_age value)\n");
684 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
685 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
686 printf("Too long BSS_EXPIRE_AGE command.\n");
689 return wpa_ctrl_command(ctrl, cmd);
693 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
700 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
701 "(bss_expire_count value)\n");
704 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
705 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
706 printf("Too long BSS_EXPIRE_COUNT command.\n");
709 return wpa_ctrl_command(ctrl, cmd);
713 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
720 printf("Invalid STKSTART command: needs one argument "
721 "(Peer STA MAC address)\n");
725 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
726 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
727 printf("Too long STKSTART command.\n");
730 return wpa_ctrl_command(ctrl, cmd);
734 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
740 printf("Invalid FT_DS command: needs one argument "
741 "(Target AP MAC address)\n");
745 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
746 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
747 printf("Too long FT_DS command.\n");
750 return wpa_ctrl_command(ctrl, cmd);
754 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
761 return wpa_ctrl_command(ctrl, "WPS_PBC");
765 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
766 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
767 printf("Too long WPS_PBC command.\n");
770 return wpa_ctrl_command(ctrl, cmd);
774 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
780 printf("Invalid WPS_PIN command: need one or two arguments:\n"
781 "- BSSID: use 'any' to select any\n"
782 "- PIN: optional, used only with devices that have no "
788 /* Use dynamically generated PIN (returned as reply) */
789 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
790 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
791 printf("Too long WPS_PIN command.\n");
794 return wpa_ctrl_command(ctrl, cmd);
797 /* Use hardcoded PIN from a label */
798 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
799 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
800 printf("Too long WPS_PIN command.\n");
803 return wpa_ctrl_command(ctrl, cmd);
807 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
813 if (argc != 1 && argc != 2) {
814 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
815 "- PIN to be verified\n");
820 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
823 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
825 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
826 printf("Too long WPS_CHECK_PIN command.\n");
829 return wpa_ctrl_command(ctrl, cmd);
833 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
836 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
840 #ifdef CONFIG_WPS_OOB
841 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
846 if (argc != 3 && argc != 4) {
847 printf("Invalid WPS_OOB command: need three or four "
849 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
850 "- PATH: path of OOB device like '/mnt'\n"
851 "- METHOD: OOB method 'pin-e' or 'pin-r', "
853 "- DEV_NAME: (only for NFC) device name like "
859 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
860 argv[0], argv[1], argv[2]);
862 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
863 argv[0], argv[1], argv[2], argv[3]);
864 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
865 printf("Too long WPS_OOB command.\n");
868 return wpa_ctrl_command(ctrl, cmd);
870 #endif /* CONFIG_WPS_OOB */
873 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
879 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
881 else if (argc == 5 || argc == 6) {
882 char ssid_hex[2 * 32 + 1];
883 char key_hex[2 * 64 + 1];
887 for (i = 0; i < 32; i++) {
888 if (argv[2][i] == '\0')
890 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
895 for (i = 0; i < 64; i++) {
896 if (argv[5][i] == '\0')
898 os_snprintf(&key_hex[i * 2], 3, "%02x",
903 res = os_snprintf(cmd, sizeof(cmd),
904 "WPS_REG %s %s %s %s %s %s",
905 argv[0], argv[1], ssid_hex, argv[3], argv[4],
908 printf("Invalid WPS_REG command: need two arguments:\n"
909 "- BSSID of the target AP\n"
911 printf("Alternatively, six arguments can be used to "
912 "reconfigure the AP:\n"
913 "- BSSID of the target AP\n"
916 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
917 "- new encr (NONE, WEP, TKIP, CCMP)\n"
922 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
923 printf("Too long WPS_REG command.\n");
926 return wpa_ctrl_command(ctrl, cmd);
930 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
937 printf("Invalid WPS_AP_PIN command: needs at least one "
943 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
944 argv[0], argv[1], argv[2]);
946 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
949 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
951 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
952 printf("Too long WPS_AP_PIN command.\n");
955 return wpa_ctrl_command(ctrl, cmd);
959 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
964 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
965 return wpa_ctrl_command(ctrl, cmd);
967 return wpa_ctrl_command(ctrl, "WPS_ER_START");
971 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
974 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
979 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
986 printf("Invalid WPS_ER_PIN command: need at least two "
988 "- UUID: use 'any' to select any\n"
989 "- PIN: Enrollee PIN\n"
990 "optional: - Enrollee MAC address\n");
995 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
996 argv[0], argv[1], argv[2]);
998 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
1000 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1001 printf("Too long WPS_ER_PIN command.\n");
1004 return wpa_ctrl_command(ctrl, cmd);
1008 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
1015 printf("Invalid WPS_ER_PBC command: need one argument:\n"
1016 "- UUID: Specify the Enrollee\n");
1020 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
1022 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1023 printf("Too long WPS_ER_PBC command.\n");
1026 return wpa_ctrl_command(ctrl, cmd);
1030 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1037 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1038 "- UUID: specify which AP to use\n"
1043 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
1045 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1046 printf("Too long WPS_ER_LEARN command.\n");
1049 return wpa_ctrl_command(ctrl, cmd);
1053 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1060 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1062 "- UUID: specify which AP to use\n"
1063 "- Network configuration id\n");
1067 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
1069 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1070 printf("Too long WPS_ER_SET_CONFIG command.\n");
1073 return wpa_ctrl_command(ctrl, cmd);
1077 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1083 if (argc == 5 || argc == 6) {
1084 char ssid_hex[2 * 32 + 1];
1085 char key_hex[2 * 64 + 1];
1089 for (i = 0; i < 32; i++) {
1090 if (argv[2][i] == '\0')
1092 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1097 for (i = 0; i < 64; i++) {
1098 if (argv[5][i] == '\0')
1100 os_snprintf(&key_hex[i * 2], 3, "%02x",
1105 res = os_snprintf(cmd, sizeof(cmd),
1106 "WPS_ER_CONFIG %s %s %s %s %s %s",
1107 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1110 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1114 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1115 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1120 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1121 printf("Too long WPS_ER_CONFIG command.\n");
1124 return wpa_ctrl_command(ctrl, cmd);
1128 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1134 printf("Invalid IBSS_RSN command: needs one argument "
1135 "(Peer STA MAC address)\n");
1139 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
1140 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1141 printf("Too long IBSS_RSN command.\n");
1144 return wpa_ctrl_command(ctrl, cmd);
1148 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1154 printf("Invalid LEVEL command: needs one argument (debug "
1158 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
1159 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1160 printf("Too long LEVEL command.\n");
1163 return wpa_ctrl_command(ctrl, cmd);
1167 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1169 char cmd[256], *pos, *end;
1173 printf("Invalid IDENTITY command: needs two arguments "
1174 "(network id and identity)\n");
1178 end = cmd + sizeof(cmd);
1180 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1182 if (ret < 0 || ret >= end - pos) {
1183 printf("Too long IDENTITY command.\n");
1187 for (i = 2; i < argc; i++) {
1188 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1189 if (ret < 0 || ret >= end - pos) {
1190 printf("Too long IDENTITY command.\n");
1196 return wpa_ctrl_command(ctrl, cmd);
1200 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1202 char cmd[256], *pos, *end;
1206 printf("Invalid PASSWORD command: needs two arguments "
1207 "(network id and password)\n");
1211 end = cmd + sizeof(cmd);
1213 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1215 if (ret < 0 || ret >= end - pos) {
1216 printf("Too long PASSWORD command.\n");
1220 for (i = 2; i < argc; i++) {
1221 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1222 if (ret < 0 || ret >= end - pos) {
1223 printf("Too long PASSWORD command.\n");
1229 return wpa_ctrl_command(ctrl, cmd);
1233 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1236 char cmd[256], *pos, *end;
1240 printf("Invalid NEW_PASSWORD command: needs two arguments "
1241 "(network id and password)\n");
1245 end = cmd + sizeof(cmd);
1247 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1249 if (ret < 0 || ret >= end - pos) {
1250 printf("Too long NEW_PASSWORD command.\n");
1254 for (i = 2; i < argc; i++) {
1255 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1256 if (ret < 0 || ret >= end - pos) {
1257 printf("Too long NEW_PASSWORD command.\n");
1263 return wpa_ctrl_command(ctrl, cmd);
1267 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1269 char cmd[256], *pos, *end;
1273 printf("Invalid PIN command: needs two arguments "
1274 "(network id and pin)\n");
1278 end = cmd + sizeof(cmd);
1280 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1282 if (ret < 0 || ret >= end - pos) {
1283 printf("Too long PIN command.\n");
1287 for (i = 2; i < argc; i++) {
1288 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1289 if (ret < 0 || ret >= end - pos) {
1290 printf("Too long PIN command.\n");
1295 return wpa_ctrl_command(ctrl, cmd);
1299 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1301 char cmd[256], *pos, *end;
1305 printf("Invalid OTP command: needs two arguments (network "
1306 "id and password)\n");
1310 end = cmd + sizeof(cmd);
1312 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1314 if (ret < 0 || ret >= end - pos) {
1315 printf("Too long OTP command.\n");
1319 for (i = 2; i < argc; i++) {
1320 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1321 if (ret < 0 || ret >= end - pos) {
1322 printf("Too long OTP command.\n");
1328 return wpa_ctrl_command(ctrl, cmd);
1332 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1335 char cmd[256], *pos, *end;
1339 printf("Invalid PASSPHRASE command: needs two arguments "
1340 "(network id and passphrase)\n");
1344 end = cmd + sizeof(cmd);
1346 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1348 if (ret < 0 || ret >= end - pos) {
1349 printf("Too long PASSPHRASE command.\n");
1353 for (i = 2; i < argc; i++) {
1354 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1355 if (ret < 0 || ret >= end - pos) {
1356 printf("Too long PASSPHRASE command.\n");
1362 return wpa_ctrl_command(ctrl, cmd);
1366 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1368 char cmd[256], *pos, *end;
1372 printf("Invalid BSSID command: needs two arguments (network "
1377 end = cmd + sizeof(cmd);
1379 ret = os_snprintf(pos, end - pos, "BSSID");
1380 if (ret < 0 || ret >= end - pos) {
1381 printf("Too long BSSID command.\n");
1385 for (i = 0; i < argc; i++) {
1386 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1387 if (ret < 0 || ret >= end - pos) {
1388 printf("Too long BSSID command.\n");
1394 return wpa_ctrl_command(ctrl, cmd);
1398 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1400 char cmd[256], *pos, *end;
1403 end = cmd + sizeof(cmd);
1405 ret = os_snprintf(pos, end - pos, "BLACKLIST");
1406 if (ret < 0 || ret >= end - pos) {
1407 printf("Too long BLACKLIST command.\n");
1411 for (i = 0; i < argc; i++) {
1412 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1413 if (ret < 0 || ret >= end - pos) {
1414 printf("Too long BLACKLIST command.\n");
1420 return wpa_ctrl_command(ctrl, cmd);
1424 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1426 char cmd[256], *pos, *end;
1429 end = cmd + sizeof(cmd);
1431 ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
1432 if (ret < 0 || ret >= end - pos) {
1433 printf("Too long LOG_LEVEL command.\n");
1437 for (i = 0; i < argc; i++) {
1438 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1439 if (ret < 0 || ret >= end - pos) {
1440 printf("Too long LOG_LEVEL command.\n");
1446 return wpa_ctrl_command(ctrl, cmd);
1450 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1453 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1457 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1464 printf("Invalid SELECT_NETWORK command: needs one argument "
1469 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1470 if (res < 0 || (size_t) res >= sizeof(cmd))
1472 cmd[sizeof(cmd) - 1] = '\0';
1474 return wpa_ctrl_command(ctrl, cmd);
1478 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1485 printf("Invalid ENABLE_NETWORK command: needs one argument "
1490 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1491 if (res < 0 || (size_t) res >= sizeof(cmd))
1493 cmd[sizeof(cmd) - 1] = '\0';
1495 return wpa_ctrl_command(ctrl, cmd);
1499 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1506 printf("Invalid DISABLE_NETWORK command: needs one argument "
1511 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1512 if (res < 0 || (size_t) res >= sizeof(cmd))
1514 cmd[sizeof(cmd) - 1] = '\0';
1516 return wpa_ctrl_command(ctrl, cmd);
1520 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1523 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1527 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1534 printf("Invalid REMOVE_NETWORK command: needs one argument "
1539 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1540 if (res < 0 || (size_t) res >= sizeof(cmd))
1542 cmd[sizeof(cmd) - 1] = '\0';
1544 return wpa_ctrl_command(ctrl, cmd);
1548 static void wpa_cli_show_network_variables(void)
1550 printf("set_network variables:\n"
1551 " ssid (network name, SSID)\n"
1552 " psk (WPA passphrase or pre-shared key)\n"
1553 " key_mgmt (key management protocol)\n"
1554 " identity (EAP identity)\n"
1555 " password (EAP password)\n"
1558 "Note: Values are entered in the same format as the "
1559 "configuration file is using,\n"
1560 "i.e., strings values need to be inside double quotation "
1562 "For example: set_network 1 ssid \"network name\"\n"
1564 "Please see wpa_supplicant.conf documentation for full list "
1565 "of\navailable variables.\n");
1569 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1576 wpa_cli_show_network_variables();
1581 printf("Invalid SET_NETWORK command: needs three arguments\n"
1582 "(network id, variable name, and value)\n");
1586 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1587 argv[0], argv[1], argv[2]);
1588 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1589 printf("Too long SET_NETWORK command.\n");
1592 return wpa_ctrl_command(ctrl, cmd);
1596 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1603 wpa_cli_show_network_variables();
1608 printf("Invalid GET_NETWORK command: needs two arguments\n"
1609 "(network id and variable name)\n");
1613 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1615 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1616 printf("Too long GET_NETWORK command.\n");
1619 return wpa_ctrl_command(ctrl, cmd);
1623 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1626 return wpa_ctrl_command(ctrl, "DISCONNECT");
1630 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1633 return wpa_ctrl_command(ctrl, "RECONNECT");
1637 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1640 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1644 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1646 return wpa_ctrl_command(ctrl, "SCAN");
1650 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1653 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1657 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1663 printf("Invalid BSS command: need one argument (index or "
1668 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1669 if (res < 0 || (size_t) res >= sizeof(cmd))
1671 cmd[sizeof(cmd) - 1] = '\0';
1673 return wpa_ctrl_command(ctrl, cmd);
1677 static char ** wpa_cli_complete_bss(const char *str, int pos)
1679 int arg = get_cmd_arg_num(str, pos);
1684 res = cli_txt_list_array(&bsses);
1692 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1698 if (argc < 1 || argc > 2) {
1699 printf("Invalid GET_CAPABILITY command: need either one or "
1704 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1705 printf("Invalid GET_CAPABILITY command: second argument, "
1706 "if any, must be 'strict'\n");
1710 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1711 (argc == 2) ? " strict" : "");
1712 if (res < 0 || (size_t) res >= sizeof(cmd))
1714 cmd[sizeof(cmd) - 1] = '\0';
1716 return wpa_ctrl_command(ctrl, cmd);
1720 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1722 printf("Available interfaces:\n");
1723 return wpa_ctrl_command(ctrl, "INTERFACES");
1727 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1730 wpa_cli_list_interfaces(ctrl);
1734 wpa_cli_close_connection();
1735 os_free(ctrl_ifname);
1736 ctrl_ifname = os_strdup(argv[0]);
1738 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1739 printf("Connected to interface '%s.\n", ctrl_ifname);
1741 printf("Could not connect to interface '%s' - re-trying\n",
1748 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1751 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1755 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1758 return wpa_ctrl_command(ctrl, "TERMINATE");
1762 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1769 printf("Invalid INTERFACE_ADD command: needs at least one "
1770 "argument (interface name)\n"
1771 "All arguments: ifname confname driver ctrl_interface "
1772 "driver_param bridge_name\n");
1777 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1778 * <driver_param>TAB<bridge_name>
1780 res = os_snprintf(cmd, sizeof(cmd),
1781 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1783 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1784 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1785 argc > 5 ? argv[5] : "");
1786 if (res < 0 || (size_t) res >= sizeof(cmd))
1788 cmd[sizeof(cmd) - 1] = '\0';
1789 return wpa_ctrl_command(ctrl, cmd);
1793 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1800 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1801 "(interface name)\n");
1805 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1806 if (res < 0 || (size_t) res >= sizeof(cmd))
1808 cmd[sizeof(cmd) - 1] = '\0';
1809 return wpa_ctrl_command(ctrl, cmd);
1813 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1816 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1821 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1825 printf("Invalid 'sta' command - exactly one argument, STA "
1826 "address, is required.\n");
1829 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1830 return wpa_ctrl_command(ctrl, buf);
1834 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1835 char *addr, size_t addr_len)
1837 char buf[4096], *pos;
1841 if (ctrl_conn == NULL) {
1842 printf("Not connected to hostapd - command dropped.\n");
1845 len = sizeof(buf) - 1;
1846 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1849 printf("'%s' command timed out.\n", cmd);
1851 } else if (ret < 0) {
1852 printf("'%s' command failed.\n", cmd);
1857 if (memcmp(buf, "FAIL", 4) == 0)
1862 while (*pos != '\0' && *pos != '\n')
1865 os_strlcpy(addr, buf, addr_len);
1870 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1872 char addr[32], cmd[64];
1874 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1877 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1878 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1882 #endif /* CONFIG_AP */
1885 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1887 return wpa_ctrl_command(ctrl, "SUSPEND");
1891 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1893 return wpa_ctrl_command(ctrl, "RESUME");
1897 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1899 return wpa_ctrl_command(ctrl, "DROP_SA");
1903 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1909 printf("Invalid ROAM command: needs one argument "
1910 "(target AP's BSSID)\n");
1914 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1915 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1916 printf("Too long ROAM command.\n");
1919 return wpa_ctrl_command(ctrl, cmd);
1925 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1931 return wpa_ctrl_command(ctrl, "P2P_FIND");
1934 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s",
1935 argv[0], argv[1], argv[2]);
1937 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1940 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1941 if (res < 0 || (size_t) res >= sizeof(cmd))
1943 cmd[sizeof(cmd) - 1] = '\0';
1944 return wpa_ctrl_command(ctrl, cmd);
1948 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1951 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1955 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1962 printf("Invalid P2P_CONNECT command: needs at least two "
1963 "arguments (address and pbc/PIN)\n");
1968 res = os_snprintf(cmd, sizeof(cmd),
1969 "P2P_CONNECT %s %s %s %s %s",
1970 argv[0], argv[1], argv[2], argv[3],
1973 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1974 argv[0], argv[1], argv[2], argv[3]);
1976 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1977 argv[0], argv[1], argv[2]);
1979 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1981 if (res < 0 || (size_t) res >= sizeof(cmd))
1983 cmd[sizeof(cmd) - 1] = '\0';
1984 return wpa_ctrl_command(ctrl, cmd);
1988 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1990 int arg = get_cmd_arg_num(str, pos);
1995 res = cli_txt_list_array(&p2p_peers);
2003 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2010 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
2012 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
2013 if (res < 0 || (size_t) res >= sizeof(cmd))
2015 cmd[sizeof(cmd) - 1] = '\0';
2016 return wpa_ctrl_command(ctrl, cmd);
2020 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2027 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2028 "(interface name)\n");
2032 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
2033 if (res < 0 || (size_t) res >= sizeof(cmd))
2035 cmd[sizeof(cmd) - 1] = '\0';
2036 return wpa_ctrl_command(ctrl, cmd);
2040 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2042 int arg = get_cmd_arg_num(str, pos);
2047 res = cli_txt_list_array(&p2p_groups);
2055 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2062 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
2065 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
2068 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
2070 if (res < 0 || (size_t) res >= sizeof(cmd))
2072 cmd[sizeof(cmd) - 1] = '\0';
2073 return wpa_ctrl_command(ctrl, cmd);
2077 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2083 if (argc != 2 && argc != 3) {
2084 printf("Invalid P2P_PROV_DISC command: needs at least "
2085 "two arguments, address and config method\n"
2086 "(display, keypad, or pbc) and an optional join\n");
2091 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
2092 argv[0], argv[1], argv[2]);
2094 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
2096 if (res < 0 || (size_t) res >= sizeof(cmd))
2098 cmd[sizeof(cmd) - 1] = '\0';
2099 return wpa_ctrl_command(ctrl, cmd);
2103 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2106 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2110 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2116 if (argc != 2 && argc != 4) {
2117 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2118 "arguments (address and TLVs) or four arguments "
2119 "(address, \"upnp\", version, search target "
2125 res = os_snprintf(cmd, sizeof(cmd),
2126 "P2P_SERV_DISC_REQ %s %s %s %s",
2127 argv[0], argv[1], argv[2], argv[3]);
2129 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
2131 if (res < 0 || (size_t) res >= sizeof(cmd))
2133 cmd[sizeof(cmd) - 1] = '\0';
2134 return wpa_ctrl_command(ctrl, cmd);
2138 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2139 int argc, char *argv[])
2145 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2146 "argument (pending request identifier)\n");
2150 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
2152 if (res < 0 || (size_t) res >= sizeof(cmd))
2154 cmd[sizeof(cmd) - 1] = '\0';
2155 return wpa_ctrl_command(ctrl, cmd);
2159 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2166 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2167 "arguments (freq, address, dialog token, and TLVs)\n");
2171 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2172 argv[0], argv[1], argv[2], argv[3]);
2173 if (res < 0 || (size_t) res >= sizeof(cmd))
2175 cmd[sizeof(cmd) - 1] = '\0';
2176 return wpa_ctrl_command(ctrl, cmd);
2180 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2183 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2187 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2188 int argc, char *argv[])
2194 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2195 "argument (external processing: 0/1)\n");
2199 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
2201 if (res < 0 || (size_t) res >= sizeof(cmd))
2203 cmd[sizeof(cmd) - 1] = '\0';
2204 return wpa_ctrl_command(ctrl, cmd);
2208 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2211 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2215 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2221 if (argc != 3 && argc != 4) {
2222 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2228 res = os_snprintf(cmd, sizeof(cmd),
2229 "P2P_SERVICE_ADD %s %s %s %s",
2230 argv[0], argv[1], argv[2], argv[3]);
2232 res = os_snprintf(cmd, sizeof(cmd),
2233 "P2P_SERVICE_ADD %s %s %s",
2234 argv[0], argv[1], argv[2]);
2235 if (res < 0 || (size_t) res >= sizeof(cmd))
2237 cmd[sizeof(cmd) - 1] = '\0';
2238 return wpa_ctrl_command(ctrl, cmd);
2242 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2248 if (argc != 2 && argc != 3) {
2249 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2255 res = os_snprintf(cmd, sizeof(cmd),
2256 "P2P_SERVICE_DEL %s %s %s",
2257 argv[0], argv[1], argv[2]);
2259 res = os_snprintf(cmd, sizeof(cmd),
2260 "P2P_SERVICE_DEL %s %s",
2262 if (res < 0 || (size_t) res >= sizeof(cmd))
2264 cmd[sizeof(cmd) - 1] = '\0';
2265 return wpa_ctrl_command(ctrl, cmd);
2269 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2270 int argc, char *argv[])
2276 printf("Invalid P2P_REJECT command: needs one argument "
2277 "(peer address)\n");
2281 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2282 if (res < 0 || (size_t) res >= sizeof(cmd))
2284 cmd[sizeof(cmd) - 1] = '\0';
2285 return wpa_ctrl_command(ctrl, cmd);
2289 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2290 int argc, char *argv[])
2296 printf("Invalid P2P_INVITE command: needs at least one "
2302 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2303 argv[0], argv[1], argv[2]);
2305 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2308 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2309 if (res < 0 || (size_t) res >= sizeof(cmd))
2311 cmd[sizeof(cmd) - 1] = '\0';
2312 return wpa_ctrl_command(ctrl, cmd);
2316 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2320 printf("Invalid 'p2p_peer' command - exactly one argument, "
2321 "P2P peer device address, is required.\n");
2324 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2325 return wpa_ctrl_command(ctrl, buf);
2329 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2331 int arg = get_cmd_arg_num(str, pos);
2336 res = cli_txt_list_array(&p2p_peers);
2344 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2345 char *addr, size_t addr_len,
2348 char buf[4096], *pos;
2352 if (ctrl_conn == NULL)
2354 len = sizeof(buf) - 1;
2355 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2358 printf("'%s' command timed out.\n", cmd);
2360 } else if (ret < 0) {
2361 printf("'%s' command failed.\n", cmd);
2366 if (memcmp(buf, "FAIL", 4) == 0)
2370 while (*pos != '\0' && *pos != '\n')
2373 os_strlcpy(addr, buf, addr_len);
2374 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2375 printf("%s\n", addr);
2380 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2382 char addr[32], cmd[64];
2385 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2387 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2388 addr, sizeof(addr), discovered))
2391 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2392 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2399 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2405 printf("Invalid P2P_SET command: needs two arguments (field, "
2410 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2411 if (res < 0 || (size_t) res >= sizeof(cmd))
2413 cmd[sizeof(cmd) - 1] = '\0';
2414 return wpa_ctrl_command(ctrl, cmd);
2418 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2420 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2424 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2427 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2431 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2438 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2439 "(peer address)\n");
2443 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2445 if (res < 0 || (size_t) res >= sizeof(cmd))
2448 cmd[sizeof(cmd) - 1] = '\0';
2449 return wpa_ctrl_command(ctrl, cmd);
2453 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2459 if (argc != 0 && argc != 2 && argc != 4) {
2460 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2461 "(preferred duration, interval; in microsecods).\n"
2462 "Optional second pair can be used to provide "
2463 "acceptable values.\n");
2468 res = os_snprintf(cmd, sizeof(cmd),
2469 "P2P_PRESENCE_REQ %s %s %s %s",
2470 argv[0], argv[1], argv[2], argv[3]);
2472 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2475 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2476 if (res < 0 || (size_t) res >= sizeof(cmd))
2478 cmd[sizeof(cmd) - 1] = '\0';
2479 return wpa_ctrl_command(ctrl, cmd);
2483 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2489 if (argc != 0 && argc != 2) {
2490 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2491 "(availability period, availability interval; in "
2493 "Extended Listen Timing can be cancelled with this "
2494 "command when used without parameters.\n");
2499 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2502 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2503 if (res < 0 || (size_t) res >= sizeof(cmd))
2505 cmd[sizeof(cmd) - 1] = '\0';
2506 return wpa_ctrl_command(ctrl, cmd);
2509 #endif /* CONFIG_P2P */
2512 #ifdef CONFIG_INTERWORKING
2513 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2516 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2520 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2523 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2527 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2534 return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
2536 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
2537 if (res < 0 || (size_t) res >= sizeof(cmd))
2539 cmd[sizeof(cmd) - 1] = '\0';
2540 return wpa_ctrl_command(ctrl, cmd);
2544 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2551 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2552 "argument (BSSID)\n");
2556 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
2558 if (res < 0 || (size_t) res >= sizeof(cmd))
2560 cmd[sizeof(cmd) - 1] = '\0';
2561 return wpa_ctrl_command(ctrl, cmd);
2565 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2571 printf("Invalid ANQP_GET command: needs two arguments "
2572 "(addr and info id list)\n");
2576 res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
2578 if (res < 0 || (size_t) res >= sizeof(cmd))
2580 cmd[sizeof(cmd) - 1] = '\0';
2581 return wpa_ctrl_command(ctrl, cmd);
2583 #endif /* CONFIG_INTERWORKING */
2586 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2593 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2594 "(0/1 = disable/enable automatic reconnection)\n");
2597 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2598 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2599 printf("Too long STA_AUTOCONNECT command.\n");
2602 return wpa_ctrl_command(ctrl, cmd);
2606 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2613 printf("Invalid TDLS_DISCOVER command: needs one argument "
2614 "(Peer STA MAC address)\n");
2618 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2619 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2620 printf("Too long TDLS_DISCOVER command.\n");
2623 return wpa_ctrl_command(ctrl, cmd);
2627 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2634 printf("Invalid TDLS_SETUP command: needs one argument "
2635 "(Peer STA MAC address)\n");
2639 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2640 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2641 printf("Too long TDLS_SETUP command.\n");
2644 return wpa_ctrl_command(ctrl, cmd);
2648 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2655 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2656 "(Peer STA MAC address)\n");
2660 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2661 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2662 printf("Too long TDLS_TEARDOWN command.\n");
2665 return wpa_ctrl_command(ctrl, cmd);
2669 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2672 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2676 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2679 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2683 enum wpa_cli_cmd_flags {
2684 cli_cmd_flag_none = 0x00,
2685 cli_cmd_flag_sensitive = 0x01
2688 struct wpa_cli_cmd {
2690 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2691 enum wpa_cli_cmd_flags flags;
2695 static struct wpa_cli_cmd wpa_cli_commands[] = {
2696 { "status", wpa_cli_cmd_status,
2698 "[verbose] = get current WPA/EAPOL/EAP status" },
2699 { "ping", wpa_cli_cmd_ping,
2701 "= pings wpa_supplicant" },
2702 { "relog", wpa_cli_cmd_relog,
2704 "= re-open log-file (allow rolling logs)" },
2705 { "note", wpa_cli_cmd_note,
2707 "<text> = add a note to wpa_supplicant debug log" },
2708 { "mib", wpa_cli_cmd_mib,
2710 "= get MIB variables (dot1x, dot11)" },
2711 { "help", wpa_cli_cmd_help,
2713 "= show this usage help" },
2714 { "interface", wpa_cli_cmd_interface,
2716 "[ifname] = show interfaces/select interface" },
2717 { "level", wpa_cli_cmd_level,
2719 "<debug level> = change debug level" },
2720 { "license", wpa_cli_cmd_license,
2722 "= show full wpa_cli license" },
2723 { "quit", wpa_cli_cmd_quit,
2726 { "set", wpa_cli_cmd_set,
2728 "= set variables (shows list of variables when run without "
2730 { "get", wpa_cli_cmd_get,
2732 "<name> = get information" },
2733 { "logon", wpa_cli_cmd_logon,
2735 "= IEEE 802.1X EAPOL state machine logon" },
2736 { "logoff", wpa_cli_cmd_logoff,
2738 "= IEEE 802.1X EAPOL state machine logoff" },
2739 { "pmksa", wpa_cli_cmd_pmksa,
2741 "= show PMKSA cache" },
2742 { "reassociate", wpa_cli_cmd_reassociate,
2744 "= force reassociation" },
2745 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2747 "<BSSID> = force preauthentication" },
2748 { "identity", wpa_cli_cmd_identity,
2750 "<network id> <identity> = configure identity for an SSID" },
2751 { "password", wpa_cli_cmd_password,
2752 cli_cmd_flag_sensitive,
2753 "<network id> <password> = configure password for an SSID" },
2754 { "new_password", wpa_cli_cmd_new_password,
2755 cli_cmd_flag_sensitive,
2756 "<network id> <password> = change password for an SSID" },
2757 { "pin", wpa_cli_cmd_pin,
2758 cli_cmd_flag_sensitive,
2759 "<network id> <pin> = configure pin for an SSID" },
2760 { "otp", wpa_cli_cmd_otp,
2761 cli_cmd_flag_sensitive,
2762 "<network id> <password> = configure one-time-password for an SSID"
2764 { "passphrase", wpa_cli_cmd_passphrase,
2765 cli_cmd_flag_sensitive,
2766 "<network id> <passphrase> = configure private key passphrase\n"
2768 { "bssid", wpa_cli_cmd_bssid,
2770 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2771 { "blacklist", wpa_cli_cmd_blacklist,
2773 "<BSSID> = add a BSSID to the blacklist\n"
2774 "blacklist clear = clear the blacklist\n"
2775 "blacklist = display the blacklist" },
2776 { "log_level", wpa_cli_cmd_log_level,
2778 "<level> [<timestamp>] = update the log level/timestamp\n"
2779 "log_level = display the current log level and log options" },
2780 { "list_networks", wpa_cli_cmd_list_networks,
2782 "= list configured networks" },
2783 { "select_network", wpa_cli_cmd_select_network,
2785 "<network id> = select a network (disable others)" },
2786 { "enable_network", wpa_cli_cmd_enable_network,
2788 "<network id> = enable a network" },
2789 { "disable_network", wpa_cli_cmd_disable_network,
2791 "<network id> = disable a network" },
2792 { "add_network", wpa_cli_cmd_add_network,
2794 "= add a network" },
2795 { "remove_network", wpa_cli_cmd_remove_network,
2797 "<network id> = remove a network" },
2798 { "set_network", wpa_cli_cmd_set_network,
2799 cli_cmd_flag_sensitive,
2800 "<network id> <variable> <value> = set network variables (shows\n"
2801 " list of variables when run without arguments)" },
2802 { "get_network", wpa_cli_cmd_get_network,
2804 "<network id> <variable> = get network variables" },
2805 { "save_config", wpa_cli_cmd_save_config,
2807 "= save the current configuration" },
2808 { "disconnect", wpa_cli_cmd_disconnect,
2810 "= disconnect and wait for reassociate/reconnect command before\n"
2812 { "reconnect", wpa_cli_cmd_reconnect,
2814 "= like reassociate, but only takes effect if already disconnected"
2816 { "scan", wpa_cli_cmd_scan,
2818 "= request new BSS scan" },
2819 { "scan_results", wpa_cli_cmd_scan_results,
2821 "= get latest scan results" },
2822 { "bss", wpa_cli_cmd_bss,
2824 "<<idx> | <bssid>> = get detailed scan result info" },
2825 { "get_capability", wpa_cli_cmd_get_capability,
2827 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2828 { "reconfigure", wpa_cli_cmd_reconfigure,
2830 "= force wpa_supplicant to re-read its configuration file" },
2831 { "terminate", wpa_cli_cmd_terminate,
2833 "= terminate wpa_supplicant" },
2834 { "interface_add", wpa_cli_cmd_interface_add,
2836 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2837 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2839 { "interface_remove", wpa_cli_cmd_interface_remove,
2841 "<ifname> = removes the interface" },
2842 { "interface_list", wpa_cli_cmd_interface_list,
2844 "= list available interfaces" },
2845 { "ap_scan", wpa_cli_cmd_ap_scan,
2847 "<value> = set ap_scan parameter" },
2848 { "scan_interval", wpa_cli_cmd_scan_interval,
2850 "<value> = set scan_interval parameter (in seconds)" },
2851 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2853 "<value> = set BSS expiration age parameter" },
2854 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2856 "<value> = set BSS expiration scan count parameter" },
2857 { "stkstart", wpa_cli_cmd_stkstart,
2859 "<addr> = request STK negotiation with <addr>" },
2860 { "ft_ds", wpa_cli_cmd_ft_ds,
2862 "<addr> = request over-the-DS FT with <addr>" },
2863 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2865 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2866 { "wps_pin", wpa_cli_cmd_wps_pin,
2867 cli_cmd_flag_sensitive,
2868 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2870 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2871 cli_cmd_flag_sensitive,
2872 "<PIN> = verify PIN checksum" },
2873 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2874 "Cancels the pending WPS operation" },
2875 #ifdef CONFIG_WPS_OOB
2876 { "wps_oob", wpa_cli_cmd_wps_oob,
2877 cli_cmd_flag_sensitive,
2878 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2879 #endif /* CONFIG_WPS_OOB */
2880 { "wps_reg", wpa_cli_cmd_wps_reg,
2881 cli_cmd_flag_sensitive,
2882 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2883 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2884 cli_cmd_flag_sensitive,
2885 "[params..] = enable/disable AP PIN" },
2886 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2888 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2889 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2891 "= stop Wi-Fi Protected Setup External Registrar" },
2892 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2893 cli_cmd_flag_sensitive,
2894 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2895 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2897 "<UUID> = accept an Enrollee PBC using External Registrar" },
2898 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2899 cli_cmd_flag_sensitive,
2900 "<UUID> <PIN> = learn AP configuration" },
2901 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2903 "<UUID> <network id> = set AP configuration for enrolling" },
2904 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2905 cli_cmd_flag_sensitive,
2906 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2907 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2909 "<addr> = request RSN authentication with <addr> in IBSS" },
2911 { "sta", wpa_cli_cmd_sta,
2913 "<addr> = get information about an associated station (AP)" },
2914 { "all_sta", wpa_cli_cmd_all_sta,
2916 "= get information about all associated stations (AP)" },
2917 #endif /* CONFIG_AP */
2918 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2919 "= notification of suspend/hibernate" },
2920 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2921 "= notification of resume/thaw" },
2922 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2923 "= drop SA without deauth/disassoc (test command)" },
2924 { "roam", wpa_cli_cmd_roam,
2926 "<addr> = roam to the specified BSS" },
2928 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2929 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2930 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2931 "= stop P2P Devices search" },
2932 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2933 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2934 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2935 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2936 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2937 "<ifname> = remove P2P group interface (terminate group if GO)" },
2938 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2939 "= add a new P2P group (local end as GO)" },
2940 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2941 "<addr> <method> = request provisioning discovery" },
2942 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2944 "= get the passphrase for a group (GO only)" },
2945 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2947 "<addr> <TLVs> = schedule service discovery request" },
2948 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2950 "<id> = cancel pending service discovery request" },
2951 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2953 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2954 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2956 "= indicate change in local services" },
2957 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2959 "<external> = set external processing of service discovery" },
2960 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2962 "= remove all stored service entries" },
2963 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2965 "<bonjour|upnp> <query|version> <response|service> = add a local "
2967 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2969 "<bonjour|upnp> <query|version> [|service] = remove a local "
2971 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2973 "<addr> = reject connection attempts from a specific peer" },
2974 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2976 "<cmd> [peer=addr] = invite peer" },
2977 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2978 "[discovered] = list known (optionally, only fully discovered) P2P "
2980 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2981 "<address> = show information about known P2P peer" },
2982 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2983 "<field> <value> = set a P2P parameter" },
2984 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2985 "= flush P2P state" },
2986 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2987 "= cancel P2P group formation" },
2988 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2989 "<address> = unauthorize a peer" },
2990 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2991 "[<duration> <interval>] [<duration> <interval>] = request GO "
2993 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2994 "[<period> <interval>] = set extended listen timing" },
2995 #endif /* CONFIG_P2P */
2997 #ifdef CONFIG_INTERWORKING
2998 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
2999 "= fetch ANQP information for all APs" },
3000 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
3001 "= stop fetch_anqp operation" },
3002 { "interworking_select", wpa_cli_cmd_interworking_select,
3004 "[auto] = perform Interworking network selection" },
3005 { "interworking_connect", wpa_cli_cmd_interworking_connect,
3007 "<BSSID> = connect using Interworking credentials" },
3008 { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
3009 "<addr> <info id>[,<info id>]... = request ANQP information" },
3010 #endif /* CONFIG_INTERWORKING */
3011 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
3012 "<0/1> = disable/enable automatic reconnection" },
3013 { "tdls_discover", wpa_cli_cmd_tdls_discover,
3015 "<addr> = request TDLS discovery with <addr>" },
3016 { "tdls_setup", wpa_cli_cmd_tdls_setup,
3018 "<addr> = request TDLS setup with <addr>" },
3019 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
3021 "<addr> = tear down TDLS with <addr>" },
3022 { "signal_poll", wpa_cli_cmd_signal_poll,
3024 "= get signal parameters" },
3025 { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
3026 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3027 { NULL, NULL, cli_cmd_flag_none, NULL }
3032 * Prints command usage, lines are padded with the specified string.
3034 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3039 printf("%s%s ", pad, cmd->cmd);
3040 for (n = 0; (c = cmd->usage[n]); n++) {
3049 static void print_help(void)
3052 printf("commands:\n");
3053 for (n = 0; wpa_cli_commands[n].cmd; n++)
3054 print_cmd_help(&wpa_cli_commands[n], " ");
3058 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3060 const char *c, *delim;
3064 delim = os_strchr(cmd, ' ');
3068 len = os_strlen(cmd);
3070 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3071 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3072 return (wpa_cli_commands[n].flags &
3073 cli_cmd_flag_sensitive);
3079 static char ** wpa_list_cmd_list(void)
3084 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
3085 res = os_zalloc(count * sizeof(char *));
3089 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3090 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3099 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3104 if (os_strcasecmp(cmd, "bss") == 0)
3105 return wpa_cli_complete_bss(str, pos);
3107 if (os_strcasecmp(cmd, "p2p_connect") == 0)
3108 return wpa_cli_complete_p2p_connect(str, pos);
3109 if (os_strcasecmp(cmd, "p2p_peer") == 0)
3110 return wpa_cli_complete_p2p_peer(str, pos);
3111 if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
3112 return wpa_cli_complete_p2p_group_remove(str, pos);
3113 #endif /* CONFIG_P2P */
3115 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3116 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3118 printf("\r%s\n", wpa_cli_commands[i].usage);
3128 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3134 end = os_strchr(str, ' ');
3135 if (end == NULL || str + pos < end)
3136 return wpa_list_cmd_list();
3138 cmd = os_malloc(pos + 1);
3141 os_memcpy(cmd, str, pos);
3142 cmd[end - str] = '\0';
3143 res = wpa_cli_cmd_completion(cmd, str, pos);
3149 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3151 struct wpa_cli_cmd *cmd, *match = NULL;
3156 cmd = wpa_cli_commands;
3158 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3161 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3162 /* we have an exact match */
3172 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3173 cmd = wpa_cli_commands;
3175 if (os_strncasecmp(cmd->cmd, argv[0],
3176 os_strlen(argv[0])) == 0) {
3177 printf(" %s", cmd->cmd);
3183 } else if (count == 0) {
3184 printf("Unknown command '%s'\n", argv[0]);
3187 ret = match->handler(ctrl, argc - 1, &argv[1]);
3194 static int str_match(const char *a, const char *b)
3196 return os_strncmp(a, b, os_strlen(b)) == 0;
3200 static int wpa_cli_exec(const char *program, const char *arg1,
3208 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3209 cmd = os_malloc(len);
3212 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3213 if (res < 0 || (size_t) res >= len) {
3217 cmd[len - 1] = '\0';
3219 if (system(cmd) < 0)
3221 #endif /* _WIN32_WCE */
3228 static void wpa_cli_action_process(const char *msg)
3231 char *copy = NULL, *id, *pos2;
3236 pos = os_strchr(pos, '>');
3243 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3245 os_unsetenv("WPA_ID");
3246 os_unsetenv("WPA_ID_STR");
3247 os_unsetenv("WPA_CTRL_DIR");
3249 pos = os_strstr(pos, "[id=");
3251 copy = os_strdup(pos + 4);
3255 while (*pos2 && *pos2 != ' ')
3259 os_setenv("WPA_ID", id, 1);
3260 while (*pos2 && *pos2 != '=')
3265 while (*pos2 && *pos2 != ']')
3268 os_setenv("WPA_ID_STR", id, 1);
3272 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3274 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3275 wpa_cli_connected = 1;
3276 wpa_cli_last_id = new_id;
3277 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3279 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3280 if (wpa_cli_connected) {
3281 wpa_cli_connected = 0;
3282 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3284 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3285 wpa_cli_exec(action_file, ctrl_ifname, pos);
3286 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3287 wpa_cli_exec(action_file, ctrl_ifname, pos);
3288 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3289 wpa_cli_exec(action_file, ctrl_ifname, pos);
3290 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3291 wpa_cli_exec(action_file, ctrl_ifname, pos);
3292 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3293 wpa_cli_exec(action_file, ctrl_ifname, pos);
3294 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3295 wpa_cli_exec(action_file, ctrl_ifname, pos);
3296 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3297 wpa_cli_exec(action_file, ctrl_ifname, pos);
3298 } else if (str_match(pos, AP_STA_CONNECTED)) {
3299 wpa_cli_exec(action_file, ctrl_ifname, pos);
3300 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3301 wpa_cli_exec(action_file, ctrl_ifname, pos);
3302 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3303 printf("wpa_supplicant is terminating - stop monitoring\n");
3309 #ifndef CONFIG_ANSI_C_EXTRA
3310 static void wpa_cli_action_cb(char *msg, size_t len)
3312 wpa_cli_action_process(msg);
3314 #endif /* CONFIG_ANSI_C_EXTRA */
3317 static void wpa_cli_reconnect(void)
3319 wpa_cli_close_connection();
3320 wpa_cli_open_connection(ctrl_ifname, 1);
3324 static void cli_event(const char *str)
3326 const char *start, *s;
3328 start = os_strchr(str, '>');
3334 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3335 s = os_strchr(start, ' ');
3338 s = os_strchr(s + 1, ' ');
3341 cli_txt_list_add(&bsses, s + 1);
3345 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3346 s = os_strchr(start, ' ');
3349 s = os_strchr(s + 1, ' ');
3352 cli_txt_list_del_addr(&bsses, s + 1);
3357 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3358 s = os_strstr(start, " p2p_dev_addr=");
3361 cli_txt_list_add_addr(&p2p_peers, s + 14);
3365 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3366 s = os_strstr(start, " p2p_dev_addr=");
3369 cli_txt_list_del_addr(&p2p_peers, s + 14);
3373 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3374 s = os_strchr(start, ' ');
3377 cli_txt_list_add_word(&p2p_groups, s + 1);
3381 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3382 s = os_strchr(start, ' ');
3385 cli_txt_list_del_word(&p2p_groups, s + 1);
3388 #endif /* CONFIG_P2P */
3392 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3394 if (ctrl_conn == NULL) {
3395 wpa_cli_reconnect();
3398 while (wpa_ctrl_pending(ctrl) > 0) {
3400 size_t len = sizeof(buf) - 1;
3401 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3404 wpa_cli_action_process(buf);
3407 if (wpa_cli_show_event(buf)) {
3409 printf("\r%s\n", buf);
3414 printf("Could not read pending message.\n");
3419 if (wpa_ctrl_pending(ctrl) < 0) {
3420 printf("Connection to wpa_supplicant lost - trying to "
3422 wpa_cli_reconnect();
3428 static int tokenize_cmd(char *cmd, char *argv[])
3441 if (argc == max_args)
3444 char *pos2 = os_strrchr(pos, '"');
3448 while (*pos != '\0' && *pos != ' ')
3458 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3460 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3461 printf("Connection to wpa_supplicant lost - trying to "
3463 wpa_cli_close_connection();
3466 wpa_cli_reconnect();
3467 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3471 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3477 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3479 wpa_cli_recv_pending(mon_conn, 0);
3483 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3485 char *argv[max_args];
3487 argc = tokenize_cmd(cmd, argv);
3489 wpa_request(ctrl_conn, argc, argv);
3493 static void wpa_cli_edit_eof_cb(void *ctx)
3499 static void wpa_cli_interactive(void)
3501 char *home, *hfile = NULL;
3503 printf("\nInteractive mode\n\n");
3505 home = getenv("HOME");
3507 const char *fname = ".wpa_cli_history";
3508 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3509 hfile = os_malloc(hfile_len);
3511 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3514 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3515 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3516 wpa_cli_edit_completion_cb, NULL, hfile);
3517 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3521 cli_txt_list_flush(&p2p_peers);
3522 cli_txt_list_flush(&p2p_groups);
3523 cli_txt_list_flush(&bsses);
3524 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3526 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3527 wpa_cli_close_connection();
3531 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3533 #ifdef CONFIG_ANSI_C_EXTRA
3534 /* TODO: ANSI C version(?) */
3535 printf("Action processing not supported in ANSI C build.\n");
3536 #else /* CONFIG_ANSI_C_EXTRA */
3540 char buf[256]; /* note: large enough to fit in unsolicited messages */
3543 fd = wpa_ctrl_get_fd(ctrl);
3545 while (!wpa_cli_quit) {
3548 tv.tv_sec = ping_interval;
3550 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3551 if (res < 0 && errno != EINTR) {
3556 if (FD_ISSET(fd, &rfds))
3557 wpa_cli_recv_pending(ctrl, 1);
3559 /* verify that connection is still working */
3560 len = sizeof(buf) - 1;
3561 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3562 wpa_cli_action_cb) < 0 ||
3563 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3564 printf("wpa_supplicant did not reply to PING "
3565 "command - exiting\n");
3570 #endif /* CONFIG_ANSI_C_EXTRA */
3574 static void wpa_cli_cleanup(void)
3576 wpa_cli_close_connection();
3578 os_daemonize_terminate(pid_file);
3580 os_program_deinit();
3583 static void wpa_cli_terminate(int sig)
3590 static char * wpa_cli_get_default_ifname(void)
3592 char *ifname = NULL;
3594 #ifdef CONFIG_CTRL_IFACE_UNIX
3595 struct dirent *dent;
3596 DIR *dir = opendir(ctrl_iface_dir);
3599 char ifprop[PROPERTY_VALUE_MAX];
3600 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3601 ifname = os_strdup(ifprop);
3602 printf("Using interface '%s'\n", ifname);
3605 #endif /* ANDROID */
3608 while ((dent = readdir(dir))) {
3609 #ifdef _DIRENT_HAVE_D_TYPE
3611 * Skip the file if it is not a socket. Also accept
3612 * DT_UNKNOWN (0) in case the C library or underlying
3613 * file system does not support d_type.
3615 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3617 #endif /* _DIRENT_HAVE_D_TYPE */
3618 if (os_strcmp(dent->d_name, ".") == 0 ||
3619 os_strcmp(dent->d_name, "..") == 0)
3621 printf("Selected interface '%s'\n", dent->d_name);
3622 ifname = os_strdup(dent->d_name);
3626 #endif /* CONFIG_CTRL_IFACE_UNIX */
3628 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3629 char buf[2048], *pos;
3631 struct wpa_ctrl *ctrl;
3634 ctrl = wpa_ctrl_open(NULL);
3638 len = sizeof(buf) - 1;
3639 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3642 pos = os_strchr(buf, '\n');
3645 ifname = os_strdup(buf);
3647 wpa_ctrl_close(ctrl);
3648 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3654 int main(int argc, char *argv[])
3656 int warning_displayed = 0;
3660 const char *global = NULL;
3662 if (os_program_init())
3666 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3671 action_file = optarg;
3680 ping_interval = atoi(optarg);
3686 printf("%s\n", wpa_cli_version);
3689 os_free(ctrl_ifname);
3690 ctrl_ifname = os_strdup(optarg);
3693 ctrl_iface_dir = optarg;
3704 interactive = (argc == optind) && (action_file == NULL);
3707 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3713 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3714 ctrl_conn = wpa_ctrl_open(NULL);
3715 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3716 ctrl_conn = wpa_ctrl_open(global);
3717 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3718 if (ctrl_conn == NULL) {
3719 perror("Failed to connect to wpa_supplicant - "
3726 signal(SIGINT, wpa_cli_terminate);
3727 signal(SIGTERM, wpa_cli_terminate);
3728 #endif /* _WIN32_WCE */
3730 if (ctrl_ifname == NULL)
3731 ctrl_ifname = wpa_cli_get_default_ifname();
3735 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3736 if (warning_displayed)
3737 printf("Connection established.\n");
3741 if (!warning_displayed) {
3742 printf("Could not connect to wpa_supplicant - "
3744 warning_displayed = 1;
3751 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3752 perror("Failed to connect to wpa_supplicant - "
3758 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3759 wpa_cli_attached = 1;
3761 printf("Warning: Failed to attach to "
3762 "wpa_supplicant.\n");
3768 if (daemonize && os_daemonize(pid_file))
3772 wpa_cli_interactive();
3773 else if (action_file)
3774 wpa_cli_action(ctrl_conn);
3776 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3778 os_free(ctrl_ifname);
3785 #else /* CONFIG_CTRL_IFACE */
3786 int main(int argc, char *argv[])
3788 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3791 #endif /* CONFIG_CTRL_IFACE */