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 #ifdef CONFIG_WPS_OOB
619 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
624 if (argc != 3 && argc != 4) {
625 printf("Invalid WPS_OOB command: need three or four "
627 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
628 "- PATH: path of OOB device like '/mnt'\n"
629 "- METHOD: OOB method 'pin-e' or 'pin-r', "
631 "- DEV_NAME: (only for NFC) device name like "
637 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
638 argv[0], argv[1], argv[2]);
640 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
641 argv[0], argv[1], argv[2], argv[3]);
642 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
643 printf("Too long WPS_OOB command.\n");
646 return wpa_ctrl_command(ctrl, cmd);
648 #endif /* CONFIG_WPS_OOB */
651 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
657 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
659 else if (argc == 5 || argc == 6) {
660 char ssid_hex[2 * 32 + 1];
661 char key_hex[2 * 64 + 1];
665 for (i = 0; i < 32; i++) {
666 if (argv[2][i] == '\0')
668 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
673 for (i = 0; i < 64; i++) {
674 if (argv[5][i] == '\0')
676 os_snprintf(&key_hex[i * 2], 3, "%02x",
681 res = os_snprintf(cmd, sizeof(cmd),
682 "WPS_REG %s %s %s %s %s %s",
683 argv[0], argv[1], ssid_hex, argv[3], argv[4],
686 printf("Invalid WPS_REG command: need two arguments:\n"
687 "- BSSID: use 'any' to select any\n"
689 printf("Alternatively, six arguments can be used to "
690 "reconfigure the AP:\n"
691 "- BSSID: use 'any' to select any\n"
694 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
695 "- new encr (NONE, WEP, TKIP, CCMP)\n"
700 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
701 printf("Too long WPS_REG command.\n");
704 return wpa_ctrl_command(ctrl, cmd);
708 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
713 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
714 return wpa_ctrl_command(ctrl, cmd);
716 return wpa_ctrl_command(ctrl, "WPS_ER_START");
720 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
723 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
728 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
735 printf("Invalid WPS_ER_PIN command: need at least two "
737 "- UUID: use 'any' to select any\n"
738 "- PIN: Enrollee PIN\n"
739 "optional: - Enrollee MAC address\n");
744 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
745 argv[0], argv[1], argv[2]);
747 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
749 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
750 printf("Too long WPS_ER_PIN command.\n");
753 return wpa_ctrl_command(ctrl, cmd);
757 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
764 printf("Invalid WPS_ER_PBC command: need one argument:\n"
765 "- UUID: Specify the Enrollee\n");
769 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
771 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
772 printf("Too long WPS_ER_PBC command.\n");
775 return wpa_ctrl_command(ctrl, cmd);
779 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
786 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
787 "- UUID: specify which AP to use\n"
792 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
794 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
795 printf("Too long WPS_ER_LEARN command.\n");
798 return wpa_ctrl_command(ctrl, cmd);
802 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
808 if (argc == 5 || argc == 6) {
809 char ssid_hex[2 * 32 + 1];
810 char key_hex[2 * 64 + 1];
814 for (i = 0; i < 32; i++) {
815 if (argv[2][i] == '\0')
817 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
822 for (i = 0; i < 64; i++) {
823 if (argv[5][i] == '\0')
825 os_snprintf(&key_hex[i * 2], 3, "%02x",
830 res = os_snprintf(cmd, sizeof(cmd),
831 "WPS_ER_CONFIG %s %s %s %s %s %s",
832 argv[0], argv[1], ssid_hex, argv[3], argv[4],
835 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
839 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
840 "- new encr (NONE, WEP, TKIP, CCMP)\n"
845 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
846 printf("Too long WPS_ER_CONFIG command.\n");
849 return wpa_ctrl_command(ctrl, cmd);
853 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
859 printf("Invalid IBSS_RSN command: needs one argument "
860 "(Peer STA MAC address)\n");
864 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
865 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
866 printf("Too long IBSS_RSN command.\n");
869 return wpa_ctrl_command(ctrl, cmd);
873 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
879 printf("Invalid LEVEL command: needs one argument (debug "
883 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
884 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
885 printf("Too long LEVEL command.\n");
888 return wpa_ctrl_command(ctrl, cmd);
892 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
894 char cmd[256], *pos, *end;
898 printf("Invalid IDENTITY command: needs two arguments "
899 "(network id and identity)\n");
903 end = cmd + sizeof(cmd);
905 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
907 if (ret < 0 || ret >= end - pos) {
908 printf("Too long IDENTITY command.\n");
912 for (i = 2; i < argc; i++) {
913 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
914 if (ret < 0 || ret >= end - pos) {
915 printf("Too long IDENTITY command.\n");
921 return wpa_ctrl_command(ctrl, cmd);
925 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
927 char cmd[256], *pos, *end;
931 printf("Invalid PASSWORD command: needs two arguments "
932 "(network id and password)\n");
936 end = cmd + sizeof(cmd);
938 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
940 if (ret < 0 || ret >= end - pos) {
941 printf("Too long PASSWORD command.\n");
945 for (i = 2; i < argc; i++) {
946 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
947 if (ret < 0 || ret >= end - pos) {
948 printf("Too long PASSWORD command.\n");
954 return wpa_ctrl_command(ctrl, cmd);
958 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
961 char cmd[256], *pos, *end;
965 printf("Invalid NEW_PASSWORD command: needs two arguments "
966 "(network id and password)\n");
970 end = cmd + sizeof(cmd);
972 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
974 if (ret < 0 || ret >= end - pos) {
975 printf("Too long NEW_PASSWORD command.\n");
979 for (i = 2; i < argc; i++) {
980 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
981 if (ret < 0 || ret >= end - pos) {
982 printf("Too long NEW_PASSWORD command.\n");
988 return wpa_ctrl_command(ctrl, cmd);
992 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
994 char cmd[256], *pos, *end;
998 printf("Invalid PIN command: needs two arguments "
999 "(network id and pin)\n");
1003 end = cmd + sizeof(cmd);
1005 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1007 if (ret < 0 || ret >= end - pos) {
1008 printf("Too long PIN command.\n");
1012 for (i = 2; i < argc; i++) {
1013 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1014 if (ret < 0 || ret >= end - pos) {
1015 printf("Too long PIN command.\n");
1020 return wpa_ctrl_command(ctrl, cmd);
1024 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1026 char cmd[256], *pos, *end;
1030 printf("Invalid OTP command: needs two arguments (network "
1031 "id and password)\n");
1035 end = cmd + sizeof(cmd);
1037 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1039 if (ret < 0 || ret >= end - pos) {
1040 printf("Too long OTP command.\n");
1044 for (i = 2; i < argc; i++) {
1045 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1046 if (ret < 0 || ret >= end - pos) {
1047 printf("Too long OTP command.\n");
1053 return wpa_ctrl_command(ctrl, cmd);
1057 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1060 char cmd[256], *pos, *end;
1064 printf("Invalid PASSPHRASE command: needs two arguments "
1065 "(network id and passphrase)\n");
1069 end = cmd + sizeof(cmd);
1071 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1073 if (ret < 0 || ret >= end - pos) {
1074 printf("Too long PASSPHRASE command.\n");
1078 for (i = 2; i < argc; i++) {
1079 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1080 if (ret < 0 || ret >= end - pos) {
1081 printf("Too long PASSPHRASE command.\n");
1087 return wpa_ctrl_command(ctrl, cmd);
1091 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1093 char cmd[256], *pos, *end;
1097 printf("Invalid BSSID command: needs two arguments (network "
1102 end = cmd + sizeof(cmd);
1104 ret = os_snprintf(pos, end - pos, "BSSID");
1105 if (ret < 0 || ret >= end - pos) {
1106 printf("Too long BSSID command.\n");
1110 for (i = 0; i < argc; i++) {
1111 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1112 if (ret < 0 || ret >= end - pos) {
1113 printf("Too long BSSID command.\n");
1119 return wpa_ctrl_command(ctrl, cmd);
1123 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1126 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1130 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1137 printf("Invalid SELECT_NETWORK command: needs one argument "
1142 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1143 if (res < 0 || (size_t) res >= sizeof(cmd))
1145 cmd[sizeof(cmd) - 1] = '\0';
1147 return wpa_ctrl_command(ctrl, cmd);
1151 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1158 printf("Invalid ENABLE_NETWORK command: needs one argument "
1163 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1164 if (res < 0 || (size_t) res >= sizeof(cmd))
1166 cmd[sizeof(cmd) - 1] = '\0';
1168 return wpa_ctrl_command(ctrl, cmd);
1172 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1179 printf("Invalid DISABLE_NETWORK command: needs one argument "
1184 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1185 if (res < 0 || (size_t) res >= sizeof(cmd))
1187 cmd[sizeof(cmd) - 1] = '\0';
1189 return wpa_ctrl_command(ctrl, cmd);
1193 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1196 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1200 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1207 printf("Invalid REMOVE_NETWORK command: needs one argument "
1212 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1213 if (res < 0 || (size_t) res >= sizeof(cmd))
1215 cmd[sizeof(cmd) - 1] = '\0';
1217 return wpa_ctrl_command(ctrl, cmd);
1221 static void wpa_cli_show_network_variables(void)
1223 printf("set_network variables:\n"
1224 " ssid (network name, SSID)\n"
1225 " psk (WPA passphrase or pre-shared key)\n"
1226 " key_mgmt (key management protocol)\n"
1227 " identity (EAP identity)\n"
1228 " password (EAP password)\n"
1231 "Note: Values are entered in the same format as the "
1232 "configuration file is using,\n"
1233 "i.e., strings values need to be inside double quotation "
1235 "For example: set_network 1 ssid \"network name\"\n"
1237 "Please see wpa_supplicant.conf documentation for full list "
1238 "of\navailable variables.\n");
1242 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1249 wpa_cli_show_network_variables();
1254 printf("Invalid SET_NETWORK command: needs three arguments\n"
1255 "(network id, variable name, and value)\n");
1259 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1260 argv[0], argv[1], argv[2]);
1261 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1262 printf("Too long SET_NETWORK command.\n");
1265 return wpa_ctrl_command(ctrl, cmd);
1269 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1276 wpa_cli_show_network_variables();
1281 printf("Invalid GET_NETWORK command: needs two arguments\n"
1282 "(network id and variable name)\n");
1286 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1288 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1289 printf("Too long GET_NETWORK command.\n");
1292 return wpa_ctrl_command(ctrl, cmd);
1296 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1299 return wpa_ctrl_command(ctrl, "DISCONNECT");
1303 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1306 return wpa_ctrl_command(ctrl, "RECONNECT");
1310 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1313 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1317 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1319 return wpa_ctrl_command(ctrl, "SCAN");
1323 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1326 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1330 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1336 printf("Invalid BSS command: need one argument (index or "
1341 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1342 if (res < 0 || (size_t) res >= sizeof(cmd))
1344 cmd[sizeof(cmd) - 1] = '\0';
1346 return wpa_ctrl_command(ctrl, cmd);
1350 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1356 if (argc < 1 || argc > 2) {
1357 printf("Invalid GET_CAPABILITY command: need either one or "
1362 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1363 printf("Invalid GET_CAPABILITY command: second argument, "
1364 "if any, must be 'strict'\n");
1368 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1369 (argc == 2) ? " strict" : "");
1370 if (res < 0 || (size_t) res >= sizeof(cmd))
1372 cmd[sizeof(cmd) - 1] = '\0';
1374 return wpa_ctrl_command(ctrl, cmd);
1378 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1380 printf("Available interfaces:\n");
1381 return wpa_ctrl_command(ctrl, "INTERFACES");
1385 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1388 wpa_cli_list_interfaces(ctrl);
1392 wpa_cli_close_connection();
1393 os_free(ctrl_ifname);
1394 ctrl_ifname = os_strdup(argv[0]);
1396 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1397 printf("Connected to interface '%s.\n", ctrl_ifname);
1399 printf("Could not connect to interface '%s' - re-trying\n",
1406 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1409 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1413 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1416 return wpa_ctrl_command(ctrl, "TERMINATE");
1420 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1427 printf("Invalid INTERFACE_ADD command: needs at least one "
1428 "argument (interface name)\n"
1429 "All arguments: ifname confname driver ctrl_interface "
1430 "driver_param bridge_name\n");
1435 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1436 * <driver_param>TAB<bridge_name>
1438 res = os_snprintf(cmd, sizeof(cmd),
1439 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1441 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1442 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1443 argc > 5 ? argv[5] : "");
1444 if (res < 0 || (size_t) res >= sizeof(cmd))
1446 cmd[sizeof(cmd) - 1] = '\0';
1447 return wpa_ctrl_command(ctrl, cmd);
1451 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1458 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1459 "(interface name)\n");
1463 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1464 if (res < 0 || (size_t) res >= sizeof(cmd))
1466 cmd[sizeof(cmd) - 1] = '\0';
1467 return wpa_ctrl_command(ctrl, cmd);
1471 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1474 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1479 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1483 printf("Invalid 'sta' command - exactly one argument, STA "
1484 "address, is required.\n");
1487 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1488 return wpa_ctrl_command(ctrl, buf);
1492 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1493 char *addr, size_t addr_len)
1495 char buf[4096], *pos;
1499 if (ctrl_conn == NULL) {
1500 printf("Not connected to hostapd - command dropped.\n");
1503 len = sizeof(buf) - 1;
1504 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1507 printf("'%s' command timed out.\n", cmd);
1509 } else if (ret < 0) {
1510 printf("'%s' command failed.\n", cmd);
1515 if (memcmp(buf, "FAIL", 4) == 0)
1520 while (*pos != '\0' && *pos != '\n')
1523 os_strlcpy(addr, buf, addr_len);
1528 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1530 char addr[32], cmd[64];
1532 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1535 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1536 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1540 #endif /* CONFIG_AP */
1543 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1545 return wpa_ctrl_command(ctrl, "SUSPEND");
1549 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1551 return wpa_ctrl_command(ctrl, "RESUME");
1555 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1557 return wpa_ctrl_command(ctrl, "DROP_SA");
1561 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1567 printf("Invalid ROAM command: needs one argument "
1568 "(target AP's BSSID)\n");
1572 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1573 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1574 printf("Too long ROAM command.\n");
1577 return wpa_ctrl_command(ctrl, cmd);
1583 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1589 return wpa_ctrl_command(ctrl, "P2P_FIND");
1592 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1595 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1596 if (res < 0 || (size_t) res >= sizeof(cmd))
1598 cmd[sizeof(cmd) - 1] = '\0';
1599 return wpa_ctrl_command(ctrl, cmd);
1603 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1606 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1610 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1617 printf("Invalid P2P_CONNECT command: needs at least two "
1618 "arguments (address and pbc/PIN)\n");
1623 res = os_snprintf(cmd, sizeof(cmd),
1624 "P2P_CONNECT %s %s %s %s %s",
1625 argv[0], argv[1], argv[2], argv[3],
1628 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1629 argv[0], argv[1], argv[2], argv[3]);
1631 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1632 argv[0], argv[1], argv[2]);
1634 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1636 if (res < 0 || (size_t) res >= sizeof(cmd))
1638 cmd[sizeof(cmd) - 1] = '\0';
1639 return wpa_ctrl_command(ctrl, cmd);
1643 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1650 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1652 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1653 if (res < 0 || (size_t) res >= sizeof(cmd))
1655 cmd[sizeof(cmd) - 1] = '\0';
1656 return wpa_ctrl_command(ctrl, cmd);
1660 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1667 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1668 "(interface name)\n");
1672 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
1673 if (res < 0 || (size_t) res >= sizeof(cmd))
1675 cmd[sizeof(cmd) - 1] = '\0';
1676 return wpa_ctrl_command(ctrl, cmd);
1680 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1687 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
1689 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", argv[0]);
1690 if (res < 0 || (size_t) res >= sizeof(cmd))
1692 cmd[sizeof(cmd) - 1] = '\0';
1693 return wpa_ctrl_command(ctrl, cmd);
1697 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1704 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1705 "(address and config method\n"
1706 "(display, keypad, or pbc)\n");
1710 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
1712 if (res < 0 || (size_t) res >= sizeof(cmd))
1714 cmd[sizeof(cmd) - 1] = '\0';
1715 return wpa_ctrl_command(ctrl, cmd);
1719 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1722 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1726 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1732 if (argc != 2 && argc != 4) {
1733 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1734 "arguments (address and TLVs) or four arguments "
1735 "(address, \"upnp\", version, search target "
1741 res = os_snprintf(cmd, sizeof(cmd),
1742 "P2P_SERV_DISC_REQ %s %s %s %s",
1743 argv[0], argv[1], argv[2], argv[3]);
1745 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
1747 if (res < 0 || (size_t) res >= sizeof(cmd))
1749 cmd[sizeof(cmd) - 1] = '\0';
1750 return wpa_ctrl_command(ctrl, cmd);
1754 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1755 int argc, char *argv[])
1761 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1762 "argument (pending request identifier)\n");
1766 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
1768 if (res < 0 || (size_t) res >= sizeof(cmd))
1770 cmd[sizeof(cmd) - 1] = '\0';
1771 return wpa_ctrl_command(ctrl, cmd);
1775 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1782 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1783 "arguments (freq, address, dialog token, and TLVs)\n");
1787 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1788 argv[0], argv[1], argv[2], argv[3]);
1789 if (res < 0 || (size_t) res >= sizeof(cmd))
1791 cmd[sizeof(cmd) - 1] = '\0';
1792 return wpa_ctrl_command(ctrl, cmd);
1796 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1799 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1803 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1804 int argc, char *argv[])
1810 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1811 "argument (external processing: 0/1)\n");
1815 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
1817 if (res < 0 || (size_t) res >= sizeof(cmd))
1819 cmd[sizeof(cmd) - 1] = '\0';
1820 return wpa_ctrl_command(ctrl, cmd);
1824 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1827 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1831 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1837 if (argc != 3 && argc != 4) {
1838 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1844 res = os_snprintf(cmd, sizeof(cmd),
1845 "P2P_SERVICE_ADD %s %s %s %s",
1846 argv[0], argv[1], argv[2], argv[3]);
1848 res = os_snprintf(cmd, sizeof(cmd),
1849 "P2P_SERVICE_ADD %s %s %s",
1850 argv[0], argv[1], argv[2]);
1851 if (res < 0 || (size_t) res >= sizeof(cmd))
1853 cmd[sizeof(cmd) - 1] = '\0';
1854 return wpa_ctrl_command(ctrl, cmd);
1858 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1864 if (argc != 2 && argc != 3) {
1865 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1871 res = os_snprintf(cmd, sizeof(cmd),
1872 "P2P_SERVICE_DEL %s %s %s",
1873 argv[0], argv[1], argv[2]);
1875 res = os_snprintf(cmd, sizeof(cmd),
1876 "P2P_SERVICE_DEL %s %s",
1878 if (res < 0 || (size_t) res >= sizeof(cmd))
1880 cmd[sizeof(cmd) - 1] = '\0';
1881 return wpa_ctrl_command(ctrl, cmd);
1885 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1886 int argc, char *argv[])
1892 printf("Invalid P2P_REJECT command: needs one argument "
1893 "(peer address)\n");
1897 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
1898 if (res < 0 || (size_t) res >= sizeof(cmd))
1900 cmd[sizeof(cmd) - 1] = '\0';
1901 return wpa_ctrl_command(ctrl, cmd);
1905 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1906 int argc, char *argv[])
1912 printf("Invalid P2P_INVITE command: needs at least one "
1918 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
1919 argv[0], argv[1], argv[2]);
1921 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
1924 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
1925 if (res < 0 || (size_t) res >= sizeof(cmd))
1927 cmd[sizeof(cmd) - 1] = '\0';
1928 return wpa_ctrl_command(ctrl, cmd);
1932 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
1936 printf("Invalid 'p2p_peer' command - exactly one argument, "
1937 "P2P peer device address, is required.\n");
1940 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
1941 return wpa_ctrl_command(ctrl, buf);
1945 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
1946 char *addr, size_t addr_len,
1949 char buf[4096], *pos;
1953 if (ctrl_conn == NULL)
1955 len = sizeof(buf) - 1;
1956 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1959 printf("'%s' command timed out.\n", cmd);
1961 } else if (ret < 0) {
1962 printf("'%s' command failed.\n", cmd);
1967 if (memcmp(buf, "FAIL", 4) == 0)
1971 while (*pos != '\0' && *pos != '\n')
1974 os_strlcpy(addr, buf, addr_len);
1975 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
1976 printf("%s\n", addr);
1981 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
1983 char addr[32], cmd[64];
1986 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
1988 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
1989 addr, sizeof(addr), discovered))
1992 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
1993 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2000 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2006 printf("Invalid P2P_SET command: needs two arguments (field, "
2011 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2012 if (res < 0 || (size_t) res >= sizeof(cmd))
2014 cmd[sizeof(cmd) - 1] = '\0';
2015 return wpa_ctrl_command(ctrl, cmd);
2019 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2021 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2025 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2031 if (argc != 0 && argc != 2 && argc != 4) {
2032 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2033 "(preferred duration, interval; in microsecods).\n"
2034 "Optional second pair can be used to provide "
2035 "acceptable values.\n");
2040 res = os_snprintf(cmd, sizeof(cmd),
2041 "P2P_PRESENCE_REQ %s %s %s %s",
2042 argv[0], argv[1], argv[2], argv[3]);
2044 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2047 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2048 if (res < 0 || (size_t) res >= sizeof(cmd))
2050 cmd[sizeof(cmd) - 1] = '\0';
2051 return wpa_ctrl_command(ctrl, cmd);
2055 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2061 if (argc != 0 && argc != 2) {
2062 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2063 "(availability period, availability interval; in "
2065 "Extended Listen Timing can be cancelled with this "
2066 "command when used without parameters.\n");
2071 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2074 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2075 if (res < 0 || (size_t) res >= sizeof(cmd))
2077 cmd[sizeof(cmd) - 1] = '\0';
2078 return wpa_ctrl_command(ctrl, cmd);
2081 #endif /* CONFIG_P2P */
2084 enum wpa_cli_cmd_flags {
2085 cli_cmd_flag_none = 0x00,
2086 cli_cmd_flag_sensitive = 0x01
2089 struct wpa_cli_cmd {
2091 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2092 enum wpa_cli_cmd_flags flags;
2096 static struct wpa_cli_cmd wpa_cli_commands[] = {
2097 { "status", wpa_cli_cmd_status,
2099 "[verbose] = get current WPA/EAPOL/EAP status" },
2100 { "ping", wpa_cli_cmd_ping,
2102 "= pings wpa_supplicant" },
2103 { "note", wpa_cli_cmd_note,
2105 "<text> = add a note to wpa_supplicant debug log" },
2106 { "mib", wpa_cli_cmd_mib,
2108 "= get MIB variables (dot1x, dot11)" },
2109 { "help", wpa_cli_cmd_help,
2111 "= show this usage help" },
2112 { "interface", wpa_cli_cmd_interface,
2114 "[ifname] = show interfaces/select interface" },
2115 { "level", wpa_cli_cmd_level,
2117 "<debug level> = change debug level" },
2118 { "license", wpa_cli_cmd_license,
2120 "= show full wpa_cli license" },
2121 { "quit", wpa_cli_cmd_quit,
2124 { "set", wpa_cli_cmd_set,
2126 "= set variables (shows list of variables when run without "
2128 { "logon", wpa_cli_cmd_logon,
2130 "= IEEE 802.1X EAPOL state machine logon" },
2131 { "logoff", wpa_cli_cmd_logoff,
2133 "= IEEE 802.1X EAPOL state machine logoff" },
2134 { "pmksa", wpa_cli_cmd_pmksa,
2136 "= show PMKSA cache" },
2137 { "reassociate", wpa_cli_cmd_reassociate,
2139 "= force reassociation" },
2140 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2142 "<BSSID> = force preauthentication" },
2143 { "identity", wpa_cli_cmd_identity,
2145 "<network id> <identity> = configure identity for an SSID" },
2146 { "password", wpa_cli_cmd_password,
2147 cli_cmd_flag_sensitive,
2148 "<network id> <password> = configure password for an SSID" },
2149 { "new_password", wpa_cli_cmd_new_password,
2150 cli_cmd_flag_sensitive,
2151 "<network id> <password> = change password for an SSID" },
2152 { "pin", wpa_cli_cmd_pin,
2153 cli_cmd_flag_sensitive,
2154 "<network id> <pin> = configure pin for an SSID" },
2155 { "otp", wpa_cli_cmd_otp,
2156 cli_cmd_flag_sensitive,
2157 "<network id> <password> = configure one-time-password for an SSID"
2159 { "passphrase", wpa_cli_cmd_passphrase,
2160 cli_cmd_flag_sensitive,
2161 "<network id> <passphrase> = configure private key passphrase\n"
2163 { "bssid", wpa_cli_cmd_bssid,
2165 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2166 { "list_networks", wpa_cli_cmd_list_networks,
2168 "= list configured networks" },
2169 { "select_network", wpa_cli_cmd_select_network,
2171 "<network id> = select a network (disable others)" },
2172 { "enable_network", wpa_cli_cmd_enable_network,
2174 "<network id> = enable a network" },
2175 { "disable_network", wpa_cli_cmd_disable_network,
2177 "<network id> = disable a network" },
2178 { "add_network", wpa_cli_cmd_add_network,
2180 "= add a network" },
2181 { "remove_network", wpa_cli_cmd_remove_network,
2183 "<network id> = remove a network" },
2184 { "set_network", wpa_cli_cmd_set_network,
2185 cli_cmd_flag_sensitive,
2186 "<network id> <variable> <value> = set network variables (shows\n"
2187 " list of variables when run without arguments)" },
2188 { "get_network", wpa_cli_cmd_get_network,
2190 "<network id> <variable> = get network variables" },
2191 { "save_config", wpa_cli_cmd_save_config,
2193 "= save the current configuration" },
2194 { "disconnect", wpa_cli_cmd_disconnect,
2196 "= disconnect and wait for reassociate/reconnect command before\n"
2198 { "reconnect", wpa_cli_cmd_reconnect,
2200 "= like reassociate, but only takes effect if already disconnected"
2202 { "scan", wpa_cli_cmd_scan,
2204 "= request new BSS scan" },
2205 { "scan_results", wpa_cli_cmd_scan_results,
2207 "= get latest scan results" },
2208 { "bss", wpa_cli_cmd_bss,
2210 "<<idx> | <bssid>> = get detailed scan result info" },
2211 { "get_capability", wpa_cli_cmd_get_capability,
2213 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2214 { "reconfigure", wpa_cli_cmd_reconfigure,
2216 "= force wpa_supplicant to re-read its configuration file" },
2217 { "terminate", wpa_cli_cmd_terminate,
2219 "= terminate wpa_supplicant" },
2220 { "interface_add", wpa_cli_cmd_interface_add,
2222 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2223 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2225 { "interface_remove", wpa_cli_cmd_interface_remove,
2227 "<ifname> = removes the interface" },
2228 { "interface_list", wpa_cli_cmd_interface_list,
2230 "= list available interfaces" },
2231 { "ap_scan", wpa_cli_cmd_ap_scan,
2233 "<value> = set ap_scan parameter" },
2234 { "stkstart", wpa_cli_cmd_stkstart,
2236 "<addr> = request STK negotiation with <addr>" },
2237 { "ft_ds", wpa_cli_cmd_ft_ds,
2239 "<addr> = request over-the-DS FT with <addr>" },
2240 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2242 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2243 { "wps_pin", wpa_cli_cmd_wps_pin,
2244 cli_cmd_flag_sensitive,
2245 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2247 #ifdef CONFIG_WPS_OOB
2248 { "wps_oob", wpa_cli_cmd_wps_oob,
2249 cli_cmd_flag_sensitive,
2250 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2251 #endif /* CONFIG_WPS_OOB */
2252 { "wps_reg", wpa_cli_cmd_wps_reg,
2253 cli_cmd_flag_sensitive,
2254 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2255 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2257 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2258 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2260 "= stop Wi-Fi Protected Setup External Registrar" },
2261 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2262 cli_cmd_flag_sensitive,
2263 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2264 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2266 "<UUID> = accept an Enrollee PBC using External Registrar" },
2267 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2268 cli_cmd_flag_sensitive,
2269 "<UUID> <PIN> = learn AP configuration" },
2270 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2271 cli_cmd_flag_sensitive,
2272 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2273 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2275 "<addr> = request RSN authentication with <addr> in IBSS" },
2277 { "sta", wpa_cli_cmd_sta,
2279 "<addr> = get information about an associated station (AP)" },
2280 { "all_sta", wpa_cli_cmd_all_sta,
2282 "= get information about all associated stations (AP)" },
2283 #endif /* CONFIG_AP */
2284 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2285 "= notification of suspend/hibernate" },
2286 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2287 "= notification of resume/thaw" },
2288 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2289 "= drop SA without deauth/disassoc (test command)" },
2290 { "roam", wpa_cli_cmd_roam,
2292 "<addr> = roam to the specified BSS" },
2294 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2295 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2296 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2297 "= stop P2P Devices search" },
2298 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2299 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2300 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2301 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2302 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2303 "<ifname> = remote P2P group interface (terminate group if GO)" },
2304 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2305 "= add a new P2P group (local end as GO)" },
2306 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2307 "<addr> <method> = request provisioning discovery" },
2308 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2310 "= get the passphrase for a group (GO only)" },
2311 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2313 "<addr> <TLVs> = schedule service discovery request" },
2314 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2316 "<id> = cancel pending service discovery request" },
2317 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2319 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2320 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2322 "= indicate change in local services" },
2323 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2325 "<external> = set external processing of service discovery" },
2326 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2328 "= remove all stored service entries" },
2329 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2331 "<bonjour|upnp> <query|version> <response|service> = add a local "
2333 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2335 "<bonjour|upnp> <query|version> [|service] = remove a local "
2337 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2339 "<addr> = reject connection attempts from a specific peer" },
2340 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2342 "<cmd> [peer=addr] = invite peer" },
2343 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2344 "[discovered] = list known (optionally, only fully discovered) P2P "
2346 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2347 "<address> = show information about known P2P peer" },
2348 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2349 "<field> <value> = set a P2P parameter" },
2350 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2351 "= flush P2P state" },
2352 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2353 "[<duration> <interval>] [<duration> <interval>] = request GO "
2355 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2356 "[<period> <interval>] = set extended listen timing" },
2357 #endif /* CONFIG_P2P */
2358 { NULL, NULL, cli_cmd_flag_none, NULL }
2363 * Prints command usage, lines are padded with the specified string.
2365 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2370 printf("%s%s ", pad, cmd->cmd);
2371 for (n = 0; (c = cmd->usage[n]); n++) {
2380 static void print_help(void)
2383 printf("commands:\n");
2384 for (n = 0; wpa_cli_commands[n].cmd; n++)
2385 print_cmd_help(&wpa_cli_commands[n], " ");
2389 #ifdef CONFIG_READLINE
2390 static int cmd_has_sensitive_data(const char *cmd)
2392 const char *c, *delim;
2396 delim = os_strchr(cmd, ' ');
2400 len = os_strlen(cmd);
2402 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2403 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2404 return (wpa_cli_commands[n].flags &
2405 cli_cmd_flag_sensitive);
2409 #endif /* CONFIG_READLINE */
2412 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2414 struct wpa_cli_cmd *cmd, *match = NULL;
2419 cmd = wpa_cli_commands;
2421 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2424 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2425 /* we have an exact match */
2435 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2436 cmd = wpa_cli_commands;
2438 if (os_strncasecmp(cmd->cmd, argv[0],
2439 os_strlen(argv[0])) == 0) {
2440 printf(" %s", cmd->cmd);
2446 } else if (count == 0) {
2447 printf("Unknown command '%s'\n", argv[0]);
2450 ret = match->handler(ctrl, argc - 1, &argv[1]);
2457 static int str_match(const char *a, const char *b)
2459 return os_strncmp(a, b, os_strlen(b)) == 0;
2463 static int wpa_cli_exec(const char *program, const char *arg1,
2471 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2472 cmd = os_malloc(len);
2475 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2476 if (res < 0 || (size_t) res >= len) {
2480 cmd[len - 1] = '\0';
2482 if (system(cmd) < 0)
2484 #endif /* _WIN32_WCE */
2491 static void wpa_cli_action_process(const char *msg)
2494 char *copy = NULL, *id, *pos2;
2499 pos = os_strchr(pos, '>');
2506 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2508 os_unsetenv("WPA_ID");
2509 os_unsetenv("WPA_ID_STR");
2510 os_unsetenv("WPA_CTRL_DIR");
2512 pos = os_strstr(pos, "[id=");
2514 copy = os_strdup(pos + 4);
2518 while (*pos2 && *pos2 != ' ')
2522 os_setenv("WPA_ID", id, 1);
2523 while (*pos2 && *pos2 != '=')
2528 while (*pos2 && *pos2 != ']')
2531 os_setenv("WPA_ID_STR", id, 1);
2535 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2537 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2538 wpa_cli_connected = 1;
2539 wpa_cli_last_id = new_id;
2540 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2542 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2543 if (wpa_cli_connected) {
2544 wpa_cli_connected = 0;
2545 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2547 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2548 wpa_cli_exec(action_file, ctrl_ifname, pos);
2549 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2550 wpa_cli_exec(action_file, ctrl_ifname, pos);
2551 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2552 wpa_cli_exec(action_file, ctrl_ifname, pos);
2553 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2554 wpa_cli_exec(action_file, ctrl_ifname, pos);
2555 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2556 wpa_cli_exec(action_file, ctrl_ifname, pos);
2557 } else if (str_match(pos, WPS_EVENT_FAIL)) {
2558 wpa_cli_exec(action_file, ctrl_ifname, pos);
2559 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2560 printf("wpa_supplicant is terminating - stop monitoring\n");
2566 #ifndef CONFIG_ANSI_C_EXTRA
2567 static void wpa_cli_action_cb(char *msg, size_t len)
2569 wpa_cli_action_process(msg);
2571 #endif /* CONFIG_ANSI_C_EXTRA */
2574 static void wpa_cli_reconnect(void)
2576 wpa_cli_close_connection();
2577 wpa_cli_open_connection(ctrl_ifname, 1);
2581 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
2585 if (ctrl_conn == NULL) {
2586 wpa_cli_reconnect();
2589 while (wpa_ctrl_pending(ctrl) > 0) {
2591 size_t len = sizeof(buf) - 1;
2592 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2595 wpa_cli_action_process(buf);
2597 if (wpa_cli_show_event(buf)) {
2598 if (in_read && first)
2601 printf("%s\n", buf);
2606 printf("Could not read pending message.\n");
2611 if (wpa_ctrl_pending(ctrl) < 0) {
2612 printf("Connection to wpa_supplicant lost - trying to "
2614 wpa_cli_reconnect();
2619 #ifdef CONFIG_READLINE
2620 static char * wpa_cli_cmd_gen(const char *text, int state)
2627 len = os_strlen(text);
2630 while ((cmd = wpa_cli_commands[i].cmd)) {
2632 if (os_strncasecmp(cmd, text, len) == 0)
2640 static char * wpa_cli_dummy_gen(const char *text, int state)
2644 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2645 const char *cmd = wpa_cli_commands[i].cmd;
2646 size_t len = os_strlen(cmd);
2647 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
2648 rl_line_buffer[len] == ' ') {
2649 printf("\n%s\n", wpa_cli_commands[i].usage);
2655 rl_attempted_completion_over = 1;
2660 static char * wpa_cli_status_gen(const char *text, int state)
2670 len = os_strlen(text);
2673 while ((t = options[i])) {
2675 if (os_strncasecmp(t, text, len) == 0)
2679 rl_attempted_completion_over = 1;
2684 static char ** wpa_cli_completion(const char *text, int start, int end)
2686 char * (*func)(const char *text, int state);
2689 func = wpa_cli_cmd_gen;
2690 else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
2691 func = wpa_cli_status_gen;
2693 func = wpa_cli_dummy_gen;
2694 return rl_completion_matches(text, func);
2696 #endif /* CONFIG_READLINE */
2699 static void wpa_cli_interactive(void)
2702 char cmdbuf[256], *cmd, *argv[max_args], *pos;
2704 #ifdef CONFIG_READLINE
2705 char *home, *hfile = NULL;
2706 #endif /* CONFIG_READLINE */
2708 printf("\nInteractive mode\n\n");
2710 #ifdef CONFIG_READLINE
2711 rl_attempted_completion_function = wpa_cli_completion;
2712 home = getenv("HOME");
2714 const char *fname = ".wpa_cli_history";
2715 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
2716 hfile = os_malloc(hfile_len);
2719 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
2721 if (res >= 0 && res < hfile_len) {
2722 hfile[hfile_len - 1] = '\0';
2723 read_history(hfile);
2724 stifle_history(100);
2728 #endif /* CONFIG_READLINE */
2731 wpa_cli_recv_pending(mon_conn, 0, 0);
2732 #ifndef CONFIG_NATIVE_WINDOWS
2733 alarm(ping_interval);
2734 #endif /* CONFIG_NATIVE_WINDOWS */
2735 #ifdef CONFIG_WPA_CLI_FORK
2737 kill(mon_pid, SIGUSR1);
2738 #endif /* CONFIG_WPA_CLI_FORK */
2739 #ifdef CONFIG_READLINE
2740 cmd = readline("> ");
2743 while (next_history())
2745 h = previous_history();
2746 if (h == NULL || os_strcmp(cmd, h->line) != 0)
2750 #else /* CONFIG_READLINE */
2752 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
2753 #endif /* CONFIG_READLINE */
2754 #ifndef CONFIG_NATIVE_WINDOWS
2756 #endif /* CONFIG_NATIVE_WINDOWS */
2759 wpa_cli_recv_pending(mon_conn, 0, 0);
2761 while (*pos != '\0') {
2777 if (argc == max_args)
2780 char *pos2 = os_strrchr(pos, '"');
2784 while (*pos != '\0' && *pos != ' ')
2790 wpa_request(ctrl_conn, argc, argv);
2794 #ifdef CONFIG_WPA_CLI_FORK
2796 kill(mon_pid, SIGUSR2);
2797 #endif /* CONFIG_WPA_CLI_FORK */
2798 } while (!wpa_cli_quit);
2800 #ifdef CONFIG_READLINE
2802 /* Save command history, excluding lines that may contain
2806 while ((h = current_history())) {
2808 while (*p == ' ' || *p == '\t')
2810 if (cmd_has_sensitive_data(p)) {
2811 h = remove_history(where_history());
2821 write_history(hfile);
2824 #endif /* CONFIG_READLINE */
2828 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2830 #ifdef CONFIG_ANSI_C_EXTRA
2831 /* TODO: ANSI C version(?) */
2832 printf("Action processing not supported in ANSI C build.\n");
2833 #else /* CONFIG_ANSI_C_EXTRA */
2837 char buf[256]; /* note: large enough to fit in unsolicited messages */
2840 fd = wpa_ctrl_get_fd(ctrl);
2842 while (!wpa_cli_quit) {
2845 tv.tv_sec = ping_interval;
2847 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2848 if (res < 0 && errno != EINTR) {
2853 if (FD_ISSET(fd, &rfds))
2854 wpa_cli_recv_pending(ctrl, 0, 1);
2856 /* verify that connection is still working */
2857 len = sizeof(buf) - 1;
2858 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2859 wpa_cli_action_cb) < 0 ||
2860 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2861 printf("wpa_supplicant did not reply to PING "
2862 "command - exiting\n");
2867 #endif /* CONFIG_ANSI_C_EXTRA */
2871 static void wpa_cli_cleanup(void)
2873 wpa_cli_close_connection();
2875 os_daemonize_terminate(pid_file);
2877 os_program_deinit();
2880 static void wpa_cli_terminate(int sig)
2887 #ifdef CONFIG_WPA_CLI_FORK
2888 static void wpa_cli_usr1(int sig)
2892 #endif /* CONFIG_WPA_CLI_FORK */
2895 #ifndef CONFIG_NATIVE_WINDOWS
2896 static void wpa_cli_alarm(int sig)
2898 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2899 printf("Connection to wpa_supplicant lost - trying to "
2901 wpa_cli_close_connection();
2904 wpa_cli_reconnect();
2906 wpa_cli_recv_pending(mon_conn, 1, 0);
2907 alarm(ping_interval);
2909 #endif /* CONFIG_NATIVE_WINDOWS */
2912 static char * wpa_cli_get_default_ifname(void)
2914 char *ifname = NULL;
2916 #ifdef CONFIG_CTRL_IFACE_UNIX
2917 struct dirent *dent;
2918 DIR *dir = opendir(ctrl_iface_dir);
2921 while ((dent = readdir(dir))) {
2922 #ifdef _DIRENT_HAVE_D_TYPE
2924 * Skip the file if it is not a socket. Also accept
2925 * DT_UNKNOWN (0) in case the C library or underlying
2926 * file system does not support d_type.
2928 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2930 #endif /* _DIRENT_HAVE_D_TYPE */
2931 if (os_strcmp(dent->d_name, ".") == 0 ||
2932 os_strcmp(dent->d_name, "..") == 0)
2934 printf("Selected interface '%s'\n", dent->d_name);
2935 ifname = os_strdup(dent->d_name);
2939 #endif /* CONFIG_CTRL_IFACE_UNIX */
2941 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2942 char buf[2048], *pos;
2944 struct wpa_ctrl *ctrl;
2947 ctrl = wpa_ctrl_open(NULL);
2951 len = sizeof(buf) - 1;
2952 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2955 pos = os_strchr(buf, '\n');
2958 ifname = os_strdup(buf);
2960 wpa_ctrl_close(ctrl);
2961 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2967 int main(int argc, char *argv[])
2969 int warning_displayed = 0;
2973 const char *global = NULL;
2975 if (os_program_init())
2979 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2984 action_file = optarg;
2993 ping_interval = atoi(optarg);
2999 printf("%s\n", wpa_cli_version);
3002 os_free(ctrl_ifname);
3003 ctrl_ifname = os_strdup(optarg);
3006 ctrl_iface_dir = optarg;
3017 interactive = (argc == optind) && (action_file == NULL);
3020 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3023 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3024 ctrl_conn = wpa_ctrl_open(NULL);
3025 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3026 ctrl_conn = wpa_ctrl_open(global);
3027 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3028 if (ctrl_conn == NULL) {
3029 perror("Failed to connect to wpa_supplicant - "
3036 signal(SIGINT, wpa_cli_terminate);
3037 signal(SIGTERM, wpa_cli_terminate);
3038 #endif /* _WIN32_WCE */
3039 #ifndef CONFIG_NATIVE_WINDOWS
3040 signal(SIGALRM, wpa_cli_alarm);
3041 #endif /* CONFIG_NATIVE_WINDOWS */
3042 #ifdef CONFIG_WPA_CLI_FORK
3043 signal(SIGUSR1, wpa_cli_usr1);
3044 #endif /* CONFIG_WPA_CLI_FORK */
3046 if (ctrl_ifname == NULL)
3047 ctrl_ifname = wpa_cli_get_default_ifname();
3051 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3052 if (warning_displayed)
3053 printf("Connection established.\n");
3057 if (!warning_displayed) {
3058 printf("Could not connect to wpa_supplicant - "
3060 warning_displayed = 1;
3067 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3068 perror("Failed to connect to wpa_supplicant - "
3074 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3075 wpa_cli_attached = 1;
3077 printf("Warning: Failed to attach to "
3078 "wpa_supplicant.\n");
3084 if (daemonize && os_daemonize(pid_file))
3088 wpa_cli_interactive();
3089 else if (action_file)
3090 wpa_cli_action(ctrl_conn);
3092 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3094 os_free(ctrl_ifname);
3100 #else /* CONFIG_CTRL_IFACE */
3101 int main(int argc, char *argv[])
3103 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3106 #endif /* CONFIG_CTRL_IFACE */