2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
22 #ifdef CONFIG_READLINE
23 #include <readline/readline.h>
24 #include <readline/history.h>
25 #endif /* CONFIG_READLINE */
26 #ifdef CONFIG_WPA_CLI_FORK
28 #endif /* CONFIG_WPA_CLI_FORK */
30 #include "common/wpa_ctrl.h"
32 #include "common/version.h"
35 static const char *wpa_cli_version =
36 "wpa_cli v" VERSION_STR "\n"
37 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
40 static const char *wpa_cli_license =
41 "This program is free software. You can distribute it and/or modify it\n"
42 "under the terms of the GNU General Public License version 2.\n"
44 "Alternatively, this software may be distributed under the terms of the\n"
45 "BSD license. See README and COPYING for more details.\n";
47 static const char *wpa_cli_full_license =
48 "This program is free software; you can redistribute it and/or modify\n"
49 "it under the terms of the GNU General Public License version 2 as\n"
50 "published by the Free Software Foundation.\n"
52 "This program is distributed in the hope that it will be useful,\n"
53 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
54 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
55 "GNU General Public License for more details.\n"
57 "You should have received a copy of the GNU General Public License\n"
58 "along with this program; if not, write to the Free Software\n"
59 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
61 "Alternatively, this software may be distributed under the terms of the\n"
64 "Redistribution and use in source and binary forms, with or without\n"
65 "modification, are permitted provided that the following conditions are\n"
68 "1. Redistributions of source code must retain the above copyright\n"
69 " notice, this list of conditions and the following disclaimer.\n"
71 "2. Redistributions in binary form must reproduce the above copyright\n"
72 " notice, this list of conditions and the following disclaimer in the\n"
73 " documentation and/or other materials provided with the distribution.\n"
75 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
76 " names of its contributors may be used to endorse or promote products\n"
77 " derived from this software without specific prior written permission.\n"
79 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
80 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
81 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
82 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
83 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
84 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
85 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
86 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
87 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
88 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
89 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
92 static struct wpa_ctrl *ctrl_conn;
93 static struct wpa_ctrl *mon_conn;
94 #ifdef CONFIG_WPA_CLI_FORK
95 static pid_t mon_pid = 0;
96 #endif /* CONFIG_WPA_CLI_FORK */
97 static int wpa_cli_quit = 0;
98 static int wpa_cli_attached = 0;
99 static int wpa_cli_connected = 0;
100 static int wpa_cli_last_id = 0;
101 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
102 static char *ctrl_ifname = NULL;
103 static const char *pid_file = NULL;
104 static const char *action_file = NULL;
105 static int ping_interval = 5;
106 static int interactive = 0;
109 static void print_help();
112 static void usage(void)
114 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
115 "[-a<action file>] \\\n"
116 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
118 " -h = help (show this usage text)\n"
119 " -v = shown version information\n"
120 " -a = run in daemon mode executing the action file based on "
123 " -B = run a daemon in the background\n"
124 " default path: /var/run/wpa_supplicant\n"
125 " default interface: first interface found in socket path\n");
130 static void readline_redraw()
132 #ifdef CONFIG_READLINE
135 #endif /* CONFIG_READLINE */
139 static int str_starts(const char *src, const char *match)
141 return os_strncmp(src, match, os_strlen(match)) == 0;
145 static int wpa_cli_show_event(const char *event)
149 start = os_strchr(event, '>');
155 * Skip BSS added/removed events since they can be relatively frequent
156 * and are likely of not much use for an interactive user.
158 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
159 str_starts(start, WPA_EVENT_BSS_REMOVED))
166 #ifdef CONFIG_WPA_CLI_FORK
167 static int in_query = 0;
169 static void wpa_cli_monitor_sig(int sig)
173 else if (sig == SIGUSR2)
178 static void wpa_cli_monitor(void)
181 size_t len = sizeof(buf) - 1;
186 signal(SIGUSR1, wpa_cli_monitor_sig);
187 signal(SIGUSR2, wpa_cli_monitor_sig);
191 int s = wpa_ctrl_get_fd(mon_conn);
196 if (select(s + 1, &rfds, NULL, NULL, &tv) < 0) {
202 if (mon_conn == NULL)
204 if (FD_ISSET(s, &rfds)) {
205 len = sizeof(buf) - 1;
206 int res = wpa_ctrl_recv(mon_conn, buf, &len);
208 perror("wpa_ctrl_recv");
212 if (wpa_cli_show_event(buf)) {
221 #endif /* CONFIG_WPA_CLI_FORK */
224 static int wpa_cli_open_connection(const char *ifname, int attach)
226 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
227 ctrl_conn = wpa_ctrl_open(ifname);
228 if (ctrl_conn == NULL)
231 if (attach && interactive)
232 mon_conn = wpa_ctrl_open(ifname);
235 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
242 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
243 cfile = os_malloc(flen);
246 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
247 if (res < 0 || res >= flen) {
252 ctrl_conn = wpa_ctrl_open(cfile);
253 if (ctrl_conn == NULL) {
258 if (attach && interactive)
259 mon_conn = wpa_ctrl_open(cfile);
263 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
266 if (wpa_ctrl_attach(mon_conn) == 0) {
267 wpa_cli_attached = 1;
269 printf("Warning: Failed to attach to "
270 "wpa_supplicant.\n");
274 #ifdef CONFIG_WPA_CLI_FORK
287 #endif /* CONFIG_WPA_CLI_FORK */
294 static void wpa_cli_close_connection(void)
296 if (ctrl_conn == NULL)
299 #ifdef CONFIG_WPA_CLI_FORK
302 kill(mon_pid, SIGPIPE);
306 #endif /* CONFIG_WPA_CLI_FORK */
308 if (wpa_cli_attached) {
309 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
310 wpa_cli_attached = 0;
312 wpa_ctrl_close(ctrl_conn);
315 wpa_ctrl_close(mon_conn);
321 static void wpa_cli_msg_cb(char *msg, size_t len)
327 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
333 if (ctrl_conn == NULL) {
334 printf("Not connected to wpa_supplicant - command dropped.\n");
337 len = sizeof(buf) - 1;
338 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
341 printf("'%s' command timed out.\n", cmd);
343 } else if (ret < 0) {
344 printf("'%s' command failed.\n", cmd);
355 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
357 return _wpa_ctrl_command(ctrl, cmd, 1);
361 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
363 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
364 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
368 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
370 return wpa_ctrl_command(ctrl, "PING");
374 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
380 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
381 if (ret < 0 || (size_t) ret >= sizeof(cmd))
383 return wpa_ctrl_command(ctrl, cmd);
387 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
389 return wpa_ctrl_command(ctrl, "MIB");
393 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
395 return wpa_ctrl_command(ctrl, "PMKSA");
399 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
406 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
408 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
413 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
420 static void wpa_cli_show_variables(void)
422 printf("set variables:\n"
423 " EAPOL::heldPeriod (EAPOL state machine held period, "
425 " EAPOL::authPeriod (EAPOL state machine authentication "
426 "period, in seconds)\n"
427 " EAPOL::startPeriod (EAPOL state machine start period, in "
429 " EAPOL::maxStart (EAPOL state machine maximum start "
431 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
433 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
434 " threshold\n\tpercentage)\n"
435 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
436 "security\n\tassociation in seconds)\n");
440 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
446 wpa_cli_show_variables();
451 printf("Invalid SET command: needs two arguments (variable "
452 "name and value)\n");
456 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
457 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
458 printf("Too long SET command.\n");
461 return wpa_ctrl_command(ctrl, cmd);
465 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
467 return wpa_ctrl_command(ctrl, "LOGOFF");
471 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
473 return wpa_ctrl_command(ctrl, "LOGON");
477 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
480 return wpa_ctrl_command(ctrl, "REASSOCIATE");
484 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
491 printf("Invalid PREAUTH command: needs one argument "
496 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
497 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
498 printf("Too long PREAUTH command.\n");
501 return wpa_ctrl_command(ctrl, cmd);
505 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
511 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
515 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
516 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
517 printf("Too long AP_SCAN command.\n");
520 return wpa_ctrl_command(ctrl, cmd);
524 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
531 printf("Invalid STKSTART command: needs one argument "
532 "(Peer STA MAC address)\n");
536 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
537 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
538 printf("Too long STKSTART command.\n");
541 return wpa_ctrl_command(ctrl, cmd);
545 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
551 printf("Invalid FT_DS command: needs one argument "
552 "(Target AP MAC address)\n");
556 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
557 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
558 printf("Too long FT_DS command.\n");
561 return wpa_ctrl_command(ctrl, cmd);
565 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
572 return wpa_ctrl_command(ctrl, "WPS_PBC");
576 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
577 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
578 printf("Too long WPS_PBC command.\n");
581 return wpa_ctrl_command(ctrl, cmd);
585 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
591 printf("Invalid WPS_PIN command: need one or two arguments:\n"
592 "- BSSID: use 'any' to select any\n"
593 "- PIN: optional, used only with devices that have no "
599 /* Use dynamically generated PIN (returned as reply) */
600 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
601 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
602 printf("Too long WPS_PIN command.\n");
605 return wpa_ctrl_command(ctrl, cmd);
608 /* Use hardcoded PIN from a label */
609 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
610 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
611 printf("Too long WPS_PIN command.\n");
614 return wpa_ctrl_command(ctrl, cmd);
618 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
624 if (argc != 1 && argc != 2) {
625 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
626 "- PIN to be verified\n");
631 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
634 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
636 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
637 printf("Too long WPS_CHECK_PIN command.\n");
640 return wpa_ctrl_command(ctrl, cmd);
644 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
647 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
651 #ifdef CONFIG_WPS_OOB
652 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
657 if (argc != 3 && argc != 4) {
658 printf("Invalid WPS_OOB command: need three or four "
660 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
661 "- PATH: path of OOB device like '/mnt'\n"
662 "- METHOD: OOB method 'pin-e' or 'pin-r', "
664 "- DEV_NAME: (only for NFC) device name like "
670 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
671 argv[0], argv[1], argv[2]);
673 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
674 argv[0], argv[1], argv[2], argv[3]);
675 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
676 printf("Too long WPS_OOB command.\n");
679 return wpa_ctrl_command(ctrl, cmd);
681 #endif /* CONFIG_WPS_OOB */
684 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
690 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
692 else if (argc == 5 || argc == 6) {
693 char ssid_hex[2 * 32 + 1];
694 char key_hex[2 * 64 + 1];
698 for (i = 0; i < 32; i++) {
699 if (argv[2][i] == '\0')
701 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
706 for (i = 0; i < 64; i++) {
707 if (argv[5][i] == '\0')
709 os_snprintf(&key_hex[i * 2], 3, "%02x",
714 res = os_snprintf(cmd, sizeof(cmd),
715 "WPS_REG %s %s %s %s %s %s",
716 argv[0], argv[1], ssid_hex, argv[3], argv[4],
719 printf("Invalid WPS_REG command: need two arguments:\n"
720 "- BSSID: use 'any' to select any\n"
722 printf("Alternatively, six arguments can be used to "
723 "reconfigure the AP:\n"
724 "- BSSID: use 'any' to select any\n"
727 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
728 "- new encr (NONE, WEP, TKIP, CCMP)\n"
733 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
734 printf("Too long WPS_REG command.\n");
737 return wpa_ctrl_command(ctrl, cmd);
741 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
746 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
747 return wpa_ctrl_command(ctrl, cmd);
749 return wpa_ctrl_command(ctrl, "WPS_ER_START");
753 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
756 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
761 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
768 printf("Invalid WPS_ER_PIN command: need at least two "
770 "- UUID: use 'any' to select any\n"
771 "- PIN: Enrollee PIN\n"
772 "optional: - Enrollee MAC address\n");
777 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
778 argv[0], argv[1], argv[2]);
780 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
782 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
783 printf("Too long WPS_ER_PIN command.\n");
786 return wpa_ctrl_command(ctrl, cmd);
790 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
797 printf("Invalid WPS_ER_PBC command: need one argument:\n"
798 "- UUID: Specify the Enrollee\n");
802 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
804 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
805 printf("Too long WPS_ER_PBC command.\n");
808 return wpa_ctrl_command(ctrl, cmd);
812 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
819 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
820 "- UUID: specify which AP to use\n"
825 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
827 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
828 printf("Too long WPS_ER_LEARN command.\n");
831 return wpa_ctrl_command(ctrl, cmd);
835 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
841 if (argc == 5 || argc == 6) {
842 char ssid_hex[2 * 32 + 1];
843 char key_hex[2 * 64 + 1];
847 for (i = 0; i < 32; i++) {
848 if (argv[2][i] == '\0')
850 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
855 for (i = 0; i < 64; i++) {
856 if (argv[5][i] == '\0')
858 os_snprintf(&key_hex[i * 2], 3, "%02x",
863 res = os_snprintf(cmd, sizeof(cmd),
864 "WPS_ER_CONFIG %s %s %s %s %s %s",
865 argv[0], argv[1], ssid_hex, argv[3], argv[4],
868 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
872 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
873 "- new encr (NONE, WEP, TKIP, CCMP)\n"
878 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
879 printf("Too long WPS_ER_CONFIG command.\n");
882 return wpa_ctrl_command(ctrl, cmd);
886 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
892 printf("Invalid IBSS_RSN command: needs one argument "
893 "(Peer STA MAC address)\n");
897 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
898 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
899 printf("Too long IBSS_RSN command.\n");
902 return wpa_ctrl_command(ctrl, cmd);
906 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
912 printf("Invalid LEVEL command: needs one argument (debug "
916 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
917 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
918 printf("Too long LEVEL command.\n");
921 return wpa_ctrl_command(ctrl, cmd);
925 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
927 char cmd[256], *pos, *end;
931 printf("Invalid IDENTITY command: needs two arguments "
932 "(network id and identity)\n");
936 end = cmd + sizeof(cmd);
938 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
940 if (ret < 0 || ret >= end - pos) {
941 printf("Too long IDENTITY 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 IDENTITY command.\n");
954 return wpa_ctrl_command(ctrl, cmd);
958 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
960 char cmd[256], *pos, *end;
964 printf("Invalid PASSWORD command: needs two arguments "
965 "(network id and password)\n");
969 end = cmd + sizeof(cmd);
971 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
973 if (ret < 0 || ret >= end - pos) {
974 printf("Too long PASSWORD command.\n");
978 for (i = 2; i < argc; i++) {
979 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
980 if (ret < 0 || ret >= end - pos) {
981 printf("Too long PASSWORD command.\n");
987 return wpa_ctrl_command(ctrl, cmd);
991 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
994 char cmd[256], *pos, *end;
998 printf("Invalid NEW_PASSWORD command: needs two arguments "
999 "(network id and password)\n");
1003 end = cmd + sizeof(cmd);
1005 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1007 if (ret < 0 || ret >= end - pos) {
1008 printf("Too long NEW_PASSWORD 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 NEW_PASSWORD command.\n");
1021 return wpa_ctrl_command(ctrl, cmd);
1025 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1027 char cmd[256], *pos, *end;
1031 printf("Invalid PIN command: needs two arguments "
1032 "(network id and pin)\n");
1036 end = cmd + sizeof(cmd);
1038 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1040 if (ret < 0 || ret >= end - pos) {
1041 printf("Too long PIN command.\n");
1045 for (i = 2; i < argc; i++) {
1046 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1047 if (ret < 0 || ret >= end - pos) {
1048 printf("Too long PIN command.\n");
1053 return wpa_ctrl_command(ctrl, cmd);
1057 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1059 char cmd[256], *pos, *end;
1063 printf("Invalid OTP command: needs two arguments (network "
1064 "id and password)\n");
1068 end = cmd + sizeof(cmd);
1070 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1072 if (ret < 0 || ret >= end - pos) {
1073 printf("Too long OTP command.\n");
1077 for (i = 2; i < argc; i++) {
1078 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1079 if (ret < 0 || ret >= end - pos) {
1080 printf("Too long OTP command.\n");
1086 return wpa_ctrl_command(ctrl, cmd);
1090 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1093 char cmd[256], *pos, *end;
1097 printf("Invalid PASSPHRASE command: needs two arguments "
1098 "(network id and passphrase)\n");
1102 end = cmd + sizeof(cmd);
1104 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1106 if (ret < 0 || ret >= end - pos) {
1107 printf("Too long PASSPHRASE command.\n");
1111 for (i = 2; i < argc; i++) {
1112 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1113 if (ret < 0 || ret >= end - pos) {
1114 printf("Too long PASSPHRASE command.\n");
1120 return wpa_ctrl_command(ctrl, cmd);
1124 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1126 char cmd[256], *pos, *end;
1130 printf("Invalid BSSID command: needs two arguments (network "
1135 end = cmd + sizeof(cmd);
1137 ret = os_snprintf(pos, end - pos, "BSSID");
1138 if (ret < 0 || ret >= end - pos) {
1139 printf("Too long BSSID command.\n");
1143 for (i = 0; i < argc; i++) {
1144 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1145 if (ret < 0 || ret >= end - pos) {
1146 printf("Too long BSSID command.\n");
1152 return wpa_ctrl_command(ctrl, cmd);
1156 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1159 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1163 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1170 printf("Invalid SELECT_NETWORK command: needs one argument "
1175 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1176 if (res < 0 || (size_t) res >= sizeof(cmd))
1178 cmd[sizeof(cmd) - 1] = '\0';
1180 return wpa_ctrl_command(ctrl, cmd);
1184 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1191 printf("Invalid ENABLE_NETWORK command: needs one argument "
1196 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1197 if (res < 0 || (size_t) res >= sizeof(cmd))
1199 cmd[sizeof(cmd) - 1] = '\0';
1201 return wpa_ctrl_command(ctrl, cmd);
1205 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1212 printf("Invalid DISABLE_NETWORK command: needs one argument "
1217 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1218 if (res < 0 || (size_t) res >= sizeof(cmd))
1220 cmd[sizeof(cmd) - 1] = '\0';
1222 return wpa_ctrl_command(ctrl, cmd);
1226 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1229 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1233 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1240 printf("Invalid REMOVE_NETWORK command: needs one argument "
1245 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1246 if (res < 0 || (size_t) res >= sizeof(cmd))
1248 cmd[sizeof(cmd) - 1] = '\0';
1250 return wpa_ctrl_command(ctrl, cmd);
1254 static void wpa_cli_show_network_variables(void)
1256 printf("set_network variables:\n"
1257 " ssid (network name, SSID)\n"
1258 " psk (WPA passphrase or pre-shared key)\n"
1259 " key_mgmt (key management protocol)\n"
1260 " identity (EAP identity)\n"
1261 " password (EAP password)\n"
1264 "Note: Values are entered in the same format as the "
1265 "configuration file is using,\n"
1266 "i.e., strings values need to be inside double quotation "
1268 "For example: set_network 1 ssid \"network name\"\n"
1270 "Please see wpa_supplicant.conf documentation for full list "
1271 "of\navailable variables.\n");
1275 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1282 wpa_cli_show_network_variables();
1287 printf("Invalid SET_NETWORK command: needs three arguments\n"
1288 "(network id, variable name, and value)\n");
1292 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1293 argv[0], argv[1], argv[2]);
1294 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1295 printf("Too long SET_NETWORK command.\n");
1298 return wpa_ctrl_command(ctrl, cmd);
1302 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1309 wpa_cli_show_network_variables();
1314 printf("Invalid GET_NETWORK command: needs two arguments\n"
1315 "(network id and variable name)\n");
1319 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1321 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1322 printf("Too long GET_NETWORK command.\n");
1325 return wpa_ctrl_command(ctrl, cmd);
1329 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1332 return wpa_ctrl_command(ctrl, "DISCONNECT");
1336 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1339 return wpa_ctrl_command(ctrl, "RECONNECT");
1343 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1346 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1350 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1352 return wpa_ctrl_command(ctrl, "SCAN");
1356 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1359 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1363 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1369 printf("Invalid BSS command: need one argument (index or "
1374 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1375 if (res < 0 || (size_t) res >= sizeof(cmd))
1377 cmd[sizeof(cmd) - 1] = '\0';
1379 return wpa_ctrl_command(ctrl, cmd);
1383 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1389 if (argc < 1 || argc > 2) {
1390 printf("Invalid GET_CAPABILITY command: need either one or "
1395 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1396 printf("Invalid GET_CAPABILITY command: second argument, "
1397 "if any, must be 'strict'\n");
1401 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1402 (argc == 2) ? " strict" : "");
1403 if (res < 0 || (size_t) res >= sizeof(cmd))
1405 cmd[sizeof(cmd) - 1] = '\0';
1407 return wpa_ctrl_command(ctrl, cmd);
1411 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1413 printf("Available interfaces:\n");
1414 return wpa_ctrl_command(ctrl, "INTERFACES");
1418 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1421 wpa_cli_list_interfaces(ctrl);
1425 wpa_cli_close_connection();
1426 os_free(ctrl_ifname);
1427 ctrl_ifname = os_strdup(argv[0]);
1429 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1430 printf("Connected to interface '%s.\n", ctrl_ifname);
1432 printf("Could not connect to interface '%s' - re-trying\n",
1439 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1442 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1446 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1449 return wpa_ctrl_command(ctrl, "TERMINATE");
1453 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1460 printf("Invalid INTERFACE_ADD command: needs at least one "
1461 "argument (interface name)\n"
1462 "All arguments: ifname confname driver ctrl_interface "
1463 "driver_param bridge_name\n");
1468 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1469 * <driver_param>TAB<bridge_name>
1471 res = os_snprintf(cmd, sizeof(cmd),
1472 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1474 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1475 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1476 argc > 5 ? argv[5] : "");
1477 if (res < 0 || (size_t) res >= sizeof(cmd))
1479 cmd[sizeof(cmd) - 1] = '\0';
1480 return wpa_ctrl_command(ctrl, cmd);
1484 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1491 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1492 "(interface name)\n");
1496 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1497 if (res < 0 || (size_t) res >= sizeof(cmd))
1499 cmd[sizeof(cmd) - 1] = '\0';
1500 return wpa_ctrl_command(ctrl, cmd);
1504 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1507 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1512 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1516 printf("Invalid 'sta' command - exactly one argument, STA "
1517 "address, is required.\n");
1520 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1521 return wpa_ctrl_command(ctrl, buf);
1525 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1526 char *addr, size_t addr_len)
1528 char buf[4096], *pos;
1532 if (ctrl_conn == NULL) {
1533 printf("Not connected to hostapd - command dropped.\n");
1536 len = sizeof(buf) - 1;
1537 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1540 printf("'%s' command timed out.\n", cmd);
1542 } else if (ret < 0) {
1543 printf("'%s' command failed.\n", cmd);
1548 if (memcmp(buf, "FAIL", 4) == 0)
1553 while (*pos != '\0' && *pos != '\n')
1556 os_strlcpy(addr, buf, addr_len);
1561 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1563 char addr[32], cmd[64];
1565 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1568 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1569 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1573 #endif /* CONFIG_AP */
1576 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1578 return wpa_ctrl_command(ctrl, "SUSPEND");
1582 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1584 return wpa_ctrl_command(ctrl, "RESUME");
1588 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1590 return wpa_ctrl_command(ctrl, "DROP_SA");
1594 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1600 printf("Invalid ROAM command: needs one argument "
1601 "(target AP's BSSID)\n");
1605 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1606 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1607 printf("Too long ROAM command.\n");
1610 return wpa_ctrl_command(ctrl, cmd);
1616 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1622 return wpa_ctrl_command(ctrl, "P2P_FIND");
1625 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1628 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1629 if (res < 0 || (size_t) res >= sizeof(cmd))
1631 cmd[sizeof(cmd) - 1] = '\0';
1632 return wpa_ctrl_command(ctrl, cmd);
1636 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1639 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1643 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1650 printf("Invalid P2P_CONNECT command: needs at least two "
1651 "arguments (address and pbc/PIN)\n");
1656 res = os_snprintf(cmd, sizeof(cmd),
1657 "P2P_CONNECT %s %s %s %s %s",
1658 argv[0], argv[1], argv[2], argv[3],
1661 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1662 argv[0], argv[1], argv[2], argv[3]);
1664 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1665 argv[0], argv[1], argv[2]);
1667 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1669 if (res < 0 || (size_t) res >= sizeof(cmd))
1671 cmd[sizeof(cmd) - 1] = '\0';
1672 return wpa_ctrl_command(ctrl, cmd);
1676 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1683 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1685 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1686 if (res < 0 || (size_t) res >= sizeof(cmd))
1688 cmd[sizeof(cmd) - 1] = '\0';
1689 return wpa_ctrl_command(ctrl, cmd);
1693 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1700 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1701 "(interface name)\n");
1705 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
1706 if (res < 0 || (size_t) res >= sizeof(cmd))
1708 cmd[sizeof(cmd) - 1] = '\0';
1709 return wpa_ctrl_command(ctrl, cmd);
1713 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1720 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
1722 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", argv[0]);
1723 if (res < 0 || (size_t) res >= sizeof(cmd))
1725 cmd[sizeof(cmd) - 1] = '\0';
1726 return wpa_ctrl_command(ctrl, cmd);
1730 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1737 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1738 "(address and config method\n"
1739 "(display, keypad, or pbc)\n");
1743 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
1745 if (res < 0 || (size_t) res >= sizeof(cmd))
1747 cmd[sizeof(cmd) - 1] = '\0';
1748 return wpa_ctrl_command(ctrl, cmd);
1752 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1755 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1759 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1765 if (argc != 2 && argc != 4) {
1766 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1767 "arguments (address and TLVs) or four arguments "
1768 "(address, \"upnp\", version, search target "
1774 res = os_snprintf(cmd, sizeof(cmd),
1775 "P2P_SERV_DISC_REQ %s %s %s %s",
1776 argv[0], argv[1], argv[2], argv[3]);
1778 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
1780 if (res < 0 || (size_t) res >= sizeof(cmd))
1782 cmd[sizeof(cmd) - 1] = '\0';
1783 return wpa_ctrl_command(ctrl, cmd);
1787 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1788 int argc, char *argv[])
1794 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1795 "argument (pending request identifier)\n");
1799 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
1801 if (res < 0 || (size_t) res >= sizeof(cmd))
1803 cmd[sizeof(cmd) - 1] = '\0';
1804 return wpa_ctrl_command(ctrl, cmd);
1808 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1815 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1816 "arguments (freq, address, dialog token, and TLVs)\n");
1820 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1821 argv[0], argv[1], argv[2], argv[3]);
1822 if (res < 0 || (size_t) res >= sizeof(cmd))
1824 cmd[sizeof(cmd) - 1] = '\0';
1825 return wpa_ctrl_command(ctrl, cmd);
1829 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1832 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1836 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1837 int argc, char *argv[])
1843 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1844 "argument (external processing: 0/1)\n");
1848 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
1850 if (res < 0 || (size_t) res >= sizeof(cmd))
1852 cmd[sizeof(cmd) - 1] = '\0';
1853 return wpa_ctrl_command(ctrl, cmd);
1857 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1860 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1864 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1870 if (argc != 3 && argc != 4) {
1871 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1877 res = os_snprintf(cmd, sizeof(cmd),
1878 "P2P_SERVICE_ADD %s %s %s %s",
1879 argv[0], argv[1], argv[2], argv[3]);
1881 res = os_snprintf(cmd, sizeof(cmd),
1882 "P2P_SERVICE_ADD %s %s %s",
1883 argv[0], argv[1], argv[2]);
1884 if (res < 0 || (size_t) res >= sizeof(cmd))
1886 cmd[sizeof(cmd) - 1] = '\0';
1887 return wpa_ctrl_command(ctrl, cmd);
1891 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1897 if (argc != 2 && argc != 3) {
1898 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1904 res = os_snprintf(cmd, sizeof(cmd),
1905 "P2P_SERVICE_DEL %s %s %s",
1906 argv[0], argv[1], argv[2]);
1908 res = os_snprintf(cmd, sizeof(cmd),
1909 "P2P_SERVICE_DEL %s %s",
1911 if (res < 0 || (size_t) res >= sizeof(cmd))
1913 cmd[sizeof(cmd) - 1] = '\0';
1914 return wpa_ctrl_command(ctrl, cmd);
1918 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1919 int argc, char *argv[])
1925 printf("Invalid P2P_REJECT command: needs one argument "
1926 "(peer address)\n");
1930 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
1931 if (res < 0 || (size_t) res >= sizeof(cmd))
1933 cmd[sizeof(cmd) - 1] = '\0';
1934 return wpa_ctrl_command(ctrl, cmd);
1938 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1939 int argc, char *argv[])
1945 printf("Invalid P2P_INVITE command: needs at least one "
1951 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
1952 argv[0], argv[1], argv[2]);
1954 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
1957 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
1958 if (res < 0 || (size_t) res >= sizeof(cmd))
1960 cmd[sizeof(cmd) - 1] = '\0';
1961 return wpa_ctrl_command(ctrl, cmd);
1965 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
1969 printf("Invalid 'p2p_peer' command - exactly one argument, "
1970 "P2P peer device address, is required.\n");
1973 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
1974 return wpa_ctrl_command(ctrl, buf);
1978 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
1979 char *addr, size_t addr_len,
1982 char buf[4096], *pos;
1986 if (ctrl_conn == NULL)
1988 len = sizeof(buf) - 1;
1989 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1992 printf("'%s' command timed out.\n", cmd);
1994 } else if (ret < 0) {
1995 printf("'%s' command failed.\n", cmd);
2000 if (memcmp(buf, "FAIL", 4) == 0)
2004 while (*pos != '\0' && *pos != '\n')
2007 os_strlcpy(addr, buf, addr_len);
2008 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2009 printf("%s\n", addr);
2014 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2016 char addr[32], cmd[64];
2019 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2021 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2022 addr, sizeof(addr), discovered))
2025 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2026 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2033 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2039 printf("Invalid P2P_SET command: needs two arguments (field, "
2044 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2045 if (res < 0 || (size_t) res >= sizeof(cmd))
2047 cmd[sizeof(cmd) - 1] = '\0';
2048 return wpa_ctrl_command(ctrl, cmd);
2052 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2054 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2058 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2064 if (argc != 0 && argc != 2 && argc != 4) {
2065 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2066 "(preferred duration, interval; in microsecods).\n"
2067 "Optional second pair can be used to provide "
2068 "acceptable values.\n");
2073 res = os_snprintf(cmd, sizeof(cmd),
2074 "P2P_PRESENCE_REQ %s %s %s %s",
2075 argv[0], argv[1], argv[2], argv[3]);
2077 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2080 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2081 if (res < 0 || (size_t) res >= sizeof(cmd))
2083 cmd[sizeof(cmd) - 1] = '\0';
2084 return wpa_ctrl_command(ctrl, cmd);
2088 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2094 if (argc != 0 && argc != 2) {
2095 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2096 "(availability period, availability interval; in "
2098 "Extended Listen Timing can be cancelled with this "
2099 "command when used without parameters.\n");
2104 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2107 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2108 if (res < 0 || (size_t) res >= sizeof(cmd))
2110 cmd[sizeof(cmd) - 1] = '\0';
2111 return wpa_ctrl_command(ctrl, cmd);
2114 #endif /* CONFIG_P2P */
2117 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2124 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2125 "(0/1 = disable/enable automatic reconnection)\n");
2128 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2129 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2130 printf("Too long STA_AUTOCONNECT command.\n");
2133 return wpa_ctrl_command(ctrl, cmd);
2137 enum wpa_cli_cmd_flags {
2138 cli_cmd_flag_none = 0x00,
2139 cli_cmd_flag_sensitive = 0x01
2142 struct wpa_cli_cmd {
2144 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2145 enum wpa_cli_cmd_flags flags;
2149 static struct wpa_cli_cmd wpa_cli_commands[] = {
2150 { "status", wpa_cli_cmd_status,
2152 "[verbose] = get current WPA/EAPOL/EAP status" },
2153 { "ping", wpa_cli_cmd_ping,
2155 "= pings wpa_supplicant" },
2156 { "note", wpa_cli_cmd_note,
2158 "<text> = add a note to wpa_supplicant debug log" },
2159 { "mib", wpa_cli_cmd_mib,
2161 "= get MIB variables (dot1x, dot11)" },
2162 { "help", wpa_cli_cmd_help,
2164 "= show this usage help" },
2165 { "interface", wpa_cli_cmd_interface,
2167 "[ifname] = show interfaces/select interface" },
2168 { "level", wpa_cli_cmd_level,
2170 "<debug level> = change debug level" },
2171 { "license", wpa_cli_cmd_license,
2173 "= show full wpa_cli license" },
2174 { "quit", wpa_cli_cmd_quit,
2177 { "set", wpa_cli_cmd_set,
2179 "= set variables (shows list of variables when run without "
2181 { "logon", wpa_cli_cmd_logon,
2183 "= IEEE 802.1X EAPOL state machine logon" },
2184 { "logoff", wpa_cli_cmd_logoff,
2186 "= IEEE 802.1X EAPOL state machine logoff" },
2187 { "pmksa", wpa_cli_cmd_pmksa,
2189 "= show PMKSA cache" },
2190 { "reassociate", wpa_cli_cmd_reassociate,
2192 "= force reassociation" },
2193 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2195 "<BSSID> = force preauthentication" },
2196 { "identity", wpa_cli_cmd_identity,
2198 "<network id> <identity> = configure identity for an SSID" },
2199 { "password", wpa_cli_cmd_password,
2200 cli_cmd_flag_sensitive,
2201 "<network id> <password> = configure password for an SSID" },
2202 { "new_password", wpa_cli_cmd_new_password,
2203 cli_cmd_flag_sensitive,
2204 "<network id> <password> = change password for an SSID" },
2205 { "pin", wpa_cli_cmd_pin,
2206 cli_cmd_flag_sensitive,
2207 "<network id> <pin> = configure pin for an SSID" },
2208 { "otp", wpa_cli_cmd_otp,
2209 cli_cmd_flag_sensitive,
2210 "<network id> <password> = configure one-time-password for an SSID"
2212 { "passphrase", wpa_cli_cmd_passphrase,
2213 cli_cmd_flag_sensitive,
2214 "<network id> <passphrase> = configure private key passphrase\n"
2216 { "bssid", wpa_cli_cmd_bssid,
2218 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2219 { "list_networks", wpa_cli_cmd_list_networks,
2221 "= list configured networks" },
2222 { "select_network", wpa_cli_cmd_select_network,
2224 "<network id> = select a network (disable others)" },
2225 { "enable_network", wpa_cli_cmd_enable_network,
2227 "<network id> = enable a network" },
2228 { "disable_network", wpa_cli_cmd_disable_network,
2230 "<network id> = disable a network" },
2231 { "add_network", wpa_cli_cmd_add_network,
2233 "= add a network" },
2234 { "remove_network", wpa_cli_cmd_remove_network,
2236 "<network id> = remove a network" },
2237 { "set_network", wpa_cli_cmd_set_network,
2238 cli_cmd_flag_sensitive,
2239 "<network id> <variable> <value> = set network variables (shows\n"
2240 " list of variables when run without arguments)" },
2241 { "get_network", wpa_cli_cmd_get_network,
2243 "<network id> <variable> = get network variables" },
2244 { "save_config", wpa_cli_cmd_save_config,
2246 "= save the current configuration" },
2247 { "disconnect", wpa_cli_cmd_disconnect,
2249 "= disconnect and wait for reassociate/reconnect command before\n"
2251 { "reconnect", wpa_cli_cmd_reconnect,
2253 "= like reassociate, but only takes effect if already disconnected"
2255 { "scan", wpa_cli_cmd_scan,
2257 "= request new BSS scan" },
2258 { "scan_results", wpa_cli_cmd_scan_results,
2260 "= get latest scan results" },
2261 { "bss", wpa_cli_cmd_bss,
2263 "<<idx> | <bssid>> = get detailed scan result info" },
2264 { "get_capability", wpa_cli_cmd_get_capability,
2266 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2267 { "reconfigure", wpa_cli_cmd_reconfigure,
2269 "= force wpa_supplicant to re-read its configuration file" },
2270 { "terminate", wpa_cli_cmd_terminate,
2272 "= terminate wpa_supplicant" },
2273 { "interface_add", wpa_cli_cmd_interface_add,
2275 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2276 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2278 { "interface_remove", wpa_cli_cmd_interface_remove,
2280 "<ifname> = removes the interface" },
2281 { "interface_list", wpa_cli_cmd_interface_list,
2283 "= list available interfaces" },
2284 { "ap_scan", wpa_cli_cmd_ap_scan,
2286 "<value> = set ap_scan parameter" },
2287 { "stkstart", wpa_cli_cmd_stkstart,
2289 "<addr> = request STK negotiation with <addr>" },
2290 { "ft_ds", wpa_cli_cmd_ft_ds,
2292 "<addr> = request over-the-DS FT with <addr>" },
2293 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2295 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2296 { "wps_pin", wpa_cli_cmd_wps_pin,
2297 cli_cmd_flag_sensitive,
2298 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2300 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2301 cli_cmd_flag_sensitive,
2302 "<PIN> = verify PIN checksum" },
2303 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2304 "Cancels the pending WPS operation" },
2305 #ifdef CONFIG_WPS_OOB
2306 { "wps_oob", wpa_cli_cmd_wps_oob,
2307 cli_cmd_flag_sensitive,
2308 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2309 #endif /* CONFIG_WPS_OOB */
2310 { "wps_reg", wpa_cli_cmd_wps_reg,
2311 cli_cmd_flag_sensitive,
2312 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2313 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2315 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2316 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2318 "= stop Wi-Fi Protected Setup External Registrar" },
2319 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2320 cli_cmd_flag_sensitive,
2321 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2322 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2324 "<UUID> = accept an Enrollee PBC using External Registrar" },
2325 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2326 cli_cmd_flag_sensitive,
2327 "<UUID> <PIN> = learn AP configuration" },
2328 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2329 cli_cmd_flag_sensitive,
2330 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2331 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2333 "<addr> = request RSN authentication with <addr> in IBSS" },
2335 { "sta", wpa_cli_cmd_sta,
2337 "<addr> = get information about an associated station (AP)" },
2338 { "all_sta", wpa_cli_cmd_all_sta,
2340 "= get information about all associated stations (AP)" },
2341 #endif /* CONFIG_AP */
2342 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2343 "= notification of suspend/hibernate" },
2344 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2345 "= notification of resume/thaw" },
2346 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2347 "= drop SA without deauth/disassoc (test command)" },
2348 { "roam", wpa_cli_cmd_roam,
2350 "<addr> = roam to the specified BSS" },
2352 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2353 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2354 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2355 "= stop P2P Devices search" },
2356 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2357 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2358 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2359 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2360 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2361 "<ifname> = remote P2P group interface (terminate group if GO)" },
2362 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2363 "= add a new P2P group (local end as GO)" },
2364 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2365 "<addr> <method> = request provisioning discovery" },
2366 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2368 "= get the passphrase for a group (GO only)" },
2369 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2371 "<addr> <TLVs> = schedule service discovery request" },
2372 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2374 "<id> = cancel pending service discovery request" },
2375 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2377 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2378 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2380 "= indicate change in local services" },
2381 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2383 "<external> = set external processing of service discovery" },
2384 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2386 "= remove all stored service entries" },
2387 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2389 "<bonjour|upnp> <query|version> <response|service> = add a local "
2391 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2393 "<bonjour|upnp> <query|version> [|service] = remove a local "
2395 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2397 "<addr> = reject connection attempts from a specific peer" },
2398 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2400 "<cmd> [peer=addr] = invite peer" },
2401 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2402 "[discovered] = list known (optionally, only fully discovered) P2P "
2404 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2405 "<address> = show information about known P2P peer" },
2406 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2407 "<field> <value> = set a P2P parameter" },
2408 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2409 "= flush P2P state" },
2410 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2411 "[<duration> <interval>] [<duration> <interval>] = request GO "
2413 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2414 "[<period> <interval>] = set extended listen timing" },
2415 #endif /* CONFIG_P2P */
2416 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2417 "<0/1> = disable/enable automatic reconnection" },
2418 { NULL, NULL, cli_cmd_flag_none, NULL }
2423 * Prints command usage, lines are padded with the specified string.
2425 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2430 printf("%s%s ", pad, cmd->cmd);
2431 for (n = 0; (c = cmd->usage[n]); n++) {
2440 static void print_help(void)
2443 printf("commands:\n");
2444 for (n = 0; wpa_cli_commands[n].cmd; n++)
2445 print_cmd_help(&wpa_cli_commands[n], " ");
2449 #ifdef CONFIG_READLINE
2450 static int cmd_has_sensitive_data(const char *cmd)
2452 const char *c, *delim;
2456 delim = os_strchr(cmd, ' ');
2460 len = os_strlen(cmd);
2462 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2463 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2464 return (wpa_cli_commands[n].flags &
2465 cli_cmd_flag_sensitive);
2469 #endif /* CONFIG_READLINE */
2472 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2474 struct wpa_cli_cmd *cmd, *match = NULL;
2479 cmd = wpa_cli_commands;
2481 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2484 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2485 /* we have an exact match */
2495 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2496 cmd = wpa_cli_commands;
2498 if (os_strncasecmp(cmd->cmd, argv[0],
2499 os_strlen(argv[0])) == 0) {
2500 printf(" %s", cmd->cmd);
2506 } else if (count == 0) {
2507 printf("Unknown command '%s'\n", argv[0]);
2510 ret = match->handler(ctrl, argc - 1, &argv[1]);
2517 static int str_match(const char *a, const char *b)
2519 return os_strncmp(a, b, os_strlen(b)) == 0;
2523 static int wpa_cli_exec(const char *program, const char *arg1,
2531 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2532 cmd = os_malloc(len);
2535 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2536 if (res < 0 || (size_t) res >= len) {
2540 cmd[len - 1] = '\0';
2542 if (system(cmd) < 0)
2544 #endif /* _WIN32_WCE */
2551 static void wpa_cli_action_process(const char *msg)
2554 char *copy = NULL, *id, *pos2;
2559 pos = os_strchr(pos, '>');
2566 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2568 os_unsetenv("WPA_ID");
2569 os_unsetenv("WPA_ID_STR");
2570 os_unsetenv("WPA_CTRL_DIR");
2572 pos = os_strstr(pos, "[id=");
2574 copy = os_strdup(pos + 4);
2578 while (*pos2 && *pos2 != ' ')
2582 os_setenv("WPA_ID", id, 1);
2583 while (*pos2 && *pos2 != '=')
2588 while (*pos2 && *pos2 != ']')
2591 os_setenv("WPA_ID_STR", id, 1);
2595 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2597 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2598 wpa_cli_connected = 1;
2599 wpa_cli_last_id = new_id;
2600 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2602 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2603 if (wpa_cli_connected) {
2604 wpa_cli_connected = 0;
2605 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2607 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2608 wpa_cli_exec(action_file, ctrl_ifname, pos);
2609 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2610 wpa_cli_exec(action_file, ctrl_ifname, pos);
2611 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2612 wpa_cli_exec(action_file, ctrl_ifname, pos);
2613 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2614 wpa_cli_exec(action_file, ctrl_ifname, pos);
2615 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2616 wpa_cli_exec(action_file, ctrl_ifname, pos);
2617 } else if (str_match(pos, WPS_EVENT_FAIL)) {
2618 wpa_cli_exec(action_file, ctrl_ifname, pos);
2619 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2620 printf("wpa_supplicant is terminating - stop monitoring\n");
2626 #ifndef CONFIG_ANSI_C_EXTRA
2627 static void wpa_cli_action_cb(char *msg, size_t len)
2629 wpa_cli_action_process(msg);
2631 #endif /* CONFIG_ANSI_C_EXTRA */
2634 static void wpa_cli_reconnect(void)
2636 wpa_cli_close_connection();
2637 wpa_cli_open_connection(ctrl_ifname, 1);
2641 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
2645 if (ctrl_conn == NULL) {
2646 wpa_cli_reconnect();
2649 while (wpa_ctrl_pending(ctrl) > 0) {
2651 size_t len = sizeof(buf) - 1;
2652 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2655 wpa_cli_action_process(buf);
2657 if (wpa_cli_show_event(buf)) {
2658 if (in_read && first)
2661 printf("%s\n", buf);
2666 printf("Could not read pending message.\n");
2671 if (wpa_ctrl_pending(ctrl) < 0) {
2672 printf("Connection to wpa_supplicant lost - trying to "
2674 wpa_cli_reconnect();
2679 #ifdef CONFIG_READLINE
2680 static char * wpa_cli_cmd_gen(const char *text, int state)
2687 len = os_strlen(text);
2690 while ((cmd = wpa_cli_commands[i].cmd)) {
2692 if (os_strncasecmp(cmd, text, len) == 0)
2700 static char * wpa_cli_dummy_gen(const char *text, int state)
2704 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2705 const char *cmd = wpa_cli_commands[i].cmd;
2706 size_t len = os_strlen(cmd);
2707 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
2708 rl_line_buffer[len] == ' ') {
2709 printf("\n%s\n", wpa_cli_commands[i].usage);
2715 rl_attempted_completion_over = 1;
2720 static char * wpa_cli_status_gen(const char *text, int state)
2730 len = os_strlen(text);
2733 while ((t = options[i])) {
2735 if (os_strncasecmp(t, text, len) == 0)
2739 rl_attempted_completion_over = 1;
2744 static char ** wpa_cli_completion(const char *text, int start, int end)
2746 char * (*func)(const char *text, int state);
2749 func = wpa_cli_cmd_gen;
2750 else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
2751 func = wpa_cli_status_gen;
2753 func = wpa_cli_dummy_gen;
2754 return rl_completion_matches(text, func);
2756 #endif /* CONFIG_READLINE */
2759 static void wpa_cli_interactive(void)
2762 char cmdbuf[256], *cmd, *argv[max_args], *pos;
2764 #ifdef CONFIG_READLINE
2765 char *home, *hfile = NULL;
2766 #endif /* CONFIG_READLINE */
2768 printf("\nInteractive mode\n\n");
2770 #ifdef CONFIG_READLINE
2771 rl_attempted_completion_function = wpa_cli_completion;
2772 home = getenv("HOME");
2774 const char *fname = ".wpa_cli_history";
2775 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
2776 hfile = os_malloc(hfile_len);
2779 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
2781 if (res >= 0 && res < hfile_len) {
2782 hfile[hfile_len - 1] = '\0';
2783 read_history(hfile);
2784 stifle_history(100);
2788 #endif /* CONFIG_READLINE */
2791 wpa_cli_recv_pending(mon_conn, 0, 0);
2792 #ifndef CONFIG_NATIVE_WINDOWS
2793 alarm(ping_interval);
2794 #endif /* CONFIG_NATIVE_WINDOWS */
2795 #ifdef CONFIG_WPA_CLI_FORK
2797 kill(mon_pid, SIGUSR1);
2798 #endif /* CONFIG_WPA_CLI_FORK */
2799 #ifdef CONFIG_READLINE
2800 cmd = readline("> ");
2803 while (next_history())
2805 h = previous_history();
2806 if (h == NULL || os_strcmp(cmd, h->line) != 0)
2810 #else /* CONFIG_READLINE */
2812 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
2813 #endif /* CONFIG_READLINE */
2814 #ifndef CONFIG_NATIVE_WINDOWS
2816 #endif /* CONFIG_NATIVE_WINDOWS */
2819 wpa_cli_recv_pending(mon_conn, 0, 0);
2821 while (*pos != '\0') {
2837 if (argc == max_args)
2840 char *pos2 = os_strrchr(pos, '"');
2844 while (*pos != '\0' && *pos != ' ')
2850 wpa_request(ctrl_conn, argc, argv);
2854 #ifdef CONFIG_WPA_CLI_FORK
2856 kill(mon_pid, SIGUSR2);
2857 #endif /* CONFIG_WPA_CLI_FORK */
2858 } while (!wpa_cli_quit);
2860 #ifdef CONFIG_READLINE
2862 /* Save command history, excluding lines that may contain
2866 while ((h = current_history())) {
2868 while (*p == ' ' || *p == '\t')
2870 if (cmd_has_sensitive_data(p)) {
2871 h = remove_history(where_history());
2881 write_history(hfile);
2884 #endif /* CONFIG_READLINE */
2888 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2890 #ifdef CONFIG_ANSI_C_EXTRA
2891 /* TODO: ANSI C version(?) */
2892 printf("Action processing not supported in ANSI C build.\n");
2893 #else /* CONFIG_ANSI_C_EXTRA */
2897 char buf[256]; /* note: large enough to fit in unsolicited messages */
2900 fd = wpa_ctrl_get_fd(ctrl);
2902 while (!wpa_cli_quit) {
2905 tv.tv_sec = ping_interval;
2907 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2908 if (res < 0 && errno != EINTR) {
2913 if (FD_ISSET(fd, &rfds))
2914 wpa_cli_recv_pending(ctrl, 0, 1);
2916 /* verify that connection is still working */
2917 len = sizeof(buf) - 1;
2918 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2919 wpa_cli_action_cb) < 0 ||
2920 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2921 printf("wpa_supplicant did not reply to PING "
2922 "command - exiting\n");
2927 #endif /* CONFIG_ANSI_C_EXTRA */
2931 static void wpa_cli_cleanup(void)
2933 wpa_cli_close_connection();
2935 os_daemonize_terminate(pid_file);
2937 os_program_deinit();
2940 static void wpa_cli_terminate(int sig)
2947 #ifdef CONFIG_WPA_CLI_FORK
2948 static void wpa_cli_usr1(int sig)
2952 #endif /* CONFIG_WPA_CLI_FORK */
2955 #ifndef CONFIG_NATIVE_WINDOWS
2956 static void wpa_cli_alarm(int sig)
2958 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2959 printf("Connection to wpa_supplicant lost - trying to "
2961 wpa_cli_close_connection();
2964 wpa_cli_reconnect();
2966 wpa_cli_recv_pending(mon_conn, 1, 0);
2967 alarm(ping_interval);
2969 #endif /* CONFIG_NATIVE_WINDOWS */
2972 static char * wpa_cli_get_default_ifname(void)
2974 char *ifname = NULL;
2976 #ifdef CONFIG_CTRL_IFACE_UNIX
2977 struct dirent *dent;
2978 DIR *dir = opendir(ctrl_iface_dir);
2981 while ((dent = readdir(dir))) {
2982 #ifdef _DIRENT_HAVE_D_TYPE
2984 * Skip the file if it is not a socket. Also accept
2985 * DT_UNKNOWN (0) in case the C library or underlying
2986 * file system does not support d_type.
2988 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2990 #endif /* _DIRENT_HAVE_D_TYPE */
2991 if (os_strcmp(dent->d_name, ".") == 0 ||
2992 os_strcmp(dent->d_name, "..") == 0)
2994 printf("Selected interface '%s'\n", dent->d_name);
2995 ifname = os_strdup(dent->d_name);
2999 #endif /* CONFIG_CTRL_IFACE_UNIX */
3001 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3002 char buf[2048], *pos;
3004 struct wpa_ctrl *ctrl;
3007 ctrl = wpa_ctrl_open(NULL);
3011 len = sizeof(buf) - 1;
3012 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3015 pos = os_strchr(buf, '\n');
3018 ifname = os_strdup(buf);
3020 wpa_ctrl_close(ctrl);
3021 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3027 int main(int argc, char *argv[])
3029 int warning_displayed = 0;
3033 const char *global = NULL;
3035 if (os_program_init())
3039 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3044 action_file = optarg;
3053 ping_interval = atoi(optarg);
3059 printf("%s\n", wpa_cli_version);
3062 os_free(ctrl_ifname);
3063 ctrl_ifname = os_strdup(optarg);
3066 ctrl_iface_dir = optarg;
3077 interactive = (argc == optind) && (action_file == NULL);
3080 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3083 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3084 ctrl_conn = wpa_ctrl_open(NULL);
3085 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3086 ctrl_conn = wpa_ctrl_open(global);
3087 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3088 if (ctrl_conn == NULL) {
3089 perror("Failed to connect to wpa_supplicant - "
3096 signal(SIGINT, wpa_cli_terminate);
3097 signal(SIGTERM, wpa_cli_terminate);
3098 #endif /* _WIN32_WCE */
3099 #ifndef CONFIG_NATIVE_WINDOWS
3100 signal(SIGALRM, wpa_cli_alarm);
3101 #endif /* CONFIG_NATIVE_WINDOWS */
3102 #ifdef CONFIG_WPA_CLI_FORK
3103 signal(SIGUSR1, wpa_cli_usr1);
3104 #endif /* CONFIG_WPA_CLI_FORK */
3106 if (ctrl_ifname == NULL)
3107 ctrl_ifname = wpa_cli_get_default_ifname();
3111 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3112 if (warning_displayed)
3113 printf("Connection established.\n");
3117 if (!warning_displayed) {
3118 printf("Could not connect to wpa_supplicant - "
3120 warning_displayed = 1;
3127 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3128 perror("Failed to connect to wpa_supplicant - "
3134 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3135 wpa_cli_attached = 1;
3137 printf("Warning: Failed to attach to "
3138 "wpa_supplicant.\n");
3144 if (daemonize && os_daemonize(pid_file))
3148 wpa_cli_interactive();
3149 else if (action_file)
3150 wpa_cli_action(ctrl_conn);
3152 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3154 os_free(ctrl_ifname);
3160 #else /* CONFIG_CTRL_IFACE */
3161 int main(int argc, char *argv[])
3163 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3166 #endif /* CONFIG_CTRL_IFACE */