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_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
558 printf("Invalid IBSS_RSN command: needs one argument "
559 "(Peer STA MAC address)\n");
563 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
564 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
565 printf("Too long IBSS_RSN command.\n");
568 return wpa_ctrl_command(ctrl, cmd);
572 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
578 printf("Invalid LEVEL command: needs one argument (debug "
582 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
583 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
584 printf("Too long LEVEL command.\n");
587 return wpa_ctrl_command(ctrl, cmd);
591 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
593 char cmd[256], *pos, *end;
597 printf("Invalid IDENTITY command: needs two arguments "
598 "(network id and identity)\n");
602 end = cmd + sizeof(cmd);
604 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
606 if (ret < 0 || ret >= end - pos) {
607 printf("Too long IDENTITY command.\n");
611 for (i = 2; i < argc; i++) {
612 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
613 if (ret < 0 || ret >= end - pos) {
614 printf("Too long IDENTITY command.\n");
620 return wpa_ctrl_command(ctrl, cmd);
624 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
626 char cmd[256], *pos, *end;
630 printf("Invalid PASSWORD command: needs two arguments "
631 "(network id and password)\n");
635 end = cmd + sizeof(cmd);
637 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
639 if (ret < 0 || ret >= end - pos) {
640 printf("Too long PASSWORD command.\n");
644 for (i = 2; i < argc; i++) {
645 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
646 if (ret < 0 || ret >= end - pos) {
647 printf("Too long PASSWORD command.\n");
653 return wpa_ctrl_command(ctrl, cmd);
657 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
660 char cmd[256], *pos, *end;
664 printf("Invalid NEW_PASSWORD command: needs two arguments "
665 "(network id and password)\n");
669 end = cmd + sizeof(cmd);
671 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
673 if (ret < 0 || ret >= end - pos) {
674 printf("Too long NEW_PASSWORD command.\n");
678 for (i = 2; i < argc; i++) {
679 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
680 if (ret < 0 || ret >= end - pos) {
681 printf("Too long NEW_PASSWORD command.\n");
687 return wpa_ctrl_command(ctrl, cmd);
691 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
693 char cmd[256], *pos, *end;
697 printf("Invalid PIN command: needs two arguments "
698 "(network id and pin)\n");
702 end = cmd + sizeof(cmd);
704 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
706 if (ret < 0 || ret >= end - pos) {
707 printf("Too long PIN command.\n");
711 for (i = 2; i < argc; i++) {
712 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
713 if (ret < 0 || ret >= end - pos) {
714 printf("Too long PIN command.\n");
719 return wpa_ctrl_command(ctrl, cmd);
723 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
725 char cmd[256], *pos, *end;
729 printf("Invalid OTP command: needs two arguments (network "
730 "id and password)\n");
734 end = cmd + sizeof(cmd);
736 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
738 if (ret < 0 || ret >= end - pos) {
739 printf("Too long OTP command.\n");
743 for (i = 2; i < argc; i++) {
744 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
745 if (ret < 0 || ret >= end - pos) {
746 printf("Too long OTP command.\n");
752 return wpa_ctrl_command(ctrl, cmd);
756 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
759 char cmd[256], *pos, *end;
763 printf("Invalid PASSPHRASE command: needs two arguments "
764 "(network id and passphrase)\n");
768 end = cmd + sizeof(cmd);
770 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
772 if (ret < 0 || ret >= end - pos) {
773 printf("Too long PASSPHRASE command.\n");
777 for (i = 2; i < argc; i++) {
778 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
779 if (ret < 0 || ret >= end - pos) {
780 printf("Too long PASSPHRASE command.\n");
786 return wpa_ctrl_command(ctrl, cmd);
790 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
792 char cmd[256], *pos, *end;
796 printf("Invalid BSSID command: needs two arguments (network "
801 end = cmd + sizeof(cmd);
803 ret = os_snprintf(pos, end - pos, "BSSID");
804 if (ret < 0 || ret >= end - pos) {
805 printf("Too long BSSID command.\n");
809 for (i = 0; i < argc; i++) {
810 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
811 if (ret < 0 || ret >= end - pos) {
812 printf("Too long BSSID command.\n");
818 return wpa_ctrl_command(ctrl, cmd);
822 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
825 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
829 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
836 printf("Invalid SELECT_NETWORK command: needs one argument "
841 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
842 if (res < 0 || (size_t) res >= sizeof(cmd))
844 cmd[sizeof(cmd) - 1] = '\0';
846 return wpa_ctrl_command(ctrl, cmd);
850 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
857 printf("Invalid ENABLE_NETWORK command: needs one argument "
862 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
863 if (res < 0 || (size_t) res >= sizeof(cmd))
865 cmd[sizeof(cmd) - 1] = '\0';
867 return wpa_ctrl_command(ctrl, cmd);
871 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
878 printf("Invalid DISABLE_NETWORK command: needs one argument "
883 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
884 if (res < 0 || (size_t) res >= sizeof(cmd))
886 cmd[sizeof(cmd) - 1] = '\0';
888 return wpa_ctrl_command(ctrl, cmd);
892 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
895 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
899 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
906 printf("Invalid REMOVE_NETWORK command: needs one argument "
911 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
912 if (res < 0 || (size_t) res >= sizeof(cmd))
914 cmd[sizeof(cmd) - 1] = '\0';
916 return wpa_ctrl_command(ctrl, cmd);
920 static void wpa_cli_show_network_variables(void)
922 printf("set_network variables:\n"
923 " ssid (network name, SSID)\n"
924 " psk (WPA passphrase or pre-shared key)\n"
925 " key_mgmt (key management protocol)\n"
926 " identity (EAP identity)\n"
927 " password (EAP password)\n"
930 "Note: Values are entered in the same format as the "
931 "configuration file is using,\n"
932 "i.e., strings values need to be inside double quotation "
934 "For example: set_network 1 ssid \"network name\"\n"
936 "Please see wpa_supplicant.conf documentation for full list "
937 "of\navailable variables.\n");
941 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
948 wpa_cli_show_network_variables();
953 printf("Invalid SET_NETWORK command: needs three arguments\n"
954 "(network id, variable name, and value)\n");
958 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
959 argv[0], argv[1], argv[2]);
960 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
961 printf("Too long SET_NETWORK command.\n");
964 return wpa_ctrl_command(ctrl, cmd);
968 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
975 wpa_cli_show_network_variables();
980 printf("Invalid GET_NETWORK command: needs two arguments\n"
981 "(network id and variable name)\n");
985 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
987 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
988 printf("Too long GET_NETWORK command.\n");
991 return wpa_ctrl_command(ctrl, cmd);
995 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
998 return wpa_ctrl_command(ctrl, "DISCONNECT");
1002 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1005 return wpa_ctrl_command(ctrl, "RECONNECT");
1009 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1012 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1016 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1018 return wpa_ctrl_command(ctrl, "SCAN");
1022 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1025 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1029 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1035 printf("Invalid BSS command: need one argument (index or "
1040 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1041 if (res < 0 || (size_t) res >= sizeof(cmd))
1043 cmd[sizeof(cmd) - 1] = '\0';
1045 return wpa_ctrl_command(ctrl, cmd);
1049 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1055 if (argc < 1 || argc > 2) {
1056 printf("Invalid GET_CAPABILITY command: need either one or "
1061 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1062 printf("Invalid GET_CAPABILITY command: second argument, "
1063 "if any, must be 'strict'\n");
1067 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1068 (argc == 2) ? " strict" : "");
1069 if (res < 0 || (size_t) res >= sizeof(cmd))
1071 cmd[sizeof(cmd) - 1] = '\0';
1073 return wpa_ctrl_command(ctrl, cmd);
1077 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1079 printf("Available interfaces:\n");
1080 return wpa_ctrl_command(ctrl, "INTERFACES");
1084 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1087 wpa_cli_list_interfaces(ctrl);
1091 wpa_cli_close_connection();
1092 os_free(ctrl_ifname);
1093 ctrl_ifname = os_strdup(argv[0]);
1095 if (wpa_cli_open_connection(ctrl_ifname)) {
1096 printf("Connected to interface '%s.\n", ctrl_ifname);
1097 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1098 wpa_cli_attached = 1;
1100 printf("Warning: Failed to attach to "
1101 "wpa_supplicant.\n");
1104 printf("Could not connect to interface '%s' - re-trying\n",
1111 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1114 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1118 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1121 return wpa_ctrl_command(ctrl, "TERMINATE");
1125 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1132 printf("Invalid INTERFACE_ADD command: needs at least one "
1133 "argument (interface name)\n"
1134 "All arguments: ifname confname driver ctrl_interface "
1135 "driver_param bridge_name\n");
1140 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1141 * <driver_param>TAB<bridge_name>
1143 res = os_snprintf(cmd, sizeof(cmd),
1144 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1146 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1147 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1148 argc > 5 ? argv[5] : "");
1149 if (res < 0 || (size_t) res >= sizeof(cmd))
1151 cmd[sizeof(cmd) - 1] = '\0';
1152 return wpa_ctrl_command(ctrl, cmd);
1156 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1163 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1164 "(interface name)\n");
1168 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1169 if (res < 0 || (size_t) res >= sizeof(cmd))
1171 cmd[sizeof(cmd) - 1] = '\0';
1172 return wpa_ctrl_command(ctrl, cmd);
1176 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1179 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1184 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1188 printf("Invalid 'sta' command - exactly one argument, STA "
1189 "address, is required.\n");
1192 snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1193 return wpa_ctrl_command(ctrl, buf);
1197 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1198 char *addr, size_t addr_len)
1200 char buf[4096], *pos;
1204 if (ctrl_conn == NULL) {
1205 printf("Not connected to hostapd - command dropped.\n");
1208 len = sizeof(buf) - 1;
1209 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1212 printf("'%s' command timed out.\n", cmd);
1214 } else if (ret < 0) {
1215 printf("'%s' command failed.\n", cmd);
1220 if (memcmp(buf, "FAIL", 4) == 0)
1225 while (*pos != '\0' && *pos != '\n')
1228 os_strlcpy(addr, buf, addr_len);
1233 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1235 char addr[32], cmd[64];
1237 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1240 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1241 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1245 #endif /* CONFIG_AP */
1248 enum wpa_cli_cmd_flags {
1249 cli_cmd_flag_none = 0x00,
1250 cli_cmd_flag_sensitive = 0x01
1253 struct wpa_cli_cmd {
1255 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1256 enum wpa_cli_cmd_flags flags;
1260 static struct wpa_cli_cmd wpa_cli_commands[] = {
1261 { "status", wpa_cli_cmd_status,
1263 "[verbose] = get current WPA/EAPOL/EAP status" },
1264 { "ping", wpa_cli_cmd_ping,
1266 "= pings wpa_supplicant" },
1267 { "mib", wpa_cli_cmd_mib,
1269 "= get MIB variables (dot1x, dot11)" },
1270 { "help", wpa_cli_cmd_help,
1272 "= show this usage help" },
1273 { "interface", wpa_cli_cmd_interface,
1275 "[ifname] = show interfaces/select interface" },
1276 { "level", wpa_cli_cmd_level,
1278 "<debug level> = change debug level" },
1279 { "license", wpa_cli_cmd_license,
1281 "= show full wpa_cli license" },
1282 { "quit", wpa_cli_cmd_quit,
1285 { "set", wpa_cli_cmd_set,
1287 "= set variables (shows list of variables when run without "
1289 { "logon", wpa_cli_cmd_logon,
1291 "= IEEE 802.1X EAPOL state machine logon" },
1292 { "logoff", wpa_cli_cmd_logoff,
1294 "= IEEE 802.1X EAPOL state machine logoff" },
1295 { "pmksa", wpa_cli_cmd_pmksa,
1297 "= show PMKSA cache" },
1298 { "reassociate", wpa_cli_cmd_reassociate,
1300 "= force reassociation" },
1301 { "preauthenticate", wpa_cli_cmd_preauthenticate,
1303 "<BSSID> = force preauthentication" },
1304 { "identity", wpa_cli_cmd_identity,
1306 "<network id> <identity> = configure identity for an SSID" },
1307 { "password", wpa_cli_cmd_password,
1308 cli_cmd_flag_sensitive,
1309 "<network id> <password> = configure password for an SSID" },
1310 { "new_password", wpa_cli_cmd_new_password,
1311 cli_cmd_flag_sensitive,
1312 "<network id> <password> = change password for an SSID" },
1313 { "pin", wpa_cli_cmd_pin,
1314 cli_cmd_flag_sensitive,
1315 "<network id> <pin> = configure pin for an SSID" },
1316 { "otp", wpa_cli_cmd_otp,
1317 cli_cmd_flag_sensitive,
1318 "<network id> <password> = configure one-time-password for an SSID"
1320 { "passphrase", wpa_cli_cmd_passphrase,
1321 cli_cmd_flag_sensitive,
1322 "<network id> <passphrase> = configure private key passphrase\n"
1324 { "bssid", wpa_cli_cmd_bssid,
1326 "<network id> <BSSID> = set preferred BSSID for an SSID" },
1327 { "list_networks", wpa_cli_cmd_list_networks,
1329 "= list configured networks" },
1330 { "select_network", wpa_cli_cmd_select_network,
1332 "<network id> = select a network (disable others)" },
1333 { "enable_network", wpa_cli_cmd_enable_network,
1335 "<network id> = enable a network" },
1336 { "disable_network", wpa_cli_cmd_disable_network,
1338 "<network id> = disable a network" },
1339 { "add_network", wpa_cli_cmd_add_network,
1341 "= add a network" },
1342 { "remove_network", wpa_cli_cmd_remove_network,
1344 "<network id> = remove a network" },
1345 { "set_network", wpa_cli_cmd_set_network,
1346 cli_cmd_flag_sensitive,
1347 "<network id> <variable> <value> = set network variables (shows\n"
1348 " list of variables when run without arguments)" },
1349 { "get_network", wpa_cli_cmd_get_network,
1351 "<network id> <variable> = get network variables" },
1352 { "save_config", wpa_cli_cmd_save_config,
1354 "= save the current configuration" },
1355 { "disconnect", wpa_cli_cmd_disconnect,
1357 "= disconnect and wait for reassociate/reconnect command before\n"
1359 { "reconnect", wpa_cli_cmd_reconnect,
1361 "= like reassociate, but only takes effect if already disconnected"
1363 { "scan", wpa_cli_cmd_scan,
1365 "= request new BSS scan" },
1366 { "scan_results", wpa_cli_cmd_scan_results,
1368 "= get latest scan results" },
1369 { "bss", wpa_cli_cmd_bss,
1371 "<<idx> | <bssid>> = get detailed scan result info" },
1372 { "get_capability", wpa_cli_cmd_get_capability,
1374 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1375 { "reconfigure", wpa_cli_cmd_reconfigure,
1377 "= force wpa_supplicant to re-read its configuration file" },
1378 { "terminate", wpa_cli_cmd_terminate,
1380 "= terminate wpa_supplicant" },
1381 { "interface_add", wpa_cli_cmd_interface_add,
1383 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1384 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
1386 { "interface_remove", wpa_cli_cmd_interface_remove,
1388 "<ifname> = removes the interface" },
1389 { "interface_list", wpa_cli_cmd_interface_list,
1391 "= list available interfaces" },
1392 { "ap_scan", wpa_cli_cmd_ap_scan,
1394 "<value> = set ap_scan parameter" },
1395 { "stkstart", wpa_cli_cmd_stkstart,
1397 "<addr> = request STK negotiation with <addr>" },
1398 { "ft_ds", wpa_cli_cmd_ft_ds,
1400 "<addr> = request over-the-DS FT with <addr>" },
1401 { "wps_pbc", wpa_cli_cmd_wps_pbc,
1403 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1404 { "wps_pin", wpa_cli_cmd_wps_pin,
1405 cli_cmd_flag_sensitive,
1406 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1408 #ifdef CONFIG_WPS_OOB
1409 { "wps_oob", wpa_cli_cmd_wps_oob,
1410 cli_cmd_flag_sensitive,
1411 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1412 #endif /* CONFIG_WPS_OOB */
1413 { "wps_reg", wpa_cli_cmd_wps_reg,
1414 cli_cmd_flag_sensitive,
1415 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1416 { "wps_er_start", wpa_cli_cmd_wps_er_start,
1418 "= start Wi-Fi Protected Setup External Registrar" },
1419 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1421 "= stop Wi-Fi Protected Setup External Registrar" },
1422 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1424 "<addr> = request RSN authentication with <addr> in IBSS" },
1426 { "sta", wpa_cli_cmd_sta,
1428 "<addr> = get information about an associated station (AP)" },
1429 { "all_sta", wpa_cli_cmd_all_sta,
1431 "= get information about all associated stations (AP)" },
1432 #endif /* CONFIG_AP */
1433 { NULL, NULL, cli_cmd_flag_none, NULL }
1438 * Prints command usage, lines are padded with the specified string.
1440 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1445 printf("%s%s ", pad, cmd->cmd);
1446 for (n = 0; (c = cmd->usage[n]); n++) {
1455 static void print_help(void)
1458 printf("commands:\n");
1459 for (n = 0; wpa_cli_commands[n].cmd; n++)
1460 print_cmd_help(&wpa_cli_commands[n], " ");
1464 #ifdef CONFIG_READLINE
1465 static int cmd_has_sensitive_data(const char *cmd)
1467 const char *c, *delim;
1471 delim = os_strchr(cmd, ' ');
1475 len = os_strlen(cmd);
1477 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1478 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1479 return (wpa_cli_commands[n].flags &
1480 cli_cmd_flag_sensitive);
1484 #endif /* CONFIG_READLINE */
1487 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1489 struct wpa_cli_cmd *cmd, *match = NULL;
1494 cmd = wpa_cli_commands;
1496 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1499 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1500 /* we have an exact match */
1510 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1511 cmd = wpa_cli_commands;
1513 if (os_strncasecmp(cmd->cmd, argv[0],
1514 os_strlen(argv[0])) == 0) {
1515 printf(" %s", cmd->cmd);
1521 } else if (count == 0) {
1522 printf("Unknown command '%s'\n", argv[0]);
1525 ret = match->handler(ctrl, argc - 1, &argv[1]);
1532 static int str_match(const char *a, const char *b)
1534 return os_strncmp(a, b, os_strlen(b)) == 0;
1538 static int wpa_cli_exec(const char *program, const char *arg1,
1546 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1547 cmd = os_malloc(len);
1550 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1551 if (res < 0 || (size_t) res >= len) {
1555 cmd[len - 1] = '\0';
1557 if (system(cmd) < 0)
1559 #endif /* _WIN32_WCE */
1566 static void wpa_cli_action_process(const char *msg)
1569 char *copy = NULL, *id, *pos2;
1574 pos = os_strchr(pos, '>');
1581 if (str_match(pos, WPA_EVENT_CONNECTED)) {
1583 os_unsetenv("WPA_ID");
1584 os_unsetenv("WPA_ID_STR");
1585 os_unsetenv("WPA_CTRL_DIR");
1587 pos = os_strstr(pos, "[id=");
1589 copy = os_strdup(pos + 4);
1593 while (*pos2 && *pos2 != ' ')
1597 os_setenv("WPA_ID", id, 1);
1598 while (*pos2 && *pos2 != '=')
1603 while (*pos2 && *pos2 != ']')
1606 os_setenv("WPA_ID_STR", id, 1);
1610 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1612 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1613 wpa_cli_connected = 1;
1614 wpa_cli_last_id = new_id;
1615 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1617 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1618 if (wpa_cli_connected) {
1619 wpa_cli_connected = 0;
1620 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1622 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1623 printf("wpa_supplicant is terminating - stop monitoring\n");
1629 #ifndef CONFIG_ANSI_C_EXTRA
1630 static void wpa_cli_action_cb(char *msg, size_t len)
1632 wpa_cli_action_process(msg);
1634 #endif /* CONFIG_ANSI_C_EXTRA */
1637 static void wpa_cli_reconnect(void)
1639 wpa_cli_close_connection();
1640 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1642 printf("Connection to wpa_supplicant re-established\n");
1643 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1644 wpa_cli_attached = 1;
1646 printf("Warning: Failed to attach to "
1647 "wpa_supplicant.\n");
1653 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1657 if (ctrl_conn == NULL) {
1658 wpa_cli_reconnect();
1661 while (wpa_ctrl_pending(ctrl) > 0) {
1663 size_t len = sizeof(buf) - 1;
1664 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1667 wpa_cli_action_process(buf);
1669 if (in_read && first)
1672 printf("%s\n", buf);
1675 printf("Could not read pending message.\n");
1680 if (wpa_ctrl_pending(ctrl) < 0) {
1681 printf("Connection to wpa_supplicant lost - trying to "
1683 wpa_cli_reconnect();
1688 #ifdef CONFIG_READLINE
1689 static char * wpa_cli_cmd_gen(const char *text, int state)
1696 len = os_strlen(text);
1699 while ((cmd = wpa_cli_commands[i].cmd)) {
1701 if (os_strncasecmp(cmd, text, len) == 0)
1702 return os_strdup(cmd);
1709 static char * wpa_cli_dummy_gen(const char *text, int state)
1715 static char ** wpa_cli_completion(const char *text, int start, int end)
1717 return rl_completion_matches(text, start == 0 ?
1718 wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1720 #endif /* CONFIG_READLINE */
1723 static void wpa_cli_interactive(void)
1726 char cmdbuf[256], *cmd, *argv[max_args], *pos;
1728 #ifdef CONFIG_READLINE
1729 char *home, *hfile = NULL;
1730 #endif /* CONFIG_READLINE */
1732 printf("\nInteractive mode\n\n");
1734 #ifdef CONFIG_READLINE
1735 rl_attempted_completion_function = wpa_cli_completion;
1736 home = getenv("HOME");
1738 const char *fname = ".wpa_cli_history";
1739 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1740 hfile = os_malloc(hfile_len);
1743 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
1745 if (res >= 0 && res < hfile_len) {
1746 hfile[hfile_len - 1] = '\0';
1747 read_history(hfile);
1748 stifle_history(100);
1752 #endif /* CONFIG_READLINE */
1755 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1756 #ifndef CONFIG_NATIVE_WINDOWS
1757 alarm(ping_interval);
1758 #endif /* CONFIG_NATIVE_WINDOWS */
1759 #ifdef CONFIG_READLINE
1760 cmd = readline("> ");
1763 while (next_history())
1765 h = previous_history();
1766 if (h == NULL || os_strcmp(cmd, h->line) != 0)
1770 #else /* CONFIG_READLINE */
1772 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1773 #endif /* CONFIG_READLINE */
1774 #ifndef CONFIG_NATIVE_WINDOWS
1776 #endif /* CONFIG_NATIVE_WINDOWS */
1779 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1781 while (*pos != '\0') {
1797 if (argc == max_args)
1800 char *pos2 = os_strrchr(pos, '"');
1804 while (*pos != '\0' && *pos != ' ')
1810 wpa_request(ctrl_conn, argc, argv);
1814 } while (!wpa_cli_quit);
1816 #ifdef CONFIG_READLINE
1818 /* Save command history, excluding lines that may contain
1822 while ((h = current_history())) {
1824 while (*p == ' ' || *p == '\t')
1826 if (cmd_has_sensitive_data(p)) {
1827 h = remove_history(where_history());
1837 write_history(hfile);
1840 #endif /* CONFIG_READLINE */
1844 static void wpa_cli_action(struct wpa_ctrl *ctrl)
1846 #ifdef CONFIG_ANSI_C_EXTRA
1847 /* TODO: ANSI C version(?) */
1848 printf("Action processing not supported in ANSI C build.\n");
1849 #else /* CONFIG_ANSI_C_EXTRA */
1853 char buf[256]; /* note: large enough to fit in unsolicited messages */
1856 fd = wpa_ctrl_get_fd(ctrl);
1858 while (!wpa_cli_quit) {
1861 tv.tv_sec = ping_interval;
1863 res = select(fd + 1, &rfds, NULL, NULL, &tv);
1864 if (res < 0 && errno != EINTR) {
1869 if (FD_ISSET(fd, &rfds))
1870 wpa_cli_recv_pending(ctrl, 0, 1);
1872 /* verify that connection is still working */
1873 len = sizeof(buf) - 1;
1874 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
1875 wpa_cli_action_cb) < 0 ||
1876 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
1877 printf("wpa_supplicant did not reply to PING "
1878 "command - exiting\n");
1883 #endif /* CONFIG_ANSI_C_EXTRA */
1887 static void wpa_cli_cleanup(void)
1889 wpa_cli_close_connection();
1891 os_daemonize_terminate(pid_file);
1893 os_program_deinit();
1896 static void wpa_cli_terminate(int sig)
1903 #ifndef CONFIG_NATIVE_WINDOWS
1904 static void wpa_cli_alarm(int sig)
1906 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
1907 printf("Connection to wpa_supplicant lost - trying to "
1909 wpa_cli_close_connection();
1912 wpa_cli_reconnect();
1914 wpa_cli_recv_pending(ctrl_conn, 1, 0);
1915 alarm(ping_interval);
1917 #endif /* CONFIG_NATIVE_WINDOWS */
1920 static char * wpa_cli_get_default_ifname(void)
1922 char *ifname = NULL;
1924 #ifdef CONFIG_CTRL_IFACE_UNIX
1925 struct dirent *dent;
1926 DIR *dir = opendir(ctrl_iface_dir);
1929 while ((dent = readdir(dir))) {
1930 #ifdef _DIRENT_HAVE_D_TYPE
1932 * Skip the file if it is not a socket. Also accept
1933 * DT_UNKNOWN (0) in case the C library or underlying
1934 * file system does not support d_type.
1936 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
1938 #endif /* _DIRENT_HAVE_D_TYPE */
1939 if (os_strcmp(dent->d_name, ".") == 0 ||
1940 os_strcmp(dent->d_name, "..") == 0)
1942 printf("Selected interface '%s'\n", dent->d_name);
1943 ifname = os_strdup(dent->d_name);
1947 #endif /* CONFIG_CTRL_IFACE_UNIX */
1949 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1950 char buf[2048], *pos;
1952 struct wpa_ctrl *ctrl;
1955 ctrl = wpa_ctrl_open(NULL);
1959 len = sizeof(buf) - 1;
1960 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
1963 pos = os_strchr(buf, '\n');
1966 ifname = os_strdup(buf);
1968 wpa_ctrl_close(ctrl);
1969 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1975 int main(int argc, char *argv[])
1978 int warning_displayed = 0;
1982 const char *global = NULL;
1984 if (os_program_init())
1988 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
1993 action_file = optarg;
2002 ping_interval = atoi(optarg);
2008 printf("%s\n", wpa_cli_version);
2011 os_free(ctrl_ifname);
2012 ctrl_ifname = os_strdup(optarg);
2015 ctrl_iface_dir = optarg;
2026 interactive = (argc == optind) && (action_file == NULL);
2029 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2032 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2033 ctrl_conn = wpa_ctrl_open(NULL);
2034 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2035 ctrl_conn = wpa_ctrl_open(global);
2036 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2037 if (ctrl_conn == NULL) {
2038 perror("Failed to connect to wpa_supplicant - "
2045 if (ctrl_ifname == NULL)
2046 ctrl_ifname = wpa_cli_get_default_ifname();
2047 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
2049 if (warning_displayed)
2050 printf("Connection established.\n");
2055 perror("Failed to connect to wpa_supplicant - "
2060 if (!warning_displayed) {
2061 printf("Could not connect to wpa_supplicant - "
2063 warning_displayed = 1;
2070 signal(SIGINT, wpa_cli_terminate);
2071 signal(SIGTERM, wpa_cli_terminate);
2072 #endif /* _WIN32_WCE */
2073 #ifndef CONFIG_NATIVE_WINDOWS
2074 signal(SIGALRM, wpa_cli_alarm);
2075 #endif /* CONFIG_NATIVE_WINDOWS */
2077 if (interactive || action_file) {
2078 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2079 wpa_cli_attached = 1;
2081 printf("Warning: Failed to attach to "
2082 "wpa_supplicant.\n");
2088 if (daemonize && os_daemonize(pid_file))
2092 wpa_cli_interactive();
2093 else if (action_file)
2094 wpa_cli_action(ctrl_conn);
2096 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2098 os_free(ctrl_ifname);
2104 #else /* CONFIG_CTRL_IFACE */
2105 int main(int argc, char *argv[])
2107 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2110 #endif /* CONFIG_CTRL_IFACE */