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-2011, 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",
1937 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1938 if (res < 0 || (size_t) res >= sizeof(cmd))
1940 cmd[sizeof(cmd) - 1] = '\0';
1941 return wpa_ctrl_command(ctrl, cmd);
1945 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1948 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1952 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1959 printf("Invalid P2P_CONNECT command: needs at least two "
1960 "arguments (address and pbc/PIN)\n");
1965 res = os_snprintf(cmd, sizeof(cmd),
1966 "P2P_CONNECT %s %s %s %s %s",
1967 argv[0], argv[1], argv[2], argv[3],
1970 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1971 argv[0], argv[1], argv[2], argv[3]);
1973 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1974 argv[0], argv[1], argv[2]);
1976 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1978 if (res < 0 || (size_t) res >= sizeof(cmd))
1980 cmd[sizeof(cmd) - 1] = '\0';
1981 return wpa_ctrl_command(ctrl, cmd);
1985 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1987 int arg = get_cmd_arg_num(str, pos);
1992 res = cli_txt_list_array(&p2p_peers);
2000 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2007 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
2009 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
2010 if (res < 0 || (size_t) res >= sizeof(cmd))
2012 cmd[sizeof(cmd) - 1] = '\0';
2013 return wpa_ctrl_command(ctrl, cmd);
2017 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2024 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2025 "(interface name)\n");
2029 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
2030 if (res < 0 || (size_t) res >= sizeof(cmd))
2032 cmd[sizeof(cmd) - 1] = '\0';
2033 return wpa_ctrl_command(ctrl, cmd);
2037 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2039 int arg = get_cmd_arg_num(str, pos);
2044 res = cli_txt_list_array(&p2p_groups);
2052 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2059 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
2062 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
2065 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
2067 if (res < 0 || (size_t) res >= sizeof(cmd))
2069 cmd[sizeof(cmd) - 1] = '\0';
2070 return wpa_ctrl_command(ctrl, cmd);
2074 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2080 if (argc != 2 && argc != 3) {
2081 printf("Invalid P2P_PROV_DISC command: needs at least "
2082 "two arguments, address and config method\n"
2083 "(display, keypad, or pbc) and an optional join\n");
2088 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
2089 argv[0], argv[1], argv[2]);
2091 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
2093 if (res < 0 || (size_t) res >= sizeof(cmd))
2095 cmd[sizeof(cmd) - 1] = '\0';
2096 return wpa_ctrl_command(ctrl, cmd);
2100 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2103 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2107 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2113 if (argc != 2 && argc != 4) {
2114 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2115 "arguments (address and TLVs) or four arguments "
2116 "(address, \"upnp\", version, search target "
2122 res = os_snprintf(cmd, sizeof(cmd),
2123 "P2P_SERV_DISC_REQ %s %s %s %s",
2124 argv[0], argv[1], argv[2], argv[3]);
2126 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
2128 if (res < 0 || (size_t) res >= sizeof(cmd))
2130 cmd[sizeof(cmd) - 1] = '\0';
2131 return wpa_ctrl_command(ctrl, cmd);
2135 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2136 int argc, char *argv[])
2142 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2143 "argument (pending request identifier)\n");
2147 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
2149 if (res < 0 || (size_t) res >= sizeof(cmd))
2151 cmd[sizeof(cmd) - 1] = '\0';
2152 return wpa_ctrl_command(ctrl, cmd);
2156 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2163 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2164 "arguments (freq, address, dialog token, and TLVs)\n");
2168 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2169 argv[0], argv[1], argv[2], argv[3]);
2170 if (res < 0 || (size_t) res >= sizeof(cmd))
2172 cmd[sizeof(cmd) - 1] = '\0';
2173 return wpa_ctrl_command(ctrl, cmd);
2177 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2180 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2184 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2185 int argc, char *argv[])
2191 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2192 "argument (external processing: 0/1)\n");
2196 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
2198 if (res < 0 || (size_t) res >= sizeof(cmd))
2200 cmd[sizeof(cmd) - 1] = '\0';
2201 return wpa_ctrl_command(ctrl, cmd);
2205 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2208 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2212 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2218 if (argc != 3 && argc != 4) {
2219 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2225 res = os_snprintf(cmd, sizeof(cmd),
2226 "P2P_SERVICE_ADD %s %s %s %s",
2227 argv[0], argv[1], argv[2], argv[3]);
2229 res = os_snprintf(cmd, sizeof(cmd),
2230 "P2P_SERVICE_ADD %s %s %s",
2231 argv[0], argv[1], argv[2]);
2232 if (res < 0 || (size_t) res >= sizeof(cmd))
2234 cmd[sizeof(cmd) - 1] = '\0';
2235 return wpa_ctrl_command(ctrl, cmd);
2239 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2245 if (argc != 2 && argc != 3) {
2246 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2252 res = os_snprintf(cmd, sizeof(cmd),
2253 "P2P_SERVICE_DEL %s %s %s",
2254 argv[0], argv[1], argv[2]);
2256 res = os_snprintf(cmd, sizeof(cmd),
2257 "P2P_SERVICE_DEL %s %s",
2259 if (res < 0 || (size_t) res >= sizeof(cmd))
2261 cmd[sizeof(cmd) - 1] = '\0';
2262 return wpa_ctrl_command(ctrl, cmd);
2266 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2267 int argc, char *argv[])
2273 printf("Invalid P2P_REJECT command: needs one argument "
2274 "(peer address)\n");
2278 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2279 if (res < 0 || (size_t) res >= sizeof(cmd))
2281 cmd[sizeof(cmd) - 1] = '\0';
2282 return wpa_ctrl_command(ctrl, cmd);
2286 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2287 int argc, char *argv[])
2293 printf("Invalid P2P_INVITE command: needs at least one "
2299 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2300 argv[0], argv[1], argv[2]);
2302 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2305 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2306 if (res < 0 || (size_t) res >= sizeof(cmd))
2308 cmd[sizeof(cmd) - 1] = '\0';
2309 return wpa_ctrl_command(ctrl, cmd);
2313 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2317 printf("Invalid 'p2p_peer' command - exactly one argument, "
2318 "P2P peer device address, is required.\n");
2321 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2322 return wpa_ctrl_command(ctrl, buf);
2326 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2328 int arg = get_cmd_arg_num(str, pos);
2333 res = cli_txt_list_array(&p2p_peers);
2341 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2342 char *addr, size_t addr_len,
2345 char buf[4096], *pos;
2349 if (ctrl_conn == NULL)
2351 len = sizeof(buf) - 1;
2352 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2355 printf("'%s' command timed out.\n", cmd);
2357 } else if (ret < 0) {
2358 printf("'%s' command failed.\n", cmd);
2363 if (memcmp(buf, "FAIL", 4) == 0)
2367 while (*pos != '\0' && *pos != '\n')
2370 os_strlcpy(addr, buf, addr_len);
2371 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2372 printf("%s\n", addr);
2377 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2379 char addr[32], cmd[64];
2382 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2384 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2385 addr, sizeof(addr), discovered))
2388 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2389 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2396 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2402 printf("Invalid P2P_SET command: needs two arguments (field, "
2407 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2408 if (res < 0 || (size_t) res >= sizeof(cmd))
2410 cmd[sizeof(cmd) - 1] = '\0';
2411 return wpa_ctrl_command(ctrl, cmd);
2415 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2417 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2421 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2424 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2428 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2435 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2436 "(peer address)\n");
2440 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2442 if (res < 0 || (size_t) res >= sizeof(cmd))
2445 cmd[sizeof(cmd) - 1] = '\0';
2446 return wpa_ctrl_command(ctrl, cmd);
2450 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2456 if (argc != 0 && argc != 2 && argc != 4) {
2457 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2458 "(preferred duration, interval; in microsecods).\n"
2459 "Optional second pair can be used to provide "
2460 "acceptable values.\n");
2465 res = os_snprintf(cmd, sizeof(cmd),
2466 "P2P_PRESENCE_REQ %s %s %s %s",
2467 argv[0], argv[1], argv[2], argv[3]);
2469 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2472 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2473 if (res < 0 || (size_t) res >= sizeof(cmd))
2475 cmd[sizeof(cmd) - 1] = '\0';
2476 return wpa_ctrl_command(ctrl, cmd);
2480 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2486 if (argc != 0 && argc != 2) {
2487 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2488 "(availability period, availability interval; in "
2490 "Extended Listen Timing can be cancelled with this "
2491 "command when used without parameters.\n");
2496 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2499 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2500 if (res < 0 || (size_t) res >= sizeof(cmd))
2502 cmd[sizeof(cmd) - 1] = '\0';
2503 return wpa_ctrl_command(ctrl, cmd);
2506 #endif /* CONFIG_P2P */
2509 #ifdef CONFIG_INTERWORKING
2510 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2513 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2517 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2520 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2524 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2531 return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
2533 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
2534 if (res < 0 || (size_t) res >= sizeof(cmd))
2536 cmd[sizeof(cmd) - 1] = '\0';
2537 return wpa_ctrl_command(ctrl, cmd);
2541 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2548 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2549 "argument (BSSID)\n");
2553 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
2555 if (res < 0 || (size_t) res >= sizeof(cmd))
2557 cmd[sizeof(cmd) - 1] = '\0';
2558 return wpa_ctrl_command(ctrl, cmd);
2562 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2568 printf("Invalid ANQP_GET command: needs two arguments "
2569 "(addr and info id list)\n");
2573 res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
2575 if (res < 0 || (size_t) res >= sizeof(cmd))
2577 cmd[sizeof(cmd) - 1] = '\0';
2578 return wpa_ctrl_command(ctrl, cmd);
2580 #endif /* CONFIG_INTERWORKING */
2583 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2590 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2591 "(0/1 = disable/enable automatic reconnection)\n");
2594 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2595 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2596 printf("Too long STA_AUTOCONNECT command.\n");
2599 return wpa_ctrl_command(ctrl, cmd);
2603 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2610 printf("Invalid TDLS_DISCOVER command: needs one argument "
2611 "(Peer STA MAC address)\n");
2615 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2616 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2617 printf("Too long TDLS_DISCOVER command.\n");
2620 return wpa_ctrl_command(ctrl, cmd);
2624 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2631 printf("Invalid TDLS_SETUP command: needs one argument "
2632 "(Peer STA MAC address)\n");
2636 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2637 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2638 printf("Too long TDLS_SETUP command.\n");
2641 return wpa_ctrl_command(ctrl, cmd);
2645 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2652 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2653 "(Peer STA MAC address)\n");
2657 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2658 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2659 printf("Too long TDLS_TEARDOWN command.\n");
2662 return wpa_ctrl_command(ctrl, cmd);
2666 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2669 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2673 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2676 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2680 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2687 printf("Invalid DRIVER command: needs one argument (cmd)\n");
2691 len = os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
2692 for (i=1; i < argc; i++)
2693 len += os_snprintf(cmd + len, sizeof(cmd) - len, " %s", argv[i]);
2694 cmd[sizeof(cmd) - 1] = '\0';
2695 printf("%s: %s\n", __func__, cmd);
2696 return wpa_ctrl_command(ctrl, cmd);
2700 enum wpa_cli_cmd_flags {
2701 cli_cmd_flag_none = 0x00,
2702 cli_cmd_flag_sensitive = 0x01
2705 struct wpa_cli_cmd {
2707 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2708 enum wpa_cli_cmd_flags flags;
2712 static struct wpa_cli_cmd wpa_cli_commands[] = {
2713 { "status", wpa_cli_cmd_status,
2715 "[verbose] = get current WPA/EAPOL/EAP status" },
2716 { "ping", wpa_cli_cmd_ping,
2718 "= pings wpa_supplicant" },
2719 { "relog", wpa_cli_cmd_relog,
2721 "= re-open log-file (allow rolling logs)" },
2722 { "note", wpa_cli_cmd_note,
2724 "<text> = add a note to wpa_supplicant debug log" },
2725 { "mib", wpa_cli_cmd_mib,
2727 "= get MIB variables (dot1x, dot11)" },
2728 { "help", wpa_cli_cmd_help,
2730 "= show this usage help" },
2731 { "interface", wpa_cli_cmd_interface,
2733 "[ifname] = show interfaces/select interface" },
2734 { "level", wpa_cli_cmd_level,
2736 "<debug level> = change debug level" },
2737 { "license", wpa_cli_cmd_license,
2739 "= show full wpa_cli license" },
2740 { "quit", wpa_cli_cmd_quit,
2743 { "set", wpa_cli_cmd_set,
2745 "= set variables (shows list of variables when run without "
2747 { "get", wpa_cli_cmd_get,
2749 "<name> = get information" },
2750 { "logon", wpa_cli_cmd_logon,
2752 "= IEEE 802.1X EAPOL state machine logon" },
2753 { "logoff", wpa_cli_cmd_logoff,
2755 "= IEEE 802.1X EAPOL state machine logoff" },
2756 { "pmksa", wpa_cli_cmd_pmksa,
2758 "= show PMKSA cache" },
2759 { "reassociate", wpa_cli_cmd_reassociate,
2761 "= force reassociation" },
2762 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2764 "<BSSID> = force preauthentication" },
2765 { "identity", wpa_cli_cmd_identity,
2767 "<network id> <identity> = configure identity for an SSID" },
2768 { "password", wpa_cli_cmd_password,
2769 cli_cmd_flag_sensitive,
2770 "<network id> <password> = configure password for an SSID" },
2771 { "new_password", wpa_cli_cmd_new_password,
2772 cli_cmd_flag_sensitive,
2773 "<network id> <password> = change password for an SSID" },
2774 { "pin", wpa_cli_cmd_pin,
2775 cli_cmd_flag_sensitive,
2776 "<network id> <pin> = configure pin for an SSID" },
2777 { "otp", wpa_cli_cmd_otp,
2778 cli_cmd_flag_sensitive,
2779 "<network id> <password> = configure one-time-password for an SSID"
2781 { "passphrase", wpa_cli_cmd_passphrase,
2782 cli_cmd_flag_sensitive,
2783 "<network id> <passphrase> = configure private key passphrase\n"
2785 { "bssid", wpa_cli_cmd_bssid,
2787 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2788 { "blacklist", wpa_cli_cmd_blacklist,
2790 "<BSSID> = add a BSSID to the blacklist\n"
2791 "blacklist clear = clear the blacklist\n"
2792 "blacklist = display the blacklist" },
2793 { "log_level", wpa_cli_cmd_log_level,
2795 "<level> [<timestamp>] = update the log level/timestamp\n"
2796 "log_level = display the current log level and log options" },
2797 { "list_networks", wpa_cli_cmd_list_networks,
2799 "= list configured networks" },
2800 { "select_network", wpa_cli_cmd_select_network,
2802 "<network id> = select a network (disable others)" },
2803 { "enable_network", wpa_cli_cmd_enable_network,
2805 "<network id> = enable a network" },
2806 { "disable_network", wpa_cli_cmd_disable_network,
2808 "<network id> = disable a network" },
2809 { "add_network", wpa_cli_cmd_add_network,
2811 "= add a network" },
2812 { "remove_network", wpa_cli_cmd_remove_network,
2814 "<network id> = remove a network" },
2815 { "set_network", wpa_cli_cmd_set_network,
2816 cli_cmd_flag_sensitive,
2817 "<network id> <variable> <value> = set network variables (shows\n"
2818 " list of variables when run without arguments)" },
2819 { "get_network", wpa_cli_cmd_get_network,
2821 "<network id> <variable> = get network variables" },
2822 { "save_config", wpa_cli_cmd_save_config,
2824 "= save the current configuration" },
2825 { "disconnect", wpa_cli_cmd_disconnect,
2827 "= disconnect and wait for reassociate/reconnect command before\n"
2829 { "reconnect", wpa_cli_cmd_reconnect,
2831 "= like reassociate, but only takes effect if already disconnected"
2833 { "scan", wpa_cli_cmd_scan,
2835 "= request new BSS scan" },
2836 { "scan_results", wpa_cli_cmd_scan_results,
2838 "= get latest scan results" },
2839 { "bss", wpa_cli_cmd_bss,
2841 "<<idx> | <bssid>> = get detailed scan result info" },
2842 { "get_capability", wpa_cli_cmd_get_capability,
2844 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2845 { "reconfigure", wpa_cli_cmd_reconfigure,
2847 "= force wpa_supplicant to re-read its configuration file" },
2848 { "terminate", wpa_cli_cmd_terminate,
2850 "= terminate wpa_supplicant" },
2851 { "interface_add", wpa_cli_cmd_interface_add,
2853 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2854 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2856 { "interface_remove", wpa_cli_cmd_interface_remove,
2858 "<ifname> = removes the interface" },
2859 { "interface_list", wpa_cli_cmd_interface_list,
2861 "= list available interfaces" },
2862 { "ap_scan", wpa_cli_cmd_ap_scan,
2864 "<value> = set ap_scan parameter" },
2865 { "scan_interval", wpa_cli_cmd_scan_interval,
2867 "<value> = set scan_interval parameter (in seconds)" },
2868 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2870 "<value> = set BSS expiration age parameter" },
2871 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2873 "<value> = set BSS expiration scan count parameter" },
2874 { "stkstart", wpa_cli_cmd_stkstart,
2876 "<addr> = request STK negotiation with <addr>" },
2877 { "ft_ds", wpa_cli_cmd_ft_ds,
2879 "<addr> = request over-the-DS FT with <addr>" },
2880 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2882 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2883 { "wps_pin", wpa_cli_cmd_wps_pin,
2884 cli_cmd_flag_sensitive,
2885 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2887 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2888 cli_cmd_flag_sensitive,
2889 "<PIN> = verify PIN checksum" },
2890 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2891 "Cancels the pending WPS operation" },
2892 #ifdef CONFIG_WPS_OOB
2893 { "wps_oob", wpa_cli_cmd_wps_oob,
2894 cli_cmd_flag_sensitive,
2895 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2896 #endif /* CONFIG_WPS_OOB */
2897 { "wps_reg", wpa_cli_cmd_wps_reg,
2898 cli_cmd_flag_sensitive,
2899 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2900 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2901 cli_cmd_flag_sensitive,
2902 "[params..] = enable/disable AP PIN" },
2903 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2905 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2906 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2908 "= stop Wi-Fi Protected Setup External Registrar" },
2909 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2910 cli_cmd_flag_sensitive,
2911 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2912 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2914 "<UUID> = accept an Enrollee PBC using External Registrar" },
2915 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2916 cli_cmd_flag_sensitive,
2917 "<UUID> <PIN> = learn AP configuration" },
2918 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2920 "<UUID> <network id> = set AP configuration for enrolling" },
2921 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2922 cli_cmd_flag_sensitive,
2923 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2924 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2926 "<addr> = request RSN authentication with <addr> in IBSS" },
2928 { "sta", wpa_cli_cmd_sta,
2930 "<addr> = get information about an associated station (AP)" },
2931 { "all_sta", wpa_cli_cmd_all_sta,
2933 "= get information about all associated stations (AP)" },
2934 #endif /* CONFIG_AP */
2935 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2936 "= notification of suspend/hibernate" },
2937 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2938 "= notification of resume/thaw" },
2939 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2940 "= drop SA without deauth/disassoc (test command)" },
2941 { "roam", wpa_cli_cmd_roam,
2943 "<addr> = roam to the specified BSS" },
2945 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2946 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2947 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2948 "= stop P2P Devices search" },
2949 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2950 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2951 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2952 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2953 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2954 "<ifname> = remove P2P group interface (terminate group if GO)" },
2955 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2956 "= add a new P2P group (local end as GO)" },
2957 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2958 "<addr> <method> = request provisioning discovery" },
2959 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2961 "= get the passphrase for a group (GO only)" },
2962 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2964 "<addr> <TLVs> = schedule service discovery request" },
2965 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2967 "<id> = cancel pending service discovery request" },
2968 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2970 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2971 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2973 "= indicate change in local services" },
2974 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2976 "<external> = set external processing of service discovery" },
2977 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2979 "= remove all stored service entries" },
2980 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2982 "<bonjour|upnp> <query|version> <response|service> = add a local "
2984 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2986 "<bonjour|upnp> <query|version> [|service] = remove a local "
2988 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2990 "<addr> = reject connection attempts from a specific peer" },
2991 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2993 "<cmd> [peer=addr] = invite peer" },
2994 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2995 "[discovered] = list known (optionally, only fully discovered) P2P "
2997 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2998 "<address> = show information about known P2P peer" },
2999 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
3000 "<field> <value> = set a P2P parameter" },
3001 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
3002 "= flush P2P state" },
3003 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
3004 "= cancel P2P group formation" },
3005 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
3006 "<address> = unauthorize a peer" },
3007 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
3008 "[<duration> <interval>] [<duration> <interval>] = request GO "
3010 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
3011 "[<period> <interval>] = set extended listen timing" },
3012 #endif /* CONFIG_P2P */
3014 #ifdef CONFIG_INTERWORKING
3015 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
3016 "= fetch ANQP information for all APs" },
3017 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
3018 "= stop fetch_anqp operation" },
3019 { "interworking_select", wpa_cli_cmd_interworking_select,
3021 "[auto] = perform Interworking network selection" },
3022 { "interworking_connect", wpa_cli_cmd_interworking_connect,
3024 "<BSSID> = connect using Interworking credentials" },
3025 { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
3026 "<addr> <info id>[,<info id>]... = request ANQP information" },
3027 #endif /* CONFIG_INTERWORKING */
3028 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
3029 "<0/1> = disable/enable automatic reconnection" },
3030 { "tdls_discover", wpa_cli_cmd_tdls_discover,
3032 "<addr> = request TDLS discovery with <addr>" },
3033 { "tdls_setup", wpa_cli_cmd_tdls_setup,
3035 "<addr> = request TDLS setup with <addr>" },
3036 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
3038 "<addr> = tear down TDLS with <addr>" },
3039 { "signal_poll", wpa_cli_cmd_signal_poll,
3041 "= get signal parameters" },
3042 { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
3043 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3044 { "driver", wpa_cli_cmd_driver,
3046 "<command> = driver private commands" },
3047 { NULL, NULL, cli_cmd_flag_none, NULL }
3052 * Prints command usage, lines are padded with the specified string.
3054 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3059 printf("%s%s ", pad, cmd->cmd);
3060 for (n = 0; (c = cmd->usage[n]); n++) {
3069 static void print_help(void)
3072 printf("commands:\n");
3073 for (n = 0; wpa_cli_commands[n].cmd; n++)
3074 print_cmd_help(&wpa_cli_commands[n], " ");
3078 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3080 const char *c, *delim;
3084 delim = os_strchr(cmd, ' ');
3088 len = os_strlen(cmd);
3090 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3091 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3092 return (wpa_cli_commands[n].flags &
3093 cli_cmd_flag_sensitive);
3099 static char ** wpa_list_cmd_list(void)
3104 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
3105 res = os_zalloc(count * sizeof(char *));
3109 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3110 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3119 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3124 if (os_strcasecmp(cmd, "bss") == 0)
3125 return wpa_cli_complete_bss(str, pos);
3127 if (os_strcasecmp(cmd, "p2p_connect") == 0)
3128 return wpa_cli_complete_p2p_connect(str, pos);
3129 if (os_strcasecmp(cmd, "p2p_peer") == 0)
3130 return wpa_cli_complete_p2p_peer(str, pos);
3131 if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
3132 return wpa_cli_complete_p2p_group_remove(str, pos);
3133 #endif /* CONFIG_P2P */
3135 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3136 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3138 printf("\r%s\n", wpa_cli_commands[i].usage);
3148 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3154 end = os_strchr(str, ' ');
3155 if (end == NULL || str + pos < end)
3156 return wpa_list_cmd_list();
3158 cmd = os_malloc(pos + 1);
3161 os_memcpy(cmd, str, pos);
3162 cmd[end - str] = '\0';
3163 res = wpa_cli_cmd_completion(cmd, str, pos);
3169 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3171 struct wpa_cli_cmd *cmd, *match = NULL;
3176 cmd = wpa_cli_commands;
3178 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3181 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3182 /* we have an exact match */
3192 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3193 cmd = wpa_cli_commands;
3195 if (os_strncasecmp(cmd->cmd, argv[0],
3196 os_strlen(argv[0])) == 0) {
3197 printf(" %s", cmd->cmd);
3203 } else if (count == 0) {
3204 printf("Unknown command '%s'\n", argv[0]);
3207 ret = match->handler(ctrl, argc - 1, &argv[1]);
3214 static int str_match(const char *a, const char *b)
3216 return os_strncmp(a, b, os_strlen(b)) == 0;
3220 static int wpa_cli_exec(const char *program, const char *arg1,
3228 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3229 cmd = os_malloc(len);
3232 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3233 if (res < 0 || (size_t) res >= len) {
3237 cmd[len - 1] = '\0';
3239 if (system(cmd) < 0)
3241 #endif /* _WIN32_WCE */
3248 static void wpa_cli_action_process(const char *msg)
3251 char *copy = NULL, *id, *pos2;
3256 pos = os_strchr(pos, '>');
3263 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3265 os_unsetenv("WPA_ID");
3266 os_unsetenv("WPA_ID_STR");
3267 os_unsetenv("WPA_CTRL_DIR");
3269 pos = os_strstr(pos, "[id=");
3271 copy = os_strdup(pos + 4);
3275 while (*pos2 && *pos2 != ' ')
3279 os_setenv("WPA_ID", id, 1);
3280 while (*pos2 && *pos2 != '=')
3285 while (*pos2 && *pos2 != ']')
3288 os_setenv("WPA_ID_STR", id, 1);
3292 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3294 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3295 wpa_cli_connected = 1;
3296 wpa_cli_last_id = new_id;
3297 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3299 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3300 if (wpa_cli_connected) {
3301 wpa_cli_connected = 0;
3302 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3304 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3305 wpa_cli_exec(action_file, ctrl_ifname, pos);
3306 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3307 wpa_cli_exec(action_file, ctrl_ifname, pos);
3308 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3309 wpa_cli_exec(action_file, ctrl_ifname, pos);
3310 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3311 wpa_cli_exec(action_file, ctrl_ifname, pos);
3312 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3313 wpa_cli_exec(action_file, ctrl_ifname, pos);
3314 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3315 wpa_cli_exec(action_file, ctrl_ifname, pos);
3316 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3317 wpa_cli_exec(action_file, ctrl_ifname, pos);
3318 } else if (str_match(pos, AP_STA_CONNECTED)) {
3319 wpa_cli_exec(action_file, ctrl_ifname, pos);
3320 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3321 wpa_cli_exec(action_file, ctrl_ifname, pos);
3322 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3323 printf("wpa_supplicant is terminating - stop monitoring\n");
3329 #ifndef CONFIG_ANSI_C_EXTRA
3330 static void wpa_cli_action_cb(char *msg, size_t len)
3332 wpa_cli_action_process(msg);
3334 #endif /* CONFIG_ANSI_C_EXTRA */
3337 static void wpa_cli_reconnect(void)
3339 wpa_cli_close_connection();
3340 wpa_cli_open_connection(ctrl_ifname, 1);
3344 static void cli_event(const char *str)
3346 const char *start, *s;
3348 start = os_strchr(str, '>');
3354 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3355 s = os_strchr(start, ' ');
3358 s = os_strchr(s + 1, ' ');
3361 cli_txt_list_add(&bsses, s + 1);
3365 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3366 s = os_strchr(start, ' ');
3369 s = os_strchr(s + 1, ' ');
3372 cli_txt_list_del_addr(&bsses, s + 1);
3377 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3378 s = os_strstr(start, " p2p_dev_addr=");
3381 cli_txt_list_add_addr(&p2p_peers, s + 14);
3385 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3386 s = os_strstr(start, " p2p_dev_addr=");
3389 cli_txt_list_del_addr(&p2p_peers, s + 14);
3393 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3394 s = os_strchr(start, ' ');
3397 cli_txt_list_add_word(&p2p_groups, s + 1);
3401 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3402 s = os_strchr(start, ' ');
3405 cli_txt_list_del_word(&p2p_groups, s + 1);
3408 #endif /* CONFIG_P2P */
3412 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3414 if (ctrl_conn == NULL) {
3415 wpa_cli_reconnect();
3418 while (wpa_ctrl_pending(ctrl) > 0) {
3420 size_t len = sizeof(buf) - 1;
3421 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3424 wpa_cli_action_process(buf);
3427 if (wpa_cli_show_event(buf)) {
3429 printf("\r%s\n", buf);
3434 printf("Could not read pending message.\n");
3439 if (wpa_ctrl_pending(ctrl) < 0) {
3440 printf("Connection to wpa_supplicant lost - trying to "
3442 wpa_cli_reconnect();
3448 static int tokenize_cmd(char *cmd, char *argv[])
3461 if (argc == max_args)
3464 char *pos2 = os_strrchr(pos, '"');
3468 while (*pos != '\0' && *pos != ' ')
3478 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3480 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3481 printf("Connection to wpa_supplicant lost - trying to "
3483 wpa_cli_close_connection();
3486 wpa_cli_reconnect();
3487 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3491 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3497 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3499 wpa_cli_recv_pending(mon_conn, 0);
3503 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3505 char *argv[max_args];
3507 argc = tokenize_cmd(cmd, argv);
3509 wpa_request(ctrl_conn, argc, argv);
3513 static void wpa_cli_edit_eof_cb(void *ctx)
3519 static void wpa_cli_interactive(void)
3521 char *home, *hfile = NULL;
3523 printf("\nInteractive mode\n\n");
3525 home = getenv("HOME");
3527 const char *fname = ".wpa_cli_history";
3528 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3529 hfile = os_malloc(hfile_len);
3531 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3534 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3535 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3536 wpa_cli_edit_completion_cb, NULL, hfile);
3537 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3541 cli_txt_list_flush(&p2p_peers);
3542 cli_txt_list_flush(&p2p_groups);
3543 cli_txt_list_flush(&bsses);
3544 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3546 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3547 wpa_cli_close_connection();
3551 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3553 #ifdef CONFIG_ANSI_C_EXTRA
3554 /* TODO: ANSI C version(?) */
3555 printf("Action processing not supported in ANSI C build.\n");
3556 #else /* CONFIG_ANSI_C_EXTRA */
3560 char buf[256]; /* note: large enough to fit in unsolicited messages */
3563 fd = wpa_ctrl_get_fd(ctrl);
3565 while (!wpa_cli_quit) {
3568 tv.tv_sec = ping_interval;
3570 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3571 if (res < 0 && errno != EINTR) {
3576 if (FD_ISSET(fd, &rfds))
3577 wpa_cli_recv_pending(ctrl, 1);
3579 /* verify that connection is still working */
3580 len = sizeof(buf) - 1;
3581 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3582 wpa_cli_action_cb) < 0 ||
3583 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3584 printf("wpa_supplicant did not reply to PING "
3585 "command - exiting\n");
3590 #endif /* CONFIG_ANSI_C_EXTRA */
3594 static void wpa_cli_cleanup(void)
3596 wpa_cli_close_connection();
3598 os_daemonize_terminate(pid_file);
3600 os_program_deinit();
3603 static void wpa_cli_terminate(int sig)
3610 static char * wpa_cli_get_default_ifname(void)
3612 char *ifname = NULL;
3614 #ifdef CONFIG_CTRL_IFACE_UNIX
3615 struct dirent *dent;
3616 DIR *dir = opendir(ctrl_iface_dir);
3619 char ifprop[PROPERTY_VALUE_MAX];
3620 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3621 ifname = os_strdup(ifprop);
3622 printf("Using interface '%s'\n", ifname);
3625 #endif /* ANDROID */
3628 while ((dent = readdir(dir))) {
3629 #ifdef _DIRENT_HAVE_D_TYPE
3631 * Skip the file if it is not a socket. Also accept
3632 * DT_UNKNOWN (0) in case the C library or underlying
3633 * file system does not support d_type.
3635 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3637 #endif /* _DIRENT_HAVE_D_TYPE */
3638 if (os_strcmp(dent->d_name, ".") == 0 ||
3639 os_strcmp(dent->d_name, "..") == 0)
3641 printf("Selected interface '%s'\n", dent->d_name);
3642 ifname = os_strdup(dent->d_name);
3646 #endif /* CONFIG_CTRL_IFACE_UNIX */
3648 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3649 char buf[4096], *pos;
3651 struct wpa_ctrl *ctrl;
3654 ctrl = wpa_ctrl_open(NULL);
3658 len = sizeof(buf) - 1;
3659 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3662 pos = os_strchr(buf, '\n');
3665 ifname = os_strdup(buf);
3667 wpa_ctrl_close(ctrl);
3668 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3674 int main(int argc, char *argv[])
3676 int warning_displayed = 0;
3680 const char *global = NULL;
3682 if (os_program_init())
3686 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3691 action_file = optarg;
3700 ping_interval = atoi(optarg);
3706 printf("%s\n", wpa_cli_version);
3709 os_free(ctrl_ifname);
3710 ctrl_ifname = os_strdup(optarg);
3713 ctrl_iface_dir = optarg;
3724 interactive = (argc == optind) && (action_file == NULL);
3727 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3733 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3734 ctrl_conn = wpa_ctrl_open(NULL);
3735 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3736 ctrl_conn = wpa_ctrl_open(global);
3737 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3738 if (ctrl_conn == NULL) {
3739 perror("Failed to connect to wpa_supplicant - "
3746 signal(SIGINT, wpa_cli_terminate);
3747 signal(SIGTERM, wpa_cli_terminate);
3748 #endif /* _WIN32_WCE */
3750 if (ctrl_ifname == NULL)
3751 ctrl_ifname = wpa_cli_get_default_ifname();
3755 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3756 if (warning_displayed)
3757 printf("Connection established.\n");
3761 if (!warning_displayed) {
3762 printf("Could not connect to wpa_supplicant - "
3764 warning_displayed = 1;
3771 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3772 perror("Failed to connect to wpa_supplicant - "
3778 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3779 wpa_cli_attached = 1;
3781 printf("Warning: Failed to attach to "
3782 "wpa_supplicant.\n");
3788 if (daemonize && os_daemonize(pid_file))
3792 wpa_cli_interactive();
3793 else if (action_file)
3794 wpa_cli_action(ctrl_conn);
3796 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3798 os_free(ctrl_ifname);
3805 #else /* CONFIG_CTRL_IFACE */
3806 int main(int argc, char *argv[])
3808 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3811 #endif /* CONFIG_CTRL_IFACE */