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 " terminate = terminate wpa_supplicant\n"
136 " quit = exit wpa_cli\n";
138 static struct wpa_ctrl
*ctrl_conn
;
139 static int wpa_cli_quit
= 0;
140 static int wpa_cli_attached
= 0;
141 static int wpa_cli_connected
= 0;
142 static int wpa_cli_last_id
= 0;
143 static const char *ctrl_iface_dir
= "/var/run/wpa_supplicant";
144 static char *ctrl_ifname
= NULL
;
145 static const char *pid_file
= NULL
;
146 static const char *action_file
= NULL
;
149 static void usage(void)
151 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
152 "[-a<action file>] \\\n"
153 " [-P<pid file>] [-g<global ctrl>] [command..]\n"
154 " -h = help (show this usage text)\n"
155 " -v = shown version information\n"
156 " -a = run in daemon mode executing the action file based on "
159 " -B = run a daemon in the background\n"
160 " default path: /var/run/wpa_supplicant\n"
161 " default interface: first interface found in socket path\n"
167 static struct wpa_ctrl
* wpa_cli_open_connection(const char *ifname
)
169 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
170 ctrl_conn
= wpa_ctrl_open(ifname
);
172 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
179 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
180 cfile
= os_malloc(flen
);
183 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
, ifname
);
184 if (res
< 0 || res
>= flen
) {
189 ctrl_conn
= wpa_ctrl_open(cfile
);
192 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
196 static void wpa_cli_close_connection(void)
198 if (ctrl_conn
== NULL
)
201 if (wpa_cli_attached
) {
202 wpa_ctrl_detach(ctrl_conn
);
203 wpa_cli_attached
= 0;
205 wpa_ctrl_close(ctrl_conn
);
210 static const char *skip_priority(const char *msg
)
212 const char *pos
= msg
;
217 for (pos
= msg
+ 1; isdigit((unsigned char)*pos
); pos
++)
226 static const char *fmttime(char *buf
, size_t buflen
)
235 (void)gettimeofday(&tv
, NULL
);
236 t
= (time_t)tv
.tv_sec
;
237 (void)localtime_r(&t
, &tm
);
238 (void)strftime(buf
, buflen
, "%H:%M:%S", &tm
);
239 (void)snprintf(buf
+ 8, buflen
- 8, ".%.3d", (int)(tv
.tv_usec
/ 1000));
243 static void wpa_cli_msg_cb(char *msg
, size_t len
)
246 printf("%s: %s\n", fmttime(tbuf
, sizeof(tbuf
)), skip_priority(msg
));
250 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
256 if (ctrl_conn
== NULL
) {
257 printf("Not connected to wpa_supplicant - command dropped.\n");
260 len
= sizeof(buf
) - 1;
261 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
264 printf("'%s' command timed out.\n", cmd
);
266 } else if (ret
< 0) {
267 printf("'%s' command failed.\n", cmd
);
272 wpa_cli_msg_cb(buf
, 0);
278 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
280 return _wpa_ctrl_command(ctrl
, cmd
, 1);
284 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
286 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
287 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
291 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
293 return wpa_ctrl_command(ctrl
, "PING");
297 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
299 return wpa_ctrl_command(ctrl
, "MIB");
303 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
305 return wpa_ctrl_command(ctrl
, "PMKSA");
309 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
311 printf("%s", commands_help
);
316 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
318 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
323 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
330 static void wpa_cli_show_variables(void)
332 printf("set variables:\n"
333 " EAPOL::heldPeriod (EAPOL state machine held period, "
335 " EAPOL::authPeriod (EAPOL state machine authentication "
336 "period, in seconds)\n"
337 " EAPOL::startPeriod (EAPOL state machine start period, in "
339 " EAPOL::maxStart (EAPOL state machine maximum start "
341 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
343 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
344 " threshold\n\tpercentage)\n"
345 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
346 "security\n\tassociation in seconds)\n");
350 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
356 wpa_cli_show_variables();
361 printf("Invalid SET command: needs two arguments (variable "
362 "name and value)\n");
366 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s", argv
[0], argv
[1]);
367 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
368 printf("Too long SET command.\n");
371 return wpa_ctrl_command(ctrl
, cmd
);
375 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
377 return wpa_ctrl_command(ctrl
, "LOGOFF");
381 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
383 return wpa_ctrl_command(ctrl
, "LOGON");
387 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
390 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
394 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
401 printf("Invalid PREAUTH command: needs one argument "
406 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
407 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
408 printf("Too long PREAUTH command.\n");
411 return wpa_ctrl_command(ctrl
, cmd
);
415 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
421 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
425 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
426 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
427 printf("Too long AP_SCAN command.\n");
430 return wpa_ctrl_command(ctrl
, cmd
);
434 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
441 printf("Invalid STKSTART command: needs one argument "
442 "(Peer STA MAC address)\n");
446 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
447 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
448 printf("Too long STKSTART command.\n");
451 return wpa_ctrl_command(ctrl
, cmd
);
455 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
461 printf("Invalid FT_DS command: needs one argument "
462 "(Target AP MAC address)\n");
466 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
467 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
468 printf("Too long FT_DS command.\n");
471 return wpa_ctrl_command(ctrl
, cmd
);
475 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
481 printf("Invalid LEVEL command: needs one argument (debug "
485 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
486 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
487 printf("Too long LEVEL command.\n");
490 return wpa_ctrl_command(ctrl
, cmd
);
494 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
496 char cmd
[256], *pos
, *end
;
500 printf("Invalid IDENTITY command: needs two arguments "
501 "(network id and identity)\n");
505 end
= cmd
+ sizeof(cmd
);
507 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
509 if (ret
< 0 || ret
>= end
- pos
) {
510 printf("Too long IDENTITY command.\n");
514 for (i
= 2; i
< argc
; i
++) {
515 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
516 if (ret
< 0 || ret
>= end
- pos
) {
517 printf("Too long IDENTITY command.\n");
523 return wpa_ctrl_command(ctrl
, cmd
);
527 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
529 char cmd
[256], *pos
, *end
;
533 printf("Invalid PASSWORD command: needs two arguments "
534 "(network id and password)\n");
538 end
= cmd
+ sizeof(cmd
);
540 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
542 if (ret
< 0 || ret
>= end
- pos
) {
543 printf("Too long PASSWORD command.\n");
547 for (i
= 2; i
< argc
; i
++) {
548 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
549 if (ret
< 0 || ret
>= end
- pos
) {
550 printf("Too long PASSWORD command.\n");
556 return wpa_ctrl_command(ctrl
, cmd
);
560 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
563 char cmd
[256], *pos
, *end
;
567 printf("Invalid NEW_PASSWORD command: needs two arguments "
568 "(network id and password)\n");
572 end
= cmd
+ sizeof(cmd
);
574 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
576 if (ret
< 0 || ret
>= end
- pos
) {
577 printf("Too long NEW_PASSWORD command.\n");
581 for (i
= 2; i
< argc
; i
++) {
582 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
583 if (ret
< 0 || ret
>= end
- pos
) {
584 printf("Too long NEW_PASSWORD command.\n");
590 return wpa_ctrl_command(ctrl
, cmd
);
594 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
596 char cmd
[256], *pos
, *end
;
600 printf("Invalid PIN command: needs two arguments "
601 "(network id and pin)\n");
605 end
= cmd
+ sizeof(cmd
);
607 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
609 if (ret
< 0 || ret
>= end
- pos
) {
610 printf("Too long PIN command.\n");
614 for (i
= 2; i
< argc
; i
++) {
615 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
616 if (ret
< 0 || ret
>= end
- pos
) {
617 printf("Too long PIN command.\n");
622 return wpa_ctrl_command(ctrl
, cmd
);
626 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
628 char cmd
[256], *pos
, *end
;
632 printf("Invalid OTP command: needs two arguments (network "
633 "id and password)\n");
637 end
= cmd
+ sizeof(cmd
);
639 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
641 if (ret
< 0 || ret
>= end
- pos
) {
642 printf("Too long OTP command.\n");
646 for (i
= 2; i
< argc
; i
++) {
647 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
648 if (ret
< 0 || ret
>= end
- pos
) {
649 printf("Too long OTP command.\n");
655 return wpa_ctrl_command(ctrl
, cmd
);
659 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
662 char cmd
[256], *pos
, *end
;
666 printf("Invalid PASSPHRASE command: needs two arguments "
667 "(network id and passphrase)\n");
671 end
= cmd
+ sizeof(cmd
);
673 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
675 if (ret
< 0 || ret
>= end
- pos
) {
676 printf("Too long PASSPHRASE command.\n");
680 for (i
= 2; i
< argc
; i
++) {
681 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
682 if (ret
< 0 || ret
>= end
- pos
) {
683 printf("Too long PASSPHRASE command.\n");
689 return wpa_ctrl_command(ctrl
, cmd
);
693 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
695 char cmd
[256], *pos
, *end
;
699 printf("Invalid BSSID command: needs two arguments (network "
704 end
= cmd
+ sizeof(cmd
);
706 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
707 if (ret
< 0 || ret
>= end
- pos
) {
708 printf("Too long BSSID command.\n");
712 for (i
= 0; i
< argc
; i
++) {
713 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
714 if (ret
< 0 || ret
>= end
- pos
) {
715 printf("Too long BSSID command.\n");
721 return wpa_ctrl_command(ctrl
, cmd
);
725 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
728 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
732 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
739 printf("Invalid SELECT_NETWORK command: needs one argument "
744 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
745 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
747 cmd
[sizeof(cmd
) - 1] = '\0';
749 return wpa_ctrl_command(ctrl
, cmd
);
753 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
760 printf("Invalid ENABLE_NETWORK command: needs one argument "
765 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
766 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
768 cmd
[sizeof(cmd
) - 1] = '\0';
770 return wpa_ctrl_command(ctrl
, cmd
);
774 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
781 printf("Invalid DISABLE_NETWORK command: needs one argument "
786 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
787 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
789 cmd
[sizeof(cmd
) - 1] = '\0';
791 return wpa_ctrl_command(ctrl
, cmd
);
795 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
798 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
802 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
809 printf("Invalid REMOVE_NETWORK command: needs one argument "
814 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
815 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
817 cmd
[sizeof(cmd
) - 1] = '\0';
819 return wpa_ctrl_command(ctrl
, cmd
);
823 static void wpa_cli_show_network_variables(void)
825 printf("set_network variables:\n"
826 " ssid (network name, SSID)\n"
827 " psk (WPA passphrase or pre-shared key)\n"
828 " key_mgmt (key management protocol)\n"
829 " identity (EAP identity)\n"
830 " password (EAP password)\n"
833 "Note: Values are entered in the same format as the "
834 "configuration file is using,\n"
835 "i.e., strings values need to be inside double quotation "
837 "For example: set_network 1 ssid \"network name\"\n"
839 "Please see wpa_supplicant.conf documentation for full list "
840 "of\navailable variables.\n");
844 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
851 wpa_cli_show_network_variables();
856 printf("Invalid SET_NETWORK command: needs three arguments\n"
857 "(network id, variable name, and value)\n");
861 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
862 argv
[0], argv
[1], argv
[2]);
863 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
864 printf("Too long SET_NETWORK command.\n");
867 return wpa_ctrl_command(ctrl
, cmd
);
871 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
878 wpa_cli_show_network_variables();
883 printf("Invalid GET_NETWORK command: needs two arguments\n"
884 "(network id and variable name)\n");
888 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
890 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
891 printf("Too long GET_NETWORK command.\n");
894 return wpa_ctrl_command(ctrl
, cmd
);
898 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
901 return wpa_ctrl_command(ctrl
, "DISCONNECT");
905 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
908 return wpa_ctrl_command(ctrl
, "RECONNECT");
912 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
915 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
919 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
921 return wpa_ctrl_command(ctrl
, "SCAN");
925 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
928 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
932 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
938 printf("Invalid BSS command: need one argument (index or "
943 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
944 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
946 cmd
[sizeof(cmd
) - 1] = '\0';
948 return wpa_ctrl_command(ctrl
, cmd
);
952 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
958 if (argc
< 1 || argc
> 2) {
959 printf("Invalid GET_CAPABILITY command: need either one or "
964 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
965 printf("Invalid GET_CAPABILITY command: second argument, "
966 "if any, must be 'strict'\n");
970 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
971 (argc
== 2) ? " strict" : "");
972 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
974 cmd
[sizeof(cmd
) - 1] = '\0';
976 return wpa_ctrl_command(ctrl
, cmd
);
980 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
982 printf("Available interfaces:\n");
983 return wpa_ctrl_command(ctrl
, "INTERFACES");
987 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
990 wpa_cli_list_interfaces(ctrl
);
994 wpa_cli_close_connection();
995 os_free(ctrl_ifname
);
996 ctrl_ifname
= os_strdup(argv
[0]);
998 if (wpa_cli_open_connection(ctrl_ifname
)) {
999 printf("Connected to interface '%s.\n", ctrl_ifname
);
1000 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
1001 wpa_cli_attached
= 1;
1003 printf("Warning: Failed to attach to "
1004 "wpa_supplicant.\n");
1007 printf("Could not connect to interface '%s' - re-trying\n",
1014 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1017 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1021 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1024 return wpa_ctrl_command(ctrl
, "TERMINATE");
1028 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1035 printf("Invalid INTERFACE_ADD command: needs at least one "
1036 "argument (interface name)\n"
1037 "All arguments: ifname confname driver ctrl_interface "
1038 "driver_param bridge_name\n");
1043 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1044 * <driver_param>TAB<bridge_name>
1046 res
= os_snprintf(cmd
, sizeof(cmd
),
1047 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1049 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1050 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1051 argc
> 5 ? argv
[5] : "");
1052 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1054 cmd
[sizeof(cmd
) - 1] = '\0';
1055 return wpa_ctrl_command(ctrl
, cmd
);
1059 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1066 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1067 "(interface name)\n");
1071 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1072 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1074 cmd
[sizeof(cmd
) - 1] = '\0';
1075 return wpa_ctrl_command(ctrl
, cmd
);
1079 struct wpa_cli_cmd
{
1081 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
1084 static struct wpa_cli_cmd wpa_cli_commands
[] = {
1085 { "status", wpa_cli_cmd_status
},
1086 { "ping", wpa_cli_cmd_ping
},
1087 { "mib", wpa_cli_cmd_mib
},
1088 { "help", wpa_cli_cmd_help
},
1089 { "interface", wpa_cli_cmd_interface
},
1090 { "level", wpa_cli_cmd_level
},
1091 { "license", wpa_cli_cmd_license
},
1092 { "quit", wpa_cli_cmd_quit
},
1093 { "set", wpa_cli_cmd_set
},
1094 { "logon", wpa_cli_cmd_logon
},
1095 { "logoff", wpa_cli_cmd_logoff
},
1096 { "pmksa", wpa_cli_cmd_pmksa
},
1097 { "reassociate", wpa_cli_cmd_reassociate
},
1098 { "preauthenticate", wpa_cli_cmd_preauthenticate
},
1099 { "identity", wpa_cli_cmd_identity
},
1100 { "password", wpa_cli_cmd_password
},
1101 { "new_password", wpa_cli_cmd_new_password
},
1102 { "pin", wpa_cli_cmd_pin
},
1103 { "otp", wpa_cli_cmd_otp
},
1104 { "passphrase", wpa_cli_cmd_passphrase
},
1105 { "bssid", wpa_cli_cmd_bssid
},
1106 { "list_networks", wpa_cli_cmd_list_networks
},
1107 { "select_network", wpa_cli_cmd_select_network
},
1108 { "enable_network", wpa_cli_cmd_enable_network
},
1109 { "disable_network", wpa_cli_cmd_disable_network
},
1110 { "add_network", wpa_cli_cmd_add_network
},
1111 { "remove_network", wpa_cli_cmd_remove_network
},
1112 { "set_network", wpa_cli_cmd_set_network
},
1113 { "get_network", wpa_cli_cmd_get_network
},
1114 { "save_config", wpa_cli_cmd_save_config
},
1115 { "disconnect", wpa_cli_cmd_disconnect
},
1116 { "reconnect", wpa_cli_cmd_reconnect
},
1117 { "scan", wpa_cli_cmd_scan
},
1118 { "scan_results", wpa_cli_cmd_scan_results
},
1119 { "bss", wpa_cli_cmd_bss
},
1120 { "get_capability", wpa_cli_cmd_get_capability
},
1121 { "reconfigure", wpa_cli_cmd_reconfigure
},
1122 { "terminate", wpa_cli_cmd_terminate
},
1123 { "interface_add", wpa_cli_cmd_interface_add
},
1124 { "interface_remove", wpa_cli_cmd_interface_remove
},
1125 { "ap_scan", wpa_cli_cmd_ap_scan
},
1126 { "stkstart", wpa_cli_cmd_stkstart
},
1127 { "ft_ds", wpa_cli_cmd_ft_ds
},
1132 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1134 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
1139 cmd
= wpa_cli_commands
;
1141 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
1144 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
1145 /* we have an exact match */
1155 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
1156 cmd
= wpa_cli_commands
;
1158 if (os_strncasecmp(cmd
->cmd
, argv
[0],
1159 os_strlen(argv
[0])) == 0) {
1160 printf(" %s", cmd
->cmd
);
1166 } else if (count
== 0) {
1167 printf("Unknown command '%s'\n", argv
[0]);
1170 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
1177 static int str_match(const char *a
, const char *b
)
1179 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
1183 static int wpa_cli_exec(const char *program
, const char *arg1
,
1190 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
1191 cmd
= os_malloc(len
);
1194 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
1195 if (res
< 0 || (size_t) res
>= len
) {
1199 cmd
[len
- 1] = '\0';
1202 #endif /* _WIN32_WCE */
1209 static void wpa_cli_action_process(const char *msg
)
1211 const char *pos
= skip_priority(msg
);
1213 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
1216 os_unsetenv("WPA_ID");
1217 os_unsetenv("WPA_ID_STR");
1218 os_unsetenv("WPA_CTRL_DIR");
1220 pos
= os_strstr(pos
, "[id=");
1221 copy
= pos
? os_strdup(pos
+ 4) : NULL
;
1224 char *pos2
= id
= copy
;
1225 while (*pos2
&& *pos2
!= ' ')
1229 os_setenv("WPA_ID", id
, 1);
1230 while (*pos2
&& *pos2
!= '=')
1235 while (*pos2
&& *pos2
!= ']')
1238 os_setenv("WPA_ID_STR", id
, 1);
1242 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
1244 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
1245 wpa_cli_connected
= 1;
1246 wpa_cli_last_id
= new_id
;
1247 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
1249 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
1250 if (wpa_cli_connected
) {
1251 wpa_cli_connected
= 0;
1252 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
1254 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
1255 printf("wpa_supplicant is terminating - stop monitoring\n");
1261 #ifndef CONFIG_ANSI_C_EXTRA
1262 static void wpa_cli_action_cb(char *msg
, size_t len
)
1264 wpa_cli_action_process(msg
);
1266 #endif /* CONFIG_ANSI_C_EXTRA */
1269 static void wpa_cli_reconnect(void)
1271 wpa_cli_close_connection();
1272 ctrl_conn
= wpa_cli_open_connection(ctrl_ifname
);
1274 printf("Connection to wpa_supplicant re-established\n");
1275 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
1276 wpa_cli_attached
= 1;
1278 printf("Warning: Failed to attach to "
1279 "wpa_supplicant.\n");
1284 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int in_read
,
1288 if (ctrl_conn
== NULL
) {
1289 wpa_cli_reconnect();
1292 while (wpa_ctrl_pending(ctrl
) > 0) {
1294 size_t len
= sizeof(buf
) - 1;
1295 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
1298 wpa_cli_action_process(buf
);
1300 if (in_read
&& first
)
1303 wpa_cli_msg_cb(buf
, 0);
1306 printf("Could not read pending message.\n");
1311 if (wpa_ctrl_pending(ctrl
) < 0) {
1312 printf("Connection to wpa_supplicant lost - trying to "
1314 wpa_cli_reconnect();
1319 #ifdef CONFIG_READLINE
1320 static char * wpa_cli_cmd_gen(const char *text
, int state
)
1327 len
= os_strlen(text
);
1330 while ((cmd
= wpa_cli_commands
[i
].cmd
)) {
1332 if (os_strncasecmp(cmd
, text
, len
) == 0)
1333 return os_strdup(cmd
);
1340 static char * wpa_cli_dummy_gen(const char *text
, int state
)
1346 static char ** wpa_cli_completion(const char *text
, int start
, int end
)
1348 return rl_completion_matches(text
, start
== 0 ?
1349 wpa_cli_cmd_gen
: wpa_cli_dummy_gen
);
1351 #endif /* CONFIG_READLINE */
1354 static void wpa_cli_interactive(void)
1357 char cmdbuf
[256], *cmd
, *argv
[max_args
], *pos
;
1359 #ifdef CONFIG_READLINE
1360 char *home
, *hfile
= NULL
;
1361 #endif /* CONFIG_READLINE */
1363 printf("\nInteractive mode\n\n");
1365 #ifdef CONFIG_READLINE
1366 rl_attempted_completion_function
= wpa_cli_completion
;
1367 home
= getenv("HOME");
1369 const char *fname
= ".wpa_cli_history";
1370 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
1371 hfile
= os_malloc(hfile_len
);
1374 res
= os_snprintf(hfile
, hfile_len
, "%s/%s", home
,
1376 if (res
>= 0 && res
< hfile_len
) {
1377 hfile
[hfile_len
- 1] = '\0';
1378 read_history(hfile
);
1379 stifle_history(100);
1383 #endif /* CONFIG_READLINE */
1386 wpa_cli_recv_pending(ctrl_conn
, 0, 0);
1387 #ifndef CONFIG_NATIVE_WINDOWS
1389 #endif /* CONFIG_NATIVE_WINDOWS */
1390 #ifdef CONFIG_READLINE
1391 cmd
= readline("> ");
1394 while (next_history())
1396 h
= previous_history();
1397 if (h
== NULL
|| os_strcmp(cmd
, h
->line
) != 0)
1401 #else /* CONFIG_READLINE */
1403 cmd
= fgets(cmdbuf
, sizeof(cmdbuf
), stdin
);
1404 #endif /* CONFIG_READLINE */
1405 #ifndef CONFIG_NATIVE_WINDOWS
1407 #endif /* CONFIG_NATIVE_WINDOWS */
1410 wpa_cli_recv_pending(ctrl_conn
, 0, 0);
1412 while (*pos
!= '\0') {
1428 if (argc
== max_args
)
1431 char *pos2
= os_strrchr(pos
, '"');
1435 while (*pos
!= '\0' && *pos
!= ' ')
1441 wpa_request(ctrl_conn
, argc
, argv
);
1445 } while (!wpa_cli_quit
);
1447 #ifdef CONFIG_READLINE
1449 /* Save command history, excluding lines that may contain
1455 const char *p
= h
->line
;
1456 while (*p
== ' ' || *p
== '\t')
1458 if (os_strncasecmp(p
, "pa", 2) == 0 ||
1459 os_strncasecmp(p
, "o", 1) == 0 ||
1460 os_strncasecmp(p
, "n", 1)) {
1461 h
= remove_history(where_history());
1463 os_free(__UNCONST(h
->line
));
1464 os_free(__UNCONST(h
->data
));
1467 h
= current_history();
1472 write_history(hfile
);
1475 #endif /* CONFIG_READLINE */
1479 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
1481 #ifdef CONFIG_ANSI_C_EXTRA
1482 /* TODO: ANSI C version(?) */
1483 printf("Action processing not supported in ANSI C build.\n");
1484 #else /* CONFIG_ANSI_C_EXTRA */
1488 char buf
[256]; /* note: large enough to fit in unsolicited messages */
1491 fd
= wpa_ctrl_get_fd(ctrl
);
1493 while (!wpa_cli_quit
) {
1498 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
1499 if (res
< 0 && errno
!= EINTR
) {
1504 if (FD_ISSET(fd
, &rfds
))
1505 wpa_cli_recv_pending(ctrl
, 0, 1);
1507 /* verify that connection is still working */
1508 len
= sizeof(buf
) - 1;
1509 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
1510 wpa_cli_action_cb
) < 0 ||
1511 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
1512 printf("wpa_supplicant did not reply to PING "
1513 "command - exiting\n");
1518 #endif /* CONFIG_ANSI_C_EXTRA */
1522 static void wpa_cli_cleanup(void)
1524 wpa_cli_close_connection();
1526 os_daemonize_terminate(pid_file
);
1528 os_program_deinit();
1531 static void wpa_cli_terminate(int sig
)
1538 #ifndef CONFIG_NATIVE_WINDOWS
1539 static void wpa_cli_alarm(int sig
)
1541 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
1542 printf("Connection to wpa_supplicant lost - trying to "
1544 wpa_cli_close_connection();
1547 wpa_cli_reconnect();
1549 wpa_cli_recv_pending(ctrl_conn
, 1, 0);
1552 #endif /* CONFIG_NATIVE_WINDOWS */
1555 static char * wpa_cli_get_default_ifname(void)
1557 char *ifname
= NULL
;
1559 #ifdef CONFIG_CTRL_IFACE_UNIX
1560 struct dirent
*dent
;
1561 DIR *dir
= opendir(ctrl_iface_dir
);
1564 while ((dent
= readdir(dir
))) {
1565 #ifdef _DIRENT_HAVE_D_TYPE
1567 * Skip the file if it is not a socket. Also accept
1568 * DT_UNKNOWN (0) in case the C library or underlying
1569 * file system does not support d_type.
1571 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
1573 #endif /* _DIRENT_HAVE_D_TYPE */
1574 if (os_strcmp(dent
->d_name
, ".") == 0 ||
1575 os_strcmp(dent
->d_name
, "..") == 0)
1577 printf("Selected interface '%s'\n", dent
->d_name
);
1578 ifname
= os_strdup(dent
->d_name
);
1582 #endif /* CONFIG_CTRL_IFACE_UNIX */
1584 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1585 char buf
[2048], *pos
;
1587 struct wpa_ctrl
*ctrl
;
1590 ctrl
= wpa_ctrl_open(NULL
);
1594 len
= sizeof(buf
) - 1;
1595 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
1598 pos
= os_strchr(buf
, '\n');
1601 ifname
= os_strdup(buf
);
1603 wpa_ctrl_close(ctrl
);
1604 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1610 int main(int argc
, char *argv
[])
1613 int warning_displayed
= 0;
1617 const char *global
= NULL
;
1619 if (os_program_init())
1623 c
= getopt(argc
, argv
, "a:Bg:hi:p:P:v");
1628 action_file
= optarg
;
1640 printf("%s\n", wpa_cli_version
);
1643 os_free(ctrl_ifname
);
1644 ctrl_ifname
= os_strdup(optarg
);
1647 ctrl_iface_dir
= optarg
;
1658 interactive
= (argc
== optind
) && (action_file
== NULL
);
1661 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
1664 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1665 ctrl_conn
= wpa_ctrl_open(NULL
);
1666 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1667 ctrl_conn
= wpa_ctrl_open(global
);
1668 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1669 if (ctrl_conn
== NULL
) {
1670 perror("Failed to connect to wpa_supplicant - "
1677 if (ctrl_ifname
== NULL
)
1678 ctrl_ifname
= wpa_cli_get_default_ifname();
1679 ctrl_conn
= wpa_cli_open_connection(ctrl_ifname
);
1681 if (warning_displayed
)
1682 printf("Connection established.\n");
1687 perror("Failed to connect to wpa_supplicant - "
1692 if (!warning_displayed
) {
1693 printf("Could not connect to wpa_supplicant - "
1695 warning_displayed
= 1;
1702 signal(SIGINT
, wpa_cli_terminate
);
1703 signal(SIGTERM
, wpa_cli_terminate
);
1704 #endif /* _WIN32_WCE */
1705 #ifndef CONFIG_NATIVE_WINDOWS
1706 signal(SIGALRM
, wpa_cli_alarm
);
1707 #endif /* CONFIG_NATIVE_WINDOWS */
1709 if (interactive
|| action_file
) {
1710 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
1711 wpa_cli_attached
= 1;
1713 printf("Warning: Failed to attach to "
1714 "wpa_supplicant.\n");
1720 if (daemonize
&& os_daemonize(pid_file
))
1724 wpa_cli_interactive();
1725 else if (action_file
)
1726 wpa_cli_action(ctrl_conn
);
1728 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
1730 os_free(ctrl_ifname
);
1736 #else /* CONFIG_CTRL_IFACE */
1737 int main(int argc
, char *argv
[])
1739 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
1742 #endif /* CONFIG_CTRL_IFACE */