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 #ifdef CONFIG_WPA_CLI_FORK
131 static int in_query = 0;
133 static void wpa_cli_monitor_sig(int sig)
137 else if (sig == SIGUSR2)
141 static void wpa_cli_monitor(void)
144 size_t len = sizeof(buf) - 1;
148 signal(SIGUSR1, wpa_cli_monitor_sig);
149 signal(SIGUSR2, wpa_cli_monitor_sig);
152 int s = wpa_ctrl_get_fd(mon_conn);
157 if (select(s + 1, &rfds, NULL, NULL, &tv) < 0) {
163 if (mon_conn == NULL)
165 if (FD_ISSET(s, &rfds)) {
166 len = sizeof(buf) - 1;
167 int res = wpa_ctrl_recv(mon_conn, buf, &len);
169 perror("wpa_ctrl_recv");
176 kill(getppid(), SIGUSR1);
180 #endif /* CONFIG_WPA_CLI_FORK */
183 static int wpa_cli_open_connection(const char *ifname, int attach)
185 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
186 ctrl_conn = wpa_ctrl_open(ifname);
187 if (ctrl_conn == NULL)
190 if (attach && interactive)
191 mon_conn = wpa_ctrl_open(ifname);
194 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
201 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
202 cfile = os_malloc(flen);
205 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
206 if (res < 0 || res >= flen) {
211 ctrl_conn = wpa_ctrl_open(cfile);
212 if (ctrl_conn == NULL) {
217 if (attach && interactive)
218 mon_conn = wpa_ctrl_open(cfile);
222 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
225 if (wpa_ctrl_attach(mon_conn) == 0) {
226 wpa_cli_attached = 1;
228 printf("Warning: Failed to attach to "
229 "wpa_supplicant.\n");
233 #ifdef CONFIG_WPA_CLI_FORK
246 #endif /* CONFIG_WPA_CLI_FORK */
253 static void wpa_cli_close_connection(void)
255 if (ctrl_conn == NULL)
258 if (wpa_cli_attached) {
259 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
260 wpa_cli_attached = 0;
262 wpa_ctrl_close(ctrl_conn);
265 wpa_ctrl_close(mon_conn);
268 #ifdef CONFIG_WPA_CLI_FORK
271 kill(mon_pid, SIGPIPE);
275 #endif /* CONFIG_WPA_CLI_FORK */
279 static void wpa_cli_msg_cb(char *msg, size_t len)
285 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
291 if (ctrl_conn == NULL) {
292 printf("Not connected to wpa_supplicant - command dropped.\n");
295 len = sizeof(buf) - 1;
296 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
299 printf("'%s' command timed out.\n", cmd);
301 } else if (ret < 0) {
302 printf("'%s' command failed.\n", cmd);
313 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
315 return _wpa_ctrl_command(ctrl, cmd, 1);
319 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
321 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
322 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
326 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
328 return wpa_ctrl_command(ctrl, "PING");
332 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
334 return wpa_ctrl_command(ctrl, "MIB");
338 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
340 return wpa_ctrl_command(ctrl, "PMKSA");
344 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
351 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
353 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
358 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
365 static void wpa_cli_show_variables(void)
367 printf("set variables:\n"
368 " EAPOL::heldPeriod (EAPOL state machine held period, "
370 " EAPOL::authPeriod (EAPOL state machine authentication "
371 "period, in seconds)\n"
372 " EAPOL::startPeriod (EAPOL state machine start period, in "
374 " EAPOL::maxStart (EAPOL state machine maximum start "
376 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
378 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
379 " threshold\n\tpercentage)\n"
380 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
381 "security\n\tassociation in seconds)\n");
385 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
391 wpa_cli_show_variables();
396 printf("Invalid SET command: needs two arguments (variable "
397 "name and value)\n");
401 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
402 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
403 printf("Too long SET command.\n");
406 return wpa_ctrl_command(ctrl, cmd);
410 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
412 return wpa_ctrl_command(ctrl, "LOGOFF");
416 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
418 return wpa_ctrl_command(ctrl, "LOGON");
422 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
425 return wpa_ctrl_command(ctrl, "REASSOCIATE");
429 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
436 printf("Invalid PREAUTH command: needs one argument "
441 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
442 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
443 printf("Too long PREAUTH command.\n");
446 return wpa_ctrl_command(ctrl, cmd);
450 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
456 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
460 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
461 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
462 printf("Too long AP_SCAN command.\n");
465 return wpa_ctrl_command(ctrl, cmd);
469 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
476 printf("Invalid STKSTART command: needs one argument "
477 "(Peer STA MAC address)\n");
481 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
482 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
483 printf("Too long STKSTART command.\n");
486 return wpa_ctrl_command(ctrl, cmd);
490 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
496 printf("Invalid FT_DS command: needs one argument "
497 "(Target AP MAC address)\n");
501 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
502 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
503 printf("Too long FT_DS command.\n");
506 return wpa_ctrl_command(ctrl, cmd);
510 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
517 return wpa_ctrl_command(ctrl, "WPS_PBC");
521 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
522 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
523 printf("Too long WPS_PBC command.\n");
526 return wpa_ctrl_command(ctrl, cmd);
530 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
536 printf("Invalid WPS_PIN command: need one or two arguments:\n"
537 "- BSSID: use 'any' to select any\n"
538 "- PIN: optional, used only with devices that have no "
544 /* Use dynamically generated PIN (returned as reply) */
545 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
546 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
547 printf("Too long WPS_PIN command.\n");
550 return wpa_ctrl_command(ctrl, cmd);
553 /* Use hardcoded PIN from a label */
554 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
555 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
556 printf("Too long WPS_PIN command.\n");
559 return wpa_ctrl_command(ctrl, cmd);
563 #ifdef CONFIG_WPS_OOB
564 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
569 if (argc != 3 && argc != 4) {
570 printf("Invalid WPS_OOB command: need three or four "
572 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
573 "- PATH: path of OOB device like '/mnt'\n"
574 "- METHOD: OOB method 'pin-e' or 'pin-r', "
576 "- DEV_NAME: (only for NFC) device name like "
582 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
583 argv[0], argv[1], argv[2]);
585 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
586 argv[0], argv[1], argv[2], argv[3]);
587 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
588 printf("Too long WPS_OOB command.\n");
591 return wpa_ctrl_command(ctrl, cmd);
593 #endif /* CONFIG_WPS_OOB */
596 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
602 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
604 else if (argc == 6) {
605 char ssid_hex[2 * 32 + 1];
606 char key_hex[2 * 64 + 1];
610 for (i = 0; i < 32; i++) {
611 if (argv[2][i] == '\0')
613 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
617 for (i = 0; i < 64; i++) {
618 if (argv[5][i] == '\0')
620 os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]);
623 res = os_snprintf(cmd, sizeof(cmd),
624 "WPS_REG %s %s %s %s %s %s",
625 argv[0], argv[1], ssid_hex, argv[3], argv[4],
628 printf("Invalid WPS_REG command: need two arguments:\n"
629 "- BSSID: use 'any' to select any\n"
631 printf("Alternatively, six arguments can be used to "
632 "reconfigure the AP:\n"
633 "- BSSID: use 'any' to select any\n"
636 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
637 "- new encr (NONE, WEP, TKIP, CCMP)\n"
642 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
643 printf("Too long WPS_REG command.\n");
646 return wpa_ctrl_command(ctrl, cmd);
650 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
653 return wpa_ctrl_command(ctrl, "WPS_ER_START");
658 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
661 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
666 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
673 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
674 "- UUID: use 'any' to select any\n"
675 "- PIN: Enrollee PIN\n");
679 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
681 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
682 printf("Too long WPS_ER_PIN command.\n");
685 return wpa_ctrl_command(ctrl, cmd);
689 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
696 printf("Invalid WPS_ER_PBC command: need one argument:\n"
697 "- UUID: Specify the Enrollee\n");
701 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
703 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
704 printf("Too long WPS_ER_PBC command.\n");
707 return wpa_ctrl_command(ctrl, cmd);
711 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
718 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
719 "- UUID: specify which AP to use\n"
724 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
726 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
727 printf("Too long WPS_ER_LEARN command.\n");
730 return wpa_ctrl_command(ctrl, cmd);
734 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
740 printf("Invalid IBSS_RSN command: needs one argument "
741 "(Peer STA MAC address)\n");
745 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
746 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
747 printf("Too long IBSS_RSN command.\n");
750 return wpa_ctrl_command(ctrl, cmd);
754 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
760 printf("Invalid LEVEL command: needs one argument (debug "
764 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
765 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
766 printf("Too long LEVEL command.\n");
769 return wpa_ctrl_command(ctrl, cmd);
773 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
775 char cmd[256], *pos, *end;
779 printf("Invalid IDENTITY command: needs two arguments "
780 "(network id and identity)\n");
784 end = cmd + sizeof(cmd);
786 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
788 if (ret < 0 || ret >= end - pos) {
789 printf("Too long IDENTITY command.\n");
793 for (i = 2; i < argc; i++) {
794 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
795 if (ret < 0 || ret >= end - pos) {
796 printf("Too long IDENTITY command.\n");
802 return wpa_ctrl_command(ctrl, cmd);
806 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
808 char cmd[256], *pos, *end;
812 printf("Invalid PASSWORD command: needs two arguments "
813 "(network id and password)\n");
817 end = cmd + sizeof(cmd);
819 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
821 if (ret < 0 || ret >= end - pos) {
822 printf("Too long PASSWORD command.\n");
826 for (i = 2; i < argc; i++) {
827 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
828 if (ret < 0 || ret >= end - pos) {
829 printf("Too long PASSWORD command.\n");
835 return wpa_ctrl_command(ctrl, cmd);
839 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
842 char cmd[256], *pos, *end;
846 printf("Invalid NEW_PASSWORD command: needs two arguments "
847 "(network id and password)\n");
851 end = cmd + sizeof(cmd);
853 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
855 if (ret < 0 || ret >= end - pos) {
856 printf("Too long NEW_PASSWORD command.\n");
860 for (i = 2; i < argc; i++) {
861 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
862 if (ret < 0 || ret >= end - pos) {
863 printf("Too long NEW_PASSWORD command.\n");
869 return wpa_ctrl_command(ctrl, cmd);
873 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
875 char cmd[256], *pos, *end;
879 printf("Invalid PIN command: needs two arguments "
880 "(network id and pin)\n");
884 end = cmd + sizeof(cmd);
886 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
888 if (ret < 0 || ret >= end - pos) {
889 printf("Too long PIN command.\n");
893 for (i = 2; i < argc; i++) {
894 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
895 if (ret < 0 || ret >= end - pos) {
896 printf("Too long PIN command.\n");
901 return wpa_ctrl_command(ctrl, cmd);
905 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
907 char cmd[256], *pos, *end;
911 printf("Invalid OTP command: needs two arguments (network "
912 "id and password)\n");
916 end = cmd + sizeof(cmd);
918 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
920 if (ret < 0 || ret >= end - pos) {
921 printf("Too long OTP command.\n");
925 for (i = 2; i < argc; i++) {
926 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
927 if (ret < 0 || ret >= end - pos) {
928 printf("Too long OTP command.\n");
934 return wpa_ctrl_command(ctrl, cmd);
938 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
941 char cmd[256], *pos, *end;
945 printf("Invalid PASSPHRASE command: needs two arguments "
946 "(network id and passphrase)\n");
950 end = cmd + sizeof(cmd);
952 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
954 if (ret < 0 || ret >= end - pos) {
955 printf("Too long PASSPHRASE command.\n");
959 for (i = 2; i < argc; i++) {
960 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
961 if (ret < 0 || ret >= end - pos) {
962 printf("Too long PASSPHRASE command.\n");
968 return wpa_ctrl_command(ctrl, cmd);
972 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
974 char cmd[256], *pos, *end;
978 printf("Invalid BSSID command: needs two arguments (network "
983 end = cmd + sizeof(cmd);
985 ret = os_snprintf(pos, end - pos, "BSSID");
986 if (ret < 0 || ret >= end - pos) {
987 printf("Too long BSSID command.\n");
991 for (i = 0; i < argc; i++) {
992 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
993 if (ret < 0 || ret >= end - pos) {
994 printf("Too long BSSID command.\n");
1000 return wpa_ctrl_command(ctrl, cmd);
1004 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1007 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1011 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1018 printf("Invalid SELECT_NETWORK command: needs one argument "
1023 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1024 if (res < 0 || (size_t) res >= sizeof(cmd))
1026 cmd[sizeof(cmd) - 1] = '\0';
1028 return wpa_ctrl_command(ctrl, cmd);
1032 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1039 printf("Invalid ENABLE_NETWORK command: needs one argument "
1044 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1045 if (res < 0 || (size_t) res >= sizeof(cmd))
1047 cmd[sizeof(cmd) - 1] = '\0';
1049 return wpa_ctrl_command(ctrl, cmd);
1053 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1060 printf("Invalid DISABLE_NETWORK command: needs one argument "
1065 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1066 if (res < 0 || (size_t) res >= sizeof(cmd))
1068 cmd[sizeof(cmd) - 1] = '\0';
1070 return wpa_ctrl_command(ctrl, cmd);
1074 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1077 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1081 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1088 printf("Invalid REMOVE_NETWORK command: needs one argument "
1093 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1094 if (res < 0 || (size_t) res >= sizeof(cmd))
1096 cmd[sizeof(cmd) - 1] = '\0';
1098 return wpa_ctrl_command(ctrl, cmd);
1102 static void wpa_cli_show_network_variables(void)
1104 printf("set_network variables:\n"
1105 " ssid (network name, SSID)\n"
1106 " psk (WPA passphrase or pre-shared key)\n"
1107 " key_mgmt (key management protocol)\n"
1108 " identity (EAP identity)\n"
1109 " password (EAP password)\n"
1112 "Note: Values are entered in the same format as the "
1113 "configuration file is using,\n"
1114 "i.e., strings values need to be inside double quotation "
1116 "For example: set_network 1 ssid \"network name\"\n"
1118 "Please see wpa_supplicant.conf documentation for full list "
1119 "of\navailable variables.\n");
1123 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1130 wpa_cli_show_network_variables();
1135 printf("Invalid SET_NETWORK command: needs three arguments\n"
1136 "(network id, variable name, and value)\n");
1140 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1141 argv[0], argv[1], argv[2]);
1142 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1143 printf("Too long SET_NETWORK command.\n");
1146 return wpa_ctrl_command(ctrl, cmd);
1150 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1157 wpa_cli_show_network_variables();
1162 printf("Invalid GET_NETWORK command: needs two arguments\n"
1163 "(network id and variable name)\n");
1167 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1169 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1170 printf("Too long GET_NETWORK command.\n");
1173 return wpa_ctrl_command(ctrl, cmd);
1177 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1180 return wpa_ctrl_command(ctrl, "DISCONNECT");
1184 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1187 return wpa_ctrl_command(ctrl, "RECONNECT");
1191 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1194 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1198 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1200 return wpa_ctrl_command(ctrl, "SCAN");
1204 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1207 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1211 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1217 printf("Invalid BSS command: need one argument (index or "
1222 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1223 if (res < 0 || (size_t) res >= sizeof(cmd))
1225 cmd[sizeof(cmd) - 1] = '\0';
1227 return wpa_ctrl_command(ctrl, cmd);
1231 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1237 if (argc < 1 || argc > 2) {
1238 printf("Invalid GET_CAPABILITY command: need either one or "
1243 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1244 printf("Invalid GET_CAPABILITY command: second argument, "
1245 "if any, must be 'strict'\n");
1249 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1250 (argc == 2) ? " strict" : "");
1251 if (res < 0 || (size_t) res >= sizeof(cmd))
1253 cmd[sizeof(cmd) - 1] = '\0';
1255 return wpa_ctrl_command(ctrl, cmd);
1259 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1261 printf("Available interfaces:\n");
1262 return wpa_ctrl_command(ctrl, "INTERFACES");
1266 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1269 wpa_cli_list_interfaces(ctrl);
1273 wpa_cli_close_connection();
1274 os_free(ctrl_ifname);
1275 ctrl_ifname = os_strdup(argv[0]);
1277 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1278 printf("Connected to interface '%s.\n", ctrl_ifname);
1280 printf("Could not connect to interface '%s' - re-trying\n",
1287 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1290 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1294 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1297 return wpa_ctrl_command(ctrl, "TERMINATE");
1301 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1308 printf("Invalid INTERFACE_ADD command: needs at least one "
1309 "argument (interface name)\n"
1310 "All arguments: ifname confname driver ctrl_interface "
1311 "driver_param bridge_name\n");
1316 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1317 * <driver_param>TAB<bridge_name>
1319 res = os_snprintf(cmd, sizeof(cmd),
1320 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1322 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1323 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1324 argc > 5 ? argv[5] : "");
1325 if (res < 0 || (size_t) res >= sizeof(cmd))
1327 cmd[sizeof(cmd) - 1] = '\0';
1328 return wpa_ctrl_command(ctrl, cmd);
1332 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1339 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1340 "(interface name)\n");
1344 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1345 if (res < 0 || (size_t) res >= sizeof(cmd))
1347 cmd[sizeof(cmd) - 1] = '\0';
1348 return wpa_ctrl_command(ctrl, cmd);
1352 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1355 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1360 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1364 printf("Invalid 'sta' command - exactly one argument, STA "
1365 "address, is required.\n");
1368 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1369 return wpa_ctrl_command(ctrl, buf);
1373 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1374 char *addr, size_t addr_len)
1376 char buf[4096], *pos;
1380 if (ctrl_conn == NULL) {
1381 printf("Not connected to hostapd - command dropped.\n");
1384 len = sizeof(buf) - 1;
1385 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1388 printf("'%s' command timed out.\n", cmd);
1390 } else if (ret < 0) {
1391 printf("'%s' command failed.\n", cmd);
1396 if (memcmp(buf, "FAIL", 4) == 0)
1401 while (*pos != '\0' && *pos != '\n')
1404 os_strlcpy(addr, buf, addr_len);
1409 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1411 char addr[32], cmd[64];
1413 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1416 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1417 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1421 #endif /* CONFIG_AP */
1424 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1426 return wpa_ctrl_command(ctrl, "SUSPEND");
1430 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1432 return wpa_ctrl_command(ctrl, "RESUME");
1436 enum wpa_cli_cmd_flags {
1437 cli_cmd_flag_none = 0x00,
1438 cli_cmd_flag_sensitive = 0x01
1441 struct wpa_cli_cmd {
1443 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1444 enum wpa_cli_cmd_flags flags;
1448 static struct wpa_cli_cmd wpa_cli_commands[] = {
1449 { "status", wpa_cli_cmd_status,
1451 "[verbose] = get current WPA/EAPOL/EAP status" },
1452 { "ping", wpa_cli_cmd_ping,
1454 "= pings wpa_supplicant" },
1455 { "mib", wpa_cli_cmd_mib,
1457 "= get MIB variables (dot1x, dot11)" },
1458 { "help", wpa_cli_cmd_help,
1460 "= show this usage help" },
1461 { "interface", wpa_cli_cmd_interface,
1463 "[ifname] = show interfaces/select interface" },
1464 { "level", wpa_cli_cmd_level,
1466 "<debug level> = change debug level" },
1467 { "license", wpa_cli_cmd_license,
1469 "= show full wpa_cli license" },
1470 { "quit", wpa_cli_cmd_quit,
1473 { "set", wpa_cli_cmd_set,
1475 "= set variables (shows list of variables when run without "
1477 { "logon", wpa_cli_cmd_logon,
1479 "= IEEE 802.1X EAPOL state machine logon" },
1480 { "logoff", wpa_cli_cmd_logoff,
1482 "= IEEE 802.1X EAPOL state machine logoff" },
1483 { "pmksa", wpa_cli_cmd_pmksa,
1485 "= show PMKSA cache" },
1486 { "reassociate", wpa_cli_cmd_reassociate,
1488 "= force reassociation" },
1489 { "preauthenticate", wpa_cli_cmd_preauthenticate,
1491 "<BSSID> = force preauthentication" },
1492 { "identity", wpa_cli_cmd_identity,
1494 "<network id> <identity> = configure identity for an SSID" },
1495 { "password", wpa_cli_cmd_password,
1496 cli_cmd_flag_sensitive,
1497 "<network id> <password> = configure password for an SSID" },
1498 { "new_password", wpa_cli_cmd_new_password,
1499 cli_cmd_flag_sensitive,
1500 "<network id> <password> = change password for an SSID" },
1501 { "pin", wpa_cli_cmd_pin,
1502 cli_cmd_flag_sensitive,
1503 "<network id> <pin> = configure pin for an SSID" },
1504 { "otp", wpa_cli_cmd_otp,
1505 cli_cmd_flag_sensitive,
1506 "<network id> <password> = configure one-time-password for an SSID"
1508 { "passphrase", wpa_cli_cmd_passphrase,
1509 cli_cmd_flag_sensitive,
1510 "<network id> <passphrase> = configure private key passphrase\n"
1512 { "bssid", wpa_cli_cmd_bssid,
1514 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1515 { "list_networks", wpa_cli_cmd_list_networks,
1517 "= list configured networks" },
1518 { "select_network", wpa_cli_cmd_select_network,
1520 "<network id> = select a network (disable others)" },
1521 { "enable_network", wpa_cli_cmd_enable_network,
1523 "<network id> = enable a network" },
1524 { "disable_network", wpa_cli_cmd_disable_network,
1526 "<network id> = disable a network" },
1527 { "add_network", wpa_cli_cmd_add_network,
1529 "= add a network" },
1530 { "remove_network", wpa_cli_cmd_remove_network,
1532 "<network id> = remove a network" },
1533 { "set_network", wpa_cli_cmd_set_network,
1534 cli_cmd_flag_sensitive,
1535 "<network id> <variable> <value> = set network variables (shows\n"
1536 " list of variables when run without arguments)" },
1537 { "get_network", wpa_cli_cmd_get_network,
1539 "<network id> <variable> = get network variables" },
1540 { "save_config", wpa_cli_cmd_save_config,
1542 "= save the current configuration" },
1543 { "disconnect", wpa_cli_cmd_disconnect,
1545 "= disconnect and wait for reassociate/reconnect command before\n"
1547 { "reconnect", wpa_cli_cmd_reconnect,
1549 "= like reassociate, but only takes effect if already disconnected"
1551 { "scan", wpa_cli_cmd_scan,
1553 "= request new BSS scan" },
1554 { "scan_results", wpa_cli_cmd_scan_results,
1556 "= get latest scan results" },
1557 { "bss", wpa_cli_cmd_bss,
1559 "<<idx> | <bssid>> = get detailed scan result info" },
1560 { "get_capability", wpa_cli_cmd_get_capability,
1562 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1563 { "reconfigure", wpa_cli_cmd_reconfigure,
1565 "= force wpa_supplicant to re-read its configuration file" },
1566 { "terminate", wpa_cli_cmd_terminate,
1568 "= terminate wpa_supplicant" },
1569 { "interface_add", wpa_cli_cmd_interface_add,
1571 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1572 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1574 { "interface_remove", wpa_cli_cmd_interface_remove,
1576 "<ifname> = removes the interface" },
1577 { "interface_list", wpa_cli_cmd_interface_list,
1579 "= list available interfaces" },
1580 { "ap_scan", wpa_cli_cmd_ap_scan,
1582 "<value> = set ap_scan parameter" },
1583 { "stkstart", wpa_cli_cmd_stkstart,
1585 "<addr> = request STK negotiation with <addr>" },
1586 { "ft_ds", wpa_cli_cmd_ft_ds,
1588 "<addr> = request over-the-DS FT with <addr>" },
1589 { "wps_pbc", wpa_cli_cmd_wps_pbc,
1591 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1592 { "wps_pin", wpa_cli_cmd_wps_pin,
1593 cli_cmd_flag_sensitive,
1594 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1596 #ifdef CONFIG_WPS_OOB
1597 { "wps_oob", wpa_cli_cmd_wps_oob,
1598 cli_cmd_flag_sensitive,
1599 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1600 #endif /* CONFIG_WPS_OOB */
1601 { "wps_reg", wpa_cli_cmd_wps_reg,
1602 cli_cmd_flag_sensitive,
1603 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1604 { "wps_er_start", wpa_cli_cmd_wps_er_start,
1606 "= start Wi-Fi Protected Setup External Registrar" },
1607 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1609 "= stop Wi-Fi Protected Setup External Registrar" },
1610 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
1611 cli_cmd_flag_sensitive,
1612 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1613 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
1615 "<UUID> = accept an Enrollee PBC using External Registrar" },
1616 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
1617 cli_cmd_flag_sensitive,
1618 "<UUID> <PIN> = learn AP configuration" },
1619 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1621 "<addr> = request RSN authentication with <addr> in IBSS" },
1623 { "sta", wpa_cli_cmd_sta,
1625 "<addr> = get information about an associated station (AP)" },
1626 { "all_sta", wpa_cli_cmd_all_sta,
1628 "= get information about all associated stations (AP)" },
1629 #endif /* CONFIG_AP */
1630 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
1631 "= notification of suspend/hibernate" },
1632 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
1633 "= notification of resume/thaw" },
1634 { NULL, NULL, cli_cmd_flag_none, NULL }
1639 * Prints command usage, lines are padded with the specified string.
1641 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1646 printf("%s%s ", pad, cmd->cmd);
1647 for (n = 0; (c = cmd->usage[n]); n++) {
1656 static void print_help(void)
1659 printf("commands:\n");
1660 for (n = 0; wpa_cli_commands[n].cmd; n++)
1661 print_cmd_help(&wpa_cli_commands[n], " ");
1665 #ifdef CONFIG_READLINE
1666 static int cmd_has_sensitive_data(const char *cmd)
1668 const char *c, *delim;
1672 delim = os_strchr(cmd, ' ');
1676 len = os_strlen(cmd);
1678 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1679 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1680 return (wpa_cli_commands[n].flags &
1681 cli_cmd_flag_sensitive);
1685 #endif /* CONFIG_READLINE */
1688 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1690 struct wpa_cli_cmd *cmd, *match = NULL;
1695 cmd = wpa_cli_commands;
1697 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1700 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1701 /* we have an exact match */
1711 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1712 cmd = wpa_cli_commands;
1714 if (os_strncasecmp(cmd->cmd, argv[0],
1715 os_strlen(argv[0])) == 0) {
1716 printf(" %s", cmd->cmd);
1722 } else if (count == 0) {
1723 printf("Unknown command '%s'\n", argv[0]);
1726 ret = match->handler(ctrl, argc - 1, &argv[1]);
1733 static int str_match(const char *a, const char *b)
1735 return os_strncmp(a, b, os_strlen(b)) == 0;
1739 static int wpa_cli_exec(const char *program, const char *arg1,
1747 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1748 cmd = os_malloc(len);
1751 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1752 if (res < 0 || (size_t) res >= len) {
1756 cmd[len - 1] = '\0';
1758 if (system(cmd) < 0)
1760 #endif /* _WIN32_WCE */
1767 static void wpa_cli_action_process(const char *msg)
1770 char *copy = NULL, *id, *pos2;
1775 pos = os_strchr(pos, '>');
1782 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1784 os_unsetenv("WPA_ID");
1785 os_unsetenv("WPA_ID_STR");
1786 os_unsetenv("WPA_CTRL_DIR");
1788 pos = os_strstr(pos, "[id=");
1790 copy = os_strdup(pos + 4);
1794 while (*pos2 && *pos2 != ' ')
1798 os_setenv("WPA_ID", id, 1);
1799 while (*pos2 && *pos2 != '=')
1804 while (*pos2 && *pos2 != ']')
1807 os_setenv("WPA_ID_STR", id, 1);
1811 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1813 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1814 wpa_cli_connected = 1;
1815 wpa_cli_last_id = new_id;
1816 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1818 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1819 if (wpa_cli_connected) {
1820 wpa_cli_connected = 0;
1821 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1823 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1824 printf("wpa_supplicant is terminating - stop monitoring\n");
1830 #ifndef CONFIG_ANSI_C_EXTRA
1831 static void wpa_cli_action_cb(char *msg, size_t len)
1833 wpa_cli_action_process(msg);
1835 #endif /* CONFIG_ANSI_C_EXTRA */
1838 static void wpa_cli_reconnect(void)
1840 wpa_cli_close_connection();
1841 wpa_cli_open_connection(ctrl_ifname, 1);
1845 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1849 if (ctrl_conn == NULL) {
1850 wpa_cli_reconnect();
1853 while (wpa_ctrl_pending(ctrl) > 0) {
1855 size_t len = sizeof(buf) - 1;
1856 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1859 wpa_cli_action_process(buf);
1861 if (in_read && first)
1864 printf("%s\n", buf);
1865 #ifdef CONFIG_READLINE
1868 #endif /* CONFIG_READLINE */
1871 printf("Could not read pending message.\n");
1876 if (wpa_ctrl_pending(ctrl) < 0) {
1877 printf("Connection to wpa_supplicant lost - trying to "
1879 wpa_cli_reconnect();
1884 #ifdef CONFIG_READLINE
1885 static char * wpa_cli_cmd_gen(const char *text, int state)
1892 len = os_strlen(text);
1895 while ((cmd = wpa_cli_commands[i].cmd)) {
1897 if (os_strncasecmp(cmd, text, len) == 0)
1905 static char * wpa_cli_dummy_gen(const char *text, int state)
1911 static char ** wpa_cli_completion(const char *text, int start, int end)
1913 return rl_completion_matches(text, start == 0 ?
1914 wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1916 #endif /* CONFIG_READLINE */
1919 static void wpa_cli_interactive(void)
1922 char cmdbuf[256], *cmd, *argv[max_args], *pos;
1924 #ifdef CONFIG_READLINE
1925 char *home, *hfile = NULL;
1926 #endif /* CONFIG_READLINE */
1928 printf("\nInteractive mode\n\n");
1930 #ifdef CONFIG_READLINE
1931 rl_attempted_completion_function = wpa_cli_completion;
1932 home = getenv("HOME");
1934 const char *fname = ".wpa_cli_history";
1935 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1936 hfile = os_malloc(hfile_len);
1939 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
1941 if (res >= 0 && res < hfile_len) {
1942 hfile[hfile_len - 1] = '\0';
1943 read_history(hfile);
1944 stifle_history(100);
1948 #endif /* CONFIG_READLINE */
1951 wpa_cli_recv_pending(mon_conn, 0, 0);
1952 #ifndef CONFIG_NATIVE_WINDOWS
1953 alarm(ping_interval);
1954 #endif /* CONFIG_NATIVE_WINDOWS */
1955 #ifdef CONFIG_WPA_CLI_FORK
1957 kill(mon_pid, SIGUSR1);
1958 #endif /* CONFIG_WPA_CLI_FORK */
1959 #ifdef CONFIG_READLINE
1960 cmd = readline("> ");
1963 while (next_history())
1965 h = previous_history();
1966 if (h == NULL || os_strcmp(cmd, h->line) != 0)
1970 #else /* CONFIG_READLINE */
1972 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1973 #endif /* CONFIG_READLINE */
1974 #ifndef CONFIG_NATIVE_WINDOWS
1976 #endif /* CONFIG_NATIVE_WINDOWS */
1979 wpa_cli_recv_pending(mon_conn, 0, 0);
1981 while (*pos != '\0') {
1997 if (argc == max_args)
2000 char *pos2 = os_strrchr(pos, '"');
2004 while (*pos != '\0' && *pos != ' ')
2010 wpa_request(ctrl_conn, argc, argv);
2014 #ifdef CONFIG_WPA_CLI_FORK
2016 kill(mon_pid, SIGUSR2);
2017 #endif /* CONFIG_WPA_CLI_FORK */
2018 } while (!wpa_cli_quit);
2020 #ifdef CONFIG_READLINE
2022 /* Save command history, excluding lines that may contain
2026 while ((h = current_history())) {
2028 while (*p == ' ' || *p == '\t')
2030 if (cmd_has_sensitive_data(p)) {
2031 h = remove_history(where_history());
2041 write_history(hfile);
2044 #endif /* CONFIG_READLINE */
2048 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2050 #ifdef CONFIG_ANSI_C_EXTRA
2051 /* TODO: ANSI C version(?) */
2052 printf("Action processing not supported in ANSI C build.\n");
2053 #else /* CONFIG_ANSI_C_EXTRA */
2057 char buf[256]; /* note: large enough to fit in unsolicited messages */
2060 fd = wpa_ctrl_get_fd(ctrl);
2062 while (!wpa_cli_quit) {
2065 tv.tv_sec = ping_interval;
2067 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2068 if (res < 0 && errno != EINTR) {
2073 if (FD_ISSET(fd, &rfds))
2074 wpa_cli_recv_pending(ctrl, 0, 1);
2076 /* verify that connection is still working */
2077 len = sizeof(buf) - 1;
2078 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2079 wpa_cli_action_cb) < 0 ||
2080 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2081 printf("wpa_supplicant did not reply to PING "
2082 "command - exiting\n");
2087 #endif /* CONFIG_ANSI_C_EXTRA */
2091 static void wpa_cli_cleanup(void)
2093 wpa_cli_close_connection();
2095 os_daemonize_terminate(pid_file);
2097 os_program_deinit();
2100 static void wpa_cli_terminate(int sig)
2107 #ifdef CONFIG_WPA_CLI_FORK
2108 static void wpa_cli_usr1(int sig)
2110 #ifdef CONFIG_READLINE
2113 #endif /* CONFIG_READLINE */
2115 #endif /* CONFIG_WPA_CLI_FORK */
2118 #ifndef CONFIG_NATIVE_WINDOWS
2119 static void wpa_cli_alarm(int sig)
2121 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2122 printf("Connection to wpa_supplicant lost - trying to "
2124 wpa_cli_close_connection();
2127 wpa_cli_reconnect();
2129 wpa_cli_recv_pending(mon_conn, 1, 0);
2130 alarm(ping_interval);
2132 #endif /* CONFIG_NATIVE_WINDOWS */
2135 static char * wpa_cli_get_default_ifname(void)
2137 char *ifname = NULL;
2139 #ifdef CONFIG_CTRL_IFACE_UNIX
2140 struct dirent *dent;
2141 DIR *dir = opendir(ctrl_iface_dir);
2144 while ((dent = readdir(dir))) {
2145 #ifdef _DIRENT_HAVE_D_TYPE
2147 * Skip the file if it is not a socket. Also accept
2148 * DT_UNKNOWN (0) in case the C library or underlying
2149 * file system does not support d_type.
2151 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2153 #endif /* _DIRENT_HAVE_D_TYPE */
2154 if (os_strcmp(dent->d_name, ".") == 0 ||
2155 os_strcmp(dent->d_name, "..") == 0)
2157 printf("Selected interface '%s'\n", dent->d_name);
2158 ifname = os_strdup(dent->d_name);
2162 #endif /* CONFIG_CTRL_IFACE_UNIX */
2164 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2165 char buf[2048], *pos;
2167 struct wpa_ctrl *ctrl;
2170 ctrl = wpa_ctrl_open(NULL);
2174 len = sizeof(buf) - 1;
2175 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2178 pos = os_strchr(buf, '\n');
2181 ifname = os_strdup(buf);
2183 wpa_ctrl_close(ctrl);
2184 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2190 int main(int argc, char *argv[])
2192 int warning_displayed = 0;
2196 const char *global = NULL;
2198 if (os_program_init())
2202 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2207 action_file = optarg;
2216 ping_interval = atoi(optarg);
2222 printf("%s\n", wpa_cli_version);
2225 os_free(ctrl_ifname);
2226 ctrl_ifname = os_strdup(optarg);
2229 ctrl_iface_dir = optarg;
2240 interactive = (argc == optind) && (action_file == NULL);
2243 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2246 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2247 ctrl_conn = wpa_ctrl_open(NULL);
2248 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2249 ctrl_conn = wpa_ctrl_open(global);
2250 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2251 if (ctrl_conn == NULL) {
2252 perror("Failed to connect to wpa_supplicant - "
2259 signal(SIGINT, wpa_cli_terminate);
2260 signal(SIGTERM, wpa_cli_terminate);
2261 #endif /* _WIN32_WCE */
2262 #ifndef CONFIG_NATIVE_WINDOWS
2263 signal(SIGALRM, wpa_cli_alarm);
2264 #endif /* CONFIG_NATIVE_WINDOWS */
2265 #ifdef CONFIG_WPA_CLI_FORK
2266 signal(SIGUSR1, wpa_cli_usr1);
2267 #endif /* CONFIG_WPA_CLI_FORK */
2269 if (ctrl_ifname == NULL)
2270 ctrl_ifname = wpa_cli_get_default_ifname();
2274 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
2275 if (warning_displayed)
2276 printf("Connection established.\n");
2280 if (!warning_displayed) {
2281 printf("Could not connect to wpa_supplicant - "
2283 warning_displayed = 1;
2290 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
2291 perror("Failed to connect to wpa_supplicant - "
2297 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2298 wpa_cli_attached = 1;
2300 printf("Warning: Failed to attach to "
2301 "wpa_supplicant.\n");
2307 if (daemonize && os_daemonize(pid_file))
2311 wpa_cli_interactive();
2312 else if (action_file)
2313 wpa_cli_action(ctrl_conn);
2315 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2317 os_free(ctrl_ifname);
2323 #else /* CONFIG_CTRL_IFACE */
2324 int main(int argc, char *argv[])
2326 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2329 #endif /* CONFIG_CTRL_IFACE */