2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
22 #ifdef CONFIG_READLINE
23 #include <readline/readline.h>
24 #include <readline/history.h>
25 #endif /* CONFIG_READLINE */
26 #ifdef CONFIG_WPA_CLI_FORK
28 #endif /* CONFIG_WPA_CLI_FORK */
30 #include "common/wpa_ctrl.h"
32 #include "common/version.h"
35 static const char *wpa_cli_version
=
36 "wpa_cli v" VERSION_STR
"\n"
37 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
40 static const char *wpa_cli_license
=
41 "This program is free software. You can distribute it and/or modify it\n"
42 "under the terms of the GNU General Public License version 2.\n"
44 "Alternatively, this software may be distributed under the terms of the\n"
45 "BSD license. See README and COPYING for more details.\n";
47 static const char *wpa_cli_full_license
=
48 "This program is free software; you can redistribute it and/or modify\n"
49 "it under the terms of the GNU General Public License version 2 as\n"
50 "published by the Free Software Foundation.\n"
52 "This program is distributed in the hope that it will be useful,\n"
53 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
54 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
55 "GNU General Public License for more details.\n"
57 "You should have received a copy of the GNU General Public License\n"
58 "along with this program; if not, write to the Free Software\n"
59 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
61 "Alternatively, this software may be distributed under the terms of the\n"
64 "Redistribution and use in source and binary forms, with or without\n"
65 "modification, are permitted provided that the following conditions are\n"
68 "1. Redistributions of source code must retain the above copyright\n"
69 " notice, this list of conditions and the following disclaimer.\n"
71 "2. Redistributions in binary form must reproduce the above copyright\n"
72 " notice, this list of conditions and the following disclaimer in the\n"
73 " documentation and/or other materials provided with the distribution.\n"
75 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
76 " names of its contributors may be used to endorse or promote products\n"
77 " derived from this software without specific prior written permission.\n"
79 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
80 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
81 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
82 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
83 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
84 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
85 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
86 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
87 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
88 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
89 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
92 static struct wpa_ctrl
*ctrl_conn
;
93 static struct wpa_ctrl
*mon_conn
;
94 #ifdef CONFIG_WPA_CLI_FORK
95 static pid_t mon_pid
= 0;
96 #endif /* CONFIG_WPA_CLI_FORK */
97 static int wpa_cli_quit
= 0;
98 static int wpa_cli_attached
= 0;
99 static int wpa_cli_connected
= 0;
100 static int wpa_cli_last_id
= 0;
101 static const char *ctrl_iface_dir
= "/var/run/wpa_supplicant";
102 static char *ctrl_ifname
= NULL
;
103 static const char *pid_file
= NULL
;
104 static const char *action_file
= NULL
;
105 static int ping_interval
= 5;
106 static int interactive
= 0;
109 static void print_help();
112 static void usage(void)
114 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
115 "[-a<action file>] \\\n"
116 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
118 " -h = help (show this usage text)\n"
119 " -v = shown version information\n"
120 " -a = run in daemon mode executing the action file based on "
123 " -B = run a daemon in the background\n"
124 " default path: /var/run/wpa_supplicant\n"
125 " default interface: first interface found in socket path\n");
130 #ifdef CONFIG_WPA_CLI_FORK
131 static int in_query
= 0;
133 static void wpa_cli_monitor_sig(int sig
)
137 else if (sig
== SIGUSR2
)
141 static void wpa_cli_monitor(void)
144 size_t len
= sizeof(buf
) - 1;
148 signal(SIGUSR1
, wpa_cli_monitor_sig
);
149 signal(SIGUSR2
, wpa_cli_monitor_sig
);
152 int s
= wpa_ctrl_get_fd(mon_conn
);
157 if (select(s
+ 1, &rfds
, NULL
, NULL
, &tv
) < 0) {
163 if (mon_conn
== NULL
)
165 if (FD_ISSET(s
, &rfds
)) {
166 len
= sizeof(buf
) - 1;
167 int res
= wpa_ctrl_recv(mon_conn
, buf
, &len
);
169 perror("wpa_ctrl_recv");
176 kill(getppid(), SIGUSR1
);
180 #endif /* CONFIG_WPA_CLI_FORK */
183 static int wpa_cli_open_connection(const char *ifname
, int attach
)
185 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
186 ctrl_conn
= wpa_ctrl_open(ifname
);
187 if (ctrl_conn
== NULL
)
190 if (attach
&& interactive
)
191 mon_conn
= wpa_ctrl_open(ifname
);
194 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
201 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
202 cfile
= os_malloc(flen
);
205 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
, ifname
);
206 if (res
< 0 || res
>= flen
) {
211 ctrl_conn
= wpa_ctrl_open(cfile
);
212 if (ctrl_conn
== NULL
) {
217 if (attach
&& interactive
)
218 mon_conn
= wpa_ctrl_open(cfile
);
222 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
225 if (wpa_ctrl_attach(mon_conn
) == 0) {
226 wpa_cli_attached
= 1;
228 printf("Warning: Failed to attach to "
229 "wpa_supplicant.\n");
233 #ifdef CONFIG_WPA_CLI_FORK
246 #endif /* CONFIG_WPA_CLI_FORK */
253 static void wpa_cli_close_connection(void)
255 if (ctrl_conn
== NULL
)
258 #ifdef CONFIG_WPA_CLI_FORK
261 kill(mon_pid
, SIGPIPE
);
265 #endif /* CONFIG_WPA_CLI_FORK */
267 if (wpa_cli_attached
) {
268 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
269 wpa_cli_attached
= 0;
271 wpa_ctrl_close(ctrl_conn
);
274 wpa_ctrl_close(mon_conn
);
280 static void wpa_cli_msg_cb(char *msg
, size_t len
)
286 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
292 if (ctrl_conn
== NULL
) {
293 printf("Not connected to wpa_supplicant - command dropped.\n");
296 len
= sizeof(buf
) - 1;
297 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
300 printf("'%s' command timed out.\n", cmd
);
302 } else if (ret
< 0) {
303 printf("'%s' command failed.\n", cmd
);
314 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
316 return _wpa_ctrl_command(ctrl
, cmd
, 1);
320 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
322 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
323 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
327 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
329 return wpa_ctrl_command(ctrl
, "PING");
333 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
335 return wpa_ctrl_command(ctrl
, "MIB");
339 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
341 return wpa_ctrl_command(ctrl
, "PMKSA");
345 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
352 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
354 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
359 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
366 static void wpa_cli_show_variables(void)
368 printf("set variables:\n"
369 " EAPOL::heldPeriod (EAPOL state machine held period, "
371 " EAPOL::authPeriod (EAPOL state machine authentication "
372 "period, in seconds)\n"
373 " EAPOL::startPeriod (EAPOL state machine start period, in "
375 " EAPOL::maxStart (EAPOL state machine maximum start "
377 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
379 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
380 " threshold\n\tpercentage)\n"
381 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
382 "security\n\tassociation in seconds)\n");
386 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
392 wpa_cli_show_variables();
397 printf("Invalid SET command: needs two arguments (variable "
398 "name and value)\n");
402 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s", argv
[0], argv
[1]);
403 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
404 printf("Too long SET command.\n");
407 return wpa_ctrl_command(ctrl
, cmd
);
411 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
413 return wpa_ctrl_command(ctrl
, "LOGOFF");
417 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
419 return wpa_ctrl_command(ctrl
, "LOGON");
423 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
426 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
430 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
437 printf("Invalid PREAUTH command: needs one argument "
442 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
443 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
444 printf("Too long PREAUTH command.\n");
447 return wpa_ctrl_command(ctrl
, cmd
);
451 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
457 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
461 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
462 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
463 printf("Too long AP_SCAN command.\n");
466 return wpa_ctrl_command(ctrl
, cmd
);
470 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
477 printf("Invalid STKSTART command: needs one argument "
478 "(Peer STA MAC address)\n");
482 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
483 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
484 printf("Too long STKSTART command.\n");
487 return wpa_ctrl_command(ctrl
, cmd
);
491 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
497 printf("Invalid FT_DS command: needs one argument "
498 "(Target AP MAC address)\n");
502 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
503 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
504 printf("Too long FT_DS command.\n");
507 return wpa_ctrl_command(ctrl
, cmd
);
511 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
518 return wpa_ctrl_command(ctrl
, "WPS_PBC");
522 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
523 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
524 printf("Too long WPS_PBC command.\n");
527 return wpa_ctrl_command(ctrl
, cmd
);
531 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
537 printf("Invalid WPS_PIN command: need one or two arguments:\n"
538 "- BSSID: use 'any' to select any\n"
539 "- PIN: optional, used only with devices that have no "
545 /* Use dynamically generated PIN (returned as reply) */
546 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
547 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
548 printf("Too long WPS_PIN command.\n");
551 return wpa_ctrl_command(ctrl
, cmd
);
554 /* Use hardcoded PIN from a label */
555 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
556 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
557 printf("Too long WPS_PIN command.\n");
560 return wpa_ctrl_command(ctrl
, cmd
);
564 #ifdef CONFIG_WPS_OOB
565 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
570 if (argc
!= 3 && argc
!= 4) {
571 printf("Invalid WPS_OOB command: need three or four "
573 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
574 "- PATH: path of OOB device like '/mnt'\n"
575 "- METHOD: OOB method 'pin-e' or 'pin-r', "
577 "- DEV_NAME: (only for NFC) device name like "
583 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
584 argv
[0], argv
[1], argv
[2]);
586 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
587 argv
[0], argv
[1], argv
[2], argv
[3]);
588 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
589 printf("Too long WPS_OOB command.\n");
592 return wpa_ctrl_command(ctrl
, cmd
);
594 #endif /* CONFIG_WPS_OOB */
597 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
603 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
605 else if (argc
== 6) {
606 char ssid_hex
[2 * 32 + 1];
607 char key_hex
[2 * 64 + 1];
611 for (i
= 0; i
< 32; i
++) {
612 if (argv
[2][i
] == '\0')
614 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
618 for (i
= 0; i
< 64; i
++) {
619 if (argv
[5][i
] == '\0')
621 os_snprintf(&key_hex
[i
* 2], 3, "%02x", argv
[5][i
]);
624 res
= os_snprintf(cmd
, sizeof(cmd
),
625 "WPS_REG %s %s %s %s %s %s",
626 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
629 printf("Invalid WPS_REG command: need two arguments:\n"
630 "- BSSID: use 'any' to select any\n"
632 printf("Alternatively, six arguments can be used to "
633 "reconfigure the AP:\n"
634 "- BSSID: use 'any' to select any\n"
637 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
638 "- new encr (NONE, WEP, TKIP, CCMP)\n"
643 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
644 printf("Too long WPS_REG command.\n");
647 return wpa_ctrl_command(ctrl
, cmd
);
651 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
654 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
659 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
662 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
667 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
674 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
675 "- UUID: use 'any' to select any\n"
676 "- PIN: Enrollee PIN\n");
680 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
682 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
683 printf("Too long WPS_ER_PIN command.\n");
686 return wpa_ctrl_command(ctrl
, cmd
);
690 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
697 printf("Invalid WPS_ER_PBC command: need one argument:\n"
698 "- UUID: Specify the Enrollee\n");
702 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
704 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
705 printf("Too long WPS_ER_PBC command.\n");
708 return wpa_ctrl_command(ctrl
, cmd
);
712 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
719 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
720 "- UUID: specify which AP to use\n"
725 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
727 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
728 printf("Too long WPS_ER_LEARN command.\n");
731 return wpa_ctrl_command(ctrl
, cmd
);
735 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
741 printf("Invalid IBSS_RSN command: needs one argument "
742 "(Peer STA MAC address)\n");
746 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
747 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
748 printf("Too long IBSS_RSN command.\n");
751 return wpa_ctrl_command(ctrl
, cmd
);
755 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
761 printf("Invalid LEVEL command: needs one argument (debug "
765 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
766 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
767 printf("Too long LEVEL command.\n");
770 return wpa_ctrl_command(ctrl
, cmd
);
774 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
776 char cmd
[256], *pos
, *end
;
780 printf("Invalid IDENTITY command: needs two arguments "
781 "(network id and identity)\n");
785 end
= cmd
+ sizeof(cmd
);
787 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
789 if (ret
< 0 || ret
>= end
- pos
) {
790 printf("Too long IDENTITY command.\n");
794 for (i
= 2; i
< argc
; i
++) {
795 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
796 if (ret
< 0 || ret
>= end
- pos
) {
797 printf("Too long IDENTITY command.\n");
803 return wpa_ctrl_command(ctrl
, cmd
);
807 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
809 char cmd
[256], *pos
, *end
;
813 printf("Invalid PASSWORD command: needs two arguments "
814 "(network id and password)\n");
818 end
= cmd
+ sizeof(cmd
);
820 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
822 if (ret
< 0 || ret
>= end
- pos
) {
823 printf("Too long PASSWORD command.\n");
827 for (i
= 2; i
< argc
; i
++) {
828 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
829 if (ret
< 0 || ret
>= end
- pos
) {
830 printf("Too long PASSWORD command.\n");
836 return wpa_ctrl_command(ctrl
, cmd
);
840 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
843 char cmd
[256], *pos
, *end
;
847 printf("Invalid NEW_PASSWORD command: needs two arguments "
848 "(network id and password)\n");
852 end
= cmd
+ sizeof(cmd
);
854 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
856 if (ret
< 0 || ret
>= end
- pos
) {
857 printf("Too long NEW_PASSWORD command.\n");
861 for (i
= 2; i
< argc
; i
++) {
862 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
863 if (ret
< 0 || ret
>= end
- pos
) {
864 printf("Too long NEW_PASSWORD command.\n");
870 return wpa_ctrl_command(ctrl
, cmd
);
874 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
876 char cmd
[256], *pos
, *end
;
880 printf("Invalid PIN command: needs two arguments "
881 "(network id and pin)\n");
885 end
= cmd
+ sizeof(cmd
);
887 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
889 if (ret
< 0 || ret
>= end
- pos
) {
890 printf("Too long PIN command.\n");
894 for (i
= 2; i
< argc
; i
++) {
895 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
896 if (ret
< 0 || ret
>= end
- pos
) {
897 printf("Too long PIN command.\n");
902 return wpa_ctrl_command(ctrl
, cmd
);
906 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
908 char cmd
[256], *pos
, *end
;
912 printf("Invalid OTP command: needs two arguments (network "
913 "id and password)\n");
917 end
= cmd
+ sizeof(cmd
);
919 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
921 if (ret
< 0 || ret
>= end
- pos
) {
922 printf("Too long OTP command.\n");
926 for (i
= 2; i
< argc
; i
++) {
927 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
928 if (ret
< 0 || ret
>= end
- pos
) {
929 printf("Too long OTP command.\n");
935 return wpa_ctrl_command(ctrl
, cmd
);
939 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
942 char cmd
[256], *pos
, *end
;
946 printf("Invalid PASSPHRASE command: needs two arguments "
947 "(network id and passphrase)\n");
951 end
= cmd
+ sizeof(cmd
);
953 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
955 if (ret
< 0 || ret
>= end
- pos
) {
956 printf("Too long PASSPHRASE command.\n");
960 for (i
= 2; i
< argc
; i
++) {
961 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
962 if (ret
< 0 || ret
>= end
- pos
) {
963 printf("Too long PASSPHRASE command.\n");
969 return wpa_ctrl_command(ctrl
, cmd
);
973 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
975 char cmd
[256], *pos
, *end
;
979 printf("Invalid BSSID command: needs two arguments (network "
984 end
= cmd
+ sizeof(cmd
);
986 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
987 if (ret
< 0 || ret
>= end
- pos
) {
988 printf("Too long BSSID command.\n");
992 for (i
= 0; i
< argc
; i
++) {
993 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
994 if (ret
< 0 || ret
>= end
- pos
) {
995 printf("Too long BSSID command.\n");
1001 return wpa_ctrl_command(ctrl
, cmd
);
1005 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1008 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1012 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1019 printf("Invalid SELECT_NETWORK command: needs one argument "
1024 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1025 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1027 cmd
[sizeof(cmd
) - 1] = '\0';
1029 return wpa_ctrl_command(ctrl
, cmd
);
1033 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1040 printf("Invalid ENABLE_NETWORK command: needs one argument "
1045 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1046 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1048 cmd
[sizeof(cmd
) - 1] = '\0';
1050 return wpa_ctrl_command(ctrl
, cmd
);
1054 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1061 printf("Invalid DISABLE_NETWORK command: needs one argument "
1066 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1067 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1069 cmd
[sizeof(cmd
) - 1] = '\0';
1071 return wpa_ctrl_command(ctrl
, cmd
);
1075 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1078 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1082 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1089 printf("Invalid REMOVE_NETWORK command: needs one argument "
1094 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1095 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1097 cmd
[sizeof(cmd
) - 1] = '\0';
1099 return wpa_ctrl_command(ctrl
, cmd
);
1103 static void wpa_cli_show_network_variables(void)
1105 printf("set_network variables:\n"
1106 " ssid (network name, SSID)\n"
1107 " psk (WPA passphrase or pre-shared key)\n"
1108 " key_mgmt (key management protocol)\n"
1109 " identity (EAP identity)\n"
1110 " password (EAP password)\n"
1113 "Note: Values are entered in the same format as the "
1114 "configuration file is using,\n"
1115 "i.e., strings values need to be inside double quotation "
1117 "For example: set_network 1 ssid \"network name\"\n"
1119 "Please see wpa_supplicant.conf documentation for full list "
1120 "of\navailable variables.\n");
1124 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1131 wpa_cli_show_network_variables();
1136 printf("Invalid SET_NETWORK command: needs three arguments\n"
1137 "(network id, variable name, and value)\n");
1141 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1142 argv
[0], argv
[1], argv
[2]);
1143 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1144 printf("Too long SET_NETWORK command.\n");
1147 return wpa_ctrl_command(ctrl
, cmd
);
1151 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1158 wpa_cli_show_network_variables();
1163 printf("Invalid GET_NETWORK command: needs two arguments\n"
1164 "(network id and variable name)\n");
1168 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1170 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1171 printf("Too long GET_NETWORK command.\n");
1174 return wpa_ctrl_command(ctrl
, cmd
);
1178 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1181 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1185 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1188 return wpa_ctrl_command(ctrl
, "RECONNECT");
1192 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1195 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1199 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1201 return wpa_ctrl_command(ctrl
, "SCAN");
1205 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1208 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1212 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1218 printf("Invalid BSS command: need one argument (index or "
1223 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1224 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1226 cmd
[sizeof(cmd
) - 1] = '\0';
1228 return wpa_ctrl_command(ctrl
, cmd
);
1232 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1238 if (argc
< 1 || argc
> 2) {
1239 printf("Invalid GET_CAPABILITY command: need either one or "
1244 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1245 printf("Invalid GET_CAPABILITY command: second argument, "
1246 "if any, must be 'strict'\n");
1250 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1251 (argc
== 2) ? " strict" : "");
1252 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1254 cmd
[sizeof(cmd
) - 1] = '\0';
1256 return wpa_ctrl_command(ctrl
, cmd
);
1260 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1262 printf("Available interfaces:\n");
1263 return wpa_ctrl_command(ctrl
, "INTERFACES");
1267 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1270 wpa_cli_list_interfaces(ctrl
);
1274 wpa_cli_close_connection();
1275 os_free(ctrl_ifname
);
1276 ctrl_ifname
= os_strdup(argv
[0]);
1278 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1279 printf("Connected to interface '%s.\n", ctrl_ifname
);
1281 printf("Could not connect to interface '%s' - re-trying\n",
1288 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1291 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1295 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1298 return wpa_ctrl_command(ctrl
, "TERMINATE");
1302 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1309 printf("Invalid INTERFACE_ADD command: needs at least one "
1310 "argument (interface name)\n"
1311 "All arguments: ifname confname driver ctrl_interface "
1312 "driver_param bridge_name\n");
1317 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1318 * <driver_param>TAB<bridge_name>
1320 res
= os_snprintf(cmd
, sizeof(cmd
),
1321 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1323 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1324 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1325 argc
> 5 ? argv
[5] : "");
1326 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1328 cmd
[sizeof(cmd
) - 1] = '\0';
1329 return wpa_ctrl_command(ctrl
, cmd
);
1333 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1340 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1341 "(interface name)\n");
1345 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1346 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1348 cmd
[sizeof(cmd
) - 1] = '\0';
1349 return wpa_ctrl_command(ctrl
, cmd
);
1353 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1356 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1361 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1365 printf("Invalid 'sta' command - exactly one argument, STA "
1366 "address, is required.\n");
1369 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1370 return wpa_ctrl_command(ctrl
, buf
);
1374 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1375 char *addr
, size_t addr_len
)
1377 char buf
[4096], *pos
;
1381 if (ctrl_conn
== NULL
) {
1382 printf("Not connected to hostapd - command dropped.\n");
1385 len
= sizeof(buf
) - 1;
1386 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1389 printf("'%s' command timed out.\n", cmd
);
1391 } else if (ret
< 0) {
1392 printf("'%s' command failed.\n", cmd
);
1397 if (memcmp(buf
, "FAIL", 4) == 0)
1402 while (*pos
!= '\0' && *pos
!= '\n')
1405 os_strlcpy(addr
, buf
, addr_len
);
1410 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1412 char addr
[32], cmd
[64];
1414 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1417 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1418 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1422 #endif /* CONFIG_AP */
1425 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1427 return wpa_ctrl_command(ctrl
, "SUSPEND");
1431 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1433 return wpa_ctrl_command(ctrl
, "RESUME");
1437 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1439 return wpa_ctrl_command(ctrl
, "DROP_SA");
1443 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1449 printf("Invalid ROAM command: needs one argument "
1450 "(target AP's BSSID)\n");
1454 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
1455 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1456 printf("Too long ROAM command.\n");
1459 return wpa_ctrl_command(ctrl
, cmd
);
1463 enum wpa_cli_cmd_flags
{
1464 cli_cmd_flag_none
= 0x00,
1465 cli_cmd_flag_sensitive
= 0x01
1468 struct wpa_cli_cmd
{
1470 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
1471 enum wpa_cli_cmd_flags flags
;
1475 static struct wpa_cli_cmd wpa_cli_commands
[] = {
1476 { "status", wpa_cli_cmd_status
,
1478 "[verbose] = get current WPA/EAPOL/EAP status" },
1479 { "ping", wpa_cli_cmd_ping
,
1481 "= pings wpa_supplicant" },
1482 { "mib", wpa_cli_cmd_mib
,
1484 "= get MIB variables (dot1x, dot11)" },
1485 { "help", wpa_cli_cmd_help
,
1487 "= show this usage help" },
1488 { "interface", wpa_cli_cmd_interface
,
1490 "[ifname] = show interfaces/select interface" },
1491 { "level", wpa_cli_cmd_level
,
1493 "<debug level> = change debug level" },
1494 { "license", wpa_cli_cmd_license
,
1496 "= show full wpa_cli license" },
1497 { "quit", wpa_cli_cmd_quit
,
1500 { "set", wpa_cli_cmd_set
,
1502 "= set variables (shows list of variables when run without "
1504 { "logon", wpa_cli_cmd_logon
,
1506 "= IEEE 802.1X EAPOL state machine logon" },
1507 { "logoff", wpa_cli_cmd_logoff
,
1509 "= IEEE 802.1X EAPOL state machine logoff" },
1510 { "pmksa", wpa_cli_cmd_pmksa
,
1512 "= show PMKSA cache" },
1513 { "reassociate", wpa_cli_cmd_reassociate
,
1515 "= force reassociation" },
1516 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
1518 "<BSSID> = force preauthentication" },
1519 { "identity", wpa_cli_cmd_identity
,
1521 "<network id> <identity> = configure identity for an SSID" },
1522 { "password", wpa_cli_cmd_password
,
1523 cli_cmd_flag_sensitive
,
1524 "<network id> <password> = configure password for an SSID" },
1525 { "new_password", wpa_cli_cmd_new_password
,
1526 cli_cmd_flag_sensitive
,
1527 "<network id> <password> = change password for an SSID" },
1528 { "pin", wpa_cli_cmd_pin
,
1529 cli_cmd_flag_sensitive
,
1530 "<network id> <pin> = configure pin for an SSID" },
1531 { "otp", wpa_cli_cmd_otp
,
1532 cli_cmd_flag_sensitive
,
1533 "<network id> <password> = configure one-time-password for an SSID"
1535 { "passphrase", wpa_cli_cmd_passphrase
,
1536 cli_cmd_flag_sensitive
,
1537 "<network id> <passphrase> = configure private key passphrase\n"
1539 { "bssid", wpa_cli_cmd_bssid
,
1541 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1542 { "list_networks", wpa_cli_cmd_list_networks
,
1544 "= list configured networks" },
1545 { "select_network", wpa_cli_cmd_select_network
,
1547 "<network id> = select a network (disable others)" },
1548 { "enable_network", wpa_cli_cmd_enable_network
,
1550 "<network id> = enable a network" },
1551 { "disable_network", wpa_cli_cmd_disable_network
,
1553 "<network id> = disable a network" },
1554 { "add_network", wpa_cli_cmd_add_network
,
1556 "= add a network" },
1557 { "remove_network", wpa_cli_cmd_remove_network
,
1559 "<network id> = remove a network" },
1560 { "set_network", wpa_cli_cmd_set_network
,
1561 cli_cmd_flag_sensitive
,
1562 "<network id> <variable> <value> = set network variables (shows\n"
1563 " list of variables when run without arguments)" },
1564 { "get_network", wpa_cli_cmd_get_network
,
1566 "<network id> <variable> = get network variables" },
1567 { "save_config", wpa_cli_cmd_save_config
,
1569 "= save the current configuration" },
1570 { "disconnect", wpa_cli_cmd_disconnect
,
1572 "= disconnect and wait for reassociate/reconnect command before\n"
1574 { "reconnect", wpa_cli_cmd_reconnect
,
1576 "= like reassociate, but only takes effect if already disconnected"
1578 { "scan", wpa_cli_cmd_scan
,
1580 "= request new BSS scan" },
1581 { "scan_results", wpa_cli_cmd_scan_results
,
1583 "= get latest scan results" },
1584 { "bss", wpa_cli_cmd_bss
,
1586 "<<idx> | <bssid>> = get detailed scan result info" },
1587 { "get_capability", wpa_cli_cmd_get_capability
,
1589 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1590 { "reconfigure", wpa_cli_cmd_reconfigure
,
1592 "= force wpa_supplicant to re-read its configuration file" },
1593 { "terminate", wpa_cli_cmd_terminate
,
1595 "= terminate wpa_supplicant" },
1596 { "interface_add", wpa_cli_cmd_interface_add
,
1598 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1599 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1601 { "interface_remove", wpa_cli_cmd_interface_remove
,
1603 "<ifname> = removes the interface" },
1604 { "interface_list", wpa_cli_cmd_interface_list
,
1606 "= list available interfaces" },
1607 { "ap_scan", wpa_cli_cmd_ap_scan
,
1609 "<value> = set ap_scan parameter" },
1610 { "stkstart", wpa_cli_cmd_stkstart
,
1612 "<addr> = request STK negotiation with <addr>" },
1613 { "ft_ds", wpa_cli_cmd_ft_ds
,
1615 "<addr> = request over-the-DS FT with <addr>" },
1616 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
1618 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1619 { "wps_pin", wpa_cli_cmd_wps_pin
,
1620 cli_cmd_flag_sensitive
,
1621 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1623 #ifdef CONFIG_WPS_OOB
1624 { "wps_oob", wpa_cli_cmd_wps_oob
,
1625 cli_cmd_flag_sensitive
,
1626 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1627 #endif /* CONFIG_WPS_OOB */
1628 { "wps_reg", wpa_cli_cmd_wps_reg
,
1629 cli_cmd_flag_sensitive
,
1630 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1631 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
1633 "= start Wi-Fi Protected Setup External Registrar" },
1634 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
1636 "= stop Wi-Fi Protected Setup External Registrar" },
1637 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
1638 cli_cmd_flag_sensitive
,
1639 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1640 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
1642 "<UUID> = accept an Enrollee PBC using External Registrar" },
1643 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
1644 cli_cmd_flag_sensitive
,
1645 "<UUID> <PIN> = learn AP configuration" },
1646 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
1648 "<addr> = request RSN authentication with <addr> in IBSS" },
1650 { "sta", wpa_cli_cmd_sta
,
1652 "<addr> = get information about an associated station (AP)" },
1653 { "all_sta", wpa_cli_cmd_all_sta
,
1655 "= get information about all associated stations (AP)" },
1656 #endif /* CONFIG_AP */
1657 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
1658 "= notification of suspend/hibernate" },
1659 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
1660 "= notification of resume/thaw" },
1661 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
1662 "= drop SA without deauth/disassoc (test command)" },
1663 { "roam", wpa_cli_cmd_roam
,
1665 "<addr> = roam to the specified BSS" },
1666 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
1671 * Prints command usage, lines are padded with the specified string.
1673 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
1678 printf("%s%s ", pad
, cmd
->cmd
);
1679 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
1688 static void print_help(void)
1691 printf("commands:\n");
1692 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
1693 print_cmd_help(&wpa_cli_commands
[n
], " ");
1697 #ifdef CONFIG_READLINE
1698 static int cmd_has_sensitive_data(const char *cmd
)
1700 const char *c
, *delim
;
1704 delim
= os_strchr(cmd
, ' ');
1708 len
= os_strlen(cmd
);
1710 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
1711 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
1712 return (wpa_cli_commands
[n
].flags
&
1713 cli_cmd_flag_sensitive
);
1717 #endif /* CONFIG_READLINE */
1720 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1722 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
1727 cmd
= wpa_cli_commands
;
1729 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
1732 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
1733 /* we have an exact match */
1743 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
1744 cmd
= wpa_cli_commands
;
1746 if (os_strncasecmp(cmd
->cmd
, argv
[0],
1747 os_strlen(argv
[0])) == 0) {
1748 printf(" %s", cmd
->cmd
);
1754 } else if (count
== 0) {
1755 printf("Unknown command '%s'\n", argv
[0]);
1758 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
1765 static int str_match(const char *a
, const char *b
)
1767 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
1771 static int wpa_cli_exec(const char *program
, const char *arg1
,
1779 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
1780 cmd
= os_malloc(len
);
1783 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
1784 if (res
< 0 || (size_t) res
>= len
) {
1788 cmd
[len
- 1] = '\0';
1790 if (system(cmd
) < 0)
1792 #endif /* _WIN32_WCE */
1799 static void wpa_cli_action_process(const char *msg
)
1802 char *copy
= NULL
, *id
, *pos2
;
1807 pos
= os_strchr(pos
, '>');
1814 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
1816 os_unsetenv("WPA_ID");
1817 os_unsetenv("WPA_ID_STR");
1818 os_unsetenv("WPA_CTRL_DIR");
1820 pos
= os_strstr(pos
, "[id=");
1822 copy
= os_strdup(pos
+ 4);
1826 while (*pos2
&& *pos2
!= ' ')
1830 os_setenv("WPA_ID", id
, 1);
1831 while (*pos2
&& *pos2
!= '=')
1836 while (*pos2
&& *pos2
!= ']')
1839 os_setenv("WPA_ID_STR", id
, 1);
1843 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
1845 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
1846 wpa_cli_connected
= 1;
1847 wpa_cli_last_id
= new_id
;
1848 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
1850 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
1851 if (wpa_cli_connected
) {
1852 wpa_cli_connected
= 0;
1853 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
1855 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
1856 printf("wpa_supplicant is terminating - stop monitoring\n");
1862 #ifndef CONFIG_ANSI_C_EXTRA
1863 static void wpa_cli_action_cb(char *msg
, size_t len
)
1865 wpa_cli_action_process(msg
);
1867 #endif /* CONFIG_ANSI_C_EXTRA */
1870 static void wpa_cli_reconnect(void)
1872 wpa_cli_close_connection();
1873 wpa_cli_open_connection(ctrl_ifname
, 1);
1877 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int in_read
,
1881 if (ctrl_conn
== NULL
) {
1882 wpa_cli_reconnect();
1885 while (wpa_ctrl_pending(ctrl
) > 0) {
1887 size_t len
= sizeof(buf
) - 1;
1888 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
1891 wpa_cli_action_process(buf
);
1893 if (in_read
&& first
)
1896 printf("%s\n", buf
);
1897 #ifdef CONFIG_READLINE
1900 #endif /* CONFIG_READLINE */
1903 printf("Could not read pending message.\n");
1908 if (wpa_ctrl_pending(ctrl
) < 0) {
1909 printf("Connection to wpa_supplicant lost - trying to "
1911 wpa_cli_reconnect();
1916 #ifdef CONFIG_READLINE
1917 static char * wpa_cli_cmd_gen(const char *text
, int state
)
1924 len
= os_strlen(text
);
1927 while ((cmd
= wpa_cli_commands
[i
].cmd
)) {
1929 if (os_strncasecmp(cmd
, text
, len
) == 0)
1937 static char * wpa_cli_dummy_gen(const char *text
, int state
)
1941 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
1942 const char *cmd
= wpa_cli_commands
[i
].cmd
;
1943 size_t len
= os_strlen(cmd
);
1944 if (os_strncasecmp(rl_line_buffer
, cmd
, len
) == 0 &&
1945 rl_line_buffer
[len
] == ' ') {
1946 printf("\n%s\n", wpa_cli_commands
[i
].usage
);
1953 rl_attempted_completion_over
= 1;
1958 static char * wpa_cli_status_gen(const char *text
, int state
)
1968 len
= os_strlen(text
);
1971 while ((t
= options
[i
])) {
1973 if (os_strncasecmp(t
, text
, len
) == 0)
1977 rl_attempted_completion_over
= 1;
1982 static char ** wpa_cli_completion(const char *text
, int start
, int end
)
1984 char * (*func
)(const char *text
, int state
);
1987 func
= wpa_cli_cmd_gen
;
1988 else if (os_strncasecmp(rl_line_buffer
, "status ", 7) == 0)
1989 func
= wpa_cli_status_gen
;
1991 func
= wpa_cli_dummy_gen
;
1992 return rl_completion_matches(text
, func
);
1994 #endif /* CONFIG_READLINE */
1997 static void wpa_cli_interactive(void)
2000 char cmdbuf
[256], *cmd
, *argv
[max_args
], *pos
;
2002 #ifdef CONFIG_READLINE
2003 char *home
, *hfile
= NULL
;
2004 #endif /* CONFIG_READLINE */
2006 printf("\nInteractive mode\n\n");
2008 #ifdef CONFIG_READLINE
2009 rl_attempted_completion_function
= wpa_cli_completion
;
2010 home
= getenv("HOME");
2012 const char *fname
= ".wpa_cli_history";
2013 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
2014 hfile
= os_malloc(hfile_len
);
2017 res
= os_snprintf(hfile
, hfile_len
, "%s/%s", home
,
2019 if (res
>= 0 && res
< hfile_len
) {
2020 hfile
[hfile_len
- 1] = '\0';
2021 read_history(hfile
);
2022 stifle_history(100);
2026 #endif /* CONFIG_READLINE */
2029 wpa_cli_recv_pending(mon_conn
, 0, 0);
2030 #ifndef CONFIG_NATIVE_WINDOWS
2031 alarm(ping_interval
);
2032 #endif /* CONFIG_NATIVE_WINDOWS */
2033 #ifdef CONFIG_WPA_CLI_FORK
2035 kill(mon_pid
, SIGUSR1
);
2036 #endif /* CONFIG_WPA_CLI_FORK */
2037 #ifdef CONFIG_READLINE
2038 cmd
= readline("> ");
2041 while (next_history())
2043 h
= previous_history();
2044 if (h
== NULL
|| os_strcmp(cmd
, h
->line
) != 0)
2048 #else /* CONFIG_READLINE */
2050 cmd
= fgets(cmdbuf
, sizeof(cmdbuf
), stdin
);
2051 #endif /* CONFIG_READLINE */
2052 #ifndef CONFIG_NATIVE_WINDOWS
2054 #endif /* CONFIG_NATIVE_WINDOWS */
2057 wpa_cli_recv_pending(mon_conn
, 0, 0);
2059 while (*pos
!= '\0') {
2075 if (argc
== max_args
)
2078 char *pos2
= os_strrchr(pos
, '"');
2082 while (*pos
!= '\0' && *pos
!= ' ')
2088 wpa_request(ctrl_conn
, argc
, argv
);
2092 #ifdef CONFIG_WPA_CLI_FORK
2094 kill(mon_pid
, SIGUSR2
);
2095 #endif /* CONFIG_WPA_CLI_FORK */
2096 } while (!wpa_cli_quit
);
2098 #ifdef CONFIG_READLINE
2100 /* Save command history, excluding lines that may contain
2104 while ((h
= current_history())) {
2106 while (*p
== ' ' || *p
== '\t')
2108 if (cmd_has_sensitive_data(p
)) {
2109 h
= remove_history(where_history());
2119 write_history(hfile
);
2122 #endif /* CONFIG_READLINE */
2126 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
2128 #ifdef CONFIG_ANSI_C_EXTRA
2129 /* TODO: ANSI C version(?) */
2130 printf("Action processing not supported in ANSI C build.\n");
2131 #else /* CONFIG_ANSI_C_EXTRA */
2135 char buf
[256]; /* note: large enough to fit in unsolicited messages */
2138 fd
= wpa_ctrl_get_fd(ctrl
);
2140 while (!wpa_cli_quit
) {
2143 tv
.tv_sec
= ping_interval
;
2145 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
2146 if (res
< 0 && errno
!= EINTR
) {
2151 if (FD_ISSET(fd
, &rfds
))
2152 wpa_cli_recv_pending(ctrl
, 0, 1);
2154 /* verify that connection is still working */
2155 len
= sizeof(buf
) - 1;
2156 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
2157 wpa_cli_action_cb
) < 0 ||
2158 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
2159 printf("wpa_supplicant did not reply to PING "
2160 "command - exiting\n");
2165 #endif /* CONFIG_ANSI_C_EXTRA */
2169 static void wpa_cli_cleanup(void)
2171 wpa_cli_close_connection();
2173 os_daemonize_terminate(pid_file
);
2175 os_program_deinit();
2178 static void wpa_cli_terminate(int sig
)
2185 #ifdef CONFIG_WPA_CLI_FORK
2186 static void wpa_cli_usr1(int sig
)
2188 #ifdef CONFIG_READLINE
2191 #endif /* CONFIG_READLINE */
2193 #endif /* CONFIG_WPA_CLI_FORK */
2196 #ifndef CONFIG_NATIVE_WINDOWS
2197 static void wpa_cli_alarm(int sig
)
2199 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
2200 printf("Connection to wpa_supplicant lost - trying to "
2202 wpa_cli_close_connection();
2205 wpa_cli_reconnect();
2207 wpa_cli_recv_pending(mon_conn
, 1, 0);
2208 alarm(ping_interval
);
2210 #endif /* CONFIG_NATIVE_WINDOWS */
2213 static char * wpa_cli_get_default_ifname(void)
2215 char *ifname
= NULL
;
2217 #ifdef CONFIG_CTRL_IFACE_UNIX
2218 struct dirent
*dent
;
2219 DIR *dir
= opendir(ctrl_iface_dir
);
2222 while ((dent
= readdir(dir
))) {
2223 #ifdef _DIRENT_HAVE_D_TYPE
2225 * Skip the file if it is not a socket. Also accept
2226 * DT_UNKNOWN (0) in case the C library or underlying
2227 * file system does not support d_type.
2229 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
2231 #endif /* _DIRENT_HAVE_D_TYPE */
2232 if (os_strcmp(dent
->d_name
, ".") == 0 ||
2233 os_strcmp(dent
->d_name
, "..") == 0)
2235 printf("Selected interface '%s'\n", dent
->d_name
);
2236 ifname
= os_strdup(dent
->d_name
);
2240 #endif /* CONFIG_CTRL_IFACE_UNIX */
2242 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2243 char buf
[2048], *pos
;
2245 struct wpa_ctrl
*ctrl
;
2248 ctrl
= wpa_ctrl_open(NULL
);
2252 len
= sizeof(buf
) - 1;
2253 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
2256 pos
= os_strchr(buf
, '\n');
2259 ifname
= os_strdup(buf
);
2261 wpa_ctrl_close(ctrl
);
2262 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2268 int main(int argc
, char *argv
[])
2270 int warning_displayed
= 0;
2274 const char *global
= NULL
;
2276 if (os_program_init())
2280 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
2285 action_file
= optarg
;
2294 ping_interval
= atoi(optarg
);
2300 printf("%s\n", wpa_cli_version
);
2303 os_free(ctrl_ifname
);
2304 ctrl_ifname
= os_strdup(optarg
);
2307 ctrl_iface_dir
= optarg
;
2318 interactive
= (argc
== optind
) && (action_file
== NULL
);
2321 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
2324 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2325 ctrl_conn
= wpa_ctrl_open(NULL
);
2326 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2327 ctrl_conn
= wpa_ctrl_open(global
);
2328 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2329 if (ctrl_conn
== NULL
) {
2330 perror("Failed to connect to wpa_supplicant - "
2337 signal(SIGINT
, wpa_cli_terminate
);
2338 signal(SIGTERM
, wpa_cli_terminate
);
2339 #endif /* _WIN32_WCE */
2340 #ifndef CONFIG_NATIVE_WINDOWS
2341 signal(SIGALRM
, wpa_cli_alarm
);
2342 #endif /* CONFIG_NATIVE_WINDOWS */
2343 #ifdef CONFIG_WPA_CLI_FORK
2344 signal(SIGUSR1
, wpa_cli_usr1
);
2345 #endif /* CONFIG_WPA_CLI_FORK */
2347 if (ctrl_ifname
== NULL
)
2348 ctrl_ifname
= wpa_cli_get_default_ifname();
2352 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
2353 if (warning_displayed
)
2354 printf("Connection established.\n");
2358 if (!warning_displayed
) {
2359 printf("Could not connect to wpa_supplicant - "
2361 warning_displayed
= 1;
2368 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
2369 perror("Failed to connect to wpa_supplicant - "
2375 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
2376 wpa_cli_attached
= 1;
2378 printf("Warning: Failed to attach to "
2379 "wpa_supplicant.\n");
2385 if (daemonize
&& os_daemonize(pid_file
))
2389 wpa_cli_interactive();
2390 else if (action_file
)
2391 wpa_cli_action(ctrl_conn
);
2393 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
2395 os_free(ctrl_ifname
);
2401 #else /* CONFIG_CTRL_IFACE */
2402 int main(int argc
, char *argv
[])
2404 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2407 #endif /* CONFIG_CTRL_IFACE */