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 void wpa_cli_monitor(void)
134 size_t len = sizeof(buf) - 1;
139 int s = wpa_ctrl_get_fd(mon_conn);
144 if (select(s + 1, &rfds, NULL, NULL, &tv) < 0) {
148 if (mon_conn == NULL)
150 if (FD_ISSET(s, &rfds)) {
151 len = sizeof(buf) - 1;
152 int res = wpa_ctrl_recv(mon_conn, buf, &len);
154 perror("wpa_ctrl_recv");
162 #endif /* CONFIG_WPA_CLI_FORK */
165 static int wpa_cli_open_connection(const char *ifname, int attach)
167 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
168 ctrl_conn = wpa_ctrl_open(ifname);
169 if (ctrl_conn == NULL)
172 if (attach && interactive)
173 mon_conn = wpa_ctrl_open(ifname);
176 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
183 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
184 cfile = os_malloc(flen);
187 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
188 if (res < 0 || res >= flen) {
193 ctrl_conn = wpa_ctrl_open(cfile);
194 if (ctrl_conn == NULL) {
199 if (attach && interactive)
200 mon_conn = wpa_ctrl_open(cfile);
204 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
207 if (wpa_ctrl_attach(mon_conn) == 0) {
208 wpa_cli_attached = 1;
210 printf("Warning: Failed to attach to "
211 "wpa_supplicant.\n");
215 #ifdef CONFIG_WPA_CLI_FORK
228 #endif /* CONFIG_WPA_CLI_FORK */
235 static void wpa_cli_close_connection(void)
237 if (ctrl_conn == NULL)
240 if (wpa_cli_attached) {
241 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
242 wpa_cli_attached = 0;
244 wpa_ctrl_close(ctrl_conn);
247 wpa_ctrl_close(mon_conn);
250 #ifdef CONFIG_WPA_CLI_FORK
253 kill(mon_pid, SIGPIPE);
257 #endif /* CONFIG_WPA_CLI_FORK */
261 static void wpa_cli_msg_cb(char *msg, size_t len)
267 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
273 if (ctrl_conn == NULL) {
274 printf("Not connected to wpa_supplicant - command dropped.\n");
277 len = sizeof(buf) - 1;
278 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
281 printf("'%s' command timed out.\n", cmd);
283 } else if (ret < 0) {
284 printf("'%s' command failed.\n", cmd);
295 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
297 return _wpa_ctrl_command(ctrl, cmd, 1);
301 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
303 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
304 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
308 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
310 return wpa_ctrl_command(ctrl, "PING");
314 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
316 return wpa_ctrl_command(ctrl, "MIB");
320 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
322 return wpa_ctrl_command(ctrl, "PMKSA");
326 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
333 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
335 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
340 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
347 static void wpa_cli_show_variables(void)
349 printf("set variables:\n"
350 " EAPOL::heldPeriod (EAPOL state machine held period, "
352 " EAPOL::authPeriod (EAPOL state machine authentication "
353 "period, in seconds)\n"
354 " EAPOL::startPeriod (EAPOL state machine start period, in "
356 " EAPOL::maxStart (EAPOL state machine maximum start "
358 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
360 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
361 " threshold\n\tpercentage)\n"
362 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
363 "security\n\tassociation in seconds)\n");
367 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
373 wpa_cli_show_variables();
378 printf("Invalid SET command: needs two arguments (variable "
379 "name and value)\n");
383 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
384 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
385 printf("Too long SET command.\n");
388 return wpa_ctrl_command(ctrl, cmd);
392 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
394 return wpa_ctrl_command(ctrl, "LOGOFF");
398 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
400 return wpa_ctrl_command(ctrl, "LOGON");
404 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
407 return wpa_ctrl_command(ctrl, "REASSOCIATE");
411 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
418 printf("Invalid PREAUTH command: needs one argument "
423 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
424 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
425 printf("Too long PREAUTH command.\n");
428 return wpa_ctrl_command(ctrl, cmd);
432 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
438 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
442 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
443 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
444 printf("Too long AP_SCAN command.\n");
447 return wpa_ctrl_command(ctrl, cmd);
451 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
458 printf("Invalid STKSTART command: needs one argument "
459 "(Peer STA MAC address)\n");
463 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
464 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
465 printf("Too long STKSTART command.\n");
468 return wpa_ctrl_command(ctrl, cmd);
472 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
478 printf("Invalid FT_DS command: needs one argument "
479 "(Target AP MAC address)\n");
483 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
484 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
485 printf("Too long FT_DS command.\n");
488 return wpa_ctrl_command(ctrl, cmd);
492 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
499 return wpa_ctrl_command(ctrl, "WPS_PBC");
503 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
504 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
505 printf("Too long WPS_PBC command.\n");
508 return wpa_ctrl_command(ctrl, cmd);
512 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
518 printf("Invalid WPS_PIN command: need one or two arguments:\n"
519 "- BSSID: use 'any' to select any\n"
520 "- PIN: optional, used only with devices that have no "
526 /* Use dynamically generated PIN (returned as reply) */
527 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
528 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
529 printf("Too long WPS_PIN command.\n");
532 return wpa_ctrl_command(ctrl, cmd);
535 /* Use hardcoded PIN from a label */
536 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
537 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
538 printf("Too long WPS_PIN command.\n");
541 return wpa_ctrl_command(ctrl, cmd);
545 #ifdef CONFIG_WPS_OOB
546 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
551 if (argc != 3 && argc != 4) {
552 printf("Invalid WPS_OOB command: need three or four "
554 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
555 "- PATH: path of OOB device like '/mnt'\n"
556 "- METHOD: OOB method 'pin-e' or 'pin-r', "
558 "- DEV_NAME: (only for NFC) device name like "
564 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
565 argv[0], argv[1], argv[2]);
567 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
568 argv[0], argv[1], argv[2], argv[3]);
569 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
570 printf("Too long WPS_OOB command.\n");
573 return wpa_ctrl_command(ctrl, cmd);
575 #endif /* CONFIG_WPS_OOB */
578 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
584 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
586 else if (argc == 6) {
587 char ssid_hex[2 * 32 + 1];
588 char key_hex[2 * 64 + 1];
592 for (i = 0; i < 32; i++) {
593 if (argv[2][i] == '\0')
595 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
599 for (i = 0; i < 64; i++) {
600 if (argv[5][i] == '\0')
602 os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]);
605 res = os_snprintf(cmd, sizeof(cmd),
606 "WPS_REG %s %s %s %s %s %s",
607 argv[0], argv[1], ssid_hex, argv[3], argv[4],
610 printf("Invalid WPS_REG command: need two arguments:\n"
611 "- BSSID: use 'any' to select any\n"
613 printf("Alternatively, six arguments can be used to "
614 "reconfigure the AP:\n"
615 "- BSSID: use 'any' to select any\n"
618 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
619 "- new encr (NONE, WEP, TKIP, CCMP)\n"
624 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
625 printf("Too long WPS_REG command.\n");
628 return wpa_ctrl_command(ctrl, cmd);
632 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
635 return wpa_ctrl_command(ctrl, "WPS_ER_START");
640 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
643 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
648 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
655 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
656 "- UUID: use 'any' to select any\n"
657 "- PIN: Enrollee PIN\n");
661 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
663 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
664 printf("Too long WPS_ER_PIN command.\n");
667 return wpa_ctrl_command(ctrl, cmd);
671 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
678 printf("Invalid WPS_ER_PBC command: need one argument:\n"
679 "- UUID: Specify the Enrollee\n");
683 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
685 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
686 printf("Too long WPS_ER_PBC command.\n");
689 return wpa_ctrl_command(ctrl, cmd);
693 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
700 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
701 "- UUID: specify which AP to use\n"
706 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
708 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
709 printf("Too long WPS_ER_LEARN command.\n");
712 return wpa_ctrl_command(ctrl, cmd);
716 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
722 printf("Invalid IBSS_RSN command: needs one argument "
723 "(Peer STA MAC address)\n");
727 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
728 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
729 printf("Too long IBSS_RSN command.\n");
732 return wpa_ctrl_command(ctrl, cmd);
736 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
742 printf("Invalid LEVEL command: needs one argument (debug "
746 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
747 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
748 printf("Too long LEVEL command.\n");
751 return wpa_ctrl_command(ctrl, cmd);
755 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
757 char cmd[256], *pos, *end;
761 printf("Invalid IDENTITY command: needs two arguments "
762 "(network id and identity)\n");
766 end = cmd + sizeof(cmd);
768 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
770 if (ret < 0 || ret >= end - pos) {
771 printf("Too long IDENTITY command.\n");
775 for (i = 2; i < argc; i++) {
776 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
777 if (ret < 0 || ret >= end - pos) {
778 printf("Too long IDENTITY command.\n");
784 return wpa_ctrl_command(ctrl, cmd);
788 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
790 char cmd[256], *pos, *end;
794 printf("Invalid PASSWORD command: needs two arguments "
795 "(network id and password)\n");
799 end = cmd + sizeof(cmd);
801 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
803 if (ret < 0 || ret >= end - pos) {
804 printf("Too long PASSWORD command.\n");
808 for (i = 2; i < argc; i++) {
809 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
810 if (ret < 0 || ret >= end - pos) {
811 printf("Too long PASSWORD command.\n");
817 return wpa_ctrl_command(ctrl, cmd);
821 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
824 char cmd[256], *pos, *end;
828 printf("Invalid NEW_PASSWORD command: needs two arguments "
829 "(network id and password)\n");
833 end = cmd + sizeof(cmd);
835 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
837 if (ret < 0 || ret >= end - pos) {
838 printf("Too long NEW_PASSWORD command.\n");
842 for (i = 2; i < argc; i++) {
843 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
844 if (ret < 0 || ret >= end - pos) {
845 printf("Too long NEW_PASSWORD command.\n");
851 return wpa_ctrl_command(ctrl, cmd);
855 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
857 char cmd[256], *pos, *end;
861 printf("Invalid PIN command: needs two arguments "
862 "(network id and pin)\n");
866 end = cmd + sizeof(cmd);
868 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
870 if (ret < 0 || ret >= end - pos) {
871 printf("Too long PIN command.\n");
875 for (i = 2; i < argc; i++) {
876 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
877 if (ret < 0 || ret >= end - pos) {
878 printf("Too long PIN command.\n");
883 return wpa_ctrl_command(ctrl, cmd);
887 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
889 char cmd[256], *pos, *end;
893 printf("Invalid OTP command: needs two arguments (network "
894 "id and password)\n");
898 end = cmd + sizeof(cmd);
900 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
902 if (ret < 0 || ret >= end - pos) {
903 printf("Too long OTP command.\n");
907 for (i = 2; i < argc; i++) {
908 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
909 if (ret < 0 || ret >= end - pos) {
910 printf("Too long OTP command.\n");
916 return wpa_ctrl_command(ctrl, cmd);
920 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
923 char cmd[256], *pos, *end;
927 printf("Invalid PASSPHRASE command: needs two arguments "
928 "(network id and passphrase)\n");
932 end = cmd + sizeof(cmd);
934 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
936 if (ret < 0 || ret >= end - pos) {
937 printf("Too long PASSPHRASE command.\n");
941 for (i = 2; i < argc; i++) {
942 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
943 if (ret < 0 || ret >= end - pos) {
944 printf("Too long PASSPHRASE command.\n");
950 return wpa_ctrl_command(ctrl, cmd);
954 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
956 char cmd[256], *pos, *end;
960 printf("Invalid BSSID command: needs two arguments (network "
965 end = cmd + sizeof(cmd);
967 ret = os_snprintf(pos, end - pos, "BSSID");
968 if (ret < 0 || ret >= end - pos) {
969 printf("Too long BSSID command.\n");
973 for (i = 0; i < argc; i++) {
974 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
975 if (ret < 0 || ret >= end - pos) {
976 printf("Too long BSSID command.\n");
982 return wpa_ctrl_command(ctrl, cmd);
986 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
989 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
993 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1000 printf("Invalid SELECT_NETWORK command: needs one argument "
1005 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1006 if (res < 0 || (size_t) res >= sizeof(cmd))
1008 cmd[sizeof(cmd) - 1] = '\0';
1010 return wpa_ctrl_command(ctrl, cmd);
1014 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1021 printf("Invalid ENABLE_NETWORK command: needs one argument "
1026 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1027 if (res < 0 || (size_t) res >= sizeof(cmd))
1029 cmd[sizeof(cmd) - 1] = '\0';
1031 return wpa_ctrl_command(ctrl, cmd);
1035 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1042 printf("Invalid DISABLE_NETWORK command: needs one argument "
1047 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1048 if (res < 0 || (size_t) res >= sizeof(cmd))
1050 cmd[sizeof(cmd) - 1] = '\0';
1052 return wpa_ctrl_command(ctrl, cmd);
1056 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1059 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1063 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1070 printf("Invalid REMOVE_NETWORK command: needs one argument "
1075 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1076 if (res < 0 || (size_t) res >= sizeof(cmd))
1078 cmd[sizeof(cmd) - 1] = '\0';
1080 return wpa_ctrl_command(ctrl, cmd);
1084 static void wpa_cli_show_network_variables(void)
1086 printf("set_network variables:\n"
1087 " ssid (network name, SSID)\n"
1088 " psk (WPA passphrase or pre-shared key)\n"
1089 " key_mgmt (key management protocol)\n"
1090 " identity (EAP identity)\n"
1091 " password (EAP password)\n"
1094 "Note: Values are entered in the same format as the "
1095 "configuration file is using,\n"
1096 "i.e., strings values need to be inside double quotation "
1098 "For example: set_network 1 ssid \"network name\"\n"
1100 "Please see wpa_supplicant.conf documentation for full list "
1101 "of\navailable variables.\n");
1105 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1112 wpa_cli_show_network_variables();
1117 printf("Invalid SET_NETWORK command: needs three arguments\n"
1118 "(network id, variable name, and value)\n");
1122 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1123 argv[0], argv[1], argv[2]);
1124 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1125 printf("Too long SET_NETWORK command.\n");
1128 return wpa_ctrl_command(ctrl, cmd);
1132 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1139 wpa_cli_show_network_variables();
1144 printf("Invalid GET_NETWORK command: needs two arguments\n"
1145 "(network id and variable name)\n");
1149 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1151 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1152 printf("Too long GET_NETWORK command.\n");
1155 return wpa_ctrl_command(ctrl, cmd);
1159 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1162 return wpa_ctrl_command(ctrl, "DISCONNECT");
1166 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1169 return wpa_ctrl_command(ctrl, "RECONNECT");
1173 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1176 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1180 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1182 return wpa_ctrl_command(ctrl, "SCAN");
1186 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1189 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1193 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1199 printf("Invalid BSS command: need one argument (index or "
1204 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1205 if (res < 0 || (size_t) res >= sizeof(cmd))
1207 cmd[sizeof(cmd) - 1] = '\0';
1209 return wpa_ctrl_command(ctrl, cmd);
1213 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1219 if (argc < 1 || argc > 2) {
1220 printf("Invalid GET_CAPABILITY command: need either one or "
1225 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1226 printf("Invalid GET_CAPABILITY command: second argument, "
1227 "if any, must be 'strict'\n");
1231 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1232 (argc == 2) ? " strict" : "");
1233 if (res < 0 || (size_t) res >= sizeof(cmd))
1235 cmd[sizeof(cmd) - 1] = '\0';
1237 return wpa_ctrl_command(ctrl, cmd);
1241 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1243 printf("Available interfaces:\n");
1244 return wpa_ctrl_command(ctrl, "INTERFACES");
1248 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1251 wpa_cli_list_interfaces(ctrl);
1255 wpa_cli_close_connection();
1256 os_free(ctrl_ifname);
1257 ctrl_ifname = os_strdup(argv[0]);
1259 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1260 printf("Connected to interface '%s.\n", ctrl_ifname);
1262 printf("Could not connect to interface '%s' - re-trying\n",
1269 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1272 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1276 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1279 return wpa_ctrl_command(ctrl, "TERMINATE");
1283 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1290 printf("Invalid INTERFACE_ADD command: needs at least one "
1291 "argument (interface name)\n"
1292 "All arguments: ifname confname driver ctrl_interface "
1293 "driver_param bridge_name\n");
1298 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1299 * <driver_param>TAB<bridge_name>
1301 res = os_snprintf(cmd, sizeof(cmd),
1302 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1304 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1305 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1306 argc > 5 ? argv[5] : "");
1307 if (res < 0 || (size_t) res >= sizeof(cmd))
1309 cmd[sizeof(cmd) - 1] = '\0';
1310 return wpa_ctrl_command(ctrl, cmd);
1314 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1321 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1322 "(interface name)\n");
1326 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1327 if (res < 0 || (size_t) res >= sizeof(cmd))
1329 cmd[sizeof(cmd) - 1] = '\0';
1330 return wpa_ctrl_command(ctrl, cmd);
1334 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1337 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1342 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1346 printf("Invalid 'sta' command - exactly one argument, STA "
1347 "address, is required.\n");
1350 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1351 return wpa_ctrl_command(ctrl, buf);
1355 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1356 char *addr, size_t addr_len)
1358 char buf[4096], *pos;
1362 if (ctrl_conn == NULL) {
1363 printf("Not connected to hostapd - command dropped.\n");
1366 len = sizeof(buf) - 1;
1367 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1370 printf("'%s' command timed out.\n", cmd);
1372 } else if (ret < 0) {
1373 printf("'%s' command failed.\n", cmd);
1378 if (memcmp(buf, "FAIL", 4) == 0)
1383 while (*pos != '\0' && *pos != '\n')
1386 os_strlcpy(addr, buf, addr_len);
1391 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1393 char addr[32], cmd[64];
1395 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1398 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1399 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1403 #endif /* CONFIG_AP */
1406 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1408 return wpa_ctrl_command(ctrl, "SUSPEND");
1412 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1414 return wpa_ctrl_command(ctrl, "RESUME");
1418 enum wpa_cli_cmd_flags {
1419 cli_cmd_flag_none = 0x00,
1420 cli_cmd_flag_sensitive = 0x01
1423 struct wpa_cli_cmd {
1425 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1426 enum wpa_cli_cmd_flags flags;
1430 static struct wpa_cli_cmd wpa_cli_commands[] = {
1431 { "status", wpa_cli_cmd_status,
1433 "[verbose] = get current WPA/EAPOL/EAP status" },
1434 { "ping", wpa_cli_cmd_ping,
1436 "= pings wpa_supplicant" },
1437 { "mib", wpa_cli_cmd_mib,
1439 "= get MIB variables (dot1x, dot11)" },
1440 { "help", wpa_cli_cmd_help,
1442 "= show this usage help" },
1443 { "interface", wpa_cli_cmd_interface,
1445 "[ifname] = show interfaces/select interface" },
1446 { "level", wpa_cli_cmd_level,
1448 "<debug level> = change debug level" },
1449 { "license", wpa_cli_cmd_license,
1451 "= show full wpa_cli license" },
1452 { "quit", wpa_cli_cmd_quit,
1455 { "set", wpa_cli_cmd_set,
1457 "= set variables (shows list of variables when run without "
1459 { "logon", wpa_cli_cmd_logon,
1461 "= IEEE 802.1X EAPOL state machine logon" },
1462 { "logoff", wpa_cli_cmd_logoff,
1464 "= IEEE 802.1X EAPOL state machine logoff" },
1465 { "pmksa", wpa_cli_cmd_pmksa,
1467 "= show PMKSA cache" },
1468 { "reassociate", wpa_cli_cmd_reassociate,
1470 "= force reassociation" },
1471 { "preauthenticate", wpa_cli_cmd_preauthenticate,
1473 "<BSSID> = force preauthentication" },
1474 { "identity", wpa_cli_cmd_identity,
1476 "<network id> <identity> = configure identity for an SSID" },
1477 { "password", wpa_cli_cmd_password,
1478 cli_cmd_flag_sensitive,
1479 "<network id> <password> = configure password for an SSID" },
1480 { "new_password", wpa_cli_cmd_new_password,
1481 cli_cmd_flag_sensitive,
1482 "<network id> <password> = change password for an SSID" },
1483 { "pin", wpa_cli_cmd_pin,
1484 cli_cmd_flag_sensitive,
1485 "<network id> <pin> = configure pin for an SSID" },
1486 { "otp", wpa_cli_cmd_otp,
1487 cli_cmd_flag_sensitive,
1488 "<network id> <password> = configure one-time-password for an SSID"
1490 { "passphrase", wpa_cli_cmd_passphrase,
1491 cli_cmd_flag_sensitive,
1492 "<network id> <passphrase> = configure private key passphrase\n"
1494 { "bssid", wpa_cli_cmd_bssid,
1496 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1497 { "list_networks", wpa_cli_cmd_list_networks,
1499 "= list configured networks" },
1500 { "select_network", wpa_cli_cmd_select_network,
1502 "<network id> = select a network (disable others)" },
1503 { "enable_network", wpa_cli_cmd_enable_network,
1505 "<network id> = enable a network" },
1506 { "disable_network", wpa_cli_cmd_disable_network,
1508 "<network id> = disable a network" },
1509 { "add_network", wpa_cli_cmd_add_network,
1511 "= add a network" },
1512 { "remove_network", wpa_cli_cmd_remove_network,
1514 "<network id> = remove a network" },
1515 { "set_network", wpa_cli_cmd_set_network,
1516 cli_cmd_flag_sensitive,
1517 "<network id> <variable> <value> = set network variables (shows\n"
1518 " list of variables when run without arguments)" },
1519 { "get_network", wpa_cli_cmd_get_network,
1521 "<network id> <variable> = get network variables" },
1522 { "save_config", wpa_cli_cmd_save_config,
1524 "= save the current configuration" },
1525 { "disconnect", wpa_cli_cmd_disconnect,
1527 "= disconnect and wait for reassociate/reconnect command before\n"
1529 { "reconnect", wpa_cli_cmd_reconnect,
1531 "= like reassociate, but only takes effect if already disconnected"
1533 { "scan", wpa_cli_cmd_scan,
1535 "= request new BSS scan" },
1536 { "scan_results", wpa_cli_cmd_scan_results,
1538 "= get latest scan results" },
1539 { "bss", wpa_cli_cmd_bss,
1541 "<<idx> | <bssid>> = get detailed scan result info" },
1542 { "get_capability", wpa_cli_cmd_get_capability,
1544 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1545 { "reconfigure", wpa_cli_cmd_reconfigure,
1547 "= force wpa_supplicant to re-read its configuration file" },
1548 { "terminate", wpa_cli_cmd_terminate,
1550 "= terminate wpa_supplicant" },
1551 { "interface_add", wpa_cli_cmd_interface_add,
1553 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1554 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1556 { "interface_remove", wpa_cli_cmd_interface_remove,
1558 "<ifname> = removes the interface" },
1559 { "interface_list", wpa_cli_cmd_interface_list,
1561 "= list available interfaces" },
1562 { "ap_scan", wpa_cli_cmd_ap_scan,
1564 "<value> = set ap_scan parameter" },
1565 { "stkstart", wpa_cli_cmd_stkstart,
1567 "<addr> = request STK negotiation with <addr>" },
1568 { "ft_ds", wpa_cli_cmd_ft_ds,
1570 "<addr> = request over-the-DS FT with <addr>" },
1571 { "wps_pbc", wpa_cli_cmd_wps_pbc,
1573 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1574 { "wps_pin", wpa_cli_cmd_wps_pin,
1575 cli_cmd_flag_sensitive,
1576 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1578 #ifdef CONFIG_WPS_OOB
1579 { "wps_oob", wpa_cli_cmd_wps_oob,
1580 cli_cmd_flag_sensitive,
1581 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1582 #endif /* CONFIG_WPS_OOB */
1583 { "wps_reg", wpa_cli_cmd_wps_reg,
1584 cli_cmd_flag_sensitive,
1585 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1586 { "wps_er_start", wpa_cli_cmd_wps_er_start,
1588 "= start Wi-Fi Protected Setup External Registrar" },
1589 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1591 "= stop Wi-Fi Protected Setup External Registrar" },
1592 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
1593 cli_cmd_flag_sensitive,
1594 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1595 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
1597 "<UUID> = accept an Enrollee PBC using External Registrar" },
1598 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
1599 cli_cmd_flag_sensitive,
1600 "<UUID> <PIN> = learn AP configuration" },
1601 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1603 "<addr> = request RSN authentication with <addr> in IBSS" },
1605 { "sta", wpa_cli_cmd_sta,
1607 "<addr> = get information about an associated station (AP)" },
1608 { "all_sta", wpa_cli_cmd_all_sta,
1610 "= get information about all associated stations (AP)" },
1611 #endif /* CONFIG_AP */
1612 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
1613 "= notification of suspend/hibernate" },
1614 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
1615 "= notification of resume/thaw" },
1616 { NULL, NULL, cli_cmd_flag_none, NULL }
1621 * Prints command usage, lines are padded with the specified string.
1623 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1628 printf("%s%s ", pad, cmd->cmd);
1629 for (n = 0; (c = cmd->usage[n]); n++) {
1638 static void print_help(void)
1641 printf("commands:\n");
1642 for (n = 0; wpa_cli_commands[n].cmd; n++)
1643 print_cmd_help(&wpa_cli_commands[n], " ");
1647 #ifdef CONFIG_READLINE
1648 static int cmd_has_sensitive_data(const char *cmd)
1650 const char *c, *delim;
1654 delim = os_strchr(cmd, ' ');
1658 len = os_strlen(cmd);
1660 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1661 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1662 return (wpa_cli_commands[n].flags &
1663 cli_cmd_flag_sensitive);
1667 #endif /* CONFIG_READLINE */
1670 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1672 struct wpa_cli_cmd *cmd, *match = NULL;
1677 cmd = wpa_cli_commands;
1679 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1682 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1683 /* we have an exact match */
1693 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1694 cmd = wpa_cli_commands;
1696 if (os_strncasecmp(cmd->cmd, argv[0],
1697 os_strlen(argv[0])) == 0) {
1698 printf(" %s", cmd->cmd);
1704 } else if (count == 0) {
1705 printf("Unknown command '%s'\n", argv[0]);
1708 ret = match->handler(ctrl, argc - 1, &argv[1]);
1715 static int str_match(const char *a, const char *b)
1717 return os_strncmp(a, b, os_strlen(b)) == 0;
1721 static int wpa_cli_exec(const char *program, const char *arg1,
1729 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1730 cmd = os_malloc(len);
1733 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1734 if (res < 0 || (size_t) res >= len) {
1738 cmd[len - 1] = '\0';
1740 if (system(cmd) < 0)
1742 #endif /* _WIN32_WCE */
1749 static void wpa_cli_action_process(const char *msg)
1752 char *copy = NULL, *id, *pos2;
1757 pos = os_strchr(pos, '>');
1764 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1766 os_unsetenv("WPA_ID");
1767 os_unsetenv("WPA_ID_STR");
1768 os_unsetenv("WPA_CTRL_DIR");
1770 pos = os_strstr(pos, "[id=");
1772 copy = os_strdup(pos + 4);
1776 while (*pos2 && *pos2 != ' ')
1780 os_setenv("WPA_ID", id, 1);
1781 while (*pos2 && *pos2 != '=')
1786 while (*pos2 && *pos2 != ']')
1789 os_setenv("WPA_ID_STR", id, 1);
1793 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1795 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1796 wpa_cli_connected = 1;
1797 wpa_cli_last_id = new_id;
1798 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1800 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1801 if (wpa_cli_connected) {
1802 wpa_cli_connected = 0;
1803 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1805 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1806 printf("wpa_supplicant is terminating - stop monitoring\n");
1812 #ifndef CONFIG_ANSI_C_EXTRA
1813 static void wpa_cli_action_cb(char *msg, size_t len)
1815 wpa_cli_action_process(msg);
1817 #endif /* CONFIG_ANSI_C_EXTRA */
1820 static void wpa_cli_reconnect(void)
1822 wpa_cli_close_connection();
1823 wpa_cli_open_connection(ctrl_ifname, 1);
1827 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1831 if (ctrl_conn == NULL) {
1832 wpa_cli_reconnect();
1835 while (wpa_ctrl_pending(ctrl) > 0) {
1837 size_t len = sizeof(buf) - 1;
1838 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1841 wpa_cli_action_process(buf);
1843 if (in_read && first)
1846 printf("%s\n", buf);
1849 printf("Could not read pending message.\n");
1854 if (wpa_ctrl_pending(ctrl) < 0) {
1855 printf("Connection to wpa_supplicant lost - trying to "
1857 wpa_cli_reconnect();
1862 #ifdef CONFIG_READLINE
1863 static char * wpa_cli_cmd_gen(const char *text, int state)
1870 len = os_strlen(text);
1873 while ((cmd = wpa_cli_commands[i].cmd)) {
1875 if (os_strncasecmp(cmd, text, len) == 0)
1883 static char * wpa_cli_dummy_gen(const char *text, int state)
1889 static char ** wpa_cli_completion(const char *text, int start, int end)
1891 return rl_completion_matches(text, start == 0 ?
1892 wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1894 #endif /* CONFIG_READLINE */
1897 static void wpa_cli_interactive(void)
1900 char cmdbuf[256], *cmd, *argv[max_args], *pos;
1902 #ifdef CONFIG_READLINE
1903 char *home, *hfile = NULL;
1904 #endif /* CONFIG_READLINE */
1906 printf("\nInteractive mode\n\n");
1908 #ifdef CONFIG_READLINE
1909 rl_attempted_completion_function = wpa_cli_completion;
1910 home = getenv("HOME");
1912 const char *fname = ".wpa_cli_history";
1913 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1914 hfile = os_malloc(hfile_len);
1917 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
1919 if (res >= 0 && res < hfile_len) {
1920 hfile[hfile_len - 1] = '\0';
1921 read_history(hfile);
1922 stifle_history(100);
1926 #endif /* CONFIG_READLINE */
1929 wpa_cli_recv_pending(mon_conn, 0, 0);
1930 #ifndef CONFIG_NATIVE_WINDOWS
1931 alarm(ping_interval);
1932 #endif /* CONFIG_NATIVE_WINDOWS */
1933 #ifdef CONFIG_READLINE
1934 cmd = readline("> ");
1937 while (next_history())
1939 h = previous_history();
1940 if (h == NULL || os_strcmp(cmd, h->line) != 0)
1944 #else /* CONFIG_READLINE */
1946 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1947 #endif /* CONFIG_READLINE */
1948 #ifndef CONFIG_NATIVE_WINDOWS
1950 #endif /* CONFIG_NATIVE_WINDOWS */
1953 wpa_cli_recv_pending(mon_conn, 0, 0);
1955 while (*pos != '\0') {
1971 if (argc == max_args)
1974 char *pos2 = os_strrchr(pos, '"');
1978 while (*pos != '\0' && *pos != ' ')
1984 wpa_request(ctrl_conn, argc, argv);
1988 } while (!wpa_cli_quit);
1990 #ifdef CONFIG_READLINE
1992 /* Save command history, excluding lines that may contain
1996 while ((h = current_history())) {
1998 while (*p == ' ' || *p == '\t')
2000 if (cmd_has_sensitive_data(p)) {
2001 h = remove_history(where_history());
2011 write_history(hfile);
2014 #endif /* CONFIG_READLINE */
2018 static void wpa_cli_action(struct wpa_ctrl *ctrl)
2020 #ifdef CONFIG_ANSI_C_EXTRA
2021 /* TODO: ANSI C version(?) */
2022 printf("Action processing not supported in ANSI C build.\n");
2023 #else /* CONFIG_ANSI_C_EXTRA */
2027 char buf[256]; /* note: large enough to fit in unsolicited messages */
2030 fd = wpa_ctrl_get_fd(ctrl);
2032 while (!wpa_cli_quit) {
2035 tv.tv_sec = ping_interval;
2037 res = select(fd + 1, &rfds, NULL, NULL, &tv);
2038 if (res < 0 && errno != EINTR) {
2043 if (FD_ISSET(fd, &rfds))
2044 wpa_cli_recv_pending(ctrl, 0, 1);
2046 /* verify that connection is still working */
2047 len = sizeof(buf) - 1;
2048 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
2049 wpa_cli_action_cb) < 0 ||
2050 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
2051 printf("wpa_supplicant did not reply to PING "
2052 "command - exiting\n");
2057 #endif /* CONFIG_ANSI_C_EXTRA */
2061 static void wpa_cli_cleanup(void)
2063 wpa_cli_close_connection();
2065 os_daemonize_terminate(pid_file);
2067 os_program_deinit();
2070 static void wpa_cli_terminate(int sig)
2077 #ifndef CONFIG_NATIVE_WINDOWS
2078 static void wpa_cli_alarm(int sig)
2080 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
2081 printf("Connection to wpa_supplicant lost - trying to "
2083 wpa_cli_close_connection();
2086 wpa_cli_reconnect();
2088 wpa_cli_recv_pending(mon_conn, 1, 0);
2089 alarm(ping_interval);
2091 #endif /* CONFIG_NATIVE_WINDOWS */
2094 static char * wpa_cli_get_default_ifname(void)
2096 char *ifname = NULL;
2098 #ifdef CONFIG_CTRL_IFACE_UNIX
2099 struct dirent *dent;
2100 DIR *dir = opendir(ctrl_iface_dir);
2103 while ((dent = readdir(dir))) {
2104 #ifdef _DIRENT_HAVE_D_TYPE
2106 * Skip the file if it is not a socket. Also accept
2107 * DT_UNKNOWN (0) in case the C library or underlying
2108 * file system does not support d_type.
2110 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
2112 #endif /* _DIRENT_HAVE_D_TYPE */
2113 if (os_strcmp(dent->d_name, ".") == 0 ||
2114 os_strcmp(dent->d_name, "..") == 0)
2116 printf("Selected interface '%s'\n", dent->d_name);
2117 ifname = os_strdup(dent->d_name);
2121 #endif /* CONFIG_CTRL_IFACE_UNIX */
2123 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2124 char buf[2048], *pos;
2126 struct wpa_ctrl *ctrl;
2129 ctrl = wpa_ctrl_open(NULL);
2133 len = sizeof(buf) - 1;
2134 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2137 pos = os_strchr(buf, '\n');
2140 ifname = os_strdup(buf);
2142 wpa_ctrl_close(ctrl);
2143 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2149 int main(int argc, char *argv[])
2151 int warning_displayed = 0;
2155 const char *global = NULL;
2157 if (os_program_init())
2161 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2166 action_file = optarg;
2175 ping_interval = atoi(optarg);
2181 printf("%s\n", wpa_cli_version);
2184 os_free(ctrl_ifname);
2185 ctrl_ifname = os_strdup(optarg);
2188 ctrl_iface_dir = optarg;
2199 interactive = (argc == optind) && (action_file == NULL);
2202 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2205 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2206 ctrl_conn = wpa_ctrl_open(NULL);
2207 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2208 ctrl_conn = wpa_ctrl_open(global);
2209 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2210 if (ctrl_conn == NULL) {
2211 perror("Failed to connect to wpa_supplicant - "
2218 signal(SIGINT, wpa_cli_terminate);
2219 signal(SIGTERM, wpa_cli_terminate);
2220 #endif /* _WIN32_WCE */
2221 #ifndef CONFIG_NATIVE_WINDOWS
2222 signal(SIGALRM, wpa_cli_alarm);
2223 #endif /* CONFIG_NATIVE_WINDOWS */
2225 if (ctrl_ifname == NULL)
2226 ctrl_ifname = wpa_cli_get_default_ifname();
2230 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
2231 if (warning_displayed)
2232 printf("Connection established.\n");
2236 if (!warning_displayed) {
2237 printf("Could not connect to wpa_supplicant - "
2239 warning_displayed = 1;
2246 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
2247 perror("Failed to connect to wpa_supplicant - "
2253 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2254 wpa_cli_attached = 1;
2256 printf("Warning: Failed to attach to "
2257 "wpa_supplicant.\n");
2263 if (daemonize && os_daemonize(pid_file))
2267 wpa_cli_interactive();
2268 else if (action_file)
2269 wpa_cli_action(ctrl_conn);
2271 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2273 os_free(ctrl_ifname);
2279 #else /* CONFIG_CTRL_IFACE */
2280 int main(int argc, char *argv[])
2282 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2285 #endif /* CONFIG_CTRL_IFACE */