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 #ifdef CONFIG_WPA_CLI_FORK
261 kill(mon_pid, SIGPIPE);
265 #endif /* CONFIG_WPA_CLI_FORK */
267 if (wpa_cli_attached) {
268 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
269 wpa_cli_attached = 0;
271 wpa_ctrl_close(ctrl_conn);
274 wpa_ctrl_close(mon_conn);
280 static void wpa_cli_msg_cb(char *msg, size_t len)
286 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
292 if (ctrl_conn == NULL) {
293 printf("Not connected to wpa_supplicant - command dropped.\n");
296 len = sizeof(buf) - 1;
297 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
300 printf("'%s' command timed out.\n", cmd);
302 } else if (ret < 0) {
303 printf("'%s' command failed.\n", cmd);
314 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
316 return _wpa_ctrl_command(ctrl, cmd, 1);
320 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
322 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
323 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
327 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
329 return wpa_ctrl_command(ctrl, "PING");
333 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
335 return wpa_ctrl_command(ctrl, "MIB");
339 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
341 return wpa_ctrl_command(ctrl, "PMKSA");
345 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
352 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
354 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
359 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
366 static void wpa_cli_show_variables(void)
368 printf("set variables:\n"
369 " EAPOL::heldPeriod (EAPOL state machine held period, "
371 " EAPOL::authPeriod (EAPOL state machine authentication "
372 "period, in seconds)\n"
373 " EAPOL::startPeriod (EAPOL state machine start period, in "
375 " EAPOL::maxStart (EAPOL state machine maximum start "
377 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
379 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
380 " threshold\n\tpercentage)\n"
381 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
382 "security\n\tassociation in seconds)\n");
386 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
392 wpa_cli_show_variables();
397 printf("Invalid SET command: needs two arguments (variable "
398 "name and value)\n");
402 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
403 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
404 printf("Too long SET command.\n");
407 return wpa_ctrl_command(ctrl, cmd);
411 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
413 return wpa_ctrl_command(ctrl, "LOGOFF");
417 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
419 return wpa_ctrl_command(ctrl, "LOGON");
423 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
426 return wpa_ctrl_command(ctrl, "REASSOCIATE");
430 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
437 printf("Invalid PREAUTH command: needs one argument "
442 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
443 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
444 printf("Too long PREAUTH command.\n");
447 return wpa_ctrl_command(ctrl, cmd);
451 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
457 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
461 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
462 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
463 printf("Too long AP_SCAN command.\n");
466 return wpa_ctrl_command(ctrl, cmd);
470 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
477 printf("Invalid STKSTART command: needs one argument "
478 "(Peer STA MAC address)\n");
482 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
483 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
484 printf("Too long STKSTART command.\n");
487 return wpa_ctrl_command(ctrl, cmd);
491 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
497 printf("Invalid FT_DS command: needs one argument "
498 "(Target AP MAC address)\n");
502 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
503 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
504 printf("Too long FT_DS command.\n");
507 return wpa_ctrl_command(ctrl, cmd);
511 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
518 return wpa_ctrl_command(ctrl, "WPS_PBC");
522 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
523 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
524 printf("Too long WPS_PBC command.\n");
527 return wpa_ctrl_command(ctrl, cmd);
531 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
537 printf("Invalid WPS_PIN command: need one or two arguments:\n"
538 "- BSSID: use 'any' to select any\n"
539 "- PIN: optional, used only with devices that have no "
545 /* Use dynamically generated PIN (returned as reply) */
546 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
547 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
548 printf("Too long WPS_PIN command.\n");
551 return wpa_ctrl_command(ctrl, cmd);
554 /* Use hardcoded PIN from a label */
555 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
556 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
557 printf("Too long WPS_PIN command.\n");
560 return wpa_ctrl_command(ctrl, cmd);
564 #ifdef CONFIG_WPS_OOB
565 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
570 if (argc != 3 && argc != 4) {
571 printf("Invalid WPS_OOB command: need three or four "
573 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
574 "- PATH: path of OOB device like '/mnt'\n"
575 "- METHOD: OOB method 'pin-e' or 'pin-r', "
577 "- DEV_NAME: (only for NFC) device name like "
583 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
584 argv[0], argv[1], argv[2]);
586 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
587 argv[0], argv[1], argv[2], argv[3]);
588 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
589 printf("Too long WPS_OOB command.\n");
592 return wpa_ctrl_command(ctrl, cmd);
594 #endif /* CONFIG_WPS_OOB */
597 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
603 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
605 else if (argc == 6) {
606 char ssid_hex[2 * 32 + 1];
607 char key_hex[2 * 64 + 1];
611 for (i = 0; i < 32; i++) {
612 if (argv[2][i] == '\0')
614 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
618 for (i = 0; i < 64; i++) {
619 if (argv[5][i] == '\0')
621 os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]);
624 res = os_snprintf(cmd, sizeof(cmd),
625 "WPS_REG %s %s %s %s %s %s",
626 argv[0], argv[1], ssid_hex, argv[3], argv[4],
629 printf("Invalid WPS_REG command: need two arguments:\n"
630 "- BSSID: use 'any' to select any\n"
632 printf("Alternatively, six arguments can be used to "
633 "reconfigure the AP:\n"
634 "- BSSID: use 'any' to select any\n"
637 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
638 "- new encr (NONE, WEP, TKIP, CCMP)\n"
643 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
644 printf("Too long WPS_REG command.\n");
647 return wpa_ctrl_command(ctrl, cmd);
651 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
656 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
657 return wpa_ctrl_command(ctrl, cmd);
659 return wpa_ctrl_command(ctrl, "WPS_ER_START");
663 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
666 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
671 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
678 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
679 "- UUID: use 'any' to select any\n"
680 "- PIN: Enrollee PIN\n");
684 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
686 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
687 printf("Too long WPS_ER_PIN command.\n");
690 return wpa_ctrl_command(ctrl, cmd);
694 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
701 printf("Invalid WPS_ER_PBC command: need one argument:\n"
702 "- UUID: Specify the Enrollee\n");
706 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
708 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
709 printf("Too long WPS_ER_PBC command.\n");
712 return wpa_ctrl_command(ctrl, cmd);
716 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
723 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
724 "- UUID: specify which AP to use\n"
729 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
731 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
732 printf("Too long WPS_ER_LEARN command.\n");
735 return wpa_ctrl_command(ctrl, cmd);
739 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
745 printf("Invalid IBSS_RSN command: needs one argument "
746 "(Peer STA MAC address)\n");
750 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
751 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
752 printf("Too long IBSS_RSN command.\n");
755 return wpa_ctrl_command(ctrl, cmd);
759 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
765 printf("Invalid LEVEL command: needs one argument (debug "
769 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
770 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
771 printf("Too long LEVEL command.\n");
774 return wpa_ctrl_command(ctrl, cmd);
778 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
780 char cmd[256], *pos, *end;
784 printf("Invalid IDENTITY command: needs two arguments "
785 "(network id and identity)\n");
789 end = cmd + sizeof(cmd);
791 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
793 if (ret < 0 || ret >= end - pos) {
794 printf("Too long IDENTITY command.\n");
798 for (i = 2; i < argc; i++) {
799 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
800 if (ret < 0 || ret >= end - pos) {
801 printf("Too long IDENTITY command.\n");
807 return wpa_ctrl_command(ctrl, cmd);
811 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
813 char cmd[256], *pos, *end;
817 printf("Invalid PASSWORD command: needs two arguments "
818 "(network id and password)\n");
822 end = cmd + sizeof(cmd);
824 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
826 if (ret < 0 || ret >= end - pos) {
827 printf("Too long PASSWORD command.\n");
831 for (i = 2; i < argc; i++) {
832 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
833 if (ret < 0 || ret >= end - pos) {
834 printf("Too long PASSWORD command.\n");
840 return wpa_ctrl_command(ctrl, cmd);
844 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
847 char cmd[256], *pos, *end;
851 printf("Invalid NEW_PASSWORD command: needs two arguments "
852 "(network id and password)\n");
856 end = cmd + sizeof(cmd);
858 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
860 if (ret < 0 || ret >= end - pos) {
861 printf("Too long NEW_PASSWORD command.\n");
865 for (i = 2; i < argc; i++) {
866 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
867 if (ret < 0 || ret >= end - pos) {
868 printf("Too long NEW_PASSWORD command.\n");
874 return wpa_ctrl_command(ctrl, cmd);
878 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
880 char cmd[256], *pos, *end;
884 printf("Invalid PIN command: needs two arguments "
885 "(network id and pin)\n");
889 end = cmd + sizeof(cmd);
891 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
893 if (ret < 0 || ret >= end - pos) {
894 printf("Too long PIN command.\n");
898 for (i = 2; i < argc; i++) {
899 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
900 if (ret < 0 || ret >= end - pos) {
901 printf("Too long PIN command.\n");
906 return wpa_ctrl_command(ctrl, cmd);
910 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
912 char cmd[256], *pos, *end;
916 printf("Invalid OTP command: needs two arguments (network "
917 "id and password)\n");
921 end = cmd + sizeof(cmd);
923 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
925 if (ret < 0 || ret >= end - pos) {
926 printf("Too long OTP command.\n");
930 for (i = 2; i < argc; i++) {
931 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
932 if (ret < 0 || ret >= end - pos) {
933 printf("Too long OTP command.\n");
939 return wpa_ctrl_command(ctrl, cmd);
943 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
946 char cmd[256], *pos, *end;
950 printf("Invalid PASSPHRASE command: needs two arguments "
951 "(network id and passphrase)\n");
955 end = cmd + sizeof(cmd);
957 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
959 if (ret < 0 || ret >= end - pos) {
960 printf("Too long PASSPHRASE command.\n");
964 for (i = 2; i < argc; i++) {
965 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
966 if (ret < 0 || ret >= end - pos) {
967 printf("Too long PASSPHRASE command.\n");
973 return wpa_ctrl_command(ctrl, cmd);
977 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
979 char cmd[256], *pos, *end;
983 printf("Invalid BSSID command: needs two arguments (network "
988 end = cmd + sizeof(cmd);
990 ret = os_snprintf(pos, end - pos, "BSSID");
991 if (ret < 0 || ret >= end - pos) {
992 printf("Too long BSSID command.\n");
996 for (i = 0; i < argc; i++) {
997 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
998 if (ret < 0 || ret >= end - pos) {
999 printf("Too long BSSID command.\n");
1005 return wpa_ctrl_command(ctrl, cmd);
1009 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1012 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1016 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1023 printf("Invalid SELECT_NETWORK command: needs one argument "
1028 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1029 if (res < 0 || (size_t) res >= sizeof(cmd))
1031 cmd[sizeof(cmd) - 1] = '\0';
1033 return wpa_ctrl_command(ctrl, cmd);
1037 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1044 printf("Invalid ENABLE_NETWORK command: needs one argument "
1049 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1050 if (res < 0 || (size_t) res >= sizeof(cmd))
1052 cmd[sizeof(cmd) - 1] = '\0';
1054 return wpa_ctrl_command(ctrl, cmd);
1058 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1065 printf("Invalid DISABLE_NETWORK command: needs one argument "
1070 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1071 if (res < 0 || (size_t) res >= sizeof(cmd))
1073 cmd[sizeof(cmd) - 1] = '\0';
1075 return wpa_ctrl_command(ctrl, cmd);
1079 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1082 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1086 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1093 printf("Invalid REMOVE_NETWORK command: needs one argument "
1098 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1099 if (res < 0 || (size_t) res >= sizeof(cmd))
1101 cmd[sizeof(cmd) - 1] = '\0';
1103 return wpa_ctrl_command(ctrl, cmd);
1107 static void wpa_cli_show_network_variables(void)
1109 printf("set_network variables:\n"
1110 " ssid (network name, SSID)\n"
1111 " psk (WPA passphrase or pre-shared key)\n"
1112 " key_mgmt (key management protocol)\n"
1113 " identity (EAP identity)\n"
1114 " password (EAP password)\n"
1117 "Note: Values are entered in the same format as the "
1118 "configuration file is using,\n"
1119 "i.e., strings values need to be inside double quotation "
1121 "For example: set_network 1 ssid \"network name\"\n"
1123 "Please see wpa_supplicant.conf documentation for full list "
1124 "of\navailable variables.\n");
1128 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1135 wpa_cli_show_network_variables();
1140 printf("Invalid SET_NETWORK command: needs three arguments\n"
1141 "(network id, variable name, and value)\n");
1145 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1146 argv[0], argv[1], argv[2]);
1147 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1148 printf("Too long SET_NETWORK command.\n");
1151 return wpa_ctrl_command(ctrl, cmd);
1155 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1162 wpa_cli_show_network_variables();
1167 printf("Invalid GET_NETWORK command: needs two arguments\n"
1168 "(network id and variable name)\n");
1172 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1174 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1175 printf("Too long GET_NETWORK command.\n");
1178 return wpa_ctrl_command(ctrl, cmd);
1182 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1185 return wpa_ctrl_command(ctrl, "DISCONNECT");
1189 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1192 return wpa_ctrl_command(ctrl, "RECONNECT");
1196 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1199 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1203 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1205 return wpa_ctrl_command(ctrl, "SCAN");
1209 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1212 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1216 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1222 printf("Invalid BSS command: need one argument (index or "
1227 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1228 if (res < 0 || (size_t) res >= sizeof(cmd))
1230 cmd[sizeof(cmd) - 1] = '\0';
1232 return wpa_ctrl_command(ctrl, cmd);
1236 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1242 if (argc < 1 || argc > 2) {
1243 printf("Invalid GET_CAPABILITY command: need either one or "
1248 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1249 printf("Invalid GET_CAPABILITY command: second argument, "
1250 "if any, must be 'strict'\n");
1254 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1255 (argc == 2) ? " strict" : "");
1256 if (res < 0 || (size_t) res >= sizeof(cmd))
1258 cmd[sizeof(cmd) - 1] = '\0';
1260 return wpa_ctrl_command(ctrl, cmd);
1264 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1266 printf("Available interfaces:\n");
1267 return wpa_ctrl_command(ctrl, "INTERFACES");
1271 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1274 wpa_cli_list_interfaces(ctrl);
1278 wpa_cli_close_connection();
1279 os_free(ctrl_ifname);
1280 ctrl_ifname = os_strdup(argv[0]);
1282 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1283 printf("Connected to interface '%s.\n", ctrl_ifname);
1285 printf("Could not connect to interface '%s' - re-trying\n",
1292 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1295 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1299 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1302 return wpa_ctrl_command(ctrl, "TERMINATE");
1306 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1313 printf("Invalid INTERFACE_ADD command: needs at least one "
1314 "argument (interface name)\n"
1315 "All arguments: ifname confname driver ctrl_interface "
1316 "driver_param bridge_name\n");
1321 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1322 * <driver_param>TAB<bridge_name>
1324 res = os_snprintf(cmd, sizeof(cmd),
1325 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1327 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1328 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1329 argc > 5 ? argv[5] : "");
1330 if (res < 0 || (size_t) res >= sizeof(cmd))
1332 cmd[sizeof(cmd) - 1] = '\0';
1333 return wpa_ctrl_command(ctrl, cmd);
1337 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1344 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1345 "(interface name)\n");
1349 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1350 if (res < 0 || (size_t) res >= sizeof(cmd))
1352 cmd[sizeof(cmd) - 1] = '\0';
1353 return wpa_ctrl_command(ctrl, cmd);
1357 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1360 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1365 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1369 printf("Invalid 'sta' command - exactly one argument, STA "
1370 "address, is required.\n");
1373 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1374 return wpa_ctrl_command(ctrl, buf);
1378 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1379 char *addr, size_t addr_len)
1381 char buf[4096], *pos;
1385 if (ctrl_conn == NULL) {
1386 printf("Not connected to hostapd - command dropped.\n");
1389 len = sizeof(buf) - 1;
1390 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1393 printf("'%s' command timed out.\n", cmd);
1395 } else if (ret < 0) {
1396 printf("'%s' command failed.\n", cmd);
1401 if (memcmp(buf, "FAIL", 4) == 0)
1406 while (*pos != '\0' && *pos != '\n')
1409 os_strlcpy(addr, buf, addr_len);
1414 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1416 char addr[32], cmd[64];
1418 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1421 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1422 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1426 #endif /* CONFIG_AP */
1429 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1431 return wpa_ctrl_command(ctrl, "SUSPEND");
1435 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1437 return wpa_ctrl_command(ctrl, "RESUME");
1441 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1443 return wpa_ctrl_command(ctrl, "DROP_SA");
1447 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1453 printf("Invalid ROAM command: needs one argument "
1454 "(target AP's BSSID)\n");
1458 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1459 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1460 printf("Too long ROAM command.\n");
1463 return wpa_ctrl_command(ctrl, cmd);
1467 enum wpa_cli_cmd_flags {
1468 cli_cmd_flag_none = 0x00,
1469 cli_cmd_flag_sensitive = 0x01
1472 struct wpa_cli_cmd {
1474 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1475 enum wpa_cli_cmd_flags flags;
1479 static struct wpa_cli_cmd wpa_cli_commands[] = {
1480 { "status", wpa_cli_cmd_status,
1482 "[verbose] = get current WPA/EAPOL/EAP status" },
1483 { "ping", wpa_cli_cmd_ping,
1485 "= pings wpa_supplicant" },
1486 { "mib", wpa_cli_cmd_mib,
1488 "= get MIB variables (dot1x, dot11)" },
1489 { "help", wpa_cli_cmd_help,
1491 "= show this usage help" },
1492 { "interface", wpa_cli_cmd_interface,
1494 "[ifname] = show interfaces/select interface" },
1495 { "level", wpa_cli_cmd_level,
1497 "<debug level> = change debug level" },
1498 { "license", wpa_cli_cmd_license,
1500 "= show full wpa_cli license" },
1501 { "quit", wpa_cli_cmd_quit,
1504 { "set", wpa_cli_cmd_set,
1506 "= set variables (shows list of variables when run without "
1508 { "logon", wpa_cli_cmd_logon,
1510 "= IEEE 802.1X EAPOL state machine logon" },
1511 { "logoff", wpa_cli_cmd_logoff,
1513 "= IEEE 802.1X EAPOL state machine logoff" },
1514 { "pmksa", wpa_cli_cmd_pmksa,
1516 "= show PMKSA cache" },
1517 { "reassociate", wpa_cli_cmd_reassociate,
1519 "= force reassociation" },
1520 { "preauthenticate", wpa_cli_cmd_preauthenticate,
1522 "<BSSID> = force preauthentication" },
1523 { "identity", wpa_cli_cmd_identity,
1525 "<network id> <identity> = configure identity for an SSID" },
1526 { "password", wpa_cli_cmd_password,
1527 cli_cmd_flag_sensitive,
1528 "<network id> <password> = configure password for an SSID" },
1529 { "new_password", wpa_cli_cmd_new_password,
1530 cli_cmd_flag_sensitive,
1531 "<network id> <password> = change password for an SSID" },
1532 { "pin", wpa_cli_cmd_pin,
1533 cli_cmd_flag_sensitive,
1534 "<network id> <pin> = configure pin for an SSID" },
1535 { "otp", wpa_cli_cmd_otp,
1536 cli_cmd_flag_sensitive,
1537 "<network id> <password> = configure one-time-password for an SSID"
1539 { "passphrase", wpa_cli_cmd_passphrase,
1540 cli_cmd_flag_sensitive,
1541 "<network id> <passphrase> = configure private key passphrase\n"
1543 { "bssid", wpa_cli_cmd_bssid,
1545 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1546 { "list_networks", wpa_cli_cmd_list_networks,
1548 "= list configured networks" },
1549 { "select_network", wpa_cli_cmd_select_network,
1551 "<network id> = select a network (disable others)" },
1552 { "enable_network", wpa_cli_cmd_enable_network,
1554 "<network id> = enable a network" },
1555 { "disable_network", wpa_cli_cmd_disable_network,
1557 "<network id> = disable a network" },
1558 { "add_network", wpa_cli_cmd_add_network,
1560 "= add a network" },
1561 { "remove_network", wpa_cli_cmd_remove_network,
1563 "<network id> = remove a network" },
1564 { "set_network", wpa_cli_cmd_set_network,
1565 cli_cmd_flag_sensitive,
1566 "<network id> <variable> <value> = set network variables (shows\n"
1567 " list of variables when run without arguments)" },
1568 { "get_network", wpa_cli_cmd_get_network,
1570 "<network id> <variable> = get network variables" },
1571 { "save_config", wpa_cli_cmd_save_config,
1573 "= save the current configuration" },
1574 { "disconnect", wpa_cli_cmd_disconnect,
1576 "= disconnect and wait for reassociate/reconnect command before\n"
1578 { "reconnect", wpa_cli_cmd_reconnect,
1580 "= like reassociate, but only takes effect if already disconnected"
1582 { "scan", wpa_cli_cmd_scan,
1584 "= request new BSS scan" },
1585 { "scan_results", wpa_cli_cmd_scan_results,
1587 "= get latest scan results" },
1588 { "bss", wpa_cli_cmd_bss,
1590 "<<idx> | <bssid>> = get detailed scan result info" },
1591 { "get_capability", wpa_cli_cmd_get_capability,
1593 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1594 { "reconfigure", wpa_cli_cmd_reconfigure,
1596 "= force wpa_supplicant to re-read its configuration file" },
1597 { "terminate", wpa_cli_cmd_terminate,
1599 "= terminate wpa_supplicant" },
1600 { "interface_add", wpa_cli_cmd_interface_add,
1602 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1603 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1605 { "interface_remove", wpa_cli_cmd_interface_remove,
1607 "<ifname> = removes the interface" },
1608 { "interface_list", wpa_cli_cmd_interface_list,
1610 "= list available interfaces" },
1611 { "ap_scan", wpa_cli_cmd_ap_scan,
1613 "<value> = set ap_scan parameter" },
1614 { "stkstart", wpa_cli_cmd_stkstart,
1616 "<addr> = request STK negotiation with <addr>" },
1617 { "ft_ds", wpa_cli_cmd_ft_ds,
1619 "<addr> = request over-the-DS FT with <addr>" },
1620 { "wps_pbc", wpa_cli_cmd_wps_pbc,
1622 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1623 { "wps_pin", wpa_cli_cmd_wps_pin,
1624 cli_cmd_flag_sensitive,
1625 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1627 #ifdef CONFIG_WPS_OOB
1628 { "wps_oob", wpa_cli_cmd_wps_oob,
1629 cli_cmd_flag_sensitive,
1630 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1631 #endif /* CONFIG_WPS_OOB */
1632 { "wps_reg", wpa_cli_cmd_wps_reg,
1633 cli_cmd_flag_sensitive,
1634 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1635 { "wps_er_start", wpa_cli_cmd_wps_er_start,
1637 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
1638 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1640 "= stop Wi-Fi Protected Setup External Registrar" },
1641 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
1642 cli_cmd_flag_sensitive,
1643 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1644 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
1646 "<UUID> = accept an Enrollee PBC using External Registrar" },
1647 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
1648 cli_cmd_flag_sensitive,
1649 "<UUID> <PIN> = learn AP configuration" },
1650 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1652 "<addr> = request RSN authentication with <addr> in IBSS" },
1654 { "sta", wpa_cli_cmd_sta,
1656 "<addr> = get information about an associated station (AP)" },
1657 { "all_sta", wpa_cli_cmd_all_sta,
1659 "= get information about all associated stations (AP)" },
1660 #endif /* CONFIG_AP */
1661 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
1662 "= notification of suspend/hibernate" },
1663 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
1664 "= notification of resume/thaw" },
1665 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
1666 "= drop SA without deauth/disassoc (test command)" },
1667 { "roam", wpa_cli_cmd_roam,
1669 "<addr> = roam to the specified BSS" },
1670 { NULL, NULL, cli_cmd_flag_none, NULL }
1675 * Prints command usage, lines are padded with the specified string.
1677 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1682 printf("%s%s ", pad, cmd->cmd);
1683 for (n = 0; (c = cmd->usage[n]); n++) {
1692 static void print_help(void)
1695 printf("commands:\n");
1696 for (n = 0; wpa_cli_commands[n].cmd; n++)
1697 print_cmd_help(&wpa_cli_commands[n], " ");
1701 #ifdef CONFIG_READLINE
1702 static int cmd_has_sensitive_data(const char *cmd)
1704 const char *c, *delim;
1708 delim = os_strchr(cmd, ' ');
1712 len = os_strlen(cmd);
1714 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1715 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1716 return (wpa_cli_commands[n].flags &
1717 cli_cmd_flag_sensitive);
1721 #endif /* CONFIG_READLINE */
1724 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1726 struct wpa_cli_cmd *cmd, *match = NULL;
1731 cmd = wpa_cli_commands;
1733 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1736 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1737 /* we have an exact match */
1747 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1748 cmd = wpa_cli_commands;
1750 if (os_strncasecmp(cmd->cmd, argv[0],
1751 os_strlen(argv[0])) == 0) {
1752 printf(" %s", cmd->cmd);
1758 } else if (count == 0) {
1759 printf("Unknown command '%s'\n", argv[0]);
1762 ret = match->handler(ctrl, argc - 1, &argv[1]);
1769 static int str_match(const char *a, const char *b)
1771 return os_strncmp(a, b, os_strlen(b)) == 0;
1775 static int wpa_cli_exec(const char *program, const char *arg1,
1783 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1784 cmd = os_malloc(len);
1787 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1788 if (res < 0 || (size_t) res >= len) {
1792 cmd[len - 1] = '\0';
1794 if (system(cmd) < 0)
1796 #endif /* _WIN32_WCE */
1803 static void wpa_cli_action_process(const char *msg)
1806 char *copy = NULL, *id, *pos2;
1811 pos = os_strchr(pos, '>');
1818 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1820 os_unsetenv("WPA_ID");
1821 os_unsetenv("WPA_ID_STR");
1822 os_unsetenv("WPA_CTRL_DIR");
1824 pos = os_strstr(pos, "[id=");
1826 copy = os_strdup(pos + 4);
1830 while (*pos2 && *pos2 != ' ')
1834 os_setenv("WPA_ID", id, 1);
1835 while (*pos2 && *pos2 != '=')
1840 while (*pos2 && *pos2 != ']')
1843 os_setenv("WPA_ID_STR", id, 1);
1847 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1849 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1850 wpa_cli_connected = 1;
1851 wpa_cli_last_id = new_id;
1852 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1854 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1855 if (wpa_cli_connected) {
1856 wpa_cli_connected = 0;
1857 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1859 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1860 printf("wpa_supplicant is terminating - stop monitoring\n");
1866 #ifndef CONFIG_ANSI_C_EXTRA
1867 static void wpa_cli_action_cb(char *msg, size_t len)
1869 wpa_cli_action_process(msg);
1871 #endif /* CONFIG_ANSI_C_EXTRA */
1874 static void wpa_cli_reconnect(void)
1876 wpa_cli_close_connection();
1877 wpa_cli_open_connection(ctrl_ifname, 1);
1881 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1885 if (ctrl_conn == NULL) {
1886 wpa_cli_reconnect();
1889 while (wpa_ctrl_pending(ctrl) > 0) {
1891 size_t len = sizeof(buf) - 1;
1892 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1895 wpa_cli_action_process(buf);
1897 if (in_read && first)
1900 printf("%s\n", buf);
1901 #ifdef CONFIG_READLINE
1904 #endif /* CONFIG_READLINE */
1907 printf("Could not read pending message.\n");
1912 if (wpa_ctrl_pending(ctrl) < 0) {
1913 printf("Connection to wpa_supplicant lost - trying to "
1915 wpa_cli_reconnect();
1920 #ifdef CONFIG_READLINE
1921 static char * wpa_cli_cmd_gen(const char *text, int state)
1928 len = os_strlen(text);
1931 while ((cmd = wpa_cli_commands[i].cmd)) {
1933 if (os_strncasecmp(cmd, text, len) == 0)
1941 static char * wpa_cli_dummy_gen(const char *text, int state)
1945 for (i = 0; wpa_cli_commands[i].cmd; i++) {
1946 const char *cmd = wpa_cli_commands[i].cmd;
1947 size_t len = os_strlen(cmd);
1948 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
1949 rl_line_buffer[len] == ' ') {
1950 printf("\n%s\n", wpa_cli_commands[i].usage);
1957 rl_attempted_completion_over = 1;
1962 static char * wpa_cli_status_gen(const char *text, int state)
1972 len = os_strlen(text);
1975 while ((t = options[i])) {
1977 if (os_strncasecmp(t, text, len) == 0)
1981 rl_attempted_completion_over = 1;
1986 static char ** wpa_cli_completion(const char *text, int start, int end)
1988 char * (*func)(const char *text, int state);
1991 func = wpa_cli_cmd_gen;
1992 else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
1993 func = wpa_cli_status_gen;
1995 func = wpa_cli_dummy_gen;
1996 return rl_completion_matches(text, func);
1998 #endif /* CONFIG_READLINE */
2001 static void wpa_cli_interactive(void)
2004 char cmdbuf[256], *cmd, *argv[max_args], *pos;
2006 #ifdef CONFIG_READLINE
2007 char *home, *hfile = NULL;
2008 #endif /* CONFIG_READLINE */
2010 printf("\nInteractive mode\n\n");
2012 #ifdef CONFIG_READLINE
2013 rl_attempted_completion_function = wpa_cli_completion;
2014 home = getenv("HOME");
2016 const char *fname = ".wpa_cli_history";
2017 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
2018 hfile = os_malloc(hfile_len);
2021 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
2023 if (res >= 0 && res < hfile_len) {
2024 hfile[hfile_len - 1] = '\0';
2025 read_history(hfile);
2026 stifle_history(100);
2030 #endif /* CONFIG_READLINE */
2033 wpa_cli_recv_pending(mon_conn, 0, 0);
2034 #ifndef CONFIG_NATIVE_WINDOWS
2035 alarm(ping_interval);
2036 #endif /* CONFIG_NATIVE_WINDOWS */
2037 #ifdef CONFIG_WPA_CLI_FORK
2039 kill(mon_pid, SIGUSR1);
2040 #endif /* CONFIG_WPA_CLI_FORK */
2041 #ifdef CONFIG_READLINE
2042 cmd = readline("> ");
2045 while (next_history())
2047 h = previous_history();
2048 if (h == NULL || os_strcmp(cmd, h->line) != 0)
2052 #else /* CONFIG_READLINE */
2054 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
2055 #endif /* CONFIG_READLINE */
2056 #ifndef CONFIG_NATIVE_WINDOWS
2058 #endif /* CONFIG_NATIVE_WINDOWS */
2061 wpa_cli_recv_pending(mon_conn, 0, 0);
2063 while (*pos != '\0') {
2079 if (argc == max_args)
2082 char *pos2 = os_strrchr(pos, '"');
2086 while (*pos != '\0' && *pos != ' ')
2092 wpa_request(ctrl_conn, argc, argv);
2096 #ifdef CONFIG_WPA_CLI_FORK
2098 kill(mon_pid, SIGUSR2);
2099 #endif /* CONFIG_WPA_CLI_FORK */
2100 } while (!wpa_cli_quit);
2102 #ifdef CONFIG_READLINE
2104 /* Save command history, excluding lines that may contain
2108 while ((h = current_history())) {
2110 while (*p == ' ' || *p == '\t')
2112 if (cmd_has_sensitive_data(p)) {
2113 h = remove_history(where_history());
2123 write_history(hfile);
2126 #endif /* CONFIG_READLINE */
2130 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2132 #ifdef CONFIG_ANSI_C_EXTRA
2133 /* TODO: ANSI C version(?) */
2134 printf("Action processing not supported in ANSI C build.\n");
2135 #else /* CONFIG_ANSI_C_EXTRA */
2139 char buf[256]; /* note: large enough to fit in unsolicited messages */
2142 fd = wpa_ctrl_get_fd(ctrl);
2144 while (!wpa_cli_quit) {
2147 tv.tv_sec = ping_interval;
2149 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2150 if (res < 0 && errno != EINTR) {
2155 if (FD_ISSET(fd, &rfds))
2156 wpa_cli_recv_pending(ctrl, 0, 1);
2158 /* verify that connection is still working */
2159 len = sizeof(buf) - 1;
2160 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2161 wpa_cli_action_cb) < 0 ||
2162 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2163 printf("wpa_supplicant did not reply to PING "
2164 "command - exiting\n");
2169 #endif /* CONFIG_ANSI_C_EXTRA */
2173 static void wpa_cli_cleanup(void)
2175 wpa_cli_close_connection();
2177 os_daemonize_terminate(pid_file);
2179 os_program_deinit();
2182 static void wpa_cli_terminate(int sig)
2189 #ifdef CONFIG_WPA_CLI_FORK
2190 static void wpa_cli_usr1(int sig)
2192 #ifdef CONFIG_READLINE
2195 #endif /* CONFIG_READLINE */
2197 #endif /* CONFIG_WPA_CLI_FORK */
2200 #ifndef CONFIG_NATIVE_WINDOWS
2201 static void wpa_cli_alarm(int sig)
2203 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2204 printf("Connection to wpa_supplicant lost - trying to "
2206 wpa_cli_close_connection();
2209 wpa_cli_reconnect();
2211 wpa_cli_recv_pending(mon_conn, 1, 0);
2212 alarm(ping_interval);
2214 #endif /* CONFIG_NATIVE_WINDOWS */
2217 static char * wpa_cli_get_default_ifname(void)
2219 char *ifname = NULL;
2221 #ifdef CONFIG_CTRL_IFACE_UNIX
2222 struct dirent *dent;
2223 DIR *dir = opendir(ctrl_iface_dir);
2226 while ((dent = readdir(dir))) {
2227 #ifdef _DIRENT_HAVE_D_TYPE
2229 * Skip the file if it is not a socket. Also accept
2230 * DT_UNKNOWN (0) in case the C library or underlying
2231 * file system does not support d_type.
2233 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2235 #endif /* _DIRENT_HAVE_D_TYPE */
2236 if (os_strcmp(dent->d_name, ".") == 0 ||
2237 os_strcmp(dent->d_name, "..") == 0)
2239 printf("Selected interface '%s'\n", dent->d_name);
2240 ifname = os_strdup(dent->d_name);
2244 #endif /* CONFIG_CTRL_IFACE_UNIX */
2246 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2247 char buf[2048], *pos;
2249 struct wpa_ctrl *ctrl;
2252 ctrl = wpa_ctrl_open(NULL);
2256 len = sizeof(buf) - 1;
2257 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2260 pos = os_strchr(buf, '\n');
2263 ifname = os_strdup(buf);
2265 wpa_ctrl_close(ctrl);
2266 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2272 int main(int argc, char *argv[])
2274 int warning_displayed = 0;
2278 const char *global = NULL;
2280 if (os_program_init())
2284 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2289 action_file = optarg;
2298 ping_interval = atoi(optarg);
2304 printf("%s\n", wpa_cli_version);
2307 os_free(ctrl_ifname);
2308 ctrl_ifname = os_strdup(optarg);
2311 ctrl_iface_dir = optarg;
2322 interactive = (argc == optind) && (action_file == NULL);
2325 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2328 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2329 ctrl_conn = wpa_ctrl_open(NULL);
2330 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2331 ctrl_conn = wpa_ctrl_open(global);
2332 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2333 if (ctrl_conn == NULL) {
2334 perror("Failed to connect to wpa_supplicant - "
2341 signal(SIGINT, wpa_cli_terminate);
2342 signal(SIGTERM, wpa_cli_terminate);
2343 #endif /* _WIN32_WCE */
2344 #ifndef CONFIG_NATIVE_WINDOWS
2345 signal(SIGALRM, wpa_cli_alarm);
2346 #endif /* CONFIG_NATIVE_WINDOWS */
2347 #ifdef CONFIG_WPA_CLI_FORK
2348 signal(SIGUSR1, wpa_cli_usr1);
2349 #endif /* CONFIG_WPA_CLI_FORK */
2351 if (ctrl_ifname == NULL)
2352 ctrl_ifname = wpa_cli_get_default_ifname();
2356 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
2357 if (warning_displayed)
2358 printf("Connection established.\n");
2362 if (!warning_displayed) {
2363 printf("Could not connect to wpa_supplicant - "
2365 warning_displayed = 1;
2372 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
2373 perror("Failed to connect to wpa_supplicant - "
2379 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2380 wpa_cli_attached = 1;
2382 printf("Warning: Failed to attach to "
2383 "wpa_supplicant.\n");
2389 if (daemonize && os_daemonize(pid_file))
2393 wpa_cli_interactive();
2394 else if (action_file)
2395 wpa_cli_action(ctrl_conn);
2397 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2399 os_free(ctrl_ifname);
2405 #else /* CONFIG_CTRL_IFACE */
2406 int main(int argc, char *argv[])
2408 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2411 #endif /* CONFIG_CTRL_IFACE */