2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
22 #ifdef CONFIG_READLINE
23 #include <readline/readline.h>
24 #include <readline/history.h>
25 #endif /* CONFIG_READLINE */
26 #ifdef CONFIG_WPA_CLI_FORK
28 #endif /* CONFIG_WPA_CLI_FORK */
30 #include "common/wpa_ctrl.h"
32 #include "common/version.h"
35 static const char *wpa_cli_version =
36 "wpa_cli v" VERSION_STR "\n"
37 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
40 static const char *wpa_cli_license =
41 "This program is free software. You can distribute it and/or modify it\n"
42 "under the terms of the GNU General Public License version 2.\n"
44 "Alternatively, this software may be distributed under the terms of the\n"
45 "BSD license. See README and COPYING for more details.\n";
47 static const char *wpa_cli_full_license =
48 "This program is free software; you can redistribute it and/or modify\n"
49 "it under the terms of the GNU General Public License version 2 as\n"
50 "published by the Free Software Foundation.\n"
52 "This program is distributed in the hope that it will be useful,\n"
53 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
54 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
55 "GNU General Public License for more details.\n"
57 "You should have received a copy of the GNU General Public License\n"
58 "along with this program; if not, write to the Free Software\n"
59 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
61 "Alternatively, this software may be distributed under the terms of the\n"
64 "Redistribution and use in source and binary forms, with or without\n"
65 "modification, are permitted provided that the following conditions are\n"
68 "1. Redistributions of source code must retain the above copyright\n"
69 " notice, this list of conditions and the following disclaimer.\n"
71 "2. Redistributions in binary form must reproduce the above copyright\n"
72 " notice, this list of conditions and the following disclaimer in the\n"
73 " documentation and/or other materials provided with the distribution.\n"
75 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
76 " names of its contributors may be used to endorse or promote products\n"
77 " derived from this software without specific prior written permission.\n"
79 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
80 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
81 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
82 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
83 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
84 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
85 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
86 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
87 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
88 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
89 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
92 static struct wpa_ctrl *ctrl_conn;
93 static struct wpa_ctrl *mon_conn;
94 #ifdef CONFIG_WPA_CLI_FORK
95 static pid_t mon_pid = 0;
96 #endif /* CONFIG_WPA_CLI_FORK */
97 static int wpa_cli_quit = 0;
98 static int wpa_cli_attached = 0;
99 static int wpa_cli_connected = 0;
100 static int wpa_cli_last_id = 0;
101 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
102 static char *ctrl_ifname = NULL;
103 static const char *pid_file = NULL;
104 static const char *action_file = NULL;
105 static int ping_interval = 5;
106 static int interactive = 0;
109 static void print_help();
112 static void usage(void)
114 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
115 "[-a<action file>] \\\n"
116 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
118 " -h = help (show this usage text)\n"
119 " -v = shown version information\n"
120 " -a = run in daemon mode executing the action file based on "
123 " -B = run a daemon in the background\n"
124 " default path: /var/run/wpa_supplicant\n"
125 " default interface: first interface found in socket path\n");
130 #ifdef CONFIG_WPA_CLI_FORK
131 static int in_query = 0;
133 static void wpa_cli_monitor_sig(int sig)
137 else if (sig == SIGUSR2)
141 static void wpa_cli_monitor(void)
144 size_t len = sizeof(buf) - 1;
148 signal(SIGUSR1, wpa_cli_monitor_sig);
149 signal(SIGUSR2, wpa_cli_monitor_sig);
152 int s = wpa_ctrl_get_fd(mon_conn);
157 if (select(s + 1, &rfds, NULL, NULL, &tv) < 0) {
163 if (mon_conn == NULL)
165 if (FD_ISSET(s, &rfds)) {
166 len = sizeof(buf) - 1;
167 int res = wpa_ctrl_recv(mon_conn, buf, &len);
169 perror("wpa_ctrl_recv");
176 kill(getppid(), SIGUSR1);
180 #endif /* CONFIG_WPA_CLI_FORK */
183 static int wpa_cli_open_connection(const char *ifname, int attach)
185 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
186 ctrl_conn = wpa_ctrl_open(ifname);
187 if (ctrl_conn == NULL)
190 if (attach && interactive)
191 mon_conn = wpa_ctrl_open(ifname);
194 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
201 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
202 cfile = os_malloc(flen);
205 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
206 if (res < 0 || res >= flen) {
211 ctrl_conn = wpa_ctrl_open(cfile);
212 if (ctrl_conn == NULL) {
217 if (attach && interactive)
218 mon_conn = wpa_ctrl_open(cfile);
222 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
225 if (wpa_ctrl_attach(mon_conn) == 0) {
226 wpa_cli_attached = 1;
228 printf("Warning: Failed to attach to "
229 "wpa_supplicant.\n");
233 #ifdef CONFIG_WPA_CLI_FORK
246 #endif /* CONFIG_WPA_CLI_FORK */
253 static void wpa_cli_close_connection(void)
255 if (ctrl_conn == NULL)
258 #ifdef CONFIG_WPA_CLI_FORK
261 kill(mon_pid, SIGPIPE);
265 #endif /* CONFIG_WPA_CLI_FORK */
267 if (wpa_cli_attached) {
268 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
269 wpa_cli_attached = 0;
271 wpa_ctrl_close(ctrl_conn);
274 wpa_ctrl_close(mon_conn);
280 static void wpa_cli_msg_cb(char *msg, size_t len)
286 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
292 if (ctrl_conn == NULL) {
293 printf("Not connected to wpa_supplicant - command dropped.\n");
296 len = sizeof(buf) - 1;
297 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
300 printf("'%s' command timed out.\n", cmd);
302 } else if (ret < 0) {
303 printf("'%s' command failed.\n", cmd);
314 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
316 return _wpa_ctrl_command(ctrl, cmd, 1);
320 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
322 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
323 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
327 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
329 return wpa_ctrl_command(ctrl, "PING");
333 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
335 return wpa_ctrl_command(ctrl, "MIB");
339 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
341 return wpa_ctrl_command(ctrl, "PMKSA");
345 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
352 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
354 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
359 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
366 static void wpa_cli_show_variables(void)
368 printf("set variables:\n"
369 " EAPOL::heldPeriod (EAPOL state machine held period, "
371 " EAPOL::authPeriod (EAPOL state machine authentication "
372 "period, in seconds)\n"
373 " EAPOL::startPeriod (EAPOL state machine start period, in "
375 " EAPOL::maxStart (EAPOL state machine maximum start "
377 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
379 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
380 " threshold\n\tpercentage)\n"
381 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
382 "security\n\tassociation in seconds)\n");
386 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
392 wpa_cli_show_variables();
397 printf("Invalid SET command: needs two arguments (variable "
398 "name and value)\n");
402 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
403 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
404 printf("Too long SET command.\n");
407 return wpa_ctrl_command(ctrl, cmd);
411 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
413 return wpa_ctrl_command(ctrl, "LOGOFF");
417 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
419 return wpa_ctrl_command(ctrl, "LOGON");
423 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
426 return wpa_ctrl_command(ctrl, "REASSOCIATE");
430 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
437 printf("Invalid PREAUTH command: needs one argument "
442 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
443 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
444 printf("Too long PREAUTH command.\n");
447 return wpa_ctrl_command(ctrl, cmd);
451 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
457 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
461 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
462 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
463 printf("Too long AP_SCAN command.\n");
466 return wpa_ctrl_command(ctrl, cmd);
470 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
477 printf("Invalid STKSTART command: needs one argument "
478 "(Peer STA MAC address)\n");
482 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
483 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
484 printf("Too long STKSTART command.\n");
487 return wpa_ctrl_command(ctrl, cmd);
491 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
497 printf("Invalid FT_DS command: needs one argument "
498 "(Target AP MAC address)\n");
502 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
503 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
504 printf("Too long FT_DS command.\n");
507 return wpa_ctrl_command(ctrl, cmd);
511 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
518 return wpa_ctrl_command(ctrl, "WPS_PBC");
522 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
523 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
524 printf("Too long WPS_PBC command.\n");
527 return wpa_ctrl_command(ctrl, cmd);
531 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
537 printf("Invalid WPS_PIN command: need one or two arguments:\n"
538 "- BSSID: use 'any' to select any\n"
539 "- PIN: optional, used only with devices that have no "
545 /* Use dynamically generated PIN (returned as reply) */
546 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
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);
554 /* Use hardcoded PIN from a label */
555 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
556 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
557 printf("Too long WPS_PIN command.\n");
560 return wpa_ctrl_command(ctrl, cmd);
564 #ifdef CONFIG_WPS_OOB
565 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
570 if (argc != 3 && argc != 4) {
571 printf("Invalid WPS_OOB command: need three or four "
573 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
574 "- PATH: path of OOB device like '/mnt'\n"
575 "- METHOD: OOB method 'pin-e' or 'pin-r', "
577 "- DEV_NAME: (only for NFC) device name like "
583 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
584 argv[0], argv[1], argv[2]);
586 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
587 argv[0], argv[1], argv[2], argv[3]);
588 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
589 printf("Too long WPS_OOB command.\n");
592 return wpa_ctrl_command(ctrl, cmd);
594 #endif /* CONFIG_WPS_OOB */
597 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
603 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
605 else if (argc == 5 || argc == 6) {
606 char ssid_hex[2 * 32 + 1];
607 char key_hex[2 * 64 + 1];
611 for (i = 0; i < 32; i++) {
612 if (argv[2][i] == '\0')
614 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
619 for (i = 0; i < 64; i++) {
620 if (argv[5][i] == '\0')
622 os_snprintf(&key_hex[i * 2], 3, "%02x",
627 res = os_snprintf(cmd, sizeof(cmd),
628 "WPS_REG %s %s %s %s %s %s",
629 argv[0], argv[1], ssid_hex, argv[3], argv[4],
632 printf("Invalid WPS_REG command: need two arguments:\n"
633 "- BSSID: use 'any' to select any\n"
635 printf("Alternatively, six arguments can be used to "
636 "reconfigure the AP:\n"
637 "- BSSID: use 'any' to select any\n"
640 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
641 "- new encr (NONE, WEP, TKIP, CCMP)\n"
646 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
647 printf("Too long WPS_REG command.\n");
650 return wpa_ctrl_command(ctrl, cmd);
654 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
659 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
660 return wpa_ctrl_command(ctrl, cmd);
662 return wpa_ctrl_command(ctrl, "WPS_ER_START");
666 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
669 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
674 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
681 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
682 "- UUID: use 'any' to select any\n"
683 "- PIN: Enrollee PIN\n");
687 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
689 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
690 printf("Too long WPS_ER_PIN command.\n");
693 return wpa_ctrl_command(ctrl, cmd);
697 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
704 printf("Invalid WPS_ER_PBC command: need one argument:\n"
705 "- UUID: Specify the Enrollee\n");
709 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
711 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
712 printf("Too long WPS_ER_PBC command.\n");
715 return wpa_ctrl_command(ctrl, cmd);
719 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
726 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
727 "- UUID: specify which AP to use\n"
732 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
734 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
735 printf("Too long WPS_ER_LEARN command.\n");
738 return wpa_ctrl_command(ctrl, cmd);
742 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
748 if (argc == 5 || argc == 6) {
749 char ssid_hex[2 * 32 + 1];
750 char key_hex[2 * 64 + 1];
754 for (i = 0; i < 32; i++) {
755 if (argv[2][i] == '\0')
757 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
762 for (i = 0; i < 64; i++) {
763 if (argv[5][i] == '\0')
765 os_snprintf(&key_hex[i * 2], 3, "%02x",
770 res = os_snprintf(cmd, sizeof(cmd),
771 "WPS_ER_CONFIG %s %s %s %s %s %s",
772 argv[0], argv[1], ssid_hex, argv[3], argv[4],
775 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
779 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
780 "- new encr (NONE, WEP, TKIP, CCMP)\n"
785 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
786 printf("Too long WPS_ER_CONFIG command.\n");
789 return wpa_ctrl_command(ctrl, cmd);
793 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
799 printf("Invalid IBSS_RSN command: needs one argument "
800 "(Peer STA MAC address)\n");
804 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
805 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
806 printf("Too long IBSS_RSN command.\n");
809 return wpa_ctrl_command(ctrl, cmd);
813 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
819 printf("Invalid LEVEL command: needs one argument (debug "
823 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
824 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
825 printf("Too long LEVEL command.\n");
828 return wpa_ctrl_command(ctrl, cmd);
832 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
834 char cmd[256], *pos, *end;
838 printf("Invalid IDENTITY command: needs two arguments "
839 "(network id and identity)\n");
843 end = cmd + sizeof(cmd);
845 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
847 if (ret < 0 || ret >= end - pos) {
848 printf("Too long IDENTITY command.\n");
852 for (i = 2; i < argc; i++) {
853 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
854 if (ret < 0 || ret >= end - pos) {
855 printf("Too long IDENTITY command.\n");
861 return wpa_ctrl_command(ctrl, cmd);
865 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
867 char cmd[256], *pos, *end;
871 printf("Invalid PASSWORD command: needs two arguments "
872 "(network id and password)\n");
876 end = cmd + sizeof(cmd);
878 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
880 if (ret < 0 || ret >= end - pos) {
881 printf("Too long PASSWORD command.\n");
885 for (i = 2; i < argc; i++) {
886 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
887 if (ret < 0 || ret >= end - pos) {
888 printf("Too long PASSWORD command.\n");
894 return wpa_ctrl_command(ctrl, cmd);
898 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
901 char cmd[256], *pos, *end;
905 printf("Invalid NEW_PASSWORD command: needs two arguments "
906 "(network id and password)\n");
910 end = cmd + sizeof(cmd);
912 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
914 if (ret < 0 || ret >= end - pos) {
915 printf("Too long NEW_PASSWORD command.\n");
919 for (i = 2; i < argc; i++) {
920 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
921 if (ret < 0 || ret >= end - pos) {
922 printf("Too long NEW_PASSWORD command.\n");
928 return wpa_ctrl_command(ctrl, cmd);
932 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
934 char cmd[256], *pos, *end;
938 printf("Invalid PIN command: needs two arguments "
939 "(network id and pin)\n");
943 end = cmd + sizeof(cmd);
945 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
947 if (ret < 0 || ret >= end - pos) {
948 printf("Too long PIN command.\n");
952 for (i = 2; i < argc; i++) {
953 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
954 if (ret < 0 || ret >= end - pos) {
955 printf("Too long PIN command.\n");
960 return wpa_ctrl_command(ctrl, cmd);
964 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
966 char cmd[256], *pos, *end;
970 printf("Invalid OTP command: needs two arguments (network "
971 "id and password)\n");
975 end = cmd + sizeof(cmd);
977 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
979 if (ret < 0 || ret >= end - pos) {
980 printf("Too long OTP command.\n");
984 for (i = 2; i < argc; i++) {
985 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
986 if (ret < 0 || ret >= end - pos) {
987 printf("Too long OTP command.\n");
993 return wpa_ctrl_command(ctrl, cmd);
997 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1000 char cmd[256], *pos, *end;
1004 printf("Invalid PASSPHRASE command: needs two arguments "
1005 "(network id and passphrase)\n");
1009 end = cmd + sizeof(cmd);
1011 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1013 if (ret < 0 || ret >= end - pos) {
1014 printf("Too long PASSPHRASE command.\n");
1018 for (i = 2; i < argc; i++) {
1019 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1020 if (ret < 0 || ret >= end - pos) {
1021 printf("Too long PASSPHRASE command.\n");
1027 return wpa_ctrl_command(ctrl, cmd);
1031 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1033 char cmd[256], *pos, *end;
1037 printf("Invalid BSSID command: needs two arguments (network "
1042 end = cmd + sizeof(cmd);
1044 ret = os_snprintf(pos, end - pos, "BSSID");
1045 if (ret < 0 || ret >= end - pos) {
1046 printf("Too long BSSID command.\n");
1050 for (i = 0; i < argc; i++) {
1051 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1052 if (ret < 0 || ret >= end - pos) {
1053 printf("Too long BSSID command.\n");
1059 return wpa_ctrl_command(ctrl, cmd);
1063 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1066 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1070 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1077 printf("Invalid SELECT_NETWORK command: needs one argument "
1082 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1083 if (res < 0 || (size_t) res >= sizeof(cmd))
1085 cmd[sizeof(cmd) - 1] = '\0';
1087 return wpa_ctrl_command(ctrl, cmd);
1091 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1098 printf("Invalid ENABLE_NETWORK command: needs one argument "
1103 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1104 if (res < 0 || (size_t) res >= sizeof(cmd))
1106 cmd[sizeof(cmd) - 1] = '\0';
1108 return wpa_ctrl_command(ctrl, cmd);
1112 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1119 printf("Invalid DISABLE_NETWORK command: needs one argument "
1124 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1125 if (res < 0 || (size_t) res >= sizeof(cmd))
1127 cmd[sizeof(cmd) - 1] = '\0';
1129 return wpa_ctrl_command(ctrl, cmd);
1133 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1136 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1140 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1147 printf("Invalid REMOVE_NETWORK command: needs one argument "
1152 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1153 if (res < 0 || (size_t) res >= sizeof(cmd))
1155 cmd[sizeof(cmd) - 1] = '\0';
1157 return wpa_ctrl_command(ctrl, cmd);
1161 static void wpa_cli_show_network_variables(void)
1163 printf("set_network variables:\n"
1164 " ssid (network name, SSID)\n"
1165 " psk (WPA passphrase or pre-shared key)\n"
1166 " key_mgmt (key management protocol)\n"
1167 " identity (EAP identity)\n"
1168 " password (EAP password)\n"
1171 "Note: Values are entered in the same format as the "
1172 "configuration file is using,\n"
1173 "i.e., strings values need to be inside double quotation "
1175 "For example: set_network 1 ssid \"network name\"\n"
1177 "Please see wpa_supplicant.conf documentation for full list "
1178 "of\navailable variables.\n");
1182 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1189 wpa_cli_show_network_variables();
1194 printf("Invalid SET_NETWORK command: needs three arguments\n"
1195 "(network id, variable name, and value)\n");
1199 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1200 argv[0], argv[1], argv[2]);
1201 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1202 printf("Too long SET_NETWORK command.\n");
1205 return wpa_ctrl_command(ctrl, cmd);
1209 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1216 wpa_cli_show_network_variables();
1221 printf("Invalid GET_NETWORK command: needs two arguments\n"
1222 "(network id and variable name)\n");
1226 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1228 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1229 printf("Too long GET_NETWORK command.\n");
1232 return wpa_ctrl_command(ctrl, cmd);
1236 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1239 return wpa_ctrl_command(ctrl, "DISCONNECT");
1243 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1246 return wpa_ctrl_command(ctrl, "RECONNECT");
1250 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1253 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1257 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1259 return wpa_ctrl_command(ctrl, "SCAN");
1263 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1266 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1270 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1276 printf("Invalid BSS command: need one argument (index or "
1281 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1282 if (res < 0 || (size_t) res >= sizeof(cmd))
1284 cmd[sizeof(cmd) - 1] = '\0';
1286 return wpa_ctrl_command(ctrl, cmd);
1290 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1296 if (argc < 1 || argc > 2) {
1297 printf("Invalid GET_CAPABILITY command: need either one or "
1302 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1303 printf("Invalid GET_CAPABILITY command: second argument, "
1304 "if any, must be 'strict'\n");
1308 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1309 (argc == 2) ? " strict" : "");
1310 if (res < 0 || (size_t) res >= sizeof(cmd))
1312 cmd[sizeof(cmd) - 1] = '\0';
1314 return wpa_ctrl_command(ctrl, cmd);
1318 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1320 printf("Available interfaces:\n");
1321 return wpa_ctrl_command(ctrl, "INTERFACES");
1325 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1328 wpa_cli_list_interfaces(ctrl);
1332 wpa_cli_close_connection();
1333 os_free(ctrl_ifname);
1334 ctrl_ifname = os_strdup(argv[0]);
1336 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1337 printf("Connected to interface '%s.\n", ctrl_ifname);
1339 printf("Could not connect to interface '%s' - re-trying\n",
1346 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1349 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1353 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1356 return wpa_ctrl_command(ctrl, "TERMINATE");
1360 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1367 printf("Invalid INTERFACE_ADD command: needs at least one "
1368 "argument (interface name)\n"
1369 "All arguments: ifname confname driver ctrl_interface "
1370 "driver_param bridge_name\n");
1375 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1376 * <driver_param>TAB<bridge_name>
1378 res = os_snprintf(cmd, sizeof(cmd),
1379 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1381 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1382 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1383 argc > 5 ? argv[5] : "");
1384 if (res < 0 || (size_t) res >= sizeof(cmd))
1386 cmd[sizeof(cmd) - 1] = '\0';
1387 return wpa_ctrl_command(ctrl, cmd);
1391 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1398 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1399 "(interface name)\n");
1403 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1404 if (res < 0 || (size_t) res >= sizeof(cmd))
1406 cmd[sizeof(cmd) - 1] = '\0';
1407 return wpa_ctrl_command(ctrl, cmd);
1411 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1414 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1419 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1423 printf("Invalid 'sta' command - exactly one argument, STA "
1424 "address, is required.\n");
1427 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1428 return wpa_ctrl_command(ctrl, buf);
1432 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1433 char *addr, size_t addr_len)
1435 char buf[4096], *pos;
1439 if (ctrl_conn == NULL) {
1440 printf("Not connected to hostapd - command dropped.\n");
1443 len = sizeof(buf) - 1;
1444 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1447 printf("'%s' command timed out.\n", cmd);
1449 } else if (ret < 0) {
1450 printf("'%s' command failed.\n", cmd);
1455 if (memcmp(buf, "FAIL", 4) == 0)
1460 while (*pos != '\0' && *pos != '\n')
1463 os_strlcpy(addr, buf, addr_len);
1468 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1470 char addr[32], cmd[64];
1472 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1475 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1476 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1480 #endif /* CONFIG_AP */
1483 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1485 return wpa_ctrl_command(ctrl, "SUSPEND");
1489 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1491 return wpa_ctrl_command(ctrl, "RESUME");
1495 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1497 return wpa_ctrl_command(ctrl, "DROP_SA");
1501 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1507 printf("Invalid ROAM command: needs one argument "
1508 "(target AP's BSSID)\n");
1512 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1513 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1514 printf("Too long ROAM command.\n");
1517 return wpa_ctrl_command(ctrl, cmd);
1521 enum wpa_cli_cmd_flags {
1522 cli_cmd_flag_none = 0x00,
1523 cli_cmd_flag_sensitive = 0x01
1526 struct wpa_cli_cmd {
1528 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1529 enum wpa_cli_cmd_flags flags;
1533 static struct wpa_cli_cmd wpa_cli_commands[] = {
1534 { "status", wpa_cli_cmd_status,
1536 "[verbose] = get current WPA/EAPOL/EAP status" },
1537 { "ping", wpa_cli_cmd_ping,
1539 "= pings wpa_supplicant" },
1540 { "mib", wpa_cli_cmd_mib,
1542 "= get MIB variables (dot1x, dot11)" },
1543 { "help", wpa_cli_cmd_help,
1545 "= show this usage help" },
1546 { "interface", wpa_cli_cmd_interface,
1548 "[ifname] = show interfaces/select interface" },
1549 { "level", wpa_cli_cmd_level,
1551 "<debug level> = change debug level" },
1552 { "license", wpa_cli_cmd_license,
1554 "= show full wpa_cli license" },
1555 { "quit", wpa_cli_cmd_quit,
1558 { "set", wpa_cli_cmd_set,
1560 "= set variables (shows list of variables when run without "
1562 { "logon", wpa_cli_cmd_logon,
1564 "= IEEE 802.1X EAPOL state machine logon" },
1565 { "logoff", wpa_cli_cmd_logoff,
1567 "= IEEE 802.1X EAPOL state machine logoff" },
1568 { "pmksa", wpa_cli_cmd_pmksa,
1570 "= show PMKSA cache" },
1571 { "reassociate", wpa_cli_cmd_reassociate,
1573 "= force reassociation" },
1574 { "preauthenticate", wpa_cli_cmd_preauthenticate,
1576 "<BSSID> = force preauthentication" },
1577 { "identity", wpa_cli_cmd_identity,
1579 "<network id> <identity> = configure identity for an SSID" },
1580 { "password", wpa_cli_cmd_password,
1581 cli_cmd_flag_sensitive,
1582 "<network id> <password> = configure password for an SSID" },
1583 { "new_password", wpa_cli_cmd_new_password,
1584 cli_cmd_flag_sensitive,
1585 "<network id> <password> = change password for an SSID" },
1586 { "pin", wpa_cli_cmd_pin,
1587 cli_cmd_flag_sensitive,
1588 "<network id> <pin> = configure pin for an SSID" },
1589 { "otp", wpa_cli_cmd_otp,
1590 cli_cmd_flag_sensitive,
1591 "<network id> <password> = configure one-time-password for an SSID"
1593 { "passphrase", wpa_cli_cmd_passphrase,
1594 cli_cmd_flag_sensitive,
1595 "<network id> <passphrase> = configure private key passphrase\n"
1597 { "bssid", wpa_cli_cmd_bssid,
1599 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1600 { "list_networks", wpa_cli_cmd_list_networks,
1602 "= list configured networks" },
1603 { "select_network", wpa_cli_cmd_select_network,
1605 "<network id> = select a network (disable others)" },
1606 { "enable_network", wpa_cli_cmd_enable_network,
1608 "<network id> = enable a network" },
1609 { "disable_network", wpa_cli_cmd_disable_network,
1611 "<network id> = disable a network" },
1612 { "add_network", wpa_cli_cmd_add_network,
1614 "= add a network" },
1615 { "remove_network", wpa_cli_cmd_remove_network,
1617 "<network id> = remove a network" },
1618 { "set_network", wpa_cli_cmd_set_network,
1619 cli_cmd_flag_sensitive,
1620 "<network id> <variable> <value> = set network variables (shows\n"
1621 " list of variables when run without arguments)" },
1622 { "get_network", wpa_cli_cmd_get_network,
1624 "<network id> <variable> = get network variables" },
1625 { "save_config", wpa_cli_cmd_save_config,
1627 "= save the current configuration" },
1628 { "disconnect", wpa_cli_cmd_disconnect,
1630 "= disconnect and wait for reassociate/reconnect command before\n"
1632 { "reconnect", wpa_cli_cmd_reconnect,
1634 "= like reassociate, but only takes effect if already disconnected"
1636 { "scan", wpa_cli_cmd_scan,
1638 "= request new BSS scan" },
1639 { "scan_results", wpa_cli_cmd_scan_results,
1641 "= get latest scan results" },
1642 { "bss", wpa_cli_cmd_bss,
1644 "<<idx> | <bssid>> = get detailed scan result info" },
1645 { "get_capability", wpa_cli_cmd_get_capability,
1647 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1648 { "reconfigure", wpa_cli_cmd_reconfigure,
1650 "= force wpa_supplicant to re-read its configuration file" },
1651 { "terminate", wpa_cli_cmd_terminate,
1653 "= terminate wpa_supplicant" },
1654 { "interface_add", wpa_cli_cmd_interface_add,
1656 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1657 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1659 { "interface_remove", wpa_cli_cmd_interface_remove,
1661 "<ifname> = removes the interface" },
1662 { "interface_list", wpa_cli_cmd_interface_list,
1664 "= list available interfaces" },
1665 { "ap_scan", wpa_cli_cmd_ap_scan,
1667 "<value> = set ap_scan parameter" },
1668 { "stkstart", wpa_cli_cmd_stkstart,
1670 "<addr> = request STK negotiation with <addr>" },
1671 { "ft_ds", wpa_cli_cmd_ft_ds,
1673 "<addr> = request over-the-DS FT with <addr>" },
1674 { "wps_pbc", wpa_cli_cmd_wps_pbc,
1676 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1677 { "wps_pin", wpa_cli_cmd_wps_pin,
1678 cli_cmd_flag_sensitive,
1679 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1681 #ifdef CONFIG_WPS_OOB
1682 { "wps_oob", wpa_cli_cmd_wps_oob,
1683 cli_cmd_flag_sensitive,
1684 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1685 #endif /* CONFIG_WPS_OOB */
1686 { "wps_reg", wpa_cli_cmd_wps_reg,
1687 cli_cmd_flag_sensitive,
1688 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1689 { "wps_er_start", wpa_cli_cmd_wps_er_start,
1691 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
1692 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1694 "= stop Wi-Fi Protected Setup External Registrar" },
1695 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
1696 cli_cmd_flag_sensitive,
1697 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1698 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
1700 "<UUID> = accept an Enrollee PBC using External Registrar" },
1701 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
1702 cli_cmd_flag_sensitive,
1703 "<UUID> <PIN> = learn AP configuration" },
1704 { "wps_er_config", wpa_cli_cmd_wps_er_config,
1705 cli_cmd_flag_sensitive,
1706 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
1707 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1709 "<addr> = request RSN authentication with <addr> in IBSS" },
1711 { "sta", wpa_cli_cmd_sta,
1713 "<addr> = get information about an associated station (AP)" },
1714 { "all_sta", wpa_cli_cmd_all_sta,
1716 "= get information about all associated stations (AP)" },
1717 #endif /* CONFIG_AP */
1718 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
1719 "= notification of suspend/hibernate" },
1720 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
1721 "= notification of resume/thaw" },
1722 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
1723 "= drop SA without deauth/disassoc (test command)" },
1724 { "roam", wpa_cli_cmd_roam,
1726 "<addr> = roam to the specified BSS" },
1727 { NULL, NULL, cli_cmd_flag_none, NULL }
1732 * Prints command usage, lines are padded with the specified string.
1734 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1739 printf("%s%s ", pad, cmd->cmd);
1740 for (n = 0; (c = cmd->usage[n]); n++) {
1749 static void print_help(void)
1752 printf("commands:\n");
1753 for (n = 0; wpa_cli_commands[n].cmd; n++)
1754 print_cmd_help(&wpa_cli_commands[n], " ");
1758 #ifdef CONFIG_READLINE
1759 static int cmd_has_sensitive_data(const char *cmd)
1761 const char *c, *delim;
1765 delim = os_strchr(cmd, ' ');
1769 len = os_strlen(cmd);
1771 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1772 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1773 return (wpa_cli_commands[n].flags &
1774 cli_cmd_flag_sensitive);
1778 #endif /* CONFIG_READLINE */
1781 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1783 struct wpa_cli_cmd *cmd, *match = NULL;
1788 cmd = wpa_cli_commands;
1790 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1793 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1794 /* we have an exact match */
1804 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1805 cmd = wpa_cli_commands;
1807 if (os_strncasecmp(cmd->cmd, argv[0],
1808 os_strlen(argv[0])) == 0) {
1809 printf(" %s", cmd->cmd);
1815 } else if (count == 0) {
1816 printf("Unknown command '%s'\n", argv[0]);
1819 ret = match->handler(ctrl, argc - 1, &argv[1]);
1826 static int str_match(const char *a, const char *b)
1828 return os_strncmp(a, b, os_strlen(b)) == 0;
1832 static int wpa_cli_exec(const char *program, const char *arg1,
1840 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1841 cmd = os_malloc(len);
1844 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1845 if (res < 0 || (size_t) res >= len) {
1849 cmd[len - 1] = '\0';
1851 if (system(cmd) < 0)
1853 #endif /* _WIN32_WCE */
1860 static void wpa_cli_action_process(const char *msg)
1863 char *copy = NULL, *id, *pos2;
1868 pos = os_strchr(pos, '>');
1875 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1877 os_unsetenv("WPA_ID");
1878 os_unsetenv("WPA_ID_STR");
1879 os_unsetenv("WPA_CTRL_DIR");
1881 pos = os_strstr(pos, "[id=");
1883 copy = os_strdup(pos + 4);
1887 while (*pos2 && *pos2 != ' ')
1891 os_setenv("WPA_ID", id, 1);
1892 while (*pos2 && *pos2 != '=')
1897 while (*pos2 && *pos2 != ']')
1900 os_setenv("WPA_ID_STR", id, 1);
1904 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1906 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1907 wpa_cli_connected = 1;
1908 wpa_cli_last_id = new_id;
1909 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1911 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1912 if (wpa_cli_connected) {
1913 wpa_cli_connected = 0;
1914 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1916 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1917 printf("wpa_supplicant is terminating - stop monitoring\n");
1923 #ifndef CONFIG_ANSI_C_EXTRA
1924 static void wpa_cli_action_cb(char *msg, size_t len)
1926 wpa_cli_action_process(msg);
1928 #endif /* CONFIG_ANSI_C_EXTRA */
1931 static void wpa_cli_reconnect(void)
1933 wpa_cli_close_connection();
1934 wpa_cli_open_connection(ctrl_ifname, 1);
1938 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1942 if (ctrl_conn == NULL) {
1943 wpa_cli_reconnect();
1946 while (wpa_ctrl_pending(ctrl) > 0) {
1948 size_t len = sizeof(buf) - 1;
1949 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1952 wpa_cli_action_process(buf);
1954 if (in_read && first)
1957 printf("%s\n", buf);
1958 #ifdef CONFIG_READLINE
1961 #endif /* CONFIG_READLINE */
1964 printf("Could not read pending message.\n");
1969 if (wpa_ctrl_pending(ctrl) < 0) {
1970 printf("Connection to wpa_supplicant lost - trying to "
1972 wpa_cli_reconnect();
1977 #ifdef CONFIG_READLINE
1978 static char * wpa_cli_cmd_gen(const char *text, int state)
1985 len = os_strlen(text);
1988 while ((cmd = wpa_cli_commands[i].cmd)) {
1990 if (os_strncasecmp(cmd, text, len) == 0)
1998 static char * wpa_cli_dummy_gen(const char *text, int state)
2002 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2003 const char *cmd = wpa_cli_commands[i].cmd;
2004 size_t len = os_strlen(cmd);
2005 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
2006 rl_line_buffer[len] == ' ') {
2007 printf("\n%s\n", wpa_cli_commands[i].usage);
2014 rl_attempted_completion_over = 1;
2019 static char * wpa_cli_status_gen(const char *text, int state)
2029 len = os_strlen(text);
2032 while ((t = options[i])) {
2034 if (os_strncasecmp(t, text, len) == 0)
2038 rl_attempted_completion_over = 1;
2043 static char ** wpa_cli_completion(const char *text, int start, int end)
2045 char * (*func)(const char *text, int state);
2048 func = wpa_cli_cmd_gen;
2049 else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
2050 func = wpa_cli_status_gen;
2052 func = wpa_cli_dummy_gen;
2053 return rl_completion_matches(text, func);
2055 #endif /* CONFIG_READLINE */
2058 static void wpa_cli_interactive(void)
2061 char cmdbuf[256], *cmd, *argv[max_args], *pos;
2063 #ifdef CONFIG_READLINE
2064 char *home, *hfile = NULL;
2065 #endif /* CONFIG_READLINE */
2067 printf("\nInteractive mode\n\n");
2069 #ifdef CONFIG_READLINE
2070 rl_attempted_completion_function = wpa_cli_completion;
2071 home = getenv("HOME");
2073 const char *fname = ".wpa_cli_history";
2074 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
2075 hfile = os_malloc(hfile_len);
2078 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
2080 if (res >= 0 && res < hfile_len) {
2081 hfile[hfile_len - 1] = '\0';
2082 read_history(hfile);
2083 stifle_history(100);
2087 #endif /* CONFIG_READLINE */
2090 wpa_cli_recv_pending(mon_conn, 0, 0);
2091 #ifndef CONFIG_NATIVE_WINDOWS
2092 alarm(ping_interval);
2093 #endif /* CONFIG_NATIVE_WINDOWS */
2094 #ifdef CONFIG_WPA_CLI_FORK
2096 kill(mon_pid, SIGUSR1);
2097 #endif /* CONFIG_WPA_CLI_FORK */
2098 #ifdef CONFIG_READLINE
2099 cmd = readline("> ");
2102 while (next_history())
2104 h = previous_history();
2105 if (h == NULL || os_strcmp(cmd, h->line) != 0)
2109 #else /* CONFIG_READLINE */
2111 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
2112 #endif /* CONFIG_READLINE */
2113 #ifndef CONFIG_NATIVE_WINDOWS
2115 #endif /* CONFIG_NATIVE_WINDOWS */
2118 wpa_cli_recv_pending(mon_conn, 0, 0);
2120 while (*pos != '\0') {
2136 if (argc == max_args)
2139 char *pos2 = os_strrchr(pos, '"');
2143 while (*pos != '\0' && *pos != ' ')
2149 wpa_request(ctrl_conn, argc, argv);
2153 #ifdef CONFIG_WPA_CLI_FORK
2155 kill(mon_pid, SIGUSR2);
2156 #endif /* CONFIG_WPA_CLI_FORK */
2157 } while (!wpa_cli_quit);
2159 #ifdef CONFIG_READLINE
2161 /* Save command history, excluding lines that may contain
2165 while ((h = current_history())) {
2167 while (*p == ' ' || *p == '\t')
2169 if (cmd_has_sensitive_data(p)) {
2170 h = remove_history(where_history());
2180 write_history(hfile);
2183 #endif /* CONFIG_READLINE */
2187 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2189 #ifdef CONFIG_ANSI_C_EXTRA
2190 /* TODO: ANSI C version(?) */
2191 printf("Action processing not supported in ANSI C build.\n");
2192 #else /* CONFIG_ANSI_C_EXTRA */
2196 char buf[256]; /* note: large enough to fit in unsolicited messages */
2199 fd = wpa_ctrl_get_fd(ctrl);
2201 while (!wpa_cli_quit) {
2204 tv.tv_sec = ping_interval;
2206 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2207 if (res < 0 && errno != EINTR) {
2212 if (FD_ISSET(fd, &rfds))
2213 wpa_cli_recv_pending(ctrl, 0, 1);
2215 /* verify that connection is still working */
2216 len = sizeof(buf) - 1;
2217 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2218 wpa_cli_action_cb) < 0 ||
2219 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2220 printf("wpa_supplicant did not reply to PING "
2221 "command - exiting\n");
2226 #endif /* CONFIG_ANSI_C_EXTRA */
2230 static void wpa_cli_cleanup(void)
2232 wpa_cli_close_connection();
2234 os_daemonize_terminate(pid_file);
2236 os_program_deinit();
2239 static void wpa_cli_terminate(int sig)
2246 #ifdef CONFIG_WPA_CLI_FORK
2247 static void wpa_cli_usr1(int sig)
2249 #ifdef CONFIG_READLINE
2252 #endif /* CONFIG_READLINE */
2254 #endif /* CONFIG_WPA_CLI_FORK */
2257 #ifndef CONFIG_NATIVE_WINDOWS
2258 static void wpa_cli_alarm(int sig)
2260 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2261 printf("Connection to wpa_supplicant lost - trying to "
2263 wpa_cli_close_connection();
2266 wpa_cli_reconnect();
2268 wpa_cli_recv_pending(mon_conn, 1, 0);
2269 alarm(ping_interval);
2271 #endif /* CONFIG_NATIVE_WINDOWS */
2274 static char * wpa_cli_get_default_ifname(void)
2276 char *ifname = NULL;
2278 #ifdef CONFIG_CTRL_IFACE_UNIX
2279 struct dirent *dent;
2280 DIR *dir = opendir(ctrl_iface_dir);
2283 while ((dent = readdir(dir))) {
2284 #ifdef _DIRENT_HAVE_D_TYPE
2286 * Skip the file if it is not a socket. Also accept
2287 * DT_UNKNOWN (0) in case the C library or underlying
2288 * file system does not support d_type.
2290 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2292 #endif /* _DIRENT_HAVE_D_TYPE */
2293 if (os_strcmp(dent->d_name, ".") == 0 ||
2294 os_strcmp(dent->d_name, "..") == 0)
2296 printf("Selected interface '%s'\n", dent->d_name);
2297 ifname = os_strdup(dent->d_name);
2301 #endif /* CONFIG_CTRL_IFACE_UNIX */
2303 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2304 char buf[2048], *pos;
2306 struct wpa_ctrl *ctrl;
2309 ctrl = wpa_ctrl_open(NULL);
2313 len = sizeof(buf) - 1;
2314 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2317 pos = os_strchr(buf, '\n');
2320 ifname = os_strdup(buf);
2322 wpa_ctrl_close(ctrl);
2323 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2329 int main(int argc, char *argv[])
2331 int warning_displayed = 0;
2335 const char *global = NULL;
2337 if (os_program_init())
2341 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2346 action_file = optarg;
2355 ping_interval = atoi(optarg);
2361 printf("%s\n", wpa_cli_version);
2364 os_free(ctrl_ifname);
2365 ctrl_ifname = os_strdup(optarg);
2368 ctrl_iface_dir = optarg;
2379 interactive = (argc == optind) && (action_file == NULL);
2382 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2385 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2386 ctrl_conn = wpa_ctrl_open(NULL);
2387 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2388 ctrl_conn = wpa_ctrl_open(global);
2389 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2390 if (ctrl_conn == NULL) {
2391 perror("Failed to connect to wpa_supplicant - "
2398 signal(SIGINT, wpa_cli_terminate);
2399 signal(SIGTERM, wpa_cli_terminate);
2400 #endif /* _WIN32_WCE */
2401 #ifndef CONFIG_NATIVE_WINDOWS
2402 signal(SIGALRM, wpa_cli_alarm);
2403 #endif /* CONFIG_NATIVE_WINDOWS */
2404 #ifdef CONFIG_WPA_CLI_FORK
2405 signal(SIGUSR1, wpa_cli_usr1);
2406 #endif /* CONFIG_WPA_CLI_FORK */
2408 if (ctrl_ifname == NULL)
2409 ctrl_ifname = wpa_cli_get_default_ifname();
2413 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
2414 if (warning_displayed)
2415 printf("Connection established.\n");
2419 if (!warning_displayed) {
2420 printf("Could not connect to wpa_supplicant - "
2422 warning_displayed = 1;
2429 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
2430 perror("Failed to connect to wpa_supplicant - "
2436 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2437 wpa_cli_attached = 1;
2439 printf("Warning: Failed to attach to "
2440 "wpa_supplicant.\n");
2446 if (daemonize && os_daemonize(pid_file))
2450 wpa_cli_interactive();
2451 else if (action_file)
2452 wpa_cli_action(ctrl_conn);
2454 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2456 os_free(ctrl_ifname);
2462 #else /* CONFIG_CTRL_IFACE */
2463 int main(int argc, char *argv[])
2465 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2468 #endif /* CONFIG_CTRL_IFACE */