2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2008, 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 */
27 #define CTRL_INTERFACE_2_SOCKETS
33 #include <cutils/properties.h>
36 static const char *wpa_cli_version =
37 "wpa_cli v" VERSION_STR "\n"
38 "Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> and contributors";
41 static const char *wpa_cli_license =
42 "This program is free software. You can distribute it and/or modify it\n"
43 "under the terms of the GNU General Public License version 2.\n"
45 "Alternatively, this software may be distributed under the terms of the\n"
46 "BSD license. See README and COPYING for more details.\n";
48 static const char *wpa_cli_full_license =
49 "This program is free software; you can redistribute it and/or modify\n"
50 "it under the terms of the GNU General Public License version 2 as\n"
51 "published by the Free Software Foundation.\n"
53 "This program is distributed in the hope that it will be useful,\n"
54 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
55 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
56 "GNU General Public License for more details.\n"
58 "You should have received a copy of the GNU General Public License\n"
59 "along with this program; if not, write to the Free Software\n"
60 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
62 "Alternatively, this software may be distributed under the terms of the\n"
65 "Redistribution and use in source and binary forms, with or without\n"
66 "modification, are permitted provided that the following conditions are\n"
69 "1. Redistributions of source code must retain the above copyright\n"
70 " notice, this list of conditions and the following disclaimer.\n"
72 "2. Redistributions in binary form must reproduce the above copyright\n"
73 " notice, this list of conditions and the following disclaimer in the\n"
74 " documentation and/or other materials provided with the distribution.\n"
76 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
77 " names of its contributors may be used to endorse or promote products\n"
78 " derived from this software without specific prior written permission.\n"
80 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
81 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
82 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
83 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
84 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
85 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
86 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
87 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
88 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
89 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
90 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
93 static const char *commands_help =
95 " status [verbose] = get current WPA/EAPOL/EAP status\n"
96 " mib = get MIB variables (dot1x, dot11)\n"
97 " help = show this usage help\n"
98 " interface [ifname] = show interfaces/select interface\n"
99 " level <debug level> = change debug level\n"
100 " license = show full wpa_cli license\n"
101 " logoff = IEEE 802.1X EAPOL state machine logoff\n"
102 " logon = IEEE 802.1X EAPOL state machine logon\n"
103 " set = set variables (shows list of variables when run without arguments)\n"
104 " pmksa = show PMKSA cache\n"
105 " reassociate = force reassociation\n"
106 " reconfigure = force wpa_supplicant to re-read its configuration file\n"
107 " preauthenticate <BSSID> = force preauthentication\n"
108 " identity <network id> <identity> = configure identity for an SSID\n"
109 " password <network id> <password> = configure password for an SSID\n"
110 " new_password <network id> <password> = change password for an SSID\n"
111 " pin <network id> <pin> = configure pin for an SSID\n"
112 " otp <network id> <password> = configure one-time-password for an SSID\n"
113 " passphrase <network id> <passphrase> = configure private key passphrase\n"
115 " bssid <network id> <BSSID> = set preferred BSSID for an SSID\n"
116 " blacklist [<BSSID>] = add a BSSID to the blacklist\n"
117 " blacklist clear = clear the blacklist\n"
118 " blacklist = display the blacklist\n"
119 " list_networks = list configured networks\n"
120 " select_network <network id> = select a network (disable others)\n"
121 " enable_network <network id> = enable a network\n"
122 " disable_network <network id> = disable a network\n"
123 " add_network = add a network\n"
124 " remove_network <network id> = remove a network\n"
125 " set_network <network id> <variable> <value> = set network variables "
127 " list of variables when run without arguments)\n"
128 " get_network <network id> <variable> = get network variables\n"
129 " save_config = save the current configuration\n"
130 " disconnect = disconnect and wait for reassociate/reconnect command before\n "
132 " reconnect = like reassociate, but only takes effect if already "
134 " scan = request new BSS scan\n"
135 " scan_results = get latest scan results\n"
136 " get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = "
138 " ap_scan <value> = set ap_scan parameter\n"
139 " stkstart <addr> = request STK negotiation with <addr>\n"
140 " terminate = terminate wpa_supplicant\n"
141 " quit = exit wpa_cli\n";
143 static struct wpa_ctrl *ctrl_conn;
144 static struct wpa_ctrl *monitor_conn;
145 static int wpa_cli_quit = 0;
146 static int wpa_cli_attached = 0;
147 static int wpa_cli_connected = 0;
148 static int wpa_cli_last_id = 0;
150 static const char *ctrl_iface_dir = "/data/misc/wifi/wpa_supplicant";
152 static const char *ctrl_iface_dir = "/tmp/run/wpa_supplicant";
154 static char *ctrl_ifname = NULL;
155 static const char *pid_file = NULL;
156 static const char *action_file = NULL;
159 static void usage(void)
161 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
162 "[-a<action file>] \\\n"
163 " [-P<pid file>] [-g<global ctrl>] [command..]\n"
164 " -h = help (show this usage text)\n"
165 " -v = shown version information\n"
166 " -a = run in daemon mode executing the action file based on "
169 " -B = run a daemon in the background\n"
170 " default path: /var/run/wpa_supplicant\n"
171 " default interface: first interface found in socket path\n"
177 static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
179 struct wpa_ctrl *cur_conn;
180 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
181 cur_conn = wpa_ctrl_open(ifname);
183 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
191 if (access(ctrl_iface_dir, F_OK) < 0)
192 cfile = (char *)ifname;
195 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
196 cfile = os_malloc(flen);
199 os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
204 cur_conn = wpa_ctrl_open(cfile); /* Dm: */
205 #ifdef CTRL_INTERFACE_2_SOCKETS
206 monitor_conn = wpa_ctrl_open(cfile);
208 monitor_conn = cur_conn;
215 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
219 static void wpa_cli_close_connection(void)
221 if (ctrl_conn == NULL)
224 if (wpa_cli_attached) {
225 wpa_ctrl_detach(monitor_conn);
226 wpa_cli_attached = 0;
228 #ifdef CTRL_INTERFACE_2_SOCKETS
229 wpa_ctrl_close(monitor_conn);
231 wpa_ctrl_close(ctrl_conn);
232 ctrl_conn = monitor_conn = NULL;
236 static void wpa_cli_msg_cb(char *msg, size_t len)
242 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
248 if (ctrl_conn == NULL) {
249 printf("Not connected to wpa_supplicant - command dropped.\n");
252 len = sizeof(buf) - 1;
253 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
256 printf("'%s' command timed out.\n", cmd);
258 } else if (ret < 0) {
259 printf("'%s' command failed.\n", cmd);
270 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
272 return _wpa_ctrl_command(ctrl, cmd, 1);
276 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
278 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
279 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
283 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
285 return wpa_ctrl_command(ctrl, "PING");
289 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
291 return wpa_ctrl_command(ctrl, "MIB");
295 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
297 return wpa_ctrl_command(ctrl, "PMKSA");
301 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
303 printf("%s", commands_help);
308 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
310 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
315 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
322 static void wpa_cli_show_variables(void)
324 printf("set variables:\n"
325 " EAPOL::heldPeriod (EAPOL state machine held period, "
327 " EAPOL::authPeriod (EAPOL state machine authentication "
328 "period, in seconds)\n"
329 " EAPOL::startPeriod (EAPOL state machine start period, in "
331 " EAPOL::maxStart (EAPOL state machine maximum start "
333 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
335 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
336 " threshold\n\tpercentage)\n"
337 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
338 "security\n\tassociation in seconds)\n");
342 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
348 wpa_cli_show_variables();
353 printf("Invalid SET command: needs two arguments (variable "
354 "name and value)\n");
358 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
359 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
360 printf("Too long SET command.\n");
363 return wpa_ctrl_command(ctrl, cmd);
367 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
369 return wpa_ctrl_command(ctrl, "LOGOFF");
373 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
375 return wpa_ctrl_command(ctrl, "LOGON");
379 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
382 return wpa_ctrl_command(ctrl, "REASSOCIATE");
386 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
393 printf("Invalid PREAUTH command: needs one argument "
398 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
399 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
400 printf("Too long PREAUTH command.\n");
403 return wpa_ctrl_command(ctrl, cmd);
407 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
413 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
417 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
418 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
419 printf("Too long AP_SCAN command.\n");
422 return wpa_ctrl_command(ctrl, cmd);
426 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
433 printf("Invalid STKSTART command: needs one argument "
434 "(Peer STA MAC address)\n");
438 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
439 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
440 printf("Too long STKSTART command.\n");
443 return wpa_ctrl_command(ctrl, cmd);
447 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
453 printf("Invalid LEVEL command: needs one argument (debug "
457 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
458 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
459 printf("Too long LEVEL command.\n");
462 return wpa_ctrl_command(ctrl, cmd);
466 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
468 char cmd[256], *pos, *end;
472 printf("Invalid IDENTITY command: needs two arguments "
473 "(network id and identity)\n");
477 end = cmd + sizeof(cmd);
479 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
481 if (ret < 0 || ret >= end - pos) {
482 printf("Too long IDENTITY command.\n");
486 for (i = 2; i < argc; i++) {
487 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
488 if (ret < 0 || ret >= end - pos) {
489 printf("Too long IDENTITY command.\n");
495 return wpa_ctrl_command(ctrl, cmd);
499 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
501 char cmd[256], *pos, *end;
505 printf("Invalid PASSWORD command: needs two arguments "
506 "(network id and password)\n");
510 end = cmd + sizeof(cmd);
512 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
514 if (ret < 0 || ret >= end - pos) {
515 printf("Too long PASSWORD command.\n");
519 for (i = 2; i < argc; i++) {
520 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
521 if (ret < 0 || ret >= end - pos) {
522 printf("Too long PASSWORD command.\n");
528 return wpa_ctrl_command(ctrl, cmd);
532 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
535 char cmd[256], *pos, *end;
539 printf("Invalid NEW_PASSWORD command: needs two arguments "
540 "(network id and password)\n");
544 end = cmd + sizeof(cmd);
546 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
548 if (ret < 0 || ret >= end - pos) {
549 printf("Too long NEW_PASSWORD command.\n");
553 for (i = 2; i < argc; i++) {
554 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
555 if (ret < 0 || ret >= end - pos) {
556 printf("Too long NEW_PASSWORD command.\n");
562 return wpa_ctrl_command(ctrl, cmd);
566 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
568 char cmd[256], *pos, *end;
572 printf("Invalid PIN command: needs two arguments "
573 "(network id and pin)\n");
577 end = cmd + sizeof(cmd);
579 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
581 if (ret < 0 || ret >= end - pos) {
582 printf("Too long PIN command.\n");
586 for (i = 2; i < argc; i++) {
587 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
588 if (ret < 0 || ret >= end - pos) {
589 printf("Too long PIN command.\n");
594 return wpa_ctrl_command(ctrl, cmd);
598 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
600 char cmd[256], *pos, *end;
604 printf("Invalid OTP command: needs two arguments (network "
605 "id and password)\n");
609 end = cmd + sizeof(cmd);
611 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
613 if (ret < 0 || ret >= end - pos) {
614 printf("Too long OTP command.\n");
618 for (i = 2; i < argc; i++) {
619 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
620 if (ret < 0 || ret >= end - pos) {
621 printf("Too long OTP command.\n");
627 return wpa_ctrl_command(ctrl, cmd);
631 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
634 char cmd[256], *pos, *end;
638 printf("Invalid PASSPHRASE command: needs two arguments "
639 "(network id and passphrase)\n");
643 end = cmd + sizeof(cmd);
645 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
647 if (ret < 0 || ret >= end - pos) {
648 printf("Too long PASSPHRASE command.\n");
652 for (i = 2; i < argc; i++) {
653 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
654 if (ret < 0 || ret >= end - pos) {
655 printf("Too long PASSPHRASE command.\n");
661 return wpa_ctrl_command(ctrl, cmd);
665 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
667 char cmd[256], *pos, *end;
671 printf("Invalid BSSID command: needs two arguments (network "
676 end = cmd + sizeof(cmd);
678 ret = os_snprintf(pos, end - pos, "BSSID");
679 if (ret < 0 || ret >= end - pos) {
680 printf("Too long BSSID command.\n");
684 for (i = 0; i < argc; i++) {
685 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
686 if (ret < 0 || ret >= end - pos) {
687 printf("Too long BSSID command.\n");
693 return wpa_ctrl_command(ctrl, cmd);
697 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
699 char cmd[256], *pos, *end;
702 end = cmd + sizeof(cmd);
704 ret = os_snprintf(pos, end - pos, "BLACKLIST");
705 if (ret < 0 || ret >= end - pos) {
706 printf("Too long BLACKLIST command.\n");
710 for (i = 0; i < argc; i++) {
711 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
712 if (ret < 0 || ret >= end - pos) {
713 printf("Too long BLACKLIST command.\n");
719 return wpa_ctrl_command(ctrl, cmd);
723 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
726 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
730 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
736 printf("Invalid SELECT_NETWORK command: needs one argument "
741 os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
742 cmd[sizeof(cmd) - 1] = '\0';
744 return wpa_ctrl_command(ctrl, cmd);
748 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
754 printf("Invalid ENABLE_NETWORK command: needs one argument "
759 os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
760 cmd[sizeof(cmd) - 1] = '\0';
762 return wpa_ctrl_command(ctrl, cmd);
766 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
772 printf("Invalid DISABLE_NETWORK command: needs one argument "
777 os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
778 cmd[sizeof(cmd) - 1] = '\0';
780 return wpa_ctrl_command(ctrl, cmd);
784 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
787 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
791 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
797 printf("Invalid REMOVE_NETWORK command: needs one argument "
802 os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
803 cmd[sizeof(cmd) - 1] = '\0';
805 return wpa_ctrl_command(ctrl, cmd);
809 static void wpa_cli_show_network_variables(void)
811 printf("set_network variables:\n"
812 " ssid (network name, SSID)\n"
813 " psk (WPA passphrase or pre-shared key)\n"
814 " key_mgmt (key management protocol)\n"
815 " identity (EAP identity)\n"
816 " password (EAP password)\n"
819 "Note: Values are entered in the same format as the "
820 "configuration file is using,\n"
821 "i.e., strings values need to be inside double quotation "
823 "For example: set_network 1 ssid \"network name\"\n"
825 "Please see wpa_supplicant.conf documentation for full list "
826 "of\navailable variables.\n");
830 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
837 wpa_cli_show_network_variables();
842 printf("Invalid SET_NETWORK command: needs three arguments\n"
843 "(network id, variable name, and value)\n");
847 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
848 argv[0], argv[1], argv[2]);
849 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
850 printf("Too long SET_NETWORK command.\n");
853 return wpa_ctrl_command(ctrl, cmd);
857 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
864 wpa_cli_show_network_variables();
869 printf("Invalid GET_NETWORK command: needs two arguments\n"
870 "(network id and variable name)\n");
874 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
876 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
877 printf("Too long GET_NETWORK command.\n");
880 return wpa_ctrl_command(ctrl, cmd);
884 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
887 return wpa_ctrl_command(ctrl, "DISCONNECT");
891 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
894 return wpa_ctrl_command(ctrl, "RECONNECT");
898 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
901 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
905 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
907 return wpa_ctrl_command(ctrl, "SCAN");
911 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
914 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
918 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
923 if (argc < 1 || argc > 2) {
924 printf("Invalid GET_CAPABILITY command: need either one or "
929 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
930 printf("Invalid GET_CAPABILITY command: second argument, "
931 "if any, must be 'strict'\n");
935 os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
936 (argc == 2) ? " strict" : "");
937 cmd[sizeof(cmd) - 1] = '\0';
939 return wpa_ctrl_command(ctrl, cmd);
943 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
945 printf("Available interfaces:\n");
946 return wpa_ctrl_command(ctrl, "INTERFACES");
950 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
953 wpa_cli_list_interfaces(ctrl);
957 wpa_cli_close_connection();
958 os_free(ctrl_ifname);
959 ctrl_ifname = os_strdup(argv[0]);
961 if ((ctrl_conn = wpa_cli_open_connection(ctrl_ifname)) != NULL) {
962 printf("Connected to interface '%s.\n", ctrl_ifname);
963 if (wpa_ctrl_attach(monitor_conn) == 0) {
964 wpa_cli_attached = 1;
966 printf("Warning: Failed to attach to "
967 "wpa_supplicant.\n");
970 printf("Could not connect to interface '%s' - re-trying\n",
977 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
980 return wpa_ctrl_command(ctrl, "RECONFIGURE");
984 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
987 return wpa_ctrl_command(ctrl, "TERMINATE");
991 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
997 printf("Invalid INTERFACE_ADD command: needs at least one "
998 "argument (interface name)\n"
999 "All arguments: ifname confname driver ctrl_interface "
1000 "driver_param bridge_name\n");
1005 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1006 * <driver_param>TAB<bridge_name>
1008 os_snprintf(cmd, sizeof(cmd), "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1010 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1011 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1012 argc > 5 ? argv[5] : "");
1013 cmd[sizeof(cmd) - 1] = '\0';
1014 return wpa_ctrl_command(ctrl, cmd);
1018 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1024 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1025 "(interface name)\n");
1029 os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1030 cmd[sizeof(cmd) - 1] = '\0';
1031 return wpa_ctrl_command(ctrl, cmd);
1034 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc,
1040 printf("Invalid DRIVER command: needs one argument (cmd)\n");
1045 os_snprintf(cmd, sizeof(cmd), "DRIVER %s %s", argv[0], argv[1]);
1047 os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
1048 cmd[sizeof(cmd) - 1] = '\0';
1050 return wpa_ctrl_command(ctrl, cmd);
1053 struct wpa_cli_cmd {
1055 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1058 static struct wpa_cli_cmd wpa_cli_commands[] = {
1059 { "status", wpa_cli_cmd_status },
1060 { "ping", wpa_cli_cmd_ping },
1061 { "mib", wpa_cli_cmd_mib },
1062 { "help", wpa_cli_cmd_help },
1063 { "interface", wpa_cli_cmd_interface },
1064 { "level", wpa_cli_cmd_level },
1065 { "license", wpa_cli_cmd_license },
1066 { "quit", wpa_cli_cmd_quit },
1067 { "set", wpa_cli_cmd_set },
1068 { "logon", wpa_cli_cmd_logon },
1069 { "logoff", wpa_cli_cmd_logoff },
1070 { "pmksa", wpa_cli_cmd_pmksa },
1071 { "reassociate", wpa_cli_cmd_reassociate },
1072 { "preauthenticate", wpa_cli_cmd_preauthenticate },
1073 { "identity", wpa_cli_cmd_identity },
1074 { "password", wpa_cli_cmd_password },
1075 { "new_password", wpa_cli_cmd_new_password },
1076 { "pin", wpa_cli_cmd_pin },
1077 { "otp", wpa_cli_cmd_otp },
1078 { "passphrase", wpa_cli_cmd_passphrase },
1079 { "bssid", wpa_cli_cmd_bssid },
1081 { "blacklist", wpa_cli_cmd_blacklist },
1083 { "list_networks", wpa_cli_cmd_list_networks },
1084 { "select_network", wpa_cli_cmd_select_network },
1085 { "enable_network", wpa_cli_cmd_enable_network },
1086 { "disable_network", wpa_cli_cmd_disable_network },
1087 { "add_network", wpa_cli_cmd_add_network },
1088 { "remove_network", wpa_cli_cmd_remove_network },
1089 { "set_network", wpa_cli_cmd_set_network },
1090 { "get_network", wpa_cli_cmd_get_network },
1091 { "save_config", wpa_cli_cmd_save_config },
1092 { "disconnect", wpa_cli_cmd_disconnect },
1093 { "reconnect", wpa_cli_cmd_reconnect },
1094 { "scan", wpa_cli_cmd_scan },
1095 { "scan_results", wpa_cli_cmd_scan_results },
1096 { "get_capability", wpa_cli_cmd_get_capability },
1097 { "reconfigure", wpa_cli_cmd_reconfigure },
1098 { "terminate", wpa_cli_cmd_terminate },
1099 { "interface_add", wpa_cli_cmd_interface_add },
1100 { "interface_remove", wpa_cli_cmd_interface_remove },
1101 { "ap_scan", wpa_cli_cmd_ap_scan },
1102 { "stkstart", wpa_cli_cmd_stkstart },
1103 { "driver", wpa_cli_cmd_driver },
1108 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1110 struct wpa_cli_cmd *cmd, *match = NULL;
1115 cmd = wpa_cli_commands;
1117 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1120 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1121 /* we have an exact match */
1131 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1132 cmd = wpa_cli_commands;
1134 if (os_strncasecmp(cmd->cmd, argv[0],
1135 os_strlen(argv[0])) == 0) {
1136 printf(" %s", cmd->cmd);
1142 } else if (count == 0) {
1143 printf("Unknown command '%s'\n", argv[0]);
1146 if( os_strncasecmp( "level", argv[0], os_strlen(argv[0]) ) == 0 ) {
1147 ctrl = monitor_conn;
1149 ret = match->handler(ctrl, argc - 1, &argv[1]);
1156 static int str_match(const char *a, const char *b)
1158 return os_strncmp(a, b, os_strlen(b)) == 0;
1162 static int wpa_cli_exec(const char *program, const char *arg1,
1168 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1169 cmd = os_malloc(len);
1172 os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1173 cmd[len - 1] = '\0';
1176 #endif /* _WIN32_WCE */
1183 static void wpa_cli_action_process(const char *msg)
1186 char *copy = NULL, *id, *pos2;
1191 pos = os_strchr(pos, '>');
1198 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1200 os_unsetenv("WPA_ID");
1201 os_unsetenv("WPA_ID_STR");
1202 os_unsetenv("WPA_CTRL_DIR");
1204 pos = os_strstr(pos, "[id=");
1206 copy = os_strdup(pos + 4);
1210 while (*pos2 && *pos2 != ' ')
1214 os_setenv("WPA_ID", id, 1);
1215 while (*pos2 && *pos2 != '=')
1220 while (*pos2 && *pos2 != ']')
1223 os_setenv("WPA_ID_STR", id, 1);
1227 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1229 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1230 wpa_cli_connected = 1;
1231 wpa_cli_last_id = new_id;
1232 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1234 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1235 if (wpa_cli_connected) {
1236 wpa_cli_connected = 0;
1237 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1239 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1240 printf("wpa_supplicant is terminating - stop monitoring\n");
1246 #ifndef CONFIG_ANSI_C_EXTRA
1247 static void wpa_cli_action_cb(char *msg, size_t len)
1249 wpa_cli_action_process(msg);
1251 #endif /* CONFIG_ANSI_C_EXTRA */
1254 static void wpa_cli_reconnect(void)
1256 wpa_cli_close_connection();
1257 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1259 printf("Connection to wpa_supplicant re-established\n");
1260 if (wpa_ctrl_attach(monitor_conn) == 0) {
1261 wpa_cli_attached = 1;
1263 printf("Warning: Failed to attach to "
1264 "wpa_supplicant.\n");
1270 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1275 wpa_cli_reconnect();
1278 while (wpa_ctrl_pending(ctrl) > 0) {
1280 size_t len = sizeof(buf) - 1;
1281 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1284 wpa_cli_action_process(buf);
1286 if (in_read && first)
1289 printf("%s\n", buf);
1292 printf("Could not read pending message.\n");
1297 if (wpa_ctrl_pending(ctrl) < 0) {
1298 printf("Connection to wpa_supplicant lost - trying to "
1300 wpa_cli_reconnect();
1305 #ifdef CONFIG_READLINE
1306 static char * wpa_cli_cmd_gen(const char *text, int state)
1313 len = os_strlen(text);
1316 while ((cmd = wpa_cli_commands[i].cmd)) {
1318 if (os_strncasecmp(cmd, text, len) == 0)
1319 return os_strdup(cmd);
1326 static char * wpa_cli_dummy_gen(const char *text, int state)
1332 static char ** wpa_cli_completion(const char *text, int start, int end)
1334 return rl_completion_matches(text, start == 0 ?
1335 wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1337 #endif /* CONFIG_READLINE */
1340 static void wpa_cli_interactive(void)
1343 char cmdbuf[256], *cmd, *argv[max_args], *pos;
1345 #ifdef CONFIG_READLINE
1346 char *home, *hfile = NULL;
1347 #endif /* CONFIG_READLINE */
1349 printf("\nInteractive mode\n\n");
1351 #ifdef CONFIG_READLINE
1352 rl_attempted_completion_function = wpa_cli_completion;
1353 home = getenv("HOME");
1355 const char *fname = ".wpa_cli_history";
1356 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1357 hfile = os_malloc(hfile_len);
1359 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
1360 hfile[hfile_len - 1] = '\0';
1361 read_history(hfile);
1362 stifle_history(100);
1365 #endif /* CONFIG_READLINE */
1368 wpa_cli_recv_pending(monitor_conn, 0, 0);
1369 #ifndef CONFIG_NATIVE_WINDOWS
1371 #endif /* CONFIG_NATIVE_WINDOWS */
1372 #ifdef CONFIG_READLINE
1373 cmd = readline("> ");
1376 while (next_history())
1378 h = previous_history();
1379 if (h == NULL || os_strcmp(cmd, h->line) != 0)
1383 #else /* CONFIG_READLINE */
1385 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1386 #endif /* CONFIG_READLINE */
1387 #ifndef CONFIG_NATIVE_WINDOWS
1389 #endif /* CONFIG_NATIVE_WINDOWS */
1392 wpa_cli_recv_pending(monitor_conn, 0, 0);
1394 while (*pos != '\0') {
1410 if (argc == max_args)
1413 char *pos2 = os_strrchr(pos, '"');
1417 while (*pos != '\0' && *pos != ' ')
1423 wpa_request(ctrl_conn, argc, argv);
1427 } while (!wpa_cli_quit);
1429 #ifdef CONFIG_READLINE
1431 /* Save command history, excluding lines that may contain
1438 while (*p == ' ' || *p == '\t')
1440 if (os_strncasecmp(p, "pa", 2) == 0 ||
1441 os_strncasecmp(p, "o", 1) == 0 ||
1442 os_strncasecmp(p, "n", 1)) {
1443 h = remove_history(where_history());
1449 h = current_history();
1454 write_history(hfile);
1457 #endif /* CONFIG_READLINE */
1461 static void wpa_cli_action(struct wpa_ctrl *ctrl)
1463 #ifdef CONFIG_ANSI_C_EXTRA
1464 /* TODO: ANSI C version(?) */
1465 printf("Action processing not supported in ANSI C build.\n");
1466 #else /* CONFIG_ANSI_C_EXTRA */
1470 char buf[256]; /* note: large enough to fit in unsolicited messages */
1473 fd = wpa_ctrl_get_fd(ctrl);
1475 while (!wpa_cli_quit) {
1480 res = select(fd + 1, &rfds, NULL, NULL, &tv);
1481 if (res < 0 && errno != EINTR) {
1486 if (FD_ISSET(fd, &rfds))
1487 wpa_cli_recv_pending(ctrl, 0, 1);
1489 /* verify that connection is still working */
1490 len = sizeof(buf) - 1;
1491 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
1492 wpa_cli_action_cb) < 0 ||
1493 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
1494 printf("wpa_supplicant did not reply to PING "
1495 "command - exiting\n");
1500 #endif /* CONFIG_ANSI_C_EXTRA */
1504 static void wpa_cli_cleanup(void)
1506 wpa_cli_close_connection();
1508 os_daemonize_terminate(pid_file);
1510 os_program_deinit();
1513 static void wpa_cli_terminate(int sig)
1520 #ifndef CONFIG_NATIVE_WINDOWS
1521 static void wpa_cli_alarm(int sig)
1523 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
1524 printf("Connection to wpa_supplicant lost - trying to "
1526 wpa_cli_close_connection();
1529 wpa_cli_reconnect();
1531 wpa_cli_recv_pending(monitor_conn, 1, 0);
1534 #endif /* CONFIG_NATIVE_WINDOWS */
1537 static char * wpa_cli_get_default_ifname(void)
1539 char *ifname = NULL;
1541 #ifdef CONFIG_CTRL_IFACE_UNIX
1542 struct dirent *dent;
1543 DIR *dir = opendir(ctrl_iface_dir);
1546 char ifprop[PROPERTY_VALUE_MAX];
1547 if (property_get("wifi.interface", ifprop, NULL) != 0) {
1548 ifname = os_strdup(ifprop);
1549 printf("Using interface '%s'\n", ifname);
1555 while ((dent = readdir(dir))) {
1556 #ifdef _DIRENT_HAVE_D_TYPE
1558 * Skip the file if it is not a socket. Also accept
1559 * DT_UNKNOWN (0) in case the C library or underlying
1560 * file system does not support d_type.
1562 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
1564 #endif /* _DIRENT_HAVE_D_TYPE */
1565 if (os_strcmp(dent->d_name, ".") == 0 ||
1566 os_strcmp(dent->d_name, "..") == 0)
1568 printf("Selected interface '%s'\n", dent->d_name);
1569 ifname = os_strdup(dent->d_name);
1573 #endif /* CONFIG_CTRL_IFACE_UNIX */
1575 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1576 char buf[4096], *pos;
1578 struct wpa_ctrl *ctrl;
1581 ctrl = wpa_ctrl_open(NULL);
1585 len = sizeof(buf) - 1;
1586 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
1589 pos = os_strchr(buf, '\n');
1592 ifname = os_strdup(buf);
1594 wpa_ctrl_close(ctrl);
1595 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1601 int main(int argc, char *argv[])
1604 int warning_displayed = 0;
1608 const char *global = NULL;
1610 if (os_program_init())
1614 c = getopt(argc, argv, "a:Bg:hi:p:P:v");
1619 action_file = optarg;
1631 printf("%s\n", wpa_cli_version);
1634 os_free(ctrl_ifname);
1635 ctrl_ifname = os_strdup(optarg);
1638 ctrl_iface_dir = optarg;
1649 interactive = (argc == optind) && (action_file == NULL);
1652 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
1655 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1656 ctrl_conn = wpa_ctrl_open(NULL);
1657 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1658 ctrl_conn = wpa_ctrl_open(global);
1659 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1660 if (ctrl_conn == NULL) {
1661 perror("Failed to connect to wpa_supplicant - "
1668 if (ctrl_ifname == NULL)
1669 ctrl_ifname = wpa_cli_get_default_ifname();
1670 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1672 if (warning_displayed)
1673 printf("Connection established.\n");
1678 perror("Failed to connect to wpa_supplicant - "
1683 if (!warning_displayed) {
1684 printf("Could not connect to wpa_supplicant - "
1686 warning_displayed = 1;
1693 signal(SIGINT, wpa_cli_terminate);
1694 signal(SIGTERM, wpa_cli_terminate);
1695 #endif /* _WIN32_WCE */
1696 #ifndef CONFIG_NATIVE_WINDOWS
1697 signal(SIGALRM, wpa_cli_alarm);
1698 #endif /* CONFIG_NATIVE_WINDOWS */
1700 if (interactive || action_file) {
1701 if (wpa_ctrl_attach(monitor_conn) == 0) {
1702 wpa_cli_attached = 1;
1704 printf("Warning: Failed to attach to "
1705 "wpa_supplicant.\n");
1711 if (daemonize && os_daemonize(pid_file))
1715 wpa_cli_interactive();
1716 else if (action_file)
1717 wpa_cli_action(ctrl_conn);
1719 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
1721 os_free(ctrl_ifname);
1727 #else /* CONFIG_CTRL_IFACE */
1728 int main(int argc, char *argv[])
1730 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
1733 #endif /* CONFIG_CTRL_IFACE */