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);
1581 enum wpa_cli_cmd_flags {
1582 cli_cmd_flag_none = 0x00,
1583 cli_cmd_flag_sensitive = 0x01
1586 struct wpa_cli_cmd {
1588 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1589 enum wpa_cli_cmd_flags flags;
1593 static struct wpa_cli_cmd wpa_cli_commands[] = {
1594 { "status", wpa_cli_cmd_status,
1596 "[verbose] = get current WPA/EAPOL/EAP status" },
1597 { "ping", wpa_cli_cmd_ping,
1599 "= pings wpa_supplicant" },
1600 { "note", wpa_cli_cmd_note,
1602 "<text> = add a note to wpa_supplicant debug log" },
1603 { "mib", wpa_cli_cmd_mib,
1605 "= get MIB variables (dot1x, dot11)" },
1606 { "help", wpa_cli_cmd_help,
1608 "= show this usage help" },
1609 { "interface", wpa_cli_cmd_interface,
1611 "[ifname] = show interfaces/select interface" },
1612 { "level", wpa_cli_cmd_level,
1614 "<debug level> = change debug level" },
1615 { "license", wpa_cli_cmd_license,
1617 "= show full wpa_cli license" },
1618 { "quit", wpa_cli_cmd_quit,
1621 { "set", wpa_cli_cmd_set,
1623 "= set variables (shows list of variables when run without "
1625 { "logon", wpa_cli_cmd_logon,
1627 "= IEEE 802.1X EAPOL state machine logon" },
1628 { "logoff", wpa_cli_cmd_logoff,
1630 "= IEEE 802.1X EAPOL state machine logoff" },
1631 { "pmksa", wpa_cli_cmd_pmksa,
1633 "= show PMKSA cache" },
1634 { "reassociate", wpa_cli_cmd_reassociate,
1636 "= force reassociation" },
1637 { "preauthenticate", wpa_cli_cmd_preauthenticate,
1639 "<BSSID> = force preauthentication" },
1640 { "identity", wpa_cli_cmd_identity,
1642 "<network id> <identity> = configure identity for an SSID" },
1643 { "password", wpa_cli_cmd_password,
1644 cli_cmd_flag_sensitive,
1645 "<network id> <password> = configure password for an SSID" },
1646 { "new_password", wpa_cli_cmd_new_password,
1647 cli_cmd_flag_sensitive,
1648 "<network id> <password> = change password for an SSID" },
1649 { "pin", wpa_cli_cmd_pin,
1650 cli_cmd_flag_sensitive,
1651 "<network id> <pin> = configure pin for an SSID" },
1652 { "otp", wpa_cli_cmd_otp,
1653 cli_cmd_flag_sensitive,
1654 "<network id> <password> = configure one-time-password for an SSID"
1656 { "passphrase", wpa_cli_cmd_passphrase,
1657 cli_cmd_flag_sensitive,
1658 "<network id> <passphrase> = configure private key passphrase\n"
1660 { "bssid", wpa_cli_cmd_bssid,
1662 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1663 { "list_networks", wpa_cli_cmd_list_networks,
1665 "= list configured networks" },
1666 { "select_network", wpa_cli_cmd_select_network,
1668 "<network id> = select a network (disable others)" },
1669 { "enable_network", wpa_cli_cmd_enable_network,
1671 "<network id> = enable a network" },
1672 { "disable_network", wpa_cli_cmd_disable_network,
1674 "<network id> = disable a network" },
1675 { "add_network", wpa_cli_cmd_add_network,
1677 "= add a network" },
1678 { "remove_network", wpa_cli_cmd_remove_network,
1680 "<network id> = remove a network" },
1681 { "set_network", wpa_cli_cmd_set_network,
1682 cli_cmd_flag_sensitive,
1683 "<network id> <variable> <value> = set network variables (shows\n"
1684 " list of variables when run without arguments)" },
1685 { "get_network", wpa_cli_cmd_get_network,
1687 "<network id> <variable> = get network variables" },
1688 { "save_config", wpa_cli_cmd_save_config,
1690 "= save the current configuration" },
1691 { "disconnect", wpa_cli_cmd_disconnect,
1693 "= disconnect and wait for reassociate/reconnect command before\n"
1695 { "reconnect", wpa_cli_cmd_reconnect,
1697 "= like reassociate, but only takes effect if already disconnected"
1699 { "scan", wpa_cli_cmd_scan,
1701 "= request new BSS scan" },
1702 { "scan_results", wpa_cli_cmd_scan_results,
1704 "= get latest scan results" },
1705 { "bss", wpa_cli_cmd_bss,
1707 "<<idx> | <bssid>> = get detailed scan result info" },
1708 { "get_capability", wpa_cli_cmd_get_capability,
1710 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1711 { "reconfigure", wpa_cli_cmd_reconfigure,
1713 "= force wpa_supplicant to re-read its configuration file" },
1714 { "terminate", wpa_cli_cmd_terminate,
1716 "= terminate wpa_supplicant" },
1717 { "interface_add", wpa_cli_cmd_interface_add,
1719 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1720 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1722 { "interface_remove", wpa_cli_cmd_interface_remove,
1724 "<ifname> = removes the interface" },
1725 { "interface_list", wpa_cli_cmd_interface_list,
1727 "= list available interfaces" },
1728 { "ap_scan", wpa_cli_cmd_ap_scan,
1730 "<value> = set ap_scan parameter" },
1731 { "stkstart", wpa_cli_cmd_stkstart,
1733 "<addr> = request STK negotiation with <addr>" },
1734 { "ft_ds", wpa_cli_cmd_ft_ds,
1736 "<addr> = request over-the-DS FT with <addr>" },
1737 { "wps_pbc", wpa_cli_cmd_wps_pbc,
1739 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1740 { "wps_pin", wpa_cli_cmd_wps_pin,
1741 cli_cmd_flag_sensitive,
1742 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1744 #ifdef CONFIG_WPS_OOB
1745 { "wps_oob", wpa_cli_cmd_wps_oob,
1746 cli_cmd_flag_sensitive,
1747 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1748 #endif /* CONFIG_WPS_OOB */
1749 { "wps_reg", wpa_cli_cmd_wps_reg,
1750 cli_cmd_flag_sensitive,
1751 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1752 { "wps_er_start", wpa_cli_cmd_wps_er_start,
1754 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
1755 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1757 "= stop Wi-Fi Protected Setup External Registrar" },
1758 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
1759 cli_cmd_flag_sensitive,
1760 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1761 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
1763 "<UUID> = accept an Enrollee PBC using External Registrar" },
1764 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
1765 cli_cmd_flag_sensitive,
1766 "<UUID> <PIN> = learn AP configuration" },
1767 { "wps_er_config", wpa_cli_cmd_wps_er_config,
1768 cli_cmd_flag_sensitive,
1769 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
1770 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1772 "<addr> = request RSN authentication with <addr> in IBSS" },
1774 { "sta", wpa_cli_cmd_sta,
1776 "<addr> = get information about an associated station (AP)" },
1777 { "all_sta", wpa_cli_cmd_all_sta,
1779 "= get information about all associated stations (AP)" },
1780 #endif /* CONFIG_AP */
1781 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
1782 "= notification of suspend/hibernate" },
1783 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
1784 "= notification of resume/thaw" },
1785 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
1786 "= drop SA without deauth/disassoc (test command)" },
1787 { "roam", wpa_cli_cmd_roam,
1789 "<addr> = roam to the specified BSS" },
1790 { NULL, NULL, cli_cmd_flag_none, NULL }
1795 * Prints command usage, lines are padded with the specified string.
1797 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1802 printf("%s%s ", pad, cmd->cmd);
1803 for (n = 0; (c = cmd->usage[n]); n++) {
1812 static void print_help(void)
1815 printf("commands:\n");
1816 for (n = 0; wpa_cli_commands[n].cmd; n++)
1817 print_cmd_help(&wpa_cli_commands[n], " ");
1821 #ifdef CONFIG_READLINE
1822 static int cmd_has_sensitive_data(const char *cmd)
1824 const char *c, *delim;
1828 delim = os_strchr(cmd, ' ');
1832 len = os_strlen(cmd);
1834 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1835 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1836 return (wpa_cli_commands[n].flags &
1837 cli_cmd_flag_sensitive);
1841 #endif /* CONFIG_READLINE */
1844 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1846 struct wpa_cli_cmd *cmd, *match = NULL;
1851 cmd = wpa_cli_commands;
1853 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1856 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1857 /* we have an exact match */
1867 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1868 cmd = wpa_cli_commands;
1870 if (os_strncasecmp(cmd->cmd, argv[0],
1871 os_strlen(argv[0])) == 0) {
1872 printf(" %s", cmd->cmd);
1878 } else if (count == 0) {
1879 printf("Unknown command '%s'\n", argv[0]);
1882 ret = match->handler(ctrl, argc - 1, &argv[1]);
1889 static int str_match(const char *a, const char *b)
1891 return os_strncmp(a, b, os_strlen(b)) == 0;
1895 static int wpa_cli_exec(const char *program, const char *arg1,
1903 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1904 cmd = os_malloc(len);
1907 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1908 if (res < 0 || (size_t) res >= len) {
1912 cmd[len - 1] = '\0';
1914 if (system(cmd) < 0)
1916 #endif /* _WIN32_WCE */
1923 static void wpa_cli_action_process(const char *msg)
1926 char *copy = NULL, *id, *pos2;
1931 pos = os_strchr(pos, '>');
1938 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1940 os_unsetenv("WPA_ID");
1941 os_unsetenv("WPA_ID_STR");
1942 os_unsetenv("WPA_CTRL_DIR");
1944 pos = os_strstr(pos, "[id=");
1946 copy = os_strdup(pos + 4);
1950 while (*pos2 && *pos2 != ' ')
1954 os_setenv("WPA_ID", id, 1);
1955 while (*pos2 && *pos2 != '=')
1960 while (*pos2 && *pos2 != ']')
1963 os_setenv("WPA_ID_STR", id, 1);
1967 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1969 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1970 wpa_cli_connected = 1;
1971 wpa_cli_last_id = new_id;
1972 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1974 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1975 if (wpa_cli_connected) {
1976 wpa_cli_connected = 0;
1977 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1979 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1980 printf("wpa_supplicant is terminating - stop monitoring\n");
1986 #ifndef CONFIG_ANSI_C_EXTRA
1987 static void wpa_cli_action_cb(char *msg, size_t len)
1989 wpa_cli_action_process(msg);
1991 #endif /* CONFIG_ANSI_C_EXTRA */
1994 static void wpa_cli_reconnect(void)
1996 wpa_cli_close_connection();
1997 wpa_cli_open_connection(ctrl_ifname, 1);
2001 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
2005 if (ctrl_conn == NULL) {
2006 wpa_cli_reconnect();
2009 while (wpa_ctrl_pending(ctrl) > 0) {
2011 size_t len = sizeof(buf) - 1;
2012 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2015 wpa_cli_action_process(buf);
2017 if (wpa_cli_show_event(buf)) {
2018 if (in_read && first)
2021 printf("%s\n", buf);
2026 printf("Could not read pending message.\n");
2031 if (wpa_ctrl_pending(ctrl) < 0) {
2032 printf("Connection to wpa_supplicant lost - trying to "
2034 wpa_cli_reconnect();
2039 #ifdef CONFIG_READLINE
2040 static char * wpa_cli_cmd_gen(const char *text, int state)
2047 len = os_strlen(text);
2050 while ((cmd = wpa_cli_commands[i].cmd)) {
2052 if (os_strncasecmp(cmd, text, len) == 0)
2060 static char * wpa_cli_dummy_gen(const char *text, int state)
2064 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2065 const char *cmd = wpa_cli_commands[i].cmd;
2066 size_t len = os_strlen(cmd);
2067 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
2068 rl_line_buffer[len] == ' ') {
2069 printf("\n%s\n", wpa_cli_commands[i].usage);
2075 rl_attempted_completion_over = 1;
2080 static char * wpa_cli_status_gen(const char *text, int state)
2090 len = os_strlen(text);
2093 while ((t = options[i])) {
2095 if (os_strncasecmp(t, text, len) == 0)
2099 rl_attempted_completion_over = 1;
2104 static char ** wpa_cli_completion(const char *text, int start, int end)
2106 char * (*func)(const char *text, int state);
2109 func = wpa_cli_cmd_gen;
2110 else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
2111 func = wpa_cli_status_gen;
2113 func = wpa_cli_dummy_gen;
2114 return rl_completion_matches(text, func);
2116 #endif /* CONFIG_READLINE */
2119 static void wpa_cli_interactive(void)
2122 char cmdbuf[256], *cmd, *argv[max_args], *pos;
2124 #ifdef CONFIG_READLINE
2125 char *home, *hfile = NULL;
2126 #endif /* CONFIG_READLINE */
2128 printf("\nInteractive mode\n\n");
2130 #ifdef CONFIG_READLINE
2131 rl_attempted_completion_function = wpa_cli_completion;
2132 home = getenv("HOME");
2134 const char *fname = ".wpa_cli_history";
2135 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
2136 hfile = os_malloc(hfile_len);
2139 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
2141 if (res >= 0 && res < hfile_len) {
2142 hfile[hfile_len - 1] = '\0';
2143 read_history(hfile);
2144 stifle_history(100);
2148 #endif /* CONFIG_READLINE */
2151 wpa_cli_recv_pending(mon_conn, 0, 0);
2152 #ifndef CONFIG_NATIVE_WINDOWS
2153 alarm(ping_interval);
2154 #endif /* CONFIG_NATIVE_WINDOWS */
2155 #ifdef CONFIG_WPA_CLI_FORK
2157 kill(mon_pid, SIGUSR1);
2158 #endif /* CONFIG_WPA_CLI_FORK */
2159 #ifdef CONFIG_READLINE
2160 cmd = readline("> ");
2163 while (next_history())
2165 h = previous_history();
2166 if (h == NULL || os_strcmp(cmd, h->line) != 0)
2170 #else /* CONFIG_READLINE */
2172 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
2173 #endif /* CONFIG_READLINE */
2174 #ifndef CONFIG_NATIVE_WINDOWS
2176 #endif /* CONFIG_NATIVE_WINDOWS */
2179 wpa_cli_recv_pending(mon_conn, 0, 0);
2181 while (*pos != '\0') {
2197 if (argc == max_args)
2200 char *pos2 = os_strrchr(pos, '"');
2204 while (*pos != '\0' && *pos != ' ')
2210 wpa_request(ctrl_conn, argc, argv);
2214 #ifdef CONFIG_WPA_CLI_FORK
2216 kill(mon_pid, SIGUSR2);
2217 #endif /* CONFIG_WPA_CLI_FORK */
2218 } while (!wpa_cli_quit);
2220 #ifdef CONFIG_READLINE
2222 /* Save command history, excluding lines that may contain
2226 while ((h = current_history())) {
2228 while (*p == ' ' || *p == '\t')
2230 if (cmd_has_sensitive_data(p)) {
2231 h = remove_history(where_history());
2241 write_history(hfile);
2244 #endif /* CONFIG_READLINE */
2248 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2250 #ifdef CONFIG_ANSI_C_EXTRA
2251 /* TODO: ANSI C version(?) */
2252 printf("Action processing not supported in ANSI C build.\n");
2253 #else /* CONFIG_ANSI_C_EXTRA */
2257 char buf[256]; /* note: large enough to fit in unsolicited messages */
2260 fd = wpa_ctrl_get_fd(ctrl);
2262 while (!wpa_cli_quit) {
2265 tv.tv_sec = ping_interval;
2267 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2268 if (res < 0 && errno != EINTR) {
2273 if (FD_ISSET(fd, &rfds))
2274 wpa_cli_recv_pending(ctrl, 0, 1);
2276 /* verify that connection is still working */
2277 len = sizeof(buf) - 1;
2278 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2279 wpa_cli_action_cb) < 0 ||
2280 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2281 printf("wpa_supplicant did not reply to PING "
2282 "command - exiting\n");
2287 #endif /* CONFIG_ANSI_C_EXTRA */
2291 static void wpa_cli_cleanup(void)
2293 wpa_cli_close_connection();
2295 os_daemonize_terminate(pid_file);
2297 os_program_deinit();
2300 static void wpa_cli_terminate(int sig)
2307 #ifdef CONFIG_WPA_CLI_FORK
2308 static void wpa_cli_usr1(int sig)
2312 #endif /* CONFIG_WPA_CLI_FORK */
2315 #ifndef CONFIG_NATIVE_WINDOWS
2316 static void wpa_cli_alarm(int sig)
2318 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2319 printf("Connection to wpa_supplicant lost - trying to "
2321 wpa_cli_close_connection();
2324 wpa_cli_reconnect();
2326 wpa_cli_recv_pending(mon_conn, 1, 0);
2327 alarm(ping_interval);
2329 #endif /* CONFIG_NATIVE_WINDOWS */
2332 static char * wpa_cli_get_default_ifname(void)
2334 char *ifname = NULL;
2336 #ifdef CONFIG_CTRL_IFACE_UNIX
2337 struct dirent *dent;
2338 DIR *dir = opendir(ctrl_iface_dir);
2341 while ((dent = readdir(dir))) {
2342 #ifdef _DIRENT_HAVE_D_TYPE
2344 * Skip the file if it is not a socket. Also accept
2345 * DT_UNKNOWN (0) in case the C library or underlying
2346 * file system does not support d_type.
2348 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2350 #endif /* _DIRENT_HAVE_D_TYPE */
2351 if (os_strcmp(dent->d_name, ".") == 0 ||
2352 os_strcmp(dent->d_name, "..") == 0)
2354 printf("Selected interface '%s'\n", dent->d_name);
2355 ifname = os_strdup(dent->d_name);
2359 #endif /* CONFIG_CTRL_IFACE_UNIX */
2361 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2362 char buf[2048], *pos;
2364 struct wpa_ctrl *ctrl;
2367 ctrl = wpa_ctrl_open(NULL);
2371 len = sizeof(buf) - 1;
2372 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2375 pos = os_strchr(buf, '\n');
2378 ifname = os_strdup(buf);
2380 wpa_ctrl_close(ctrl);
2381 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2387 int main(int argc, char *argv[])
2389 int warning_displayed = 0;
2393 const char *global = NULL;
2395 if (os_program_init())
2399 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2404 action_file = optarg;
2413 ping_interval = atoi(optarg);
2419 printf("%s\n", wpa_cli_version);
2422 os_free(ctrl_ifname);
2423 ctrl_ifname = os_strdup(optarg);
2426 ctrl_iface_dir = optarg;
2437 interactive = (argc == optind) && (action_file == NULL);
2440 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2443 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2444 ctrl_conn = wpa_ctrl_open(NULL);
2445 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2446 ctrl_conn = wpa_ctrl_open(global);
2447 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2448 if (ctrl_conn == NULL) {
2449 perror("Failed to connect to wpa_supplicant - "
2456 signal(SIGINT, wpa_cli_terminate);
2457 signal(SIGTERM, wpa_cli_terminate);
2458 #endif /* _WIN32_WCE */
2459 #ifndef CONFIG_NATIVE_WINDOWS
2460 signal(SIGALRM, wpa_cli_alarm);
2461 #endif /* CONFIG_NATIVE_WINDOWS */
2462 #ifdef CONFIG_WPA_CLI_FORK
2463 signal(SIGUSR1, wpa_cli_usr1);
2464 #endif /* CONFIG_WPA_CLI_FORK */
2466 if (ctrl_ifname == NULL)
2467 ctrl_ifname = wpa_cli_get_default_ifname();
2471 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
2472 if (warning_displayed)
2473 printf("Connection established.\n");
2477 if (!warning_displayed) {
2478 printf("Could not connect to wpa_supplicant - "
2480 warning_displayed = 1;
2487 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
2488 perror("Failed to connect to wpa_supplicant - "
2494 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2495 wpa_cli_attached = 1;
2497 printf("Warning: Failed to attach to "
2498 "wpa_supplicant.\n");
2504 if (daemonize && os_daemonize(pid_file))
2508 wpa_cli_interactive();
2509 else if (action_file)
2510 wpa_cli_action(ctrl_conn);
2512 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2514 os_free(ctrl_ifname);
2520 #else /* CONFIG_CTRL_IFACE */
2521 int main(int argc, char *argv[])
2523 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2526 #endif /* CONFIG_CTRL_IFACE */