2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2009, 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 */
32 static const char *wpa_cli_version =
33 "wpa_cli v" VERSION_STR "\n"
34 "Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> and contributors";
37 static const char *wpa_cli_license =
38 "This program is free software. You can distribute it and/or modify it\n"
39 "under the terms of the GNU General Public License version 2.\n"
41 "Alternatively, this software may be distributed under the terms of the\n"
42 "BSD license. See README and COPYING for more details.\n";
44 static const char *wpa_cli_full_license =
45 "This program is free software; you can redistribute it and/or modify\n"
46 "it under the terms of the GNU General Public License version 2 as\n"
47 "published by the Free Software Foundation.\n"
49 "This program is distributed in the hope that it will be useful,\n"
50 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
51 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
52 "GNU General Public License for more details.\n"
54 "You should have received a copy of the GNU General Public License\n"
55 "along with this program; if not, write to the Free Software\n"
56 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
58 "Alternatively, this software may be distributed under the terms of the\n"
61 "Redistribution and use in source and binary forms, with or without\n"
62 "modification, are permitted provided that the following conditions are\n"
65 "1. Redistributions of source code must retain the above copyright\n"
66 " notice, this list of conditions and the following disclaimer.\n"
68 "2. Redistributions in binary form must reproduce the above copyright\n"
69 " notice, this list of conditions and the following disclaimer in the\n"
70 " documentation and/or other materials provided with the distribution.\n"
72 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
73 " names of its contributors may be used to endorse or promote products\n"
74 " derived from this software without specific prior written permission.\n"
76 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
77 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
78 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
79 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
80 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
81 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
82 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
83 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
84 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
85 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
86 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
89 static struct wpa_ctrl *ctrl_conn;
90 static int wpa_cli_quit = 0;
91 static int wpa_cli_attached = 0;
92 static int wpa_cli_connected = 0;
93 static int wpa_cli_last_id = 0;
94 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
95 static char *ctrl_ifname = NULL;
96 static const char *pid_file = NULL;
97 static const char *action_file = NULL;
98 static int ping_interval = 5;
101 static void print_help();
104 static void usage(void)
106 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
107 "[-a<action file>] \\\n"
108 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
110 " -h = help (show this usage text)\n"
111 " -v = shown version information\n"
112 " -a = run in daemon mode executing the action file based on "
115 " -B = run a daemon in the background\n"
116 " default path: /var/run/wpa_supplicant\n"
117 " default interface: first interface found in socket path\n");
122 static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
124 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
125 ctrl_conn = wpa_ctrl_open(ifname);
127 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
134 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
135 cfile = os_malloc(flen);
138 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
139 if (res < 0 || res >= flen) {
144 ctrl_conn = wpa_ctrl_open(cfile);
147 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
151 static void wpa_cli_close_connection(void)
153 if (ctrl_conn == NULL)
156 if (wpa_cli_attached) {
157 wpa_ctrl_detach(ctrl_conn);
158 wpa_cli_attached = 0;
160 wpa_ctrl_close(ctrl_conn);
165 static void wpa_cli_msg_cb(char *msg, size_t len)
171 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
177 if (ctrl_conn == NULL) {
178 printf("Not connected to wpa_supplicant - command dropped.\n");
181 len = sizeof(buf) - 1;
182 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
185 printf("'%s' command timed out.\n", cmd);
187 } else if (ret < 0) {
188 printf("'%s' command failed.\n", cmd);
199 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
201 return _wpa_ctrl_command(ctrl, cmd, 1);
205 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
207 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
208 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
212 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
214 return wpa_ctrl_command(ctrl, "PING");
218 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
220 return wpa_ctrl_command(ctrl, "MIB");
224 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
226 return wpa_ctrl_command(ctrl, "PMKSA");
230 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
237 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
239 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
244 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
251 static void wpa_cli_show_variables(void)
253 printf("set variables:\n"
254 " EAPOL::heldPeriod (EAPOL state machine held period, "
256 " EAPOL::authPeriod (EAPOL state machine authentication "
257 "period, in seconds)\n"
258 " EAPOL::startPeriod (EAPOL state machine start period, in "
260 " EAPOL::maxStart (EAPOL state machine maximum start "
262 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
264 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
265 " threshold\n\tpercentage)\n"
266 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
267 "security\n\tassociation in seconds)\n");
271 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
277 wpa_cli_show_variables();
282 printf("Invalid SET command: needs two arguments (variable "
283 "name and value)\n");
287 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
288 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
289 printf("Too long SET command.\n");
292 return wpa_ctrl_command(ctrl, cmd);
296 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
298 return wpa_ctrl_command(ctrl, "LOGOFF");
302 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
304 return wpa_ctrl_command(ctrl, "LOGON");
308 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
311 return wpa_ctrl_command(ctrl, "REASSOCIATE");
315 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
322 printf("Invalid PREAUTH command: needs one argument "
327 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
328 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
329 printf("Too long PREAUTH command.\n");
332 return wpa_ctrl_command(ctrl, cmd);
336 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
342 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
346 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
347 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
348 printf("Too long AP_SCAN command.\n");
351 return wpa_ctrl_command(ctrl, cmd);
355 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
362 printf("Invalid STKSTART command: needs one argument "
363 "(Peer STA MAC address)\n");
367 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
368 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
369 printf("Too long STKSTART command.\n");
372 return wpa_ctrl_command(ctrl, cmd);
376 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
382 printf("Invalid FT_DS command: needs one argument "
383 "(Target AP MAC address)\n");
387 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
388 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
389 printf("Too long FT_DS command.\n");
392 return wpa_ctrl_command(ctrl, cmd);
396 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
403 return wpa_ctrl_command(ctrl, "WPS_PBC");
407 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
408 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
409 printf("Too long WPS_PBC command.\n");
412 return wpa_ctrl_command(ctrl, cmd);
416 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
422 printf("Invalid WPS_PIN command: need one or two arguments:\n"
423 "- BSSID: use 'any' to select any\n"
424 "- PIN: optional, used only with devices that have no "
430 /* Use dynamically generated PIN (returned as reply) */
431 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
432 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
433 printf("Too long WPS_PIN command.\n");
436 return wpa_ctrl_command(ctrl, cmd);
439 /* Use hardcoded PIN from a label */
440 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
441 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
442 printf("Too long WPS_PIN command.\n");
445 return wpa_ctrl_command(ctrl, cmd);
449 #ifdef CONFIG_WPS_OOB
450 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
455 if (argc != 3 && argc != 4) {
456 printf("Invalid WPS_OOB command: need three or four "
458 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
459 "- PATH: path of OOB device like '/mnt'\n"
460 "- METHOD: OOB method 'pin-e' or 'pin-r', "
462 "- DEV_NAME: (only for NFC) device name like "
468 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
469 argv[0], argv[1], argv[2]);
471 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
472 argv[0], argv[1], argv[2], argv[3]);
473 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
474 printf("Too long WPS_OOB command.\n");
477 return wpa_ctrl_command(ctrl, cmd);
479 #endif /* CONFIG_WPS_OOB */
482 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
488 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
490 else if (argc == 6) {
491 char ssid_hex[2 * 32 + 1];
492 char key_hex[2 * 64 + 1];
496 for (i = 0; i < 32; i++) {
497 if (argv[2][i] == '\0')
499 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
503 for (i = 0; i < 64; i++) {
504 if (argv[5][i] == '\0')
506 os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]);
509 res = os_snprintf(cmd, sizeof(cmd),
510 "WPS_REG %s %s %s %s %s %s",
511 argv[0], argv[1], ssid_hex, argv[3], argv[4],
514 printf("Invalid WPS_REG command: need two arguments:\n"
515 "- BSSID: use 'any' to select any\n"
517 printf("Alternatively, six arguments can be used to "
518 "reconfigure the AP:\n"
519 "- BSSID: use 'any' to select any\n"
522 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
523 "- new encr (NONE, WEP, TKIP, CCMP)\n"
528 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
529 printf("Too long WPS_REG command.\n");
532 return wpa_ctrl_command(ctrl, cmd);
536 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
539 return wpa_ctrl_command(ctrl, "WPS_ER_START");
544 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
547 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
552 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
559 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
560 "- UUID: use 'any' to select any\n"
561 "- PIN: Enrollee PIN\n");
565 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
567 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
568 printf("Too long WPS_ER_PIN command.\n");
571 return wpa_ctrl_command(ctrl, cmd);
575 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
582 printf("Invalid WPS_ER_PBC command: need one argument:\n"
583 "- UUID: Specify the Enrollee\n");
587 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
589 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
590 printf("Too long WPS_ER_PBC command.\n");
593 return wpa_ctrl_command(ctrl, cmd);
597 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
603 printf("Invalid IBSS_RSN command: needs one argument "
604 "(Peer STA MAC address)\n");
608 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
609 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
610 printf("Too long IBSS_RSN command.\n");
613 return wpa_ctrl_command(ctrl, cmd);
617 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
623 printf("Invalid LEVEL command: needs one argument (debug "
627 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
628 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
629 printf("Too long LEVEL command.\n");
632 return wpa_ctrl_command(ctrl, cmd);
636 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
638 char cmd[256], *pos, *end;
642 printf("Invalid IDENTITY command: needs two arguments "
643 "(network id and identity)\n");
647 end = cmd + sizeof(cmd);
649 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
651 if (ret < 0 || ret >= end - pos) {
652 printf("Too long IDENTITY command.\n");
656 for (i = 2; i < argc; i++) {
657 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
658 if (ret < 0 || ret >= end - pos) {
659 printf("Too long IDENTITY command.\n");
665 return wpa_ctrl_command(ctrl, cmd);
669 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
671 char cmd[256], *pos, *end;
675 printf("Invalid PASSWORD command: needs two arguments "
676 "(network id and password)\n");
680 end = cmd + sizeof(cmd);
682 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
684 if (ret < 0 || ret >= end - pos) {
685 printf("Too long PASSWORD command.\n");
689 for (i = 2; i < argc; i++) {
690 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
691 if (ret < 0 || ret >= end - pos) {
692 printf("Too long PASSWORD command.\n");
698 return wpa_ctrl_command(ctrl, cmd);
702 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
705 char cmd[256], *pos, *end;
709 printf("Invalid NEW_PASSWORD command: needs two arguments "
710 "(network id and password)\n");
714 end = cmd + sizeof(cmd);
716 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
718 if (ret < 0 || ret >= end - pos) {
719 printf("Too long NEW_PASSWORD command.\n");
723 for (i = 2; i < argc; i++) {
724 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
725 if (ret < 0 || ret >= end - pos) {
726 printf("Too long NEW_PASSWORD command.\n");
732 return wpa_ctrl_command(ctrl, cmd);
736 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
738 char cmd[256], *pos, *end;
742 printf("Invalid PIN command: needs two arguments "
743 "(network id and pin)\n");
747 end = cmd + sizeof(cmd);
749 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
751 if (ret < 0 || ret >= end - pos) {
752 printf("Too long PIN command.\n");
756 for (i = 2; i < argc; i++) {
757 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
758 if (ret < 0 || ret >= end - pos) {
759 printf("Too long PIN command.\n");
764 return wpa_ctrl_command(ctrl, cmd);
768 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
770 char cmd[256], *pos, *end;
774 printf("Invalid OTP command: needs two arguments (network "
775 "id and password)\n");
779 end = cmd + sizeof(cmd);
781 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
783 if (ret < 0 || ret >= end - pos) {
784 printf("Too long OTP command.\n");
788 for (i = 2; i < argc; i++) {
789 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
790 if (ret < 0 || ret >= end - pos) {
791 printf("Too long OTP command.\n");
797 return wpa_ctrl_command(ctrl, cmd);
801 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
804 char cmd[256], *pos, *end;
808 printf("Invalid PASSPHRASE command: needs two arguments "
809 "(network id and passphrase)\n");
813 end = cmd + sizeof(cmd);
815 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
817 if (ret < 0 || ret >= end - pos) {
818 printf("Too long PASSPHRASE command.\n");
822 for (i = 2; i < argc; i++) {
823 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
824 if (ret < 0 || ret >= end - pos) {
825 printf("Too long PASSPHRASE command.\n");
831 return wpa_ctrl_command(ctrl, cmd);
835 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
837 char cmd[256], *pos, *end;
841 printf("Invalid BSSID command: needs two arguments (network "
846 end = cmd + sizeof(cmd);
848 ret = os_snprintf(pos, end - pos, "BSSID");
849 if (ret < 0 || ret >= end - pos) {
850 printf("Too long BSSID command.\n");
854 for (i = 0; i < argc; i++) {
855 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
856 if (ret < 0 || ret >= end - pos) {
857 printf("Too long BSSID command.\n");
863 return wpa_ctrl_command(ctrl, cmd);
867 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
870 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
874 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
881 printf("Invalid SELECT_NETWORK command: needs one argument "
886 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
887 if (res < 0 || (size_t) res >= sizeof(cmd))
889 cmd[sizeof(cmd) - 1] = '\0';
891 return wpa_ctrl_command(ctrl, cmd);
895 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
902 printf("Invalid ENABLE_NETWORK command: needs one argument "
907 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
908 if (res < 0 || (size_t) res >= sizeof(cmd))
910 cmd[sizeof(cmd) - 1] = '\0';
912 return wpa_ctrl_command(ctrl, cmd);
916 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
923 printf("Invalid DISABLE_NETWORK command: needs one argument "
928 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
929 if (res < 0 || (size_t) res >= sizeof(cmd))
931 cmd[sizeof(cmd) - 1] = '\0';
933 return wpa_ctrl_command(ctrl, cmd);
937 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
940 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
944 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
951 printf("Invalid REMOVE_NETWORK command: needs one argument "
956 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
957 if (res < 0 || (size_t) res >= sizeof(cmd))
959 cmd[sizeof(cmd) - 1] = '\0';
961 return wpa_ctrl_command(ctrl, cmd);
965 static void wpa_cli_show_network_variables(void)
967 printf("set_network variables:\n"
968 " ssid (network name, SSID)\n"
969 " psk (WPA passphrase or pre-shared key)\n"
970 " key_mgmt (key management protocol)\n"
971 " identity (EAP identity)\n"
972 " password (EAP password)\n"
975 "Note: Values are entered in the same format as the "
976 "configuration file is using,\n"
977 "i.e., strings values need to be inside double quotation "
979 "For example: set_network 1 ssid \"network name\"\n"
981 "Please see wpa_supplicant.conf documentation for full list "
982 "of\navailable variables.\n");
986 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
993 wpa_cli_show_network_variables();
998 printf("Invalid SET_NETWORK command: needs three arguments\n"
999 "(network id, variable name, and value)\n");
1003 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1004 argv[0], argv[1], argv[2]);
1005 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1006 printf("Too long SET_NETWORK command.\n");
1009 return wpa_ctrl_command(ctrl, cmd);
1013 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1020 wpa_cli_show_network_variables();
1025 printf("Invalid GET_NETWORK command: needs two arguments\n"
1026 "(network id and variable name)\n");
1030 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1032 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1033 printf("Too long GET_NETWORK command.\n");
1036 return wpa_ctrl_command(ctrl, cmd);
1040 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1043 return wpa_ctrl_command(ctrl, "DISCONNECT");
1047 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1050 return wpa_ctrl_command(ctrl, "RECONNECT");
1054 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1057 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1061 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1063 return wpa_ctrl_command(ctrl, "SCAN");
1067 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1070 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1074 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1080 printf("Invalid BSS command: need one argument (index or "
1085 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1086 if (res < 0 || (size_t) res >= sizeof(cmd))
1088 cmd[sizeof(cmd) - 1] = '\0';
1090 return wpa_ctrl_command(ctrl, cmd);
1094 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1100 if (argc < 1 || argc > 2) {
1101 printf("Invalid GET_CAPABILITY command: need either one or "
1106 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1107 printf("Invalid GET_CAPABILITY command: second argument, "
1108 "if any, must be 'strict'\n");
1112 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1113 (argc == 2) ? " strict" : "");
1114 if (res < 0 || (size_t) res >= sizeof(cmd))
1116 cmd[sizeof(cmd) - 1] = '\0';
1118 return wpa_ctrl_command(ctrl, cmd);
1122 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1124 printf("Available interfaces:\n");
1125 return wpa_ctrl_command(ctrl, "INTERFACES");
1129 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1132 wpa_cli_list_interfaces(ctrl);
1136 wpa_cli_close_connection();
1137 os_free(ctrl_ifname);
1138 ctrl_ifname = os_strdup(argv[0]);
1140 if (wpa_cli_open_connection(ctrl_ifname)) {
1141 printf("Connected to interface '%s.\n", ctrl_ifname);
1142 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1143 wpa_cli_attached = 1;
1145 printf("Warning: Failed to attach to "
1146 "wpa_supplicant.\n");
1149 printf("Could not connect to interface '%s' - re-trying\n",
1156 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1159 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1163 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1166 return wpa_ctrl_command(ctrl, "TERMINATE");
1170 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1177 printf("Invalid INTERFACE_ADD command: needs at least one "
1178 "argument (interface name)\n"
1179 "All arguments: ifname confname driver ctrl_interface "
1180 "driver_param bridge_name\n");
1185 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1186 * <driver_param>TAB<bridge_name>
1188 res = os_snprintf(cmd, sizeof(cmd),
1189 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1191 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1192 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1193 argc > 5 ? argv[5] : "");
1194 if (res < 0 || (size_t) res >= sizeof(cmd))
1196 cmd[sizeof(cmd) - 1] = '\0';
1197 return wpa_ctrl_command(ctrl, cmd);
1201 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1208 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1209 "(interface name)\n");
1213 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1214 if (res < 0 || (size_t) res >= sizeof(cmd))
1216 cmd[sizeof(cmd) - 1] = '\0';
1217 return wpa_ctrl_command(ctrl, cmd);
1221 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1224 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1229 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1233 printf("Invalid 'sta' command - exactly one argument, STA "
1234 "address, is required.\n");
1237 snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1238 return wpa_ctrl_command(ctrl, buf);
1242 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1243 char *addr, size_t addr_len)
1245 char buf[4096], *pos;
1249 if (ctrl_conn == NULL) {
1250 printf("Not connected to hostapd - command dropped.\n");
1253 len = sizeof(buf) - 1;
1254 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1257 printf("'%s' command timed out.\n", cmd);
1259 } else if (ret < 0) {
1260 printf("'%s' command failed.\n", cmd);
1265 if (memcmp(buf, "FAIL", 4) == 0)
1270 while (*pos != '\0' && *pos != '\n')
1273 os_strlcpy(addr, buf, addr_len);
1278 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1280 char addr[32], cmd[64];
1282 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1285 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1286 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1290 #endif /* CONFIG_AP */
1293 enum wpa_cli_cmd_flags {
1294 cli_cmd_flag_none = 0x00,
1295 cli_cmd_flag_sensitive = 0x01
1298 struct wpa_cli_cmd {
1300 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1301 enum wpa_cli_cmd_flags flags;
1305 static struct wpa_cli_cmd wpa_cli_commands[] = {
1306 { "status", wpa_cli_cmd_status,
1308 "[verbose] = get current WPA/EAPOL/EAP status" },
1309 { "ping", wpa_cli_cmd_ping,
1311 "= pings wpa_supplicant" },
1312 { "mib", wpa_cli_cmd_mib,
1314 "= get MIB variables (dot1x, dot11)" },
1315 { "help", wpa_cli_cmd_help,
1317 "= show this usage help" },
1318 { "interface", wpa_cli_cmd_interface,
1320 "[ifname] = show interfaces/select interface" },
1321 { "level", wpa_cli_cmd_level,
1323 "<debug level> = change debug level" },
1324 { "license", wpa_cli_cmd_license,
1326 "= show full wpa_cli license" },
1327 { "quit", wpa_cli_cmd_quit,
1330 { "set", wpa_cli_cmd_set,
1332 "= set variables (shows list of variables when run without "
1334 { "logon", wpa_cli_cmd_logon,
1336 "= IEEE 802.1X EAPOL state machine logon" },
1337 { "logoff", wpa_cli_cmd_logoff,
1339 "= IEEE 802.1X EAPOL state machine logoff" },
1340 { "pmksa", wpa_cli_cmd_pmksa,
1342 "= show PMKSA cache" },
1343 { "reassociate", wpa_cli_cmd_reassociate,
1345 "= force reassociation" },
1346 { "preauthenticate", wpa_cli_cmd_preauthenticate,
1348 "<BSSID> = force preauthentication" },
1349 { "identity", wpa_cli_cmd_identity,
1351 "<network id> <identity> = configure identity for an SSID" },
1352 { "password", wpa_cli_cmd_password,
1353 cli_cmd_flag_sensitive,
1354 "<network id> <password> = configure password for an SSID" },
1355 { "new_password", wpa_cli_cmd_new_password,
1356 cli_cmd_flag_sensitive,
1357 "<network id> <password> = change password for an SSID" },
1358 { "pin", wpa_cli_cmd_pin,
1359 cli_cmd_flag_sensitive,
1360 "<network id> <pin> = configure pin for an SSID" },
1361 { "otp", wpa_cli_cmd_otp,
1362 cli_cmd_flag_sensitive,
1363 "<network id> <password> = configure one-time-password for an SSID"
1365 { "passphrase", wpa_cli_cmd_passphrase,
1366 cli_cmd_flag_sensitive,
1367 "<network id> <passphrase> = configure private key passphrase\n"
1369 { "bssid", wpa_cli_cmd_bssid,
1371 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1372 { "list_networks", wpa_cli_cmd_list_networks,
1374 "= list configured networks" },
1375 { "select_network", wpa_cli_cmd_select_network,
1377 "<network id> = select a network (disable others)" },
1378 { "enable_network", wpa_cli_cmd_enable_network,
1380 "<network id> = enable a network" },
1381 { "disable_network", wpa_cli_cmd_disable_network,
1383 "<network id> = disable a network" },
1384 { "add_network", wpa_cli_cmd_add_network,
1386 "= add a network" },
1387 { "remove_network", wpa_cli_cmd_remove_network,
1389 "<network id> = remove a network" },
1390 { "set_network", wpa_cli_cmd_set_network,
1391 cli_cmd_flag_sensitive,
1392 "<network id> <variable> <value> = set network variables (shows\n"
1393 " list of variables when run without arguments)" },
1394 { "get_network", wpa_cli_cmd_get_network,
1396 "<network id> <variable> = get network variables" },
1397 { "save_config", wpa_cli_cmd_save_config,
1399 "= save the current configuration" },
1400 { "disconnect", wpa_cli_cmd_disconnect,
1402 "= disconnect and wait for reassociate/reconnect command before\n"
1404 { "reconnect", wpa_cli_cmd_reconnect,
1406 "= like reassociate, but only takes effect if already disconnected"
1408 { "scan", wpa_cli_cmd_scan,
1410 "= request new BSS scan" },
1411 { "scan_results", wpa_cli_cmd_scan_results,
1413 "= get latest scan results" },
1414 { "bss", wpa_cli_cmd_bss,
1416 "<<idx> | <bssid>> = get detailed scan result info" },
1417 { "get_capability", wpa_cli_cmd_get_capability,
1419 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1420 { "reconfigure", wpa_cli_cmd_reconfigure,
1422 "= force wpa_supplicant to re-read its configuration file" },
1423 { "terminate", wpa_cli_cmd_terminate,
1425 "= terminate wpa_supplicant" },
1426 { "interface_add", wpa_cli_cmd_interface_add,
1428 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1429 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1431 { "interface_remove", wpa_cli_cmd_interface_remove,
1433 "<ifname> = removes the interface" },
1434 { "interface_list", wpa_cli_cmd_interface_list,
1436 "= list available interfaces" },
1437 { "ap_scan", wpa_cli_cmd_ap_scan,
1439 "<value> = set ap_scan parameter" },
1440 { "stkstart", wpa_cli_cmd_stkstart,
1442 "<addr> = request STK negotiation with <addr>" },
1443 { "ft_ds", wpa_cli_cmd_ft_ds,
1445 "<addr> = request over-the-DS FT with <addr>" },
1446 { "wps_pbc", wpa_cli_cmd_wps_pbc,
1448 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1449 { "wps_pin", wpa_cli_cmd_wps_pin,
1450 cli_cmd_flag_sensitive,
1451 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1453 #ifdef CONFIG_WPS_OOB
1454 { "wps_oob", wpa_cli_cmd_wps_oob,
1455 cli_cmd_flag_sensitive,
1456 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1457 #endif /* CONFIG_WPS_OOB */
1458 { "wps_reg", wpa_cli_cmd_wps_reg,
1459 cli_cmd_flag_sensitive,
1460 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1461 { "wps_er_start", wpa_cli_cmd_wps_er_start,
1463 "= start Wi-Fi Protected Setup External Registrar" },
1464 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1466 "= stop Wi-Fi Protected Setup External Registrar" },
1467 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
1468 cli_cmd_flag_sensitive,
1469 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1470 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
1472 "<UUID> = accept an Enrollee PBC using External Registrar" },
1473 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1475 "<addr> = request RSN authentication with <addr> in IBSS" },
1477 { "sta", wpa_cli_cmd_sta,
1479 "<addr> = get information about an associated station (AP)" },
1480 { "all_sta", wpa_cli_cmd_all_sta,
1482 "= get information about all associated stations (AP)" },
1483 #endif /* CONFIG_AP */
1484 { NULL, NULL, cli_cmd_flag_none, NULL }
1489 * Prints command usage, lines are padded with the specified string.
1491 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1496 printf("%s%s ", pad, cmd->cmd);
1497 for (n = 0; (c = cmd->usage[n]); n++) {
1506 static void print_help(void)
1509 printf("commands:\n");
1510 for (n = 0; wpa_cli_commands[n].cmd; n++)
1511 print_cmd_help(&wpa_cli_commands[n], " ");
1515 #ifdef CONFIG_READLINE
1516 static int cmd_has_sensitive_data(const char *cmd)
1518 const char *c, *delim;
1522 delim = os_strchr(cmd, ' ');
1526 len = os_strlen(cmd);
1528 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1529 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1530 return (wpa_cli_commands[n].flags &
1531 cli_cmd_flag_sensitive);
1535 #endif /* CONFIG_READLINE */
1538 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1540 struct wpa_cli_cmd *cmd, *match = NULL;
1545 cmd = wpa_cli_commands;
1547 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1550 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1551 /* we have an exact match */
1561 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1562 cmd = wpa_cli_commands;
1564 if (os_strncasecmp(cmd->cmd, argv[0],
1565 os_strlen(argv[0])) == 0) {
1566 printf(" %s", cmd->cmd);
1572 } else if (count == 0) {
1573 printf("Unknown command '%s'\n", argv[0]);
1576 ret = match->handler(ctrl, argc - 1, &argv[1]);
1583 static int str_match(const char *a, const char *b)
1585 return os_strncmp(a, b, os_strlen(b)) == 0;
1589 static int wpa_cli_exec(const char *program, const char *arg1,
1597 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1598 cmd = os_malloc(len);
1601 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1602 if (res < 0 || (size_t) res >= len) {
1606 cmd[len - 1] = '\0';
1608 if (system(cmd) < 0)
1610 #endif /* _WIN32_WCE */
1617 static void wpa_cli_action_process(const char *msg)
1620 char *copy = NULL, *id, *pos2;
1625 pos = os_strchr(pos, '>');
1632 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1634 os_unsetenv("WPA_ID");
1635 os_unsetenv("WPA_ID_STR");
1636 os_unsetenv("WPA_CTRL_DIR");
1638 pos = os_strstr(pos, "[id=");
1640 copy = os_strdup(pos + 4);
1644 while (*pos2 && *pos2 != ' ')
1648 os_setenv("WPA_ID", id, 1);
1649 while (*pos2 && *pos2 != '=')
1654 while (*pos2 && *pos2 != ']')
1657 os_setenv("WPA_ID_STR", id, 1);
1661 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1663 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1664 wpa_cli_connected = 1;
1665 wpa_cli_last_id = new_id;
1666 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1668 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1669 if (wpa_cli_connected) {
1670 wpa_cli_connected = 0;
1671 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1673 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1674 printf("wpa_supplicant is terminating - stop monitoring\n");
1680 #ifndef CONFIG_ANSI_C_EXTRA
1681 static void wpa_cli_action_cb(char *msg, size_t len)
1683 wpa_cli_action_process(msg);
1685 #endif /* CONFIG_ANSI_C_EXTRA */
1688 static void wpa_cli_reconnect(void)
1690 wpa_cli_close_connection();
1691 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1693 printf("Connection to wpa_supplicant re-established\n");
1694 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1695 wpa_cli_attached = 1;
1697 printf("Warning: Failed to attach to "
1698 "wpa_supplicant.\n");
1704 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1708 if (ctrl_conn == NULL) {
1709 wpa_cli_reconnect();
1712 while (wpa_ctrl_pending(ctrl) > 0) {
1714 size_t len = sizeof(buf) - 1;
1715 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1718 wpa_cli_action_process(buf);
1720 if (in_read && first)
1723 printf("%s\n", buf);
1726 printf("Could not read pending message.\n");
1731 if (wpa_ctrl_pending(ctrl) < 0) {
1732 printf("Connection to wpa_supplicant lost - trying to "
1734 wpa_cli_reconnect();
1739 #ifdef CONFIG_READLINE
1740 static char * wpa_cli_cmd_gen(const char *text, int state)
1747 len = os_strlen(text);
1750 while ((cmd = wpa_cli_commands[i].cmd)) {
1752 if (os_strncasecmp(cmd, text, len) == 0)
1753 return os_strdup(cmd);
1760 static char * wpa_cli_dummy_gen(const char *text, int state)
1766 static char ** wpa_cli_completion(const char *text, int start, int end)
1768 return rl_completion_matches(text, start == 0 ?
1769 wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1771 #endif /* CONFIG_READLINE */
1774 static void wpa_cli_interactive(void)
1777 char cmdbuf[256], *cmd, *argv[max_args], *pos;
1779 #ifdef CONFIG_READLINE
1780 char *home, *hfile = NULL;
1781 #endif /* CONFIG_READLINE */
1783 printf("\nInteractive mode\n\n");
1785 #ifdef CONFIG_READLINE
1786 rl_attempted_completion_function = wpa_cli_completion;
1787 home = getenv("HOME");
1789 const char *fname = ".wpa_cli_history";
1790 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1791 hfile = os_malloc(hfile_len);
1794 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
1796 if (res >= 0 && res < hfile_len) {
1797 hfile[hfile_len - 1] = '\0';
1798 read_history(hfile);
1799 stifle_history(100);
1803 #endif /* CONFIG_READLINE */
1806 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1807 #ifndef CONFIG_NATIVE_WINDOWS
1808 alarm(ping_interval);
1809 #endif /* CONFIG_NATIVE_WINDOWS */
1810 #ifdef CONFIG_READLINE
1811 cmd = readline("> ");
1814 while (next_history())
1816 h = previous_history();
1817 if (h == NULL || os_strcmp(cmd, h->line) != 0)
1821 #else /* CONFIG_READLINE */
1823 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1824 #endif /* CONFIG_READLINE */
1825 #ifndef CONFIG_NATIVE_WINDOWS
1827 #endif /* CONFIG_NATIVE_WINDOWS */
1830 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1832 while (*pos != '\0') {
1848 if (argc == max_args)
1851 char *pos2 = os_strrchr(pos, '"');
1855 while (*pos != '\0' && *pos != ' ')
1861 wpa_request(ctrl_conn, argc, argv);
1865 } while (!wpa_cli_quit);
1867 #ifdef CONFIG_READLINE
1869 /* Save command history, excluding lines that may contain
1873 while ((h = current_history())) {
1875 while (*p == ' ' || *p == '\t')
1877 if (cmd_has_sensitive_data(p)) {
1878 h = remove_history(where_history());
1888 write_history(hfile);
1891 #endif /* CONFIG_READLINE */
1895 static void wpa_cli_action(struct wpa_ctrl *ctrl)
1897 #ifdef CONFIG_ANSI_C_EXTRA
1898 /* TODO: ANSI C version(?) */
1899 printf("Action processing not supported in ANSI C build.\n");
1900 #else /* CONFIG_ANSI_C_EXTRA */
1904 char buf[256]; /* note: large enough to fit in unsolicited messages */
1907 fd = wpa_ctrl_get_fd(ctrl);
1909 while (!wpa_cli_quit) {
1912 tv.tv_sec = ping_interval;
1914 res = select(fd + 1, &rfds, NULL, NULL, &tv);
1915 if (res < 0 && errno != EINTR) {
1920 if (FD_ISSET(fd, &rfds))
1921 wpa_cli_recv_pending(ctrl, 0, 1);
1923 /* verify that connection is still working */
1924 len = sizeof(buf) - 1;
1925 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
1926 wpa_cli_action_cb) < 0 ||
1927 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
1928 printf("wpa_supplicant did not reply to PING "
1929 "command - exiting\n");
1934 #endif /* CONFIG_ANSI_C_EXTRA */
1938 static void wpa_cli_cleanup(void)
1940 wpa_cli_close_connection();
1942 os_daemonize_terminate(pid_file);
1944 os_program_deinit();
1947 static void wpa_cli_terminate(int sig)
1954 #ifndef CONFIG_NATIVE_WINDOWS
1955 static void wpa_cli_alarm(int sig)
1957 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
1958 printf("Connection to wpa_supplicant lost - trying to "
1960 wpa_cli_close_connection();
1963 wpa_cli_reconnect();
1965 wpa_cli_recv_pending(ctrl_conn, 1, 0);
1966 alarm(ping_interval);
1968 #endif /* CONFIG_NATIVE_WINDOWS */
1971 static char * wpa_cli_get_default_ifname(void)
1973 char *ifname = NULL;
1975 #ifdef CONFIG_CTRL_IFACE_UNIX
1976 struct dirent *dent;
1977 DIR *dir = opendir(ctrl_iface_dir);
1980 while ((dent = readdir(dir))) {
1981 #ifdef _DIRENT_HAVE_D_TYPE
1983 * Skip the file if it is not a socket. Also accept
1984 * DT_UNKNOWN (0) in case the C library or underlying
1985 * file system does not support d_type.
1987 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
1989 #endif /* _DIRENT_HAVE_D_TYPE */
1990 if (os_strcmp(dent->d_name, ".") == 0 ||
1991 os_strcmp(dent->d_name, "..") == 0)
1993 printf("Selected interface '%s'\n", dent->d_name);
1994 ifname = os_strdup(dent->d_name);
1998 #endif /* CONFIG_CTRL_IFACE_UNIX */
2000 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2001 char buf[2048], *pos;
2003 struct wpa_ctrl *ctrl;
2006 ctrl = wpa_ctrl_open(NULL);
2010 len = sizeof(buf) - 1;
2011 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
2014 pos = os_strchr(buf, '\n');
2017 ifname = os_strdup(buf);
2019 wpa_ctrl_close(ctrl);
2020 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2026 int main(int argc, char *argv[])
2029 int warning_displayed = 0;
2033 const char *global = NULL;
2035 if (os_program_init())
2039 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2044 action_file = optarg;
2053 ping_interval = atoi(optarg);
2059 printf("%s\n", wpa_cli_version);
2062 os_free(ctrl_ifname);
2063 ctrl_ifname = os_strdup(optarg);
2066 ctrl_iface_dir = optarg;
2077 interactive = (argc == optind) && (action_file == NULL);
2080 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2083 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2084 ctrl_conn = wpa_ctrl_open(NULL);
2085 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2086 ctrl_conn = wpa_ctrl_open(global);
2087 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2088 if (ctrl_conn == NULL) {
2089 perror("Failed to connect to wpa_supplicant - "
2096 if (ctrl_ifname == NULL)
2097 ctrl_ifname = wpa_cli_get_default_ifname();
2098 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
2100 if (warning_displayed)
2101 printf("Connection established.\n");
2106 perror("Failed to connect to wpa_supplicant - "
2111 if (!warning_displayed) {
2112 printf("Could not connect to wpa_supplicant - "
2114 warning_displayed = 1;
2121 signal(SIGINT, wpa_cli_terminate);
2122 signal(SIGTERM, wpa_cli_terminate);
2123 #endif /* _WIN32_WCE */
2124 #ifndef CONFIG_NATIVE_WINDOWS
2125 signal(SIGALRM, wpa_cli_alarm);
2126 #endif /* CONFIG_NATIVE_WINDOWS */
2128 if (interactive || action_file) {
2129 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2130 wpa_cli_attached = 1;
2132 printf("Warning: Failed to attach to "
2133 "wpa_supplicant.\n");
2139 if (daemonize && os_daemonize(pid_file))
2143 wpa_cli_interactive();
2144 else if (action_file)
2145 wpa_cli_action(ctrl_conn);
2147 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2149 os_free(ctrl_ifname);
2155 #else /* CONFIG_CTRL_IFACE */
2156 int main(int argc, char *argv[])
2158 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2161 #endif /* CONFIG_CTRL_IFACE */