2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
22 #ifdef CONFIG_READLINE
23 #include <readline/readline.h>
24 #include <readline/history.h>
25 #endif /* CONFIG_READLINE */
27 #include "common/wpa_ctrl.h"
29 #include "common/version.h"
32 static const char *wpa_cli_version
=
33 "wpa_cli v" VERSION_STR
"\n"
34 "Copyright (c) 2004-2009, 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 struct wpa_ctrl
*ctrl_conn
;
90 static int wpa_cli_quit
= 0;
91 static int wpa_cli_attached
= 0;
92 static int wpa_cli_connected
= 0;
93 static int wpa_cli_last_id
= 0;
94 static const char *ctrl_iface_dir
= "/var/run/wpa_supplicant";
95 static char *ctrl_ifname
= NULL
;
96 static const char *pid_file
= NULL
;
97 static const char *action_file
= NULL
;
98 static int ping_interval
= 5;
101 static void print_help();
104 static void usage(void)
106 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
107 "[-a<action file>] \\\n"
108 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
110 " -h = help (show this usage text)\n"
111 " -v = shown version information\n"
112 " -a = run in daemon mode executing the action file based on "
115 " -B = run a daemon in the background\n"
116 " default path: /var/run/wpa_supplicant\n"
117 " default interface: first interface found in socket path\n");
122 static struct wpa_ctrl
* wpa_cli_open_connection(const char *ifname
)
124 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
125 ctrl_conn
= wpa_ctrl_open(ifname
);
127 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
134 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
135 cfile
= os_malloc(flen
);
138 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
, ifname
);
139 if (res
< 0 || res
>= flen
) {
144 ctrl_conn
= wpa_ctrl_open(cfile
);
147 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
151 static void wpa_cli_close_connection(void)
153 if (ctrl_conn
== NULL
)
156 if (wpa_cli_attached
) {
157 wpa_ctrl_detach(ctrl_conn
);
158 wpa_cli_attached
= 0;
160 wpa_ctrl_close(ctrl_conn
);
165 static void wpa_cli_msg_cb(char *msg
, size_t len
)
171 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
177 if (ctrl_conn
== NULL
) {
178 printf("Not connected to wpa_supplicant - command dropped.\n");
181 len
= sizeof(buf
) - 1;
182 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
185 printf("'%s' command timed out.\n", cmd
);
187 } else if (ret
< 0) {
188 printf("'%s' command failed.\n", cmd
);
199 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
201 return _wpa_ctrl_command(ctrl
, cmd
, 1);
205 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
207 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
208 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
212 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
214 return wpa_ctrl_command(ctrl
, "PING");
218 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
220 return wpa_ctrl_command(ctrl
, "MIB");
224 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
226 return wpa_ctrl_command(ctrl
, "PMKSA");
230 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
237 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
239 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
244 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
251 static void wpa_cli_show_variables(void)
253 printf("set variables:\n"
254 " EAPOL::heldPeriod (EAPOL state machine held period, "
256 " EAPOL::authPeriod (EAPOL state machine authentication "
257 "period, in seconds)\n"
258 " EAPOL::startPeriod (EAPOL state machine start period, in "
260 " EAPOL::maxStart (EAPOL state machine maximum start "
262 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
264 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
265 " threshold\n\tpercentage)\n"
266 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
267 "security\n\tassociation in seconds)\n");
271 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
277 wpa_cli_show_variables();
282 printf("Invalid SET command: needs two arguments (variable "
283 "name and value)\n");
287 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s", argv
[0], argv
[1]);
288 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
289 printf("Too long SET command.\n");
292 return wpa_ctrl_command(ctrl
, cmd
);
296 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
298 return wpa_ctrl_command(ctrl
, "LOGOFF");
302 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
304 return wpa_ctrl_command(ctrl
, "LOGON");
308 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
311 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
315 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
322 printf("Invalid PREAUTH command: needs one argument "
327 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
328 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
329 printf("Too long PREAUTH command.\n");
332 return wpa_ctrl_command(ctrl
, cmd
);
336 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
342 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
346 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
347 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
348 printf("Too long AP_SCAN command.\n");
351 return wpa_ctrl_command(ctrl
, cmd
);
355 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
362 printf("Invalid STKSTART command: needs one argument "
363 "(Peer STA MAC address)\n");
367 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
368 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
369 printf("Too long STKSTART command.\n");
372 return wpa_ctrl_command(ctrl
, cmd
);
376 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
382 printf("Invalid FT_DS command: needs one argument "
383 "(Target AP MAC address)\n");
387 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
388 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
389 printf("Too long FT_DS command.\n");
392 return wpa_ctrl_command(ctrl
, cmd
);
396 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
403 return wpa_ctrl_command(ctrl
, "WPS_PBC");
407 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
408 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
409 printf("Too long WPS_PBC command.\n");
412 return wpa_ctrl_command(ctrl
, cmd
);
416 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
422 printf("Invalid WPS_PIN command: need one or two arguments:\n"
423 "- BSSID: use 'any' to select any\n"
424 "- PIN: optional, used only with devices that have no "
430 /* Use dynamically generated PIN (returned as reply) */
431 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
432 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
433 printf("Too long WPS_PIN command.\n");
436 return wpa_ctrl_command(ctrl
, cmd
);
439 /* Use hardcoded PIN from a label */
440 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
441 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
442 printf("Too long WPS_PIN command.\n");
445 return wpa_ctrl_command(ctrl
, cmd
);
449 #ifdef CONFIG_WPS_OOB
450 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
455 if (argc
!= 3 && argc
!= 4) {
456 printf("Invalid WPS_OOB command: need three or four "
458 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
459 "- PATH: path of OOB device like '/mnt'\n"
460 "- METHOD: OOB method 'pin-e' or 'pin-r', "
462 "- DEV_NAME: (only for NFC) device name like "
468 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
469 argv
[0], argv
[1], argv
[2]);
471 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
472 argv
[0], argv
[1], argv
[2], argv
[3]);
473 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
474 printf("Too long WPS_OOB command.\n");
477 return wpa_ctrl_command(ctrl
, cmd
);
479 #endif /* CONFIG_WPS_OOB */
482 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
488 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
490 else if (argc
== 6) {
491 char ssid_hex
[2 * 32 + 1];
492 char key_hex
[2 * 64 + 1];
496 for (i
= 0; i
< 32; i
++) {
497 if (argv
[2][i
] == '\0')
499 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
503 for (i
= 0; i
< 64; i
++) {
504 if (argv
[5][i
] == '\0')
506 os_snprintf(&key_hex
[i
* 2], 3, "%02x", argv
[5][i
]);
509 res
= os_snprintf(cmd
, sizeof(cmd
),
510 "WPS_REG %s %s %s %s %s %s",
511 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
514 printf("Invalid WPS_REG command: need two arguments:\n"
515 "- BSSID: use 'any' to select any\n"
517 printf("Alternatively, six arguments can be used to "
518 "reconfigure the AP:\n"
519 "- BSSID: use 'any' to select any\n"
522 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
523 "- new encr (NONE, WEP, TKIP, CCMP)\n"
528 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
529 printf("Too long WPS_REG command.\n");
532 return wpa_ctrl_command(ctrl
, cmd
);
536 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
539 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
544 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
547 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
552 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
559 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
560 "- UUID: use 'any' to select any\n"
561 "- PIN: Enrollee PIN\n");
565 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
567 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
568 printf("Too long WPS_ER_PIN command.\n");
571 return wpa_ctrl_command(ctrl
, cmd
);
575 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
582 printf("Invalid WPS_ER_PBC command: need one argument:\n"
583 "- UUID: Specify the Enrollee\n");
587 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
589 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
590 printf("Too long WPS_ER_PBC command.\n");
593 return wpa_ctrl_command(ctrl
, cmd
);
597 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
604 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
605 "- UUID: specify which AP to use\n"
610 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
612 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
613 printf("Too long WPS_ER_LEARN command.\n");
616 return wpa_ctrl_command(ctrl
, cmd
);
620 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
626 printf("Invalid IBSS_RSN command: needs one argument "
627 "(Peer STA MAC address)\n");
631 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
632 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
633 printf("Too long IBSS_RSN command.\n");
636 return wpa_ctrl_command(ctrl
, cmd
);
640 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
646 printf("Invalid LEVEL command: needs one argument (debug "
650 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
651 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
652 printf("Too long LEVEL command.\n");
655 return wpa_ctrl_command(ctrl
, cmd
);
659 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
661 char cmd
[256], *pos
, *end
;
665 printf("Invalid IDENTITY command: needs two arguments "
666 "(network id and identity)\n");
670 end
= cmd
+ sizeof(cmd
);
672 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
674 if (ret
< 0 || ret
>= end
- pos
) {
675 printf("Too long IDENTITY command.\n");
679 for (i
= 2; i
< argc
; i
++) {
680 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
681 if (ret
< 0 || ret
>= end
- pos
) {
682 printf("Too long IDENTITY command.\n");
688 return wpa_ctrl_command(ctrl
, cmd
);
692 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
694 char cmd
[256], *pos
, *end
;
698 printf("Invalid PASSWORD command: needs two arguments "
699 "(network id and password)\n");
703 end
= cmd
+ sizeof(cmd
);
705 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
707 if (ret
< 0 || ret
>= end
- pos
) {
708 printf("Too long PASSWORD command.\n");
712 for (i
= 2; i
< argc
; i
++) {
713 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
714 if (ret
< 0 || ret
>= end
- pos
) {
715 printf("Too long PASSWORD command.\n");
721 return wpa_ctrl_command(ctrl
, cmd
);
725 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
728 char cmd
[256], *pos
, *end
;
732 printf("Invalid NEW_PASSWORD command: needs two arguments "
733 "(network id and password)\n");
737 end
= cmd
+ sizeof(cmd
);
739 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
741 if (ret
< 0 || ret
>= end
- pos
) {
742 printf("Too long NEW_PASSWORD command.\n");
746 for (i
= 2; i
< argc
; i
++) {
747 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
748 if (ret
< 0 || ret
>= end
- pos
) {
749 printf("Too long NEW_PASSWORD command.\n");
755 return wpa_ctrl_command(ctrl
, cmd
);
759 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
761 char cmd
[256], *pos
, *end
;
765 printf("Invalid PIN command: needs two arguments "
766 "(network id and pin)\n");
770 end
= cmd
+ sizeof(cmd
);
772 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
774 if (ret
< 0 || ret
>= end
- pos
) {
775 printf("Too long PIN command.\n");
779 for (i
= 2; i
< argc
; i
++) {
780 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
781 if (ret
< 0 || ret
>= end
- pos
) {
782 printf("Too long PIN command.\n");
787 return wpa_ctrl_command(ctrl
, cmd
);
791 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
793 char cmd
[256], *pos
, *end
;
797 printf("Invalid OTP command: needs two arguments (network "
798 "id and password)\n");
802 end
= cmd
+ sizeof(cmd
);
804 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
806 if (ret
< 0 || ret
>= end
- pos
) {
807 printf("Too long OTP command.\n");
811 for (i
= 2; i
< argc
; i
++) {
812 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
813 if (ret
< 0 || ret
>= end
- pos
) {
814 printf("Too long OTP command.\n");
820 return wpa_ctrl_command(ctrl
, cmd
);
824 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
827 char cmd
[256], *pos
, *end
;
831 printf("Invalid PASSPHRASE command: needs two arguments "
832 "(network id and passphrase)\n");
836 end
= cmd
+ sizeof(cmd
);
838 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
840 if (ret
< 0 || ret
>= end
- pos
) {
841 printf("Too long PASSPHRASE command.\n");
845 for (i
= 2; i
< argc
; i
++) {
846 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
847 if (ret
< 0 || ret
>= end
- pos
) {
848 printf("Too long PASSPHRASE command.\n");
854 return wpa_ctrl_command(ctrl
, cmd
);
858 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
860 char cmd
[256], *pos
, *end
;
864 printf("Invalid BSSID command: needs two arguments (network "
869 end
= cmd
+ sizeof(cmd
);
871 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
872 if (ret
< 0 || ret
>= end
- pos
) {
873 printf("Too long BSSID command.\n");
877 for (i
= 0; i
< argc
; i
++) {
878 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
879 if (ret
< 0 || ret
>= end
- pos
) {
880 printf("Too long BSSID command.\n");
886 return wpa_ctrl_command(ctrl
, cmd
);
890 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
893 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
897 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
904 printf("Invalid SELECT_NETWORK command: needs one argument "
909 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
910 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
912 cmd
[sizeof(cmd
) - 1] = '\0';
914 return wpa_ctrl_command(ctrl
, cmd
);
918 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
925 printf("Invalid ENABLE_NETWORK command: needs one argument "
930 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
931 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
933 cmd
[sizeof(cmd
) - 1] = '\0';
935 return wpa_ctrl_command(ctrl
, cmd
);
939 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
946 printf("Invalid DISABLE_NETWORK command: needs one argument "
951 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
952 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
954 cmd
[sizeof(cmd
) - 1] = '\0';
956 return wpa_ctrl_command(ctrl
, cmd
);
960 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
963 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
967 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
974 printf("Invalid REMOVE_NETWORK command: needs one argument "
979 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
980 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
982 cmd
[sizeof(cmd
) - 1] = '\0';
984 return wpa_ctrl_command(ctrl
, cmd
);
988 static void wpa_cli_show_network_variables(void)
990 printf("set_network variables:\n"
991 " ssid (network name, SSID)\n"
992 " psk (WPA passphrase or pre-shared key)\n"
993 " key_mgmt (key management protocol)\n"
994 " identity (EAP identity)\n"
995 " password (EAP password)\n"
998 "Note: Values are entered in the same format as the "
999 "configuration file is using,\n"
1000 "i.e., strings values need to be inside double quotation "
1002 "For example: set_network 1 ssid \"network name\"\n"
1004 "Please see wpa_supplicant.conf documentation for full list "
1005 "of\navailable variables.\n");
1009 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1016 wpa_cli_show_network_variables();
1021 printf("Invalid SET_NETWORK command: needs three arguments\n"
1022 "(network id, variable name, and value)\n");
1026 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1027 argv
[0], argv
[1], argv
[2]);
1028 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1029 printf("Too long SET_NETWORK command.\n");
1032 return wpa_ctrl_command(ctrl
, cmd
);
1036 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1043 wpa_cli_show_network_variables();
1048 printf("Invalid GET_NETWORK command: needs two arguments\n"
1049 "(network id and variable name)\n");
1053 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1055 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1056 printf("Too long GET_NETWORK command.\n");
1059 return wpa_ctrl_command(ctrl
, cmd
);
1063 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1066 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1070 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1073 return wpa_ctrl_command(ctrl
, "RECONNECT");
1077 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1080 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1084 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1086 return wpa_ctrl_command(ctrl
, "SCAN");
1090 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1093 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1097 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1103 printf("Invalid BSS command: need one argument (index or "
1108 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1109 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1111 cmd
[sizeof(cmd
) - 1] = '\0';
1113 return wpa_ctrl_command(ctrl
, cmd
);
1117 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1123 if (argc
< 1 || argc
> 2) {
1124 printf("Invalid GET_CAPABILITY command: need either one or "
1129 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1130 printf("Invalid GET_CAPABILITY command: second argument, "
1131 "if any, must be 'strict'\n");
1135 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1136 (argc
== 2) ? " strict" : "");
1137 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1139 cmd
[sizeof(cmd
) - 1] = '\0';
1141 return wpa_ctrl_command(ctrl
, cmd
);
1145 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1147 printf("Available interfaces:\n");
1148 return wpa_ctrl_command(ctrl
, "INTERFACES");
1152 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1155 wpa_cli_list_interfaces(ctrl
);
1159 wpa_cli_close_connection();
1160 os_free(ctrl_ifname
);
1161 ctrl_ifname
= os_strdup(argv
[0]);
1163 if (wpa_cli_open_connection(ctrl_ifname
)) {
1164 printf("Connected to interface '%s.\n", ctrl_ifname
);
1165 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
1166 wpa_cli_attached
= 1;
1168 printf("Warning: Failed to attach to "
1169 "wpa_supplicant.\n");
1172 printf("Could not connect to interface '%s' - re-trying\n",
1179 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1182 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1186 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1189 return wpa_ctrl_command(ctrl
, "TERMINATE");
1193 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1200 printf("Invalid INTERFACE_ADD command: needs at least one "
1201 "argument (interface name)\n"
1202 "All arguments: ifname confname driver ctrl_interface "
1203 "driver_param bridge_name\n");
1208 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1209 * <driver_param>TAB<bridge_name>
1211 res
= os_snprintf(cmd
, sizeof(cmd
),
1212 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1214 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1215 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1216 argc
> 5 ? argv
[5] : "");
1217 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1219 cmd
[sizeof(cmd
) - 1] = '\0';
1220 return wpa_ctrl_command(ctrl
, cmd
);
1224 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1231 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1232 "(interface name)\n");
1236 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1237 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1239 cmd
[sizeof(cmd
) - 1] = '\0';
1240 return wpa_ctrl_command(ctrl
, cmd
);
1244 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1247 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1252 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1256 printf("Invalid 'sta' command - exactly one argument, STA "
1257 "address, is required.\n");
1260 snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1261 return wpa_ctrl_command(ctrl
, buf
);
1265 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1266 char *addr
, size_t addr_len
)
1268 char buf
[4096], *pos
;
1272 if (ctrl_conn
== NULL
) {
1273 printf("Not connected to hostapd - command dropped.\n");
1276 len
= sizeof(buf
) - 1;
1277 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1280 printf("'%s' command timed out.\n", cmd
);
1282 } else if (ret
< 0) {
1283 printf("'%s' command failed.\n", cmd
);
1288 if (memcmp(buf
, "FAIL", 4) == 0)
1293 while (*pos
!= '\0' && *pos
!= '\n')
1296 os_strlcpy(addr
, buf
, addr_len
);
1301 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1303 char addr
[32], cmd
[64];
1305 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1308 snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1309 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1313 #endif /* CONFIG_AP */
1316 enum wpa_cli_cmd_flags
{
1317 cli_cmd_flag_none
= 0x00,
1318 cli_cmd_flag_sensitive
= 0x01
1321 struct wpa_cli_cmd
{
1323 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
1324 enum wpa_cli_cmd_flags flags
;
1328 static struct wpa_cli_cmd wpa_cli_commands
[] = {
1329 { "status", wpa_cli_cmd_status
,
1331 "[verbose] = get current WPA/EAPOL/EAP status" },
1332 { "ping", wpa_cli_cmd_ping
,
1334 "= pings wpa_supplicant" },
1335 { "mib", wpa_cli_cmd_mib
,
1337 "= get MIB variables (dot1x, dot11)" },
1338 { "help", wpa_cli_cmd_help
,
1340 "= show this usage help" },
1341 { "interface", wpa_cli_cmd_interface
,
1343 "[ifname] = show interfaces/select interface" },
1344 { "level", wpa_cli_cmd_level
,
1346 "<debug level> = change debug level" },
1347 { "license", wpa_cli_cmd_license
,
1349 "= show full wpa_cli license" },
1350 { "quit", wpa_cli_cmd_quit
,
1353 { "set", wpa_cli_cmd_set
,
1355 "= set variables (shows list of variables when run without "
1357 { "logon", wpa_cli_cmd_logon
,
1359 "= IEEE 802.1X EAPOL state machine logon" },
1360 { "logoff", wpa_cli_cmd_logoff
,
1362 "= IEEE 802.1X EAPOL state machine logoff" },
1363 { "pmksa", wpa_cli_cmd_pmksa
,
1365 "= show PMKSA cache" },
1366 { "reassociate", wpa_cli_cmd_reassociate
,
1368 "= force reassociation" },
1369 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
1371 "<BSSID> = force preauthentication" },
1372 { "identity", wpa_cli_cmd_identity
,
1374 "<network id> <identity> = configure identity for an SSID" },
1375 { "password", wpa_cli_cmd_password
,
1376 cli_cmd_flag_sensitive
,
1377 "<network id> <password> = configure password for an SSID" },
1378 { "new_password", wpa_cli_cmd_new_password
,
1379 cli_cmd_flag_sensitive
,
1380 "<network id> <password> = change password for an SSID" },
1381 { "pin", wpa_cli_cmd_pin
,
1382 cli_cmd_flag_sensitive
,
1383 "<network id> <pin> = configure pin for an SSID" },
1384 { "otp", wpa_cli_cmd_otp
,
1385 cli_cmd_flag_sensitive
,
1386 "<network id> <password> = configure one-time-password for an SSID"
1388 { "passphrase", wpa_cli_cmd_passphrase
,
1389 cli_cmd_flag_sensitive
,
1390 "<network id> <passphrase> = configure private key passphrase\n"
1392 { "bssid", wpa_cli_cmd_bssid
,
1394 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1395 { "list_networks", wpa_cli_cmd_list_networks
,
1397 "= list configured networks" },
1398 { "select_network", wpa_cli_cmd_select_network
,
1400 "<network id> = select a network (disable others)" },
1401 { "enable_network", wpa_cli_cmd_enable_network
,
1403 "<network id> = enable a network" },
1404 { "disable_network", wpa_cli_cmd_disable_network
,
1406 "<network id> = disable a network" },
1407 { "add_network", wpa_cli_cmd_add_network
,
1409 "= add a network" },
1410 { "remove_network", wpa_cli_cmd_remove_network
,
1412 "<network id> = remove a network" },
1413 { "set_network", wpa_cli_cmd_set_network
,
1414 cli_cmd_flag_sensitive
,
1415 "<network id> <variable> <value> = set network variables (shows\n"
1416 " list of variables when run without arguments)" },
1417 { "get_network", wpa_cli_cmd_get_network
,
1419 "<network id> <variable> = get network variables" },
1420 { "save_config", wpa_cli_cmd_save_config
,
1422 "= save the current configuration" },
1423 { "disconnect", wpa_cli_cmd_disconnect
,
1425 "= disconnect and wait for reassociate/reconnect command before\n"
1427 { "reconnect", wpa_cli_cmd_reconnect
,
1429 "= like reassociate, but only takes effect if already disconnected"
1431 { "scan", wpa_cli_cmd_scan
,
1433 "= request new BSS scan" },
1434 { "scan_results", wpa_cli_cmd_scan_results
,
1436 "= get latest scan results" },
1437 { "bss", wpa_cli_cmd_bss
,
1439 "<<idx> | <bssid>> = get detailed scan result info" },
1440 { "get_capability", wpa_cli_cmd_get_capability
,
1442 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1443 { "reconfigure", wpa_cli_cmd_reconfigure
,
1445 "= force wpa_supplicant to re-read its configuration file" },
1446 { "terminate", wpa_cli_cmd_terminate
,
1448 "= terminate wpa_supplicant" },
1449 { "interface_add", wpa_cli_cmd_interface_add
,
1451 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1452 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1454 { "interface_remove", wpa_cli_cmd_interface_remove
,
1456 "<ifname> = removes the interface" },
1457 { "interface_list", wpa_cli_cmd_interface_list
,
1459 "= list available interfaces" },
1460 { "ap_scan", wpa_cli_cmd_ap_scan
,
1462 "<value> = set ap_scan parameter" },
1463 { "stkstart", wpa_cli_cmd_stkstart
,
1465 "<addr> = request STK negotiation with <addr>" },
1466 { "ft_ds", wpa_cli_cmd_ft_ds
,
1468 "<addr> = request over-the-DS FT with <addr>" },
1469 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
1471 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1472 { "wps_pin", wpa_cli_cmd_wps_pin
,
1473 cli_cmd_flag_sensitive
,
1474 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1476 #ifdef CONFIG_WPS_OOB
1477 { "wps_oob", wpa_cli_cmd_wps_oob
,
1478 cli_cmd_flag_sensitive
,
1479 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1480 #endif /* CONFIG_WPS_OOB */
1481 { "wps_reg", wpa_cli_cmd_wps_reg
,
1482 cli_cmd_flag_sensitive
,
1483 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1484 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
1486 "= start Wi-Fi Protected Setup External Registrar" },
1487 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
1489 "= stop Wi-Fi Protected Setup External Registrar" },
1490 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
1491 cli_cmd_flag_sensitive
,
1492 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1493 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
1495 "<UUID> = accept an Enrollee PBC using External Registrar" },
1496 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
1497 cli_cmd_flag_sensitive
,
1498 "<UUID> <PIN> = learn AP configuration" },
1499 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
1501 "<addr> = request RSN authentication with <addr> in IBSS" },
1503 { "sta", wpa_cli_cmd_sta
,
1505 "<addr> = get information about an associated station (AP)" },
1506 { "all_sta", wpa_cli_cmd_all_sta
,
1508 "= get information about all associated stations (AP)" },
1509 #endif /* CONFIG_AP */
1510 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
1515 * Prints command usage, lines are padded with the specified string.
1517 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
1522 printf("%s%s ", pad
, cmd
->cmd
);
1523 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
1532 static void print_help(void)
1535 printf("commands:\n");
1536 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
1537 print_cmd_help(&wpa_cli_commands
[n
], " ");
1541 #ifdef CONFIG_READLINE
1542 static int cmd_has_sensitive_data(const char *cmd
)
1544 const char *c
, *delim
;
1548 delim
= os_strchr(cmd
, ' ');
1552 len
= os_strlen(cmd
);
1554 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
1555 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
1556 return (wpa_cli_commands
[n
].flags
&
1557 cli_cmd_flag_sensitive
);
1561 #endif /* CONFIG_READLINE */
1564 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1566 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
1571 cmd
= wpa_cli_commands
;
1573 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
1576 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
1577 /* we have an exact match */
1587 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
1588 cmd
= wpa_cli_commands
;
1590 if (os_strncasecmp(cmd
->cmd
, argv
[0],
1591 os_strlen(argv
[0])) == 0) {
1592 printf(" %s", cmd
->cmd
);
1598 } else if (count
== 0) {
1599 printf("Unknown command '%s'\n", argv
[0]);
1602 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
1609 static int str_match(const char *a
, const char *b
)
1611 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
1615 static int wpa_cli_exec(const char *program
, const char *arg1
,
1623 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
1624 cmd
= os_malloc(len
);
1627 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
1628 if (res
< 0 || (size_t) res
>= len
) {
1632 cmd
[len
- 1] = '\0';
1634 if (system(cmd
) < 0)
1636 #endif /* _WIN32_WCE */
1643 static void wpa_cli_action_process(const char *msg
)
1646 char *copy
= NULL
, *id
, *pos2
;
1651 pos
= os_strchr(pos
, '>');
1658 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
1660 os_unsetenv("WPA_ID");
1661 os_unsetenv("WPA_ID_STR");
1662 os_unsetenv("WPA_CTRL_DIR");
1664 pos
= os_strstr(pos
, "[id=");
1666 copy
= os_strdup(pos
+ 4);
1670 while (*pos2
&& *pos2
!= ' ')
1674 os_setenv("WPA_ID", id
, 1);
1675 while (*pos2
&& *pos2
!= '=')
1680 while (*pos2
&& *pos2
!= ']')
1683 os_setenv("WPA_ID_STR", id
, 1);
1687 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
1689 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
1690 wpa_cli_connected
= 1;
1691 wpa_cli_last_id
= new_id
;
1692 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
1694 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
1695 if (wpa_cli_connected
) {
1696 wpa_cli_connected
= 0;
1697 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
1699 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
1700 printf("wpa_supplicant is terminating - stop monitoring\n");
1706 #ifndef CONFIG_ANSI_C_EXTRA
1707 static void wpa_cli_action_cb(char *msg
, size_t len
)
1709 wpa_cli_action_process(msg
);
1711 #endif /* CONFIG_ANSI_C_EXTRA */
1714 static void wpa_cli_reconnect(void)
1716 wpa_cli_close_connection();
1717 ctrl_conn
= wpa_cli_open_connection(ctrl_ifname
);
1719 printf("Connection to wpa_supplicant re-established\n");
1720 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
1721 wpa_cli_attached
= 1;
1723 printf("Warning: Failed to attach to "
1724 "wpa_supplicant.\n");
1730 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int in_read
,
1734 if (ctrl_conn
== NULL
) {
1735 wpa_cli_reconnect();
1738 while (wpa_ctrl_pending(ctrl
) > 0) {
1740 size_t len
= sizeof(buf
) - 1;
1741 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
1744 wpa_cli_action_process(buf
);
1746 if (in_read
&& first
)
1749 printf("%s\n", buf
);
1752 printf("Could not read pending message.\n");
1757 if (wpa_ctrl_pending(ctrl
) < 0) {
1758 printf("Connection to wpa_supplicant lost - trying to "
1760 wpa_cli_reconnect();
1765 #ifdef CONFIG_READLINE
1766 static char * wpa_cli_cmd_gen(const char *text
, int state
)
1773 len
= os_strlen(text
);
1776 while ((cmd
= wpa_cli_commands
[i
].cmd
)) {
1778 if (os_strncasecmp(cmd
, text
, len
) == 0)
1779 return os_strdup(cmd
);
1786 static char * wpa_cli_dummy_gen(const char *text
, int state
)
1792 static char ** wpa_cli_completion(const char *text
, int start
, int end
)
1794 return rl_completion_matches(text
, start
== 0 ?
1795 wpa_cli_cmd_gen
: wpa_cli_dummy_gen
);
1797 #endif /* CONFIG_READLINE */
1800 static void wpa_cli_interactive(void)
1803 char cmdbuf
[256], *cmd
, *argv
[max_args
], *pos
;
1805 #ifdef CONFIG_READLINE
1806 char *home
, *hfile
= NULL
;
1807 #endif /* CONFIG_READLINE */
1809 printf("\nInteractive mode\n\n");
1811 #ifdef CONFIG_READLINE
1812 rl_attempted_completion_function
= wpa_cli_completion
;
1813 home
= getenv("HOME");
1815 const char *fname
= ".wpa_cli_history";
1816 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
1817 hfile
= os_malloc(hfile_len
);
1820 res
= os_snprintf(hfile
, hfile_len
, "%s/%s", home
,
1822 if (res
>= 0 && res
< hfile_len
) {
1823 hfile
[hfile_len
- 1] = '\0';
1824 read_history(hfile
);
1825 stifle_history(100);
1829 #endif /* CONFIG_READLINE */
1832 wpa_cli_recv_pending(ctrl_conn
, 0, 0);
1833 #ifndef CONFIG_NATIVE_WINDOWS
1834 alarm(ping_interval
);
1835 #endif /* CONFIG_NATIVE_WINDOWS */
1836 #ifdef CONFIG_READLINE
1837 cmd
= readline("> ");
1840 while (next_history())
1842 h
= previous_history();
1843 if (h
== NULL
|| os_strcmp(cmd
, h
->line
) != 0)
1847 #else /* CONFIG_READLINE */
1849 cmd
= fgets(cmdbuf
, sizeof(cmdbuf
), stdin
);
1850 #endif /* CONFIG_READLINE */
1851 #ifndef CONFIG_NATIVE_WINDOWS
1853 #endif /* CONFIG_NATIVE_WINDOWS */
1856 wpa_cli_recv_pending(ctrl_conn
, 0, 0);
1858 while (*pos
!= '\0') {
1874 if (argc
== max_args
)
1877 char *pos2
= os_strrchr(pos
, '"');
1881 while (*pos
!= '\0' && *pos
!= ' ')
1887 wpa_request(ctrl_conn
, argc
, argv
);
1891 } while (!wpa_cli_quit
);
1893 #ifdef CONFIG_READLINE
1895 /* Save command history, excluding lines that may contain
1899 while ((h
= current_history())) {
1901 while (*p
== ' ' || *p
== '\t')
1903 if (cmd_has_sensitive_data(p
)) {
1904 h
= remove_history(where_history());
1914 write_history(hfile
);
1917 #endif /* CONFIG_READLINE */
1921 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
1923 #ifdef CONFIG_ANSI_C_EXTRA
1924 /* TODO: ANSI C version(?) */
1925 printf("Action processing not supported in ANSI C build.\n");
1926 #else /* CONFIG_ANSI_C_EXTRA */
1930 char buf
[256]; /* note: large enough to fit in unsolicited messages */
1933 fd
= wpa_ctrl_get_fd(ctrl
);
1935 while (!wpa_cli_quit
) {
1938 tv
.tv_sec
= ping_interval
;
1940 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
1941 if (res
< 0 && errno
!= EINTR
) {
1946 if (FD_ISSET(fd
, &rfds
))
1947 wpa_cli_recv_pending(ctrl
, 0, 1);
1949 /* verify that connection is still working */
1950 len
= sizeof(buf
) - 1;
1951 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
1952 wpa_cli_action_cb
) < 0 ||
1953 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
1954 printf("wpa_supplicant did not reply to PING "
1955 "command - exiting\n");
1960 #endif /* CONFIG_ANSI_C_EXTRA */
1964 static void wpa_cli_cleanup(void)
1966 wpa_cli_close_connection();
1968 os_daemonize_terminate(pid_file
);
1970 os_program_deinit();
1973 static void wpa_cli_terminate(int sig
)
1980 #ifndef CONFIG_NATIVE_WINDOWS
1981 static void wpa_cli_alarm(int sig
)
1983 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
1984 printf("Connection to wpa_supplicant lost - trying to "
1986 wpa_cli_close_connection();
1989 wpa_cli_reconnect();
1991 wpa_cli_recv_pending(ctrl_conn
, 1, 0);
1992 alarm(ping_interval
);
1994 #endif /* CONFIG_NATIVE_WINDOWS */
1997 static char * wpa_cli_get_default_ifname(void)
1999 char *ifname
= NULL
;
2001 #ifdef CONFIG_CTRL_IFACE_UNIX
2002 struct dirent
*dent
;
2003 DIR *dir
= opendir(ctrl_iface_dir
);
2006 while ((dent
= readdir(dir
))) {
2007 #ifdef _DIRENT_HAVE_D_TYPE
2009 * Skip the file if it is not a socket. Also accept
2010 * DT_UNKNOWN (0) in case the C library or underlying
2011 * file system does not support d_type.
2013 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
2015 #endif /* _DIRENT_HAVE_D_TYPE */
2016 if (os_strcmp(dent
->d_name
, ".") == 0 ||
2017 os_strcmp(dent
->d_name
, "..") == 0)
2019 printf("Selected interface '%s'\n", dent
->d_name
);
2020 ifname
= os_strdup(dent
->d_name
);
2024 #endif /* CONFIG_CTRL_IFACE_UNIX */
2026 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2027 char buf
[2048], *pos
;
2029 struct wpa_ctrl
*ctrl
;
2032 ctrl
= wpa_ctrl_open(NULL
);
2036 len
= sizeof(buf
) - 1;
2037 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
2040 pos
= os_strchr(buf
, '\n');
2043 ifname
= os_strdup(buf
);
2045 wpa_ctrl_close(ctrl
);
2046 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2052 int main(int argc
, char *argv
[])
2055 int warning_displayed
= 0;
2059 const char *global
= NULL
;
2061 if (os_program_init())
2065 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
2070 action_file
= optarg
;
2079 ping_interval
= atoi(optarg
);
2085 printf("%s\n", wpa_cli_version
);
2088 os_free(ctrl_ifname
);
2089 ctrl_ifname
= os_strdup(optarg
);
2092 ctrl_iface_dir
= optarg
;
2103 interactive
= (argc
== optind
) && (action_file
== NULL
);
2106 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
2109 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2110 ctrl_conn
= wpa_ctrl_open(NULL
);
2111 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2112 ctrl_conn
= wpa_ctrl_open(global
);
2113 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2114 if (ctrl_conn
== NULL
) {
2115 perror("Failed to connect to wpa_supplicant - "
2122 if (ctrl_ifname
== NULL
)
2123 ctrl_ifname
= wpa_cli_get_default_ifname();
2124 ctrl_conn
= wpa_cli_open_connection(ctrl_ifname
);
2126 if (warning_displayed
)
2127 printf("Connection established.\n");
2132 perror("Failed to connect to wpa_supplicant - "
2137 if (!warning_displayed
) {
2138 printf("Could not connect to wpa_supplicant - "
2140 warning_displayed
= 1;
2147 signal(SIGINT
, wpa_cli_terminate
);
2148 signal(SIGTERM
, wpa_cli_terminate
);
2149 #endif /* _WIN32_WCE */
2150 #ifndef CONFIG_NATIVE_WINDOWS
2151 signal(SIGALRM
, wpa_cli_alarm
);
2152 #endif /* CONFIG_NATIVE_WINDOWS */
2154 if (interactive
|| action_file
) {
2155 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
2156 wpa_cli_attached
= 1;
2158 printf("Warning: Failed to attach to "
2159 "wpa_supplicant.\n");
2165 if (daemonize
&& os_daemonize(pid_file
))
2169 wpa_cli_interactive();
2170 else if (action_file
)
2171 wpa_cli_action(ctrl_conn
);
2173 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
2175 os_free(ctrl_ifname
);
2181 #else /* CONFIG_CTRL_IFACE */
2182 int main(int argc
, char *argv
[])
2184 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2187 #endif /* CONFIG_CTRL_IFACE */