2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
23 #include "common/wpa_ctrl.h"
24 #include "utils/common.h"
25 #include "utils/eloop.h"
26 #include "utils/edit.h"
27 #include "common/version.h"
30 static const char *wpa_cli_version =
31 "wpa_cli v" VERSION_STR "\n"
32 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
35 static const char *wpa_cli_license =
36 "This program is free software. You can distribute it and/or modify it\n"
37 "under the terms of the GNU General Public License version 2.\n"
39 "Alternatively, this software may be distributed under the terms of the\n"
40 "BSD license. See README and COPYING for more details.\n";
42 static const char *wpa_cli_full_license =
43 "This program is free software; you can redistribute it and/or modify\n"
44 "it under the terms of the GNU General Public License version 2 as\n"
45 "published by the Free Software Foundation.\n"
47 "This program is distributed in the hope that it will be useful,\n"
48 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
49 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
50 "GNU General Public License for more details.\n"
52 "You should have received a copy of the GNU General Public License\n"
53 "along with this program; if not, write to the Free Software\n"
54 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
56 "Alternatively, this software may be distributed under the terms of the\n"
59 "Redistribution and use in source and binary forms, with or without\n"
60 "modification, are permitted provided that the following conditions are\n"
63 "1. Redistributions of source code must retain the above copyright\n"
64 " notice, this list of conditions and the following disclaimer.\n"
66 "2. Redistributions in binary form must reproduce the above copyright\n"
67 " notice, this list of conditions and the following disclaimer in the\n"
68 " documentation and/or other materials provided with the distribution.\n"
70 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
71 " names of its contributors may be used to endorse or promote products\n"
72 " derived from this software without specific prior written permission.\n"
74 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
75 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
76 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
77 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
78 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
79 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
80 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
81 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
82 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
83 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
84 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
87 static struct wpa_ctrl *ctrl_conn;
88 static struct wpa_ctrl *mon_conn;
89 static int wpa_cli_quit = 0;
90 static int wpa_cli_attached = 0;
91 static int wpa_cli_connected = 0;
92 static int wpa_cli_last_id = 0;
93 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
94 static char *ctrl_ifname = NULL;
95 static const char *pid_file = NULL;
96 static const char *action_file = NULL;
97 static int ping_interval = 5;
98 static int interactive = 0;
101 static void print_help(void);
102 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
105 static void usage(void)
107 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
108 "[-a<action file>] \\\n"
109 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
111 " -h = help (show this usage text)\n"
112 " -v = shown version information\n"
113 " -a = run in daemon mode executing the action file based on "
116 " -B = run a daemon in the background\n"
117 " default path: /var/run/wpa_supplicant\n"
118 " default interface: first interface found in socket path\n");
123 static int str_starts(const char *src, const char *match)
125 return os_strncmp(src, match, os_strlen(match)) == 0;
129 static int wpa_cli_show_event(const char *event)
133 start = os_strchr(event, '>');
139 * Skip BSS added/removed events since they can be relatively frequent
140 * and are likely of not much use for an interactive user.
142 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
143 str_starts(start, WPA_EVENT_BSS_REMOVED))
150 static int wpa_cli_open_connection(const char *ifname, int attach)
152 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
153 ctrl_conn = wpa_ctrl_open(ifname);
154 if (ctrl_conn == NULL)
157 if (attach && interactive)
158 mon_conn = wpa_ctrl_open(ifname);
161 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
168 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
169 cfile = os_malloc(flen);
172 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
173 if (res < 0 || res >= flen) {
178 ctrl_conn = wpa_ctrl_open(cfile);
179 if (ctrl_conn == NULL) {
184 if (attach && interactive)
185 mon_conn = wpa_ctrl_open(cfile);
189 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
192 if (wpa_ctrl_attach(mon_conn) == 0) {
193 wpa_cli_attached = 1;
195 eloop_register_read_sock(
196 wpa_ctrl_get_fd(mon_conn),
197 wpa_cli_mon_receive, NULL, NULL);
199 printf("Warning: Failed to attach to "
200 "wpa_supplicant.\n");
209 static void wpa_cli_close_connection(void)
211 if (ctrl_conn == NULL)
214 if (wpa_cli_attached) {
215 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
216 wpa_cli_attached = 0;
218 wpa_ctrl_close(ctrl_conn);
221 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
222 wpa_ctrl_close(mon_conn);
228 static void wpa_cli_msg_cb(char *msg, size_t len)
234 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
240 if (ctrl_conn == NULL) {
241 printf("Not connected to wpa_supplicant - command dropped.\n");
244 len = sizeof(buf) - 1;
245 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
248 printf("'%s' command timed out.\n", cmd);
250 } else if (ret < 0) {
251 printf("'%s' command failed.\n", cmd);
262 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
264 return _wpa_ctrl_command(ctrl, cmd, 1);
268 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
270 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
271 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
275 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
277 return wpa_ctrl_command(ctrl, "PING");
281 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
287 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
288 if (ret < 0 || (size_t) ret >= sizeof(cmd))
290 return wpa_ctrl_command(ctrl, cmd);
294 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
296 return wpa_ctrl_command(ctrl, "MIB");
300 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
302 return wpa_ctrl_command(ctrl, "PMKSA");
306 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
313 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
315 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
320 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
329 static void wpa_cli_show_variables(void)
331 printf("set variables:\n"
332 " EAPOL::heldPeriod (EAPOL state machine held period, "
334 " EAPOL::authPeriod (EAPOL state machine authentication "
335 "period, in seconds)\n"
336 " EAPOL::startPeriod (EAPOL state machine start period, in "
338 " EAPOL::maxStart (EAPOL state machine maximum start "
340 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
342 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
343 " threshold\n\tpercentage)\n"
344 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
345 "security\n\tassociation in seconds)\n");
349 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
355 wpa_cli_show_variables();
360 printf("Invalid SET command: needs two arguments (variable "
361 "name and value)\n");
365 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
366 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
367 printf("Too long SET command.\n");
370 return wpa_ctrl_command(ctrl, cmd);
374 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
380 printf("Invalid GET command: need one argument (variable "
385 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
386 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
387 printf("Too long GET command.\n");
390 return wpa_ctrl_command(ctrl, cmd);
394 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
396 return wpa_ctrl_command(ctrl, "LOGOFF");
400 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
402 return wpa_ctrl_command(ctrl, "LOGON");
406 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
409 return wpa_ctrl_command(ctrl, "REASSOCIATE");
413 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
420 printf("Invalid PREAUTH command: needs one argument "
425 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
426 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
427 printf("Too long PREAUTH command.\n");
430 return wpa_ctrl_command(ctrl, cmd);
434 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
440 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
444 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
445 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
446 printf("Too long AP_SCAN command.\n");
449 return wpa_ctrl_command(ctrl, cmd);
453 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
460 printf("Invalid STKSTART command: needs one argument "
461 "(Peer STA MAC address)\n");
465 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
466 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
467 printf("Too long STKSTART command.\n");
470 return wpa_ctrl_command(ctrl, cmd);
474 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
480 printf("Invalid FT_DS command: needs one argument "
481 "(Target AP MAC address)\n");
485 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
486 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
487 printf("Too long FT_DS command.\n");
490 return wpa_ctrl_command(ctrl, cmd);
494 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
501 return wpa_ctrl_command(ctrl, "WPS_PBC");
505 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
506 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
507 printf("Too long WPS_PBC command.\n");
510 return wpa_ctrl_command(ctrl, cmd);
514 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
520 printf("Invalid WPS_PIN command: need one or two arguments:\n"
521 "- BSSID: use 'any' to select any\n"
522 "- PIN: optional, used only with devices that have no "
528 /* Use dynamically generated PIN (returned as reply) */
529 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
530 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
531 printf("Too long WPS_PIN command.\n");
534 return wpa_ctrl_command(ctrl, cmd);
537 /* Use hardcoded PIN from a label */
538 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
539 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
540 printf("Too long WPS_PIN command.\n");
543 return wpa_ctrl_command(ctrl, cmd);
547 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
553 if (argc != 1 && argc != 2) {
554 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
555 "- PIN to be verified\n");
560 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
563 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
565 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
566 printf("Too long WPS_CHECK_PIN command.\n");
569 return wpa_ctrl_command(ctrl, cmd);
573 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
576 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
580 #ifdef CONFIG_WPS_OOB
581 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
586 if (argc != 3 && argc != 4) {
587 printf("Invalid WPS_OOB command: need three or four "
589 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
590 "- PATH: path of OOB device like '/mnt'\n"
591 "- METHOD: OOB method 'pin-e' or 'pin-r', "
593 "- DEV_NAME: (only for NFC) device name like "
599 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
600 argv[0], argv[1], argv[2]);
602 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
603 argv[0], argv[1], argv[2], argv[3]);
604 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
605 printf("Too long WPS_OOB command.\n");
608 return wpa_ctrl_command(ctrl, cmd);
610 #endif /* CONFIG_WPS_OOB */
613 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
619 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
621 else if (argc == 5 || argc == 6) {
622 char ssid_hex[2 * 32 + 1];
623 char key_hex[2 * 64 + 1];
627 for (i = 0; i < 32; i++) {
628 if (argv[2][i] == '\0')
630 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
635 for (i = 0; i < 64; i++) {
636 if (argv[5][i] == '\0')
638 os_snprintf(&key_hex[i * 2], 3, "%02x",
643 res = os_snprintf(cmd, sizeof(cmd),
644 "WPS_REG %s %s %s %s %s %s",
645 argv[0], argv[1], ssid_hex, argv[3], argv[4],
648 printf("Invalid WPS_REG command: need two arguments:\n"
649 "- BSSID of the target AP\n"
651 printf("Alternatively, six arguments can be used to "
652 "reconfigure the AP:\n"
653 "- BSSID of the target AP\n"
656 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
657 "- new encr (NONE, WEP, TKIP, CCMP)\n"
662 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
663 printf("Too long WPS_REG command.\n");
666 return wpa_ctrl_command(ctrl, cmd);
670 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
677 printf("Invalid WPS_AP_PIN command: needs at least one "
683 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
684 argv[0], argv[1], argv[2]);
686 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
689 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
691 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
692 printf("Too long WPS_AP_PIN command.\n");
695 return wpa_ctrl_command(ctrl, cmd);
699 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
704 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
705 return wpa_ctrl_command(ctrl, cmd);
707 return wpa_ctrl_command(ctrl, "WPS_ER_START");
711 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
714 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
719 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
726 printf("Invalid WPS_ER_PIN command: need at least two "
728 "- UUID: use 'any' to select any\n"
729 "- PIN: Enrollee PIN\n"
730 "optional: - Enrollee MAC address\n");
735 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
736 argv[0], argv[1], argv[2]);
738 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
740 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
741 printf("Too long WPS_ER_PIN command.\n");
744 return wpa_ctrl_command(ctrl, cmd);
748 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
755 printf("Invalid WPS_ER_PBC command: need one argument:\n"
756 "- UUID: Specify the Enrollee\n");
760 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
762 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
763 printf("Too long WPS_ER_PBC command.\n");
766 return wpa_ctrl_command(ctrl, cmd);
770 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
777 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
778 "- UUID: specify which AP to use\n"
783 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
785 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
786 printf("Too long WPS_ER_LEARN command.\n");
789 return wpa_ctrl_command(ctrl, cmd);
793 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
800 printf("Invalid WPS_ER_SET_CONFIG command: need two "
802 "- UUID: specify which AP to use\n"
803 "- Network configuration id\n");
807 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
809 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
810 printf("Too long WPS_ER_SET_CONFIG command.\n");
813 return wpa_ctrl_command(ctrl, cmd);
817 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
823 if (argc == 5 || argc == 6) {
824 char ssid_hex[2 * 32 + 1];
825 char key_hex[2 * 64 + 1];
829 for (i = 0; i < 32; i++) {
830 if (argv[2][i] == '\0')
832 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
837 for (i = 0; i < 64; i++) {
838 if (argv[5][i] == '\0')
840 os_snprintf(&key_hex[i * 2], 3, "%02x",
845 res = os_snprintf(cmd, sizeof(cmd),
846 "WPS_ER_CONFIG %s %s %s %s %s %s",
847 argv[0], argv[1], ssid_hex, argv[3], argv[4],
850 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
854 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
855 "- new encr (NONE, WEP, TKIP, CCMP)\n"
860 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
861 printf("Too long WPS_ER_CONFIG command.\n");
864 return wpa_ctrl_command(ctrl, cmd);
868 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
874 printf("Invalid IBSS_RSN command: needs one argument "
875 "(Peer STA MAC address)\n");
879 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
880 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
881 printf("Too long IBSS_RSN command.\n");
884 return wpa_ctrl_command(ctrl, cmd);
888 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
894 printf("Invalid LEVEL command: needs one argument (debug "
898 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
899 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
900 printf("Too long LEVEL command.\n");
903 return wpa_ctrl_command(ctrl, cmd);
907 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
909 char cmd[256], *pos, *end;
913 printf("Invalid IDENTITY command: needs two arguments "
914 "(network id and identity)\n");
918 end = cmd + sizeof(cmd);
920 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
922 if (ret < 0 || ret >= end - pos) {
923 printf("Too long IDENTITY command.\n");
927 for (i = 2; i < argc; i++) {
928 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
929 if (ret < 0 || ret >= end - pos) {
930 printf("Too long IDENTITY command.\n");
936 return wpa_ctrl_command(ctrl, cmd);
940 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
942 char cmd[256], *pos, *end;
946 printf("Invalid PASSWORD command: needs two arguments "
947 "(network id and password)\n");
951 end = cmd + sizeof(cmd);
953 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
955 if (ret < 0 || ret >= end - pos) {
956 printf("Too long PASSWORD command.\n");
960 for (i = 2; i < argc; i++) {
961 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
962 if (ret < 0 || ret >= end - pos) {
963 printf("Too long PASSWORD command.\n");
969 return wpa_ctrl_command(ctrl, cmd);
973 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
976 char cmd[256], *pos, *end;
980 printf("Invalid NEW_PASSWORD command: needs two arguments "
981 "(network id and password)\n");
985 end = cmd + sizeof(cmd);
987 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
989 if (ret < 0 || ret >= end - pos) {
990 printf("Too long NEW_PASSWORD command.\n");
994 for (i = 2; i < argc; i++) {
995 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
996 if (ret < 0 || ret >= end - pos) {
997 printf("Too long NEW_PASSWORD command.\n");
1003 return wpa_ctrl_command(ctrl, cmd);
1007 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1009 char cmd[256], *pos, *end;
1013 printf("Invalid PIN command: needs two arguments "
1014 "(network id and pin)\n");
1018 end = cmd + sizeof(cmd);
1020 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1022 if (ret < 0 || ret >= end - pos) {
1023 printf("Too long PIN command.\n");
1027 for (i = 2; i < argc; i++) {
1028 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1029 if (ret < 0 || ret >= end - pos) {
1030 printf("Too long PIN command.\n");
1035 return wpa_ctrl_command(ctrl, cmd);
1039 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1041 char cmd[256], *pos, *end;
1045 printf("Invalid OTP command: needs two arguments (network "
1046 "id and password)\n");
1050 end = cmd + sizeof(cmd);
1052 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1054 if (ret < 0 || ret >= end - pos) {
1055 printf("Too long OTP command.\n");
1059 for (i = 2; i < argc; i++) {
1060 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1061 if (ret < 0 || ret >= end - pos) {
1062 printf("Too long OTP command.\n");
1068 return wpa_ctrl_command(ctrl, cmd);
1072 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1075 char cmd[256], *pos, *end;
1079 printf("Invalid PASSPHRASE command: needs two arguments "
1080 "(network id and passphrase)\n");
1084 end = cmd + sizeof(cmd);
1086 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1088 if (ret < 0 || ret >= end - pos) {
1089 printf("Too long PASSPHRASE command.\n");
1093 for (i = 2; i < argc; i++) {
1094 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1095 if (ret < 0 || ret >= end - pos) {
1096 printf("Too long PASSPHRASE command.\n");
1102 return wpa_ctrl_command(ctrl, cmd);
1106 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1108 char cmd[256], *pos, *end;
1112 printf("Invalid BSSID command: needs two arguments (network "
1117 end = cmd + sizeof(cmd);
1119 ret = os_snprintf(pos, end - pos, "BSSID");
1120 if (ret < 0 || ret >= end - pos) {
1121 printf("Too long BSSID command.\n");
1125 for (i = 0; i < argc; i++) {
1126 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1127 if (ret < 0 || ret >= end - pos) {
1128 printf("Too long BSSID command.\n");
1134 return wpa_ctrl_command(ctrl, cmd);
1138 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1141 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1145 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1152 printf("Invalid SELECT_NETWORK command: needs one argument "
1157 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1158 if (res < 0 || (size_t) res >= sizeof(cmd))
1160 cmd[sizeof(cmd) - 1] = '\0';
1162 return wpa_ctrl_command(ctrl, cmd);
1166 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1173 printf("Invalid ENABLE_NETWORK command: needs one argument "
1178 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1179 if (res < 0 || (size_t) res >= sizeof(cmd))
1181 cmd[sizeof(cmd) - 1] = '\0';
1183 return wpa_ctrl_command(ctrl, cmd);
1187 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1194 printf("Invalid DISABLE_NETWORK command: needs one argument "
1199 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1200 if (res < 0 || (size_t) res >= sizeof(cmd))
1202 cmd[sizeof(cmd) - 1] = '\0';
1204 return wpa_ctrl_command(ctrl, cmd);
1208 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1211 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1215 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1222 printf("Invalid REMOVE_NETWORK command: needs one argument "
1227 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1228 if (res < 0 || (size_t) res >= sizeof(cmd))
1230 cmd[sizeof(cmd) - 1] = '\0';
1232 return wpa_ctrl_command(ctrl, cmd);
1236 static void wpa_cli_show_network_variables(void)
1238 printf("set_network variables:\n"
1239 " ssid (network name, SSID)\n"
1240 " psk (WPA passphrase or pre-shared key)\n"
1241 " key_mgmt (key management protocol)\n"
1242 " identity (EAP identity)\n"
1243 " password (EAP password)\n"
1246 "Note: Values are entered in the same format as the "
1247 "configuration file is using,\n"
1248 "i.e., strings values need to be inside double quotation "
1250 "For example: set_network 1 ssid \"network name\"\n"
1252 "Please see wpa_supplicant.conf documentation for full list "
1253 "of\navailable variables.\n");
1257 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1264 wpa_cli_show_network_variables();
1269 printf("Invalid SET_NETWORK command: needs three arguments\n"
1270 "(network id, variable name, and value)\n");
1274 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1275 argv[0], argv[1], argv[2]);
1276 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1277 printf("Too long SET_NETWORK command.\n");
1280 return wpa_ctrl_command(ctrl, cmd);
1284 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1291 wpa_cli_show_network_variables();
1296 printf("Invalid GET_NETWORK command: needs two arguments\n"
1297 "(network id and variable name)\n");
1301 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1303 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1304 printf("Too long GET_NETWORK command.\n");
1307 return wpa_ctrl_command(ctrl, cmd);
1311 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1314 return wpa_ctrl_command(ctrl, "DISCONNECT");
1318 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1321 return wpa_ctrl_command(ctrl, "RECONNECT");
1325 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1328 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1332 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1334 return wpa_ctrl_command(ctrl, "SCAN");
1338 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1341 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1345 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1351 printf("Invalid BSS command: need one argument (index or "
1356 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1357 if (res < 0 || (size_t) res >= sizeof(cmd))
1359 cmd[sizeof(cmd) - 1] = '\0';
1361 return wpa_ctrl_command(ctrl, cmd);
1365 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1371 if (argc < 1 || argc > 2) {
1372 printf("Invalid GET_CAPABILITY command: need either one or "
1377 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1378 printf("Invalid GET_CAPABILITY command: second argument, "
1379 "if any, must be 'strict'\n");
1383 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1384 (argc == 2) ? " strict" : "");
1385 if (res < 0 || (size_t) res >= sizeof(cmd))
1387 cmd[sizeof(cmd) - 1] = '\0';
1389 return wpa_ctrl_command(ctrl, cmd);
1393 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1395 printf("Available interfaces:\n");
1396 return wpa_ctrl_command(ctrl, "INTERFACES");
1400 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1403 wpa_cli_list_interfaces(ctrl);
1407 wpa_cli_close_connection();
1408 os_free(ctrl_ifname);
1409 ctrl_ifname = os_strdup(argv[0]);
1411 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1412 printf("Connected to interface '%s.\n", ctrl_ifname);
1414 printf("Could not connect to interface '%s' - re-trying\n",
1421 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1424 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1428 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1431 return wpa_ctrl_command(ctrl, "TERMINATE");
1435 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1442 printf("Invalid INTERFACE_ADD command: needs at least one "
1443 "argument (interface name)\n"
1444 "All arguments: ifname confname driver ctrl_interface "
1445 "driver_param bridge_name\n");
1450 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1451 * <driver_param>TAB<bridge_name>
1453 res = os_snprintf(cmd, sizeof(cmd),
1454 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1456 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1457 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1458 argc > 5 ? argv[5] : "");
1459 if (res < 0 || (size_t) res >= sizeof(cmd))
1461 cmd[sizeof(cmd) - 1] = '\0';
1462 return wpa_ctrl_command(ctrl, cmd);
1466 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1473 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1474 "(interface name)\n");
1478 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1479 if (res < 0 || (size_t) res >= sizeof(cmd))
1481 cmd[sizeof(cmd) - 1] = '\0';
1482 return wpa_ctrl_command(ctrl, cmd);
1486 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1489 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1494 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1498 printf("Invalid 'sta' command - exactly one argument, STA "
1499 "address, is required.\n");
1502 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1503 return wpa_ctrl_command(ctrl, buf);
1507 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1508 char *addr, size_t addr_len)
1510 char buf[4096], *pos;
1514 if (ctrl_conn == NULL) {
1515 printf("Not connected to hostapd - command dropped.\n");
1518 len = sizeof(buf) - 1;
1519 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1522 printf("'%s' command timed out.\n", cmd);
1524 } else if (ret < 0) {
1525 printf("'%s' command failed.\n", cmd);
1530 if (memcmp(buf, "FAIL", 4) == 0)
1535 while (*pos != '\0' && *pos != '\n')
1538 os_strlcpy(addr, buf, addr_len);
1543 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1545 char addr[32], cmd[64];
1547 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1550 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1551 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1555 #endif /* CONFIG_AP */
1558 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1560 return wpa_ctrl_command(ctrl, "SUSPEND");
1564 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1566 return wpa_ctrl_command(ctrl, "RESUME");
1570 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1572 return wpa_ctrl_command(ctrl, "DROP_SA");
1576 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1582 printf("Invalid ROAM command: needs one argument "
1583 "(target AP's BSSID)\n");
1587 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1588 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1589 printf("Too long ROAM command.\n");
1592 return wpa_ctrl_command(ctrl, cmd);
1598 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1604 return wpa_ctrl_command(ctrl, "P2P_FIND");
1607 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1610 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1611 if (res < 0 || (size_t) res >= sizeof(cmd))
1613 cmd[sizeof(cmd) - 1] = '\0';
1614 return wpa_ctrl_command(ctrl, cmd);
1618 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1621 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1625 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1632 printf("Invalid P2P_CONNECT command: needs at least two "
1633 "arguments (address and pbc/PIN)\n");
1638 res = os_snprintf(cmd, sizeof(cmd),
1639 "P2P_CONNECT %s %s %s %s %s",
1640 argv[0], argv[1], argv[2], argv[3],
1643 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1644 argv[0], argv[1], argv[2], argv[3]);
1646 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1647 argv[0], argv[1], argv[2]);
1649 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1651 if (res < 0 || (size_t) res >= sizeof(cmd))
1653 cmd[sizeof(cmd) - 1] = '\0';
1654 return wpa_ctrl_command(ctrl, cmd);
1658 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1665 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1667 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1668 if (res < 0 || (size_t) res >= sizeof(cmd))
1670 cmd[sizeof(cmd) - 1] = '\0';
1671 return wpa_ctrl_command(ctrl, cmd);
1675 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1682 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
1683 "(interface name)\n");
1687 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
1688 if (res < 0 || (size_t) res >= sizeof(cmd))
1690 cmd[sizeof(cmd) - 1] = '\0';
1691 return wpa_ctrl_command(ctrl, cmd);
1695 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1702 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
1704 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", argv[0]);
1705 if (res < 0 || (size_t) res >= sizeof(cmd))
1707 cmd[sizeof(cmd) - 1] = '\0';
1708 return wpa_ctrl_command(ctrl, cmd);
1712 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1719 printf("Invalid P2P_PROV_DISC command: needs two arguments "
1720 "(address and config method\n"
1721 "(display, keypad, or pbc)\n");
1725 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
1727 if (res < 0 || (size_t) res >= sizeof(cmd))
1729 cmd[sizeof(cmd) - 1] = '\0';
1730 return wpa_ctrl_command(ctrl, cmd);
1734 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1737 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1741 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1747 if (argc != 2 && argc != 4) {
1748 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1749 "arguments (address and TLVs) or four arguments "
1750 "(address, \"upnp\", version, search target "
1756 res = os_snprintf(cmd, sizeof(cmd),
1757 "P2P_SERV_DISC_REQ %s %s %s %s",
1758 argv[0], argv[1], argv[2], argv[3]);
1760 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
1762 if (res < 0 || (size_t) res >= sizeof(cmd))
1764 cmd[sizeof(cmd) - 1] = '\0';
1765 return wpa_ctrl_command(ctrl, cmd);
1769 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1770 int argc, char *argv[])
1776 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
1777 "argument (pending request identifier)\n");
1781 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
1783 if (res < 0 || (size_t) res >= sizeof(cmd))
1785 cmd[sizeof(cmd) - 1] = '\0';
1786 return wpa_ctrl_command(ctrl, cmd);
1790 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1797 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1798 "arguments (freq, address, dialog token, and TLVs)\n");
1802 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1803 argv[0], argv[1], argv[2], argv[3]);
1804 if (res < 0 || (size_t) res >= sizeof(cmd))
1806 cmd[sizeof(cmd) - 1] = '\0';
1807 return wpa_ctrl_command(ctrl, cmd);
1811 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1814 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1818 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1819 int argc, char *argv[])
1825 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
1826 "argument (external processing: 0/1)\n");
1830 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
1832 if (res < 0 || (size_t) res >= sizeof(cmd))
1834 cmd[sizeof(cmd) - 1] = '\0';
1835 return wpa_ctrl_command(ctrl, cmd);
1839 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1842 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1846 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1852 if (argc != 3 && argc != 4) {
1853 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1859 res = os_snprintf(cmd, sizeof(cmd),
1860 "P2P_SERVICE_ADD %s %s %s %s",
1861 argv[0], argv[1], argv[2], argv[3]);
1863 res = os_snprintf(cmd, sizeof(cmd),
1864 "P2P_SERVICE_ADD %s %s %s",
1865 argv[0], argv[1], argv[2]);
1866 if (res < 0 || (size_t) res >= sizeof(cmd))
1868 cmd[sizeof(cmd) - 1] = '\0';
1869 return wpa_ctrl_command(ctrl, cmd);
1873 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1879 if (argc != 2 && argc != 3) {
1880 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1886 res = os_snprintf(cmd, sizeof(cmd),
1887 "P2P_SERVICE_DEL %s %s %s",
1888 argv[0], argv[1], argv[2]);
1890 res = os_snprintf(cmd, sizeof(cmd),
1891 "P2P_SERVICE_DEL %s %s",
1893 if (res < 0 || (size_t) res >= sizeof(cmd))
1895 cmd[sizeof(cmd) - 1] = '\0';
1896 return wpa_ctrl_command(ctrl, cmd);
1900 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1901 int argc, char *argv[])
1907 printf("Invalid P2P_REJECT command: needs one argument "
1908 "(peer address)\n");
1912 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
1913 if (res < 0 || (size_t) res >= sizeof(cmd))
1915 cmd[sizeof(cmd) - 1] = '\0';
1916 return wpa_ctrl_command(ctrl, cmd);
1920 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1921 int argc, char *argv[])
1927 printf("Invalid P2P_INVITE command: needs at least one "
1933 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
1934 argv[0], argv[1], argv[2]);
1936 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
1939 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
1940 if (res < 0 || (size_t) res >= sizeof(cmd))
1942 cmd[sizeof(cmd) - 1] = '\0';
1943 return wpa_ctrl_command(ctrl, cmd);
1947 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
1951 printf("Invalid 'p2p_peer' command - exactly one argument, "
1952 "P2P peer device address, is required.\n");
1955 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
1956 return wpa_ctrl_command(ctrl, buf);
1960 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
1961 char *addr, size_t addr_len,
1964 char buf[4096], *pos;
1968 if (ctrl_conn == NULL)
1970 len = sizeof(buf) - 1;
1971 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1974 printf("'%s' command timed out.\n", cmd);
1976 } else if (ret < 0) {
1977 printf("'%s' command failed.\n", cmd);
1982 if (memcmp(buf, "FAIL", 4) == 0)
1986 while (*pos != '\0' && *pos != '\n')
1989 os_strlcpy(addr, buf, addr_len);
1990 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
1991 printf("%s\n", addr);
1996 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
1998 char addr[32], cmd[64];
2001 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2003 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2004 addr, sizeof(addr), discovered))
2007 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2008 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2015 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2021 printf("Invalid P2P_SET command: needs two arguments (field, "
2026 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2027 if (res < 0 || (size_t) res >= sizeof(cmd))
2029 cmd[sizeof(cmd) - 1] = '\0';
2030 return wpa_ctrl_command(ctrl, cmd);
2034 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2036 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2040 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2043 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2047 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2053 if (argc != 0 && argc != 2 && argc != 4) {
2054 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2055 "(preferred duration, interval; in microsecods).\n"
2056 "Optional second pair can be used to provide "
2057 "acceptable values.\n");
2062 res = os_snprintf(cmd, sizeof(cmd),
2063 "P2P_PRESENCE_REQ %s %s %s %s",
2064 argv[0], argv[1], argv[2], argv[3]);
2066 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2069 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2070 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_ext_listen(struct wpa_ctrl *ctrl, int argc,
2083 if (argc != 0 && argc != 2) {
2084 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2085 "(availability period, availability interval; in "
2087 "Extended Listen Timing can be cancelled with this "
2088 "command when used without parameters.\n");
2093 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2096 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2097 if (res < 0 || (size_t) res >= sizeof(cmd))
2099 cmd[sizeof(cmd) - 1] = '\0';
2100 return wpa_ctrl_command(ctrl, cmd);
2103 #endif /* CONFIG_P2P */
2106 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2113 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2114 "(0/1 = disable/enable automatic reconnection)\n");
2117 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2118 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2119 printf("Too long STA_AUTOCONNECT command.\n");
2122 return wpa_ctrl_command(ctrl, cmd);
2126 enum wpa_cli_cmd_flags {
2127 cli_cmd_flag_none = 0x00,
2128 cli_cmd_flag_sensitive = 0x01
2131 struct wpa_cli_cmd {
2133 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2134 enum wpa_cli_cmd_flags flags;
2138 static struct wpa_cli_cmd wpa_cli_commands[] = {
2139 { "status", wpa_cli_cmd_status,
2141 "[verbose] = get current WPA/EAPOL/EAP status" },
2142 { "ping", wpa_cli_cmd_ping,
2144 "= pings wpa_supplicant" },
2145 { "note", wpa_cli_cmd_note,
2147 "<text> = add a note to wpa_supplicant debug log" },
2148 { "mib", wpa_cli_cmd_mib,
2150 "= get MIB variables (dot1x, dot11)" },
2151 { "help", wpa_cli_cmd_help,
2153 "= show this usage help" },
2154 { "interface", wpa_cli_cmd_interface,
2156 "[ifname] = show interfaces/select interface" },
2157 { "level", wpa_cli_cmd_level,
2159 "<debug level> = change debug level" },
2160 { "license", wpa_cli_cmd_license,
2162 "= show full wpa_cli license" },
2163 { "quit", wpa_cli_cmd_quit,
2166 { "set", wpa_cli_cmd_set,
2168 "= set variables (shows list of variables when run without "
2170 { "get", wpa_cli_cmd_get,
2172 "<name> = get information" },
2173 { "logon", wpa_cli_cmd_logon,
2175 "= IEEE 802.1X EAPOL state machine logon" },
2176 { "logoff", wpa_cli_cmd_logoff,
2178 "= IEEE 802.1X EAPOL state machine logoff" },
2179 { "pmksa", wpa_cli_cmd_pmksa,
2181 "= show PMKSA cache" },
2182 { "reassociate", wpa_cli_cmd_reassociate,
2184 "= force reassociation" },
2185 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2187 "<BSSID> = force preauthentication" },
2188 { "identity", wpa_cli_cmd_identity,
2190 "<network id> <identity> = configure identity for an SSID" },
2191 { "password", wpa_cli_cmd_password,
2192 cli_cmd_flag_sensitive,
2193 "<network id> <password> = configure password for an SSID" },
2194 { "new_password", wpa_cli_cmd_new_password,
2195 cli_cmd_flag_sensitive,
2196 "<network id> <password> = change password for an SSID" },
2197 { "pin", wpa_cli_cmd_pin,
2198 cli_cmd_flag_sensitive,
2199 "<network id> <pin> = configure pin for an SSID" },
2200 { "otp", wpa_cli_cmd_otp,
2201 cli_cmd_flag_sensitive,
2202 "<network id> <password> = configure one-time-password for an SSID"
2204 { "passphrase", wpa_cli_cmd_passphrase,
2205 cli_cmd_flag_sensitive,
2206 "<network id> <passphrase> = configure private key passphrase\n"
2208 { "bssid", wpa_cli_cmd_bssid,
2210 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2211 { "list_networks", wpa_cli_cmd_list_networks,
2213 "= list configured networks" },
2214 { "select_network", wpa_cli_cmd_select_network,
2216 "<network id> = select a network (disable others)" },
2217 { "enable_network", wpa_cli_cmd_enable_network,
2219 "<network id> = enable a network" },
2220 { "disable_network", wpa_cli_cmd_disable_network,
2222 "<network id> = disable a network" },
2223 { "add_network", wpa_cli_cmd_add_network,
2225 "= add a network" },
2226 { "remove_network", wpa_cli_cmd_remove_network,
2228 "<network id> = remove a network" },
2229 { "set_network", wpa_cli_cmd_set_network,
2230 cli_cmd_flag_sensitive,
2231 "<network id> <variable> <value> = set network variables (shows\n"
2232 " list of variables when run without arguments)" },
2233 { "get_network", wpa_cli_cmd_get_network,
2235 "<network id> <variable> = get network variables" },
2236 { "save_config", wpa_cli_cmd_save_config,
2238 "= save the current configuration" },
2239 { "disconnect", wpa_cli_cmd_disconnect,
2241 "= disconnect and wait for reassociate/reconnect command before\n"
2243 { "reconnect", wpa_cli_cmd_reconnect,
2245 "= like reassociate, but only takes effect if already disconnected"
2247 { "scan", wpa_cli_cmd_scan,
2249 "= request new BSS scan" },
2250 { "scan_results", wpa_cli_cmd_scan_results,
2252 "= get latest scan results" },
2253 { "bss", wpa_cli_cmd_bss,
2255 "<<idx> | <bssid>> = get detailed scan result info" },
2256 { "get_capability", wpa_cli_cmd_get_capability,
2258 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2259 { "reconfigure", wpa_cli_cmd_reconfigure,
2261 "= force wpa_supplicant to re-read its configuration file" },
2262 { "terminate", wpa_cli_cmd_terminate,
2264 "= terminate wpa_supplicant" },
2265 { "interface_add", wpa_cli_cmd_interface_add,
2267 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2268 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2270 { "interface_remove", wpa_cli_cmd_interface_remove,
2272 "<ifname> = removes the interface" },
2273 { "interface_list", wpa_cli_cmd_interface_list,
2275 "= list available interfaces" },
2276 { "ap_scan", wpa_cli_cmd_ap_scan,
2278 "<value> = set ap_scan parameter" },
2279 { "stkstart", wpa_cli_cmd_stkstart,
2281 "<addr> = request STK negotiation with <addr>" },
2282 { "ft_ds", wpa_cli_cmd_ft_ds,
2284 "<addr> = request over-the-DS FT with <addr>" },
2285 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2287 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2288 { "wps_pin", wpa_cli_cmd_wps_pin,
2289 cli_cmd_flag_sensitive,
2290 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2292 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2293 cli_cmd_flag_sensitive,
2294 "<PIN> = verify PIN checksum" },
2295 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2296 "Cancels the pending WPS operation" },
2297 #ifdef CONFIG_WPS_OOB
2298 { "wps_oob", wpa_cli_cmd_wps_oob,
2299 cli_cmd_flag_sensitive,
2300 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2301 #endif /* CONFIG_WPS_OOB */
2302 { "wps_reg", wpa_cli_cmd_wps_reg,
2303 cli_cmd_flag_sensitive,
2304 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2305 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2306 cli_cmd_flag_sensitive,
2307 "[params..] = enable/disable AP PIN" },
2308 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2310 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2311 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2313 "= stop Wi-Fi Protected Setup External Registrar" },
2314 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2315 cli_cmd_flag_sensitive,
2316 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2317 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2319 "<UUID> = accept an Enrollee PBC using External Registrar" },
2320 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2321 cli_cmd_flag_sensitive,
2322 "<UUID> <PIN> = learn AP configuration" },
2323 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2325 "<UUID> <network id> = set AP configuration for enrolling" },
2326 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2327 cli_cmd_flag_sensitive,
2328 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2329 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2331 "<addr> = request RSN authentication with <addr> in IBSS" },
2333 { "sta", wpa_cli_cmd_sta,
2335 "<addr> = get information about an associated station (AP)" },
2336 { "all_sta", wpa_cli_cmd_all_sta,
2338 "= get information about all associated stations (AP)" },
2339 #endif /* CONFIG_AP */
2340 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2341 "= notification of suspend/hibernate" },
2342 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2343 "= notification of resume/thaw" },
2344 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2345 "= drop SA without deauth/disassoc (test command)" },
2346 { "roam", wpa_cli_cmd_roam,
2348 "<addr> = roam to the specified BSS" },
2350 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2351 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2352 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2353 "= stop P2P Devices search" },
2354 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2355 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2356 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2357 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2358 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2359 "<ifname> = remote P2P group interface (terminate group if GO)" },
2360 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2361 "= add a new P2P group (local end as GO)" },
2362 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2363 "<addr> <method> = request provisioning discovery" },
2364 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2366 "= get the passphrase for a group (GO only)" },
2367 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2369 "<addr> <TLVs> = schedule service discovery request" },
2370 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2372 "<id> = cancel pending service discovery request" },
2373 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2375 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2376 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2378 "= indicate change in local services" },
2379 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2381 "<external> = set external processing of service discovery" },
2382 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2384 "= remove all stored service entries" },
2385 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2387 "<bonjour|upnp> <query|version> <response|service> = add a local "
2389 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2391 "<bonjour|upnp> <query|version> [|service] = remove a local "
2393 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2395 "<addr> = reject connection attempts from a specific peer" },
2396 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2398 "<cmd> [peer=addr] = invite peer" },
2399 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2400 "[discovered] = list known (optionally, only fully discovered) P2P "
2402 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2403 "<address> = show information about known P2P peer" },
2404 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2405 "<field> <value> = set a P2P parameter" },
2406 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2407 "= flush P2P state" },
2408 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2409 "= cancel P2P group formation" },
2410 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2411 "[<duration> <interval>] [<duration> <interval>] = request GO "
2413 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2414 "[<period> <interval>] = set extended listen timing" },
2415 #endif /* CONFIG_P2P */
2416 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2417 "<0/1> = disable/enable automatic reconnection" },
2418 { NULL, NULL, cli_cmd_flag_none, NULL }
2423 * Prints command usage, lines are padded with the specified string.
2425 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2430 printf("%s%s ", pad, cmd->cmd);
2431 for (n = 0; (c = cmd->usage[n]); n++) {
2440 static void print_help(void)
2443 printf("commands:\n");
2444 for (n = 0; wpa_cli_commands[n].cmd; n++)
2445 print_cmd_help(&wpa_cli_commands[n], " ");
2449 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2451 const char *c, *delim;
2455 delim = os_strchr(cmd, ' ');
2459 len = os_strlen(cmd);
2461 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2462 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2463 return (wpa_cli_commands[n].flags &
2464 cli_cmd_flag_sensitive);
2470 static char ** wpa_list_cmd_list(void)
2475 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2476 res = os_zalloc(count * sizeof(char *));
2480 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2481 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2490 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2495 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2496 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2498 printf("\r%s\n", wpa_cli_commands[i].usage);
2508 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2514 end = os_strchr(str, ' ');
2515 if (end == NULL || str + pos < end)
2516 return wpa_list_cmd_list();
2518 cmd = os_malloc(pos + 1);
2521 os_memcpy(cmd, str, pos);
2522 cmd[end - str] = '\0';
2523 res = wpa_cli_cmd_completion(cmd, str, pos);
2529 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2531 struct wpa_cli_cmd *cmd, *match = NULL;
2536 cmd = wpa_cli_commands;
2538 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2541 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2542 /* we have an exact match */
2552 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2553 cmd = wpa_cli_commands;
2555 if (os_strncasecmp(cmd->cmd, argv[0],
2556 os_strlen(argv[0])) == 0) {
2557 printf(" %s", cmd->cmd);
2563 } else if (count == 0) {
2564 printf("Unknown command '%s'\n", argv[0]);
2567 ret = match->handler(ctrl, argc - 1, &argv[1]);
2574 static int str_match(const char *a, const char *b)
2576 return os_strncmp(a, b, os_strlen(b)) == 0;
2580 static int wpa_cli_exec(const char *program, const char *arg1,
2588 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2589 cmd = os_malloc(len);
2592 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2593 if (res < 0 || (size_t) res >= len) {
2597 cmd[len - 1] = '\0';
2599 if (system(cmd) < 0)
2601 #endif /* _WIN32_WCE */
2608 static void wpa_cli_action_process(const char *msg)
2611 char *copy = NULL, *id, *pos2;
2616 pos = os_strchr(pos, '>');
2623 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2625 os_unsetenv("WPA_ID");
2626 os_unsetenv("WPA_ID_STR");
2627 os_unsetenv("WPA_CTRL_DIR");
2629 pos = os_strstr(pos, "[id=");
2631 copy = os_strdup(pos + 4);
2635 while (*pos2 && *pos2 != ' ')
2639 os_setenv("WPA_ID", id, 1);
2640 while (*pos2 && *pos2 != '=')
2645 while (*pos2 && *pos2 != ']')
2648 os_setenv("WPA_ID_STR", id, 1);
2652 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
2654 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
2655 wpa_cli_connected = 1;
2656 wpa_cli_last_id = new_id;
2657 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
2659 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
2660 if (wpa_cli_connected) {
2661 wpa_cli_connected = 0;
2662 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
2664 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
2665 wpa_cli_exec(action_file, ctrl_ifname, pos);
2666 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
2667 wpa_cli_exec(action_file, ctrl_ifname, pos);
2668 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
2669 wpa_cli_exec(action_file, ctrl_ifname, pos);
2670 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
2671 wpa_cli_exec(action_file, ctrl_ifname, pos);
2672 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
2673 wpa_cli_exec(action_file, ctrl_ifname, pos);
2674 } else if (str_match(pos, WPS_EVENT_FAIL)) {
2675 wpa_cli_exec(action_file, ctrl_ifname, pos);
2676 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
2677 printf("wpa_supplicant is terminating - stop monitoring\n");
2683 #ifndef CONFIG_ANSI_C_EXTRA
2684 static void wpa_cli_action_cb(char *msg, size_t len)
2686 wpa_cli_action_process(msg);
2688 #endif /* CONFIG_ANSI_C_EXTRA */
2691 static void wpa_cli_reconnect(void)
2693 wpa_cli_close_connection();
2694 wpa_cli_open_connection(ctrl_ifname, 1);
2698 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
2700 if (ctrl_conn == NULL) {
2701 wpa_cli_reconnect();
2704 while (wpa_ctrl_pending(ctrl) > 0) {
2706 size_t len = sizeof(buf) - 1;
2707 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
2710 wpa_cli_action_process(buf);
2712 if (wpa_cli_show_event(buf)) {
2714 printf("\r%s\n", buf);
2719 printf("Could not read pending message.\n");
2724 if (wpa_ctrl_pending(ctrl) < 0) {
2725 printf("Connection to wpa_supplicant lost - trying to "
2727 wpa_cli_reconnect();
2733 static int tokenize_cmd(char *cmd, char *argv[])
2746 if (argc == max_args)
2749 char *pos2 = os_strrchr(pos, '"');
2753 while (*pos != '\0' && *pos != ' ')
2763 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
2765 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2766 printf("Connection to wpa_supplicant lost - trying to "
2768 wpa_cli_close_connection();
2771 wpa_cli_reconnect();
2772 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
2776 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
2782 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
2784 wpa_cli_recv_pending(mon_conn, 0);
2788 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
2790 char *argv[max_args];
2792 argc = tokenize_cmd(cmd, argv);
2794 wpa_request(ctrl_conn, argc, argv);
2798 static void wpa_cli_edit_eof_cb(void *ctx)
2804 static void wpa_cli_interactive(void)
2807 printf("\nInteractive mode\n\n");
2809 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
2810 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, NULL);
2811 edit_set_filter_history_cb(wpa_cli_edit_filter_history_cb);
2812 edit_set_completion_cb(wpa_cli_edit_completion_cb);
2813 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
2818 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
2819 wpa_cli_close_connection();
2823 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2825 #ifdef CONFIG_ANSI_C_EXTRA
2826 /* TODO: ANSI C version(?) */
2827 printf("Action processing not supported in ANSI C build.\n");
2828 #else /* CONFIG_ANSI_C_EXTRA */
2832 char buf[256]; /* note: large enough to fit in unsolicited messages */
2835 fd = wpa_ctrl_get_fd(ctrl);
2837 while (!wpa_cli_quit) {
2840 tv.tv_sec = ping_interval;
2842 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2843 if (res < 0 && errno != EINTR) {
2848 if (FD_ISSET(fd, &rfds))
2849 wpa_cli_recv_pending(ctrl, 1);
2851 /* verify that connection is still working */
2852 len = sizeof(buf) - 1;
2853 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2854 wpa_cli_action_cb) < 0 ||
2855 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2856 printf("wpa_supplicant did not reply to PING "
2857 "command - exiting\n");
2862 #endif /* CONFIG_ANSI_C_EXTRA */
2866 static void wpa_cli_cleanup(void)
2868 wpa_cli_close_connection();
2870 os_daemonize_terminate(pid_file);
2872 os_program_deinit();
2875 static void wpa_cli_terminate(int sig)
2882 static char * wpa_cli_get_default_ifname(void)
2884 char *ifname = NULL;
2886 #ifdef CONFIG_CTRL_IFACE_UNIX
2887 struct dirent *dent;
2888 DIR *dir = opendir(ctrl_iface_dir);
2891 while ((dent = readdir(dir))) {
2892 #ifdef _DIRENT_HAVE_D_TYPE
2894 * Skip the file if it is not a socket. Also accept
2895 * DT_UNKNOWN (0) in case the C library or underlying
2896 * file system does not support d_type.
2898 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2900 #endif /* _DIRENT_HAVE_D_TYPE */
2901 if (os_strcmp(dent->d_name, ".") == 0 ||
2902 os_strcmp(dent->d_name, "..") == 0)
2904 printf("Selected interface '%s'\n", dent->d_name);
2905 ifname = os_strdup(dent->d_name);
2909 #endif /* CONFIG_CTRL_IFACE_UNIX */
2911 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2912 char buf[2048], *pos;
2914 struct wpa_ctrl *ctrl;
2917 ctrl = wpa_ctrl_open(NULL);
2921 len = sizeof(buf) - 1;
2922 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2925 pos = os_strchr(buf, '\n');
2928 ifname = os_strdup(buf);
2930 wpa_ctrl_close(ctrl);
2931 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2937 int main(int argc, char *argv[])
2939 int warning_displayed = 0;
2943 const char *global = NULL;
2945 if (os_program_init())
2949 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2954 action_file = optarg;
2963 ping_interval = atoi(optarg);
2969 printf("%s\n", wpa_cli_version);
2972 os_free(ctrl_ifname);
2973 ctrl_ifname = os_strdup(optarg);
2976 ctrl_iface_dir = optarg;
2987 interactive = (argc == optind) && (action_file == NULL);
2990 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2996 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2997 ctrl_conn = wpa_ctrl_open(NULL);
2998 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2999 ctrl_conn = wpa_ctrl_open(global);
3000 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3001 if (ctrl_conn == NULL) {
3002 perror("Failed to connect to wpa_supplicant - "
3009 signal(SIGINT, wpa_cli_terminate);
3010 signal(SIGTERM, wpa_cli_terminate);
3011 #endif /* _WIN32_WCE */
3013 if (ctrl_ifname == NULL)
3014 ctrl_ifname = wpa_cli_get_default_ifname();
3018 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3019 if (warning_displayed)
3020 printf("Connection established.\n");
3024 if (!warning_displayed) {
3025 printf("Could not connect to wpa_supplicant - "
3027 warning_displayed = 1;
3034 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3035 perror("Failed to connect to wpa_supplicant - "
3041 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3042 wpa_cli_attached = 1;
3044 printf("Warning: Failed to attach to "
3045 "wpa_supplicant.\n");
3051 if (daemonize && os_daemonize(pid_file))
3055 wpa_cli_interactive();
3056 else if (action_file)
3057 wpa_cli_action(ctrl_conn);
3059 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3061 os_free(ctrl_ifname);
3068 #else /* CONFIG_CTRL_IFACE */
3069 int main(int argc, char *argv[])
3071 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3074 #endif /* CONFIG_CTRL_IFACE */