2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2007, 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-2007, 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 command before "
125 " scan = request new BSS scan\n"
126 " scan_results = get latest scan results\n"
127 " get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = "
129 " ap_scan <value> = set ap_scan parameter\n"
130 " stkstart <addr> = request STK negotiation with <addr>\n"
131 " terminate = terminate wpa_supplicant\n"
132 " quit = exit wpa_cli\n";
134 static struct wpa_ctrl
*ctrl_conn
;
135 static int wpa_cli_quit
= 0;
136 static int wpa_cli_attached
= 0;
137 static int wpa_cli_connected
= 0;
138 static int wpa_cli_last_id
= 0;
139 static const char *ctrl_iface_dir
= "/var/run/wpa_supplicant";
140 static char *ctrl_ifname
= NULL
;
141 static const char *pid_file
= NULL
;
142 static const char *action_file
= NULL
;
145 static void usage(void)
147 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
148 "[-a<action file>] \\\n"
149 " [-P<pid file>] [-g<global ctrl>] [command..]\n"
150 " -h = help (show this usage text)\n"
151 " -v = shown version information\n"
152 " -a = run in daemon mode executing the action file based on "
155 " -B = run a daemon in the background\n"
156 " default path: /var/run/wpa_supplicant\n"
157 " default interface: first interface found in socket path\n"
163 static struct wpa_ctrl
* wpa_cli_open_connection(const char *ifname
)
165 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
166 ctrl_conn
= wpa_ctrl_open(ifname
);
168 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
175 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
176 cfile
= os_malloc(flen
);
179 os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
, ifname
);
181 ctrl_conn
= wpa_ctrl_open(cfile
);
184 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
188 static void wpa_cli_close_connection(void)
190 if (ctrl_conn
== NULL
)
193 if (wpa_cli_attached
) {
194 wpa_ctrl_detach(ctrl_conn
);
195 wpa_cli_attached
= 0;
197 wpa_ctrl_close(ctrl_conn
);
202 static void wpa_cli_msg_cb(char *msg
, size_t len
)
208 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
214 if (ctrl_conn
== NULL
) {
215 printf("Not connected to wpa_supplicant - command dropped.\n");
218 len
= sizeof(buf
) - 1;
219 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
222 printf("'%s' command timed out.\n", cmd
);
224 } else if (ret
< 0) {
225 printf("'%s' command failed.\n", cmd
);
236 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
238 return _wpa_ctrl_command(ctrl
, cmd
, 1);
242 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
244 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
245 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
249 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
251 return wpa_ctrl_command(ctrl
, "PING");
255 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
257 return wpa_ctrl_command(ctrl
, "MIB");
261 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
263 return wpa_ctrl_command(ctrl
, "PMKSA");
267 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
269 printf("%s", commands_help
);
274 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
276 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
281 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
288 static void wpa_cli_show_variables(void)
290 printf("set variables:\n"
291 " EAPOL::heldPeriod (EAPOL state machine held period, "
293 " EAPOL::authPeriod (EAPOL state machine authentication "
294 "period, in seconds)\n"
295 " EAPOL::startPeriod (EAPOL state machine start period, in "
297 " EAPOL::maxStart (EAPOL state machine maximum start "
299 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
301 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
302 " threshold\n\tpercentage)\n"
303 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
304 "security\n\tassociation in seconds)\n");
308 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
314 wpa_cli_show_variables();
319 printf("Invalid SET command: needs two arguments (variable "
320 "name and value)\n");
324 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s", argv
[0], argv
[1]);
325 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
326 printf("Too long SET command.\n");
329 return wpa_ctrl_command(ctrl
, cmd
);
333 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
335 return wpa_ctrl_command(ctrl
, "LOGOFF");
339 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
341 return wpa_ctrl_command(ctrl
, "LOGON");
345 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
348 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
352 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
359 printf("Invalid PREAUTH command: needs one argument "
364 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
365 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
366 printf("Too long PREAUTH command.\n");
369 return wpa_ctrl_command(ctrl
, cmd
);
373 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
379 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
383 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
384 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
385 printf("Too long AP_SCAN command.\n");
388 return wpa_ctrl_command(ctrl
, cmd
);
392 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
399 printf("Invalid STKSTART command: needs one argument "
400 "(Peer STA MAC address)\n");
404 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
405 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
406 printf("Too long STKSTART command.\n");
409 return wpa_ctrl_command(ctrl
, cmd
);
413 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
419 printf("Invalid LEVEL command: needs one argument (debug "
423 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
424 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
425 printf("Too long LEVEL command.\n");
428 return wpa_ctrl_command(ctrl
, cmd
);
432 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
434 char cmd
[256], *pos
, *end
;
438 printf("Invalid IDENTITY command: needs two arguments "
439 "(network id and identity)\n");
443 end
= cmd
+ sizeof(cmd
);
445 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
447 if (ret
< 0 || ret
>= end
- pos
) {
448 printf("Too long IDENTITY command.\n");
452 for (i
= 2; i
< argc
; i
++) {
453 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
454 if (ret
< 0 || ret
>= end
- pos
) {
455 printf("Too long IDENTITY command.\n");
461 return wpa_ctrl_command(ctrl
, cmd
);
465 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
467 char cmd
[256], *pos
, *end
;
471 printf("Invalid PASSWORD command: needs two arguments "
472 "(network id and password)\n");
476 end
= cmd
+ sizeof(cmd
);
478 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
480 if (ret
< 0 || ret
>= end
- pos
) {
481 printf("Too long PASSWORD command.\n");
485 for (i
= 2; i
< argc
; i
++) {
486 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
487 if (ret
< 0 || ret
>= end
- pos
) {
488 printf("Too long PASSWORD command.\n");
494 return wpa_ctrl_command(ctrl
, cmd
);
498 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
501 char cmd
[256], *pos
, *end
;
505 printf("Invalid NEW_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
"NEW_PASSWORD-%s:%s",
514 if (ret
< 0 || ret
>= end
- pos
) {
515 printf("Too long NEW_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 NEW_PASSWORD command.\n");
528 return wpa_ctrl_command(ctrl
, cmd
);
532 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
534 char cmd
[256], *pos
, *end
;
538 printf("Invalid PIN command: needs two arguments "
539 "(network id and pin)\n");
543 end
= cmd
+ sizeof(cmd
);
545 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
547 if (ret
< 0 || ret
>= end
- pos
) {
548 printf("Too long PIN command.\n");
552 for (i
= 2; i
< argc
; i
++) {
553 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
554 if (ret
< 0 || ret
>= end
- pos
) {
555 printf("Too long PIN command.\n");
560 return wpa_ctrl_command(ctrl
, cmd
);
564 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
566 char cmd
[256], *pos
, *end
;
570 printf("Invalid OTP command: needs two arguments (network "
571 "id and password)\n");
575 end
= cmd
+ sizeof(cmd
);
577 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
579 if (ret
< 0 || ret
>= end
- pos
) {
580 printf("Too long OTP command.\n");
584 for (i
= 2; i
< argc
; i
++) {
585 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
586 if (ret
< 0 || ret
>= end
- pos
) {
587 printf("Too long OTP command.\n");
593 return wpa_ctrl_command(ctrl
, cmd
);
597 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
600 char cmd
[256], *pos
, *end
;
604 printf("Invalid PASSPHRASE command: needs two arguments "
605 "(network id and passphrase)\n");
609 end
= cmd
+ sizeof(cmd
);
611 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
613 if (ret
< 0 || ret
>= end
- pos
) {
614 printf("Too long PASSPHRASE 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 PASSPHRASE command.\n");
627 return wpa_ctrl_command(ctrl
, cmd
);
631 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
633 char cmd
[256], *pos
, *end
;
637 printf("Invalid BSSID command: needs two arguments (network "
642 end
= cmd
+ sizeof(cmd
);
644 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
645 if (ret
< 0 || ret
>= end
- pos
) {
646 printf("Too long BSSID command.\n");
650 for (i
= 0; i
< argc
; i
++) {
651 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
652 if (ret
< 0 || ret
>= end
- pos
) {
653 printf("Too long BSSID command.\n");
659 return wpa_ctrl_command(ctrl
, cmd
);
663 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
666 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
670 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
676 printf("Invalid SELECT_NETWORK command: needs one argument "
681 os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
682 cmd
[sizeof(cmd
) - 1] = '\0';
684 return wpa_ctrl_command(ctrl
, cmd
);
688 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
694 printf("Invalid ENABLE_NETWORK command: needs one argument "
699 os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
700 cmd
[sizeof(cmd
) - 1] = '\0';
702 return wpa_ctrl_command(ctrl
, cmd
);
706 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
712 printf("Invalid DISABLE_NETWORK command: needs one argument "
717 os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
718 cmd
[sizeof(cmd
) - 1] = '\0';
720 return wpa_ctrl_command(ctrl
, cmd
);
724 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
727 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
731 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
737 printf("Invalid REMOVE_NETWORK command: needs one argument "
742 os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
743 cmd
[sizeof(cmd
) - 1] = '\0';
745 return wpa_ctrl_command(ctrl
, cmd
);
749 static void wpa_cli_show_network_variables(void)
751 printf("set_network variables:\n"
752 " ssid (network name, SSID)\n"
753 " psk (WPA passphrase or pre-shared key)\n"
754 " key_mgmt (key management protocol)\n"
755 " identity (EAP identity)\n"
756 " password (EAP password)\n"
759 "Note: Values are entered in the same format as the "
760 "configuration file is using,\n"
761 "i.e., strings values need to be inside double quotation "
763 "For example: set_network 1 ssid \"network name\"\n"
765 "Please see wpa_supplicant.conf documentation for full list "
766 "of\navailable variables.\n");
770 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
777 wpa_cli_show_network_variables();
782 printf("Invalid SET_NETWORK command: needs three arguments\n"
783 "(network id, variable name, and value)\n");
787 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
788 argv
[0], argv
[1], argv
[2]);
789 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
790 printf("Too long SET_NETWORK command.\n");
793 return wpa_ctrl_command(ctrl
, cmd
);
797 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
804 wpa_cli_show_network_variables();
809 printf("Invalid GET_NETWORK command: needs two arguments\n"
810 "(network id and variable name)\n");
814 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
816 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
817 printf("Too long GET_NETWORK command.\n");
820 return wpa_ctrl_command(ctrl
, cmd
);
824 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
827 return wpa_ctrl_command(ctrl
, "DISCONNECT");
831 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
834 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
838 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
840 return wpa_ctrl_command(ctrl
, "SCAN");
844 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
847 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
851 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
856 if (argc
< 1 || argc
> 2) {
857 printf("Invalid GET_CAPABILITY command: need either one or "
862 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
863 printf("Invalid GET_CAPABILITY command: second argument, "
864 "if any, must be 'strict'\n");
868 os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
869 (argc
== 2) ? " strict" : "");
870 cmd
[sizeof(cmd
) - 1] = '\0';
872 return wpa_ctrl_command(ctrl
, cmd
);
876 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
878 printf("Available interfaces:\n");
879 return wpa_ctrl_command(ctrl
, "INTERFACES");
883 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
886 wpa_cli_list_interfaces(ctrl
);
890 wpa_cli_close_connection();
891 os_free(ctrl_ifname
);
892 ctrl_ifname
= os_strdup(argv
[0]);
894 if (wpa_cli_open_connection(ctrl_ifname
)) {
895 printf("Connected to interface '%s.\n", ctrl_ifname
);
896 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
897 wpa_cli_attached
= 1;
899 printf("Warning: Failed to attach to "
900 "wpa_supplicant.\n");
903 printf("Could not connect to interface '%s' - re-trying\n",
910 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
913 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
917 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
920 return wpa_ctrl_command(ctrl
, "TERMINATE");
924 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
930 printf("Invalid INTERFACE_ADD command: needs at least one "
931 "argument (interface name)\n"
932 "All arguments: ifname confname driver ctrl_interface "
933 "driver_param bridge_name\n");
938 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
939 * <driver_param>TAB<bridge_name>
941 os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
943 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
944 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
945 argc
> 5 ? argv
[5] : "");
946 cmd
[sizeof(cmd
) - 1] = '\0';
947 return wpa_ctrl_command(ctrl
, cmd
);
951 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
957 printf("Invalid INTERFACE_REMOVE command: needs one argument "
958 "(interface name)\n");
962 os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
963 cmd
[sizeof(cmd
) - 1] = '\0';
964 return wpa_ctrl_command(ctrl
, cmd
);
970 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
973 static struct wpa_cli_cmd wpa_cli_commands
[] = {
974 { "status", wpa_cli_cmd_status
},
975 { "ping", wpa_cli_cmd_ping
},
976 { "mib", wpa_cli_cmd_mib
},
977 { "help", wpa_cli_cmd_help
},
978 { "interface", wpa_cli_cmd_interface
},
979 { "level", wpa_cli_cmd_level
},
980 { "license", wpa_cli_cmd_license
},
981 { "quit", wpa_cli_cmd_quit
},
982 { "set", wpa_cli_cmd_set
},
983 { "logon", wpa_cli_cmd_logon
},
984 { "logoff", wpa_cli_cmd_logoff
},
985 { "pmksa", wpa_cli_cmd_pmksa
},
986 { "reassociate", wpa_cli_cmd_reassociate
},
987 { "preauthenticate", wpa_cli_cmd_preauthenticate
},
988 { "identity", wpa_cli_cmd_identity
},
989 { "password", wpa_cli_cmd_password
},
990 { "new_password", wpa_cli_cmd_new_password
},
991 { "pin", wpa_cli_cmd_pin
},
992 { "otp", wpa_cli_cmd_otp
},
993 { "passphrase", wpa_cli_cmd_passphrase
},
994 { "bssid", wpa_cli_cmd_bssid
},
995 { "list_networks", wpa_cli_cmd_list_networks
},
996 { "select_network", wpa_cli_cmd_select_network
},
997 { "enable_network", wpa_cli_cmd_enable_network
},
998 { "disable_network", wpa_cli_cmd_disable_network
},
999 { "add_network", wpa_cli_cmd_add_network
},
1000 { "remove_network", wpa_cli_cmd_remove_network
},
1001 { "set_network", wpa_cli_cmd_set_network
},
1002 { "get_network", wpa_cli_cmd_get_network
},
1003 { "save_config", wpa_cli_cmd_save_config
},
1004 { "disconnect", wpa_cli_cmd_disconnect
},
1005 { "scan", wpa_cli_cmd_scan
},
1006 { "scan_results", wpa_cli_cmd_scan_results
},
1007 { "get_capability", wpa_cli_cmd_get_capability
},
1008 { "reconfigure", wpa_cli_cmd_reconfigure
},
1009 { "terminate", wpa_cli_cmd_terminate
},
1010 { "interface_add", wpa_cli_cmd_interface_add
},
1011 { "interface_remove", wpa_cli_cmd_interface_remove
},
1012 { "ap_scan", wpa_cli_cmd_ap_scan
},
1013 { "stkstart", wpa_cli_cmd_stkstart
},
1018 static void wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1020 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
1024 cmd
= wpa_cli_commands
;
1026 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
1029 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
1030 /* we have an exact match */
1040 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
1041 cmd
= wpa_cli_commands
;
1043 if (os_strncasecmp(cmd
->cmd
, argv
[0],
1044 os_strlen(argv
[0])) == 0) {
1045 printf(" %s", cmd
->cmd
);
1050 } else if (count
== 0) {
1051 printf("Unknown command '%s'\n", argv
[0]);
1053 match
->handler(ctrl
, argc
- 1, &argv
[1]);
1058 static int str_match(const char *a
, const char *b
)
1060 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
1064 static int wpa_cli_exec(const char *program
, const char *arg1
,
1070 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
1071 cmd
= os_malloc(len
);
1074 os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
1075 cmd
[len
- 1] = '\0';
1078 #endif /* _WIN32_WCE */
1085 static void wpa_cli_action_process(const char *msg
)
1088 char *copy
= NULL
, *id
, *pos2
;
1093 pos
= os_strchr(pos
, '>');
1100 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
1102 os_unsetenv("WPA_ID");
1103 os_unsetenv("WPA_ID_STR");
1104 os_unsetenv("WPA_CTRL_DIR");
1106 pos
= os_strstr(pos
, "[id=");
1108 copy
= os_strdup(pos
+ 4);
1112 while (*pos2
&& *pos2
!= ' ')
1116 os_setenv("WPA_ID", id
, 1);
1117 while (*pos2
&& *pos2
!= '=')
1122 while (*pos2
&& *pos2
!= ']')
1125 os_setenv("WPA_ID_STR", id
, 1);
1129 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
1131 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
1132 wpa_cli_connected
= 1;
1133 wpa_cli_last_id
= new_id
;
1134 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
1136 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
1137 if (wpa_cli_connected
) {
1138 wpa_cli_connected
= 0;
1139 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
1141 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
1142 printf("wpa_supplicant is terminating - stop monitoring\n");
1148 #ifndef CONFIG_ANSI_C_EXTRA
1149 static void wpa_cli_action_cb(char *msg
, size_t len
)
1151 wpa_cli_action_process(msg
);
1153 #endif /* CONFIG_ANSI_C_EXTRA */
1156 static void wpa_cli_reconnect(void)
1158 wpa_cli_close_connection();
1159 ctrl_conn
= wpa_cli_open_connection(ctrl_ifname
);
1161 printf("Connection to wpa_supplicant re-established\n");
1162 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
1163 wpa_cli_attached
= 1;
1165 printf("Warning: Failed to attach to "
1166 "wpa_supplicant.\n");
1172 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int in_read
,
1176 if (ctrl_conn
== NULL
) {
1177 wpa_cli_reconnect();
1180 while (wpa_ctrl_pending(ctrl
) > 0) {
1182 size_t len
= sizeof(buf
) - 1;
1183 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
1186 wpa_cli_action_process(buf
);
1188 if (in_read
&& first
)
1191 printf("%s\n", buf
);
1194 printf("Could not read pending message.\n");
1199 if (wpa_ctrl_pending(ctrl
) < 0) {
1200 printf("Connection to wpa_supplicant lost - trying to "
1202 wpa_cli_reconnect();
1207 #ifdef CONFIG_READLINE
1208 static char * wpa_cli_cmd_gen(const char *text
, int state
)
1215 len
= os_strlen(text
);
1218 while ((cmd
= wpa_cli_commands
[i
].cmd
)) {
1220 if (os_strncasecmp(cmd
, text
, len
) == 0)
1221 return os_strdup(cmd
);
1228 static char * wpa_cli_dummy_gen(const char *text
, int state
)
1234 static char ** wpa_cli_completion(const char *text
, int start
, int end
)
1236 return rl_completion_matches(text
, start
== 0 ?
1237 wpa_cli_cmd_gen
: wpa_cli_dummy_gen
);
1239 #endif /* CONFIG_READLINE */
1242 static void wpa_cli_interactive(void)
1245 char cmdbuf
[256], *cmd
, *argv
[max_args
], *pos
;
1247 #ifdef CONFIG_READLINE
1248 char *home
, *hfile
= NULL
;
1249 #endif /* CONFIG_READLINE */
1251 printf("\nInteractive mode\n\n");
1253 #ifdef CONFIG_READLINE
1254 rl_attempted_completion_function
= wpa_cli_completion
;
1255 home
= getenv("HOME");
1257 const char *fname
= ".wpa_cli_history";
1258 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
1259 hfile
= os_malloc(hfile_len
);
1261 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
1262 hfile
[hfile_len
- 1] = '\0';
1263 read_history(hfile
);
1264 stifle_history(100);
1267 #endif /* CONFIG_READLINE */
1270 wpa_cli_recv_pending(ctrl_conn
, 0, 0);
1271 #ifndef CONFIG_NATIVE_WINDOWS
1273 #endif /* CONFIG_NATIVE_WINDOWS */
1274 #ifdef CONFIG_READLINE
1275 cmd
= readline("> ");
1278 while (next_history())
1280 h
= previous_history();
1281 if (h
== NULL
|| os_strcmp(cmd
, h
->line
) != 0)
1285 #else /* CONFIG_READLINE */
1287 cmd
= fgets(cmdbuf
, sizeof(cmdbuf
), stdin
);
1288 #endif /* CONFIG_READLINE */
1289 #ifndef CONFIG_NATIVE_WINDOWS
1291 #endif /* CONFIG_NATIVE_WINDOWS */
1294 wpa_cli_recv_pending(ctrl_conn
, 0, 0);
1296 while (*pos
!= '\0') {
1312 if (argc
== max_args
)
1315 char *pos2
= os_strrchr(pos
, '"');
1319 while (*pos
!= '\0' && *pos
!= ' ')
1325 wpa_request(ctrl_conn
, argc
, argv
);
1329 } while (!wpa_cli_quit
);
1331 #ifdef CONFIG_READLINE
1333 /* Save command history, excluding lines that may contain
1340 while (*p
== ' ' || *p
== '\t')
1342 if (os_strncasecmp(p
, "pa", 2) == 0 ||
1343 os_strncasecmp(p
, "o", 1) == 0 ||
1344 os_strncasecmp(p
, "n", 1)) {
1345 h
= remove_history(where_history());
1351 h
= current_history();
1356 write_history(hfile
);
1359 #endif /* CONFIG_READLINE */
1363 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
1365 #ifdef CONFIG_ANSI_C_EXTRA
1366 /* TODO: ANSI C version(?) */
1367 printf("Action processing not supported in ANSI C build.\n");
1368 #else /* CONFIG_ANSI_C_EXTRA */
1372 char buf
[256]; /* note: large enough to fit in unsolicited messages */
1375 fd
= wpa_ctrl_get_fd(ctrl
);
1377 while (!wpa_cli_quit
) {
1382 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
1383 if (res
< 0 && errno
!= EINTR
) {
1388 if (FD_ISSET(fd
, &rfds
))
1389 wpa_cli_recv_pending(ctrl
, 0, 1);
1391 /* verify that connection is still working */
1392 len
= sizeof(buf
) - 1;
1393 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
1394 wpa_cli_action_cb
) < 0 ||
1395 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
1396 printf("wpa_supplicant did not reply to PING "
1397 "command - exiting\n");
1402 #endif /* CONFIG_ANSI_C_EXTRA */
1406 static void wpa_cli_cleanup(void)
1408 wpa_cli_close_connection();
1410 os_daemonize_terminate(pid_file
);
1412 os_program_deinit();
1415 static void wpa_cli_terminate(int sig
)
1422 #ifndef CONFIG_NATIVE_WINDOWS
1423 static void wpa_cli_alarm(int sig
)
1425 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
1426 printf("Connection to wpa_supplicant lost - trying to "
1428 wpa_cli_close_connection();
1431 wpa_cli_reconnect();
1433 wpa_cli_recv_pending(ctrl_conn
, 1, 0);
1436 #endif /* CONFIG_NATIVE_WINDOWS */
1439 static char * wpa_cli_get_default_ifname(void)
1441 char *ifname
= NULL
;
1443 #ifdef CONFIG_CTRL_IFACE_UNIX
1444 struct dirent
*dent
;
1445 DIR *dir
= opendir(ctrl_iface_dir
);
1448 while ((dent
= readdir(dir
))) {
1449 #ifdef _DIRENT_HAVE_D_TYPE
1451 * Skip the file if it is not a socket. Also accept
1452 * DT_UNKNOWN (0) in case the C library or underlying
1453 * file system does not support d_type.
1455 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
1457 #endif /* _DIRENT_HAVE_D_TYPE */
1458 if (os_strcmp(dent
->d_name
, ".") == 0 ||
1459 os_strcmp(dent
->d_name
, "..") == 0)
1461 printf("Selected interface '%s'\n", dent
->d_name
);
1462 ifname
= os_strdup(dent
->d_name
);
1466 #endif /* CONFIG_CTRL_IFACE_UNIX */
1468 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1469 char buf
[2048], *pos
;
1471 struct wpa_ctrl
*ctrl
;
1474 ctrl
= wpa_ctrl_open(NULL
);
1478 len
= sizeof(buf
) - 1;
1479 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
1482 pos
= os_strchr(buf
, '\n');
1485 ifname
= os_strdup(buf
);
1487 wpa_ctrl_close(ctrl
);
1488 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1494 int main(int argc
, char *argv
[])
1497 int warning_displayed
= 0;
1500 const char *global
= NULL
;
1502 if (os_program_init())
1506 c
= getopt(argc
, argv
, "a:Bg:hi:p:P:v");
1511 action_file
= optarg
;
1523 printf("%s\n", wpa_cli_version
);
1526 os_free(ctrl_ifname
);
1527 ctrl_ifname
= os_strdup(optarg
);
1530 ctrl_iface_dir
= optarg
;
1541 interactive
= (argc
== optind
) && (action_file
== NULL
);
1544 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
1547 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1548 ctrl_conn
= wpa_ctrl_open(NULL
);
1549 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1550 ctrl_conn
= wpa_ctrl_open(global
);
1551 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1552 if (ctrl_conn
== NULL
) {
1553 perror("Failed to connect to wpa_supplicant - "
1560 if (ctrl_ifname
== NULL
)
1561 ctrl_ifname
= wpa_cli_get_default_ifname();
1562 ctrl_conn
= wpa_cli_open_connection(ctrl_ifname
);
1564 if (warning_displayed
)
1565 printf("Connection established.\n");
1570 perror("Failed to connect to wpa_supplicant - "
1575 if (!warning_displayed
) {
1576 printf("Could not connect to wpa_supplicant - "
1578 warning_displayed
= 1;
1585 signal(SIGINT
, wpa_cli_terminate
);
1586 signal(SIGTERM
, wpa_cli_terminate
);
1587 #endif /* _WIN32_WCE */
1588 #ifndef CONFIG_NATIVE_WINDOWS
1589 signal(SIGALRM
, wpa_cli_alarm
);
1590 #endif /* CONFIG_NATIVE_WINDOWS */
1592 if (interactive
|| action_file
) {
1593 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
1594 wpa_cli_attached
= 1;
1596 printf("Warning: Failed to attach to "
1597 "wpa_supplicant.\n");
1603 if (daemonize
&& os_daemonize(pid_file
))
1607 wpa_cli_interactive();
1608 else if (action_file
)
1609 wpa_cli_action(ctrl_conn
);
1611 wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
1613 os_free(ctrl_ifname
);
1619 #else /* CONFIG_CTRL_IFACE */
1620 int main(int argc
, char *argv
[])
1622 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
1625 #endif /* CONFIG_CTRL_IFACE */