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 */
23 #include "common/wpa_ctrl.h"
24 #include "utils/common.h"
25 #include "utils/eloop.h"
26 #include "utils/edit.h"
27 #include "common/version.h"
30 static const char *wpa_cli_version
=
31 "wpa_cli v" VERSION_STR
"\n"
32 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
35 static const char *wpa_cli_license
=
36 "This program is free software. You can distribute it and/or modify it\n"
37 "under the terms of the GNU General Public License version 2.\n"
39 "Alternatively, this software may be distributed under the terms of the\n"
40 "BSD license. See README and COPYING for more details.\n";
42 static const char *wpa_cli_full_license
=
43 "This program is free software; you can redistribute it and/or modify\n"
44 "it under the terms of the GNU General Public License version 2 as\n"
45 "published by the Free Software Foundation.\n"
47 "This program is distributed in the hope that it will be useful,\n"
48 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
49 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
50 "GNU General Public License for more details.\n"
52 "You should have received a copy of the GNU General Public License\n"
53 "along with this program; if not, write to the Free Software\n"
54 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
56 "Alternatively, this software may be distributed under the terms of the\n"
59 "Redistribution and use in source and binary forms, with or without\n"
60 "modification, are permitted provided that the following conditions are\n"
63 "1. Redistributions of source code must retain the above copyright\n"
64 " notice, this list of conditions and the following disclaimer.\n"
66 "2. Redistributions in binary form must reproduce the above copyright\n"
67 " notice, this list of conditions and the following disclaimer in the\n"
68 " documentation and/or other materials provided with the distribution.\n"
70 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
71 " names of its contributors may be used to endorse or promote products\n"
72 " derived from this software without specific prior written permission.\n"
74 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
75 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
76 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
77 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
78 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
79 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
80 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
81 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
82 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
83 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
84 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
87 static struct wpa_ctrl
*ctrl_conn
;
88 static struct wpa_ctrl
*mon_conn
;
89 static int wpa_cli_quit
= 0;
90 static int wpa_cli_attached
= 0;
91 static int wpa_cli_connected
= 0;
92 static int wpa_cli_last_id
= 0;
93 static const char *ctrl_iface_dir
= "/var/run/wpa_supplicant";
94 static char *ctrl_ifname
= NULL
;
95 static const char *pid_file
= NULL
;
96 static const char *action_file
= NULL
;
97 static int ping_interval
= 5;
98 static int interactive
= 0;
101 static void print_help(void);
102 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
);
105 static void usage(void)
107 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
108 "[-a<action file>] \\\n"
109 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
111 " -h = help (show this usage text)\n"
112 " -v = shown version information\n"
113 " -a = run in daemon mode executing the action file based on "
116 " -B = run a daemon in the background\n"
117 " default path: /var/run/wpa_supplicant\n"
118 " default interface: first interface found in socket path\n");
123 static int str_starts(const char *src
, const char *match
)
125 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
129 static int wpa_cli_show_event(const char *event
)
133 start
= os_strchr(event
, '>');
139 * Skip BSS added/removed events since they can be relatively frequent
140 * and are likely of not much use for an interactive user.
142 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
143 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
150 static int wpa_cli_open_connection(const char *ifname
, int attach
)
152 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
153 ctrl_conn
= wpa_ctrl_open(ifname
);
154 if (ctrl_conn
== NULL
)
157 if (attach
&& interactive
)
158 mon_conn
= wpa_ctrl_open(ifname
);
161 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
168 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
169 cfile
= os_malloc(flen
);
172 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
, ifname
);
173 if (res
< 0 || res
>= flen
) {
178 ctrl_conn
= wpa_ctrl_open(cfile
);
179 if (ctrl_conn
== NULL
) {
184 if (attach
&& interactive
)
185 mon_conn
= wpa_ctrl_open(cfile
);
189 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
192 if (wpa_ctrl_attach(mon_conn
) == 0) {
193 wpa_cli_attached
= 1;
195 eloop_register_read_sock(
196 wpa_ctrl_get_fd(mon_conn
),
197 wpa_cli_mon_receive
, NULL
, NULL
);
199 printf("Warning: Failed to attach to "
200 "wpa_supplicant.\n");
209 static void wpa_cli_close_connection(void)
211 if (ctrl_conn
== NULL
)
214 if (wpa_cli_attached
) {
215 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
216 wpa_cli_attached
= 0;
218 wpa_ctrl_close(ctrl_conn
);
221 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
222 wpa_ctrl_close(mon_conn
);
228 static void wpa_cli_msg_cb(char *msg
, size_t len
)
234 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
240 if (ctrl_conn
== NULL
) {
241 printf("Not connected to wpa_supplicant - command dropped.\n");
244 len
= sizeof(buf
) - 1;
245 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
248 printf("'%s' command timed out.\n", cmd
);
250 } else if (ret
< 0) {
251 printf("'%s' command failed.\n", cmd
);
257 if (interactive
&& len
> 0 && buf
[len
- 1] != '\n')
264 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
266 return _wpa_ctrl_command(ctrl
, cmd
, 1);
270 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
272 int verbose
= argc
> 0 && os_strcmp(argv
[0], "verbose") == 0;
273 return wpa_ctrl_command(ctrl
, verbose
? "STATUS-VERBOSE" : "STATUS");
277 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
279 return wpa_ctrl_command(ctrl
, "PING");
283 static int wpa_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
285 return wpa_ctrl_command(ctrl
, "RELOG");
289 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
295 ret
= os_snprintf(cmd
, sizeof(cmd
), "NOTE %s", argv
[0]);
296 if (ret
< 0 || (size_t) ret
>= sizeof(cmd
))
298 return wpa_ctrl_command(ctrl
, cmd
);
302 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
304 return wpa_ctrl_command(ctrl
, "MIB");
308 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
310 return wpa_ctrl_command(ctrl
, "PMKSA");
314 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
321 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
323 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
328 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
337 static void wpa_cli_show_variables(void)
339 printf("set variables:\n"
340 " EAPOL::heldPeriod (EAPOL state machine held period, "
342 " EAPOL::authPeriod (EAPOL state machine authentication "
343 "period, in seconds)\n"
344 " EAPOL::startPeriod (EAPOL state machine start period, in "
346 " EAPOL::maxStart (EAPOL state machine maximum start "
348 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
350 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
351 " threshold\n\tpercentage)\n"
352 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
353 "security\n\tassociation in seconds)\n");
357 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
363 wpa_cli_show_variables();
368 printf("Invalid SET command: needs two arguments (variable "
369 "name and value)\n");
373 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s", argv
[0], argv
[1]);
374 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
375 printf("Too long SET command.\n");
378 return wpa_ctrl_command(ctrl
, cmd
);
382 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
388 printf("Invalid GET command: need one argument (variable "
393 res
= os_snprintf(cmd
, sizeof(cmd
), "GET %s", argv
[0]);
394 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
395 printf("Too long GET command.\n");
398 return wpa_ctrl_command(ctrl
, cmd
);
402 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
404 return wpa_ctrl_command(ctrl
, "LOGOFF");
408 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
410 return wpa_ctrl_command(ctrl
, "LOGON");
414 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
417 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
421 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
428 printf("Invalid PREAUTH command: needs one argument "
433 res
= os_snprintf(cmd
, sizeof(cmd
), "PREAUTH %s", argv
[0]);
434 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
435 printf("Too long PREAUTH command.\n");
438 return wpa_ctrl_command(ctrl
, cmd
);
442 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
448 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
452 res
= os_snprintf(cmd
, sizeof(cmd
), "AP_SCAN %s", argv
[0]);
453 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
454 printf("Too long AP_SCAN command.\n");
457 return wpa_ctrl_command(ctrl
, cmd
);
461 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
468 printf("Invalid STKSTART command: needs one argument "
469 "(Peer STA MAC address)\n");
473 res
= os_snprintf(cmd
, sizeof(cmd
), "STKSTART %s", argv
[0]);
474 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
475 printf("Too long STKSTART command.\n");
478 return wpa_ctrl_command(ctrl
, cmd
);
482 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
488 printf("Invalid FT_DS command: needs one argument "
489 "(Target AP MAC address)\n");
493 res
= os_snprintf(cmd
, sizeof(cmd
), "FT_DS %s", argv
[0]);
494 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
495 printf("Too long FT_DS command.\n");
498 return wpa_ctrl_command(ctrl
, cmd
);
502 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
509 return wpa_ctrl_command(ctrl
, "WPS_PBC");
513 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PBC %s", argv
[0]);
514 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
515 printf("Too long WPS_PBC command.\n");
518 return wpa_ctrl_command(ctrl
, cmd
);
522 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
528 printf("Invalid WPS_PIN command: need one or two arguments:\n"
529 "- BSSID: use 'any' to select any\n"
530 "- PIN: optional, used only with devices that have no "
536 /* Use dynamically generated PIN (returned as reply) */
537 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s", argv
[0]);
538 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
539 printf("Too long WPS_PIN command.\n");
542 return wpa_ctrl_command(ctrl
, cmd
);
545 /* Use hardcoded PIN from a label */
546 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_PIN %s %s", argv
[0], argv
[1]);
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
);
555 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
561 if (argc
!= 1 && argc
!= 2) {
562 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
563 "- PIN to be verified\n");
568 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
571 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
573 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
574 printf("Too long WPS_CHECK_PIN command.\n");
577 return wpa_ctrl_command(ctrl
, cmd
);
581 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
584 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
588 #ifdef CONFIG_WPS_OOB
589 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
594 if (argc
!= 3 && argc
!= 4) {
595 printf("Invalid WPS_OOB command: need three or four "
597 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
598 "- PATH: path of OOB device like '/mnt'\n"
599 "- METHOD: OOB method 'pin-e' or 'pin-r', "
601 "- DEV_NAME: (only for NFC) device name like "
607 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
608 argv
[0], argv
[1], argv
[2]);
610 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s %s",
611 argv
[0], argv
[1], argv
[2], argv
[3]);
612 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
613 printf("Too long WPS_OOB command.\n");
616 return wpa_ctrl_command(ctrl
, cmd
);
618 #endif /* CONFIG_WPS_OOB */
621 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
627 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
629 else if (argc
== 5 || argc
== 6) {
630 char ssid_hex
[2 * 32 + 1];
631 char key_hex
[2 * 64 + 1];
635 for (i
= 0; i
< 32; i
++) {
636 if (argv
[2][i
] == '\0')
638 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
643 for (i
= 0; i
< 64; i
++) {
644 if (argv
[5][i
] == '\0')
646 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
651 res
= os_snprintf(cmd
, sizeof(cmd
),
652 "WPS_REG %s %s %s %s %s %s",
653 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
656 printf("Invalid WPS_REG command: need two arguments:\n"
657 "- BSSID of the target AP\n"
659 printf("Alternatively, six arguments can be used to "
660 "reconfigure the AP:\n"
661 "- BSSID of the target AP\n"
664 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
665 "- new encr (NONE, WEP, TKIP, CCMP)\n"
670 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
671 printf("Too long WPS_REG command.\n");
674 return wpa_ctrl_command(ctrl
, cmd
);
678 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
685 printf("Invalid WPS_AP_PIN command: needs at least one "
691 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s %s",
692 argv
[0], argv
[1], argv
[2]);
694 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s",
697 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s",
699 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
700 printf("Too long WPS_AP_PIN command.\n");
703 return wpa_ctrl_command(ctrl
, cmd
);
707 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
712 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
713 return wpa_ctrl_command(ctrl
, cmd
);
715 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
719 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
722 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
727 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
734 printf("Invalid WPS_ER_PIN command: need at least two "
736 "- UUID: use 'any' to select any\n"
737 "- PIN: Enrollee PIN\n"
738 "optional: - Enrollee MAC address\n");
743 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
744 argv
[0], argv
[1], argv
[2]);
746 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
748 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
749 printf("Too long WPS_ER_PIN command.\n");
752 return wpa_ctrl_command(ctrl
, cmd
);
756 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
763 printf("Invalid WPS_ER_PBC command: need one argument:\n"
764 "- UUID: Specify the Enrollee\n");
768 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
770 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
771 printf("Too long WPS_ER_PBC command.\n");
774 return wpa_ctrl_command(ctrl
, cmd
);
778 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
785 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
786 "- UUID: specify which AP to use\n"
791 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
793 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
794 printf("Too long WPS_ER_LEARN command.\n");
797 return wpa_ctrl_command(ctrl
, cmd
);
801 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
808 printf("Invalid WPS_ER_SET_CONFIG command: need two "
810 "- UUID: specify which AP to use\n"
811 "- Network configuration id\n");
815 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_SET_CONFIG %s %s",
817 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
818 printf("Too long WPS_ER_SET_CONFIG command.\n");
821 return wpa_ctrl_command(ctrl
, cmd
);
825 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
831 if (argc
== 5 || argc
== 6) {
832 char ssid_hex
[2 * 32 + 1];
833 char key_hex
[2 * 64 + 1];
837 for (i
= 0; i
< 32; i
++) {
838 if (argv
[2][i
] == '\0')
840 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
845 for (i
= 0; i
< 64; i
++) {
846 if (argv
[5][i
] == '\0')
848 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
853 res
= os_snprintf(cmd
, sizeof(cmd
),
854 "WPS_ER_CONFIG %s %s %s %s %s %s",
855 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
858 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
862 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
863 "- new encr (NONE, WEP, TKIP, CCMP)\n"
868 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
869 printf("Too long WPS_ER_CONFIG command.\n");
872 return wpa_ctrl_command(ctrl
, cmd
);
876 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
882 printf("Invalid IBSS_RSN command: needs one argument "
883 "(Peer STA MAC address)\n");
887 res
= os_snprintf(cmd
, sizeof(cmd
), "IBSS_RSN %s", argv
[0]);
888 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
889 printf("Too long IBSS_RSN command.\n");
892 return wpa_ctrl_command(ctrl
, cmd
);
896 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
902 printf("Invalid LEVEL command: needs one argument (debug "
906 res
= os_snprintf(cmd
, sizeof(cmd
), "LEVEL %s", argv
[0]);
907 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
908 printf("Too long LEVEL command.\n");
911 return wpa_ctrl_command(ctrl
, cmd
);
915 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
917 char cmd
[256], *pos
, *end
;
921 printf("Invalid IDENTITY command: needs two arguments "
922 "(network id and identity)\n");
926 end
= cmd
+ sizeof(cmd
);
928 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
930 if (ret
< 0 || ret
>= end
- pos
) {
931 printf("Too long IDENTITY command.\n");
935 for (i
= 2; i
< argc
; i
++) {
936 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
937 if (ret
< 0 || ret
>= end
- pos
) {
938 printf("Too long IDENTITY command.\n");
944 return wpa_ctrl_command(ctrl
, cmd
);
948 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
950 char cmd
[256], *pos
, *end
;
954 printf("Invalid PASSWORD command: needs two arguments "
955 "(network id and password)\n");
959 end
= cmd
+ sizeof(cmd
);
961 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
963 if (ret
< 0 || ret
>= end
- pos
) {
964 printf("Too long PASSWORD command.\n");
968 for (i
= 2; i
< argc
; i
++) {
969 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
970 if (ret
< 0 || ret
>= end
- pos
) {
971 printf("Too long PASSWORD command.\n");
977 return wpa_ctrl_command(ctrl
, cmd
);
981 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
984 char cmd
[256], *pos
, *end
;
988 printf("Invalid NEW_PASSWORD command: needs two arguments "
989 "(network id and password)\n");
993 end
= cmd
+ sizeof(cmd
);
995 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
997 if (ret
< 0 || ret
>= end
- pos
) {
998 printf("Too long NEW_PASSWORD command.\n");
1002 for (i
= 2; i
< argc
; i
++) {
1003 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1004 if (ret
< 0 || ret
>= end
- pos
) {
1005 printf("Too long NEW_PASSWORD command.\n");
1011 return wpa_ctrl_command(ctrl
, cmd
);
1015 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1017 char cmd
[256], *pos
, *end
;
1021 printf("Invalid PIN command: needs two arguments "
1022 "(network id and pin)\n");
1026 end
= cmd
+ sizeof(cmd
);
1028 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1030 if (ret
< 0 || ret
>= end
- pos
) {
1031 printf("Too long PIN command.\n");
1035 for (i
= 2; i
< argc
; i
++) {
1036 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1037 if (ret
< 0 || ret
>= end
- pos
) {
1038 printf("Too long PIN command.\n");
1043 return wpa_ctrl_command(ctrl
, cmd
);
1047 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1049 char cmd
[256], *pos
, *end
;
1053 printf("Invalid OTP command: needs two arguments (network "
1054 "id and password)\n");
1058 end
= cmd
+ sizeof(cmd
);
1060 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1062 if (ret
< 0 || ret
>= end
- pos
) {
1063 printf("Too long OTP command.\n");
1067 for (i
= 2; i
< argc
; i
++) {
1068 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1069 if (ret
< 0 || ret
>= end
- pos
) {
1070 printf("Too long OTP command.\n");
1076 return wpa_ctrl_command(ctrl
, cmd
);
1080 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1083 char cmd
[256], *pos
, *end
;
1087 printf("Invalid PASSPHRASE command: needs two arguments "
1088 "(network id and passphrase)\n");
1092 end
= cmd
+ sizeof(cmd
);
1094 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1096 if (ret
< 0 || ret
>= end
- pos
) {
1097 printf("Too long PASSPHRASE command.\n");
1101 for (i
= 2; i
< argc
; i
++) {
1102 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1103 if (ret
< 0 || ret
>= end
- pos
) {
1104 printf("Too long PASSPHRASE command.\n");
1110 return wpa_ctrl_command(ctrl
, cmd
);
1114 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1116 char cmd
[256], *pos
, *end
;
1120 printf("Invalid BSSID command: needs two arguments (network "
1125 end
= cmd
+ sizeof(cmd
);
1127 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1128 if (ret
< 0 || ret
>= end
- pos
) {
1129 printf("Too long BSSID command.\n");
1133 for (i
= 0; i
< argc
; i
++) {
1134 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1135 if (ret
< 0 || ret
>= end
- pos
) {
1136 printf("Too long BSSID command.\n");
1142 return wpa_ctrl_command(ctrl
, cmd
);
1146 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1149 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1153 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1160 printf("Invalid SELECT_NETWORK command: needs one argument "
1165 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1166 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1168 cmd
[sizeof(cmd
) - 1] = '\0';
1170 return wpa_ctrl_command(ctrl
, cmd
);
1174 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1181 printf("Invalid ENABLE_NETWORK command: needs one argument "
1186 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1187 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1189 cmd
[sizeof(cmd
) - 1] = '\0';
1191 return wpa_ctrl_command(ctrl
, cmd
);
1195 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1202 printf("Invalid DISABLE_NETWORK command: needs one argument "
1207 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1208 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1210 cmd
[sizeof(cmd
) - 1] = '\0';
1212 return wpa_ctrl_command(ctrl
, cmd
);
1216 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1219 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1223 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1230 printf("Invalid REMOVE_NETWORK command: needs one argument "
1235 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1236 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1238 cmd
[sizeof(cmd
) - 1] = '\0';
1240 return wpa_ctrl_command(ctrl
, cmd
);
1244 static void wpa_cli_show_network_variables(void)
1246 printf("set_network variables:\n"
1247 " ssid (network name, SSID)\n"
1248 " psk (WPA passphrase or pre-shared key)\n"
1249 " key_mgmt (key management protocol)\n"
1250 " identity (EAP identity)\n"
1251 " password (EAP password)\n"
1254 "Note: Values are entered in the same format as the "
1255 "configuration file is using,\n"
1256 "i.e., strings values need to be inside double quotation "
1258 "For example: set_network 1 ssid \"network name\"\n"
1260 "Please see wpa_supplicant.conf documentation for full list "
1261 "of\navailable variables.\n");
1265 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1272 wpa_cli_show_network_variables();
1277 printf("Invalid SET_NETWORK command: needs three arguments\n"
1278 "(network id, variable name, and value)\n");
1282 res
= os_snprintf(cmd
, sizeof(cmd
), "SET_NETWORK %s %s %s",
1283 argv
[0], argv
[1], argv
[2]);
1284 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1285 printf("Too long SET_NETWORK command.\n");
1288 return wpa_ctrl_command(ctrl
, cmd
);
1292 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1299 wpa_cli_show_network_variables();
1304 printf("Invalid GET_NETWORK command: needs two arguments\n"
1305 "(network id and variable name)\n");
1309 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1311 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1312 printf("Too long GET_NETWORK command.\n");
1315 return wpa_ctrl_command(ctrl
, cmd
);
1319 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1322 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1326 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1329 return wpa_ctrl_command(ctrl
, "RECONNECT");
1333 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1336 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1340 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1342 return wpa_ctrl_command(ctrl
, "SCAN");
1346 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1349 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1353 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1359 printf("Invalid BSS command: need one argument (index or "
1364 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1365 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1367 cmd
[sizeof(cmd
) - 1] = '\0';
1369 return wpa_ctrl_command(ctrl
, cmd
);
1373 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1379 if (argc
< 1 || argc
> 2) {
1380 printf("Invalid GET_CAPABILITY command: need either one or "
1385 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1386 printf("Invalid GET_CAPABILITY command: second argument, "
1387 "if any, must be 'strict'\n");
1391 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_CAPABILITY %s%s", argv
[0],
1392 (argc
== 2) ? " strict" : "");
1393 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1395 cmd
[sizeof(cmd
) - 1] = '\0';
1397 return wpa_ctrl_command(ctrl
, cmd
);
1401 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1403 printf("Available interfaces:\n");
1404 return wpa_ctrl_command(ctrl
, "INTERFACES");
1408 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1411 wpa_cli_list_interfaces(ctrl
);
1415 wpa_cli_close_connection();
1416 os_free(ctrl_ifname
);
1417 ctrl_ifname
= os_strdup(argv
[0]);
1419 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1420 printf("Connected to interface '%s.\n", ctrl_ifname
);
1422 printf("Could not connect to interface '%s' - re-trying\n",
1429 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1432 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1436 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1439 return wpa_ctrl_command(ctrl
, "TERMINATE");
1443 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1450 printf("Invalid INTERFACE_ADD command: needs at least one "
1451 "argument (interface name)\n"
1452 "All arguments: ifname confname driver ctrl_interface "
1453 "driver_param bridge_name\n");
1458 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1459 * <driver_param>TAB<bridge_name>
1461 res
= os_snprintf(cmd
, sizeof(cmd
),
1462 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1464 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1465 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1466 argc
> 5 ? argv
[5] : "");
1467 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1469 cmd
[sizeof(cmd
) - 1] = '\0';
1470 return wpa_ctrl_command(ctrl
, cmd
);
1474 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1481 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1482 "(interface name)\n");
1486 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1487 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1489 cmd
[sizeof(cmd
) - 1] = '\0';
1490 return wpa_ctrl_command(ctrl
, cmd
);
1494 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1497 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1502 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1506 printf("Invalid 'sta' command - exactly one argument, STA "
1507 "address, is required.\n");
1510 os_snprintf(buf
, sizeof(buf
), "STA %s", argv
[0]);
1511 return wpa_ctrl_command(ctrl
, buf
);
1515 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1516 char *addr
, size_t addr_len
)
1518 char buf
[4096], *pos
;
1522 if (ctrl_conn
== NULL
) {
1523 printf("Not connected to hostapd - command dropped.\n");
1526 len
= sizeof(buf
) - 1;
1527 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1530 printf("'%s' command timed out.\n", cmd
);
1532 } else if (ret
< 0) {
1533 printf("'%s' command failed.\n", cmd
);
1538 if (memcmp(buf
, "FAIL", 4) == 0)
1543 while (*pos
!= '\0' && *pos
!= '\n')
1546 os_strlcpy(addr
, buf
, addr_len
);
1551 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1553 char addr
[32], cmd
[64];
1555 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1558 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1559 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1563 #endif /* CONFIG_AP */
1566 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1568 return wpa_ctrl_command(ctrl
, "SUSPEND");
1572 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1574 return wpa_ctrl_command(ctrl
, "RESUME");
1578 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1580 return wpa_ctrl_command(ctrl
, "DROP_SA");
1584 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1590 printf("Invalid ROAM command: needs one argument "
1591 "(target AP's BSSID)\n");
1595 res
= os_snprintf(cmd
, sizeof(cmd
), "ROAM %s", argv
[0]);
1596 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1597 printf("Too long ROAM command.\n");
1600 return wpa_ctrl_command(ctrl
, cmd
);
1606 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1612 return wpa_ctrl_command(ctrl
, "P2P_FIND");
1615 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
1618 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
1619 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1621 cmd
[sizeof(cmd
) - 1] = '\0';
1622 return wpa_ctrl_command(ctrl
, cmd
);
1626 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1629 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1633 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1640 printf("Invalid P2P_CONNECT command: needs at least two "
1641 "arguments (address and pbc/PIN)\n");
1646 res
= os_snprintf(cmd
, sizeof(cmd
),
1647 "P2P_CONNECT %s %s %s %s %s",
1648 argv
[0], argv
[1], argv
[2], argv
[3],
1651 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
1652 argv
[0], argv
[1], argv
[2], argv
[3]);
1654 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
1655 argv
[0], argv
[1], argv
[2]);
1657 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
1659 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1661 cmd
[sizeof(cmd
) - 1] = '\0';
1662 return wpa_ctrl_command(ctrl
, cmd
);
1666 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1673 return wpa_ctrl_command(ctrl
, "P2P_LISTEN");
1675 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_LISTEN %s", argv
[0]);
1676 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1678 cmd
[sizeof(cmd
) - 1] = '\0';
1679 return wpa_ctrl_command(ctrl
, cmd
);
1683 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1690 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1691 "(interface name)\n");
1695 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
1696 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1698 cmd
[sizeof(cmd
) - 1] = '\0';
1699 return wpa_ctrl_command(ctrl
, cmd
);
1703 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1710 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
1712 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s", argv
[0]);
1713 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1715 cmd
[sizeof(cmd
) - 1] = '\0';
1716 return wpa_ctrl_command(ctrl
, cmd
);
1720 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1727 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1728 "(address and config method\n"
1729 "(display, keypad, or pbc)\n");
1733 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
1735 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1737 cmd
[sizeof(cmd
) - 1] = '\0';
1738 return wpa_ctrl_command(ctrl
, cmd
);
1742 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1745 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1749 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1755 if (argc
!= 2 && argc
!= 4) {
1756 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1757 "arguments (address and TLVs) or four arguments "
1758 "(address, \"upnp\", version, search target "
1764 res
= os_snprintf(cmd
, sizeof(cmd
),
1765 "P2P_SERV_DISC_REQ %s %s %s %s",
1766 argv
[0], argv
[1], argv
[2], argv
[3]);
1768 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
1770 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1772 cmd
[sizeof(cmd
) - 1] = '\0';
1773 return wpa_ctrl_command(ctrl
, cmd
);
1777 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1778 int argc
, char *argv
[])
1784 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1785 "argument (pending request identifier)\n");
1789 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
1791 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1793 cmd
[sizeof(cmd
) - 1] = '\0';
1794 return wpa_ctrl_command(ctrl
, cmd
);
1798 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1805 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1806 "arguments (freq, address, dialog token, and TLVs)\n");
1810 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1811 argv
[0], argv
[1], argv
[2], argv
[3]);
1812 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1814 cmd
[sizeof(cmd
) - 1] = '\0';
1815 return wpa_ctrl_command(ctrl
, cmd
);
1819 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1822 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1826 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1827 int argc
, char *argv
[])
1833 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1834 "argument (external processing: 0/1)\n");
1838 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
1840 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1842 cmd
[sizeof(cmd
) - 1] = '\0';
1843 return wpa_ctrl_command(ctrl
, cmd
);
1847 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1850 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1854 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1860 if (argc
!= 3 && argc
!= 4) {
1861 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1867 res
= os_snprintf(cmd
, sizeof(cmd
),
1868 "P2P_SERVICE_ADD %s %s %s %s",
1869 argv
[0], argv
[1], argv
[2], argv
[3]);
1871 res
= os_snprintf(cmd
, sizeof(cmd
),
1872 "P2P_SERVICE_ADD %s %s %s",
1873 argv
[0], argv
[1], argv
[2]);
1874 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1876 cmd
[sizeof(cmd
) - 1] = '\0';
1877 return wpa_ctrl_command(ctrl
, cmd
);
1881 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1887 if (argc
!= 2 && argc
!= 3) {
1888 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1894 res
= os_snprintf(cmd
, sizeof(cmd
),
1895 "P2P_SERVICE_DEL %s %s %s",
1896 argv
[0], argv
[1], argv
[2]);
1898 res
= os_snprintf(cmd
, sizeof(cmd
),
1899 "P2P_SERVICE_DEL %s %s",
1901 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1903 cmd
[sizeof(cmd
) - 1] = '\0';
1904 return wpa_ctrl_command(ctrl
, cmd
);
1908 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1909 int argc
, char *argv
[])
1915 printf("Invalid P2P_REJECT command: needs one argument "
1916 "(peer address)\n");
1920 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
1921 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1923 cmd
[sizeof(cmd
) - 1] = '\0';
1924 return wpa_ctrl_command(ctrl
, cmd
);
1928 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
1929 int argc
, char *argv
[])
1935 printf("Invalid P2P_INVITE command: needs at least one "
1941 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
1942 argv
[0], argv
[1], argv
[2]);
1944 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
1947 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
1948 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1950 cmd
[sizeof(cmd
) - 1] = '\0';
1951 return wpa_ctrl_command(ctrl
, cmd
);
1955 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1959 printf("Invalid 'p2p_peer' command - exactly one argument, "
1960 "P2P peer device address, is required.\n");
1963 os_snprintf(buf
, sizeof(buf
), "P2P_PEER %s", argv
[0]);
1964 return wpa_ctrl_command(ctrl
, buf
);
1968 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
1969 char *addr
, size_t addr_len
,
1972 char buf
[4096], *pos
;
1976 if (ctrl_conn
== NULL
)
1978 len
= sizeof(buf
) - 1;
1979 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1982 printf("'%s' command timed out.\n", cmd
);
1984 } else if (ret
< 0) {
1985 printf("'%s' command failed.\n", cmd
);
1990 if (memcmp(buf
, "FAIL", 4) == 0)
1994 while (*pos
!= '\0' && *pos
!= '\n')
1997 os_strlcpy(addr
, buf
, addr_len
);
1998 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
1999 printf("%s\n", addr
);
2004 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2006 char addr
[32], cmd
[64];
2009 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2011 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2012 addr
, sizeof(addr
), discovered
))
2015 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2016 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2023 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2029 printf("Invalid P2P_SET command: needs two arguments (field, "
2034 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
2035 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2037 cmd
[sizeof(cmd
) - 1] = '\0';
2038 return wpa_ctrl_command(ctrl
, cmd
);
2042 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2044 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2048 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2051 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2055 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
2062 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2063 "(peer address)\n");
2067 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_UNAUTHORIZE %s", argv
[0]);
2069 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2072 cmd
[sizeof(cmd
) - 1] = '\0';
2073 return wpa_ctrl_command(ctrl
, cmd
);
2077 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2083 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2084 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2085 "(preferred duration, interval; in microsecods).\n"
2086 "Optional second pair can be used to provide "
2087 "acceptable values.\n");
2092 res
= os_snprintf(cmd
, sizeof(cmd
),
2093 "P2P_PRESENCE_REQ %s %s %s %s",
2094 argv
[0], argv
[1], argv
[2], argv
[3]);
2096 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2099 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
2100 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2102 cmd
[sizeof(cmd
) - 1] = '\0';
2103 return wpa_ctrl_command(ctrl
, cmd
);
2107 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2113 if (argc
!= 0 && argc
!= 2) {
2114 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2115 "(availability period, availability interval; in "
2117 "Extended Listen Timing can be cancelled with this "
2118 "command when used without parameters.\n");
2123 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2126 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2127 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2129 cmd
[sizeof(cmd
) - 1] = '\0';
2130 return wpa_ctrl_command(ctrl
, cmd
);
2133 #endif /* CONFIG_P2P */
2136 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2143 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2144 "(0/1 = disable/enable automatic reconnection)\n");
2147 res
= os_snprintf(cmd
, sizeof(cmd
), "STA_AUTOCONNECT %s", argv
[0]);
2148 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
2149 printf("Too long STA_AUTOCONNECT command.\n");
2152 return wpa_ctrl_command(ctrl
, cmd
);
2156 enum wpa_cli_cmd_flags
{
2157 cli_cmd_flag_none
= 0x00,
2158 cli_cmd_flag_sensitive
= 0x01
2161 struct wpa_cli_cmd
{
2163 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2164 enum wpa_cli_cmd_flags flags
;
2168 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2169 { "status", wpa_cli_cmd_status
,
2171 "[verbose] = get current WPA/EAPOL/EAP status" },
2172 { "ping", wpa_cli_cmd_ping
,
2174 "= pings wpa_supplicant" },
2175 { "relog", wpa_cli_cmd_relog
,
2177 "= re-open log-file (allow rolling logs)" },
2178 { "note", wpa_cli_cmd_note
,
2180 "<text> = add a note to wpa_supplicant debug log" },
2181 { "mib", wpa_cli_cmd_mib
,
2183 "= get MIB variables (dot1x, dot11)" },
2184 { "help", wpa_cli_cmd_help
,
2186 "= show this usage help" },
2187 { "interface", wpa_cli_cmd_interface
,
2189 "[ifname] = show interfaces/select interface" },
2190 { "level", wpa_cli_cmd_level
,
2192 "<debug level> = change debug level" },
2193 { "license", wpa_cli_cmd_license
,
2195 "= show full wpa_cli license" },
2196 { "quit", wpa_cli_cmd_quit
,
2199 { "set", wpa_cli_cmd_set
,
2201 "= set variables (shows list of variables when run without "
2203 { "get", wpa_cli_cmd_get
,
2205 "<name> = get information" },
2206 { "logon", wpa_cli_cmd_logon
,
2208 "= IEEE 802.1X EAPOL state machine logon" },
2209 { "logoff", wpa_cli_cmd_logoff
,
2211 "= IEEE 802.1X EAPOL state machine logoff" },
2212 { "pmksa", wpa_cli_cmd_pmksa
,
2214 "= show PMKSA cache" },
2215 { "reassociate", wpa_cli_cmd_reassociate
,
2217 "= force reassociation" },
2218 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2220 "<BSSID> = force preauthentication" },
2221 { "identity", wpa_cli_cmd_identity
,
2223 "<network id> <identity> = configure identity for an SSID" },
2224 { "password", wpa_cli_cmd_password
,
2225 cli_cmd_flag_sensitive
,
2226 "<network id> <password> = configure password for an SSID" },
2227 { "new_password", wpa_cli_cmd_new_password
,
2228 cli_cmd_flag_sensitive
,
2229 "<network id> <password> = change password for an SSID" },
2230 { "pin", wpa_cli_cmd_pin
,
2231 cli_cmd_flag_sensitive
,
2232 "<network id> <pin> = configure pin for an SSID" },
2233 { "otp", wpa_cli_cmd_otp
,
2234 cli_cmd_flag_sensitive
,
2235 "<network id> <password> = configure one-time-password for an SSID"
2237 { "passphrase", wpa_cli_cmd_passphrase
,
2238 cli_cmd_flag_sensitive
,
2239 "<network id> <passphrase> = configure private key passphrase\n"
2241 { "bssid", wpa_cli_cmd_bssid
,
2243 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2244 { "list_networks", wpa_cli_cmd_list_networks
,
2246 "= list configured networks" },
2247 { "select_network", wpa_cli_cmd_select_network
,
2249 "<network id> = select a network (disable others)" },
2250 { "enable_network", wpa_cli_cmd_enable_network
,
2252 "<network id> = enable a network" },
2253 { "disable_network", wpa_cli_cmd_disable_network
,
2255 "<network id> = disable a network" },
2256 { "add_network", wpa_cli_cmd_add_network
,
2258 "= add a network" },
2259 { "remove_network", wpa_cli_cmd_remove_network
,
2261 "<network id> = remove a network" },
2262 { "set_network", wpa_cli_cmd_set_network
,
2263 cli_cmd_flag_sensitive
,
2264 "<network id> <variable> <value> = set network variables (shows\n"
2265 " list of variables when run without arguments)" },
2266 { "get_network", wpa_cli_cmd_get_network
,
2268 "<network id> <variable> = get network variables" },
2269 { "save_config", wpa_cli_cmd_save_config
,
2271 "= save the current configuration" },
2272 { "disconnect", wpa_cli_cmd_disconnect
,
2274 "= disconnect and wait for reassociate/reconnect command before\n"
2276 { "reconnect", wpa_cli_cmd_reconnect
,
2278 "= like reassociate, but only takes effect if already disconnected"
2280 { "scan", wpa_cli_cmd_scan
,
2282 "= request new BSS scan" },
2283 { "scan_results", wpa_cli_cmd_scan_results
,
2285 "= get latest scan results" },
2286 { "bss", wpa_cli_cmd_bss
,
2288 "<<idx> | <bssid>> = get detailed scan result info" },
2289 { "get_capability", wpa_cli_cmd_get_capability
,
2291 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2292 { "reconfigure", wpa_cli_cmd_reconfigure
,
2294 "= force wpa_supplicant to re-read its configuration file" },
2295 { "terminate", wpa_cli_cmd_terminate
,
2297 "= terminate wpa_supplicant" },
2298 { "interface_add", wpa_cli_cmd_interface_add
,
2300 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2301 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2303 { "interface_remove", wpa_cli_cmd_interface_remove
,
2305 "<ifname> = removes the interface" },
2306 { "interface_list", wpa_cli_cmd_interface_list
,
2308 "= list available interfaces" },
2309 { "ap_scan", wpa_cli_cmd_ap_scan
,
2311 "<value> = set ap_scan parameter" },
2312 { "stkstart", wpa_cli_cmd_stkstart
,
2314 "<addr> = request STK negotiation with <addr>" },
2315 { "ft_ds", wpa_cli_cmd_ft_ds
,
2317 "<addr> = request over-the-DS FT with <addr>" },
2318 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
2320 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2321 { "wps_pin", wpa_cli_cmd_wps_pin
,
2322 cli_cmd_flag_sensitive
,
2323 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2325 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
2326 cli_cmd_flag_sensitive
,
2327 "<PIN> = verify PIN checksum" },
2328 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
2329 "Cancels the pending WPS operation" },
2330 #ifdef CONFIG_WPS_OOB
2331 { "wps_oob", wpa_cli_cmd_wps_oob
,
2332 cli_cmd_flag_sensitive
,
2333 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2334 #endif /* CONFIG_WPS_OOB */
2335 { "wps_reg", wpa_cli_cmd_wps_reg
,
2336 cli_cmd_flag_sensitive
,
2337 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2338 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
,
2339 cli_cmd_flag_sensitive
,
2340 "[params..] = enable/disable AP PIN" },
2341 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
2343 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2344 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
2346 "= stop Wi-Fi Protected Setup External Registrar" },
2347 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
2348 cli_cmd_flag_sensitive
,
2349 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2350 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
2352 "<UUID> = accept an Enrollee PBC using External Registrar" },
2353 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
2354 cli_cmd_flag_sensitive
,
2355 "<UUID> <PIN> = learn AP configuration" },
2356 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
,
2358 "<UUID> <network id> = set AP configuration for enrolling" },
2359 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
2360 cli_cmd_flag_sensitive
,
2361 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2362 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
2364 "<addr> = request RSN authentication with <addr> in IBSS" },
2366 { "sta", wpa_cli_cmd_sta
,
2368 "<addr> = get information about an associated station (AP)" },
2369 { "all_sta", wpa_cli_cmd_all_sta
,
2371 "= get information about all associated stations (AP)" },
2372 #endif /* CONFIG_AP */
2373 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
2374 "= notification of suspend/hibernate" },
2375 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
2376 "= notification of resume/thaw" },
2377 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
2378 "= drop SA without deauth/disassoc (test command)" },
2379 { "roam", wpa_cli_cmd_roam
,
2381 "<addr> = roam to the specified BSS" },
2383 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
2384 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2385 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
2386 "= stop P2P Devices search" },
2387 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
2388 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2389 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
2390 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2391 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
2392 "<ifname> = remove P2P group interface (terminate group if GO)" },
2393 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
2394 "= add a new P2P group (local end as GO)" },
2395 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
2396 "<addr> <method> = request provisioning discovery" },
2397 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
2399 "= get the passphrase for a group (GO only)" },
2400 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2402 "<addr> <TLVs> = schedule service discovery request" },
2403 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2405 "<id> = cancel pending service discovery request" },
2406 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2408 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2409 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2411 "= indicate change in local services" },
2412 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2414 "<external> = set external processing of service discovery" },
2415 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2417 "= remove all stored service entries" },
2418 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2420 "<bonjour|upnp> <query|version> <response|service> = add a local "
2422 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2424 "<bonjour|upnp> <query|version> [|service] = remove a local "
2426 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2428 "<addr> = reject connection attempts from a specific peer" },
2429 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
2431 "<cmd> [peer=addr] = invite peer" },
2432 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
2433 "[discovered] = list known (optionally, only fully discovered) P2P "
2435 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
2436 "<address> = show information about known P2P peer" },
2437 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
2438 "<field> <value> = set a P2P parameter" },
2439 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
2440 "= flush P2P state" },
2441 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
2442 "= cancel P2P group formation" },
2443 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
, cli_cmd_flag_none
,
2444 "<address> = unauthorize a peer" },
2445 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
2446 "[<duration> <interval>] [<duration> <interval>] = request GO "
2448 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
2449 "[<period> <interval>] = set extended listen timing" },
2450 #endif /* CONFIG_P2P */
2451 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
2452 "<0/1> = disable/enable automatic reconnection" },
2453 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2458 * Prints command usage, lines are padded with the specified string.
2460 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2465 printf("%s%s ", pad
, cmd
->cmd
);
2466 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2475 static void print_help(void)
2478 printf("commands:\n");
2479 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
2480 print_cmd_help(&wpa_cli_commands
[n
], " ");
2484 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
2486 const char *c
, *delim
;
2490 delim
= os_strchr(cmd
, ' ');
2494 len
= os_strlen(cmd
);
2496 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2497 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2498 return (wpa_cli_commands
[n
].flags
&
2499 cli_cmd_flag_sensitive
);
2505 static char ** wpa_list_cmd_list(void)
2510 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
2511 res
= os_zalloc(count
* sizeof(char *));
2515 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2516 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
2525 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
2530 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2531 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
2533 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
2543 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
2549 end
= os_strchr(str
, ' ');
2550 if (end
== NULL
|| str
+ pos
< end
)
2551 return wpa_list_cmd_list();
2553 cmd
= os_malloc(pos
+ 1);
2556 os_memcpy(cmd
, str
, pos
);
2557 cmd
[end
- str
] = '\0';
2558 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
2564 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2566 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2571 cmd
= wpa_cli_commands
;
2573 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2576 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2577 /* we have an exact match */
2587 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
2588 cmd
= wpa_cli_commands
;
2590 if (os_strncasecmp(cmd
->cmd
, argv
[0],
2591 os_strlen(argv
[0])) == 0) {
2592 printf(" %s", cmd
->cmd
);
2598 } else if (count
== 0) {
2599 printf("Unknown command '%s'\n", argv
[0]);
2602 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
2609 static int str_match(const char *a
, const char *b
)
2611 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
2615 static int wpa_cli_exec(const char *program
, const char *arg1
,
2623 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
2624 cmd
= os_malloc(len
);
2627 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
2628 if (res
< 0 || (size_t) res
>= len
) {
2632 cmd
[len
- 1] = '\0';
2634 if (system(cmd
) < 0)
2636 #endif /* _WIN32_WCE */
2643 static void wpa_cli_action_process(const char *msg
)
2646 char *copy
= NULL
, *id
, *pos2
;
2651 pos
= os_strchr(pos
, '>');
2658 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
2660 os_unsetenv("WPA_ID");
2661 os_unsetenv("WPA_ID_STR");
2662 os_unsetenv("WPA_CTRL_DIR");
2664 pos
= os_strstr(pos
, "[id=");
2666 copy
= os_strdup(pos
+ 4);
2670 while (*pos2
&& *pos2
!= ' ')
2674 os_setenv("WPA_ID", id
, 1);
2675 while (*pos2
&& *pos2
!= '=')
2680 while (*pos2
&& *pos2
!= ']')
2683 os_setenv("WPA_ID_STR", id
, 1);
2687 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
2689 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
2690 wpa_cli_connected
= 1;
2691 wpa_cli_last_id
= new_id
;
2692 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
2694 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
2695 if (wpa_cli_connected
) {
2696 wpa_cli_connected
= 0;
2697 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
2699 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
2700 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2701 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
2702 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2703 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
2704 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2705 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
2706 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2707 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
2708 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2709 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
2710 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2711 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
2712 printf("wpa_supplicant is terminating - stop monitoring\n");
2718 #ifndef CONFIG_ANSI_C_EXTRA
2719 static void wpa_cli_action_cb(char *msg
, size_t len
)
2721 wpa_cli_action_process(msg
);
2723 #endif /* CONFIG_ANSI_C_EXTRA */
2726 static void wpa_cli_reconnect(void)
2728 wpa_cli_close_connection();
2729 wpa_cli_open_connection(ctrl_ifname
, 1);
2733 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
2735 if (ctrl_conn
== NULL
) {
2736 wpa_cli_reconnect();
2739 while (wpa_ctrl_pending(ctrl
) > 0) {
2741 size_t len
= sizeof(buf
) - 1;
2742 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
2745 wpa_cli_action_process(buf
);
2747 if (wpa_cli_show_event(buf
)) {
2749 printf("\r%s\n", buf
);
2754 printf("Could not read pending message.\n");
2759 if (wpa_ctrl_pending(ctrl
) < 0) {
2760 printf("Connection to wpa_supplicant lost - trying to "
2762 wpa_cli_reconnect();
2768 static int tokenize_cmd(char *cmd
, char *argv
[])
2781 if (argc
== max_args
)
2784 char *pos2
= os_strrchr(pos
, '"');
2788 while (*pos
!= '\0' && *pos
!= ' ')
2798 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
2800 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
2801 printf("Connection to wpa_supplicant lost - trying to "
2803 wpa_cli_close_connection();
2806 wpa_cli_reconnect();
2807 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
2811 static void wpa_cli_eloop_terminate(int sig
, void *signal_ctx
)
2817 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
2819 wpa_cli_recv_pending(mon_conn
, 0);
2823 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
2825 char *argv
[max_args
];
2827 argc
= tokenize_cmd(cmd
, argv
);
2829 wpa_request(ctrl_conn
, argc
, argv
);
2833 static void wpa_cli_edit_eof_cb(void *ctx
)
2839 static void wpa_cli_interactive(void)
2841 char *home
, *hfile
= NULL
;
2843 printf("\nInteractive mode\n\n");
2845 home
= getenv("HOME");
2847 const char *fname
= ".wpa_cli_history";
2848 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
2849 hfile
= os_malloc(hfile_len
);
2851 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
2854 eloop_register_signal_terminate(wpa_cli_eloop_terminate
, NULL
);
2855 edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
2856 wpa_cli_edit_completion_cb
, NULL
, hfile
);
2857 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
2861 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
2863 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
2864 wpa_cli_close_connection();
2868 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
2870 #ifdef CONFIG_ANSI_C_EXTRA
2871 /* TODO: ANSI C version(?) */
2872 printf("Action processing not supported in ANSI C build.\n");
2873 #else /* CONFIG_ANSI_C_EXTRA */
2877 char buf
[256]; /* note: large enough to fit in unsolicited messages */
2880 fd
= wpa_ctrl_get_fd(ctrl
);
2882 while (!wpa_cli_quit
) {
2885 tv
.tv_sec
= ping_interval
;
2887 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
2888 if (res
< 0 && errno
!= EINTR
) {
2893 if (FD_ISSET(fd
, &rfds
))
2894 wpa_cli_recv_pending(ctrl
, 1);
2896 /* verify that connection is still working */
2897 len
= sizeof(buf
) - 1;
2898 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
2899 wpa_cli_action_cb
) < 0 ||
2900 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
2901 printf("wpa_supplicant did not reply to PING "
2902 "command - exiting\n");
2907 #endif /* CONFIG_ANSI_C_EXTRA */
2911 static void wpa_cli_cleanup(void)
2913 wpa_cli_close_connection();
2915 os_daemonize_terminate(pid_file
);
2917 os_program_deinit();
2920 static void wpa_cli_terminate(int sig
)
2927 static char * wpa_cli_get_default_ifname(void)
2929 char *ifname
= NULL
;
2931 #ifdef CONFIG_CTRL_IFACE_UNIX
2932 struct dirent
*dent
;
2933 DIR *dir
= opendir(ctrl_iface_dir
);
2936 while ((dent
= readdir(dir
))) {
2937 #ifdef _DIRENT_HAVE_D_TYPE
2939 * Skip the file if it is not a socket. Also accept
2940 * DT_UNKNOWN (0) in case the C library or underlying
2941 * file system does not support d_type.
2943 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
2945 #endif /* _DIRENT_HAVE_D_TYPE */
2946 if (os_strcmp(dent
->d_name
, ".") == 0 ||
2947 os_strcmp(dent
->d_name
, "..") == 0)
2949 printf("Selected interface '%s'\n", dent
->d_name
);
2950 ifname
= os_strdup(dent
->d_name
);
2954 #endif /* CONFIG_CTRL_IFACE_UNIX */
2956 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2957 char buf
[2048], *pos
;
2959 struct wpa_ctrl
*ctrl
;
2962 ctrl
= wpa_ctrl_open(NULL
);
2966 len
= sizeof(buf
) - 1;
2967 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
2970 pos
= os_strchr(buf
, '\n');
2973 ifname
= os_strdup(buf
);
2975 wpa_ctrl_close(ctrl
);
2976 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2982 int main(int argc
, char *argv
[])
2984 int warning_displayed
= 0;
2988 const char *global
= NULL
;
2990 if (os_program_init())
2994 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
2999 action_file
= optarg
;
3008 ping_interval
= atoi(optarg
);
3014 printf("%s\n", wpa_cli_version
);
3017 os_free(ctrl_ifname
);
3018 ctrl_ifname
= os_strdup(optarg
);
3021 ctrl_iface_dir
= optarg
;
3032 interactive
= (argc
== optind
) && (action_file
== NULL
);
3035 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3041 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3042 ctrl_conn
= wpa_ctrl_open(NULL
);
3043 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3044 ctrl_conn
= wpa_ctrl_open(global
);
3045 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3046 if (ctrl_conn
== NULL
) {
3047 perror("Failed to connect to wpa_supplicant - "
3054 signal(SIGINT
, wpa_cli_terminate
);
3055 signal(SIGTERM
, wpa_cli_terminate
);
3056 #endif /* _WIN32_WCE */
3058 if (ctrl_ifname
== NULL
)
3059 ctrl_ifname
= wpa_cli_get_default_ifname();
3063 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3064 if (warning_displayed
)
3065 printf("Connection established.\n");
3069 if (!warning_displayed
) {
3070 printf("Could not connect to wpa_supplicant - "
3072 warning_displayed
= 1;
3079 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3080 perror("Failed to connect to wpa_supplicant - "
3086 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3087 wpa_cli_attached
= 1;
3089 printf("Warning: Failed to attach to "
3090 "wpa_supplicant.\n");
3096 if (daemonize
&& os_daemonize(pid_file
))
3100 wpa_cli_interactive();
3101 else if (action_file
)
3102 wpa_cli_action(ctrl_conn
);
3104 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
3106 os_free(ctrl_ifname
);
3113 #else /* CONFIG_CTRL_IFACE */
3114 int main(int argc
, char *argv
[])
3116 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3119 #endif /* CONFIG_CTRL_IFACE */