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 */
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-2010, 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 struct wpa_ctrl
*mon_conn
;
91 static int wpa_cli_quit
= 0;
92 static int wpa_cli_attached
= 0;
93 static int wpa_cli_connected
= 0;
94 static int wpa_cli_last_id
= 0;
95 static const char *ctrl_iface_dir
= "/var/run/wpa_supplicant";
96 static char *ctrl_ifname
= NULL
;
97 static const char *pid_file
= NULL
;
98 static const char *action_file
= NULL
;
99 static int ping_interval
= 5;
100 static int interactive
= 0;
103 static void print_help();
106 static void usage(void)
108 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
109 "[-a<action file>] \\\n"
110 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
112 " -h = help (show this usage text)\n"
113 " -v = shown version information\n"
114 " -a = run in daemon mode executing the action file based on "
117 " -B = run a daemon in the background\n"
118 " default path: /var/run/wpa_supplicant\n"
119 " default interface: first interface found in socket path\n");
124 static int wpa_cli_open_connection(const char *ifname
, int attach
)
126 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
127 ctrl_conn
= wpa_ctrl_open(ifname
);
128 if (ctrl_conn
== NULL
)
131 if (attach
&& interactive
)
132 mon_conn
= wpa_ctrl_open(ifname
);
135 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
142 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
143 cfile
= os_malloc(flen
);
146 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
, ifname
);
147 if (res
< 0 || res
>= flen
) {
152 ctrl_conn
= wpa_ctrl_open(cfile
);
153 if (ctrl_conn
== NULL
) {
158 if (attach
&& interactive
)
159 mon_conn
= wpa_ctrl_open(cfile
);
163 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
166 if (wpa_ctrl_attach(mon_conn
) == 0) {
167 wpa_cli_attached
= 1;
169 printf("Warning: Failed to attach to "
170 "wpa_supplicant.\n");
179 static void wpa_cli_close_connection(void)
181 if (ctrl_conn
== NULL
)
184 if (wpa_cli_attached
) {
185 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
186 wpa_cli_attached
= 0;
188 wpa_ctrl_close(ctrl_conn
);
191 wpa_ctrl_close(mon_conn
);
197 static void wpa_cli_msg_cb(char *msg
, size_t len
)
203 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
209 if (ctrl_conn
== NULL
) {
210 printf("Not connected to wpa_supplicant - command dropped.\n");
213 len
= sizeof(buf
) - 1;
214 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
217 printf("'%s' command timed out.\n", cmd
);
219 } else if (ret
< 0) {
220 printf("'%s' command failed.\n", cmd
);
231 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
233 return _wpa_ctrl_command(ctrl
, cmd
, 1);
237 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
239 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
240 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
244 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
246 return wpa_ctrl_command(ctrl
, "PING");
250 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
252 return wpa_ctrl_command(ctrl
, "MIB");
256 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
258 return wpa_ctrl_command(ctrl
, "PMKSA");
262 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
269 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
271 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
276 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
283 static void wpa_cli_show_variables(void)
285 printf("set variables:\n"
286 " EAPOL::heldPeriod (EAPOL state machine held period, "
288 " EAPOL::authPeriod (EAPOL state machine authentication "
289 "period, in seconds)\n"
290 " EAPOL::startPeriod (EAPOL state machine start period, in "
292 " EAPOL::maxStart (EAPOL state machine maximum start "
294 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
296 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
297 " threshold\n\tpercentage)\n"
298 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
299 "security\n\tassociation in seconds)\n");
303 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
309 wpa_cli_show_variables();
314 printf("Invalid SET command: needs two arguments (variable "
315 "name and value)\n");
319 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s", argv
[0], argv
[1]);
320 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
321 printf("Too long SET command.\n");
324 return wpa_ctrl_command(ctrl
, cmd
);
328 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
330 return wpa_ctrl_command(ctrl
, "LOGOFF");
334 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
336 return wpa_ctrl_command(ctrl
, "LOGON");
340 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
343 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
347 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
354 printf("Invalid PREAUTH command: needs one argument "
359 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
360 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
361 printf("Too long PREAUTH command.\n");
364 return wpa_ctrl_command(ctrl
, cmd
);
368 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
374 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
378 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
379 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
380 printf("Too long AP_SCAN command.\n");
383 return wpa_ctrl_command(ctrl
, cmd
);
387 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
394 printf("Invalid STKSTART command: needs one argument "
395 "(Peer STA MAC address)\n");
399 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
400 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
401 printf("Too long STKSTART command.\n");
404 return wpa_ctrl_command(ctrl
, cmd
);
408 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
414 printf("Invalid FT_DS command: needs one argument "
415 "(Target AP MAC address)\n");
419 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
420 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
421 printf("Too long FT_DS command.\n");
424 return wpa_ctrl_command(ctrl
, cmd
);
428 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
435 return wpa_ctrl_command(ctrl
, "WPS_PBC");
439 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
440 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
441 printf("Too long WPS_PBC command.\n");
444 return wpa_ctrl_command(ctrl
, cmd
);
448 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
454 printf("Invalid WPS_PIN command: need one or two arguments:\n"
455 "- BSSID: use 'any' to select any\n"
456 "- PIN: optional, used only with devices that have no "
462 /* Use dynamically generated PIN (returned as reply) */
463 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
464 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
465 printf("Too long WPS_PIN command.\n");
468 return wpa_ctrl_command(ctrl
, cmd
);
471 /* Use hardcoded PIN from a label */
472 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
473 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
474 printf("Too long WPS_PIN command.\n");
477 return wpa_ctrl_command(ctrl
, cmd
);
481 #ifdef CONFIG_WPS_OOB
482 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
487 if (argc
!= 3 && argc
!= 4) {
488 printf("Invalid WPS_OOB command: need three or four "
490 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
491 "- PATH: path of OOB device like '/mnt'\n"
492 "- METHOD: OOB method 'pin-e' or 'pin-r', "
494 "- DEV_NAME: (only for NFC) device name like "
500 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
501 argv
[0], argv
[1], argv
[2]);
503 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
504 argv
[0], argv
[1], argv
[2], argv
[3]);
505 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
506 printf("Too long WPS_OOB command.\n");
509 return wpa_ctrl_command(ctrl
, cmd
);
511 #endif /* CONFIG_WPS_OOB */
514 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
520 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
522 else if (argc
== 6) {
523 char ssid_hex
[2 * 32 + 1];
524 char key_hex
[2 * 64 + 1];
528 for (i
= 0; i
< 32; i
++) {
529 if (argv
[2][i
] == '\0')
531 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
535 for (i
= 0; i
< 64; i
++) {
536 if (argv
[5][i
] == '\0')
538 os_snprintf(&key_hex
[i
* 2], 3, "%02x", argv
[5][i
]);
541 res
= os_snprintf(cmd
, sizeof(cmd
),
542 "WPS_REG %s %s %s %s %s %s",
543 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
546 printf("Invalid WPS_REG command: need two arguments:\n"
547 "- BSSID: use 'any' to select any\n"
549 printf("Alternatively, six arguments can be used to "
550 "reconfigure the AP:\n"
551 "- BSSID: use 'any' to select any\n"
554 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
555 "- new encr (NONE, WEP, TKIP, CCMP)\n"
560 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
561 printf("Too long WPS_REG command.\n");
564 return wpa_ctrl_command(ctrl
, cmd
);
568 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
571 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
576 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
579 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
584 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
591 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
592 "- UUID: use 'any' to select any\n"
593 "- PIN: Enrollee PIN\n");
597 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
599 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
600 printf("Too long WPS_ER_PIN command.\n");
603 return wpa_ctrl_command(ctrl
, cmd
);
607 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
614 printf("Invalid WPS_ER_PBC command: need one argument:\n"
615 "- UUID: Specify the Enrollee\n");
619 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
621 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
622 printf("Too long WPS_ER_PBC command.\n");
625 return wpa_ctrl_command(ctrl
, cmd
);
629 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
636 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
637 "- UUID: specify which AP to use\n"
642 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
644 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
645 printf("Too long WPS_ER_LEARN command.\n");
648 return wpa_ctrl_command(ctrl
, cmd
);
652 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
658 printf("Invalid IBSS_RSN command: needs one argument "
659 "(Peer STA MAC address)\n");
663 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
664 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
665 printf("Too long IBSS_RSN command.\n");
668 return wpa_ctrl_command(ctrl
, cmd
);
672 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
678 printf("Invalid LEVEL command: needs one argument (debug "
682 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
683 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
684 printf("Too long LEVEL command.\n");
687 return wpa_ctrl_command(ctrl
, cmd
);
691 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
693 char cmd
[256], *pos
, *end
;
697 printf("Invalid IDENTITY command: needs two arguments "
698 "(network id and identity)\n");
702 end
= cmd
+ sizeof(cmd
);
704 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
706 if (ret
< 0 || ret
>= end
- pos
) {
707 printf("Too long IDENTITY command.\n");
711 for (i
= 2; i
< argc
; i
++) {
712 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
713 if (ret
< 0 || ret
>= end
- pos
) {
714 printf("Too long IDENTITY command.\n");
720 return wpa_ctrl_command(ctrl
, cmd
);
724 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
726 char cmd
[256], *pos
, *end
;
730 printf("Invalid PASSWORD command: needs two arguments "
731 "(network id and password)\n");
735 end
= cmd
+ sizeof(cmd
);
737 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
739 if (ret
< 0 || ret
>= end
- pos
) {
740 printf("Too long PASSWORD command.\n");
744 for (i
= 2; i
< argc
; i
++) {
745 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
746 if (ret
< 0 || ret
>= end
- pos
) {
747 printf("Too long PASSWORD command.\n");
753 return wpa_ctrl_command(ctrl
, cmd
);
757 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
760 char cmd
[256], *pos
, *end
;
764 printf("Invalid NEW_PASSWORD command: needs two arguments "
765 "(network id and password)\n");
769 end
= cmd
+ sizeof(cmd
);
771 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
773 if (ret
< 0 || ret
>= end
- pos
) {
774 printf("Too long NEW_PASSWORD command.\n");
778 for (i
= 2; i
< argc
; i
++) {
779 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
780 if (ret
< 0 || ret
>= end
- pos
) {
781 printf("Too long NEW_PASSWORD command.\n");
787 return wpa_ctrl_command(ctrl
, cmd
);
791 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
793 char cmd
[256], *pos
, *end
;
797 printf("Invalid PIN command: needs two arguments "
798 "(network id and pin)\n");
802 end
= cmd
+ sizeof(cmd
);
804 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
806 if (ret
< 0 || ret
>= end
- pos
) {
807 printf("Too long PIN 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 PIN command.\n");
819 return wpa_ctrl_command(ctrl
, cmd
);
823 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
825 char cmd
[256], *pos
, *end
;
829 printf("Invalid OTP command: needs two arguments (network "
830 "id and password)\n");
834 end
= cmd
+ sizeof(cmd
);
836 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
838 if (ret
< 0 || ret
>= end
- pos
) {
839 printf("Too long OTP command.\n");
843 for (i
= 2; i
< argc
; i
++) {
844 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
845 if (ret
< 0 || ret
>= end
- pos
) {
846 printf("Too long OTP command.\n");
852 return wpa_ctrl_command(ctrl
, cmd
);
856 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
859 char cmd
[256], *pos
, *end
;
863 printf("Invalid PASSPHRASE command: needs two arguments "
864 "(network id and passphrase)\n");
868 end
= cmd
+ sizeof(cmd
);
870 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
872 if (ret
< 0 || ret
>= end
- pos
) {
873 printf("Too long PASSPHRASE command.\n");
877 for (i
= 2; i
< argc
; i
++) {
878 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
879 if (ret
< 0 || ret
>= end
- pos
) {
880 printf("Too long PASSPHRASE command.\n");
886 return wpa_ctrl_command(ctrl
, cmd
);
890 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
892 char cmd
[256], *pos
, *end
;
896 printf("Invalid BSSID command: needs two arguments (network "
901 end
= cmd
+ sizeof(cmd
);
903 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
904 if (ret
< 0 || ret
>= end
- pos
) {
905 printf("Too long BSSID command.\n");
909 for (i
= 0; i
< argc
; i
++) {
910 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
911 if (ret
< 0 || ret
>= end
- pos
) {
912 printf("Too long BSSID command.\n");
918 return wpa_ctrl_command(ctrl
, cmd
);
922 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
925 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
929 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
936 printf("Invalid SELECT_NETWORK command: needs one argument "
941 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
942 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
944 cmd
[sizeof(cmd
) - 1] = '\0';
946 return wpa_ctrl_command(ctrl
, cmd
);
950 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
957 printf("Invalid ENABLE_NETWORK command: needs one argument "
962 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
963 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
965 cmd
[sizeof(cmd
) - 1] = '\0';
967 return wpa_ctrl_command(ctrl
, cmd
);
971 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
978 printf("Invalid DISABLE_NETWORK command: needs one argument "
983 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
984 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
986 cmd
[sizeof(cmd
) - 1] = '\0';
988 return wpa_ctrl_command(ctrl
, cmd
);
992 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
995 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
999 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1006 printf("Invalid REMOVE_NETWORK command: needs one argument "
1011 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1012 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1014 cmd
[sizeof(cmd
) - 1] = '\0';
1016 return wpa_ctrl_command(ctrl
, cmd
);
1020 static void wpa_cli_show_network_variables(void)
1022 printf("set_network variables:\n"
1023 " ssid (network name, SSID)\n"
1024 " psk (WPA passphrase or pre-shared key)\n"
1025 " key_mgmt (key management protocol)\n"
1026 " identity (EAP identity)\n"
1027 " password (EAP password)\n"
1030 "Note: Values are entered in the same format as the "
1031 "configuration file is using,\n"
1032 "i.e., strings values need to be inside double quotation "
1034 "For example: set_network 1 ssid \"network name\"\n"
1036 "Please see wpa_supplicant.conf documentation for full list "
1037 "of\navailable variables.\n");
1041 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1048 wpa_cli_show_network_variables();
1053 printf("Invalid SET_NETWORK command: needs three arguments\n"
1054 "(network id, variable name, and value)\n");
1058 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1059 argv
[0], argv
[1], argv
[2]);
1060 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1061 printf("Too long SET_NETWORK command.\n");
1064 return wpa_ctrl_command(ctrl
, cmd
);
1068 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1075 wpa_cli_show_network_variables();
1080 printf("Invalid GET_NETWORK command: needs two arguments\n"
1081 "(network id and variable name)\n");
1085 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1087 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1088 printf("Too long GET_NETWORK command.\n");
1091 return wpa_ctrl_command(ctrl
, cmd
);
1095 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1098 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1102 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1105 return wpa_ctrl_command(ctrl
, "RECONNECT");
1109 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1112 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1116 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1118 return wpa_ctrl_command(ctrl
, "SCAN");
1122 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1125 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1129 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1135 printf("Invalid BSS command: need one argument (index or "
1140 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1141 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1143 cmd
[sizeof(cmd
) - 1] = '\0';
1145 return wpa_ctrl_command(ctrl
, cmd
);
1149 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1155 if (argc
< 1 || argc
> 2) {
1156 printf("Invalid GET_CAPABILITY command: need either one or "
1161 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1162 printf("Invalid GET_CAPABILITY command: second argument, "
1163 "if any, must be 'strict'\n");
1167 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1168 (argc
== 2) ? " strict" : "");
1169 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1171 cmd
[sizeof(cmd
) - 1] = '\0';
1173 return wpa_ctrl_command(ctrl
, cmd
);
1177 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1179 printf("Available interfaces:\n");
1180 return wpa_ctrl_command(ctrl
, "INTERFACES");
1184 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1187 wpa_cli_list_interfaces(ctrl
);
1191 wpa_cli_close_connection();
1192 os_free(ctrl_ifname
);
1193 ctrl_ifname
= os_strdup(argv
[0]);
1195 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1196 printf("Connected to interface '%s.\n", ctrl_ifname
);
1198 printf("Could not connect to interface '%s' - re-trying\n",
1205 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1208 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1212 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1215 return wpa_ctrl_command(ctrl
, "TERMINATE");
1219 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1226 printf("Invalid INTERFACE_ADD command: needs at least one "
1227 "argument (interface name)\n"
1228 "All arguments: ifname confname driver ctrl_interface "
1229 "driver_param bridge_name\n");
1234 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1235 * <driver_param>TAB<bridge_name>
1237 res
= os_snprintf(cmd
, sizeof(cmd
),
1238 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1240 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1241 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1242 argc
> 5 ? argv
[5] : "");
1243 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1245 cmd
[sizeof(cmd
) - 1] = '\0';
1246 return wpa_ctrl_command(ctrl
, cmd
);
1250 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1257 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1258 "(interface name)\n");
1262 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1263 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1265 cmd
[sizeof(cmd
) - 1] = '\0';
1266 return wpa_ctrl_command(ctrl
, cmd
);
1270 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1273 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1278 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1282 printf("Invalid 'sta' command - exactly one argument, STA "
1283 "address, is required.\n");
1286 snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1287 return wpa_ctrl_command(ctrl
, buf
);
1291 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1292 char *addr
, size_t addr_len
)
1294 char buf
[4096], *pos
;
1298 if (ctrl_conn
== NULL
) {
1299 printf("Not connected to hostapd - command dropped.\n");
1302 len
= sizeof(buf
) - 1;
1303 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1306 printf("'%s' command timed out.\n", cmd
);
1308 } else if (ret
< 0) {
1309 printf("'%s' command failed.\n", cmd
);
1314 if (memcmp(buf
, "FAIL", 4) == 0)
1319 while (*pos
!= '\0' && *pos
!= '\n')
1322 os_strlcpy(addr
, buf
, addr_len
);
1327 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1329 char addr
[32], cmd
[64];
1331 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1334 snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1335 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1339 #endif /* CONFIG_AP */
1342 enum wpa_cli_cmd_flags
{
1343 cli_cmd_flag_none
= 0x00,
1344 cli_cmd_flag_sensitive
= 0x01
1347 struct wpa_cli_cmd
{
1349 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
1350 enum wpa_cli_cmd_flags flags
;
1354 static struct wpa_cli_cmd wpa_cli_commands
[] = {
1355 { "status", wpa_cli_cmd_status
,
1357 "[verbose] = get current WPA/EAPOL/EAP status" },
1358 { "ping", wpa_cli_cmd_ping
,
1360 "= pings wpa_supplicant" },
1361 { "mib", wpa_cli_cmd_mib
,
1363 "= get MIB variables (dot1x, dot11)" },
1364 { "help", wpa_cli_cmd_help
,
1366 "= show this usage help" },
1367 { "interface", wpa_cli_cmd_interface
,
1369 "[ifname] = show interfaces/select interface" },
1370 { "level", wpa_cli_cmd_level
,
1372 "<debug level> = change debug level" },
1373 { "license", wpa_cli_cmd_license
,
1375 "= show full wpa_cli license" },
1376 { "quit", wpa_cli_cmd_quit
,
1379 { "set", wpa_cli_cmd_set
,
1381 "= set variables (shows list of variables when run without "
1383 { "logon", wpa_cli_cmd_logon
,
1385 "= IEEE 802.1X EAPOL state machine logon" },
1386 { "logoff", wpa_cli_cmd_logoff
,
1388 "= IEEE 802.1X EAPOL state machine logoff" },
1389 { "pmksa", wpa_cli_cmd_pmksa
,
1391 "= show PMKSA cache" },
1392 { "reassociate", wpa_cli_cmd_reassociate
,
1394 "= force reassociation" },
1395 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
1397 "<BSSID> = force preauthentication" },
1398 { "identity", wpa_cli_cmd_identity
,
1400 "<network id> <identity> = configure identity for an SSID" },
1401 { "password", wpa_cli_cmd_password
,
1402 cli_cmd_flag_sensitive
,
1403 "<network id> <password> = configure password for an SSID" },
1404 { "new_password", wpa_cli_cmd_new_password
,
1405 cli_cmd_flag_sensitive
,
1406 "<network id> <password> = change password for an SSID" },
1407 { "pin", wpa_cli_cmd_pin
,
1408 cli_cmd_flag_sensitive
,
1409 "<network id> <pin> = configure pin for an SSID" },
1410 { "otp", wpa_cli_cmd_otp
,
1411 cli_cmd_flag_sensitive
,
1412 "<network id> <password> = configure one-time-password for an SSID"
1414 { "passphrase", wpa_cli_cmd_passphrase
,
1415 cli_cmd_flag_sensitive
,
1416 "<network id> <passphrase> = configure private key passphrase\n"
1418 { "bssid", wpa_cli_cmd_bssid
,
1420 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1421 { "list_networks", wpa_cli_cmd_list_networks
,
1423 "= list configured networks" },
1424 { "select_network", wpa_cli_cmd_select_network
,
1426 "<network id> = select a network (disable others)" },
1427 { "enable_network", wpa_cli_cmd_enable_network
,
1429 "<network id> = enable a network" },
1430 { "disable_network", wpa_cli_cmd_disable_network
,
1432 "<network id> = disable a network" },
1433 { "add_network", wpa_cli_cmd_add_network
,
1435 "= add a network" },
1436 { "remove_network", wpa_cli_cmd_remove_network
,
1438 "<network id> = remove a network" },
1439 { "set_network", wpa_cli_cmd_set_network
,
1440 cli_cmd_flag_sensitive
,
1441 "<network id> <variable> <value> = set network variables (shows\n"
1442 " list of variables when run without arguments)" },
1443 { "get_network", wpa_cli_cmd_get_network
,
1445 "<network id> <variable> = get network variables" },
1446 { "save_config", wpa_cli_cmd_save_config
,
1448 "= save the current configuration" },
1449 { "disconnect", wpa_cli_cmd_disconnect
,
1451 "= disconnect and wait for reassociate/reconnect command before\n"
1453 { "reconnect", wpa_cli_cmd_reconnect
,
1455 "= like reassociate, but only takes effect if already disconnected"
1457 { "scan", wpa_cli_cmd_scan
,
1459 "= request new BSS scan" },
1460 { "scan_results", wpa_cli_cmd_scan_results
,
1462 "= get latest scan results" },
1463 { "bss", wpa_cli_cmd_bss
,
1465 "<<idx> | <bssid>> = get detailed scan result info" },
1466 { "get_capability", wpa_cli_cmd_get_capability
,
1468 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1469 { "reconfigure", wpa_cli_cmd_reconfigure
,
1471 "= force wpa_supplicant to re-read its configuration file" },
1472 { "terminate", wpa_cli_cmd_terminate
,
1474 "= terminate wpa_supplicant" },
1475 { "interface_add", wpa_cli_cmd_interface_add
,
1477 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1478 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1480 { "interface_remove", wpa_cli_cmd_interface_remove
,
1482 "<ifname> = removes the interface" },
1483 { "interface_list", wpa_cli_cmd_interface_list
,
1485 "= list available interfaces" },
1486 { "ap_scan", wpa_cli_cmd_ap_scan
,
1488 "<value> = set ap_scan parameter" },
1489 { "stkstart", wpa_cli_cmd_stkstart
,
1491 "<addr> = request STK negotiation with <addr>" },
1492 { "ft_ds", wpa_cli_cmd_ft_ds
,
1494 "<addr> = request over-the-DS FT with <addr>" },
1495 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
1497 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1498 { "wps_pin", wpa_cli_cmd_wps_pin
,
1499 cli_cmd_flag_sensitive
,
1500 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1502 #ifdef CONFIG_WPS_OOB
1503 { "wps_oob", wpa_cli_cmd_wps_oob
,
1504 cli_cmd_flag_sensitive
,
1505 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1506 #endif /* CONFIG_WPS_OOB */
1507 { "wps_reg", wpa_cli_cmd_wps_reg
,
1508 cli_cmd_flag_sensitive
,
1509 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1510 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
1512 "= start Wi-Fi Protected Setup External Registrar" },
1513 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
1515 "= stop Wi-Fi Protected Setup External Registrar" },
1516 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
1517 cli_cmd_flag_sensitive
,
1518 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1519 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
1521 "<UUID> = accept an Enrollee PBC using External Registrar" },
1522 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
1523 cli_cmd_flag_sensitive
,
1524 "<UUID> <PIN> = learn AP configuration" },
1525 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
1527 "<addr> = request RSN authentication with <addr> in IBSS" },
1529 { "sta", wpa_cli_cmd_sta
,
1531 "<addr> = get information about an associated station (AP)" },
1532 { "all_sta", wpa_cli_cmd_all_sta
,
1534 "= get information about all associated stations (AP)" },
1535 #endif /* CONFIG_AP */
1536 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
1541 * Prints command usage, lines are padded with the specified string.
1543 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
1548 printf("%s%s ", pad
, cmd
->cmd
);
1549 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
1558 static void print_help(void)
1561 printf("commands:\n");
1562 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
1563 print_cmd_help(&wpa_cli_commands
[n
], " ");
1567 #ifdef CONFIG_READLINE
1568 static int cmd_has_sensitive_data(const char *cmd
)
1570 const char *c
, *delim
;
1574 delim
= os_strchr(cmd
, ' ');
1578 len
= os_strlen(cmd
);
1580 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
1581 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
1582 return (wpa_cli_commands
[n
].flags
&
1583 cli_cmd_flag_sensitive
);
1587 #endif /* CONFIG_READLINE */
1590 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1592 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
1597 cmd
= wpa_cli_commands
;
1599 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
1602 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
1603 /* we have an exact match */
1613 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
1614 cmd
= wpa_cli_commands
;
1616 if (os_strncasecmp(cmd
->cmd
, argv
[0],
1617 os_strlen(argv
[0])) == 0) {
1618 printf(" %s", cmd
->cmd
);
1624 } else if (count
== 0) {
1625 printf("Unknown command '%s'\n", argv
[0]);
1628 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
1635 static int str_match(const char *a
, const char *b
)
1637 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
1641 static int wpa_cli_exec(const char *program
, const char *arg1
,
1649 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
1650 cmd
= os_malloc(len
);
1653 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
1654 if (res
< 0 || (size_t) res
>= len
) {
1658 cmd
[len
- 1] = '\0';
1660 if (system(cmd
) < 0)
1662 #endif /* _WIN32_WCE */
1669 static void wpa_cli_action_process(const char *msg
)
1672 char *copy
= NULL
, *id
, *pos2
;
1677 pos
= os_strchr(pos
, '>');
1684 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
1686 os_unsetenv("WPA_ID");
1687 os_unsetenv("WPA_ID_STR");
1688 os_unsetenv("WPA_CTRL_DIR");
1690 pos
= os_strstr(pos
, "[id=");
1692 copy
= os_strdup(pos
+ 4);
1696 while (*pos2
&& *pos2
!= ' ')
1700 os_setenv("WPA_ID", id
, 1);
1701 while (*pos2
&& *pos2
!= '=')
1706 while (*pos2
&& *pos2
!= ']')
1709 os_setenv("WPA_ID_STR", id
, 1);
1713 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
1715 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
1716 wpa_cli_connected
= 1;
1717 wpa_cli_last_id
= new_id
;
1718 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
1720 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
1721 if (wpa_cli_connected
) {
1722 wpa_cli_connected
= 0;
1723 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
1725 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
1726 printf("wpa_supplicant is terminating - stop monitoring\n");
1732 #ifndef CONFIG_ANSI_C_EXTRA
1733 static void wpa_cli_action_cb(char *msg
, size_t len
)
1735 wpa_cli_action_process(msg
);
1737 #endif /* CONFIG_ANSI_C_EXTRA */
1740 static void wpa_cli_reconnect(void)
1742 wpa_cli_close_connection();
1743 wpa_cli_open_connection(ctrl_ifname
, 1);
1747 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int in_read
,
1751 if (ctrl_conn
== NULL
) {
1752 wpa_cli_reconnect();
1755 while (wpa_ctrl_pending(ctrl
) > 0) {
1757 size_t len
= sizeof(buf
) - 1;
1758 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
1761 wpa_cli_action_process(buf
);
1763 if (in_read
&& first
)
1766 printf("%s\n", buf
);
1769 printf("Could not read pending message.\n");
1774 if (wpa_ctrl_pending(ctrl
) < 0) {
1775 printf("Connection to wpa_supplicant lost - trying to "
1777 wpa_cli_reconnect();
1782 #ifdef CONFIG_READLINE
1783 static char * wpa_cli_cmd_gen(const char *text
, int state
)
1790 len
= os_strlen(text
);
1793 while ((cmd
= wpa_cli_commands
[i
].cmd
)) {
1795 if (os_strncasecmp(cmd
, text
, len
) == 0)
1803 static char * wpa_cli_dummy_gen(const char *text
, int state
)
1809 static char ** wpa_cli_completion(const char *text
, int start
, int end
)
1811 return rl_completion_matches(text
, start
== 0 ?
1812 wpa_cli_cmd_gen
: wpa_cli_dummy_gen
);
1814 #endif /* CONFIG_READLINE */
1817 static void wpa_cli_interactive(void)
1820 char cmdbuf
[256], *cmd
, *argv
[max_args
], *pos
;
1822 #ifdef CONFIG_READLINE
1823 char *home
, *hfile
= NULL
;
1824 #endif /* CONFIG_READLINE */
1826 printf("\nInteractive mode\n\n");
1828 #ifdef CONFIG_READLINE
1829 rl_attempted_completion_function
= wpa_cli_completion
;
1830 home
= getenv("HOME");
1832 const char *fname
= ".wpa_cli_history";
1833 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
1834 hfile
= os_malloc(hfile_len
);
1837 res
= os_snprintf(hfile
, hfile_len
, "%s/%s", home
,
1839 if (res
>= 0 && res
< hfile_len
) {
1840 hfile
[hfile_len
- 1] = '\0';
1841 read_history(hfile
);
1842 stifle_history(100);
1846 #endif /* CONFIG_READLINE */
1849 wpa_cli_recv_pending(mon_conn
, 0, 0);
1850 #ifndef CONFIG_NATIVE_WINDOWS
1851 alarm(ping_interval
);
1852 #endif /* CONFIG_NATIVE_WINDOWS */
1853 #ifdef CONFIG_READLINE
1854 cmd
= readline("> ");
1857 while (next_history())
1859 h
= previous_history();
1860 if (h
== NULL
|| os_strcmp(cmd
, h
->line
) != 0)
1864 #else /* CONFIG_READLINE */
1866 cmd
= fgets(cmdbuf
, sizeof(cmdbuf
), stdin
);
1867 #endif /* CONFIG_READLINE */
1868 #ifndef CONFIG_NATIVE_WINDOWS
1870 #endif /* CONFIG_NATIVE_WINDOWS */
1873 wpa_cli_recv_pending(mon_conn
, 0, 0);
1875 while (*pos
!= '\0') {
1891 if (argc
== max_args
)
1894 char *pos2
= os_strrchr(pos
, '"');
1898 while (*pos
!= '\0' && *pos
!= ' ')
1904 wpa_request(ctrl_conn
, argc
, argv
);
1908 } while (!wpa_cli_quit
);
1910 #ifdef CONFIG_READLINE
1912 /* Save command history, excluding lines that may contain
1916 while ((h
= current_history())) {
1918 while (*p
== ' ' || *p
== '\t')
1920 if (cmd_has_sensitive_data(p
)) {
1921 h
= remove_history(where_history());
1931 write_history(hfile
);
1934 #endif /* CONFIG_READLINE */
1938 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
1940 #ifdef CONFIG_ANSI_C_EXTRA
1941 /* TODO: ANSI C version(?) */
1942 printf("Action processing not supported in ANSI C build.\n");
1943 #else /* CONFIG_ANSI_C_EXTRA */
1947 char buf
[256]; /* note: large enough to fit in unsolicited messages */
1950 fd
= wpa_ctrl_get_fd(ctrl
);
1952 while (!wpa_cli_quit
) {
1955 tv
.tv_sec
= ping_interval
;
1957 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
1958 if (res
< 0 && errno
!= EINTR
) {
1963 if (FD_ISSET(fd
, &rfds
))
1964 wpa_cli_recv_pending(ctrl
, 0, 1);
1966 /* verify that connection is still working */
1967 len
= sizeof(buf
) - 1;
1968 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
1969 wpa_cli_action_cb
) < 0 ||
1970 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
1971 printf("wpa_supplicant did not reply to PING "
1972 "command - exiting\n");
1977 #endif /* CONFIG_ANSI_C_EXTRA */
1981 static void wpa_cli_cleanup(void)
1983 wpa_cli_close_connection();
1985 os_daemonize_terminate(pid_file
);
1987 os_program_deinit();
1990 static void wpa_cli_terminate(int sig
)
1997 #ifndef CONFIG_NATIVE_WINDOWS
1998 static void wpa_cli_alarm(int sig
)
2000 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
2001 printf("Connection to wpa_supplicant lost - trying to "
2003 wpa_cli_close_connection();
2006 wpa_cli_reconnect();
2008 wpa_cli_recv_pending(mon_conn
, 1, 0);
2009 alarm(ping_interval
);
2011 #endif /* CONFIG_NATIVE_WINDOWS */
2014 static char * wpa_cli_get_default_ifname(void)
2016 char *ifname
= NULL
;
2018 #ifdef CONFIG_CTRL_IFACE_UNIX
2019 struct dirent
*dent
;
2020 DIR *dir
= opendir(ctrl_iface_dir
);
2023 while ((dent
= readdir(dir
))) {
2024 #ifdef _DIRENT_HAVE_D_TYPE
2026 * Skip the file if it is not a socket. Also accept
2027 * DT_UNKNOWN (0) in case the C library or underlying
2028 * file system does not support d_type.
2030 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
2032 #endif /* _DIRENT_HAVE_D_TYPE */
2033 if (os_strcmp(dent
->d_name
, ".") == 0 ||
2034 os_strcmp(dent
->d_name
, "..") == 0)
2036 printf("Selected interface '%s'\n", dent
->d_name
);
2037 ifname
= os_strdup(dent
->d_name
);
2041 #endif /* CONFIG_CTRL_IFACE_UNIX */
2043 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2044 char buf
[2048], *pos
;
2046 struct wpa_ctrl
*ctrl
;
2049 ctrl
= wpa_ctrl_open(NULL
);
2053 len
= sizeof(buf
) - 1;
2054 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
2057 pos
= os_strchr(buf
, '\n');
2060 ifname
= os_strdup(buf
);
2062 wpa_ctrl_close(ctrl
);
2063 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2069 int main(int argc
, char *argv
[])
2071 int warning_displayed
= 0;
2075 const char *global
= NULL
;
2077 if (os_program_init())
2081 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
2086 action_file
= optarg
;
2095 ping_interval
= atoi(optarg
);
2101 printf("%s\n", wpa_cli_version
);
2104 os_free(ctrl_ifname
);
2105 ctrl_ifname
= os_strdup(optarg
);
2108 ctrl_iface_dir
= optarg
;
2119 interactive
= (argc
== optind
) && (action_file
== NULL
);
2122 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
2125 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2126 ctrl_conn
= wpa_ctrl_open(NULL
);
2127 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2128 ctrl_conn
= wpa_ctrl_open(global
);
2129 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2130 if (ctrl_conn
== NULL
) {
2131 perror("Failed to connect to wpa_supplicant - "
2138 signal(SIGINT
, wpa_cli_terminate
);
2139 signal(SIGTERM
, wpa_cli_terminate
);
2140 #endif /* _WIN32_WCE */
2141 #ifndef CONFIG_NATIVE_WINDOWS
2142 signal(SIGALRM
, wpa_cli_alarm
);
2143 #endif /* CONFIG_NATIVE_WINDOWS */
2145 if (ctrl_ifname
== NULL
)
2146 ctrl_ifname
= wpa_cli_get_default_ifname();
2150 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
2151 if (warning_displayed
)
2152 printf("Connection established.\n");
2156 if (!warning_displayed
) {
2157 printf("Could not connect to wpa_supplicant - "
2159 warning_displayed
= 1;
2166 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
2167 perror("Failed to connect to wpa_supplicant - "
2173 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
2174 wpa_cli_attached
= 1;
2176 printf("Warning: Failed to attach to "
2177 "wpa_supplicant.\n");
2183 if (daemonize
&& os_daemonize(pid_file
))
2187 wpa_cli_interactive();
2188 else if (action_file
)
2189 wpa_cli_action(ctrl_conn
);
2191 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
2193 os_free(ctrl_ifname
);
2199 #else /* CONFIG_CTRL_IFACE */
2200 int main(int argc
, char *argv
[])
2202 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2205 #endif /* CONFIG_CTRL_IFACE */