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 */
32 static const char *wpa_cli_version =
33 "wpa_cli v" VERSION_STR "\n"
34 "Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> and contributors";
37 static const char *wpa_cli_license =
38 "This program is free software. You can distribute it and/or modify it\n"
39 "under the terms of the GNU General Public License version 2.\n"
41 "Alternatively, this software may be distributed under the terms of the\n"
42 "BSD license. See README and COPYING for more details.\n";
44 static const char *wpa_cli_full_license =
45 "This program is free software; you can redistribute it and/or modify\n"
46 "it under the terms of the GNU General Public License version 2 as\n"
47 "published by the Free Software Foundation.\n"
49 "This program is distributed in the hope that it will be useful,\n"
50 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
51 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
52 "GNU General Public License for more details.\n"
54 "You should have received a copy of the GNU General Public License\n"
55 "along with this program; if not, write to the Free Software\n"
56 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
58 "Alternatively, this software may be distributed under the terms of the\n"
61 "Redistribution and use in source and binary forms, with or without\n"
62 "modification, are permitted provided that the following conditions are\n"
65 "1. Redistributions of source code must retain the above copyright\n"
66 " notice, this list of conditions and the following disclaimer.\n"
68 "2. Redistributions in binary form must reproduce the above copyright\n"
69 " notice, this list of conditions and the following disclaimer in the\n"
70 " documentation and/or other materials provided with the distribution.\n"
72 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
73 " names of its contributors may be used to endorse or promote products\n"
74 " derived from this software without specific prior written permission.\n"
76 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
77 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
78 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
79 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
80 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
81 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
82 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
83 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
84 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
85 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
86 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
89 static const char *commands_help =
91 " status [verbose] = get current WPA/EAPOL/EAP status\n"
92 " mib = get MIB variables (dot1x, dot11)\n"
93 " help = show this usage help\n"
94 " interface [ifname] = show interfaces/select interface\n"
95 " level <debug level> = change debug level\n"
96 " license = show full wpa_cli license\n"
97 " logoff = IEEE 802.1X EAPOL state machine logoff\n"
98 " logon = IEEE 802.1X EAPOL state machine logon\n"
99 " set = set variables (shows list of variables when run without arguments)\n"
100 " pmksa = show PMKSA cache\n"
101 " reassociate = force reassociation\n"
102 " reconfigure = force wpa_supplicant to re-read its configuration file\n"
103 " preauthenticate <BSSID> = force preauthentication\n"
104 " identity <network id> <identity> = configure identity for an SSID\n"
105 " password <network id> <password> = configure password for an SSID\n"
106 " new_password <network id> <password> = change password for an SSID\n"
107 " pin <network id> <pin> = configure pin for an SSID\n"
108 " otp <network id> <password> = configure one-time-password for an SSID\n"
109 " passphrase <network id> <passphrase> = configure private key passphrase\n"
111 " bssid <network id> <BSSID> = set preferred BSSID for an SSID\n"
112 " list_networks = list configured networks\n"
113 " select_network <network id> = select a network (disable others)\n"
114 " enable_network <network id> = enable a network\n"
115 " disable_network <network id> = disable a network\n"
116 " add_network = add a network\n"
117 " remove_network <network id> = remove a network\n"
118 " set_network <network id> <variable> <value> = set network variables "
120 " list of variables when run without arguments)\n"
121 " get_network <network id> <variable> = get network variables\n"
122 " save_config = save the current configuration\n"
123 " disconnect = disconnect and wait for reassociate/reconnect command before\n "
125 " reconnect = like reassociate, but only takes effect if already "
127 " scan = request new BSS scan\n"
128 " scan_results = get latest scan results\n"
129 " bss <<idx> | <bssid>> = get detailed scan result info\n"
130 " get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = "
132 " ap_scan <value> = set ap_scan parameter\n"
133 " stkstart <addr> = request STK negotiation with <addr>\n"
134 " ft_ds <addr> = request over-the-DS FT with <addr>\n"
135 " wps_pbc [BSSID] = start Wi-Fi Protected Setup: Push Button Configuration\n"
136 " wps_pin <BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
138 " wps_reg <BSSID> <AP PIN> = start WPS Registrar to configure an AP\n"
139 " terminate = terminate wpa_supplicant\n"
140 " quit = exit wpa_cli\n";
142 static struct wpa_ctrl *ctrl_conn;
143 static int wpa_cli_quit = 0;
144 static int wpa_cli_attached = 0;
145 static int wpa_cli_connected = 0;
146 static int wpa_cli_last_id = 0;
147 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
148 static char *ctrl_ifname = NULL;
149 static const char *pid_file = NULL;
150 static const char *action_file = NULL;
153 static void usage(void)
155 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
156 "[-a<action file>] \\\n"
157 " [-P<pid file>] [-g<global ctrl>] [command..]\n"
158 " -h = help (show this usage text)\n"
159 " -v = shown version information\n"
160 " -a = run in daemon mode executing the action file based on "
163 " -B = run a daemon in the background\n"
164 " default path: /var/run/wpa_supplicant\n"
165 " default interface: first interface found in socket path\n"
171 static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
173 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
174 ctrl_conn = wpa_ctrl_open(ifname);
176 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
183 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
184 cfile = os_malloc(flen);
187 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
188 if (res < 0 || res >= flen) {
193 ctrl_conn = wpa_ctrl_open(cfile);
196 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
200 static void wpa_cli_close_connection(void)
202 if (ctrl_conn == NULL)
205 if (wpa_cli_attached) {
206 wpa_ctrl_detach(ctrl_conn);
207 wpa_cli_attached = 0;
209 wpa_ctrl_close(ctrl_conn);
214 static void wpa_cli_msg_cb(char *msg, size_t len)
220 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
226 if (ctrl_conn == NULL) {
227 printf("Not connected to wpa_supplicant - command dropped.\n");
230 len = sizeof(buf) - 1;
231 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
234 printf("'%s' command timed out.\n", cmd);
236 } else if (ret < 0) {
237 printf("'%s' command failed.\n", cmd);
248 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
250 return _wpa_ctrl_command(ctrl, cmd, 1);
254 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
256 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
257 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
261 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
263 return wpa_ctrl_command(ctrl, "PING");
267 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
269 return wpa_ctrl_command(ctrl, "MIB");
273 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
275 return wpa_ctrl_command(ctrl, "PMKSA");
279 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
281 printf("%s", commands_help);
286 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
288 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
293 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
300 static void wpa_cli_show_variables(void)
302 printf("set variables:\n"
303 " EAPOL::heldPeriod (EAPOL state machine held period, "
305 " EAPOL::authPeriod (EAPOL state machine authentication "
306 "period, in seconds)\n"
307 " EAPOL::startPeriod (EAPOL state machine start period, in "
309 " EAPOL::maxStart (EAPOL state machine maximum start "
311 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
313 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
314 " threshold\n\tpercentage)\n"
315 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
316 "security\n\tassociation in seconds)\n");
320 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
326 wpa_cli_show_variables();
331 printf("Invalid SET command: needs two arguments (variable "
332 "name and value)\n");
336 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
337 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
338 printf("Too long SET command.\n");
341 return wpa_ctrl_command(ctrl, cmd);
345 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
347 return wpa_ctrl_command(ctrl, "LOGOFF");
351 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
353 return wpa_ctrl_command(ctrl, "LOGON");
357 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
360 return wpa_ctrl_command(ctrl, "REASSOCIATE");
364 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
371 printf("Invalid PREAUTH command: needs one argument "
376 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
377 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
378 printf("Too long PREAUTH command.\n");
381 return wpa_ctrl_command(ctrl, cmd);
385 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
391 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
395 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
396 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
397 printf("Too long AP_SCAN command.\n");
400 return wpa_ctrl_command(ctrl, cmd);
404 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
411 printf("Invalid STKSTART command: needs one argument "
412 "(Peer STA MAC address)\n");
416 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
417 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
418 printf("Too long STKSTART command.\n");
421 return wpa_ctrl_command(ctrl, cmd);
425 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
431 printf("Invalid FT_DS command: needs one argument "
432 "(Target AP MAC address)\n");
436 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
437 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
438 printf("Too long FT_DS command.\n");
441 return wpa_ctrl_command(ctrl, cmd);
445 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
452 return wpa_ctrl_command(ctrl, "WPS_PBC");
456 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
457 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
458 printf("Too long WPS_PBC command.\n");
461 return wpa_ctrl_command(ctrl, cmd);
465 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
471 printf("Invalid WPS_PIN command: need one or two arguments:\n"
472 "- BSSID: use 'any' to select any\n"
473 "- PIN: optional, used only with devices that have no "
479 /* Use dynamically generated PIN (returned as reply) */
480 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
481 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
482 printf("Too long WPS_PIN command.\n");
485 return wpa_ctrl_command(ctrl, cmd);
488 /* Use hardcoded PIN from a label */
489 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
490 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
491 printf("Too long WPS_PIN command.\n");
494 return wpa_ctrl_command(ctrl, cmd);
498 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
504 printf("Invalid WPS_REG command: need two arguments:\n"
505 "- BSSID: use 'any' to select any\n"
510 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", argv[0], argv[1]);
511 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
512 printf("Too long WPS_REG command.\n");
515 return wpa_ctrl_command(ctrl, cmd);
519 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
525 printf("Invalid LEVEL command: needs one argument (debug "
529 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
530 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
531 printf("Too long LEVEL command.\n");
534 return wpa_ctrl_command(ctrl, cmd);
538 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
540 char cmd[256], *pos, *end;
544 printf("Invalid IDENTITY command: needs two arguments "
545 "(network id and identity)\n");
549 end = cmd + sizeof(cmd);
551 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
553 if (ret < 0 || ret >= end - pos) {
554 printf("Too long IDENTITY command.\n");
558 for (i = 2; i < argc; i++) {
559 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
560 if (ret < 0 || ret >= end - pos) {
561 printf("Too long IDENTITY command.\n");
567 return wpa_ctrl_command(ctrl, cmd);
571 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
573 char cmd[256], *pos, *end;
577 printf("Invalid PASSWORD command: needs two arguments "
578 "(network id and password)\n");
582 end = cmd + sizeof(cmd);
584 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
586 if (ret < 0 || ret >= end - pos) {
587 printf("Too long PASSWORD command.\n");
591 for (i = 2; i < argc; i++) {
592 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
593 if (ret < 0 || ret >= end - pos) {
594 printf("Too long PASSWORD command.\n");
600 return wpa_ctrl_command(ctrl, cmd);
604 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
607 char cmd[256], *pos, *end;
611 printf("Invalid NEW_PASSWORD command: needs two arguments "
612 "(network id and password)\n");
616 end = cmd + sizeof(cmd);
618 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
620 if (ret < 0 || ret >= end - pos) {
621 printf("Too long NEW_PASSWORD command.\n");
625 for (i = 2; i < argc; i++) {
626 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
627 if (ret < 0 || ret >= end - pos) {
628 printf("Too long NEW_PASSWORD command.\n");
634 return wpa_ctrl_command(ctrl, cmd);
638 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
640 char cmd[256], *pos, *end;
644 printf("Invalid PIN command: needs two arguments "
645 "(network id and pin)\n");
649 end = cmd + sizeof(cmd);
651 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
653 if (ret < 0 || ret >= end - pos) {
654 printf("Too long PIN command.\n");
658 for (i = 2; i < argc; i++) {
659 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
660 if (ret < 0 || ret >= end - pos) {
661 printf("Too long PIN command.\n");
666 return wpa_ctrl_command(ctrl, cmd);
670 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
672 char cmd[256], *pos, *end;
676 printf("Invalid OTP command: needs two arguments (network "
677 "id and password)\n");
681 end = cmd + sizeof(cmd);
683 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
685 if (ret < 0 || ret >= end - pos) {
686 printf("Too long OTP command.\n");
690 for (i = 2; i < argc; i++) {
691 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
692 if (ret < 0 || ret >= end - pos) {
693 printf("Too long OTP command.\n");
699 return wpa_ctrl_command(ctrl, cmd);
703 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
706 char cmd[256], *pos, *end;
710 printf("Invalid PASSPHRASE command: needs two arguments "
711 "(network id and passphrase)\n");
715 end = cmd + sizeof(cmd);
717 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
719 if (ret < 0 || ret >= end - pos) {
720 printf("Too long PASSPHRASE command.\n");
724 for (i = 2; i < argc; i++) {
725 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
726 if (ret < 0 || ret >= end - pos) {
727 printf("Too long PASSPHRASE command.\n");
733 return wpa_ctrl_command(ctrl, cmd);
737 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
739 char cmd[256], *pos, *end;
743 printf("Invalid BSSID command: needs two arguments (network "
748 end = cmd + sizeof(cmd);
750 ret = os_snprintf(pos, end - pos, "BSSID");
751 if (ret < 0 || ret >= end - pos) {
752 printf("Too long BSSID command.\n");
756 for (i = 0; i < argc; i++) {
757 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
758 if (ret < 0 || ret >= end - pos) {
759 printf("Too long BSSID command.\n");
765 return wpa_ctrl_command(ctrl, cmd);
769 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
772 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
776 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
783 printf("Invalid SELECT_NETWORK command: needs one argument "
788 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
789 if (res < 0 || (size_t) res >= sizeof(cmd))
791 cmd[sizeof(cmd) - 1] = '\0';
793 return wpa_ctrl_command(ctrl, cmd);
797 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
804 printf("Invalid ENABLE_NETWORK command: needs one argument "
809 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
810 if (res < 0 || (size_t) res >= sizeof(cmd))
812 cmd[sizeof(cmd) - 1] = '\0';
814 return wpa_ctrl_command(ctrl, cmd);
818 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
825 printf("Invalid DISABLE_NETWORK command: needs one argument "
830 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
831 if (res < 0 || (size_t) res >= sizeof(cmd))
833 cmd[sizeof(cmd) - 1] = '\0';
835 return wpa_ctrl_command(ctrl, cmd);
839 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
842 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
846 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
853 printf("Invalid REMOVE_NETWORK command: needs one argument "
858 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
859 if (res < 0 || (size_t) res >= sizeof(cmd))
861 cmd[sizeof(cmd) - 1] = '\0';
863 return wpa_ctrl_command(ctrl, cmd);
867 static void wpa_cli_show_network_variables(void)
869 printf("set_network variables:\n"
870 " ssid (network name, SSID)\n"
871 " psk (WPA passphrase or pre-shared key)\n"
872 " key_mgmt (key management protocol)\n"
873 " identity (EAP identity)\n"
874 " password (EAP password)\n"
877 "Note: Values are entered in the same format as the "
878 "configuration file is using,\n"
879 "i.e., strings values need to be inside double quotation "
881 "For example: set_network 1 ssid \"network name\"\n"
883 "Please see wpa_supplicant.conf documentation for full list "
884 "of\navailable variables.\n");
888 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
895 wpa_cli_show_network_variables();
900 printf("Invalid SET_NETWORK command: needs three arguments\n"
901 "(network id, variable name, and value)\n");
905 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
906 argv[0], argv[1], argv[2]);
907 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
908 printf("Too long SET_NETWORK command.\n");
911 return wpa_ctrl_command(ctrl, cmd);
915 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
922 wpa_cli_show_network_variables();
927 printf("Invalid GET_NETWORK command: needs two arguments\n"
928 "(network id and variable name)\n");
932 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
934 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
935 printf("Too long GET_NETWORK command.\n");
938 return wpa_ctrl_command(ctrl, cmd);
942 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
945 return wpa_ctrl_command(ctrl, "DISCONNECT");
949 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
952 return wpa_ctrl_command(ctrl, "RECONNECT");
956 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
959 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
963 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
965 return wpa_ctrl_command(ctrl, "SCAN");
969 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
972 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
976 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
982 printf("Invalid BSS command: need one argument (index or "
987 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
988 if (res < 0 || (size_t) res >= sizeof(cmd))
990 cmd[sizeof(cmd) - 1] = '\0';
992 return wpa_ctrl_command(ctrl, cmd);
996 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1002 if (argc < 1 || argc > 2) {
1003 printf("Invalid GET_CAPABILITY command: need either one or "
1008 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1009 printf("Invalid GET_CAPABILITY command: second argument, "
1010 "if any, must be 'strict'\n");
1014 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1015 (argc == 2) ? " strict" : "");
1016 if (res < 0 || (size_t) res >= sizeof(cmd))
1018 cmd[sizeof(cmd) - 1] = '\0';
1020 return wpa_ctrl_command(ctrl, cmd);
1024 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1026 printf("Available interfaces:\n");
1027 return wpa_ctrl_command(ctrl, "INTERFACES");
1031 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1034 wpa_cli_list_interfaces(ctrl);
1038 wpa_cli_close_connection();
1039 os_free(ctrl_ifname);
1040 ctrl_ifname = os_strdup(argv[0]);
1042 if (wpa_cli_open_connection(ctrl_ifname)) {
1043 printf("Connected to interface '%s.\n", ctrl_ifname);
1044 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1045 wpa_cli_attached = 1;
1047 printf("Warning: Failed to attach to "
1048 "wpa_supplicant.\n");
1051 printf("Could not connect to interface '%s' - re-trying\n",
1058 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1061 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1065 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1068 return wpa_ctrl_command(ctrl, "TERMINATE");
1072 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1079 printf("Invalid INTERFACE_ADD command: needs at least one "
1080 "argument (interface name)\n"
1081 "All arguments: ifname confname driver ctrl_interface "
1082 "driver_param bridge_name\n");
1087 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1088 * <driver_param>TAB<bridge_name>
1090 res = os_snprintf(cmd, sizeof(cmd),
1091 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1093 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1094 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1095 argc > 5 ? argv[5] : "");
1096 if (res < 0 || (size_t) res >= sizeof(cmd))
1098 cmd[sizeof(cmd) - 1] = '\0';
1099 return wpa_ctrl_command(ctrl, cmd);
1103 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1110 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1111 "(interface name)\n");
1115 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1116 if (res < 0 || (size_t) res >= sizeof(cmd))
1118 cmd[sizeof(cmd) - 1] = '\0';
1119 return wpa_ctrl_command(ctrl, cmd);
1123 struct wpa_cli_cmd {
1125 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1128 static struct wpa_cli_cmd wpa_cli_commands[] = {
1129 { "status", wpa_cli_cmd_status },
1130 { "ping", wpa_cli_cmd_ping },
1131 { "mib", wpa_cli_cmd_mib },
1132 { "help", wpa_cli_cmd_help },
1133 { "interface", wpa_cli_cmd_interface },
1134 { "level", wpa_cli_cmd_level },
1135 { "license", wpa_cli_cmd_license },
1136 { "quit", wpa_cli_cmd_quit },
1137 { "set", wpa_cli_cmd_set },
1138 { "logon", wpa_cli_cmd_logon },
1139 { "logoff", wpa_cli_cmd_logoff },
1140 { "pmksa", wpa_cli_cmd_pmksa },
1141 { "reassociate", wpa_cli_cmd_reassociate },
1142 { "preauthenticate", wpa_cli_cmd_preauthenticate },
1143 { "identity", wpa_cli_cmd_identity },
1144 { "password", wpa_cli_cmd_password },
1145 { "new_password", wpa_cli_cmd_new_password },
1146 { "pin", wpa_cli_cmd_pin },
1147 { "otp", wpa_cli_cmd_otp },
1148 { "passphrase", wpa_cli_cmd_passphrase },
1149 { "bssid", wpa_cli_cmd_bssid },
1150 { "list_networks", wpa_cli_cmd_list_networks },
1151 { "select_network", wpa_cli_cmd_select_network },
1152 { "enable_network", wpa_cli_cmd_enable_network },
1153 { "disable_network", wpa_cli_cmd_disable_network },
1154 { "add_network", wpa_cli_cmd_add_network },
1155 { "remove_network", wpa_cli_cmd_remove_network },
1156 { "set_network", wpa_cli_cmd_set_network },
1157 { "get_network", wpa_cli_cmd_get_network },
1158 { "save_config", wpa_cli_cmd_save_config },
1159 { "disconnect", wpa_cli_cmd_disconnect },
1160 { "reconnect", wpa_cli_cmd_reconnect },
1161 { "scan", wpa_cli_cmd_scan },
1162 { "scan_results", wpa_cli_cmd_scan_results },
1163 { "bss", wpa_cli_cmd_bss },
1164 { "get_capability", wpa_cli_cmd_get_capability },
1165 { "reconfigure", wpa_cli_cmd_reconfigure },
1166 { "terminate", wpa_cli_cmd_terminate },
1167 { "interface_add", wpa_cli_cmd_interface_add },
1168 { "interface_remove", wpa_cli_cmd_interface_remove },
1169 { "ap_scan", wpa_cli_cmd_ap_scan },
1170 { "stkstart", wpa_cli_cmd_stkstart },
1171 { "ft_ds", wpa_cli_cmd_ft_ds },
1172 { "wps_pbc", wpa_cli_cmd_wps_pbc },
1173 { "wps_pin", wpa_cli_cmd_wps_pin },
1174 { "wps_reg", wpa_cli_cmd_wps_reg },
1179 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1181 struct wpa_cli_cmd *cmd, *match = NULL;
1186 cmd = wpa_cli_commands;
1188 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1191 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1192 /* we have an exact match */
1202 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1203 cmd = wpa_cli_commands;
1205 if (os_strncasecmp(cmd->cmd, argv[0],
1206 os_strlen(argv[0])) == 0) {
1207 printf(" %s", cmd->cmd);
1213 } else if (count == 0) {
1214 printf("Unknown command '%s'\n", argv[0]);
1217 ret = match->handler(ctrl, argc - 1, &argv[1]);
1224 static int str_match(const char *a, const char *b)
1226 return os_strncmp(a, b, os_strlen(b)) == 0;
1230 static int wpa_cli_exec(const char *program, const char *arg1,
1238 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1239 cmd = os_malloc(len);
1242 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1243 if (res < 0 || (size_t) res >= len) {
1247 cmd[len - 1] = '\0';
1249 if (system(cmd) < 0)
1251 #endif /* _WIN32_WCE */
1258 static void wpa_cli_action_process(const char *msg)
1261 char *copy = NULL, *id, *pos2;
1266 pos = os_strchr(pos, '>');
1273 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1275 os_unsetenv("WPA_ID");
1276 os_unsetenv("WPA_ID_STR");
1277 os_unsetenv("WPA_CTRL_DIR");
1279 pos = os_strstr(pos, "[id=");
1281 copy = os_strdup(pos + 4);
1285 while (*pos2 && *pos2 != ' ')
1289 os_setenv("WPA_ID", id, 1);
1290 while (*pos2 && *pos2 != '=')
1295 while (*pos2 && *pos2 != ']')
1298 os_setenv("WPA_ID_STR", id, 1);
1302 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1304 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1305 wpa_cli_connected = 1;
1306 wpa_cli_last_id = new_id;
1307 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1309 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1310 if (wpa_cli_connected) {
1311 wpa_cli_connected = 0;
1312 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1314 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1315 printf("wpa_supplicant is terminating - stop monitoring\n");
1321 #ifndef CONFIG_ANSI_C_EXTRA
1322 static void wpa_cli_action_cb(char *msg, size_t len)
1324 wpa_cli_action_process(msg);
1326 #endif /* CONFIG_ANSI_C_EXTRA */
1329 static void wpa_cli_reconnect(void)
1331 wpa_cli_close_connection();
1332 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1334 printf("Connection to wpa_supplicant re-established\n");
1335 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1336 wpa_cli_attached = 1;
1338 printf("Warning: Failed to attach to "
1339 "wpa_supplicant.\n");
1345 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1349 if (ctrl_conn == NULL) {
1350 wpa_cli_reconnect();
1353 while (wpa_ctrl_pending(ctrl) > 0) {
1355 size_t len = sizeof(buf) - 1;
1356 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1359 wpa_cli_action_process(buf);
1361 if (in_read && first)
1364 printf("%s\n", buf);
1367 printf("Could not read pending message.\n");
1372 if (wpa_ctrl_pending(ctrl) < 0) {
1373 printf("Connection to wpa_supplicant lost - trying to "
1375 wpa_cli_reconnect();
1380 #ifdef CONFIG_READLINE
1381 static char * wpa_cli_cmd_gen(const char *text, int state)
1388 len = os_strlen(text);
1391 while ((cmd = wpa_cli_commands[i].cmd)) {
1393 if (os_strncasecmp(cmd, text, len) == 0)
1394 return os_strdup(cmd);
1401 static char * wpa_cli_dummy_gen(const char *text, int state)
1407 static char ** wpa_cli_completion(const char *text, int start, int end)
1409 return rl_completion_matches(text, start == 0 ?
1410 wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1412 #endif /* CONFIG_READLINE */
1415 static void wpa_cli_interactive(void)
1418 char cmdbuf[256], *cmd, *argv[max_args], *pos;
1420 #ifdef CONFIG_READLINE
1421 char *home, *hfile = NULL;
1422 #endif /* CONFIG_READLINE */
1424 printf("\nInteractive mode\n\n");
1426 #ifdef CONFIG_READLINE
1427 rl_attempted_completion_function = wpa_cli_completion;
1428 home = getenv("HOME");
1430 const char *fname = ".wpa_cli_history";
1431 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1432 hfile = os_malloc(hfile_len);
1435 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
1437 if (res >= 0 && res < hfile_len) {
1438 hfile[hfile_len - 1] = '\0';
1439 read_history(hfile);
1440 stifle_history(100);
1444 #endif /* CONFIG_READLINE */
1447 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1448 #ifndef CONFIG_NATIVE_WINDOWS
1450 #endif /* CONFIG_NATIVE_WINDOWS */
1451 #ifdef CONFIG_READLINE
1452 cmd = readline("> ");
1455 while (next_history())
1457 h = previous_history();
1458 if (h == NULL || os_strcmp(cmd, h->line) != 0)
1462 #else /* CONFIG_READLINE */
1464 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1465 #endif /* CONFIG_READLINE */
1466 #ifndef CONFIG_NATIVE_WINDOWS
1468 #endif /* CONFIG_NATIVE_WINDOWS */
1471 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1473 while (*pos != '\0') {
1489 if (argc == max_args)
1492 char *pos2 = os_strrchr(pos, '"');
1496 while (*pos != '\0' && *pos != ' ')
1502 wpa_request(ctrl_conn, argc, argv);
1506 } while (!wpa_cli_quit);
1508 #ifdef CONFIG_READLINE
1510 /* Save command history, excluding lines that may contain
1517 while (*p == ' ' || *p == '\t')
1519 if (os_strncasecmp(p, "pa", 2) == 0 ||
1520 os_strncasecmp(p, "o", 1) == 0 ||
1521 os_strncasecmp(p, "n", 1)) {
1522 h = remove_history(where_history());
1528 h = current_history();
1533 write_history(hfile);
1536 #endif /* CONFIG_READLINE */
1540 static void wpa_cli_action(struct wpa_ctrl *ctrl)
1542 #ifdef CONFIG_ANSI_C_EXTRA
1543 /* TODO: ANSI C version(?) */
1544 printf("Action processing not supported in ANSI C build.\n");
1545 #else /* CONFIG_ANSI_C_EXTRA */
1549 char buf[256]; /* note: large enough to fit in unsolicited messages */
1552 fd = wpa_ctrl_get_fd(ctrl);
1554 while (!wpa_cli_quit) {
1559 res = select(fd + 1, &rfds, NULL, NULL, &tv);
1560 if (res < 0 && errno != EINTR) {
1565 if (FD_ISSET(fd, &rfds))
1566 wpa_cli_recv_pending(ctrl, 0, 1);
1568 /* verify that connection is still working */
1569 len = sizeof(buf) - 1;
1570 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
1571 wpa_cli_action_cb) < 0 ||
1572 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
1573 printf("wpa_supplicant did not reply to PING "
1574 "command - exiting\n");
1579 #endif /* CONFIG_ANSI_C_EXTRA */
1583 static void wpa_cli_cleanup(void)
1585 wpa_cli_close_connection();
1587 os_daemonize_terminate(pid_file);
1589 os_program_deinit();
1592 static void wpa_cli_terminate(int sig)
1599 #ifndef CONFIG_NATIVE_WINDOWS
1600 static void wpa_cli_alarm(int sig)
1602 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
1603 printf("Connection to wpa_supplicant lost - trying to "
1605 wpa_cli_close_connection();
1608 wpa_cli_reconnect();
1610 wpa_cli_recv_pending(ctrl_conn, 1, 0);
1613 #endif /* CONFIG_NATIVE_WINDOWS */
1616 static char * wpa_cli_get_default_ifname(void)
1618 char *ifname = NULL;
1620 #ifdef CONFIG_CTRL_IFACE_UNIX
1621 struct dirent *dent;
1622 DIR *dir = opendir(ctrl_iface_dir);
1625 while ((dent = readdir(dir))) {
1626 #ifdef _DIRENT_HAVE_D_TYPE
1628 * Skip the file if it is not a socket. Also accept
1629 * DT_UNKNOWN (0) in case the C library or underlying
1630 * file system does not support d_type.
1632 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
1634 #endif /* _DIRENT_HAVE_D_TYPE */
1635 if (os_strcmp(dent->d_name, ".") == 0 ||
1636 os_strcmp(dent->d_name, "..") == 0)
1638 printf("Selected interface '%s'\n", dent->d_name);
1639 ifname = os_strdup(dent->d_name);
1643 #endif /* CONFIG_CTRL_IFACE_UNIX */
1645 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1646 char buf[2048], *pos;
1648 struct wpa_ctrl *ctrl;
1651 ctrl = wpa_ctrl_open(NULL);
1655 len = sizeof(buf) - 1;
1656 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
1659 pos = os_strchr(buf, '\n');
1662 ifname = os_strdup(buf);
1664 wpa_ctrl_close(ctrl);
1665 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1671 int main(int argc, char *argv[])
1674 int warning_displayed = 0;
1678 const char *global = NULL;
1680 if (os_program_init())
1684 c = getopt(argc, argv, "a:Bg:hi:p:P:v");
1689 action_file = optarg;
1701 printf("%s\n", wpa_cli_version);
1704 os_free(ctrl_ifname);
1705 ctrl_ifname = os_strdup(optarg);
1708 ctrl_iface_dir = optarg;
1719 interactive = (argc == optind) && (action_file == NULL);
1722 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
1725 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1726 ctrl_conn = wpa_ctrl_open(NULL);
1727 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1728 ctrl_conn = wpa_ctrl_open(global);
1729 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1730 if (ctrl_conn == NULL) {
1731 perror("Failed to connect to wpa_supplicant - "
1738 if (ctrl_ifname == NULL)
1739 ctrl_ifname = wpa_cli_get_default_ifname();
1740 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1742 if (warning_displayed)
1743 printf("Connection established.\n");
1748 perror("Failed to connect to wpa_supplicant - "
1753 if (!warning_displayed) {
1754 printf("Could not connect to wpa_supplicant - "
1756 warning_displayed = 1;
1763 signal(SIGINT, wpa_cli_terminate);
1764 signal(SIGTERM, wpa_cli_terminate);
1765 #endif /* _WIN32_WCE */
1766 #ifndef CONFIG_NATIVE_WINDOWS
1767 signal(SIGALRM, wpa_cli_alarm);
1768 #endif /* CONFIG_NATIVE_WINDOWS */
1770 if (interactive || action_file) {
1771 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1772 wpa_cli_attached = 1;
1774 printf("Warning: Failed to attach to "
1775 "wpa_supplicant.\n");
1781 if (daemonize && os_daemonize(pid_file))
1785 wpa_cli_interactive();
1786 else if (action_file)
1787 wpa_cli_action(ctrl_conn);
1789 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
1791 os_free(ctrl_ifname);
1797 #else /* CONFIG_CTRL_IFACE */
1798 int main(int argc, char *argv[])
1800 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
1803 #endif /* CONFIG_CTRL_IFACE */