2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2011, 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"
29 #include <cutils/properties.h>
33 static const char *wpa_cli_version =
34 "wpa_cli v" VERSION_STR "\n"
35 "Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> and contributors";
38 static const char *wpa_cli_license =
39 "This program is free software. You can distribute it and/or modify it\n"
40 "under the terms of the GNU General Public License version 2.\n"
42 "Alternatively, this software may be distributed under the terms of the\n"
43 "BSD license. See README and COPYING for more details.\n";
45 static const char *wpa_cli_full_license =
46 "This program is free software; you can redistribute it and/or modify\n"
47 "it under the terms of the GNU General Public License version 2 as\n"
48 "published by the Free Software Foundation.\n"
50 "This program is distributed in the hope that it will be useful,\n"
51 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
52 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
53 "GNU General Public License for more details.\n"
55 "You should have received a copy of the GNU General Public License\n"
56 "along with this program; if not, write to the Free Software\n"
57 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
59 "Alternatively, this software may be distributed under the terms of the\n"
62 "Redistribution and use in source and binary forms, with or without\n"
63 "modification, are permitted provided that the following conditions are\n"
66 "1. Redistributions of source code must retain the above copyright\n"
67 " notice, this list of conditions and the following disclaimer.\n"
69 "2. Redistributions in binary form must reproduce the above copyright\n"
70 " notice, this list of conditions and the following disclaimer in the\n"
71 " documentation and/or other materials provided with the distribution.\n"
73 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
74 " names of its contributors may be used to endorse or promote products\n"
75 " derived from this software without specific prior written permission.\n"
77 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
78 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
79 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
80 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
81 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
82 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
83 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
84 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
85 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
86 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
87 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
90 static struct wpa_ctrl *ctrl_conn;
91 static struct wpa_ctrl *mon_conn;
92 static int wpa_cli_quit = 0;
93 static int wpa_cli_attached = 0;
94 static int wpa_cli_connected = 0;
95 static int wpa_cli_last_id = 0;
96 #ifndef CONFIG_CTRL_IFACE_DIR
97 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
98 #endif /* CONFIG_CTRL_IFACE_DIR */
99 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
100 static char *ctrl_ifname = NULL;
101 static const char *pid_file = NULL;
102 static const char *action_file = NULL;
103 static int ping_interval = 5;
104 static int interactive = 0;
107 static void print_help(void);
108 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
111 static void usage(void)
113 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
114 "[-a<action file>] \\\n"
115 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
117 " -h = help (show this usage text)\n"
118 " -v = shown version information\n"
119 " -a = run in daemon mode executing the action file based on "
122 " -B = run a daemon in the background\n"
123 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
124 " default interface: first interface found in socket path\n");
129 static int str_starts(const char *src, const char *match)
131 return os_strncmp(src, match, os_strlen(match)) == 0;
135 static int wpa_cli_show_event(const char *event)
139 start = os_strchr(event, '>');
145 * Skip BSS added/removed events since they can be relatively frequent
146 * and are likely of not much use for an interactive user.
148 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
149 str_starts(start, WPA_EVENT_BSS_REMOVED))
156 static int wpa_cli_open_connection(const char *ifname, int attach)
158 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
159 ctrl_conn = wpa_ctrl_open(ifname);
160 if (ctrl_conn == NULL)
163 if (attach && interactive)
164 mon_conn = wpa_ctrl_open(ifname);
167 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
175 if (access(ctrl_iface_dir, F_OK) < 0) {
176 cfile = os_strdup(ifname);
183 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
184 cfile = os_malloc(flen);
187 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
189 if (res < 0 || res >= flen) {
195 ctrl_conn = wpa_ctrl_open(cfile);
196 if (ctrl_conn == NULL) {
201 if (attach && interactive)
202 mon_conn = wpa_ctrl_open(cfile);
206 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
209 if (wpa_ctrl_attach(mon_conn) == 0) {
210 wpa_cli_attached = 1;
212 eloop_register_read_sock(
213 wpa_ctrl_get_fd(mon_conn),
214 wpa_cli_mon_receive, NULL, NULL);
216 printf("Warning: Failed to attach to "
217 "wpa_supplicant.\n");
226 static void wpa_cli_close_connection(void)
228 if (ctrl_conn == NULL)
231 if (wpa_cli_attached) {
232 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
233 wpa_cli_attached = 0;
235 wpa_ctrl_close(ctrl_conn);
238 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
239 wpa_ctrl_close(mon_conn);
245 static void wpa_cli_msg_cb(char *msg, size_t len)
251 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
257 if (ctrl_conn == NULL) {
258 printf("Not connected to wpa_supplicant - command dropped.\n");
261 len = sizeof(buf) - 1;
262 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
265 printf("'%s' command timed out.\n", cmd);
267 } else if (ret < 0) {
268 printf("'%s' command failed.\n", cmd);
274 if (interactive && len > 0 && buf[len - 1] != '\n')
281 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
283 return _wpa_ctrl_command(ctrl, cmd, 1);
287 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
289 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
290 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
294 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
296 return wpa_ctrl_command(ctrl, "PING");
300 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
302 return wpa_ctrl_command(ctrl, "RELOG");
306 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
312 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
313 if (ret < 0 || (size_t) ret >= sizeof(cmd))
315 return wpa_ctrl_command(ctrl, cmd);
319 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
321 return wpa_ctrl_command(ctrl, "MIB");
325 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
327 return wpa_ctrl_command(ctrl, "PMKSA");
331 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
338 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
340 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
345 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
354 static void wpa_cli_show_variables(void)
356 printf("set variables:\n"
357 " EAPOL::heldPeriod (EAPOL state machine held period, "
359 " EAPOL::authPeriod (EAPOL state machine authentication "
360 "period, in seconds)\n"
361 " EAPOL::startPeriod (EAPOL state machine start period, in "
363 " EAPOL::maxStart (EAPOL state machine maximum start "
365 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
367 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
368 " threshold\n\tpercentage)\n"
369 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
370 "security\n\tassociation in seconds)\n");
374 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
380 wpa_cli_show_variables();
385 printf("Invalid SET command: needs two arguments (variable "
386 "name and value)\n");
390 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
391 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
392 printf("Too long SET command.\n");
395 return wpa_ctrl_command(ctrl, cmd);
399 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
405 printf("Invalid GET command: need one argument (variable "
410 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
411 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
412 printf("Too long GET command.\n");
415 return wpa_ctrl_command(ctrl, cmd);
419 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
421 return wpa_ctrl_command(ctrl, "LOGOFF");
425 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
427 return wpa_ctrl_command(ctrl, "LOGON");
431 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
434 return wpa_ctrl_command(ctrl, "REASSOCIATE");
438 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
445 printf("Invalid PREAUTH command: needs one argument "
450 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
451 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
452 printf("Too long PREAUTH command.\n");
455 return wpa_ctrl_command(ctrl, cmd);
459 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
465 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
469 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
470 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
471 printf("Too long AP_SCAN command.\n");
474 return wpa_ctrl_command(ctrl, cmd);
478 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
485 printf("Invalid SCAN_INTERVAL command: needs one argument "
486 "scan_interval value)\n");
489 res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
490 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
491 printf("Too long SCAN_INTERVAL command.\n");
494 return wpa_ctrl_command(ctrl, cmd);
498 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
505 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
506 "(bss_expire_age value)\n");
509 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
510 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
511 printf("Too long BSS_EXPIRE_AGE command.\n");
514 return wpa_ctrl_command(ctrl, cmd);
518 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
525 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
526 "(bss_expire_count value)\n");
529 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
530 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
531 printf("Too long BSS_EXPIRE_COUNT command.\n");
534 return wpa_ctrl_command(ctrl, cmd);
538 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
545 printf("Invalid STKSTART command: needs one argument "
546 "(Peer STA MAC address)\n");
550 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
551 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
552 printf("Too long STKSTART command.\n");
555 return wpa_ctrl_command(ctrl, cmd);
559 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
565 printf("Invalid FT_DS command: needs one argument "
566 "(Target AP MAC address)\n");
570 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
571 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
572 printf("Too long FT_DS command.\n");
575 return wpa_ctrl_command(ctrl, cmd);
579 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
586 return wpa_ctrl_command(ctrl, "WPS_PBC");
590 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
591 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
592 printf("Too long WPS_PBC command.\n");
595 return wpa_ctrl_command(ctrl, cmd);
599 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
605 printf("Invalid WPS_PIN command: need one or two arguments:\n"
606 "- BSSID: use 'any' to select any\n"
607 "- PIN: optional, used only with devices that have no "
613 /* Use dynamically generated PIN (returned as reply) */
614 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
615 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
616 printf("Too long WPS_PIN command.\n");
619 return wpa_ctrl_command(ctrl, cmd);
622 /* Use hardcoded PIN from a label */
623 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
624 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
625 printf("Too long WPS_PIN command.\n");
628 return wpa_ctrl_command(ctrl, cmd);
632 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
638 if (argc != 1 && argc != 2) {
639 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
640 "- PIN to be verified\n");
645 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
648 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
650 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
651 printf("Too long WPS_CHECK_PIN command.\n");
654 return wpa_ctrl_command(ctrl, cmd);
658 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
661 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
665 #ifdef CONFIG_WPS_OOB
666 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
671 if (argc != 3 && argc != 4) {
672 printf("Invalid WPS_OOB command: need three or four "
674 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
675 "- PATH: path of OOB device like '/mnt'\n"
676 "- METHOD: OOB method 'pin-e' or 'pin-r', "
678 "- DEV_NAME: (only for NFC) device name like "
684 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
685 argv[0], argv[1], argv[2]);
687 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
688 argv[0], argv[1], argv[2], argv[3]);
689 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
690 printf("Too long WPS_OOB command.\n");
693 return wpa_ctrl_command(ctrl, cmd);
695 #endif /* CONFIG_WPS_OOB */
698 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
704 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
706 else if (argc == 5 || argc == 6) {
707 char ssid_hex[2 * 32 + 1];
708 char key_hex[2 * 64 + 1];
712 for (i = 0; i < 32; i++) {
713 if (argv[2][i] == '\0')
715 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
720 for (i = 0; i < 64; i++) {
721 if (argv[5][i] == '\0')
723 os_snprintf(&key_hex[i * 2], 3, "%02x",
728 res = os_snprintf(cmd, sizeof(cmd),
729 "WPS_REG %s %s %s %s %s %s",
730 argv[0], argv[1], ssid_hex, argv[3], argv[4],
733 printf("Invalid WPS_REG command: need two arguments:\n"
734 "- BSSID of the target AP\n"
736 printf("Alternatively, six arguments can be used to "
737 "reconfigure the AP:\n"
738 "- BSSID of the target AP\n"
741 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
742 "- new encr (NONE, WEP, TKIP, CCMP)\n"
747 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
748 printf("Too long WPS_REG command.\n");
751 return wpa_ctrl_command(ctrl, cmd);
755 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
762 printf("Invalid WPS_AP_PIN command: needs at least one "
768 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
769 argv[0], argv[1], argv[2]);
771 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
774 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
776 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
777 printf("Too long WPS_AP_PIN command.\n");
780 return wpa_ctrl_command(ctrl, cmd);
784 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
789 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
790 return wpa_ctrl_command(ctrl, cmd);
792 return wpa_ctrl_command(ctrl, "WPS_ER_START");
796 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
799 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
804 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
811 printf("Invalid WPS_ER_PIN command: need at least two "
813 "- UUID: use 'any' to select any\n"
814 "- PIN: Enrollee PIN\n"
815 "optional: - Enrollee MAC address\n");
820 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
821 argv[0], argv[1], argv[2]);
823 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
825 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
826 printf("Too long WPS_ER_PIN command.\n");
829 return wpa_ctrl_command(ctrl, cmd);
833 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
840 printf("Invalid WPS_ER_PBC command: need one argument:\n"
841 "- UUID: Specify the Enrollee\n");
845 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
847 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
848 printf("Too long WPS_ER_PBC command.\n");
851 return wpa_ctrl_command(ctrl, cmd);
855 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
862 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
863 "- UUID: specify which AP to use\n"
868 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
870 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
871 printf("Too long WPS_ER_LEARN command.\n");
874 return wpa_ctrl_command(ctrl, cmd);
878 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
885 printf("Invalid WPS_ER_SET_CONFIG command: need two "
887 "- UUID: specify which AP to use\n"
888 "- Network configuration id\n");
892 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
894 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
895 printf("Too long WPS_ER_SET_CONFIG command.\n");
898 return wpa_ctrl_command(ctrl, cmd);
902 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
908 if (argc == 5 || argc == 6) {
909 char ssid_hex[2 * 32 + 1];
910 char key_hex[2 * 64 + 1];
914 for (i = 0; i < 32; i++) {
915 if (argv[2][i] == '\0')
917 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
922 for (i = 0; i < 64; i++) {
923 if (argv[5][i] == '\0')
925 os_snprintf(&key_hex[i * 2], 3, "%02x",
930 res = os_snprintf(cmd, sizeof(cmd),
931 "WPS_ER_CONFIG %s %s %s %s %s %s",
932 argv[0], argv[1], ssid_hex, argv[3], argv[4],
935 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
939 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
940 "- new encr (NONE, WEP, TKIP, CCMP)\n"
945 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
946 printf("Too long WPS_ER_CONFIG command.\n");
949 return wpa_ctrl_command(ctrl, cmd);
953 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
959 printf("Invalid IBSS_RSN command: needs one argument "
960 "(Peer STA MAC address)\n");
964 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
965 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
966 printf("Too long IBSS_RSN command.\n");
969 return wpa_ctrl_command(ctrl, cmd);
973 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
979 printf("Invalid LEVEL command: needs one argument (debug "
983 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
984 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
985 printf("Too long LEVEL command.\n");
988 return wpa_ctrl_command(ctrl, cmd);
992 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
994 char cmd[256], *pos, *end;
998 printf("Invalid IDENTITY command: needs two arguments "
999 "(network id and identity)\n");
1003 end = cmd + sizeof(cmd);
1005 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1007 if (ret < 0 || ret >= end - pos) {
1008 printf("Too long IDENTITY command.\n");
1012 for (i = 2; i < argc; i++) {
1013 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1014 if (ret < 0 || ret >= end - pos) {
1015 printf("Too long IDENTITY command.\n");
1021 return wpa_ctrl_command(ctrl, cmd);
1025 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1027 char cmd[256], *pos, *end;
1031 printf("Invalid PASSWORD command: needs two arguments "
1032 "(network id and password)\n");
1036 end = cmd + sizeof(cmd);
1038 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1040 if (ret < 0 || ret >= end - pos) {
1041 printf("Too long PASSWORD command.\n");
1045 for (i = 2; i < argc; i++) {
1046 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1047 if (ret < 0 || ret >= end - pos) {
1048 printf("Too long PASSWORD command.\n");
1054 return wpa_ctrl_command(ctrl, cmd);
1058 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1061 char cmd[256], *pos, *end;
1065 printf("Invalid NEW_PASSWORD command: needs two arguments "
1066 "(network id and password)\n");
1070 end = cmd + sizeof(cmd);
1072 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1074 if (ret < 0 || ret >= end - pos) {
1075 printf("Too long NEW_PASSWORD command.\n");
1079 for (i = 2; i < argc; i++) {
1080 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1081 if (ret < 0 || ret >= end - pos) {
1082 printf("Too long NEW_PASSWORD command.\n");
1088 return wpa_ctrl_command(ctrl, cmd);
1092 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1094 char cmd[256], *pos, *end;
1098 printf("Invalid PIN command: needs two arguments "
1099 "(network id and pin)\n");
1103 end = cmd + sizeof(cmd);
1105 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1107 if (ret < 0 || ret >= end - pos) {
1108 printf("Too long PIN command.\n");
1112 for (i = 2; i < argc; i++) {
1113 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1114 if (ret < 0 || ret >= end - pos) {
1115 printf("Too long PIN command.\n");
1120 return wpa_ctrl_command(ctrl, cmd);
1124 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1126 char cmd[256], *pos, *end;
1130 printf("Invalid OTP command: needs two arguments (network "
1131 "id and password)\n");
1135 end = cmd + sizeof(cmd);
1137 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1139 if (ret < 0 || ret >= end - pos) {
1140 printf("Too long OTP command.\n");
1144 for (i = 2; i < argc; i++) {
1145 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1146 if (ret < 0 || ret >= end - pos) {
1147 printf("Too long OTP command.\n");
1153 return wpa_ctrl_command(ctrl, cmd);
1157 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1160 char cmd[256], *pos, *end;
1164 printf("Invalid PASSPHRASE command: needs two arguments "
1165 "(network id and passphrase)\n");
1169 end = cmd + sizeof(cmd);
1171 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1173 if (ret < 0 || ret >= end - pos) {
1174 printf("Too long PASSPHRASE command.\n");
1178 for (i = 2; i < argc; i++) {
1179 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1180 if (ret < 0 || ret >= end - pos) {
1181 printf("Too long PASSPHRASE command.\n");
1187 return wpa_ctrl_command(ctrl, cmd);
1191 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1193 char cmd[256], *pos, *end;
1197 printf("Invalid BSSID command: needs two arguments (network "
1202 end = cmd + sizeof(cmd);
1204 ret = os_snprintf(pos, end - pos, "BSSID");
1205 if (ret < 0 || ret >= end - pos) {
1206 printf("Too long BSSID command.\n");
1210 for (i = 0; i < argc; i++) {
1211 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1212 if (ret < 0 || ret >= end - pos) {
1213 printf("Too long BSSID command.\n");
1219 return wpa_ctrl_command(ctrl, cmd);
1223 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1226 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1230 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1237 printf("Invalid SELECT_NETWORK command: needs one argument "
1242 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1243 if (res < 0 || (size_t) res >= sizeof(cmd))
1245 cmd[sizeof(cmd) - 1] = '\0';
1247 return wpa_ctrl_command(ctrl, cmd);
1251 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1258 printf("Invalid ENABLE_NETWORK command: needs one argument "
1263 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1264 if (res < 0 || (size_t) res >= sizeof(cmd))
1266 cmd[sizeof(cmd) - 1] = '\0';
1268 return wpa_ctrl_command(ctrl, cmd);
1272 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1279 printf("Invalid DISABLE_NETWORK command: needs one argument "
1284 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1285 if (res < 0 || (size_t) res >= sizeof(cmd))
1287 cmd[sizeof(cmd) - 1] = '\0';
1289 return wpa_ctrl_command(ctrl, cmd);
1293 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1296 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1300 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1307 printf("Invalid REMOVE_NETWORK command: needs one argument "
1312 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1313 if (res < 0 || (size_t) res >= sizeof(cmd))
1315 cmd[sizeof(cmd) - 1] = '\0';
1317 return wpa_ctrl_command(ctrl, cmd);
1321 static void wpa_cli_show_network_variables(void)
1323 printf("set_network variables:\n"
1324 " ssid (network name, SSID)\n"
1325 " psk (WPA passphrase or pre-shared key)\n"
1326 " key_mgmt (key management protocol)\n"
1327 " identity (EAP identity)\n"
1328 " password (EAP password)\n"
1331 "Note: Values are entered in the same format as the "
1332 "configuration file is using,\n"
1333 "i.e., strings values need to be inside double quotation "
1335 "For example: set_network 1 ssid \"network name\"\n"
1337 "Please see wpa_supplicant.conf documentation for full list "
1338 "of\navailable variables.\n");
1342 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1349 wpa_cli_show_network_variables();
1354 printf("Invalid SET_NETWORK command: needs three arguments\n"
1355 "(network id, variable name, and value)\n");
1359 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1360 argv[0], argv[1], argv[2]);
1361 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1362 printf("Too long SET_NETWORK command.\n");
1365 return wpa_ctrl_command(ctrl, cmd);
1369 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1376 wpa_cli_show_network_variables();
1381 printf("Invalid GET_NETWORK command: needs two arguments\n"
1382 "(network id and variable name)\n");
1386 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1388 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1389 printf("Too long GET_NETWORK command.\n");
1392 return wpa_ctrl_command(ctrl, cmd);
1396 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1399 return wpa_ctrl_command(ctrl, "DISCONNECT");
1403 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1406 return wpa_ctrl_command(ctrl, "RECONNECT");
1410 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1413 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1417 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1419 return wpa_ctrl_command(ctrl, "SCAN");
1423 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1426 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1430 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1436 printf("Invalid BSS command: need one argument (index or "
1441 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1442 if (res < 0 || (size_t) res >= sizeof(cmd))
1444 cmd[sizeof(cmd) - 1] = '\0';
1446 return wpa_ctrl_command(ctrl, cmd);
1450 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1456 if (argc < 1 || argc > 2) {
1457 printf("Invalid GET_CAPABILITY command: need either one or "
1462 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1463 printf("Invalid GET_CAPABILITY command: second argument, "
1464 "if any, must be 'strict'\n");
1468 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1469 (argc == 2) ? " strict" : "");
1470 if (res < 0 || (size_t) res >= sizeof(cmd))
1472 cmd[sizeof(cmd) - 1] = '\0';
1474 return wpa_ctrl_command(ctrl, cmd);
1478 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1480 printf("Available interfaces:\n");
1481 return wpa_ctrl_command(ctrl, "INTERFACES");
1485 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1488 wpa_cli_list_interfaces(ctrl);
1492 wpa_cli_close_connection();
1493 os_free(ctrl_ifname);
1494 ctrl_ifname = os_strdup(argv[0]);
1496 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1497 printf("Connected to interface '%s.\n", ctrl_ifname);
1499 printf("Could not connect to interface '%s' - re-trying\n",
1506 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1509 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1513 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1516 return wpa_ctrl_command(ctrl, "TERMINATE");
1520 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1527 printf("Invalid INTERFACE_ADD command: needs at least one "
1528 "argument (interface name)\n"
1529 "All arguments: ifname confname driver ctrl_interface "
1530 "driver_param bridge_name\n");
1535 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1536 * <driver_param>TAB<bridge_name>
1538 res = os_snprintf(cmd, sizeof(cmd),
1539 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1541 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1542 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1543 argc > 5 ? argv[5] : "");
1544 if (res < 0 || (size_t) res >= sizeof(cmd))
1546 cmd[sizeof(cmd) - 1] = '\0';
1547 return wpa_ctrl_command(ctrl, cmd);
1551 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1558 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1559 "(interface name)\n");
1563 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1564 if (res < 0 || (size_t) res >= sizeof(cmd))
1566 cmd[sizeof(cmd) - 1] = '\0';
1567 return wpa_ctrl_command(ctrl, cmd);
1571 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1574 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1579 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1583 printf("Invalid 'sta' command - exactly one argument, STA "
1584 "address, is required.\n");
1587 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1588 return wpa_ctrl_command(ctrl, buf);
1592 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1593 char *addr, size_t addr_len)
1595 char buf[4096], *pos;
1599 if (ctrl_conn == NULL) {
1600 printf("Not connected to hostapd - command dropped.\n");
1603 len = sizeof(buf) - 1;
1604 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1607 printf("'%s' command timed out.\n", cmd);
1609 } else if (ret < 0) {
1610 printf("'%s' command failed.\n", cmd);
1615 if (memcmp(buf, "FAIL", 4) == 0)
1620 while (*pos != '\0' && *pos != '\n')
1623 os_strlcpy(addr, buf, addr_len);
1628 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1630 char addr[32], cmd[64];
1632 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1635 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1636 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1640 #endif /* CONFIG_AP */
1643 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1645 return wpa_ctrl_command(ctrl, "SUSPEND");
1649 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1651 return wpa_ctrl_command(ctrl, "RESUME");
1655 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1657 return wpa_ctrl_command(ctrl, "DROP_SA");
1661 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1667 printf("Invalid ROAM command: needs one argument "
1668 "(target AP's BSSID)\n");
1672 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1673 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1674 printf("Too long ROAM command.\n");
1677 return wpa_ctrl_command(ctrl, cmd);
1683 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1689 return wpa_ctrl_command(ctrl, "P2P_FIND");
1692 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1695 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %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_stop_find(struct wpa_ctrl *ctrl, int argc,
1706 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1710 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1717 printf("Invalid P2P_CONNECT command: needs at least two "
1718 "arguments (address and pbc/PIN)\n");
1723 res = os_snprintf(cmd, sizeof(cmd),
1724 "P2P_CONNECT %s %s %s %s %s",
1725 argv[0], argv[1], argv[2], argv[3],
1728 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1729 argv[0], argv[1], argv[2], argv[3]);
1731 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1732 argv[0], argv[1], argv[2]);
1734 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1736 if (res < 0 || (size_t) res >= sizeof(cmd))
1738 cmd[sizeof(cmd) - 1] = '\0';
1739 return wpa_ctrl_command(ctrl, cmd);
1743 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1750 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1752 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1753 if (res < 0 || (size_t) res >= sizeof(cmd))
1755 cmd[sizeof(cmd) - 1] = '\0';
1756 return wpa_ctrl_command(ctrl, cmd);
1760 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1767 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1768 "(interface name)\n");
1772 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
1773 if (res < 0 || (size_t) res >= sizeof(cmd))
1775 cmd[sizeof(cmd) - 1] = '\0';
1776 return wpa_ctrl_command(ctrl, cmd);
1780 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1787 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
1789 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", argv[0]);
1790 if (res < 0 || (size_t) res >= sizeof(cmd))
1792 cmd[sizeof(cmd) - 1] = '\0';
1793 return wpa_ctrl_command(ctrl, cmd);
1797 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1804 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1805 "(address and config method\n"
1806 "(display, keypad, or pbc)\n");
1810 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
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_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1822 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1826 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1832 if (argc != 2 && argc != 4) {
1833 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1834 "arguments (address and TLVs) or four arguments "
1835 "(address, \"upnp\", version, search target "
1841 res = os_snprintf(cmd, sizeof(cmd),
1842 "P2P_SERV_DISC_REQ %s %s %s %s",
1843 argv[0], argv[1], argv[2], argv[3]);
1845 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
1847 if (res < 0 || (size_t) res >= sizeof(cmd))
1849 cmd[sizeof(cmd) - 1] = '\0';
1850 return wpa_ctrl_command(ctrl, cmd);
1854 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1855 int argc, char *argv[])
1861 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1862 "argument (pending request identifier)\n");
1866 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
1868 if (res < 0 || (size_t) res >= sizeof(cmd))
1870 cmd[sizeof(cmd) - 1] = '\0';
1871 return wpa_ctrl_command(ctrl, cmd);
1875 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1882 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1883 "arguments (freq, address, dialog token, and TLVs)\n");
1887 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1888 argv[0], argv[1], argv[2], argv[3]);
1889 if (res < 0 || (size_t) res >= sizeof(cmd))
1891 cmd[sizeof(cmd) - 1] = '\0';
1892 return wpa_ctrl_command(ctrl, cmd);
1896 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1899 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1903 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1904 int argc, char *argv[])
1910 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1911 "argument (external processing: 0/1)\n");
1915 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
1917 if (res < 0 || (size_t) res >= sizeof(cmd))
1919 cmd[sizeof(cmd) - 1] = '\0';
1920 return wpa_ctrl_command(ctrl, cmd);
1924 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1927 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1931 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1937 if (argc != 3 && argc != 4) {
1938 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1944 res = os_snprintf(cmd, sizeof(cmd),
1945 "P2P_SERVICE_ADD %s %s %s %s",
1946 argv[0], argv[1], argv[2], argv[3]);
1948 res = os_snprintf(cmd, sizeof(cmd),
1949 "P2P_SERVICE_ADD %s %s %s",
1950 argv[0], argv[1], argv[2]);
1951 if (res < 0 || (size_t) res >= sizeof(cmd))
1953 cmd[sizeof(cmd) - 1] = '\0';
1954 return wpa_ctrl_command(ctrl, cmd);
1958 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1964 if (argc != 2 && argc != 3) {
1965 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1971 res = os_snprintf(cmd, sizeof(cmd),
1972 "P2P_SERVICE_DEL %s %s %s",
1973 argv[0], argv[1], argv[2]);
1975 res = os_snprintf(cmd, sizeof(cmd),
1976 "P2P_SERVICE_DEL %s %s",
1978 if (res < 0 || (size_t) res >= sizeof(cmd))
1980 cmd[sizeof(cmd) - 1] = '\0';
1981 return wpa_ctrl_command(ctrl, cmd);
1985 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1986 int argc, char *argv[])
1992 printf("Invalid P2P_REJECT command: needs one argument "
1993 "(peer address)\n");
1997 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
1998 if (res < 0 || (size_t) res >= sizeof(cmd))
2000 cmd[sizeof(cmd) - 1] = '\0';
2001 return wpa_ctrl_command(ctrl, cmd);
2005 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2006 int argc, char *argv[])
2012 printf("Invalid P2P_INVITE command: needs at least one "
2018 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2019 argv[0], argv[1], argv[2]);
2021 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2024 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2025 if (res < 0 || (size_t) res >= sizeof(cmd))
2027 cmd[sizeof(cmd) - 1] = '\0';
2028 return wpa_ctrl_command(ctrl, cmd);
2032 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2036 printf("Invalid 'p2p_peer' command - exactly one argument, "
2037 "P2P peer device address, is required.\n");
2040 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2041 return wpa_ctrl_command(ctrl, buf);
2045 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2046 char *addr, size_t addr_len,
2049 char buf[4096], *pos;
2053 if (ctrl_conn == NULL)
2055 len = sizeof(buf) - 1;
2056 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2059 printf("'%s' command timed out.\n", cmd);
2061 } else if (ret < 0) {
2062 printf("'%s' command failed.\n", cmd);
2067 if (memcmp(buf, "FAIL", 4) == 0)
2071 while (*pos != '\0' && *pos != '\n')
2074 os_strlcpy(addr, buf, addr_len);
2075 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2076 printf("%s\n", addr);
2081 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2083 char addr[32], cmd[64];
2086 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2088 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2089 addr, sizeof(addr), discovered))
2092 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2093 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2100 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2106 printf("Invalid P2P_SET command: needs two arguments (field, "
2111 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2112 if (res < 0 || (size_t) res >= sizeof(cmd))
2114 cmd[sizeof(cmd) - 1] = '\0';
2115 return wpa_ctrl_command(ctrl, cmd);
2119 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2121 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2125 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2128 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2132 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2139 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2140 "(peer address)\n");
2144 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2146 if (res < 0 || (size_t) res >= sizeof(cmd))
2149 cmd[sizeof(cmd) - 1] = '\0';
2150 return wpa_ctrl_command(ctrl, cmd);
2154 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2160 if (argc != 0 && argc != 2 && argc != 4) {
2161 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2162 "(preferred duration, interval; in microsecods).\n"
2163 "Optional second pair can be used to provide "
2164 "acceptable values.\n");
2169 res = os_snprintf(cmd, sizeof(cmd),
2170 "P2P_PRESENCE_REQ %s %s %s %s",
2171 argv[0], argv[1], argv[2], argv[3]);
2173 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2176 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2177 if (res < 0 || (size_t) res >= sizeof(cmd))
2179 cmd[sizeof(cmd) - 1] = '\0';
2180 return wpa_ctrl_command(ctrl, cmd);
2184 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2190 if (argc != 0 && argc != 2) {
2191 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2192 "(availability period, availability interval; in "
2194 "Extended Listen Timing can be cancelled with this "
2195 "command when used without parameters.\n");
2200 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2203 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2204 if (res < 0 || (size_t) res >= sizeof(cmd))
2206 cmd[sizeof(cmd) - 1] = '\0';
2207 return wpa_ctrl_command(ctrl, cmd);
2210 #endif /* CONFIG_P2P */
2213 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2220 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2221 "(0/1 = disable/enable automatic reconnection)\n");
2224 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2225 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2226 printf("Too long STA_AUTOCONNECT command.\n");
2229 return wpa_ctrl_command(ctrl, cmd);
2233 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2240 printf("Invalid TDLS_DISCOVER command: needs one argument "
2241 "(Peer STA MAC address)\n");
2245 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2246 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2247 printf("Too long TDLS_DISCOVER command.\n");
2250 return wpa_ctrl_command(ctrl, cmd);
2254 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2261 printf("Invalid TDLS_SETUP command: needs one argument "
2262 "(Peer STA MAC address)\n");
2266 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2267 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2268 printf("Too long TDLS_SETUP command.\n");
2271 return wpa_ctrl_command(ctrl, cmd);
2275 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2282 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2283 "(Peer STA MAC address)\n");
2287 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2288 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2289 printf("Too long TDLS_TEARDOWN command.\n");
2292 return wpa_ctrl_command(ctrl, cmd);
2296 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2299 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2303 enum wpa_cli_cmd_flags {
2304 cli_cmd_flag_none = 0x00,
2305 cli_cmd_flag_sensitive = 0x01
2308 struct wpa_cli_cmd {
2310 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2311 enum wpa_cli_cmd_flags flags;
2315 static struct wpa_cli_cmd wpa_cli_commands[] = {
2316 { "status", wpa_cli_cmd_status,
2318 "[verbose] = get current WPA/EAPOL/EAP status" },
2319 { "ping", wpa_cli_cmd_ping,
2321 "= pings wpa_supplicant" },
2322 { "relog", wpa_cli_cmd_relog,
2324 "= re-open log-file (allow rolling logs)" },
2325 { "note", wpa_cli_cmd_note,
2327 "<text> = add a note to wpa_supplicant debug log" },
2328 { "mib", wpa_cli_cmd_mib,
2330 "= get MIB variables (dot1x, dot11)" },
2331 { "help", wpa_cli_cmd_help,
2333 "= show this usage help" },
2334 { "interface", wpa_cli_cmd_interface,
2336 "[ifname] = show interfaces/select interface" },
2337 { "level", wpa_cli_cmd_level,
2339 "<debug level> = change debug level" },
2340 { "license", wpa_cli_cmd_license,
2342 "= show full wpa_cli license" },
2343 { "quit", wpa_cli_cmd_quit,
2346 { "set", wpa_cli_cmd_set,
2348 "= set variables (shows list of variables when run without "
2350 { "get", wpa_cli_cmd_get,
2352 "<name> = get information" },
2353 { "logon", wpa_cli_cmd_logon,
2355 "= IEEE 802.1X EAPOL state machine logon" },
2356 { "logoff", wpa_cli_cmd_logoff,
2358 "= IEEE 802.1X EAPOL state machine logoff" },
2359 { "pmksa", wpa_cli_cmd_pmksa,
2361 "= show PMKSA cache" },
2362 { "reassociate", wpa_cli_cmd_reassociate,
2364 "= force reassociation" },
2365 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2367 "<BSSID> = force preauthentication" },
2368 { "identity", wpa_cli_cmd_identity,
2370 "<network id> <identity> = configure identity for an SSID" },
2371 { "password", wpa_cli_cmd_password,
2372 cli_cmd_flag_sensitive,
2373 "<network id> <password> = configure password for an SSID" },
2374 { "new_password", wpa_cli_cmd_new_password,
2375 cli_cmd_flag_sensitive,
2376 "<network id> <password> = change password for an SSID" },
2377 { "pin", wpa_cli_cmd_pin,
2378 cli_cmd_flag_sensitive,
2379 "<network id> <pin> = configure pin for an SSID" },
2380 { "otp", wpa_cli_cmd_otp,
2381 cli_cmd_flag_sensitive,
2382 "<network id> <password> = configure one-time-password for an SSID"
2384 { "passphrase", wpa_cli_cmd_passphrase,
2385 cli_cmd_flag_sensitive,
2386 "<network id> <passphrase> = configure private key passphrase\n"
2388 { "bssid", wpa_cli_cmd_bssid,
2390 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2391 { "list_networks", wpa_cli_cmd_list_networks,
2393 "= list configured networks" },
2394 { "select_network", wpa_cli_cmd_select_network,
2396 "<network id> = select a network (disable others)" },
2397 { "enable_network", wpa_cli_cmd_enable_network,
2399 "<network id> = enable a network" },
2400 { "disable_network", wpa_cli_cmd_disable_network,
2402 "<network id> = disable a network" },
2403 { "add_network", wpa_cli_cmd_add_network,
2405 "= add a network" },
2406 { "remove_network", wpa_cli_cmd_remove_network,
2408 "<network id> = remove a network" },
2409 { "set_network", wpa_cli_cmd_set_network,
2410 cli_cmd_flag_sensitive,
2411 "<network id> <variable> <value> = set network variables (shows\n"
2412 " list of variables when run without arguments)" },
2413 { "get_network", wpa_cli_cmd_get_network,
2415 "<network id> <variable> = get network variables" },
2416 { "save_config", wpa_cli_cmd_save_config,
2418 "= save the current configuration" },
2419 { "disconnect", wpa_cli_cmd_disconnect,
2421 "= disconnect and wait for reassociate/reconnect command before\n"
2423 { "reconnect", wpa_cli_cmd_reconnect,
2425 "= like reassociate, but only takes effect if already disconnected"
2427 { "scan", wpa_cli_cmd_scan,
2429 "= request new BSS scan" },
2430 { "scan_results", wpa_cli_cmd_scan_results,
2432 "= get latest scan results" },
2433 { "bss", wpa_cli_cmd_bss,
2435 "<<idx> | <bssid>> = get detailed scan result info" },
2436 { "get_capability", wpa_cli_cmd_get_capability,
2438 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2439 { "reconfigure", wpa_cli_cmd_reconfigure,
2441 "= force wpa_supplicant to re-read its configuration file" },
2442 { "terminate", wpa_cli_cmd_terminate,
2444 "= terminate wpa_supplicant" },
2445 { "interface_add", wpa_cli_cmd_interface_add,
2447 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2448 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2450 { "interface_remove", wpa_cli_cmd_interface_remove,
2452 "<ifname> = removes the interface" },
2453 { "interface_list", wpa_cli_cmd_interface_list,
2455 "= list available interfaces" },
2456 { "ap_scan", wpa_cli_cmd_ap_scan,
2458 "<value> = set ap_scan parameter" },
2459 { "scan_interval", wpa_cli_cmd_scan_interval,
2461 "<value> = set scan_interval parameter (in seconds)" },
2462 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2464 "<value> = set BSS expiration age parameter" },
2465 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2467 "<value> = set BSS expiration scan count parameter" },
2468 { "stkstart", wpa_cli_cmd_stkstart,
2470 "<addr> = request STK negotiation with <addr>" },
2471 { "ft_ds", wpa_cli_cmd_ft_ds,
2473 "<addr> = request over-the-DS FT with <addr>" },
2474 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2476 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2477 { "wps_pin", wpa_cli_cmd_wps_pin,
2478 cli_cmd_flag_sensitive,
2479 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2481 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2482 cli_cmd_flag_sensitive,
2483 "<PIN> = verify PIN checksum" },
2484 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2485 "Cancels the pending WPS operation" },
2486 #ifdef CONFIG_WPS_OOB
2487 { "wps_oob", wpa_cli_cmd_wps_oob,
2488 cli_cmd_flag_sensitive,
2489 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2490 #endif /* CONFIG_WPS_OOB */
2491 { "wps_reg", wpa_cli_cmd_wps_reg,
2492 cli_cmd_flag_sensitive,
2493 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2494 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2495 cli_cmd_flag_sensitive,
2496 "[params..] = enable/disable AP PIN" },
2497 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2499 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2500 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2502 "= stop Wi-Fi Protected Setup External Registrar" },
2503 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2504 cli_cmd_flag_sensitive,
2505 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2506 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2508 "<UUID> = accept an Enrollee PBC using External Registrar" },
2509 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2510 cli_cmd_flag_sensitive,
2511 "<UUID> <PIN> = learn AP configuration" },
2512 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2514 "<UUID> <network id> = set AP configuration for enrolling" },
2515 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2516 cli_cmd_flag_sensitive,
2517 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2518 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2520 "<addr> = request RSN authentication with <addr> in IBSS" },
2522 { "sta", wpa_cli_cmd_sta,
2524 "<addr> = get information about an associated station (AP)" },
2525 { "all_sta", wpa_cli_cmd_all_sta,
2527 "= get information about all associated stations (AP)" },
2528 #endif /* CONFIG_AP */
2529 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2530 "= notification of suspend/hibernate" },
2531 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2532 "= notification of resume/thaw" },
2533 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2534 "= drop SA without deauth/disassoc (test command)" },
2535 { "roam", wpa_cli_cmd_roam,
2537 "<addr> = roam to the specified BSS" },
2539 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2540 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2541 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2542 "= stop P2P Devices search" },
2543 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2544 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2545 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2546 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2547 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2548 "<ifname> = remove P2P group interface (terminate group if GO)" },
2549 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2550 "= add a new P2P group (local end as GO)" },
2551 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2552 "<addr> <method> = request provisioning discovery" },
2553 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2555 "= get the passphrase for a group (GO only)" },
2556 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2558 "<addr> <TLVs> = schedule service discovery request" },
2559 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2561 "<id> = cancel pending service discovery request" },
2562 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2564 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2565 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2567 "= indicate change in local services" },
2568 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2570 "<external> = set external processing of service discovery" },
2571 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2573 "= remove all stored service entries" },
2574 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2576 "<bonjour|upnp> <query|version> <response|service> = add a local "
2578 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2580 "<bonjour|upnp> <query|version> [|service] = remove a local "
2582 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2584 "<addr> = reject connection attempts from a specific peer" },
2585 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2587 "<cmd> [peer=addr] = invite peer" },
2588 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2589 "[discovered] = list known (optionally, only fully discovered) P2P "
2591 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2592 "<address> = show information about known P2P peer" },
2593 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2594 "<field> <value> = set a P2P parameter" },
2595 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2596 "= flush P2P state" },
2597 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2598 "= cancel P2P group formation" },
2599 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2600 "<address> = unauthorize a peer" },
2601 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2602 "[<duration> <interval>] [<duration> <interval>] = request GO "
2604 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2605 "[<period> <interval>] = set extended listen timing" },
2606 #endif /* CONFIG_P2P */
2607 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2608 "<0/1> = disable/enable automatic reconnection" },
2609 { "tdls_discover", wpa_cli_cmd_tdls_discover,
2611 "<addr> = request TDLS discovery with <addr>" },
2612 { "tdls_setup", wpa_cli_cmd_tdls_setup,
2614 "<addr> = request TDLS setup with <addr>" },
2615 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
2617 "<addr> = tear down TDLS with <addr>" },
2618 { "signal_poll", wpa_cli_cmd_signal_poll,
2620 "= get signal parameters" },
2621 { NULL, NULL, cli_cmd_flag_none, NULL }
2626 * Prints command usage, lines are padded with the specified string.
2628 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2633 printf("%s%s ", pad, cmd->cmd);
2634 for (n = 0; (c = cmd->usage[n]); n++) {
2643 static void print_help(void)
2646 printf("commands:\n");
2647 for (n = 0; wpa_cli_commands[n].cmd; n++)
2648 print_cmd_help(&wpa_cli_commands[n], " ");
2652 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2654 const char *c, *delim;
2658 delim = os_strchr(cmd, ' ');
2662 len = os_strlen(cmd);
2664 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2665 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2666 return (wpa_cli_commands[n].flags &
2667 cli_cmd_flag_sensitive);
2673 static char ** wpa_list_cmd_list(void)
2678 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2679 res = os_zalloc(count * sizeof(char *));
2683 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2684 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2693 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2698 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2699 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2701 printf("\r%s\n", wpa_cli_commands[i].usage);
2711 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2717 end = os_strchr(str, ' ');
2718 if (end == NULL || str + pos < end)
2719 return wpa_list_cmd_list();
2721 cmd = os_malloc(pos + 1);
2724 os_memcpy(cmd, str, pos);
2725 cmd[end - str] = '\0';
2726 res = wpa_cli_cmd_completion(cmd, str, pos);
2732 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2734 struct wpa_cli_cmd *cmd, *match = NULL;
2739 cmd = wpa_cli_commands;
2741 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2744 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2745 /* we have an exact match */
2755 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2756 cmd = wpa_cli_commands;
2758 if (os_strncasecmp(cmd->cmd, argv[0],
2759 os_strlen(argv[0])) == 0) {
2760 printf(" %s", cmd->cmd);
2766 } else if (count == 0) {
2767 printf("Unknown command '%s'\n", argv[0]);
2770 ret = match->handler(ctrl, argc - 1, &argv[1]);
2777 static int str_match(const char *a, const char *b)
2779 return os_strncmp(a, b, os_strlen(b)) == 0;
2783 static int wpa_cli_exec(const char *program, const char *arg1,
2791 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2792 cmd = os_malloc(len);
2795 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2796 if (res < 0 || (size_t) res >= len) {
2800 cmd[len - 1] = '\0';
2802 if (system(cmd) < 0)
2804 #endif /* _WIN32_WCE */
2811 static void wpa_cli_action_process(const char *msg)
2814 char *copy = NULL, *id, *pos2;
2819 pos = os_strchr(pos, '>');
2826 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2828 os_unsetenv("WPA_ID");
2829 os_unsetenv("WPA_ID_STR");
2830 os_unsetenv("WPA_CTRL_DIR");
2832 pos = os_strstr(pos, "[id=");
2834 copy = os_strdup(pos + 4);
2838 while (*pos2 && *pos2 != ' ')
2842 os_setenv("WPA_ID", id, 1);
2843 while (*pos2 && *pos2 != '=')
2848 while (*pos2 && *pos2 != ']')
2851 os_setenv("WPA_ID_STR", id, 1);
2855 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2857 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2858 wpa_cli_connected = 1;
2859 wpa_cli_last_id = new_id;
2860 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2862 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2863 if (wpa_cli_connected) {
2864 wpa_cli_connected = 0;
2865 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2867 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2868 wpa_cli_exec(action_file, ctrl_ifname, pos);
2869 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2870 wpa_cli_exec(action_file, ctrl_ifname, pos);
2871 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2872 wpa_cli_exec(action_file, ctrl_ifname, pos);
2873 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2874 wpa_cli_exec(action_file, ctrl_ifname, pos);
2875 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2876 wpa_cli_exec(action_file, ctrl_ifname, pos);
2877 } else if (str_match(pos, WPS_EVENT_FAIL)) {
2878 wpa_cli_exec(action_file, ctrl_ifname, pos);
2879 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2880 printf("wpa_supplicant is terminating - stop monitoring\n");
2886 #ifndef CONFIG_ANSI_C_EXTRA
2887 static void wpa_cli_action_cb(char *msg, size_t len)
2889 wpa_cli_action_process(msg);
2891 #endif /* CONFIG_ANSI_C_EXTRA */
2894 static void wpa_cli_reconnect(void)
2896 wpa_cli_close_connection();
2897 wpa_cli_open_connection(ctrl_ifname, 1);
2901 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
2903 if (ctrl_conn == NULL) {
2904 wpa_cli_reconnect();
2907 while (wpa_ctrl_pending(ctrl) > 0) {
2909 size_t len = sizeof(buf) - 1;
2910 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2913 wpa_cli_action_process(buf);
2915 if (wpa_cli_show_event(buf)) {
2917 printf("\r%s\n", buf);
2922 printf("Could not read pending message.\n");
2927 if (wpa_ctrl_pending(ctrl) < 0) {
2928 printf("Connection to wpa_supplicant lost - trying to "
2930 wpa_cli_reconnect();
2936 static int tokenize_cmd(char *cmd, char *argv[])
2949 if (argc == max_args)
2952 char *pos2 = os_strrchr(pos, '"');
2956 while (*pos != '\0' && *pos != ' ')
2966 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
2968 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2969 printf("Connection to wpa_supplicant lost - trying to "
2971 wpa_cli_close_connection();
2974 wpa_cli_reconnect();
2975 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
2979 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
2985 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
2987 wpa_cli_recv_pending(mon_conn, 0);
2991 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
2993 char *argv[max_args];
2995 argc = tokenize_cmd(cmd, argv);
2997 wpa_request(ctrl_conn, argc, argv);
3001 static void wpa_cli_edit_eof_cb(void *ctx)
3007 static void wpa_cli_interactive(void)
3009 char *home, *hfile = NULL;
3011 printf("\nInteractive mode\n\n");
3013 home = getenv("HOME");
3015 const char *fname = ".wpa_cli_history";
3016 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3017 hfile = os_malloc(hfile_len);
3019 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3022 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3023 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3024 wpa_cli_edit_completion_cb, NULL, hfile);
3025 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3029 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3031 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3032 wpa_cli_close_connection();
3036 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3038 #ifdef CONFIG_ANSI_C_EXTRA
3039 /* TODO: ANSI C version(?) */
3040 printf("Action processing not supported in ANSI C build.\n");
3041 #else /* CONFIG_ANSI_C_EXTRA */
3045 char buf[256]; /* note: large enough to fit in unsolicited messages */
3048 fd = wpa_ctrl_get_fd(ctrl);
3050 while (!wpa_cli_quit) {
3053 tv.tv_sec = ping_interval;
3055 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3056 if (res < 0 && errno != EINTR) {
3061 if (FD_ISSET(fd, &rfds))
3062 wpa_cli_recv_pending(ctrl, 1);
3064 /* verify that connection is still working */
3065 len = sizeof(buf) - 1;
3066 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3067 wpa_cli_action_cb) < 0 ||
3068 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3069 printf("wpa_supplicant did not reply to PING "
3070 "command - exiting\n");
3075 #endif /* CONFIG_ANSI_C_EXTRA */
3079 static void wpa_cli_cleanup(void)
3081 wpa_cli_close_connection();
3083 os_daemonize_terminate(pid_file);
3085 os_program_deinit();
3088 static void wpa_cli_terminate(int sig)
3095 static char * wpa_cli_get_default_ifname(void)
3097 char *ifname = NULL;
3099 #ifdef CONFIG_CTRL_IFACE_UNIX
3100 struct dirent *dent;
3101 DIR *dir = opendir(ctrl_iface_dir);
3104 char ifprop[PROPERTY_VALUE_MAX];
3105 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3106 ifname = os_strdup(ifprop);
3107 printf("Using interface '%s'\n", ifname);
3110 #endif /* ANDROID */
3113 while ((dent = readdir(dir))) {
3114 #ifdef _DIRENT_HAVE_D_TYPE
3116 * Skip the file if it is not a socket. Also accept
3117 * DT_UNKNOWN (0) in case the C library or underlying
3118 * file system does not support d_type.
3120 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3122 #endif /* _DIRENT_HAVE_D_TYPE */
3123 if (os_strcmp(dent->d_name, ".") == 0 ||
3124 os_strcmp(dent->d_name, "..") == 0)
3126 printf("Selected interface '%s'\n", dent->d_name);
3127 ifname = os_strdup(dent->d_name);
3131 #endif /* CONFIG_CTRL_IFACE_UNIX */
3133 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3134 char buf[2048], *pos;
3136 struct wpa_ctrl *ctrl;
3139 ctrl = wpa_ctrl_open(NULL);
3143 len = sizeof(buf) - 1;
3144 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3147 pos = os_strchr(buf, '\n');
3150 ifname = os_strdup(buf);
3152 wpa_ctrl_close(ctrl);
3153 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3159 int main(int argc, char *argv[])
3161 int warning_displayed = 0;
3165 const char *global = NULL;
3167 if (os_program_init())
3171 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3176 action_file = optarg;
3185 ping_interval = atoi(optarg);
3191 printf("%s\n", wpa_cli_version);
3194 os_free(ctrl_ifname);
3195 ctrl_ifname = os_strdup(optarg);
3198 ctrl_iface_dir = optarg;
3209 interactive = (argc == optind) && (action_file == NULL);
3212 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3218 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3219 ctrl_conn = wpa_ctrl_open(NULL);
3220 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3221 ctrl_conn = wpa_ctrl_open(global);
3222 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3223 if (ctrl_conn == NULL) {
3224 perror("Failed to connect to wpa_supplicant - "
3231 signal(SIGINT, wpa_cli_terminate);
3232 signal(SIGTERM, wpa_cli_terminate);
3233 #endif /* _WIN32_WCE */
3235 if (ctrl_ifname == NULL)
3236 ctrl_ifname = wpa_cli_get_default_ifname();
3240 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3241 if (warning_displayed)
3242 printf("Connection established.\n");
3246 if (!warning_displayed) {
3247 printf("Could not connect to wpa_supplicant - "
3249 warning_displayed = 1;
3256 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3257 perror("Failed to connect to wpa_supplicant - "
3263 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3264 wpa_cli_attached = 1;
3266 printf("Warning: Failed to attach to "
3267 "wpa_supplicant.\n");
3273 if (daemonize && os_daemonize(pid_file))
3277 wpa_cli_interactive();
3278 else if (action_file)
3279 wpa_cli_action(ctrl_conn);
3281 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3283 os_free(ctrl_ifname);
3290 #else /* CONFIG_CTRL_IFACE */
3291 int main(int argc, char *argv[])
3293 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3296 #endif /* CONFIG_CTRL_IFACE */