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