2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2010, 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 */
22 #ifdef CONFIG_READLINE
23 #include <readline/readline.h>
24 #include <readline/history.h>
25 #endif /* CONFIG_READLINE */
26 #ifdef CONFIG_WPA_CLI_FORK
28 #endif /* CONFIG_WPA_CLI_FORK */
30 #include "common/wpa_ctrl.h"
32 #include "common/version.h"
35 static const char *wpa_cli_version =
36 "wpa_cli v" VERSION_STR "\n"
37 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
40 static const char *wpa_cli_license =
41 "This program is free software. You can distribute it and/or modify it\n"
42 "under the terms of the GNU General Public License version 2.\n"
44 "Alternatively, this software may be distributed under the terms of the\n"
45 "BSD license. See README and COPYING for more details.\n";
47 static const char *wpa_cli_full_license =
48 "This program is free software; you can redistribute it and/or modify\n"
49 "it under the terms of the GNU General Public License version 2 as\n"
50 "published by the Free Software Foundation.\n"
52 "This program is distributed in the hope that it will be useful,\n"
53 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
54 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
55 "GNU General Public License for more details.\n"
57 "You should have received a copy of the GNU General Public License\n"
58 "along with this program; if not, write to the Free Software\n"
59 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
61 "Alternatively, this software may be distributed under the terms of the\n"
64 "Redistribution and use in source and binary forms, with or without\n"
65 "modification, are permitted provided that the following conditions are\n"
68 "1. Redistributions of source code must retain the above copyright\n"
69 " notice, this list of conditions and the following disclaimer.\n"
71 "2. Redistributions in binary form must reproduce the above copyright\n"
72 " notice, this list of conditions and the following disclaimer in the\n"
73 " documentation and/or other materials provided with the distribution.\n"
75 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
76 " names of its contributors may be used to endorse or promote products\n"
77 " derived from this software without specific prior written permission.\n"
79 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
80 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
81 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
82 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
83 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
84 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
85 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
86 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
87 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
88 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
89 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
92 static struct wpa_ctrl *ctrl_conn;
93 static struct wpa_ctrl *mon_conn;
94 #ifdef CONFIG_WPA_CLI_FORK
95 static pid_t mon_pid = 0;
96 #endif /* CONFIG_WPA_CLI_FORK */
97 static int wpa_cli_quit = 0;
98 static int wpa_cli_attached = 0;
99 static int wpa_cli_connected = 0;
100 static int wpa_cli_last_id = 0;
101 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
102 static char *ctrl_ifname = NULL;
103 static const char *pid_file = NULL;
104 static const char *action_file = NULL;
105 static int ping_interval = 5;
106 static int interactive = 0;
109 static void print_help();
112 static void usage(void)
114 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
115 "[-a<action file>] \\\n"
116 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
118 " -h = help (show this usage text)\n"
119 " -v = shown version information\n"
120 " -a = run in daemon mode executing the action file based on "
123 " -B = run a daemon in the background\n"
124 " default path: /var/run/wpa_supplicant\n"
125 " default interface: first interface found in socket path\n");
130 static void readline_redraw()
132 #ifdef CONFIG_READLINE
135 #endif /* CONFIG_READLINE */
139 static int str_starts(const char *src, const char *match)
141 return os_strncmp(src, match, os_strlen(match)) == 0;
145 static int wpa_cli_show_event(const char *event)
149 start = os_strchr(event, '>');
155 * Skip BSS added/removed events since they can be relatively frequent
156 * and are likely of not much use for an interactive user.
158 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
159 str_starts(start, WPA_EVENT_BSS_REMOVED))
166 #ifdef CONFIG_WPA_CLI_FORK
167 static int in_query = 0;
169 static void wpa_cli_monitor_sig(int sig)
173 else if (sig == SIGUSR2)
178 static void wpa_cli_monitor(void)
181 size_t len = sizeof(buf) - 1;
186 signal(SIGUSR1, wpa_cli_monitor_sig);
187 signal(SIGUSR2, wpa_cli_monitor_sig);
191 int s = wpa_ctrl_get_fd(mon_conn);
196 if (select(s + 1, &rfds, NULL, NULL, &tv) < 0) {
202 if (mon_conn == NULL)
204 if (FD_ISSET(s, &rfds)) {
205 len = sizeof(buf) - 1;
206 int res = wpa_ctrl_recv(mon_conn, buf, &len);
208 perror("wpa_ctrl_recv");
212 if (wpa_cli_show_event(buf)) {
221 #endif /* CONFIG_WPA_CLI_FORK */
224 static int wpa_cli_open_connection(const char *ifname, int attach)
226 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
227 ctrl_conn = wpa_ctrl_open(ifname);
228 if (ctrl_conn == NULL)
231 if (attach && interactive)
232 mon_conn = wpa_ctrl_open(ifname);
235 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
242 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
243 cfile = os_malloc(flen);
246 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
247 if (res < 0 || res >= flen) {
252 ctrl_conn = wpa_ctrl_open(cfile);
253 if (ctrl_conn == NULL) {
258 if (attach && interactive)
259 mon_conn = wpa_ctrl_open(cfile);
263 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
266 if (wpa_ctrl_attach(mon_conn) == 0) {
267 wpa_cli_attached = 1;
269 printf("Warning: Failed to attach to "
270 "wpa_supplicant.\n");
274 #ifdef CONFIG_WPA_CLI_FORK
287 #endif /* CONFIG_WPA_CLI_FORK */
294 static void wpa_cli_close_connection(void)
296 if (ctrl_conn == NULL)
299 #ifdef CONFIG_WPA_CLI_FORK
302 kill(mon_pid, SIGPIPE);
306 #endif /* CONFIG_WPA_CLI_FORK */
308 if (wpa_cli_attached) {
309 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
310 wpa_cli_attached = 0;
312 wpa_ctrl_close(ctrl_conn);
315 wpa_ctrl_close(mon_conn);
321 static void wpa_cli_msg_cb(char *msg, size_t len)
327 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
333 if (ctrl_conn == NULL) {
334 printf("Not connected to wpa_supplicant - command dropped.\n");
337 len = sizeof(buf) - 1;
338 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
341 printf("'%s' command timed out.\n", cmd);
343 } else if (ret < 0) {
344 printf("'%s' command failed.\n", cmd);
355 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
357 return _wpa_ctrl_command(ctrl, cmd, 1);
361 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
363 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
364 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
368 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
370 return wpa_ctrl_command(ctrl, "PING");
374 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
380 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
381 if (ret < 0 || (size_t) ret >= sizeof(cmd))
383 return wpa_ctrl_command(ctrl, cmd);
387 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
389 return wpa_ctrl_command(ctrl, "MIB");
393 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
395 return wpa_ctrl_command(ctrl, "PMKSA");
399 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
406 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
408 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
413 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
420 static void wpa_cli_show_variables(void)
422 printf("set variables:\n"
423 " EAPOL::heldPeriod (EAPOL state machine held period, "
425 " EAPOL::authPeriod (EAPOL state machine authentication "
426 "period, in seconds)\n"
427 " EAPOL::startPeriod (EAPOL state machine start period, in "
429 " EAPOL::maxStart (EAPOL state machine maximum start "
431 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
433 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
434 " threshold\n\tpercentage)\n"
435 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
436 "security\n\tassociation in seconds)\n");
440 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
446 wpa_cli_show_variables();
451 printf("Invalid SET command: needs two arguments (variable "
452 "name and value)\n");
456 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
457 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
458 printf("Too long SET command.\n");
461 return wpa_ctrl_command(ctrl, cmd);
465 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
467 return wpa_ctrl_command(ctrl, "LOGOFF");
471 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
473 return wpa_ctrl_command(ctrl, "LOGON");
477 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
480 return wpa_ctrl_command(ctrl, "REASSOCIATE");
484 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
491 printf("Invalid PREAUTH command: needs one argument "
496 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
497 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
498 printf("Too long PREAUTH command.\n");
501 return wpa_ctrl_command(ctrl, cmd);
505 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
511 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
515 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
516 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
517 printf("Too long AP_SCAN command.\n");
520 return wpa_ctrl_command(ctrl, cmd);
524 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
531 printf("Invalid STKSTART command: needs one argument "
532 "(Peer STA MAC address)\n");
536 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
537 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
538 printf("Too long STKSTART command.\n");
541 return wpa_ctrl_command(ctrl, cmd);
545 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
551 printf("Invalid FT_DS command: needs one argument "
552 "(Target AP MAC address)\n");
556 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
557 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
558 printf("Too long FT_DS command.\n");
561 return wpa_ctrl_command(ctrl, cmd);
565 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
572 return wpa_ctrl_command(ctrl, "WPS_PBC");
576 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
577 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
578 printf("Too long WPS_PBC command.\n");
581 return wpa_ctrl_command(ctrl, cmd);
585 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
591 printf("Invalid WPS_PIN command: need one or two arguments:\n"
592 "- BSSID: use 'any' to select any\n"
593 "- PIN: optional, used only with devices that have no "
599 /* Use dynamically generated PIN (returned as reply) */
600 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
601 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
602 printf("Too long WPS_PIN command.\n");
605 return wpa_ctrl_command(ctrl, cmd);
608 /* Use hardcoded PIN from a label */
609 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
610 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
611 printf("Too long WPS_PIN command.\n");
614 return wpa_ctrl_command(ctrl, cmd);
618 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
621 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
625 #ifdef CONFIG_WPS_OOB
626 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
631 if (argc != 3 && argc != 4) {
632 printf("Invalid WPS_OOB command: need three or four "
634 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
635 "- PATH: path of OOB device like '/mnt'\n"
636 "- METHOD: OOB method 'pin-e' or 'pin-r', "
638 "- DEV_NAME: (only for NFC) device name like "
644 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
645 argv[0], argv[1], argv[2]);
647 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
648 argv[0], argv[1], argv[2], argv[3]);
649 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
650 printf("Too long WPS_OOB command.\n");
653 return wpa_ctrl_command(ctrl, cmd);
655 #endif /* CONFIG_WPS_OOB */
658 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
664 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
666 else if (argc == 5 || argc == 6) {
667 char ssid_hex[2 * 32 + 1];
668 char key_hex[2 * 64 + 1];
672 for (i = 0; i < 32; i++) {
673 if (argv[2][i] == '\0')
675 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
680 for (i = 0; i < 64; i++) {
681 if (argv[5][i] == '\0')
683 os_snprintf(&key_hex[i * 2], 3, "%02x",
688 res = os_snprintf(cmd, sizeof(cmd),
689 "WPS_REG %s %s %s %s %s %s",
690 argv[0], argv[1], ssid_hex, argv[3], argv[4],
693 printf("Invalid WPS_REG command: need two arguments:\n"
694 "- BSSID: use 'any' to select any\n"
696 printf("Alternatively, six arguments can be used to "
697 "reconfigure the AP:\n"
698 "- BSSID: use 'any' to select any\n"
701 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
702 "- new encr (NONE, WEP, TKIP, CCMP)\n"
707 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
708 printf("Too long WPS_REG command.\n");
711 return wpa_ctrl_command(ctrl, cmd);
715 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
720 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
721 return wpa_ctrl_command(ctrl, cmd);
723 return wpa_ctrl_command(ctrl, "WPS_ER_START");
727 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
730 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
735 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
742 printf("Invalid WPS_ER_PIN command: need at least two "
744 "- UUID: use 'any' to select any\n"
745 "- PIN: Enrollee PIN\n"
746 "optional: - Enrollee MAC address\n");
751 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
752 argv[0], argv[1], argv[2]);
754 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
756 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
757 printf("Too long WPS_ER_PIN command.\n");
760 return wpa_ctrl_command(ctrl, cmd);
764 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
771 printf("Invalid WPS_ER_PBC command: need one argument:\n"
772 "- UUID: Specify the Enrollee\n");
776 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
778 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
779 printf("Too long WPS_ER_PBC command.\n");
782 return wpa_ctrl_command(ctrl, cmd);
786 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
793 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
794 "- UUID: specify which AP to use\n"
799 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
801 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
802 printf("Too long WPS_ER_LEARN command.\n");
805 return wpa_ctrl_command(ctrl, cmd);
809 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
815 if (argc == 5 || argc == 6) {
816 char ssid_hex[2 * 32 + 1];
817 char key_hex[2 * 64 + 1];
821 for (i = 0; i < 32; i++) {
822 if (argv[2][i] == '\0')
824 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
829 for (i = 0; i < 64; i++) {
830 if (argv[5][i] == '\0')
832 os_snprintf(&key_hex[i * 2], 3, "%02x",
837 res = os_snprintf(cmd, sizeof(cmd),
838 "WPS_ER_CONFIG %s %s %s %s %s %s",
839 argv[0], argv[1], ssid_hex, argv[3], argv[4],
842 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
846 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
847 "- new encr (NONE, WEP, TKIP, CCMP)\n"
852 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
853 printf("Too long WPS_ER_CONFIG command.\n");
856 return wpa_ctrl_command(ctrl, cmd);
860 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
866 printf("Invalid IBSS_RSN command: needs one argument "
867 "(Peer STA MAC address)\n");
871 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
872 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
873 printf("Too long IBSS_RSN command.\n");
876 return wpa_ctrl_command(ctrl, cmd);
880 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
886 printf("Invalid LEVEL command: needs one argument (debug "
890 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
891 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
892 printf("Too long LEVEL command.\n");
895 return wpa_ctrl_command(ctrl, cmd);
899 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
901 char cmd[256], *pos, *end;
905 printf("Invalid IDENTITY command: needs two arguments "
906 "(network id and identity)\n");
910 end = cmd + sizeof(cmd);
912 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
914 if (ret < 0 || ret >= end - pos) {
915 printf("Too long IDENTITY command.\n");
919 for (i = 2; i < argc; i++) {
920 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
921 if (ret < 0 || ret >= end - pos) {
922 printf("Too long IDENTITY command.\n");
928 return wpa_ctrl_command(ctrl, cmd);
932 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
934 char cmd[256], *pos, *end;
938 printf("Invalid PASSWORD command: needs two arguments "
939 "(network id and password)\n");
943 end = cmd + sizeof(cmd);
945 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
947 if (ret < 0 || ret >= end - pos) {
948 printf("Too long PASSWORD command.\n");
952 for (i = 2; i < argc; i++) {
953 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
954 if (ret < 0 || ret >= end - pos) {
955 printf("Too long PASSWORD command.\n");
961 return wpa_ctrl_command(ctrl, cmd);
965 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
968 char cmd[256], *pos, *end;
972 printf("Invalid NEW_PASSWORD command: needs two arguments "
973 "(network id and password)\n");
977 end = cmd + sizeof(cmd);
979 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
981 if (ret < 0 || ret >= end - pos) {
982 printf("Too long NEW_PASSWORD command.\n");
986 for (i = 2; i < argc; i++) {
987 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
988 if (ret < 0 || ret >= end - pos) {
989 printf("Too long NEW_PASSWORD command.\n");
995 return wpa_ctrl_command(ctrl, cmd);
999 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1001 char cmd[256], *pos, *end;
1005 printf("Invalid PIN command: needs two arguments "
1006 "(network id and pin)\n");
1010 end = cmd + sizeof(cmd);
1012 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1014 if (ret < 0 || ret >= end - pos) {
1015 printf("Too long PIN command.\n");
1019 for (i = 2; i < argc; i++) {
1020 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1021 if (ret < 0 || ret >= end - pos) {
1022 printf("Too long PIN command.\n");
1027 return wpa_ctrl_command(ctrl, cmd);
1031 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1033 char cmd[256], *pos, *end;
1037 printf("Invalid OTP command: needs two arguments (network "
1038 "id and password)\n");
1042 end = cmd + sizeof(cmd);
1044 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1046 if (ret < 0 || ret >= end - pos) {
1047 printf("Too long OTP command.\n");
1051 for (i = 2; i < argc; i++) {
1052 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1053 if (ret < 0 || ret >= end - pos) {
1054 printf("Too long OTP command.\n");
1060 return wpa_ctrl_command(ctrl, cmd);
1064 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1067 char cmd[256], *pos, *end;
1071 printf("Invalid PASSPHRASE command: needs two arguments "
1072 "(network id and passphrase)\n");
1076 end = cmd + sizeof(cmd);
1078 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1080 if (ret < 0 || ret >= end - pos) {
1081 printf("Too long PASSPHRASE command.\n");
1085 for (i = 2; i < argc; i++) {
1086 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1087 if (ret < 0 || ret >= end - pos) {
1088 printf("Too long PASSPHRASE command.\n");
1094 return wpa_ctrl_command(ctrl, cmd);
1098 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1100 char cmd[256], *pos, *end;
1104 printf("Invalid BSSID command: needs two arguments (network "
1109 end = cmd + sizeof(cmd);
1111 ret = os_snprintf(pos, end - pos, "BSSID");
1112 if (ret < 0 || ret >= end - pos) {
1113 printf("Too long BSSID command.\n");
1117 for (i = 0; i < argc; i++) {
1118 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1119 if (ret < 0 || ret >= end - pos) {
1120 printf("Too long BSSID command.\n");
1126 return wpa_ctrl_command(ctrl, cmd);
1130 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1133 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1137 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1144 printf("Invalid SELECT_NETWORK command: needs one argument "
1149 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1150 if (res < 0 || (size_t) res >= sizeof(cmd))
1152 cmd[sizeof(cmd) - 1] = '\0';
1154 return wpa_ctrl_command(ctrl, cmd);
1158 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1165 printf("Invalid ENABLE_NETWORK command: needs one argument "
1170 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1171 if (res < 0 || (size_t) res >= sizeof(cmd))
1173 cmd[sizeof(cmd) - 1] = '\0';
1175 return wpa_ctrl_command(ctrl, cmd);
1179 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1186 printf("Invalid DISABLE_NETWORK command: needs one argument "
1191 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1192 if (res < 0 || (size_t) res >= sizeof(cmd))
1194 cmd[sizeof(cmd) - 1] = '\0';
1196 return wpa_ctrl_command(ctrl, cmd);
1200 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1203 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1207 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1214 printf("Invalid REMOVE_NETWORK command: needs one argument "
1219 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1220 if (res < 0 || (size_t) res >= sizeof(cmd))
1222 cmd[sizeof(cmd) - 1] = '\0';
1224 return wpa_ctrl_command(ctrl, cmd);
1228 static void wpa_cli_show_network_variables(void)
1230 printf("set_network variables:\n"
1231 " ssid (network name, SSID)\n"
1232 " psk (WPA passphrase or pre-shared key)\n"
1233 " key_mgmt (key management protocol)\n"
1234 " identity (EAP identity)\n"
1235 " password (EAP password)\n"
1238 "Note: Values are entered in the same format as the "
1239 "configuration file is using,\n"
1240 "i.e., strings values need to be inside double quotation "
1242 "For example: set_network 1 ssid \"network name\"\n"
1244 "Please see wpa_supplicant.conf documentation for full list "
1245 "of\navailable variables.\n");
1249 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1256 wpa_cli_show_network_variables();
1261 printf("Invalid SET_NETWORK command: needs three arguments\n"
1262 "(network id, variable name, and value)\n");
1266 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1267 argv[0], argv[1], argv[2]);
1268 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1269 printf("Too long SET_NETWORK command.\n");
1272 return wpa_ctrl_command(ctrl, cmd);
1276 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1283 wpa_cli_show_network_variables();
1288 printf("Invalid GET_NETWORK command: needs two arguments\n"
1289 "(network id and variable name)\n");
1293 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1295 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1296 printf("Too long GET_NETWORK command.\n");
1299 return wpa_ctrl_command(ctrl, cmd);
1303 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1306 return wpa_ctrl_command(ctrl, "DISCONNECT");
1310 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1313 return wpa_ctrl_command(ctrl, "RECONNECT");
1317 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1320 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1324 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1326 return wpa_ctrl_command(ctrl, "SCAN");
1330 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1333 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1337 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1343 printf("Invalid BSS command: need one argument (index or "
1348 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1349 if (res < 0 || (size_t) res >= sizeof(cmd))
1351 cmd[sizeof(cmd) - 1] = '\0';
1353 return wpa_ctrl_command(ctrl, cmd);
1357 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1363 if (argc < 1 || argc > 2) {
1364 printf("Invalid GET_CAPABILITY command: need either one or "
1369 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1370 printf("Invalid GET_CAPABILITY command: second argument, "
1371 "if any, must be 'strict'\n");
1375 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1376 (argc == 2) ? " strict" : "");
1377 if (res < 0 || (size_t) res >= sizeof(cmd))
1379 cmd[sizeof(cmd) - 1] = '\0';
1381 return wpa_ctrl_command(ctrl, cmd);
1385 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1387 printf("Available interfaces:\n");
1388 return wpa_ctrl_command(ctrl, "INTERFACES");
1392 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1395 wpa_cli_list_interfaces(ctrl);
1399 wpa_cli_close_connection();
1400 os_free(ctrl_ifname);
1401 ctrl_ifname = os_strdup(argv[0]);
1403 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1404 printf("Connected to interface '%s.\n", ctrl_ifname);
1406 printf("Could not connect to interface '%s' - re-trying\n",
1413 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1416 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1420 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1423 return wpa_ctrl_command(ctrl, "TERMINATE");
1427 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1434 printf("Invalid INTERFACE_ADD command: needs at least one "
1435 "argument (interface name)\n"
1436 "All arguments: ifname confname driver ctrl_interface "
1437 "driver_param bridge_name\n");
1442 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1443 * <driver_param>TAB<bridge_name>
1445 res = os_snprintf(cmd, sizeof(cmd),
1446 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1448 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1449 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1450 argc > 5 ? argv[5] : "");
1451 if (res < 0 || (size_t) res >= sizeof(cmd))
1453 cmd[sizeof(cmd) - 1] = '\0';
1454 return wpa_ctrl_command(ctrl, cmd);
1458 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1465 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1466 "(interface name)\n");
1470 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1471 if (res < 0 || (size_t) res >= sizeof(cmd))
1473 cmd[sizeof(cmd) - 1] = '\0';
1474 return wpa_ctrl_command(ctrl, cmd);
1478 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1481 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1486 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1490 printf("Invalid 'sta' command - exactly one argument, STA "
1491 "address, is required.\n");
1494 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1495 return wpa_ctrl_command(ctrl, buf);
1499 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1500 char *addr, size_t addr_len)
1502 char buf[4096], *pos;
1506 if (ctrl_conn == NULL) {
1507 printf("Not connected to hostapd - command dropped.\n");
1510 len = sizeof(buf) - 1;
1511 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1514 printf("'%s' command timed out.\n", cmd);
1516 } else if (ret < 0) {
1517 printf("'%s' command failed.\n", cmd);
1522 if (memcmp(buf, "FAIL", 4) == 0)
1527 while (*pos != '\0' && *pos != '\n')
1530 os_strlcpy(addr, buf, addr_len);
1535 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1537 char addr[32], cmd[64];
1539 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1542 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1543 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1547 #endif /* CONFIG_AP */
1550 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1552 return wpa_ctrl_command(ctrl, "SUSPEND");
1556 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1558 return wpa_ctrl_command(ctrl, "RESUME");
1562 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1564 return wpa_ctrl_command(ctrl, "DROP_SA");
1568 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1574 printf("Invalid ROAM command: needs one argument "
1575 "(target AP's BSSID)\n");
1579 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1580 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1581 printf("Too long ROAM command.\n");
1584 return wpa_ctrl_command(ctrl, cmd);
1590 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1596 return wpa_ctrl_command(ctrl, "P2P_FIND");
1599 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1602 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1603 if (res < 0 || (size_t) res >= sizeof(cmd))
1605 cmd[sizeof(cmd) - 1] = '\0';
1606 return wpa_ctrl_command(ctrl, cmd);
1610 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1613 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1617 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1624 printf("Invalid P2P_CONNECT command: needs at least two "
1625 "arguments (address and pbc/PIN)\n");
1630 res = os_snprintf(cmd, sizeof(cmd),
1631 "P2P_CONNECT %s %s %s %s %s",
1632 argv[0], argv[1], argv[2], argv[3],
1635 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1636 argv[0], argv[1], argv[2], argv[3]);
1638 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1639 argv[0], argv[1], argv[2]);
1641 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1643 if (res < 0 || (size_t) res >= sizeof(cmd))
1645 cmd[sizeof(cmd) - 1] = '\0';
1646 return wpa_ctrl_command(ctrl, cmd);
1650 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1657 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1659 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1660 if (res < 0 || (size_t) res >= sizeof(cmd))
1662 cmd[sizeof(cmd) - 1] = '\0';
1663 return wpa_ctrl_command(ctrl, cmd);
1667 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1674 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1675 "(interface name)\n");
1679 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
1680 if (res < 0 || (size_t) res >= sizeof(cmd))
1682 cmd[sizeof(cmd) - 1] = '\0';
1683 return wpa_ctrl_command(ctrl, cmd);
1687 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1694 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
1696 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", argv[0]);
1697 if (res < 0 || (size_t) res >= sizeof(cmd))
1699 cmd[sizeof(cmd) - 1] = '\0';
1700 return wpa_ctrl_command(ctrl, cmd);
1704 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1711 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1712 "(address and config method\n"
1713 "(display, keypad, or pbc)\n");
1717 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
1719 if (res < 0 || (size_t) res >= sizeof(cmd))
1721 cmd[sizeof(cmd) - 1] = '\0';
1722 return wpa_ctrl_command(ctrl, cmd);
1726 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1729 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1733 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1739 if (argc != 2 && argc != 4) {
1740 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1741 "arguments (address and TLVs) or four arguments "
1742 "(address, \"upnp\", version, search target "
1748 res = os_snprintf(cmd, sizeof(cmd),
1749 "P2P_SERV_DISC_REQ %s %s %s %s",
1750 argv[0], argv[1], argv[2], argv[3]);
1752 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
1754 if (res < 0 || (size_t) res >= sizeof(cmd))
1756 cmd[sizeof(cmd) - 1] = '\0';
1757 return wpa_ctrl_command(ctrl, cmd);
1761 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1762 int argc, char *argv[])
1768 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1769 "argument (pending request identifier)\n");
1773 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
1775 if (res < 0 || (size_t) res >= sizeof(cmd))
1777 cmd[sizeof(cmd) - 1] = '\0';
1778 return wpa_ctrl_command(ctrl, cmd);
1782 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1789 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1790 "arguments (freq, address, dialog token, and TLVs)\n");
1794 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1795 argv[0], argv[1], argv[2], argv[3]);
1796 if (res < 0 || (size_t) res >= sizeof(cmd))
1798 cmd[sizeof(cmd) - 1] = '\0';
1799 return wpa_ctrl_command(ctrl, cmd);
1803 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1806 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1810 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1811 int argc, char *argv[])
1817 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1818 "argument (external processing: 0/1)\n");
1822 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
1824 if (res < 0 || (size_t) res >= sizeof(cmd))
1826 cmd[sizeof(cmd) - 1] = '\0';
1827 return wpa_ctrl_command(ctrl, cmd);
1831 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1834 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1838 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1844 if (argc != 3 && argc != 4) {
1845 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1851 res = os_snprintf(cmd, sizeof(cmd),
1852 "P2P_SERVICE_ADD %s %s %s %s",
1853 argv[0], argv[1], argv[2], argv[3]);
1855 res = os_snprintf(cmd, sizeof(cmd),
1856 "P2P_SERVICE_ADD %s %s %s",
1857 argv[0], argv[1], argv[2]);
1858 if (res < 0 || (size_t) res >= sizeof(cmd))
1860 cmd[sizeof(cmd) - 1] = '\0';
1861 return wpa_ctrl_command(ctrl, cmd);
1865 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1871 if (argc != 2 && argc != 3) {
1872 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1878 res = os_snprintf(cmd, sizeof(cmd),
1879 "P2P_SERVICE_DEL %s %s %s",
1880 argv[0], argv[1], argv[2]);
1882 res = os_snprintf(cmd, sizeof(cmd),
1883 "P2P_SERVICE_DEL %s %s",
1885 if (res < 0 || (size_t) res >= sizeof(cmd))
1887 cmd[sizeof(cmd) - 1] = '\0';
1888 return wpa_ctrl_command(ctrl, cmd);
1892 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1893 int argc, char *argv[])
1899 printf("Invalid P2P_REJECT command: needs one argument "
1900 "(peer address)\n");
1904 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
1905 if (res < 0 || (size_t) res >= sizeof(cmd))
1907 cmd[sizeof(cmd) - 1] = '\0';
1908 return wpa_ctrl_command(ctrl, cmd);
1912 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1913 int argc, char *argv[])
1919 printf("Invalid P2P_INVITE command: needs at least one "
1925 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
1926 argv[0], argv[1], argv[2]);
1928 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
1931 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
1932 if (res < 0 || (size_t) res >= sizeof(cmd))
1934 cmd[sizeof(cmd) - 1] = '\0';
1935 return wpa_ctrl_command(ctrl, cmd);
1939 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
1943 printf("Invalid 'p2p_peer' command - exactly one argument, "
1944 "P2P peer device address, is required.\n");
1947 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
1948 return wpa_ctrl_command(ctrl, buf);
1952 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
1953 char *addr, size_t addr_len,
1956 char buf[4096], *pos;
1960 if (ctrl_conn == NULL)
1962 len = sizeof(buf) - 1;
1963 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1966 printf("'%s' command timed out.\n", cmd);
1968 } else if (ret < 0) {
1969 printf("'%s' command failed.\n", cmd);
1974 if (memcmp(buf, "FAIL", 4) == 0)
1978 while (*pos != '\0' && *pos != '\n')
1981 os_strlcpy(addr, buf, addr_len);
1982 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
1983 printf("%s\n", addr);
1988 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
1990 char addr[32], cmd[64];
1993 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
1995 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
1996 addr, sizeof(addr), discovered))
1999 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2000 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2007 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2013 printf("Invalid P2P_SET command: needs two arguments (field, "
2018 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2019 if (res < 0 || (size_t) res >= sizeof(cmd))
2021 cmd[sizeof(cmd) - 1] = '\0';
2022 return wpa_ctrl_command(ctrl, cmd);
2026 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2028 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2032 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2038 if (argc != 0 && argc != 2 && argc != 4) {
2039 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2040 "(preferred duration, interval; in microsecods).\n"
2041 "Optional second pair can be used to provide "
2042 "acceptable values.\n");
2047 res = os_snprintf(cmd, sizeof(cmd),
2048 "P2P_PRESENCE_REQ %s %s %s %s",
2049 argv[0], argv[1], argv[2], argv[3]);
2051 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2054 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2055 if (res < 0 || (size_t) res >= sizeof(cmd))
2057 cmd[sizeof(cmd) - 1] = '\0';
2058 return wpa_ctrl_command(ctrl, cmd);
2062 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2068 if (argc != 0 && argc != 2) {
2069 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2070 "(availability period, availability interval; in "
2072 "Extended Listen Timing can be cancelled with this "
2073 "command when used without parameters.\n");
2078 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2081 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2082 if (res < 0 || (size_t) res >= sizeof(cmd))
2084 cmd[sizeof(cmd) - 1] = '\0';
2085 return wpa_ctrl_command(ctrl, cmd);
2088 #endif /* CONFIG_P2P */
2091 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2098 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2099 "(0/1 = disable/enable automatic reconnection)\n");
2102 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2103 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2104 printf("Too long STA_AUTOCONNECT command.\n");
2107 return wpa_ctrl_command(ctrl, cmd);
2111 enum wpa_cli_cmd_flags {
2112 cli_cmd_flag_none = 0x00,
2113 cli_cmd_flag_sensitive = 0x01
2116 struct wpa_cli_cmd {
2118 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2119 enum wpa_cli_cmd_flags flags;
2123 static struct wpa_cli_cmd wpa_cli_commands[] = {
2124 { "status", wpa_cli_cmd_status,
2126 "[verbose] = get current WPA/EAPOL/EAP status" },
2127 { "ping", wpa_cli_cmd_ping,
2129 "= pings wpa_supplicant" },
2130 { "note", wpa_cli_cmd_note,
2132 "<text> = add a note to wpa_supplicant debug log" },
2133 { "mib", wpa_cli_cmd_mib,
2135 "= get MIB variables (dot1x, dot11)" },
2136 { "help", wpa_cli_cmd_help,
2138 "= show this usage help" },
2139 { "interface", wpa_cli_cmd_interface,
2141 "[ifname] = show interfaces/select interface" },
2142 { "level", wpa_cli_cmd_level,
2144 "<debug level> = change debug level" },
2145 { "license", wpa_cli_cmd_license,
2147 "= show full wpa_cli license" },
2148 { "quit", wpa_cli_cmd_quit,
2151 { "set", wpa_cli_cmd_set,
2153 "= set variables (shows list of variables when run without "
2155 { "logon", wpa_cli_cmd_logon,
2157 "= IEEE 802.1X EAPOL state machine logon" },
2158 { "logoff", wpa_cli_cmd_logoff,
2160 "= IEEE 802.1X EAPOL state machine logoff" },
2161 { "pmksa", wpa_cli_cmd_pmksa,
2163 "= show PMKSA cache" },
2164 { "reassociate", wpa_cli_cmd_reassociate,
2166 "= force reassociation" },
2167 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2169 "<BSSID> = force preauthentication" },
2170 { "identity", wpa_cli_cmd_identity,
2172 "<network id> <identity> = configure identity for an SSID" },
2173 { "password", wpa_cli_cmd_password,
2174 cli_cmd_flag_sensitive,
2175 "<network id> <password> = configure password for an SSID" },
2176 { "new_password", wpa_cli_cmd_new_password,
2177 cli_cmd_flag_sensitive,
2178 "<network id> <password> = change password for an SSID" },
2179 { "pin", wpa_cli_cmd_pin,
2180 cli_cmd_flag_sensitive,
2181 "<network id> <pin> = configure pin for an SSID" },
2182 { "otp", wpa_cli_cmd_otp,
2183 cli_cmd_flag_sensitive,
2184 "<network id> <password> = configure one-time-password for an SSID"
2186 { "passphrase", wpa_cli_cmd_passphrase,
2187 cli_cmd_flag_sensitive,
2188 "<network id> <passphrase> = configure private key passphrase\n"
2190 { "bssid", wpa_cli_cmd_bssid,
2192 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2193 { "list_networks", wpa_cli_cmd_list_networks,
2195 "= list configured networks" },
2196 { "select_network", wpa_cli_cmd_select_network,
2198 "<network id> = select a network (disable others)" },
2199 { "enable_network", wpa_cli_cmd_enable_network,
2201 "<network id> = enable a network" },
2202 { "disable_network", wpa_cli_cmd_disable_network,
2204 "<network id> = disable a network" },
2205 { "add_network", wpa_cli_cmd_add_network,
2207 "= add a network" },
2208 { "remove_network", wpa_cli_cmd_remove_network,
2210 "<network id> = remove a network" },
2211 { "set_network", wpa_cli_cmd_set_network,
2212 cli_cmd_flag_sensitive,
2213 "<network id> <variable> <value> = set network variables (shows\n"
2214 " list of variables when run without arguments)" },
2215 { "get_network", wpa_cli_cmd_get_network,
2217 "<network id> <variable> = get network variables" },
2218 { "save_config", wpa_cli_cmd_save_config,
2220 "= save the current configuration" },
2221 { "disconnect", wpa_cli_cmd_disconnect,
2223 "= disconnect and wait for reassociate/reconnect command before\n"
2225 { "reconnect", wpa_cli_cmd_reconnect,
2227 "= like reassociate, but only takes effect if already disconnected"
2229 { "scan", wpa_cli_cmd_scan,
2231 "= request new BSS scan" },
2232 { "scan_results", wpa_cli_cmd_scan_results,
2234 "= get latest scan results" },
2235 { "bss", wpa_cli_cmd_bss,
2237 "<<idx> | <bssid>> = get detailed scan result info" },
2238 { "get_capability", wpa_cli_cmd_get_capability,
2240 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2241 { "reconfigure", wpa_cli_cmd_reconfigure,
2243 "= force wpa_supplicant to re-read its configuration file" },
2244 { "terminate", wpa_cli_cmd_terminate,
2246 "= terminate wpa_supplicant" },
2247 { "interface_add", wpa_cli_cmd_interface_add,
2249 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2250 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2252 { "interface_remove", wpa_cli_cmd_interface_remove,
2254 "<ifname> = removes the interface" },
2255 { "interface_list", wpa_cli_cmd_interface_list,
2257 "= list available interfaces" },
2258 { "ap_scan", wpa_cli_cmd_ap_scan,
2260 "<value> = set ap_scan parameter" },
2261 { "stkstart", wpa_cli_cmd_stkstart,
2263 "<addr> = request STK negotiation with <addr>" },
2264 { "ft_ds", wpa_cli_cmd_ft_ds,
2266 "<addr> = request over-the-DS FT with <addr>" },
2267 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2269 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2270 { "wps_pin", wpa_cli_cmd_wps_pin,
2271 cli_cmd_flag_sensitive,
2272 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2274 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2275 "Cancels the pending WPS operation" },
2276 #ifdef CONFIG_WPS_OOB
2277 { "wps_oob", wpa_cli_cmd_wps_oob,
2278 cli_cmd_flag_sensitive,
2279 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2280 #endif /* CONFIG_WPS_OOB */
2281 { "wps_reg", wpa_cli_cmd_wps_reg,
2282 cli_cmd_flag_sensitive,
2283 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2284 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2286 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2287 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2289 "= stop Wi-Fi Protected Setup External Registrar" },
2290 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2291 cli_cmd_flag_sensitive,
2292 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2293 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2295 "<UUID> = accept an Enrollee PBC using External Registrar" },
2296 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2297 cli_cmd_flag_sensitive,
2298 "<UUID> <PIN> = learn AP configuration" },
2299 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2300 cli_cmd_flag_sensitive,
2301 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2302 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2304 "<addr> = request RSN authentication with <addr> in IBSS" },
2306 { "sta", wpa_cli_cmd_sta,
2308 "<addr> = get information about an associated station (AP)" },
2309 { "all_sta", wpa_cli_cmd_all_sta,
2311 "= get information about all associated stations (AP)" },
2312 #endif /* CONFIG_AP */
2313 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2314 "= notification of suspend/hibernate" },
2315 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2316 "= notification of resume/thaw" },
2317 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2318 "= drop SA without deauth/disassoc (test command)" },
2319 { "roam", wpa_cli_cmd_roam,
2321 "<addr> = roam to the specified BSS" },
2323 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2324 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2325 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2326 "= stop P2P Devices search" },
2327 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2328 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2329 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2330 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2331 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2332 "<ifname> = remote P2P group interface (terminate group if GO)" },
2333 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2334 "= add a new P2P group (local end as GO)" },
2335 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2336 "<addr> <method> = request provisioning discovery" },
2337 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2339 "= get the passphrase for a group (GO only)" },
2340 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2342 "<addr> <TLVs> = schedule service discovery request" },
2343 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2345 "<id> = cancel pending service discovery request" },
2346 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2348 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2349 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2351 "= indicate change in local services" },
2352 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2354 "<external> = set external processing of service discovery" },
2355 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2357 "= remove all stored service entries" },
2358 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2360 "<bonjour|upnp> <query|version> <response|service> = add a local "
2362 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2364 "<bonjour|upnp> <query|version> [|service] = remove a local "
2366 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2368 "<addr> = reject connection attempts from a specific peer" },
2369 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2371 "<cmd> [peer=addr] = invite peer" },
2372 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2373 "[discovered] = list known (optionally, only fully discovered) P2P "
2375 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2376 "<address> = show information about known P2P peer" },
2377 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2378 "<field> <value> = set a P2P parameter" },
2379 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2380 "= flush P2P state" },
2381 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2382 "[<duration> <interval>] [<duration> <interval>] = request GO "
2384 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2385 "[<period> <interval>] = set extended listen timing" },
2386 #endif /* CONFIG_P2P */
2387 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2388 "<0/1> = disable/enable automatic reconnection" },
2389 { NULL, NULL, cli_cmd_flag_none, NULL }
2394 * Prints command usage, lines are padded with the specified string.
2396 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2401 printf("%s%s ", pad, cmd->cmd);
2402 for (n = 0; (c = cmd->usage[n]); n++) {
2411 static void print_help(void)
2414 printf("commands:\n");
2415 for (n = 0; wpa_cli_commands[n].cmd; n++)
2416 print_cmd_help(&wpa_cli_commands[n], " ");
2420 #ifdef CONFIG_READLINE
2421 static int cmd_has_sensitive_data(const char *cmd)
2423 const char *c, *delim;
2427 delim = os_strchr(cmd, ' ');
2431 len = os_strlen(cmd);
2433 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2434 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2435 return (wpa_cli_commands[n].flags &
2436 cli_cmd_flag_sensitive);
2440 #endif /* CONFIG_READLINE */
2443 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2445 struct wpa_cli_cmd *cmd, *match = NULL;
2450 cmd = wpa_cli_commands;
2452 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2455 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2456 /* we have an exact match */
2466 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2467 cmd = wpa_cli_commands;
2469 if (os_strncasecmp(cmd->cmd, argv[0],
2470 os_strlen(argv[0])) == 0) {
2471 printf(" %s", cmd->cmd);
2477 } else if (count == 0) {
2478 printf("Unknown command '%s'\n", argv[0]);
2481 ret = match->handler(ctrl, argc - 1, &argv[1]);
2488 static int str_match(const char *a, const char *b)
2490 return os_strncmp(a, b, os_strlen(b)) == 0;
2494 static int wpa_cli_exec(const char *program, const char *arg1,
2502 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2503 cmd = os_malloc(len);
2506 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2507 if (res < 0 || (size_t) res >= len) {
2511 cmd[len - 1] = '\0';
2513 if (system(cmd) < 0)
2515 #endif /* _WIN32_WCE */
2522 static void wpa_cli_action_process(const char *msg)
2525 char *copy = NULL, *id, *pos2;
2530 pos = os_strchr(pos, '>');
2537 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2539 os_unsetenv("WPA_ID");
2540 os_unsetenv("WPA_ID_STR");
2541 os_unsetenv("WPA_CTRL_DIR");
2543 pos = os_strstr(pos, "[id=");
2545 copy = os_strdup(pos + 4);
2549 while (*pos2 && *pos2 != ' ')
2553 os_setenv("WPA_ID", id, 1);
2554 while (*pos2 && *pos2 != '=')
2559 while (*pos2 && *pos2 != ']')
2562 os_setenv("WPA_ID_STR", id, 1);
2566 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2568 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2569 wpa_cli_connected = 1;
2570 wpa_cli_last_id = new_id;
2571 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2573 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2574 if (wpa_cli_connected) {
2575 wpa_cli_connected = 0;
2576 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2578 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2579 wpa_cli_exec(action_file, ctrl_ifname, pos);
2580 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2581 wpa_cli_exec(action_file, ctrl_ifname, pos);
2582 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2583 wpa_cli_exec(action_file, ctrl_ifname, pos);
2584 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2585 wpa_cli_exec(action_file, ctrl_ifname, pos);
2586 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2587 wpa_cli_exec(action_file, ctrl_ifname, pos);
2588 } else if (str_match(pos, WPS_EVENT_FAIL)) {
2589 wpa_cli_exec(action_file, ctrl_ifname, pos);
2590 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2591 printf("wpa_supplicant is terminating - stop monitoring\n");
2597 #ifndef CONFIG_ANSI_C_EXTRA
2598 static void wpa_cli_action_cb(char *msg, size_t len)
2600 wpa_cli_action_process(msg);
2602 #endif /* CONFIG_ANSI_C_EXTRA */
2605 static void wpa_cli_reconnect(void)
2607 wpa_cli_close_connection();
2608 wpa_cli_open_connection(ctrl_ifname, 1);
2612 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
2616 if (ctrl_conn == NULL) {
2617 wpa_cli_reconnect();
2620 while (wpa_ctrl_pending(ctrl) > 0) {
2622 size_t len = sizeof(buf) - 1;
2623 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2626 wpa_cli_action_process(buf);
2628 if (wpa_cli_show_event(buf)) {
2629 if (in_read && first)
2632 printf("%s\n", buf);
2637 printf("Could not read pending message.\n");
2642 if (wpa_ctrl_pending(ctrl) < 0) {
2643 printf("Connection to wpa_supplicant lost - trying to "
2645 wpa_cli_reconnect();
2650 #ifdef CONFIG_READLINE
2651 static char * wpa_cli_cmd_gen(const char *text, int state)
2658 len = os_strlen(text);
2661 while ((cmd = wpa_cli_commands[i].cmd)) {
2663 if (os_strncasecmp(cmd, text, len) == 0)
2671 static char * wpa_cli_dummy_gen(const char *text, int state)
2675 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2676 const char *cmd = wpa_cli_commands[i].cmd;
2677 size_t len = os_strlen(cmd);
2678 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
2679 rl_line_buffer[len] == ' ') {
2680 printf("\n%s\n", wpa_cli_commands[i].usage);
2686 rl_attempted_completion_over = 1;
2691 static char * wpa_cli_status_gen(const char *text, int state)
2701 len = os_strlen(text);
2704 while ((t = options[i])) {
2706 if (os_strncasecmp(t, text, len) == 0)
2710 rl_attempted_completion_over = 1;
2715 static char ** wpa_cli_completion(const char *text, int start, int end)
2717 char * (*func)(const char *text, int state);
2720 func = wpa_cli_cmd_gen;
2721 else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
2722 func = wpa_cli_status_gen;
2724 func = wpa_cli_dummy_gen;
2725 return rl_completion_matches(text, func);
2727 #endif /* CONFIG_READLINE */
2730 static void wpa_cli_interactive(void)
2733 char cmdbuf[256], *cmd, *argv[max_args], *pos;
2735 #ifdef CONFIG_READLINE
2736 char *home, *hfile = NULL;
2737 #endif /* CONFIG_READLINE */
2739 printf("\nInteractive mode\n\n");
2741 #ifdef CONFIG_READLINE
2742 rl_attempted_completion_function = wpa_cli_completion;
2743 home = getenv("HOME");
2745 const char *fname = ".wpa_cli_history";
2746 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
2747 hfile = os_malloc(hfile_len);
2750 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
2752 if (res >= 0 && res < hfile_len) {
2753 hfile[hfile_len - 1] = '\0';
2754 read_history(hfile);
2755 stifle_history(100);
2759 #endif /* CONFIG_READLINE */
2762 wpa_cli_recv_pending(mon_conn, 0, 0);
2763 #ifndef CONFIG_NATIVE_WINDOWS
2764 alarm(ping_interval);
2765 #endif /* CONFIG_NATIVE_WINDOWS */
2766 #ifdef CONFIG_WPA_CLI_FORK
2768 kill(mon_pid, SIGUSR1);
2769 #endif /* CONFIG_WPA_CLI_FORK */
2770 #ifdef CONFIG_READLINE
2771 cmd = readline("> ");
2774 while (next_history())
2776 h = previous_history();
2777 if (h == NULL || os_strcmp(cmd, h->line) != 0)
2781 #else /* CONFIG_READLINE */
2783 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
2784 #endif /* CONFIG_READLINE */
2785 #ifndef CONFIG_NATIVE_WINDOWS
2787 #endif /* CONFIG_NATIVE_WINDOWS */
2790 wpa_cli_recv_pending(mon_conn, 0, 0);
2792 while (*pos != '\0') {
2808 if (argc == max_args)
2811 char *pos2 = os_strrchr(pos, '"');
2815 while (*pos != '\0' && *pos != ' ')
2821 wpa_request(ctrl_conn, argc, argv);
2825 #ifdef CONFIG_WPA_CLI_FORK
2827 kill(mon_pid, SIGUSR2);
2828 #endif /* CONFIG_WPA_CLI_FORK */
2829 } while (!wpa_cli_quit);
2831 #ifdef CONFIG_READLINE
2833 /* Save command history, excluding lines that may contain
2837 while ((h = current_history())) {
2839 while (*p == ' ' || *p == '\t')
2841 if (cmd_has_sensitive_data(p)) {
2842 h = remove_history(where_history());
2852 write_history(hfile);
2855 #endif /* CONFIG_READLINE */
2859 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2861 #ifdef CONFIG_ANSI_C_EXTRA
2862 /* TODO: ANSI C version(?) */
2863 printf("Action processing not supported in ANSI C build.\n");
2864 #else /* CONFIG_ANSI_C_EXTRA */
2868 char buf[256]; /* note: large enough to fit in unsolicited messages */
2871 fd = wpa_ctrl_get_fd(ctrl);
2873 while (!wpa_cli_quit) {
2876 tv.tv_sec = ping_interval;
2878 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2879 if (res < 0 && errno != EINTR) {
2884 if (FD_ISSET(fd, &rfds))
2885 wpa_cli_recv_pending(ctrl, 0, 1);
2887 /* verify that connection is still working */
2888 len = sizeof(buf) - 1;
2889 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2890 wpa_cli_action_cb) < 0 ||
2891 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2892 printf("wpa_supplicant did not reply to PING "
2893 "command - exiting\n");
2898 #endif /* CONFIG_ANSI_C_EXTRA */
2902 static void wpa_cli_cleanup(void)
2904 wpa_cli_close_connection();
2906 os_daemonize_terminate(pid_file);
2908 os_program_deinit();
2911 static void wpa_cli_terminate(int sig)
2918 #ifdef CONFIG_WPA_CLI_FORK
2919 static void wpa_cli_usr1(int sig)
2923 #endif /* CONFIG_WPA_CLI_FORK */
2926 #ifndef CONFIG_NATIVE_WINDOWS
2927 static void wpa_cli_alarm(int sig)
2929 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2930 printf("Connection to wpa_supplicant lost - trying to "
2932 wpa_cli_close_connection();
2935 wpa_cli_reconnect();
2937 wpa_cli_recv_pending(mon_conn, 1, 0);
2938 alarm(ping_interval);
2940 #endif /* CONFIG_NATIVE_WINDOWS */
2943 static char * wpa_cli_get_default_ifname(void)
2945 char *ifname = NULL;
2947 #ifdef CONFIG_CTRL_IFACE_UNIX
2948 struct dirent *dent;
2949 DIR *dir = opendir(ctrl_iface_dir);
2952 while ((dent = readdir(dir))) {
2953 #ifdef _DIRENT_HAVE_D_TYPE
2955 * Skip the file if it is not a socket. Also accept
2956 * DT_UNKNOWN (0) in case the C library or underlying
2957 * file system does not support d_type.
2959 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2961 #endif /* _DIRENT_HAVE_D_TYPE */
2962 if (os_strcmp(dent->d_name, ".") == 0 ||
2963 os_strcmp(dent->d_name, "..") == 0)
2965 printf("Selected interface '%s'\n", dent->d_name);
2966 ifname = os_strdup(dent->d_name);
2970 #endif /* CONFIG_CTRL_IFACE_UNIX */
2972 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2973 char buf[2048], *pos;
2975 struct wpa_ctrl *ctrl;
2978 ctrl = wpa_ctrl_open(NULL);
2982 len = sizeof(buf) - 1;
2983 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2986 pos = os_strchr(buf, '\n');
2989 ifname = os_strdup(buf);
2991 wpa_ctrl_close(ctrl);
2992 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2998 int main(int argc, char *argv[])
3000 int warning_displayed = 0;
3004 const char *global = NULL;
3006 if (os_program_init())
3010 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3015 action_file = optarg;
3024 ping_interval = atoi(optarg);
3030 printf("%s\n", wpa_cli_version);
3033 os_free(ctrl_ifname);
3034 ctrl_ifname = os_strdup(optarg);
3037 ctrl_iface_dir = optarg;
3048 interactive = (argc == optind) && (action_file == NULL);
3051 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3054 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3055 ctrl_conn = wpa_ctrl_open(NULL);
3056 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3057 ctrl_conn = wpa_ctrl_open(global);
3058 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3059 if (ctrl_conn == NULL) {
3060 perror("Failed to connect to wpa_supplicant - "
3067 signal(SIGINT, wpa_cli_terminate);
3068 signal(SIGTERM, wpa_cli_terminate);
3069 #endif /* _WIN32_WCE */
3070 #ifndef CONFIG_NATIVE_WINDOWS
3071 signal(SIGALRM, wpa_cli_alarm);
3072 #endif /* CONFIG_NATIVE_WINDOWS */
3073 #ifdef CONFIG_WPA_CLI_FORK
3074 signal(SIGUSR1, wpa_cli_usr1);
3075 #endif /* CONFIG_WPA_CLI_FORK */
3077 if (ctrl_ifname == NULL)
3078 ctrl_ifname = wpa_cli_get_default_ifname();
3082 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3083 if (warning_displayed)
3084 printf("Connection established.\n");
3088 if (!warning_displayed) {
3089 printf("Could not connect to wpa_supplicant - "
3091 warning_displayed = 1;
3098 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3099 perror("Failed to connect to wpa_supplicant - "
3105 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3106 wpa_cli_attached = 1;
3108 printf("Warning: Failed to attach to "
3109 "wpa_supplicant.\n");
3115 if (daemonize && os_daemonize(pid_file))
3119 wpa_cli_interactive();
3120 else if (action_file)
3121 wpa_cli_action(ctrl_conn);
3123 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3125 os_free(ctrl_ifname);
3131 #else /* CONFIG_CTRL_IFACE */
3132 int main(int argc, char *argv[])
3134 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3137 #endif /* CONFIG_CTRL_IFACE */