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, WPA_EVENT_TERMINATING)) {
2556 printf("wpa_supplicant is terminating - stop monitoring\n");
2562 #ifndef CONFIG_ANSI_C_EXTRA
2563 static void wpa_cli_action_cb(char *msg, size_t len)
2565 wpa_cli_action_process(msg);
2567 #endif /* CONFIG_ANSI_C_EXTRA */
2570 static void wpa_cli_reconnect(void)
2572 wpa_cli_close_connection();
2573 wpa_cli_open_connection(ctrl_ifname, 1);
2577 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
2581 if (ctrl_conn == NULL) {
2582 wpa_cli_reconnect();
2585 while (wpa_ctrl_pending(ctrl) > 0) {
2587 size_t len = sizeof(buf) - 1;
2588 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2591 wpa_cli_action_process(buf);
2593 if (wpa_cli_show_event(buf)) {
2594 if (in_read && first)
2597 printf("%s\n", buf);
2602 printf("Could not read pending message.\n");
2607 if (wpa_ctrl_pending(ctrl) < 0) {
2608 printf("Connection to wpa_supplicant lost - trying to "
2610 wpa_cli_reconnect();
2615 #ifdef CONFIG_READLINE
2616 static char * wpa_cli_cmd_gen(const char *text, int state)
2623 len = os_strlen(text);
2626 while ((cmd = wpa_cli_commands[i].cmd)) {
2628 if (os_strncasecmp(cmd, text, len) == 0)
2636 static char * wpa_cli_dummy_gen(const char *text, int state)
2640 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2641 const char *cmd = wpa_cli_commands[i].cmd;
2642 size_t len = os_strlen(cmd);
2643 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
2644 rl_line_buffer[len] == ' ') {
2645 printf("\n%s\n", wpa_cli_commands[i].usage);
2651 rl_attempted_completion_over = 1;
2656 static char * wpa_cli_status_gen(const char *text, int state)
2666 len = os_strlen(text);
2669 while ((t = options[i])) {
2671 if (os_strncasecmp(t, text, len) == 0)
2675 rl_attempted_completion_over = 1;
2680 static char ** wpa_cli_completion(const char *text, int start, int end)
2682 char * (*func)(const char *text, int state);
2685 func = wpa_cli_cmd_gen;
2686 else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
2687 func = wpa_cli_status_gen;
2689 func = wpa_cli_dummy_gen;
2690 return rl_completion_matches(text, func);
2692 #endif /* CONFIG_READLINE */
2695 static void wpa_cli_interactive(void)
2698 char cmdbuf[256], *cmd, *argv[max_args], *pos;
2700 #ifdef CONFIG_READLINE
2701 char *home, *hfile = NULL;
2702 #endif /* CONFIG_READLINE */
2704 printf("\nInteractive mode\n\n");
2706 #ifdef CONFIG_READLINE
2707 rl_attempted_completion_function = wpa_cli_completion;
2708 home = getenv("HOME");
2710 const char *fname = ".wpa_cli_history";
2711 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
2712 hfile = os_malloc(hfile_len);
2715 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
2717 if (res >= 0 && res < hfile_len) {
2718 hfile[hfile_len - 1] = '\0';
2719 read_history(hfile);
2720 stifle_history(100);
2724 #endif /* CONFIG_READLINE */
2727 wpa_cli_recv_pending(mon_conn, 0, 0);
2728 #ifndef CONFIG_NATIVE_WINDOWS
2729 alarm(ping_interval);
2730 #endif /* CONFIG_NATIVE_WINDOWS */
2731 #ifdef CONFIG_WPA_CLI_FORK
2733 kill(mon_pid, SIGUSR1);
2734 #endif /* CONFIG_WPA_CLI_FORK */
2735 #ifdef CONFIG_READLINE
2736 cmd = readline("> ");
2739 while (next_history())
2741 h = previous_history();
2742 if (h == NULL || os_strcmp(cmd, h->line) != 0)
2746 #else /* CONFIG_READLINE */
2748 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
2749 #endif /* CONFIG_READLINE */
2750 #ifndef CONFIG_NATIVE_WINDOWS
2752 #endif /* CONFIG_NATIVE_WINDOWS */
2755 wpa_cli_recv_pending(mon_conn, 0, 0);
2757 while (*pos != '\0') {
2773 if (argc == max_args)
2776 char *pos2 = os_strrchr(pos, '"');
2780 while (*pos != '\0' && *pos != ' ')
2786 wpa_request(ctrl_conn, argc, argv);
2790 #ifdef CONFIG_WPA_CLI_FORK
2792 kill(mon_pid, SIGUSR2);
2793 #endif /* CONFIG_WPA_CLI_FORK */
2794 } while (!wpa_cli_quit);
2796 #ifdef CONFIG_READLINE
2798 /* Save command history, excluding lines that may contain
2802 while ((h = current_history())) {
2804 while (*p == ' ' || *p == '\t')
2806 if (cmd_has_sensitive_data(p)) {
2807 h = remove_history(where_history());
2817 write_history(hfile);
2820 #endif /* CONFIG_READLINE */
2824 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2826 #ifdef CONFIG_ANSI_C_EXTRA
2827 /* TODO: ANSI C version(?) */
2828 printf("Action processing not supported in ANSI C build.\n");
2829 #else /* CONFIG_ANSI_C_EXTRA */
2833 char buf[256]; /* note: large enough to fit in unsolicited messages */
2836 fd = wpa_ctrl_get_fd(ctrl);
2838 while (!wpa_cli_quit) {
2841 tv.tv_sec = ping_interval;
2843 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2844 if (res < 0 && errno != EINTR) {
2849 if (FD_ISSET(fd, &rfds))
2850 wpa_cli_recv_pending(ctrl, 0, 1);
2852 /* verify that connection is still working */
2853 len = sizeof(buf) - 1;
2854 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2855 wpa_cli_action_cb) < 0 ||
2856 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2857 printf("wpa_supplicant did not reply to PING "
2858 "command - exiting\n");
2863 #endif /* CONFIG_ANSI_C_EXTRA */
2867 static void wpa_cli_cleanup(void)
2869 wpa_cli_close_connection();
2871 os_daemonize_terminate(pid_file);
2873 os_program_deinit();
2876 static void wpa_cli_terminate(int sig)
2883 #ifdef CONFIG_WPA_CLI_FORK
2884 static void wpa_cli_usr1(int sig)
2888 #endif /* CONFIG_WPA_CLI_FORK */
2891 #ifndef CONFIG_NATIVE_WINDOWS
2892 static void wpa_cli_alarm(int sig)
2894 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2895 printf("Connection to wpa_supplicant lost - trying to "
2897 wpa_cli_close_connection();
2900 wpa_cli_reconnect();
2902 wpa_cli_recv_pending(mon_conn, 1, 0);
2903 alarm(ping_interval);
2905 #endif /* CONFIG_NATIVE_WINDOWS */
2908 static char * wpa_cli_get_default_ifname(void)
2910 char *ifname = NULL;
2912 #ifdef CONFIG_CTRL_IFACE_UNIX
2913 struct dirent *dent;
2914 DIR *dir = opendir(ctrl_iface_dir);
2917 while ((dent = readdir(dir))) {
2918 #ifdef _DIRENT_HAVE_D_TYPE
2920 * Skip the file if it is not a socket. Also accept
2921 * DT_UNKNOWN (0) in case the C library or underlying
2922 * file system does not support d_type.
2924 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2926 #endif /* _DIRENT_HAVE_D_TYPE */
2927 if (os_strcmp(dent->d_name, ".") == 0 ||
2928 os_strcmp(dent->d_name, "..") == 0)
2930 printf("Selected interface '%s'\n", dent->d_name);
2931 ifname = os_strdup(dent->d_name);
2935 #endif /* CONFIG_CTRL_IFACE_UNIX */
2937 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2938 char buf[2048], *pos;
2940 struct wpa_ctrl *ctrl;
2943 ctrl = wpa_ctrl_open(NULL);
2947 len = sizeof(buf) - 1;
2948 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2951 pos = os_strchr(buf, '\n');
2954 ifname = os_strdup(buf);
2956 wpa_ctrl_close(ctrl);
2957 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2963 int main(int argc, char *argv[])
2965 int warning_displayed = 0;
2969 const char *global = NULL;
2971 if (os_program_init())
2975 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2980 action_file = optarg;
2989 ping_interval = atoi(optarg);
2995 printf("%s\n", wpa_cli_version);
2998 os_free(ctrl_ifname);
2999 ctrl_ifname = os_strdup(optarg);
3002 ctrl_iface_dir = optarg;
3013 interactive = (argc == optind) && (action_file == NULL);
3016 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3019 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3020 ctrl_conn = wpa_ctrl_open(NULL);
3021 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3022 ctrl_conn = wpa_ctrl_open(global);
3023 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3024 if (ctrl_conn == NULL) {
3025 perror("Failed to connect to wpa_supplicant - "
3032 signal(SIGINT, wpa_cli_terminate);
3033 signal(SIGTERM, wpa_cli_terminate);
3034 #endif /* _WIN32_WCE */
3035 #ifndef CONFIG_NATIVE_WINDOWS
3036 signal(SIGALRM, wpa_cli_alarm);
3037 #endif /* CONFIG_NATIVE_WINDOWS */
3038 #ifdef CONFIG_WPA_CLI_FORK
3039 signal(SIGUSR1, wpa_cli_usr1);
3040 #endif /* CONFIG_WPA_CLI_FORK */
3042 if (ctrl_ifname == NULL)
3043 ctrl_ifname = wpa_cli_get_default_ifname();
3047 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3048 if (warning_displayed)
3049 printf("Connection established.\n");
3053 if (!warning_displayed) {
3054 printf("Could not connect to wpa_supplicant - "
3056 warning_displayed = 1;
3063 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3064 perror("Failed to connect to wpa_supplicant - "
3070 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3071 wpa_cli_attached = 1;
3073 printf("Warning: Failed to attach to "
3074 "wpa_supplicant.\n");
3080 if (daemonize && os_daemonize(pid_file))
3084 wpa_cli_interactive();
3085 else if (action_file)
3086 wpa_cli_action(ctrl_conn);
3088 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3090 os_free(ctrl_ifname);
3096 #else /* CONFIG_CTRL_IFACE */
3097 int main(int argc, char *argv[])
3099 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3102 #endif /* CONFIG_CTRL_IFACE */