2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
22 #ifdef CONFIG_READLINE
23 #include <readline/readline.h>
24 #include <readline/history.h>
25 #endif /* CONFIG_READLINE */
27 #include "common/wpa_ctrl.h"
28 #include "utils/common.h"
29 #include "utils/eloop.h"
30 #include "utils/edit.h"
31 #include "common/version.h"
34 static const char *wpa_cli_version =
35 "wpa_cli v" VERSION_STR "\n"
36 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
39 static const char *wpa_cli_license =
40 "This program is free software. You can distribute it and/or modify it\n"
41 "under the terms of the GNU General Public License version 2.\n"
43 "Alternatively, this software may be distributed under the terms of the\n"
44 "BSD license. See README and COPYING for more details.\n";
46 static const char *wpa_cli_full_license =
47 "This program is free software; you can redistribute it and/or modify\n"
48 "it under the terms of the GNU General Public License version 2 as\n"
49 "published by the Free Software Foundation.\n"
51 "This program is distributed in the hope that it will be useful,\n"
52 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
53 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
54 "GNU General Public License for more details.\n"
56 "You should have received a copy of the GNU General Public License\n"
57 "along with this program; if not, write to the Free Software\n"
58 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
60 "Alternatively, this software may be distributed under the terms of the\n"
63 "Redistribution and use in source and binary forms, with or without\n"
64 "modification, are permitted provided that the following conditions are\n"
67 "1. Redistributions of source code must retain the above copyright\n"
68 " notice, this list of conditions and the following disclaimer.\n"
70 "2. Redistributions in binary form must reproduce the above copyright\n"
71 " notice, this list of conditions and the following disclaimer in the\n"
72 " documentation and/or other materials provided with the distribution.\n"
74 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
75 " names of its contributors may be used to endorse or promote products\n"
76 " derived from this software without specific prior written permission.\n"
78 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
79 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
80 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
81 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
82 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
83 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
84 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
85 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
86 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
87 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
88 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
91 static struct wpa_ctrl *ctrl_conn;
92 static struct wpa_ctrl *mon_conn;
93 static int wpa_cli_quit = 0;
94 static int wpa_cli_attached = 0;
95 static int wpa_cli_connected = 0;
96 static int wpa_cli_last_id = 0;
97 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
98 static char *ctrl_ifname = NULL;
99 static const char *pid_file = NULL;
100 static const char *action_file = NULL;
101 static int ping_interval = 5;
102 static int interactive = 0;
105 static void print_help(void);
106 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
109 static void usage(void)
111 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
112 "[-a<action file>] \\\n"
113 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
115 " -h = help (show this usage text)\n"
116 " -v = shown version information\n"
117 " -a = run in daemon mode executing the action file based on "
120 " -B = run a daemon in the background\n"
121 " default path: /var/run/wpa_supplicant\n"
122 " default interface: first interface found in socket path\n");
127 static void readline_redraw()
129 #ifdef CONFIG_READLINE
132 #else /* CONFIG_READLINE */
134 #endif /* CONFIG_READLINE */
138 static int str_starts(const char *src, const char *match)
140 return os_strncmp(src, match, os_strlen(match)) == 0;
144 static int wpa_cli_show_event(const char *event)
148 start = os_strchr(event, '>');
154 * Skip BSS added/removed events since they can be relatively frequent
155 * and are likely of not much use for an interactive user.
157 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
158 str_starts(start, WPA_EVENT_BSS_REMOVED))
165 static int wpa_cli_open_connection(const char *ifname, int attach)
167 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
168 ctrl_conn = wpa_ctrl_open(ifname);
169 if (ctrl_conn == NULL)
172 if (attach && interactive)
173 mon_conn = wpa_ctrl_open(ifname);
176 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
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, ifname);
188 if (res < 0 || res >= flen) {
193 ctrl_conn = wpa_ctrl_open(cfile);
194 if (ctrl_conn == NULL) {
199 if (attach && interactive)
200 mon_conn = wpa_ctrl_open(cfile);
204 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
207 if (wpa_ctrl_attach(mon_conn) == 0) {
208 wpa_cli_attached = 1;
210 eloop_register_read_sock(
211 wpa_ctrl_get_fd(mon_conn),
212 wpa_cli_mon_receive, NULL, NULL);
214 printf("Warning: Failed to attach to "
215 "wpa_supplicant.\n");
224 static void wpa_cli_close_connection(void)
226 if (ctrl_conn == NULL)
229 if (wpa_cli_attached) {
230 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
231 wpa_cli_attached = 0;
233 wpa_ctrl_close(ctrl_conn);
236 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
237 wpa_ctrl_close(mon_conn);
243 static void wpa_cli_msg_cb(char *msg, size_t len)
249 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
255 if (ctrl_conn == NULL) {
256 printf("Not connected to wpa_supplicant - command dropped.\n");
259 len = sizeof(buf) - 1;
260 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
263 printf("'%s' command timed out.\n", cmd);
265 } else if (ret < 0) {
266 printf("'%s' command failed.\n", cmd);
277 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
279 return _wpa_ctrl_command(ctrl, cmd, 1);
283 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
285 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
286 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
290 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
292 return wpa_ctrl_command(ctrl, "PING");
296 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
302 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
303 if (ret < 0 || (size_t) ret >= sizeof(cmd))
305 return wpa_ctrl_command(ctrl, cmd);
309 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
311 return wpa_ctrl_command(ctrl, "MIB");
315 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
317 return wpa_ctrl_command(ctrl, "PMKSA");
321 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
328 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
330 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
335 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
344 static void wpa_cli_show_variables(void)
346 printf("set variables:\n"
347 " EAPOL::heldPeriod (EAPOL state machine held period, "
349 " EAPOL::authPeriod (EAPOL state machine authentication "
350 "period, in seconds)\n"
351 " EAPOL::startPeriod (EAPOL state machine start period, in "
353 " EAPOL::maxStart (EAPOL state machine maximum start "
355 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
357 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
358 " threshold\n\tpercentage)\n"
359 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
360 "security\n\tassociation in seconds)\n");
364 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
370 wpa_cli_show_variables();
375 printf("Invalid SET command: needs two arguments (variable "
376 "name and value)\n");
380 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
381 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
382 printf("Too long SET command.\n");
385 return wpa_ctrl_command(ctrl, cmd);
389 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
395 printf("Invalid GET command: need one argument (variable "
400 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
401 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
402 printf("Too long GET command.\n");
405 return wpa_ctrl_command(ctrl, cmd);
409 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
411 return wpa_ctrl_command(ctrl, "LOGOFF");
415 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
417 return wpa_ctrl_command(ctrl, "LOGON");
421 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
424 return wpa_ctrl_command(ctrl, "REASSOCIATE");
428 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
435 printf("Invalid PREAUTH command: needs one argument "
440 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
441 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
442 printf("Too long PREAUTH command.\n");
445 return wpa_ctrl_command(ctrl, cmd);
449 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
455 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
459 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
460 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
461 printf("Too long AP_SCAN command.\n");
464 return wpa_ctrl_command(ctrl, cmd);
468 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
475 printf("Invalid STKSTART command: needs one argument "
476 "(Peer STA MAC address)\n");
480 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
481 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
482 printf("Too long STKSTART command.\n");
485 return wpa_ctrl_command(ctrl, cmd);
489 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
495 printf("Invalid FT_DS command: needs one argument "
496 "(Target AP MAC address)\n");
500 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
501 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
502 printf("Too long FT_DS command.\n");
505 return wpa_ctrl_command(ctrl, cmd);
509 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
516 return wpa_ctrl_command(ctrl, "WPS_PBC");
520 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
521 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
522 printf("Too long WPS_PBC command.\n");
525 return wpa_ctrl_command(ctrl, cmd);
529 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
535 printf("Invalid WPS_PIN command: need one or two arguments:\n"
536 "- BSSID: use 'any' to select any\n"
537 "- PIN: optional, used only with devices that have no "
543 /* Use dynamically generated PIN (returned as reply) */
544 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
545 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
546 printf("Too long WPS_PIN command.\n");
549 return wpa_ctrl_command(ctrl, cmd);
552 /* Use hardcoded PIN from a label */
553 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
554 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
555 printf("Too long WPS_PIN command.\n");
558 return wpa_ctrl_command(ctrl, cmd);
562 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
568 if (argc != 1 && argc != 2) {
569 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
570 "- PIN to be verified\n");
575 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
578 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
580 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
581 printf("Too long WPS_CHECK_PIN command.\n");
584 return wpa_ctrl_command(ctrl, cmd);
588 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
591 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
595 #ifdef CONFIG_WPS_OOB
596 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
601 if (argc != 3 && argc != 4) {
602 printf("Invalid WPS_OOB command: need three or four "
604 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
605 "- PATH: path of OOB device like '/mnt'\n"
606 "- METHOD: OOB method 'pin-e' or 'pin-r', "
608 "- DEV_NAME: (only for NFC) device name like "
614 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
615 argv[0], argv[1], argv[2]);
617 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
618 argv[0], argv[1], argv[2], argv[3]);
619 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
620 printf("Too long WPS_OOB command.\n");
623 return wpa_ctrl_command(ctrl, cmd);
625 #endif /* CONFIG_WPS_OOB */
628 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
634 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
636 else if (argc == 5 || argc == 6) {
637 char ssid_hex[2 * 32 + 1];
638 char key_hex[2 * 64 + 1];
642 for (i = 0; i < 32; i++) {
643 if (argv[2][i] == '\0')
645 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
650 for (i = 0; i < 64; i++) {
651 if (argv[5][i] == '\0')
653 os_snprintf(&key_hex[i * 2], 3, "%02x",
658 res = os_snprintf(cmd, sizeof(cmd),
659 "WPS_REG %s %s %s %s %s %s",
660 argv[0], argv[1], ssid_hex, argv[3], argv[4],
663 printf("Invalid WPS_REG command: need two arguments:\n"
664 "- BSSID of the target AP\n"
666 printf("Alternatively, six arguments can be used to "
667 "reconfigure the AP:\n"
668 "- BSSID of the target AP\n"
671 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
672 "- new encr (NONE, WEP, TKIP, CCMP)\n"
677 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
678 printf("Too long WPS_REG command.\n");
681 return wpa_ctrl_command(ctrl, cmd);
685 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
690 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
691 return wpa_ctrl_command(ctrl, cmd);
693 return wpa_ctrl_command(ctrl, "WPS_ER_START");
697 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
700 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
705 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
712 printf("Invalid WPS_ER_PIN command: need at least two "
714 "- UUID: use 'any' to select any\n"
715 "- PIN: Enrollee PIN\n"
716 "optional: - Enrollee MAC address\n");
721 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
722 argv[0], argv[1], argv[2]);
724 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
726 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
727 printf("Too long WPS_ER_PIN command.\n");
730 return wpa_ctrl_command(ctrl, cmd);
734 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
741 printf("Invalid WPS_ER_PBC command: need one argument:\n"
742 "- UUID: Specify the Enrollee\n");
746 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
748 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
749 printf("Too long WPS_ER_PBC command.\n");
752 return wpa_ctrl_command(ctrl, cmd);
756 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
763 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
764 "- UUID: specify which AP to use\n"
769 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
771 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
772 printf("Too long WPS_ER_LEARN command.\n");
775 return wpa_ctrl_command(ctrl, cmd);
779 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
786 printf("Invalid WPS_ER_SET_CONFIG command: need two "
788 "- UUID: specify which AP to use\n"
789 "- Network configuration id\n");
793 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
795 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
796 printf("Too long WPS_ER_SET_CONFIG command.\n");
799 return wpa_ctrl_command(ctrl, cmd);
803 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
809 if (argc == 5 || argc == 6) {
810 char ssid_hex[2 * 32 + 1];
811 char key_hex[2 * 64 + 1];
815 for (i = 0; i < 32; i++) {
816 if (argv[2][i] == '\0')
818 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
823 for (i = 0; i < 64; i++) {
824 if (argv[5][i] == '\0')
826 os_snprintf(&key_hex[i * 2], 3, "%02x",
831 res = os_snprintf(cmd, sizeof(cmd),
832 "WPS_ER_CONFIG %s %s %s %s %s %s",
833 argv[0], argv[1], ssid_hex, argv[3], argv[4],
836 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
840 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
841 "- new encr (NONE, WEP, TKIP, CCMP)\n"
846 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
847 printf("Too long WPS_ER_CONFIG command.\n");
850 return wpa_ctrl_command(ctrl, cmd);
854 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
860 printf("Invalid IBSS_RSN command: needs one argument "
861 "(Peer STA MAC address)\n");
865 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
866 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
867 printf("Too long IBSS_RSN command.\n");
870 return wpa_ctrl_command(ctrl, cmd);
874 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
880 printf("Invalid LEVEL command: needs one argument (debug "
884 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
885 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
886 printf("Too long LEVEL command.\n");
889 return wpa_ctrl_command(ctrl, cmd);
893 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
895 char cmd[256], *pos, *end;
899 printf("Invalid IDENTITY command: needs two arguments "
900 "(network id and identity)\n");
904 end = cmd + sizeof(cmd);
906 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
908 if (ret < 0 || ret >= end - pos) {
909 printf("Too long IDENTITY command.\n");
913 for (i = 2; i < argc; i++) {
914 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
915 if (ret < 0 || ret >= end - pos) {
916 printf("Too long IDENTITY command.\n");
922 return wpa_ctrl_command(ctrl, cmd);
926 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
928 char cmd[256], *pos, *end;
932 printf("Invalid PASSWORD command: needs two arguments "
933 "(network id and password)\n");
937 end = cmd + sizeof(cmd);
939 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
941 if (ret < 0 || ret >= end - pos) {
942 printf("Too long PASSWORD command.\n");
946 for (i = 2; i < argc; i++) {
947 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
948 if (ret < 0 || ret >= end - pos) {
949 printf("Too long PASSWORD command.\n");
955 return wpa_ctrl_command(ctrl, cmd);
959 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
962 char cmd[256], *pos, *end;
966 printf("Invalid NEW_PASSWORD command: needs two arguments "
967 "(network id and password)\n");
971 end = cmd + sizeof(cmd);
973 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
975 if (ret < 0 || ret >= end - pos) {
976 printf("Too long NEW_PASSWORD command.\n");
980 for (i = 2; i < argc; i++) {
981 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
982 if (ret < 0 || ret >= end - pos) {
983 printf("Too long NEW_PASSWORD command.\n");
989 return wpa_ctrl_command(ctrl, cmd);
993 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
995 char cmd[256], *pos, *end;
999 printf("Invalid PIN command: needs two arguments "
1000 "(network id and pin)\n");
1004 end = cmd + sizeof(cmd);
1006 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1008 if (ret < 0 || ret >= end - pos) {
1009 printf("Too long PIN command.\n");
1013 for (i = 2; i < argc; i++) {
1014 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1015 if (ret < 0 || ret >= end - pos) {
1016 printf("Too long PIN command.\n");
1021 return wpa_ctrl_command(ctrl, cmd);
1025 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1027 char cmd[256], *pos, *end;
1031 printf("Invalid OTP command: needs two arguments (network "
1032 "id and password)\n");
1036 end = cmd + sizeof(cmd);
1038 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1040 if (ret < 0 || ret >= end - pos) {
1041 printf("Too long OTP 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 OTP command.\n");
1054 return wpa_ctrl_command(ctrl, cmd);
1058 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1061 char cmd[256], *pos, *end;
1065 printf("Invalid PASSPHRASE command: needs two arguments "
1066 "(network id and passphrase)\n");
1070 end = cmd + sizeof(cmd);
1072 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1074 if (ret < 0 || ret >= end - pos) {
1075 printf("Too long PASSPHRASE 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 PASSPHRASE command.\n");
1088 return wpa_ctrl_command(ctrl, cmd);
1092 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1094 char cmd[256], *pos, *end;
1098 printf("Invalid BSSID command: needs two arguments (network "
1103 end = cmd + sizeof(cmd);
1105 ret = os_snprintf(pos, end - pos, "BSSID");
1106 if (ret < 0 || ret >= end - pos) {
1107 printf("Too long BSSID command.\n");
1111 for (i = 0; i < argc; i++) {
1112 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1113 if (ret < 0 || ret >= end - pos) {
1114 printf("Too long BSSID command.\n");
1120 return wpa_ctrl_command(ctrl, cmd);
1124 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1127 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1131 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1138 printf("Invalid SELECT_NETWORK command: needs one argument "
1143 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1144 if (res < 0 || (size_t) res >= sizeof(cmd))
1146 cmd[sizeof(cmd) - 1] = '\0';
1148 return wpa_ctrl_command(ctrl, cmd);
1152 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1159 printf("Invalid ENABLE_NETWORK command: needs one argument "
1164 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1165 if (res < 0 || (size_t) res >= sizeof(cmd))
1167 cmd[sizeof(cmd) - 1] = '\0';
1169 return wpa_ctrl_command(ctrl, cmd);
1173 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1180 printf("Invalid DISABLE_NETWORK command: needs one argument "
1185 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1186 if (res < 0 || (size_t) res >= sizeof(cmd))
1188 cmd[sizeof(cmd) - 1] = '\0';
1190 return wpa_ctrl_command(ctrl, cmd);
1194 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1197 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1201 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1208 printf("Invalid REMOVE_NETWORK command: needs one argument "
1213 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1214 if (res < 0 || (size_t) res >= sizeof(cmd))
1216 cmd[sizeof(cmd) - 1] = '\0';
1218 return wpa_ctrl_command(ctrl, cmd);
1222 static void wpa_cli_show_network_variables(void)
1224 printf("set_network variables:\n"
1225 " ssid (network name, SSID)\n"
1226 " psk (WPA passphrase or pre-shared key)\n"
1227 " key_mgmt (key management protocol)\n"
1228 " identity (EAP identity)\n"
1229 " password (EAP password)\n"
1232 "Note: Values are entered in the same format as the "
1233 "configuration file is using,\n"
1234 "i.e., strings values need to be inside double quotation "
1236 "For example: set_network 1 ssid \"network name\"\n"
1238 "Please see wpa_supplicant.conf documentation for full list "
1239 "of\navailable variables.\n");
1243 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1250 wpa_cli_show_network_variables();
1255 printf("Invalid SET_NETWORK command: needs three arguments\n"
1256 "(network id, variable name, and value)\n");
1260 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1261 argv[0], argv[1], argv[2]);
1262 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1263 printf("Too long SET_NETWORK command.\n");
1266 return wpa_ctrl_command(ctrl, cmd);
1270 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1277 wpa_cli_show_network_variables();
1282 printf("Invalid GET_NETWORK command: needs two arguments\n"
1283 "(network id and variable name)\n");
1287 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1289 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1290 printf("Too long GET_NETWORK command.\n");
1293 return wpa_ctrl_command(ctrl, cmd);
1297 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1300 return wpa_ctrl_command(ctrl, "DISCONNECT");
1304 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1307 return wpa_ctrl_command(ctrl, "RECONNECT");
1311 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1314 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1318 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1320 return wpa_ctrl_command(ctrl, "SCAN");
1324 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1327 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1331 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1337 printf("Invalid BSS command: need one argument (index or "
1342 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1343 if (res < 0 || (size_t) res >= sizeof(cmd))
1345 cmd[sizeof(cmd) - 1] = '\0';
1347 return wpa_ctrl_command(ctrl, cmd);
1351 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1357 if (argc < 1 || argc > 2) {
1358 printf("Invalid GET_CAPABILITY command: need either one or "
1363 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1364 printf("Invalid GET_CAPABILITY command: second argument, "
1365 "if any, must be 'strict'\n");
1369 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1370 (argc == 2) ? " strict" : "");
1371 if (res < 0 || (size_t) res >= sizeof(cmd))
1373 cmd[sizeof(cmd) - 1] = '\0';
1375 return wpa_ctrl_command(ctrl, cmd);
1379 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1381 printf("Available interfaces:\n");
1382 return wpa_ctrl_command(ctrl, "INTERFACES");
1386 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1389 wpa_cli_list_interfaces(ctrl);
1393 wpa_cli_close_connection();
1394 os_free(ctrl_ifname);
1395 ctrl_ifname = os_strdup(argv[0]);
1397 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1398 printf("Connected to interface '%s.\n", ctrl_ifname);
1400 printf("Could not connect to interface '%s' - re-trying\n",
1407 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1410 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1414 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1417 return wpa_ctrl_command(ctrl, "TERMINATE");
1421 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1428 printf("Invalid INTERFACE_ADD command: needs at least one "
1429 "argument (interface name)\n"
1430 "All arguments: ifname confname driver ctrl_interface "
1431 "driver_param bridge_name\n");
1436 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1437 * <driver_param>TAB<bridge_name>
1439 res = os_snprintf(cmd, sizeof(cmd),
1440 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1442 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1443 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1444 argc > 5 ? argv[5] : "");
1445 if (res < 0 || (size_t) res >= sizeof(cmd))
1447 cmd[sizeof(cmd) - 1] = '\0';
1448 return wpa_ctrl_command(ctrl, cmd);
1452 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1459 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1460 "(interface name)\n");
1464 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1465 if (res < 0 || (size_t) res >= sizeof(cmd))
1467 cmd[sizeof(cmd) - 1] = '\0';
1468 return wpa_ctrl_command(ctrl, cmd);
1472 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1475 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1480 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1484 printf("Invalid 'sta' command - exactly one argument, STA "
1485 "address, is required.\n");
1488 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1489 return wpa_ctrl_command(ctrl, buf);
1493 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1494 char *addr, size_t addr_len)
1496 char buf[4096], *pos;
1500 if (ctrl_conn == NULL) {
1501 printf("Not connected to hostapd - command dropped.\n");
1504 len = sizeof(buf) - 1;
1505 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1508 printf("'%s' command timed out.\n", cmd);
1510 } else if (ret < 0) {
1511 printf("'%s' command failed.\n", cmd);
1516 if (memcmp(buf, "FAIL", 4) == 0)
1521 while (*pos != '\0' && *pos != '\n')
1524 os_strlcpy(addr, buf, addr_len);
1529 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1531 char addr[32], cmd[64];
1533 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1536 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1537 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1541 #endif /* CONFIG_AP */
1544 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1546 return wpa_ctrl_command(ctrl, "SUSPEND");
1550 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1552 return wpa_ctrl_command(ctrl, "RESUME");
1556 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1558 return wpa_ctrl_command(ctrl, "DROP_SA");
1562 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1568 printf("Invalid ROAM command: needs one argument "
1569 "(target AP's BSSID)\n");
1573 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1574 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1575 printf("Too long ROAM command.\n");
1578 return wpa_ctrl_command(ctrl, cmd);
1584 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1590 return wpa_ctrl_command(ctrl, "P2P_FIND");
1593 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1596 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1597 if (res < 0 || (size_t) res >= sizeof(cmd))
1599 cmd[sizeof(cmd) - 1] = '\0';
1600 return wpa_ctrl_command(ctrl, cmd);
1604 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1607 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1611 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1618 printf("Invalid P2P_CONNECT command: needs at least two "
1619 "arguments (address and pbc/PIN)\n");
1624 res = os_snprintf(cmd, sizeof(cmd),
1625 "P2P_CONNECT %s %s %s %s %s",
1626 argv[0], argv[1], argv[2], argv[3],
1629 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1630 argv[0], argv[1], argv[2], argv[3]);
1632 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1633 argv[0], argv[1], argv[2]);
1635 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1637 if (res < 0 || (size_t) res >= sizeof(cmd))
1639 cmd[sizeof(cmd) - 1] = '\0';
1640 return wpa_ctrl_command(ctrl, cmd);
1644 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1651 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1653 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1654 if (res < 0 || (size_t) res >= sizeof(cmd))
1656 cmd[sizeof(cmd) - 1] = '\0';
1657 return wpa_ctrl_command(ctrl, cmd);
1661 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1668 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1669 "(interface name)\n");
1673 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
1674 if (res < 0 || (size_t) res >= sizeof(cmd))
1676 cmd[sizeof(cmd) - 1] = '\0';
1677 return wpa_ctrl_command(ctrl, cmd);
1681 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1688 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
1690 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", argv[0]);
1691 if (res < 0 || (size_t) res >= sizeof(cmd))
1693 cmd[sizeof(cmd) - 1] = '\0';
1694 return wpa_ctrl_command(ctrl, cmd);
1698 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1705 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1706 "(address and config method\n"
1707 "(display, keypad, or pbc)\n");
1711 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
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_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1723 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1727 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1733 if (argc != 2 && argc != 4) {
1734 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1735 "arguments (address and TLVs) or four arguments "
1736 "(address, \"upnp\", version, search target "
1742 res = os_snprintf(cmd, sizeof(cmd),
1743 "P2P_SERV_DISC_REQ %s %s %s %s",
1744 argv[0], argv[1], argv[2], argv[3]);
1746 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
1748 if (res < 0 || (size_t) res >= sizeof(cmd))
1750 cmd[sizeof(cmd) - 1] = '\0';
1751 return wpa_ctrl_command(ctrl, cmd);
1755 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1756 int argc, char *argv[])
1762 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1763 "argument (pending request identifier)\n");
1767 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
1769 if (res < 0 || (size_t) res >= sizeof(cmd))
1771 cmd[sizeof(cmd) - 1] = '\0';
1772 return wpa_ctrl_command(ctrl, cmd);
1776 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1783 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1784 "arguments (freq, address, dialog token, and TLVs)\n");
1788 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1789 argv[0], argv[1], argv[2], argv[3]);
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_service_update(struct wpa_ctrl *ctrl, int argc,
1800 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1804 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1805 int argc, char *argv[])
1811 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1812 "argument (external processing: 0/1)\n");
1816 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
1818 if (res < 0 || (size_t) res >= sizeof(cmd))
1820 cmd[sizeof(cmd) - 1] = '\0';
1821 return wpa_ctrl_command(ctrl, cmd);
1825 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1828 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1832 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1838 if (argc != 3 && argc != 4) {
1839 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1845 res = os_snprintf(cmd, sizeof(cmd),
1846 "P2P_SERVICE_ADD %s %s %s %s",
1847 argv[0], argv[1], argv[2], argv[3]);
1849 res = os_snprintf(cmd, sizeof(cmd),
1850 "P2P_SERVICE_ADD %s %s %s",
1851 argv[0], argv[1], argv[2]);
1852 if (res < 0 || (size_t) res >= sizeof(cmd))
1854 cmd[sizeof(cmd) - 1] = '\0';
1855 return wpa_ctrl_command(ctrl, cmd);
1859 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1865 if (argc != 2 && argc != 3) {
1866 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1872 res = os_snprintf(cmd, sizeof(cmd),
1873 "P2P_SERVICE_DEL %s %s %s",
1874 argv[0], argv[1], argv[2]);
1876 res = os_snprintf(cmd, sizeof(cmd),
1877 "P2P_SERVICE_DEL %s %s",
1879 if (res < 0 || (size_t) res >= sizeof(cmd))
1881 cmd[sizeof(cmd) - 1] = '\0';
1882 return wpa_ctrl_command(ctrl, cmd);
1886 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1887 int argc, char *argv[])
1893 printf("Invalid P2P_REJECT command: needs one argument "
1894 "(peer address)\n");
1898 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
1899 if (res < 0 || (size_t) res >= sizeof(cmd))
1901 cmd[sizeof(cmd) - 1] = '\0';
1902 return wpa_ctrl_command(ctrl, cmd);
1906 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1907 int argc, char *argv[])
1913 printf("Invalid P2P_INVITE command: needs at least one "
1919 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
1920 argv[0], argv[1], argv[2]);
1922 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
1925 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
1926 if (res < 0 || (size_t) res >= sizeof(cmd))
1928 cmd[sizeof(cmd) - 1] = '\0';
1929 return wpa_ctrl_command(ctrl, cmd);
1933 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
1937 printf("Invalid 'p2p_peer' command - exactly one argument, "
1938 "P2P peer device address, is required.\n");
1941 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
1942 return wpa_ctrl_command(ctrl, buf);
1946 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
1947 char *addr, size_t addr_len,
1950 char buf[4096], *pos;
1954 if (ctrl_conn == NULL)
1956 len = sizeof(buf) - 1;
1957 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1960 printf("'%s' command timed out.\n", cmd);
1962 } else if (ret < 0) {
1963 printf("'%s' command failed.\n", cmd);
1968 if (memcmp(buf, "FAIL", 4) == 0)
1972 while (*pos != '\0' && *pos != '\n')
1975 os_strlcpy(addr, buf, addr_len);
1976 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
1977 printf("%s\n", addr);
1982 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
1984 char addr[32], cmd[64];
1987 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
1989 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
1990 addr, sizeof(addr), discovered))
1993 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
1994 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2001 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2007 printf("Invalid P2P_SET command: needs two arguments (field, "
2012 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2013 if (res < 0 || (size_t) res >= sizeof(cmd))
2015 cmd[sizeof(cmd) - 1] = '\0';
2016 return wpa_ctrl_command(ctrl, cmd);
2020 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2022 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2026 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2029 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2033 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2039 if (argc != 0 && argc != 2 && argc != 4) {
2040 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2041 "(preferred duration, interval; in microsecods).\n"
2042 "Optional second pair can be used to provide "
2043 "acceptable values.\n");
2048 res = os_snprintf(cmd, sizeof(cmd),
2049 "P2P_PRESENCE_REQ %s %s %s %s",
2050 argv[0], argv[1], argv[2], argv[3]);
2052 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2055 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2056 if (res < 0 || (size_t) res >= sizeof(cmd))
2058 cmd[sizeof(cmd) - 1] = '\0';
2059 return wpa_ctrl_command(ctrl, cmd);
2063 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2069 if (argc != 0 && argc != 2) {
2070 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2071 "(availability period, availability interval; in "
2073 "Extended Listen Timing can be cancelled with this "
2074 "command when used without parameters.\n");
2079 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2082 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2083 if (res < 0 || (size_t) res >= sizeof(cmd))
2085 cmd[sizeof(cmd) - 1] = '\0';
2086 return wpa_ctrl_command(ctrl, cmd);
2089 #endif /* CONFIG_P2P */
2092 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2099 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2100 "(0/1 = disable/enable automatic reconnection)\n");
2103 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2104 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2105 printf("Too long STA_AUTOCONNECT command.\n");
2108 return wpa_ctrl_command(ctrl, cmd);
2112 enum wpa_cli_cmd_flags {
2113 cli_cmd_flag_none = 0x00,
2114 cli_cmd_flag_sensitive = 0x01
2117 struct wpa_cli_cmd {
2119 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2120 enum wpa_cli_cmd_flags flags;
2124 static struct wpa_cli_cmd wpa_cli_commands[] = {
2125 { "status", wpa_cli_cmd_status,
2127 "[verbose] = get current WPA/EAPOL/EAP status" },
2128 { "ping", wpa_cli_cmd_ping,
2130 "= pings wpa_supplicant" },
2131 { "note", wpa_cli_cmd_note,
2133 "<text> = add a note to wpa_supplicant debug log" },
2134 { "mib", wpa_cli_cmd_mib,
2136 "= get MIB variables (dot1x, dot11)" },
2137 { "help", wpa_cli_cmd_help,
2139 "= show this usage help" },
2140 { "interface", wpa_cli_cmd_interface,
2142 "[ifname] = show interfaces/select interface" },
2143 { "level", wpa_cli_cmd_level,
2145 "<debug level> = change debug level" },
2146 { "license", wpa_cli_cmd_license,
2148 "= show full wpa_cli license" },
2149 { "quit", wpa_cli_cmd_quit,
2152 { "set", wpa_cli_cmd_set,
2154 "= set variables (shows list of variables when run without "
2156 { "get", wpa_cli_cmd_get,
2158 "<name> = get information" },
2159 { "logon", wpa_cli_cmd_logon,
2161 "= IEEE 802.1X EAPOL state machine logon" },
2162 { "logoff", wpa_cli_cmd_logoff,
2164 "= IEEE 802.1X EAPOL state machine logoff" },
2165 { "pmksa", wpa_cli_cmd_pmksa,
2167 "= show PMKSA cache" },
2168 { "reassociate", wpa_cli_cmd_reassociate,
2170 "= force reassociation" },
2171 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2173 "<BSSID> = force preauthentication" },
2174 { "identity", wpa_cli_cmd_identity,
2176 "<network id> <identity> = configure identity for an SSID" },
2177 { "password", wpa_cli_cmd_password,
2178 cli_cmd_flag_sensitive,
2179 "<network id> <password> = configure password for an SSID" },
2180 { "new_password", wpa_cli_cmd_new_password,
2181 cli_cmd_flag_sensitive,
2182 "<network id> <password> = change password for an SSID" },
2183 { "pin", wpa_cli_cmd_pin,
2184 cli_cmd_flag_sensitive,
2185 "<network id> <pin> = configure pin for an SSID" },
2186 { "otp", wpa_cli_cmd_otp,
2187 cli_cmd_flag_sensitive,
2188 "<network id> <password> = configure one-time-password for an SSID"
2190 { "passphrase", wpa_cli_cmd_passphrase,
2191 cli_cmd_flag_sensitive,
2192 "<network id> <passphrase> = configure private key passphrase\n"
2194 { "bssid", wpa_cli_cmd_bssid,
2196 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2197 { "list_networks", wpa_cli_cmd_list_networks,
2199 "= list configured networks" },
2200 { "select_network", wpa_cli_cmd_select_network,
2202 "<network id> = select a network (disable others)" },
2203 { "enable_network", wpa_cli_cmd_enable_network,
2205 "<network id> = enable a network" },
2206 { "disable_network", wpa_cli_cmd_disable_network,
2208 "<network id> = disable a network" },
2209 { "add_network", wpa_cli_cmd_add_network,
2211 "= add a network" },
2212 { "remove_network", wpa_cli_cmd_remove_network,
2214 "<network id> = remove a network" },
2215 { "set_network", wpa_cli_cmd_set_network,
2216 cli_cmd_flag_sensitive,
2217 "<network id> <variable> <value> = set network variables (shows\n"
2218 " list of variables when run without arguments)" },
2219 { "get_network", wpa_cli_cmd_get_network,
2221 "<network id> <variable> = get network variables" },
2222 { "save_config", wpa_cli_cmd_save_config,
2224 "= save the current configuration" },
2225 { "disconnect", wpa_cli_cmd_disconnect,
2227 "= disconnect and wait for reassociate/reconnect command before\n"
2229 { "reconnect", wpa_cli_cmd_reconnect,
2231 "= like reassociate, but only takes effect if already disconnected"
2233 { "scan", wpa_cli_cmd_scan,
2235 "= request new BSS scan" },
2236 { "scan_results", wpa_cli_cmd_scan_results,
2238 "= get latest scan results" },
2239 { "bss", wpa_cli_cmd_bss,
2241 "<<idx> | <bssid>> = get detailed scan result info" },
2242 { "get_capability", wpa_cli_cmd_get_capability,
2244 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2245 { "reconfigure", wpa_cli_cmd_reconfigure,
2247 "= force wpa_supplicant to re-read its configuration file" },
2248 { "terminate", wpa_cli_cmd_terminate,
2250 "= terminate wpa_supplicant" },
2251 { "interface_add", wpa_cli_cmd_interface_add,
2253 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2254 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2256 { "interface_remove", wpa_cli_cmd_interface_remove,
2258 "<ifname> = removes the interface" },
2259 { "interface_list", wpa_cli_cmd_interface_list,
2261 "= list available interfaces" },
2262 { "ap_scan", wpa_cli_cmd_ap_scan,
2264 "<value> = set ap_scan parameter" },
2265 { "stkstart", wpa_cli_cmd_stkstart,
2267 "<addr> = request STK negotiation with <addr>" },
2268 { "ft_ds", wpa_cli_cmd_ft_ds,
2270 "<addr> = request over-the-DS FT with <addr>" },
2271 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2273 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2274 { "wps_pin", wpa_cli_cmd_wps_pin,
2275 cli_cmd_flag_sensitive,
2276 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2278 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2279 cli_cmd_flag_sensitive,
2280 "<PIN> = verify PIN checksum" },
2281 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2282 "Cancels the pending WPS operation" },
2283 #ifdef CONFIG_WPS_OOB
2284 { "wps_oob", wpa_cli_cmd_wps_oob,
2285 cli_cmd_flag_sensitive,
2286 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2287 #endif /* CONFIG_WPS_OOB */
2288 { "wps_reg", wpa_cli_cmd_wps_reg,
2289 cli_cmd_flag_sensitive,
2290 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2291 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2293 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2294 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2296 "= stop Wi-Fi Protected Setup External Registrar" },
2297 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2298 cli_cmd_flag_sensitive,
2299 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2300 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2302 "<UUID> = accept an Enrollee PBC using External Registrar" },
2303 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2304 cli_cmd_flag_sensitive,
2305 "<UUID> <PIN> = learn AP configuration" },
2306 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2308 "<UUID> <network id> = set AP configuration for enrolling" },
2309 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2310 cli_cmd_flag_sensitive,
2311 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2312 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2314 "<addr> = request RSN authentication with <addr> in IBSS" },
2316 { "sta", wpa_cli_cmd_sta,
2318 "<addr> = get information about an associated station (AP)" },
2319 { "all_sta", wpa_cli_cmd_all_sta,
2321 "= get information about all associated stations (AP)" },
2322 #endif /* CONFIG_AP */
2323 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2324 "= notification of suspend/hibernate" },
2325 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2326 "= notification of resume/thaw" },
2327 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2328 "= drop SA without deauth/disassoc (test command)" },
2329 { "roam", wpa_cli_cmd_roam,
2331 "<addr> = roam to the specified BSS" },
2333 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2334 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2335 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2336 "= stop P2P Devices search" },
2337 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2338 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2339 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2340 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2341 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2342 "<ifname> = remote P2P group interface (terminate group if GO)" },
2343 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2344 "= add a new P2P group (local end as GO)" },
2345 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2346 "<addr> <method> = request provisioning discovery" },
2347 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2349 "= get the passphrase for a group (GO only)" },
2350 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2352 "<addr> <TLVs> = schedule service discovery request" },
2353 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2355 "<id> = cancel pending service discovery request" },
2356 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2358 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2359 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2361 "= indicate change in local services" },
2362 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2364 "<external> = set external processing of service discovery" },
2365 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2367 "= remove all stored service entries" },
2368 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2370 "<bonjour|upnp> <query|version> <response|service> = add a local "
2372 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2374 "<bonjour|upnp> <query|version> [|service] = remove a local "
2376 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2378 "<addr> = reject connection attempts from a specific peer" },
2379 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2381 "<cmd> [peer=addr] = invite peer" },
2382 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2383 "[discovered] = list known (optionally, only fully discovered) P2P "
2385 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2386 "<address> = show information about known P2P peer" },
2387 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2388 "<field> <value> = set a P2P parameter" },
2389 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2390 "= flush P2P state" },
2391 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2392 "= cancel P2P group formation" },
2393 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2394 "[<duration> <interval>] [<duration> <interval>] = request GO "
2396 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2397 "[<period> <interval>] = set extended listen timing" },
2398 #endif /* CONFIG_P2P */
2399 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2400 "<0/1> = disable/enable automatic reconnection" },
2401 { NULL, NULL, cli_cmd_flag_none, NULL }
2406 * Prints command usage, lines are padded with the specified string.
2408 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2413 printf("%s%s ", pad, cmd->cmd);
2414 for (n = 0; (c = cmd->usage[n]); n++) {
2423 static void print_help(void)
2426 printf("commands:\n");
2427 for (n = 0; wpa_cli_commands[n].cmd; n++)
2428 print_cmd_help(&wpa_cli_commands[n], " ");
2432 #ifdef CONFIG_READLINE
2433 static int cmd_has_sensitive_data(const char *cmd)
2435 const char *c, *delim;
2439 delim = os_strchr(cmd, ' ');
2443 len = os_strlen(cmd);
2445 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2446 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2447 return (wpa_cli_commands[n].flags &
2448 cli_cmd_flag_sensitive);
2452 #endif /* CONFIG_READLINE */
2455 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2457 struct wpa_cli_cmd *cmd, *match = NULL;
2462 cmd = wpa_cli_commands;
2464 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2467 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2468 /* we have an exact match */
2478 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2479 cmd = wpa_cli_commands;
2481 if (os_strncasecmp(cmd->cmd, argv[0],
2482 os_strlen(argv[0])) == 0) {
2483 printf(" %s", cmd->cmd);
2489 } else if (count == 0) {
2490 printf("Unknown command '%s'\n", argv[0]);
2493 ret = match->handler(ctrl, argc - 1, &argv[1]);
2500 static int str_match(const char *a, const char *b)
2502 return os_strncmp(a, b, os_strlen(b)) == 0;
2506 static int wpa_cli_exec(const char *program, const char *arg1,
2514 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2515 cmd = os_malloc(len);
2518 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2519 if (res < 0 || (size_t) res >= len) {
2523 cmd[len - 1] = '\0';
2525 if (system(cmd) < 0)
2527 #endif /* _WIN32_WCE */
2534 static void wpa_cli_action_process(const char *msg)
2537 char *copy = NULL, *id, *pos2;
2542 pos = os_strchr(pos, '>');
2549 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2551 os_unsetenv("WPA_ID");
2552 os_unsetenv("WPA_ID_STR");
2553 os_unsetenv("WPA_CTRL_DIR");
2555 pos = os_strstr(pos, "[id=");
2557 copy = os_strdup(pos + 4);
2561 while (*pos2 && *pos2 != ' ')
2565 os_setenv("WPA_ID", id, 1);
2566 while (*pos2 && *pos2 != '=')
2571 while (*pos2 && *pos2 != ']')
2574 os_setenv("WPA_ID_STR", id, 1);
2578 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2580 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2581 wpa_cli_connected = 1;
2582 wpa_cli_last_id = new_id;
2583 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2585 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2586 if (wpa_cli_connected) {
2587 wpa_cli_connected = 0;
2588 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2590 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2591 wpa_cli_exec(action_file, ctrl_ifname, pos);
2592 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2593 wpa_cli_exec(action_file, ctrl_ifname, pos);
2594 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2595 wpa_cli_exec(action_file, ctrl_ifname, pos);
2596 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2597 wpa_cli_exec(action_file, ctrl_ifname, pos);
2598 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2599 wpa_cli_exec(action_file, ctrl_ifname, pos);
2600 } else if (str_match(pos, WPS_EVENT_FAIL)) {
2601 wpa_cli_exec(action_file, ctrl_ifname, pos);
2602 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2603 printf("wpa_supplicant is terminating - stop monitoring\n");
2609 #ifndef CONFIG_ANSI_C_EXTRA
2610 static void wpa_cli_action_cb(char *msg, size_t len)
2612 wpa_cli_action_process(msg);
2614 #endif /* CONFIG_ANSI_C_EXTRA */
2617 static void wpa_cli_reconnect(void)
2619 wpa_cli_close_connection();
2620 wpa_cli_open_connection(ctrl_ifname, 1);
2624 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
2626 if (ctrl_conn == NULL) {
2627 wpa_cli_reconnect();
2630 while (wpa_ctrl_pending(ctrl) > 0) {
2632 size_t len = sizeof(buf) - 1;
2633 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2636 wpa_cli_action_process(buf);
2638 if (wpa_cli_show_event(buf)) {
2639 #ifndef CONFIG_READLINE
2641 #endif /* CONFIG_READLINE */
2642 printf("\r%s\n", buf);
2647 printf("Could not read pending message.\n");
2652 if (wpa_ctrl_pending(ctrl) < 0) {
2653 printf("Connection to wpa_supplicant lost - trying to "
2655 wpa_cli_reconnect();
2661 static int tokenize_cmd(char *cmd, char *argv[])
2674 if (argc == max_args)
2677 char *pos2 = os_strrchr(pos, '"');
2681 while (*pos != '\0' && *pos != ' ')
2691 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
2693 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2694 printf("Connection to wpa_supplicant lost - trying to "
2696 wpa_cli_close_connection();
2699 wpa_cli_reconnect();
2700 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
2704 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
2710 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
2712 wpa_cli_recv_pending(mon_conn, 0);
2716 #ifdef CONFIG_READLINE
2718 static char * wpa_cli_cmd_gen(const char *text, int state)
2725 len = os_strlen(text);
2728 while ((cmd = wpa_cli_commands[i].cmd)) {
2730 if (os_strncasecmp(cmd, text, len) == 0)
2738 static char * wpa_cli_dummy_gen(const char *text, int state)
2742 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2743 const char *cmd = wpa_cli_commands[i].cmd;
2744 size_t len = os_strlen(cmd);
2745 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
2746 rl_line_buffer[len] == ' ') {
2747 printf("\n%s\n", wpa_cli_commands[i].usage);
2753 rl_attempted_completion_over = 1;
2758 static char * wpa_cli_status_gen(const char *text, int state)
2768 len = os_strlen(text);
2771 while ((t = options[i])) {
2773 if (os_strncasecmp(t, text, len) == 0)
2777 rl_attempted_completion_over = 1;
2782 static char ** wpa_cli_completion(const char *text, int start, int end)
2784 char * (*func)(const char *text, int state);
2787 func = wpa_cli_cmd_gen;
2788 else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
2789 func = wpa_cli_status_gen;
2791 func = wpa_cli_dummy_gen;
2792 return rl_completion_matches(text, func);
2796 static void wpa_cli_read_char(int sock, void *eloop_ctx, void *sock_ctx)
2798 rl_callback_read_char();
2802 static void trunc_nl(char *str)
2805 while (*pos != '\0') {
2815 static void readline_cmd_handler(char *cmd)
2818 char *argv[max_args];
2822 while (next_history())
2824 h = previous_history();
2825 if (h == NULL || os_strcmp(cmd, h->line) != 0)
2834 argc = tokenize_cmd(cmd, argv);
2836 wpa_request(ctrl_conn, argc, argv);
2840 static void wpa_cli_interactive(void)
2842 char *home, *hfile = NULL;
2844 printf("\nInteractive mode\n\n");
2846 rl_attempted_completion_function = wpa_cli_completion;
2847 home = getenv("HOME");
2849 const char *fname = ".wpa_cli_history";
2850 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
2851 hfile = os_malloc(hfile_len);
2854 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
2856 if (res >= 0 && res < hfile_len) {
2857 hfile[hfile_len - 1] = '\0';
2858 read_history(hfile);
2859 stifle_history(100);
2864 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
2865 eloop_register_read_sock(STDIN_FILENO, wpa_cli_read_char, NULL, NULL);
2866 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
2868 rl_callback_handler_install("> ", readline_cmd_handler);
2872 rl_callback_handler_remove();
2874 eloop_unregister_read_sock(STDIN_FILENO);
2875 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
2876 wpa_cli_close_connection();
2879 /* Save command history, excluding lines that may contain
2883 while ((h = current_history())) {
2885 while (*p == ' ' || *p == '\t')
2887 if (cmd_has_sensitive_data(p)) {
2888 h = remove_history(where_history());
2898 write_history(hfile);
2903 #else /* CONFIG_READLINE */
2906 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
2908 char *argv[max_args];
2910 argc = tokenize_cmd(cmd, argv);
2912 wpa_request(ctrl_conn, argc, argv);
2916 static void wpa_cli_edit_eof_cb(void *ctx)
2922 static void wpa_cli_interactive(void)
2925 printf("\nInteractive mode\n\n");
2927 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
2928 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, NULL);
2929 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
2937 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
2938 wpa_cli_close_connection();
2941 #endif /* CONFIG_READLINE */
2944 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2946 #ifdef CONFIG_ANSI_C_EXTRA
2947 /* TODO: ANSI C version(?) */
2948 printf("Action processing not supported in ANSI C build.\n");
2949 #else /* CONFIG_ANSI_C_EXTRA */
2953 char buf[256]; /* note: large enough to fit in unsolicited messages */
2956 fd = wpa_ctrl_get_fd(ctrl);
2958 while (!wpa_cli_quit) {
2961 tv.tv_sec = ping_interval;
2963 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2964 if (res < 0 && errno != EINTR) {
2969 if (FD_ISSET(fd, &rfds))
2970 wpa_cli_recv_pending(ctrl, 1);
2972 /* verify that connection is still working */
2973 len = sizeof(buf) - 1;
2974 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2975 wpa_cli_action_cb) < 0 ||
2976 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2977 printf("wpa_supplicant did not reply to PING "
2978 "command - exiting\n");
2983 #endif /* CONFIG_ANSI_C_EXTRA */
2987 static void wpa_cli_cleanup(void)
2989 wpa_cli_close_connection();
2991 os_daemonize_terminate(pid_file);
2993 os_program_deinit();
2996 static void wpa_cli_terminate(int sig)
3003 static char * wpa_cli_get_default_ifname(void)
3005 char *ifname = NULL;
3007 #ifdef CONFIG_CTRL_IFACE_UNIX
3008 struct dirent *dent;
3009 DIR *dir = opendir(ctrl_iface_dir);
3012 while ((dent = readdir(dir))) {
3013 #ifdef _DIRENT_HAVE_D_TYPE
3015 * Skip the file if it is not a socket. Also accept
3016 * DT_UNKNOWN (0) in case the C library or underlying
3017 * file system does not support d_type.
3019 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3021 #endif /* _DIRENT_HAVE_D_TYPE */
3022 if (os_strcmp(dent->d_name, ".") == 0 ||
3023 os_strcmp(dent->d_name, "..") == 0)
3025 printf("Selected interface '%s'\n", dent->d_name);
3026 ifname = os_strdup(dent->d_name);
3030 #endif /* CONFIG_CTRL_IFACE_UNIX */
3032 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3033 char buf[2048], *pos;
3035 struct wpa_ctrl *ctrl;
3038 ctrl = wpa_ctrl_open(NULL);
3042 len = sizeof(buf) - 1;
3043 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3046 pos = os_strchr(buf, '\n');
3049 ifname = os_strdup(buf);
3051 wpa_ctrl_close(ctrl);
3052 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3058 int main(int argc, char *argv[])
3060 int warning_displayed = 0;
3064 const char *global = NULL;
3066 if (os_program_init())
3070 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3075 action_file = optarg;
3084 ping_interval = atoi(optarg);
3090 printf("%s\n", wpa_cli_version);
3093 os_free(ctrl_ifname);
3094 ctrl_ifname = os_strdup(optarg);
3097 ctrl_iface_dir = optarg;
3108 interactive = (argc == optind) && (action_file == NULL);
3111 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3117 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3118 ctrl_conn = wpa_ctrl_open(NULL);
3119 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3120 ctrl_conn = wpa_ctrl_open(global);
3121 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3122 if (ctrl_conn == NULL) {
3123 perror("Failed to connect to wpa_supplicant - "
3130 signal(SIGINT, wpa_cli_terminate);
3131 signal(SIGTERM, wpa_cli_terminate);
3132 #endif /* _WIN32_WCE */
3134 if (ctrl_ifname == NULL)
3135 ctrl_ifname = wpa_cli_get_default_ifname();
3139 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3140 if (warning_displayed)
3141 printf("Connection established.\n");
3145 if (!warning_displayed) {
3146 printf("Could not connect to wpa_supplicant - "
3148 warning_displayed = 1;
3155 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3156 perror("Failed to connect to wpa_supplicant - "
3162 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3163 wpa_cli_attached = 1;
3165 printf("Warning: Failed to attach to "
3166 "wpa_supplicant.\n");
3172 if (daemonize && os_daemonize(pid_file))
3176 wpa_cli_interactive();
3177 else if (action_file)
3178 wpa_cli_action(ctrl_conn);
3180 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3182 os_free(ctrl_ifname);
3189 #else /* CONFIG_CTRL_IFACE */
3190 int main(int argc, char *argv[])
3192 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3195 #endif /* CONFIG_CTRL_IFACE */