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 two arguments:\n"
736 "- UUID: use 'any' to select any\n"
737 "- PIN: Enrollee PIN\n");
741 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
743 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
744 printf("Too long WPS_ER_PIN command.\n");
747 return wpa_ctrl_command(ctrl, cmd);
751 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
758 printf("Invalid WPS_ER_PBC command: need one argument:\n"
759 "- UUID: Specify the Enrollee\n");
763 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
765 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
766 printf("Too long WPS_ER_PBC command.\n");
769 return wpa_ctrl_command(ctrl, cmd);
773 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
780 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
781 "- UUID: specify which AP to use\n"
786 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
788 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
789 printf("Too long WPS_ER_LEARN command.\n");
792 return wpa_ctrl_command(ctrl, cmd);
796 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
802 if (argc == 5 || argc == 6) {
803 char ssid_hex[2 * 32 + 1];
804 char key_hex[2 * 64 + 1];
808 for (i = 0; i < 32; i++) {
809 if (argv[2][i] == '\0')
811 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
816 for (i = 0; i < 64; i++) {
817 if (argv[5][i] == '\0')
819 os_snprintf(&key_hex[i * 2], 3, "%02x",
824 res = os_snprintf(cmd, sizeof(cmd),
825 "WPS_ER_CONFIG %s %s %s %s %s %s",
826 argv[0], argv[1], ssid_hex, argv[3], argv[4],
829 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
833 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
834 "- new encr (NONE, WEP, TKIP, CCMP)\n"
839 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
840 printf("Too long WPS_ER_CONFIG command.\n");
843 return wpa_ctrl_command(ctrl, cmd);
847 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
853 printf("Invalid IBSS_RSN command: needs one argument "
854 "(Peer STA MAC address)\n");
858 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
859 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
860 printf("Too long IBSS_RSN command.\n");
863 return wpa_ctrl_command(ctrl, cmd);
867 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
873 printf("Invalid LEVEL command: needs one argument (debug "
877 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
878 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
879 printf("Too long LEVEL command.\n");
882 return wpa_ctrl_command(ctrl, cmd);
886 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
888 char cmd[256], *pos, *end;
892 printf("Invalid IDENTITY command: needs two arguments "
893 "(network id and identity)\n");
897 end = cmd + sizeof(cmd);
899 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
901 if (ret < 0 || ret >= end - pos) {
902 printf("Too long IDENTITY command.\n");
906 for (i = 2; i < argc; i++) {
907 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
908 if (ret < 0 || ret >= end - pos) {
909 printf("Too long IDENTITY command.\n");
915 return wpa_ctrl_command(ctrl, cmd);
919 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
921 char cmd[256], *pos, *end;
925 printf("Invalid PASSWORD command: needs two arguments "
926 "(network id and password)\n");
930 end = cmd + sizeof(cmd);
932 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
934 if (ret < 0 || ret >= end - pos) {
935 printf("Too long PASSWORD command.\n");
939 for (i = 2; i < argc; i++) {
940 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
941 if (ret < 0 || ret >= end - pos) {
942 printf("Too long PASSWORD command.\n");
948 return wpa_ctrl_command(ctrl, cmd);
952 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
955 char cmd[256], *pos, *end;
959 printf("Invalid NEW_PASSWORD command: needs two arguments "
960 "(network id and password)\n");
964 end = cmd + sizeof(cmd);
966 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
968 if (ret < 0 || ret >= end - pos) {
969 printf("Too long NEW_PASSWORD command.\n");
973 for (i = 2; i < argc; i++) {
974 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
975 if (ret < 0 || ret >= end - pos) {
976 printf("Too long NEW_PASSWORD command.\n");
982 return wpa_ctrl_command(ctrl, cmd);
986 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
988 char cmd[256], *pos, *end;
992 printf("Invalid PIN command: needs two arguments "
993 "(network id and pin)\n");
997 end = cmd + sizeof(cmd);
999 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1001 if (ret < 0 || ret >= end - pos) {
1002 printf("Too long PIN command.\n");
1006 for (i = 2; i < argc; i++) {
1007 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1008 if (ret < 0 || ret >= end - pos) {
1009 printf("Too long PIN command.\n");
1014 return wpa_ctrl_command(ctrl, cmd);
1018 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1020 char cmd[256], *pos, *end;
1024 printf("Invalid OTP command: needs two arguments (network "
1025 "id and password)\n");
1029 end = cmd + sizeof(cmd);
1031 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1033 if (ret < 0 || ret >= end - pos) {
1034 printf("Too long OTP command.\n");
1038 for (i = 2; i < argc; i++) {
1039 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1040 if (ret < 0 || ret >= end - pos) {
1041 printf("Too long OTP command.\n");
1047 return wpa_ctrl_command(ctrl, cmd);
1051 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1054 char cmd[256], *pos, *end;
1058 printf("Invalid PASSPHRASE command: needs two arguments "
1059 "(network id and passphrase)\n");
1063 end = cmd + sizeof(cmd);
1065 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1067 if (ret < 0 || ret >= end - pos) {
1068 printf("Too long PASSPHRASE command.\n");
1072 for (i = 2; i < argc; i++) {
1073 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1074 if (ret < 0 || ret >= end - pos) {
1075 printf("Too long PASSPHRASE command.\n");
1081 return wpa_ctrl_command(ctrl, cmd);
1085 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1087 char cmd[256], *pos, *end;
1091 printf("Invalid BSSID command: needs two arguments (network "
1096 end = cmd + sizeof(cmd);
1098 ret = os_snprintf(pos, end - pos, "BSSID");
1099 if (ret < 0 || ret >= end - pos) {
1100 printf("Too long BSSID command.\n");
1104 for (i = 0; i < argc; i++) {
1105 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1106 if (ret < 0 || ret >= end - pos) {
1107 printf("Too long BSSID command.\n");
1113 return wpa_ctrl_command(ctrl, cmd);
1117 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1120 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1124 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1131 printf("Invalid SELECT_NETWORK command: needs one argument "
1136 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1137 if (res < 0 || (size_t) res >= sizeof(cmd))
1139 cmd[sizeof(cmd) - 1] = '\0';
1141 return wpa_ctrl_command(ctrl, cmd);
1145 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1152 printf("Invalid ENABLE_NETWORK command: needs one argument "
1157 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1158 if (res < 0 || (size_t) res >= sizeof(cmd))
1160 cmd[sizeof(cmd) - 1] = '\0';
1162 return wpa_ctrl_command(ctrl, cmd);
1166 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1173 printf("Invalid DISABLE_NETWORK command: needs one argument "
1178 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1179 if (res < 0 || (size_t) res >= sizeof(cmd))
1181 cmd[sizeof(cmd) - 1] = '\0';
1183 return wpa_ctrl_command(ctrl, cmd);
1187 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1190 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1194 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1201 printf("Invalid REMOVE_NETWORK command: needs one argument "
1206 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1207 if (res < 0 || (size_t) res >= sizeof(cmd))
1209 cmd[sizeof(cmd) - 1] = '\0';
1211 return wpa_ctrl_command(ctrl, cmd);
1215 static void wpa_cli_show_network_variables(void)
1217 printf("set_network variables:\n"
1218 " ssid (network name, SSID)\n"
1219 " psk (WPA passphrase or pre-shared key)\n"
1220 " key_mgmt (key management protocol)\n"
1221 " identity (EAP identity)\n"
1222 " password (EAP password)\n"
1225 "Note: Values are entered in the same format as the "
1226 "configuration file is using,\n"
1227 "i.e., strings values need to be inside double quotation "
1229 "For example: set_network 1 ssid \"network name\"\n"
1231 "Please see wpa_supplicant.conf documentation for full list "
1232 "of\navailable variables.\n");
1236 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1243 wpa_cli_show_network_variables();
1248 printf("Invalid SET_NETWORK command: needs three arguments\n"
1249 "(network id, variable name, and value)\n");
1253 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1254 argv[0], argv[1], argv[2]);
1255 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1256 printf("Too long SET_NETWORK command.\n");
1259 return wpa_ctrl_command(ctrl, cmd);
1263 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1270 wpa_cli_show_network_variables();
1275 printf("Invalid GET_NETWORK command: needs two arguments\n"
1276 "(network id and variable name)\n");
1280 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1282 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1283 printf("Too long GET_NETWORK command.\n");
1286 return wpa_ctrl_command(ctrl, cmd);
1290 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1293 return wpa_ctrl_command(ctrl, "DISCONNECT");
1297 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1300 return wpa_ctrl_command(ctrl, "RECONNECT");
1304 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1307 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1311 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1313 return wpa_ctrl_command(ctrl, "SCAN");
1317 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1320 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1324 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1330 printf("Invalid BSS command: need one argument (index or "
1335 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1336 if (res < 0 || (size_t) res >= sizeof(cmd))
1338 cmd[sizeof(cmd) - 1] = '\0';
1340 return wpa_ctrl_command(ctrl, cmd);
1344 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1350 if (argc < 1 || argc > 2) {
1351 printf("Invalid GET_CAPABILITY command: need either one or "
1356 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1357 printf("Invalid GET_CAPABILITY command: second argument, "
1358 "if any, must be 'strict'\n");
1362 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1363 (argc == 2) ? " strict" : "");
1364 if (res < 0 || (size_t) res >= sizeof(cmd))
1366 cmd[sizeof(cmd) - 1] = '\0';
1368 return wpa_ctrl_command(ctrl, cmd);
1372 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1374 printf("Available interfaces:\n");
1375 return wpa_ctrl_command(ctrl, "INTERFACES");
1379 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1382 wpa_cli_list_interfaces(ctrl);
1386 wpa_cli_close_connection();
1387 os_free(ctrl_ifname);
1388 ctrl_ifname = os_strdup(argv[0]);
1390 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1391 printf("Connected to interface '%s.\n", ctrl_ifname);
1393 printf("Could not connect to interface '%s' - re-trying\n",
1400 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1403 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1407 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1410 return wpa_ctrl_command(ctrl, "TERMINATE");
1414 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1421 printf("Invalid INTERFACE_ADD command: needs at least one "
1422 "argument (interface name)\n"
1423 "All arguments: ifname confname driver ctrl_interface "
1424 "driver_param bridge_name\n");
1429 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1430 * <driver_param>TAB<bridge_name>
1432 res = os_snprintf(cmd, sizeof(cmd),
1433 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1435 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1436 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1437 argc > 5 ? argv[5] : "");
1438 if (res < 0 || (size_t) res >= sizeof(cmd))
1440 cmd[sizeof(cmd) - 1] = '\0';
1441 return wpa_ctrl_command(ctrl, cmd);
1445 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1452 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1453 "(interface name)\n");
1457 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1458 if (res < 0 || (size_t) res >= sizeof(cmd))
1460 cmd[sizeof(cmd) - 1] = '\0';
1461 return wpa_ctrl_command(ctrl, cmd);
1465 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1468 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1473 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1477 printf("Invalid 'sta' command - exactly one argument, STA "
1478 "address, is required.\n");
1481 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1482 return wpa_ctrl_command(ctrl, buf);
1486 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1487 char *addr, size_t addr_len)
1489 char buf[4096], *pos;
1493 if (ctrl_conn == NULL) {
1494 printf("Not connected to hostapd - command dropped.\n");
1497 len = sizeof(buf) - 1;
1498 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1501 printf("'%s' command timed out.\n", cmd);
1503 } else if (ret < 0) {
1504 printf("'%s' command failed.\n", cmd);
1509 if (memcmp(buf, "FAIL", 4) == 0)
1514 while (*pos != '\0' && *pos != '\n')
1517 os_strlcpy(addr, buf, addr_len);
1522 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1524 char addr[32], cmd[64];
1526 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1529 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1530 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1534 #endif /* CONFIG_AP */
1537 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1539 return wpa_ctrl_command(ctrl, "SUSPEND");
1543 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1545 return wpa_ctrl_command(ctrl, "RESUME");
1549 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1551 return wpa_ctrl_command(ctrl, "DROP_SA");
1555 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1561 printf("Invalid ROAM command: needs one argument "
1562 "(target AP's BSSID)\n");
1566 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1567 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1568 printf("Too long ROAM command.\n");
1571 return wpa_ctrl_command(ctrl, cmd);
1575 enum wpa_cli_cmd_flags {
1576 cli_cmd_flag_none = 0x00,
1577 cli_cmd_flag_sensitive = 0x01
1580 struct wpa_cli_cmd {
1582 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1583 enum wpa_cli_cmd_flags flags;
1587 static struct wpa_cli_cmd wpa_cli_commands[] = {
1588 { "status", wpa_cli_cmd_status,
1590 "[verbose] = get current WPA/EAPOL/EAP status" },
1591 { "ping", wpa_cli_cmd_ping,
1593 "= pings wpa_supplicant" },
1594 { "note", wpa_cli_cmd_note,
1596 "<text> = add a note to wpa_supplicant debug log" },
1597 { "mib", wpa_cli_cmd_mib,
1599 "= get MIB variables (dot1x, dot11)" },
1600 { "help", wpa_cli_cmd_help,
1602 "= show this usage help" },
1603 { "interface", wpa_cli_cmd_interface,
1605 "[ifname] = show interfaces/select interface" },
1606 { "level", wpa_cli_cmd_level,
1608 "<debug level> = change debug level" },
1609 { "license", wpa_cli_cmd_license,
1611 "= show full wpa_cli license" },
1612 { "quit", wpa_cli_cmd_quit,
1615 { "set", wpa_cli_cmd_set,
1617 "= set variables (shows list of variables when run without "
1619 { "logon", wpa_cli_cmd_logon,
1621 "= IEEE 802.1X EAPOL state machine logon" },
1622 { "logoff", wpa_cli_cmd_logoff,
1624 "= IEEE 802.1X EAPOL state machine logoff" },
1625 { "pmksa", wpa_cli_cmd_pmksa,
1627 "= show PMKSA cache" },
1628 { "reassociate", wpa_cli_cmd_reassociate,
1630 "= force reassociation" },
1631 { "preauthenticate", wpa_cli_cmd_preauthenticate,
1633 "<BSSID> = force preauthentication" },
1634 { "identity", wpa_cli_cmd_identity,
1636 "<network id> <identity> = configure identity for an SSID" },
1637 { "password", wpa_cli_cmd_password,
1638 cli_cmd_flag_sensitive,
1639 "<network id> <password> = configure password for an SSID" },
1640 { "new_password", wpa_cli_cmd_new_password,
1641 cli_cmd_flag_sensitive,
1642 "<network id> <password> = change password for an SSID" },
1643 { "pin", wpa_cli_cmd_pin,
1644 cli_cmd_flag_sensitive,
1645 "<network id> <pin> = configure pin for an SSID" },
1646 { "otp", wpa_cli_cmd_otp,
1647 cli_cmd_flag_sensitive,
1648 "<network id> <password> = configure one-time-password for an SSID"
1650 { "passphrase", wpa_cli_cmd_passphrase,
1651 cli_cmd_flag_sensitive,
1652 "<network id> <passphrase> = configure private key passphrase\n"
1654 { "bssid", wpa_cli_cmd_bssid,
1656 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1657 { "list_networks", wpa_cli_cmd_list_networks,
1659 "= list configured networks" },
1660 { "select_network", wpa_cli_cmd_select_network,
1662 "<network id> = select a network (disable others)" },
1663 { "enable_network", wpa_cli_cmd_enable_network,
1665 "<network id> = enable a network" },
1666 { "disable_network", wpa_cli_cmd_disable_network,
1668 "<network id> = disable a network" },
1669 { "add_network", wpa_cli_cmd_add_network,
1671 "= add a network" },
1672 { "remove_network", wpa_cli_cmd_remove_network,
1674 "<network id> = remove a network" },
1675 { "set_network", wpa_cli_cmd_set_network,
1676 cli_cmd_flag_sensitive,
1677 "<network id> <variable> <value> = set network variables (shows\n"
1678 " list of variables when run without arguments)" },
1679 { "get_network", wpa_cli_cmd_get_network,
1681 "<network id> <variable> = get network variables" },
1682 { "save_config", wpa_cli_cmd_save_config,
1684 "= save the current configuration" },
1685 { "disconnect", wpa_cli_cmd_disconnect,
1687 "= disconnect and wait for reassociate/reconnect command before\n"
1689 { "reconnect", wpa_cli_cmd_reconnect,
1691 "= like reassociate, but only takes effect if already disconnected"
1693 { "scan", wpa_cli_cmd_scan,
1695 "= request new BSS scan" },
1696 { "scan_results", wpa_cli_cmd_scan_results,
1698 "= get latest scan results" },
1699 { "bss", wpa_cli_cmd_bss,
1701 "<<idx> | <bssid>> = get detailed scan result info" },
1702 { "get_capability", wpa_cli_cmd_get_capability,
1704 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1705 { "reconfigure", wpa_cli_cmd_reconfigure,
1707 "= force wpa_supplicant to re-read its configuration file" },
1708 { "terminate", wpa_cli_cmd_terminate,
1710 "= terminate wpa_supplicant" },
1711 { "interface_add", wpa_cli_cmd_interface_add,
1713 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1714 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1716 { "interface_remove", wpa_cli_cmd_interface_remove,
1718 "<ifname> = removes the interface" },
1719 { "interface_list", wpa_cli_cmd_interface_list,
1721 "= list available interfaces" },
1722 { "ap_scan", wpa_cli_cmd_ap_scan,
1724 "<value> = set ap_scan parameter" },
1725 { "stkstart", wpa_cli_cmd_stkstart,
1727 "<addr> = request STK negotiation with <addr>" },
1728 { "ft_ds", wpa_cli_cmd_ft_ds,
1730 "<addr> = request over-the-DS FT with <addr>" },
1731 { "wps_pbc", wpa_cli_cmd_wps_pbc,
1733 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1734 { "wps_pin", wpa_cli_cmd_wps_pin,
1735 cli_cmd_flag_sensitive,
1736 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1738 #ifdef CONFIG_WPS_OOB
1739 { "wps_oob", wpa_cli_cmd_wps_oob,
1740 cli_cmd_flag_sensitive,
1741 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1742 #endif /* CONFIG_WPS_OOB */
1743 { "wps_reg", wpa_cli_cmd_wps_reg,
1744 cli_cmd_flag_sensitive,
1745 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1746 { "wps_er_start", wpa_cli_cmd_wps_er_start,
1748 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
1749 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1751 "= stop Wi-Fi Protected Setup External Registrar" },
1752 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
1753 cli_cmd_flag_sensitive,
1754 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1755 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
1757 "<UUID> = accept an Enrollee PBC using External Registrar" },
1758 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
1759 cli_cmd_flag_sensitive,
1760 "<UUID> <PIN> = learn AP configuration" },
1761 { "wps_er_config", wpa_cli_cmd_wps_er_config,
1762 cli_cmd_flag_sensitive,
1763 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
1764 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1766 "<addr> = request RSN authentication with <addr> in IBSS" },
1768 { "sta", wpa_cli_cmd_sta,
1770 "<addr> = get information about an associated station (AP)" },
1771 { "all_sta", wpa_cli_cmd_all_sta,
1773 "= get information about all associated stations (AP)" },
1774 #endif /* CONFIG_AP */
1775 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
1776 "= notification of suspend/hibernate" },
1777 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
1778 "= notification of resume/thaw" },
1779 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
1780 "= drop SA without deauth/disassoc (test command)" },
1781 { "roam", wpa_cli_cmd_roam,
1783 "<addr> = roam to the specified BSS" },
1784 { NULL, NULL, cli_cmd_flag_none, NULL }
1789 * Prints command usage, lines are padded with the specified string.
1791 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1796 printf("%s%s ", pad, cmd->cmd);
1797 for (n = 0; (c = cmd->usage[n]); n++) {
1806 static void print_help(void)
1809 printf("commands:\n");
1810 for (n = 0; wpa_cli_commands[n].cmd; n++)
1811 print_cmd_help(&wpa_cli_commands[n], " ");
1815 #ifdef CONFIG_READLINE
1816 static int cmd_has_sensitive_data(const char *cmd)
1818 const char *c, *delim;
1822 delim = os_strchr(cmd, ' ');
1826 len = os_strlen(cmd);
1828 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1829 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1830 return (wpa_cli_commands[n].flags &
1831 cli_cmd_flag_sensitive);
1835 #endif /* CONFIG_READLINE */
1838 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1840 struct wpa_cli_cmd *cmd, *match = NULL;
1845 cmd = wpa_cli_commands;
1847 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1850 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1851 /* we have an exact match */
1861 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1862 cmd = wpa_cli_commands;
1864 if (os_strncasecmp(cmd->cmd, argv[0],
1865 os_strlen(argv[0])) == 0) {
1866 printf(" %s", cmd->cmd);
1872 } else if (count == 0) {
1873 printf("Unknown command '%s'\n", argv[0]);
1876 ret = match->handler(ctrl, argc - 1, &argv[1]);
1883 static int str_match(const char *a, const char *b)
1885 return os_strncmp(a, b, os_strlen(b)) == 0;
1889 static int wpa_cli_exec(const char *program, const char *arg1,
1897 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1898 cmd = os_malloc(len);
1901 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1902 if (res < 0 || (size_t) res >= len) {
1906 cmd[len - 1] = '\0';
1908 if (system(cmd) < 0)
1910 #endif /* _WIN32_WCE */
1917 static void wpa_cli_action_process(const char *msg)
1920 char *copy = NULL, *id, *pos2;
1925 pos = os_strchr(pos, '>');
1932 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1934 os_unsetenv("WPA_ID");
1935 os_unsetenv("WPA_ID_STR");
1936 os_unsetenv("WPA_CTRL_DIR");
1938 pos = os_strstr(pos, "[id=");
1940 copy = os_strdup(pos + 4);
1944 while (*pos2 && *pos2 != ' ')
1948 os_setenv("WPA_ID", id, 1);
1949 while (*pos2 && *pos2 != '=')
1954 while (*pos2 && *pos2 != ']')
1957 os_setenv("WPA_ID_STR", id, 1);
1961 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1963 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1964 wpa_cli_connected = 1;
1965 wpa_cli_last_id = new_id;
1966 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1968 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1969 if (wpa_cli_connected) {
1970 wpa_cli_connected = 0;
1971 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1973 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1974 printf("wpa_supplicant is terminating - stop monitoring\n");
1980 #ifndef CONFIG_ANSI_C_EXTRA
1981 static void wpa_cli_action_cb(char *msg, size_t len)
1983 wpa_cli_action_process(msg);
1985 #endif /* CONFIG_ANSI_C_EXTRA */
1988 static void wpa_cli_reconnect(void)
1990 wpa_cli_close_connection();
1991 wpa_cli_open_connection(ctrl_ifname, 1);
1995 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1999 if (ctrl_conn == NULL) {
2000 wpa_cli_reconnect();
2003 while (wpa_ctrl_pending(ctrl) > 0) {
2005 size_t len = sizeof(buf) - 1;
2006 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2009 wpa_cli_action_process(buf);
2011 if (wpa_cli_show_event(buf)) {
2012 if (in_read && first)
2015 printf("%s\n", buf);
2020 printf("Could not read pending message.\n");
2025 if (wpa_ctrl_pending(ctrl) < 0) {
2026 printf("Connection to wpa_supplicant lost - trying to "
2028 wpa_cli_reconnect();
2033 #ifdef CONFIG_READLINE
2034 static char * wpa_cli_cmd_gen(const char *text, int state)
2041 len = os_strlen(text);
2044 while ((cmd = wpa_cli_commands[i].cmd)) {
2046 if (os_strncasecmp(cmd, text, len) == 0)
2054 static char * wpa_cli_dummy_gen(const char *text, int state)
2058 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2059 const char *cmd = wpa_cli_commands[i].cmd;
2060 size_t len = os_strlen(cmd);
2061 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
2062 rl_line_buffer[len] == ' ') {
2063 printf("\n%s\n", wpa_cli_commands[i].usage);
2069 rl_attempted_completion_over = 1;
2074 static char * wpa_cli_status_gen(const char *text, int state)
2084 len = os_strlen(text);
2087 while ((t = options[i])) {
2089 if (os_strncasecmp(t, text, len) == 0)
2093 rl_attempted_completion_over = 1;
2098 static char ** wpa_cli_completion(const char *text, int start, int end)
2100 char * (*func)(const char *text, int state);
2103 func = wpa_cli_cmd_gen;
2104 else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
2105 func = wpa_cli_status_gen;
2107 func = wpa_cli_dummy_gen;
2108 return rl_completion_matches(text, func);
2110 #endif /* CONFIG_READLINE */
2113 static void wpa_cli_interactive(void)
2116 char cmdbuf[256], *cmd, *argv[max_args], *pos;
2118 #ifdef CONFIG_READLINE
2119 char *home, *hfile = NULL;
2120 #endif /* CONFIG_READLINE */
2122 printf("\nInteractive mode\n\n");
2124 #ifdef CONFIG_READLINE
2125 rl_attempted_completion_function = wpa_cli_completion;
2126 home = getenv("HOME");
2128 const char *fname = ".wpa_cli_history";
2129 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
2130 hfile = os_malloc(hfile_len);
2133 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
2135 if (res >= 0 && res < hfile_len) {
2136 hfile[hfile_len - 1] = '\0';
2137 read_history(hfile);
2138 stifle_history(100);
2142 #endif /* CONFIG_READLINE */
2145 wpa_cli_recv_pending(mon_conn, 0, 0);
2146 #ifndef CONFIG_NATIVE_WINDOWS
2147 alarm(ping_interval);
2148 #endif /* CONFIG_NATIVE_WINDOWS */
2149 #ifdef CONFIG_WPA_CLI_FORK
2151 kill(mon_pid, SIGUSR1);
2152 #endif /* CONFIG_WPA_CLI_FORK */
2153 #ifdef CONFIG_READLINE
2154 cmd = readline("> ");
2157 while (next_history())
2159 h = previous_history();
2160 if (h == NULL || os_strcmp(cmd, h->line) != 0)
2164 #else /* CONFIG_READLINE */
2166 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
2167 #endif /* CONFIG_READLINE */
2168 #ifndef CONFIG_NATIVE_WINDOWS
2170 #endif /* CONFIG_NATIVE_WINDOWS */
2173 wpa_cli_recv_pending(mon_conn, 0, 0);
2175 while (*pos != '\0') {
2191 if (argc == max_args)
2194 char *pos2 = os_strrchr(pos, '"');
2198 while (*pos != '\0' && *pos != ' ')
2204 wpa_request(ctrl_conn, argc, argv);
2208 #ifdef CONFIG_WPA_CLI_FORK
2210 kill(mon_pid, SIGUSR2);
2211 #endif /* CONFIG_WPA_CLI_FORK */
2212 } while (!wpa_cli_quit);
2214 #ifdef CONFIG_READLINE
2216 /* Save command history, excluding lines that may contain
2220 while ((h = current_history())) {
2222 while (*p == ' ' || *p == '\t')
2224 if (cmd_has_sensitive_data(p)) {
2225 h = remove_history(where_history());
2235 write_history(hfile);
2238 #endif /* CONFIG_READLINE */
2242 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2244 #ifdef CONFIG_ANSI_C_EXTRA
2245 /* TODO: ANSI C version(?) */
2246 printf("Action processing not supported in ANSI C build.\n");
2247 #else /* CONFIG_ANSI_C_EXTRA */
2251 char buf[256]; /* note: large enough to fit in unsolicited messages */
2254 fd = wpa_ctrl_get_fd(ctrl);
2256 while (!wpa_cli_quit) {
2259 tv.tv_sec = ping_interval;
2261 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2262 if (res < 0 && errno != EINTR) {
2267 if (FD_ISSET(fd, &rfds))
2268 wpa_cli_recv_pending(ctrl, 0, 1);
2270 /* verify that connection is still working */
2271 len = sizeof(buf) - 1;
2272 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2273 wpa_cli_action_cb) < 0 ||
2274 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2275 printf("wpa_supplicant did not reply to PING "
2276 "command - exiting\n");
2281 #endif /* CONFIG_ANSI_C_EXTRA */
2285 static void wpa_cli_cleanup(void)
2287 wpa_cli_close_connection();
2289 os_daemonize_terminate(pid_file);
2291 os_program_deinit();
2294 static void wpa_cli_terminate(int sig)
2301 #ifdef CONFIG_WPA_CLI_FORK
2302 static void wpa_cli_usr1(int sig)
2306 #endif /* CONFIG_WPA_CLI_FORK */
2309 #ifndef CONFIG_NATIVE_WINDOWS
2310 static void wpa_cli_alarm(int sig)
2312 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2313 printf("Connection to wpa_supplicant lost - trying to "
2315 wpa_cli_close_connection();
2318 wpa_cli_reconnect();
2320 wpa_cli_recv_pending(mon_conn, 1, 0);
2321 alarm(ping_interval);
2323 #endif /* CONFIG_NATIVE_WINDOWS */
2326 static char * wpa_cli_get_default_ifname(void)
2328 char *ifname = NULL;
2330 #ifdef CONFIG_CTRL_IFACE_UNIX
2331 struct dirent *dent;
2332 DIR *dir = opendir(ctrl_iface_dir);
2335 while ((dent = readdir(dir))) {
2336 #ifdef _DIRENT_HAVE_D_TYPE
2338 * Skip the file if it is not a socket. Also accept
2339 * DT_UNKNOWN (0) in case the C library or underlying
2340 * file system does not support d_type.
2342 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2344 #endif /* _DIRENT_HAVE_D_TYPE */
2345 if (os_strcmp(dent->d_name, ".") == 0 ||
2346 os_strcmp(dent->d_name, "..") == 0)
2348 printf("Selected interface '%s'\n", dent->d_name);
2349 ifname = os_strdup(dent->d_name);
2353 #endif /* CONFIG_CTRL_IFACE_UNIX */
2355 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2356 char buf[2048], *pos;
2358 struct wpa_ctrl *ctrl;
2361 ctrl = wpa_ctrl_open(NULL);
2365 len = sizeof(buf) - 1;
2366 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2369 pos = os_strchr(buf, '\n');
2372 ifname = os_strdup(buf);
2374 wpa_ctrl_close(ctrl);
2375 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2381 int main(int argc, char *argv[])
2383 int warning_displayed = 0;
2387 const char *global = NULL;
2389 if (os_program_init())
2393 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2398 action_file = optarg;
2407 ping_interval = atoi(optarg);
2413 printf("%s\n", wpa_cli_version);
2416 os_free(ctrl_ifname);
2417 ctrl_ifname = os_strdup(optarg);
2420 ctrl_iface_dir = optarg;
2431 interactive = (argc == optind) && (action_file == NULL);
2434 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2437 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2438 ctrl_conn = wpa_ctrl_open(NULL);
2439 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2440 ctrl_conn = wpa_ctrl_open(global);
2441 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2442 if (ctrl_conn == NULL) {
2443 perror("Failed to connect to wpa_supplicant - "
2450 signal(SIGINT, wpa_cli_terminate);
2451 signal(SIGTERM, wpa_cli_terminate);
2452 #endif /* _WIN32_WCE */
2453 #ifndef CONFIG_NATIVE_WINDOWS
2454 signal(SIGALRM, wpa_cli_alarm);
2455 #endif /* CONFIG_NATIVE_WINDOWS */
2456 #ifdef CONFIG_WPA_CLI_FORK
2457 signal(SIGUSR1, wpa_cli_usr1);
2458 #endif /* CONFIG_WPA_CLI_FORK */
2460 if (ctrl_ifname == NULL)
2461 ctrl_ifname = wpa_cli_get_default_ifname();
2465 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
2466 if (warning_displayed)
2467 printf("Connection established.\n");
2471 if (!warning_displayed) {
2472 printf("Could not connect to wpa_supplicant - "
2474 warning_displayed = 1;
2481 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
2482 perror("Failed to connect to wpa_supplicant - "
2488 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2489 wpa_cli_attached = 1;
2491 printf("Warning: Failed to attach to "
2492 "wpa_supplicant.\n");
2498 if (daemonize && os_daemonize(pid_file))
2502 wpa_cli_interactive();
2503 else if (action_file)
2504 wpa_cli_action(ctrl_conn);
2506 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2508 os_free(ctrl_ifname);
2514 #else /* CONFIG_CTRL_IFACE */
2515 int main(int argc, char *argv[])
2517 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2520 #endif /* CONFIG_CTRL_IFACE */