Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * WPA Supplicant - command line interface for wpa_supplicant daemon
      3  * Copyright (c) 2004-2009, Jouni Malinen <j (at) w1.fi>
      4  *
      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.
      8  *
      9  * Alternatively, this software may be distributed under the terms of BSD
     10  * license.
     11  *
     12  * See README and COPYING for more details.
     13  */
     14 
     15 #include "includes.h"
     16 
     17 #ifdef CONFIG_CTRL_IFACE
     18 
     19 #ifdef CONFIG_CTRL_IFACE_UNIX
     20 #include <dirent.h>
     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 
     27 #define CTRL_INTERFACE_2_SOCKETS
     28 
     29 #include "wpa_ctrl.h"
     30 #include "common.h"
     31 #include "version.h"
     32 #ifdef ANDROID
     33 #include <cutils/properties.h>
     34 #endif
     35 
     36 
     37 static const char *wpa_cli_version =
     38 "wpa_cli v" VERSION_STR "\n"
     39 "Copyright (c) 2004-2009, Jouni Malinen <j (at) w1.fi> and contributors";
     40 
     41 
     42 static const char *wpa_cli_license =
     43 "This program is free software. You can distribute it and/or modify it\n"
     44 "under the terms of the GNU General Public License version 2.\n"
     45 "\n"
     46 "Alternatively, this software may be distributed under the terms of the\n"
     47 "BSD license. See README and COPYING for more details.\n";
     48 
     49 static const char *wpa_cli_full_license =
     50 "This program is free software; you can redistribute it and/or modify\n"
     51 "it under the terms of the GNU General Public License version 2 as\n"
     52 "published by the Free Software Foundation.\n"
     53 "\n"
     54 "This program is distributed in the hope that it will be useful,\n"
     55 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
     56 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
     57 "GNU General Public License for more details.\n"
     58 "\n"
     59 "You should have received a copy of the GNU General Public License\n"
     60 "along with this program; if not, write to the Free Software\n"
     61 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n"
     62 "\n"
     63 "Alternatively, this software may be distributed under the terms of the\n"
     64 "BSD license.\n"
     65 "\n"
     66 "Redistribution and use in source and binary forms, with or without\n"
     67 "modification, are permitted provided that the following conditions are\n"
     68 "met:\n"
     69 "\n"
     70 "1. Redistributions of source code must retain the above copyright\n"
     71 "   notice, this list of conditions and the following disclaimer.\n"
     72 "\n"
     73 "2. Redistributions in binary form must reproduce the above copyright\n"
     74 "   notice, this list of conditions and the following disclaimer in the\n"
     75 "   documentation and/or other materials provided with the distribution.\n"
     76 "\n"
     77 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
     78 "   names of its contributors may be used to endorse or promote products\n"
     79 "   derived from this software without specific prior written permission.\n"
     80 "\n"
     81 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
     82 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
     83 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
     84 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
     85 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
     86 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
     87 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
     88 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
     89 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
     90 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
     91 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
     92 "\n";
     93 
     94 static struct wpa_ctrl *ctrl_conn;
     95 static struct wpa_ctrl *monitor_conn;
     96 static int wpa_cli_quit = 0;
     97 static int wpa_cli_attached = 0;
     98 static int wpa_cli_connected = 0;
     99 static int wpa_cli_last_id = 0;
    100 #ifdef ANDROID
    101 static const char *ctrl_iface_dir = "/data/misc/wifi/wpa_supplicant";
    102 #else
    103 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
    104 #endif
    105 static char *ctrl_ifname = NULL;
    106 static const char *pid_file = NULL;
    107 static const char *action_file = NULL;
    108 static int ping_interval = 5;
    109 
    110 
    111 static void print_help();
    112 
    113 
    114 static void usage(void)
    115 {
    116 	printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
    117 	       "[-a<action file>] \\\n"
    118 	       "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>]  "
    119 	       "[command..]\n"
    120 	       "  -h = help (show this usage text)\n"
    121 	       "  -v = shown version information\n"
    122 	       "  -a = run in daemon mode executing the action file based on "
    123 	       "events from\n"
    124 	       "       wpa_supplicant\n"
    125 	       "  -B = run a daemon in the background\n"
    126 	       "  default path: /var/run/wpa_supplicant\n"
    127 	       "  default interface: first interface found in socket path\n");
    128 	print_help();
    129 }
    130 
    131 
    132 static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
    133 {
    134     struct wpa_ctrl *cur_conn;
    135 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
    136 	cur_conn = wpa_ctrl_open(ifname);
    137 	return cur_conn;
    138 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
    139 	char *cfile;
    140 	int flen, res;
    141 
    142 	if (ifname == NULL)
    143 		return NULL;
    144 
    145 #ifdef ANDROID
    146 	if (access(ctrl_iface_dir, F_OK) < 0)
    147 		cfile = (char *)ifname;
    148 	else {
    149 #endif
    150 	flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
    151 	cfile = os_malloc(flen);
    152 	if (cfile == NULL)
    153 		return NULL;
    154 	res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
    155 	if (res < 0 || res >= flen) {
    156 		os_free(cfile);
    157 		return NULL;
    158 	}
    159 #ifdef ANDROID
    160     }
    161 #endif
    162 
    163 	cur_conn = wpa_ctrl_open(cfile);
    164 #ifdef CTRL_INTERFACE_2_SOCKETS
    165 	monitor_conn = wpa_ctrl_open(cfile);
    166 #else
    167 	monitor_conn = cur_conn;
    168 #endif
    169 #ifdef ANDROID
    170 	if (cfile != ifname)
    171 #endif
    172 	os_free(cfile);
    173 	return cur_conn;
    174 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
    175 }
    176 
    177 
    178 static void wpa_cli_close_connection(void)
    179 {
    180 	if (ctrl_conn == NULL)
    181 		return;
    182 
    183 	if (wpa_cli_attached) {
    184 		wpa_ctrl_detach(monitor_conn);
    185 		wpa_cli_attached = 0;
    186 	}
    187 #ifdef CTRL_INTERFACE_2_SOCKETS
    188 	wpa_ctrl_close(monitor_conn);
    189 #endif
    190 	wpa_ctrl_close(ctrl_conn);
    191 	ctrl_conn = monitor_conn = NULL;
    192 }
    193 
    194 
    195 static void wpa_cli_msg_cb(char *msg, size_t len)
    196 {
    197 	printf("%s\n", msg);
    198 }
    199 
    200 
    201 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
    202 {
    203 	char buf[4096];
    204 	size_t len;
    205 	int ret;
    206 
    207 	if (ctrl_conn == NULL) {
    208 		printf("Not connected to wpa_supplicant - command dropped.\n");
    209 		return -1;
    210 	}
    211 	len = sizeof(buf) - 1;
    212 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
    213 			       wpa_cli_msg_cb);
    214 	if (ret == -2) {
    215 		printf("'%s' command timed out.\n", cmd);
    216 		return -2;
    217 	} else if (ret < 0) {
    218 		printf("'%s' command failed.\n", cmd);
    219 		return -1;
    220 	}
    221 	if (print) {
    222 		buf[len] = '\0';
    223 		printf("%s", buf);
    224 	}
    225 	return 0;
    226 }
    227 
    228 
    229 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
    230 {
    231 	return _wpa_ctrl_command(ctrl, cmd, 1);
    232 }
    233 
    234 
    235 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
    236 {
    237 	int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
    238 	return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
    239 }
    240 
    241 
    242 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
    243 {
    244 	return wpa_ctrl_command(ctrl, "PING");
    245 }
    246 
    247 
    248 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
    249 {
    250 	return wpa_ctrl_command(ctrl, "MIB");
    251 }
    252 
    253 
    254 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
    255 {
    256 	return wpa_ctrl_command(ctrl, "PMKSA");
    257 }
    258 
    259 
    260 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
    261 {
    262 	print_help();
    263 	return 0;
    264 }
    265 
    266 
    267 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
    268 {
    269 	printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
    270 	return 0;
    271 }
    272 
    273 
    274 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
    275 {
    276 	wpa_cli_quit = 1;
    277 	return 0;
    278 }
    279 
    280 
    281 static void wpa_cli_show_variables(void)
    282 {
    283 	printf("set variables:\n"
    284 	       "  EAPOL::heldPeriod (EAPOL state machine held period, "
    285 	       "in seconds)\n"
    286 	       "  EAPOL::authPeriod (EAPOL state machine authentication "
    287 	       "period, in seconds)\n"
    288 	       "  EAPOL::startPeriod (EAPOL state machine start period, in "
    289 	       "seconds)\n"
    290 	       "  EAPOL::maxStart (EAPOL state machine maximum start "
    291 	       "attempts)\n");
    292 	printf("  dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
    293 	       "seconds)\n"
    294 	       "  dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
    295 	       " threshold\n\tpercentage)\n"
    296 	       "  dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
    297 	       "security\n\tassociation in seconds)\n");
    298 }
    299 
    300 
    301 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
    302 {
    303 	char cmd[256];
    304 	int res;
    305 
    306 	if (argc == 0) {
    307 		wpa_cli_show_variables();
    308 		return 0;
    309 	}
    310 
    311 	if (argc != 2) {
    312 		printf("Invalid SET command: needs two arguments (variable "
    313 		       "name and value)\n");
    314 		return -1;
    315 	}
    316 
    317 	res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
    318 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    319 		printf("Too long SET command.\n");
    320 		return -1;
    321 	}
    322 	return wpa_ctrl_command(ctrl, cmd);
    323 }
    324 
    325 
    326 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
    327 {
    328 	return wpa_ctrl_command(ctrl, "LOGOFF");
    329 }
    330 
    331 
    332 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
    333 {
    334 	return wpa_ctrl_command(ctrl, "LOGON");
    335 }
    336 
    337 
    338 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
    339 				   char *argv[])
    340 {
    341 	return wpa_ctrl_command(ctrl, "REASSOCIATE");
    342 }
    343 
    344 
    345 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
    346 				       char *argv[])
    347 {
    348 	char cmd[256];
    349 	int res;
    350 
    351 	if (argc != 1) {
    352 		printf("Invalid PREAUTH command: needs one argument "
    353 		       "(BSSID)\n");
    354 		return -1;
    355 	}
    356 
    357 	res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
    358 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    359 		printf("Too long PREAUTH command.\n");
    360 		return -1;
    361 	}
    362 	return wpa_ctrl_command(ctrl, cmd);
    363 }
    364 
    365 
    366 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
    367 {
    368 	char cmd[256];
    369 	int res;
    370 
    371 	if (argc != 1) {
    372 		printf("Invalid AP_SCAN command: needs one argument (ap_scan "
    373 		       "value)\n");
    374 		return -1;
    375 	}
    376 	res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
    377 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    378 		printf("Too long AP_SCAN command.\n");
    379 		return -1;
    380 	}
    381 	return wpa_ctrl_command(ctrl, cmd);
    382 }
    383 
    384 
    385 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
    386 				char *argv[])
    387 {
    388 	char cmd[256];
    389 	int res;
    390 
    391 	if (argc != 1) {
    392 		printf("Invalid STKSTART command: needs one argument "
    393 		       "(Peer STA MAC address)\n");
    394 		return -1;
    395 	}
    396 
    397 	res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
    398 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    399 		printf("Too long STKSTART command.\n");
    400 		return -1;
    401 	}
    402 	return wpa_ctrl_command(ctrl, cmd);
    403 }
    404 
    405 
    406 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
    407 {
    408 	char cmd[256];
    409 	int res;
    410 
    411 	if (argc != 1) {
    412 		printf("Invalid FT_DS command: needs one argument "
    413 		       "(Target AP MAC address)\n");
    414 		return -1;
    415 	}
    416 
    417 	res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
    418 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    419 		printf("Too long FT_DS command.\n");
    420 		return -1;
    421 	}
    422 	return wpa_ctrl_command(ctrl, cmd);
    423 }
    424 
    425 
    426 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
    427 {
    428 	char cmd[256];
    429 	int res;
    430 
    431 	if (argc == 0) {
    432 		/* Any BSSID */
    433 		return wpa_ctrl_command(ctrl, "WPS_PBC");
    434 	}
    435 
    436 	/* Specific BSSID */
    437 	res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
    438 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    439 		printf("Too long WPS_PBC command.\n");
    440 		return -1;
    441 	}
    442 	return wpa_ctrl_command(ctrl, cmd);
    443 }
    444 
    445 
    446 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
    447 {
    448 	char cmd[256];
    449 	int res;
    450 
    451 	if (argc == 0) {
    452 		printf("Invalid WPS_PIN command: need one or two arguments:\n"
    453 		       "- BSSID: use 'any' to select any\n"
    454 		       "- PIN: optional, used only with devices that have no "
    455 		       "display\n");
    456 		return -1;
    457 	}
    458 
    459 	if (argc == 1) {
    460 		/* Use dynamically generated PIN (returned as reply) */
    461 		res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
    462 		if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    463 			printf("Too long WPS_PIN command.\n");
    464 			return -1;
    465 		}
    466 		return wpa_ctrl_command(ctrl, cmd);
    467 	}
    468 
    469 	/* Use hardcoded PIN from a label */
    470 	res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
    471 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    472 		printf("Too long WPS_PIN command.\n");
    473 		return -1;
    474 	}
    475 	return wpa_ctrl_command(ctrl, cmd);
    476 }
    477 
    478 
    479 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
    480 {
    481 	char cmd[256];
    482 	int res;
    483 
    484 	if (argc != 2) {
    485 		printf("Invalid WPS_REG command: need two arguments:\n"
    486 		       "- BSSID: use 'any' to select any\n"
    487 		       "- AP PIN\n");
    488 		return -1;
    489 	}
    490 
    491 	res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", argv[0], argv[1]);
    492 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    493 		printf("Too long WPS_REG command.\n");
    494 		return -1;
    495 	}
    496 	return wpa_ctrl_command(ctrl, cmd);
    497 }
    498 
    499 
    500 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
    501 {
    502 	char cmd[256];
    503 	int res;
    504 
    505 	if (argc != 1) {
    506 		printf("Invalid LEVEL command: needs one argument (debug "
    507 		       "level)\n");
    508 		return -1;
    509 	}
    510 	res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
    511 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    512 		printf("Too long LEVEL command.\n");
    513 		return -1;
    514 	}
    515 	return wpa_ctrl_command(ctrl, cmd);
    516 }
    517 
    518 
    519 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
    520 {
    521 	char cmd[256], *pos, *end;
    522 	int i, ret;
    523 
    524 	if (argc < 2) {
    525 		printf("Invalid IDENTITY command: needs two arguments "
    526 		       "(network id and identity)\n");
    527 		return -1;
    528 	}
    529 
    530 	end = cmd + sizeof(cmd);
    531 	pos = cmd;
    532 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
    533 			  argv[0], argv[1]);
    534 	if (ret < 0 || ret >= end - pos) {
    535 		printf("Too long IDENTITY command.\n");
    536 		return -1;
    537 	}
    538 	pos += ret;
    539 	for (i = 2; i < argc; i++) {
    540 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    541 		if (ret < 0 || ret >= end - pos) {
    542 			printf("Too long IDENTITY command.\n");
    543 			return -1;
    544 		}
    545 		pos += ret;
    546 	}
    547 
    548 	return wpa_ctrl_command(ctrl, cmd);
    549 }
    550 
    551 
    552 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
    553 {
    554 	char cmd[256], *pos, *end;
    555 	int i, ret;
    556 
    557 	if (argc < 2) {
    558 		printf("Invalid PASSWORD command: needs two arguments "
    559 		       "(network id and password)\n");
    560 		return -1;
    561 	}
    562 
    563 	end = cmd + sizeof(cmd);
    564 	pos = cmd;
    565 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
    566 			  argv[0], argv[1]);
    567 	if (ret < 0 || ret >= end - pos) {
    568 		printf("Too long PASSWORD command.\n");
    569 		return -1;
    570 	}
    571 	pos += ret;
    572 	for (i = 2; i < argc; i++) {
    573 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    574 		if (ret < 0 || ret >= end - pos) {
    575 			printf("Too long PASSWORD command.\n");
    576 			return -1;
    577 		}
    578 		pos += ret;
    579 	}
    580 
    581 	return wpa_ctrl_command(ctrl, cmd);
    582 }
    583 
    584 
    585 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
    586 				    char *argv[])
    587 {
    588 	char cmd[256], *pos, *end;
    589 	int i, ret;
    590 
    591 	if (argc < 2) {
    592 		printf("Invalid NEW_PASSWORD command: needs two arguments "
    593 		       "(network id and password)\n");
    594 		return -1;
    595 	}
    596 
    597 	end = cmd + sizeof(cmd);
    598 	pos = cmd;
    599 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
    600 			  argv[0], argv[1]);
    601 	if (ret < 0 || ret >= end - pos) {
    602 		printf("Too long NEW_PASSWORD command.\n");
    603 		return -1;
    604 	}
    605 	pos += ret;
    606 	for (i = 2; i < argc; i++) {
    607 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    608 		if (ret < 0 || ret >= end - pos) {
    609 			printf("Too long NEW_PASSWORD command.\n");
    610 			return -1;
    611 		}
    612 		pos += ret;
    613 	}
    614 
    615 	return wpa_ctrl_command(ctrl, cmd);
    616 }
    617 
    618 
    619 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
    620 {
    621 	char cmd[256], *pos, *end;
    622 	int i, ret;
    623 
    624 	if (argc < 2) {
    625 		printf("Invalid PIN command: needs two arguments "
    626 		       "(network id and pin)\n");
    627 		return -1;
    628 	}
    629 
    630 	end = cmd + sizeof(cmd);
    631 	pos = cmd;
    632 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
    633 			  argv[0], argv[1]);
    634 	if (ret < 0 || ret >= end - pos) {
    635 		printf("Too long PIN command.\n");
    636 		return -1;
    637 	}
    638 	pos += ret;
    639 	for (i = 2; i < argc; i++) {
    640 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    641 		if (ret < 0 || ret >= end - pos) {
    642 			printf("Too long PIN command.\n");
    643 			return -1;
    644 		}
    645 		pos += ret;
    646 	}
    647 	return wpa_ctrl_command(ctrl, cmd);
    648 }
    649 
    650 
    651 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
    652 {
    653 	char cmd[256], *pos, *end;
    654 	int i, ret;
    655 
    656 	if (argc < 2) {
    657 		printf("Invalid OTP command: needs two arguments (network "
    658 		       "id and password)\n");
    659 		return -1;
    660 	}
    661 
    662 	end = cmd + sizeof(cmd);
    663 	pos = cmd;
    664 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
    665 			  argv[0], argv[1]);
    666 	if (ret < 0 || ret >= end - pos) {
    667 		printf("Too long OTP command.\n");
    668 		return -1;
    669 	}
    670 	pos += ret;
    671 	for (i = 2; i < argc; i++) {
    672 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    673 		if (ret < 0 || ret >= end - pos) {
    674 			printf("Too long OTP command.\n");
    675 			return -1;
    676 		}
    677 		pos += ret;
    678 	}
    679 
    680 	return wpa_ctrl_command(ctrl, cmd);
    681 }
    682 
    683 
    684 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
    685 				  char *argv[])
    686 {
    687 	char cmd[256], *pos, *end;
    688 	int i, ret;
    689 
    690 	if (argc < 2) {
    691 		printf("Invalid PASSPHRASE command: needs two arguments "
    692 		       "(network id and passphrase)\n");
    693 		return -1;
    694 	}
    695 
    696 	end = cmd + sizeof(cmd);
    697 	pos = cmd;
    698 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
    699 			  argv[0], argv[1]);
    700 	if (ret < 0 || ret >= end - pos) {
    701 		printf("Too long PASSPHRASE command.\n");
    702 		return -1;
    703 	}
    704 	pos += ret;
    705 	for (i = 2; i < argc; i++) {
    706 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    707 		if (ret < 0 || ret >= end - pos) {
    708 			printf("Too long PASSPHRASE command.\n");
    709 			return -1;
    710 		}
    711 		pos += ret;
    712 	}
    713 
    714 	return wpa_ctrl_command(ctrl, cmd);
    715 }
    716 
    717 
    718 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
    719 {
    720 	char cmd[256], *pos, *end;
    721 	int i, ret;
    722 
    723 	if (argc < 2) {
    724 		printf("Invalid BSSID command: needs two arguments (network "
    725 		       "id and BSSID)\n");
    726 		return -1;
    727 	}
    728 
    729 	end = cmd + sizeof(cmd);
    730 	pos = cmd;
    731 	ret = os_snprintf(pos, end - pos, "BSSID");
    732 	if (ret < 0 || ret >= end - pos) {
    733 		printf("Too long BSSID command.\n");
    734 		return -1;
    735 	}
    736 	pos += ret;
    737 	for (i = 0; i < argc; i++) {
    738 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    739 		if (ret < 0 || ret >= end - pos) {
    740 			printf("Too long BSSID command.\n");
    741 			return -1;
    742 		}
    743 		pos += ret;
    744 	}
    745 
    746 	return wpa_ctrl_command(ctrl, cmd);
    747 }
    748 
    749 
    750 #ifdef ANDROID
    751 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
    752 {
    753 	char cmd[256], *pos, *end;
    754 	int i, ret;
    755 
    756 	end = cmd + sizeof(cmd);
    757 	pos = cmd;
    758 	ret = os_snprintf(pos, end - pos, "BLACKLIST");
    759 	if (ret < 0 || ret >= end - pos) {
    760 		printf("Too long BLACKLIST command.\n");
    761 		return -1;
    762 	}
    763 	pos += ret;
    764 	for (i = 0; i < argc; i++) {
    765 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    766 		if (ret < 0 || ret >= end - pos) {
    767 			printf("Too long BLACKLIST command.\n");
    768 			return -1;
    769 		}
    770 		pos += ret;
    771 	}
    772 
    773 	return wpa_ctrl_command(ctrl, cmd);
    774 }
    775 
    776 
    777 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
    778 {
    779 	char cmd[256], *pos, *end;
    780 	int i, ret;
    781 
    782 	end = cmd + sizeof(cmd);
    783 	pos = cmd;
    784 	ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
    785 	if (ret < 0 || ret >= end - pos) {
    786 		printf("Too long LOG_LEVEL command.\n");
    787 		return -1;
    788 	}
    789 	pos += ret;
    790 	for (i = 0; i < argc; i++) {
    791 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    792 		if (ret < 0 || ret >= end - pos) {
    793 			printf("Too long LOG_LEVEL command.\n");
    794 			return -1;
    795 		}
    796 		pos += ret;
    797 	}
    798 
    799 	return wpa_ctrl_command(ctrl, cmd);
    800 }
    801 #endif /* ANDROID */
    802 
    803 
    804 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
    805 				     char *argv[])
    806 {
    807 	return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
    808 }
    809 
    810 
    811 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
    812 				      char *argv[])
    813 {
    814 	char cmd[32];
    815 	int res;
    816 
    817 	if (argc < 1) {
    818 		printf("Invalid SELECT_NETWORK command: needs one argument "
    819 		       "(network id)\n");
    820 		return -1;
    821 	}
    822 
    823 	res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
    824 	if (res < 0 || (size_t) res >= sizeof(cmd))
    825 		return -1;
    826 	cmd[sizeof(cmd) - 1] = '\0';
    827 
    828 	return wpa_ctrl_command(ctrl, cmd);
    829 }
    830 
    831 
    832 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
    833 				      char *argv[])
    834 {
    835 	char cmd[32];
    836 	int res;
    837 
    838 	if (argc < 1) {
    839 		printf("Invalid ENABLE_NETWORK command: needs one argument "
    840 		       "(network id)\n");
    841 		return -1;
    842 	}
    843 
    844 	res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
    845 	if (res < 0 || (size_t) res >= sizeof(cmd))
    846 		return -1;
    847 	cmd[sizeof(cmd) - 1] = '\0';
    848 
    849 	return wpa_ctrl_command(ctrl, cmd);
    850 }
    851 
    852 
    853 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
    854 				       char *argv[])
    855 {
    856 	char cmd[32];
    857 	int res;
    858 
    859 	if (argc < 1) {
    860 		printf("Invalid DISABLE_NETWORK command: needs one argument "
    861 		       "(network id)\n");
    862 		return -1;
    863 	}
    864 
    865 	res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
    866 	if (res < 0 || (size_t) res >= sizeof(cmd))
    867 		return -1;
    868 	cmd[sizeof(cmd) - 1] = '\0';
    869 
    870 	return wpa_ctrl_command(ctrl, cmd);
    871 }
    872 
    873 
    874 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
    875 				   char *argv[])
    876 {
    877 	return wpa_ctrl_command(ctrl, "ADD_NETWORK");
    878 }
    879 
    880 
    881 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
    882 				      char *argv[])
    883 {
    884 	char cmd[32];
    885 	int res;
    886 
    887 	if (argc < 1) {
    888 		printf("Invalid REMOVE_NETWORK command: needs one argument "
    889 		       "(network id)\n");
    890 		return -1;
    891 	}
    892 
    893 	res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
    894 	if (res < 0 || (size_t) res >= sizeof(cmd))
    895 		return -1;
    896 	cmd[sizeof(cmd) - 1] = '\0';
    897 
    898 	return wpa_ctrl_command(ctrl, cmd);
    899 }
    900 
    901 
    902 static void wpa_cli_show_network_variables(void)
    903 {
    904 	printf("set_network variables:\n"
    905 	       "  ssid (network name, SSID)\n"
    906 	       "  psk (WPA passphrase or pre-shared key)\n"
    907 	       "  key_mgmt (key management protocol)\n"
    908 	       "  identity (EAP identity)\n"
    909 	       "  password (EAP password)\n"
    910 	       "  ...\n"
    911 	       "\n"
    912 	       "Note: Values are entered in the same format as the "
    913 	       "configuration file is using,\n"
    914 	       "i.e., strings values need to be inside double quotation "
    915 	       "marks.\n"
    916 	       "For example: set_network 1 ssid \"network name\"\n"
    917 	       "\n"
    918 	       "Please see wpa_supplicant.conf documentation for full list "
    919 	       "of\navailable variables.\n");
    920 }
    921 
    922 
    923 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
    924 				   char *argv[])
    925 {
    926 	char cmd[256];
    927 	int res;
    928 
    929 	if (argc == 0) {
    930 		wpa_cli_show_network_variables();
    931 		return 0;
    932 	}
    933 
    934 	if (argc != 3) {
    935 		printf("Invalid SET_NETWORK command: needs three arguments\n"
    936 		       "(network id, variable name, and value)\n");
    937 		return -1;
    938 	}
    939 
    940 	res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
    941 			  argv[0], argv[1], argv[2]);
    942 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    943 		printf("Too long SET_NETWORK command.\n");
    944 		return -1;
    945 	}
    946 	return wpa_ctrl_command(ctrl, cmd);
    947 }
    948 
    949 
    950 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
    951 				   char *argv[])
    952 {
    953 	char cmd[256];
    954 	int res;
    955 
    956 	if (argc == 0) {
    957 		wpa_cli_show_network_variables();
    958 		return 0;
    959 	}
    960 
    961 	if (argc != 2) {
    962 		printf("Invalid GET_NETWORK command: needs two arguments\n"
    963 		       "(network id and variable name)\n");
    964 		return -1;
    965 	}
    966 
    967 	res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
    968 			  argv[0], argv[1]);
    969 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    970 		printf("Too long GET_NETWORK command.\n");
    971 		return -1;
    972 	}
    973 	return wpa_ctrl_command(ctrl, cmd);
    974 }
    975 
    976 
    977 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
    978 				  char *argv[])
    979 {
    980 	return wpa_ctrl_command(ctrl, "DISCONNECT");
    981 }
    982 
    983 
    984 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
    985 				  char *argv[])
    986 {
    987 	return wpa_ctrl_command(ctrl, "RECONNECT");
    988 }
    989 
    990 
    991 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
    992 				   char *argv[])
    993 {
    994 	return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
    995 }
    996 
    997 
    998 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
    999 {
   1000 	return wpa_ctrl_command(ctrl, "SCAN");
   1001 }
   1002 
   1003 
   1004 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
   1005 				    char *argv[])
   1006 {
   1007 	return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
   1008 }
   1009 
   1010 
   1011 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1012 {
   1013 	char cmd[64];
   1014 	int res;
   1015 
   1016 	if (argc != 1) {
   1017 		printf("Invalid BSS command: need one argument (index or "
   1018 		       "BSSID)\n");
   1019 		return -1;
   1020 	}
   1021 
   1022 	res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
   1023 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1024 		return -1;
   1025 	cmd[sizeof(cmd) - 1] = '\0';
   1026 
   1027 	return wpa_ctrl_command(ctrl, cmd);
   1028 }
   1029 
   1030 
   1031 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
   1032 				      char *argv[])
   1033 {
   1034 	char cmd[64];
   1035 	int res;
   1036 
   1037 	if (argc < 1 || argc > 2) {
   1038 		printf("Invalid GET_CAPABILITY command: need either one or "
   1039 		       "two arguments\n");
   1040 		return -1;
   1041 	}
   1042 
   1043 	if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
   1044 		printf("Invalid GET_CAPABILITY command: second argument, "
   1045 		       "if any, must be 'strict'\n");
   1046 		return -1;
   1047 	}
   1048 
   1049 	res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
   1050 			  (argc == 2) ? " strict" : "");
   1051 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1052 		return -1;
   1053 	cmd[sizeof(cmd) - 1] = '\0';
   1054 
   1055 	return wpa_ctrl_command(ctrl, cmd);
   1056 }
   1057 
   1058 
   1059 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
   1060 {
   1061 	printf("Available interfaces:\n");
   1062 	return wpa_ctrl_command(ctrl, "INTERFACES");
   1063 }
   1064 
   1065 
   1066 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1067 {
   1068 	if (argc < 1) {
   1069 		wpa_cli_list_interfaces(ctrl);
   1070 		return 0;
   1071 	}
   1072 
   1073 	wpa_cli_close_connection();
   1074 	os_free(ctrl_ifname);
   1075 	ctrl_ifname = os_strdup(argv[0]);
   1076 
   1077 	if ((ctrl_conn = wpa_cli_open_connection(ctrl_ifname)) != NULL) {
   1078 		printf("Connected to interface '%s.\n", ctrl_ifname);
   1079 		if (wpa_ctrl_attach(monitor_conn) == 0) {
   1080 			wpa_cli_attached = 1;
   1081 		} else {
   1082 			printf("Warning: Failed to attach to "
   1083 			       "wpa_supplicant.\n");
   1084 		}
   1085 	} else {
   1086 		printf("Could not connect to interface '%s' - re-trying\n",
   1087 		       ctrl_ifname);
   1088 	}
   1089 	return 0;
   1090 }
   1091 
   1092 
   1093 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
   1094 				   char *argv[])
   1095 {
   1096 	return wpa_ctrl_command(ctrl, "RECONFIGURE");
   1097 }
   1098 
   1099 
   1100 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
   1101 				 char *argv[])
   1102 {
   1103 	return wpa_ctrl_command(ctrl, "TERMINATE");
   1104 }
   1105 
   1106 
   1107 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
   1108 				     char *argv[])
   1109 {
   1110 	char cmd[256];
   1111 	int res;
   1112 
   1113 	if (argc < 1) {
   1114 		printf("Invalid INTERFACE_ADD command: needs at least one "
   1115 		       "argument (interface name)\n"
   1116 		       "All arguments: ifname confname driver ctrl_interface "
   1117 		       "driver_param bridge_name\n");
   1118 		return -1;
   1119 	}
   1120 
   1121 	/*
   1122 	 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
   1123 	 * <driver_param>TAB<bridge_name>
   1124 	 */
   1125 	res = os_snprintf(cmd, sizeof(cmd),
   1126 			  "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
   1127 			  argv[0],
   1128 			  argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
   1129 			  argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
   1130 			  argc > 5 ? argv[5] : "");
   1131 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1132 		return -1;
   1133 	cmd[sizeof(cmd) - 1] = '\0';
   1134 	return wpa_ctrl_command(ctrl, cmd);
   1135 }
   1136 
   1137 
   1138 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
   1139 					char *argv[])
   1140 {
   1141 	char cmd[128];
   1142 	int res;
   1143 
   1144 	if (argc != 1) {
   1145 		printf("Invalid INTERFACE_REMOVE command: needs one argument "
   1146 		       "(interface name)\n");
   1147 		return -1;
   1148 	}
   1149 
   1150 	res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
   1151 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1152 		return -1;
   1153 	cmd[sizeof(cmd) - 1] = '\0';
   1154 	return wpa_ctrl_command(ctrl, cmd);
   1155 }
   1156 
   1157 
   1158 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
   1159 				      char *argv[])
   1160 {
   1161 	return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
   1162 }
   1163 
   1164 
   1165 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc,
   1166 				      char *argv[])
   1167 {
   1168 	char cmd[32];
   1169 
   1170 	if (argc < 1) {
   1171 		printf("Invalid DRIVER command: needs one argument (cmd)\n");
   1172 		return -1;
   1173 	}
   1174 
   1175 	if (argc > 1)
   1176 		os_snprintf(cmd, sizeof(cmd), "DRIVER %s %s", argv[0], argv[1]);
   1177 	else
   1178 		os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
   1179 	cmd[sizeof(cmd) - 1] = '\0';
   1180 
   1181 	return wpa_ctrl_command(ctrl, cmd);
   1182 }
   1183 
   1184 
   1185 enum wpa_cli_cmd_flags {
   1186 	cli_cmd_flag_none		= 0x00,
   1187 	cli_cmd_flag_sensitive		= 0x01
   1188 };
   1189 
   1190 struct wpa_cli_cmd {
   1191 	const char *cmd;
   1192 	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
   1193 	enum wpa_cli_cmd_flags flags;
   1194 	const char *usage;
   1195 };
   1196 
   1197 static struct wpa_cli_cmd wpa_cli_commands[] = {
   1198 	{ "status", wpa_cli_cmd_status,
   1199 	  cli_cmd_flag_none,
   1200 	  "[verbose] = get current WPA/EAPOL/EAP status" },
   1201 	{ "ping", wpa_cli_cmd_ping,
   1202 	  cli_cmd_flag_none,
   1203 	  "= pings wpa_supplicant" },
   1204 	{ "mib", wpa_cli_cmd_mib,
   1205 	  cli_cmd_flag_none,
   1206 	  "= get MIB variables (dot1x, dot11)" },
   1207 	{ "help", wpa_cli_cmd_help,
   1208 	  cli_cmd_flag_none,
   1209 	  "= show this usage help" },
   1210 	{ "interface", wpa_cli_cmd_interface,
   1211 	  cli_cmd_flag_none,
   1212 	  "[ifname] = show interfaces/select interface" },
   1213 	{ "level", wpa_cli_cmd_level,
   1214 	  cli_cmd_flag_none,
   1215 	  "<debug level> = change debug level" },
   1216 	{ "license", wpa_cli_cmd_license,
   1217 	  cli_cmd_flag_none,
   1218 	  "= show full wpa_cli license" },
   1219 	{ "quit", wpa_cli_cmd_quit,
   1220 	  cli_cmd_flag_none,
   1221 	  "= exit wpa_cli" },
   1222 	{ "set", wpa_cli_cmd_set,
   1223 	  cli_cmd_flag_none,
   1224 	  "= set variables (shows list of variables when run without "
   1225 	  "arguments)" },
   1226 	{ "logon", wpa_cli_cmd_logon,
   1227 	  cli_cmd_flag_none,
   1228 	  "= IEEE 802.1X EAPOL state machine logon" },
   1229 	{ "logoff", wpa_cli_cmd_logoff,
   1230 	  cli_cmd_flag_none,
   1231 	  "= IEEE 802.1X EAPOL state machine logoff" },
   1232 	{ "pmksa", wpa_cli_cmd_pmksa,
   1233 	  cli_cmd_flag_none,
   1234 	  "= show PMKSA cache" },
   1235 	{ "reassociate", wpa_cli_cmd_reassociate,
   1236 	  cli_cmd_flag_none,
   1237 	  "= force reassociation" },
   1238 	{ "preauthenticate", wpa_cli_cmd_preauthenticate,
   1239 	  cli_cmd_flag_none,
   1240 	  "<BSSID> = force preauthentication" },
   1241 	{ "identity", wpa_cli_cmd_identity,
   1242 	  cli_cmd_flag_none,
   1243 	  "<network id> <identity> = configure identity for an SSID" },
   1244 	{ "password", wpa_cli_cmd_password,
   1245 	  cli_cmd_flag_sensitive,
   1246 	  "<network id> <password> = configure password for an SSID" },
   1247 	{ "new_password", wpa_cli_cmd_new_password,
   1248 	  cli_cmd_flag_sensitive,
   1249 	  "<network id> <password> = change password for an SSID" },
   1250 	{ "pin", wpa_cli_cmd_pin,
   1251 	  cli_cmd_flag_sensitive,
   1252 	  "<network id> <pin> = configure pin for an SSID" },
   1253 	{ "otp", wpa_cli_cmd_otp,
   1254 	  cli_cmd_flag_sensitive,
   1255 	  "<network id> <password> = configure one-time-password for an SSID"
   1256 	},
   1257 	{ "passphrase", wpa_cli_cmd_passphrase,
   1258 	  cli_cmd_flag_sensitive,
   1259 	  "<network id> <passphrase> = configure private key passphrase\n"
   1260 	  "  for an SSID" },
   1261 	{ "bssid", wpa_cli_cmd_bssid,
   1262 	  cli_cmd_flag_none,
   1263 	  "<network id> <BSSID> = set preferred BSSID for an SSID" },
   1264 #ifdef ANDROID
   1265 	{ "blacklist", wpa_cli_cmd_blacklist,
   1266 	  cli_cmd_flag_none,
   1267 	  "<BSSID> = add a BSSID to the blacklist\n"
   1268 	  "blacklist clear = clear the blacklist\n"
   1269 	  "blacklist = display the blacklist" },
   1270 	{ "log_level", wpa_cli_cmd_log_level,
   1271 	  cli_cmd_flag_none,
   1272 	  "<level> [<timestamp>] = update the log level/timestamp of wpa_supplicant\n"
   1273 	  "log_level = display the current log level and log options" },
   1274 #endif
   1275     { "list_networks", wpa_cli_cmd_list_networks,
   1276 	  cli_cmd_flag_none,
   1277 	  "= list configured networks" },
   1278 	{ "select_network", wpa_cli_cmd_select_network,
   1279 	  cli_cmd_flag_none,
   1280 	  "<network id> = select a network (disable others)" },
   1281 	{ "enable_network", wpa_cli_cmd_enable_network,
   1282 	  cli_cmd_flag_none,
   1283 	  "<network id> = enable a network" },
   1284 	{ "disable_network", wpa_cli_cmd_disable_network,
   1285 	  cli_cmd_flag_none,
   1286 	  "<network id> = disable a network" },
   1287 	{ "add_network", wpa_cli_cmd_add_network,
   1288 	  cli_cmd_flag_none,
   1289 	  "= add a network" },
   1290 	{ "remove_network", wpa_cli_cmd_remove_network,
   1291 	  cli_cmd_flag_none,
   1292 	  "<network id> = remove a network" },
   1293 	{ "set_network", wpa_cli_cmd_set_network,
   1294 	  cli_cmd_flag_sensitive,
   1295 	  "<network id> <variable> <value> = set network variables (shows\n"
   1296 	  "  list of variables when run without arguments)" },
   1297 	{ "get_network", wpa_cli_cmd_get_network,
   1298 	  cli_cmd_flag_none,
   1299 	  "<network id> <variable> = get network variables" },
   1300 	{ "save_config", wpa_cli_cmd_save_config,
   1301 	  cli_cmd_flag_none,
   1302 	  "= save the current configuration" },
   1303 	{ "disconnect", wpa_cli_cmd_disconnect,
   1304 	  cli_cmd_flag_none,
   1305 	  "= disconnect and wait for reassociate/reconnect command before\n"
   1306 	  "  connecting" },
   1307 	{ "reconnect", wpa_cli_cmd_reconnect,
   1308 	  cli_cmd_flag_none,
   1309 	  "= like reassociate, but only takes effect if already disconnected"
   1310 	},
   1311 	{ "scan", wpa_cli_cmd_scan,
   1312 	  cli_cmd_flag_none,
   1313 	  "= request new BSS scan" },
   1314 	{ "scan_results", wpa_cli_cmd_scan_results,
   1315 	  cli_cmd_flag_none,
   1316 	  "= get latest scan results" },
   1317 	{ "bss", wpa_cli_cmd_bss,
   1318 	  cli_cmd_flag_none,
   1319 	  "<<idx> | <bssid>> = get detailed scan result info" },
   1320 	{ "get_capability", wpa_cli_cmd_get_capability,
   1321 	  cli_cmd_flag_none,
   1322 	  "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
   1323 	{ "reconfigure", wpa_cli_cmd_reconfigure,
   1324 	  cli_cmd_flag_none,
   1325 	  "= force wpa_supplicant to re-read its configuration file" },
   1326 	{ "terminate", wpa_cli_cmd_terminate,
   1327 	  cli_cmd_flag_none,
   1328 	  "= terminate wpa_supplicant" },
   1329 	{ "interface_add", wpa_cli_cmd_interface_add,
   1330 	  cli_cmd_flag_none,
   1331 	  "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
   1332 	  "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
   1333 	  "  are optional" },
   1334 	{ "interface_remove", wpa_cli_cmd_interface_remove,
   1335 	  cli_cmd_flag_none,
   1336 	  "<ifname> = removes the interface" },
   1337 	{ "interface_list", wpa_cli_cmd_interface_list,
   1338 	  cli_cmd_flag_none,
   1339 	  "= list available interfaces" },
   1340 	{ "ap_scan", wpa_cli_cmd_ap_scan,
   1341 	  cli_cmd_flag_none,
   1342 	  "<value> = set ap_scan parameter" },
   1343 	{ "stkstart", wpa_cli_cmd_stkstart,
   1344 	  cli_cmd_flag_none,
   1345 	  "<addr> = request STK negotiation with <addr>" },
   1346 	{ "ft_ds", wpa_cli_cmd_ft_ds,
   1347 	  cli_cmd_flag_none,
   1348 	  "<addr> = request over-the-DS FT with <addr>" },
   1349 	{ "wps_pbc", wpa_cli_cmd_wps_pbc,
   1350 	  cli_cmd_flag_none,
   1351 	  "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
   1352 	{ "wps_pin", wpa_cli_cmd_wps_pin,
   1353 	  cli_cmd_flag_sensitive,
   1354 	  "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
   1355 	  "hardcoded)" },
   1356 	{ "wps_reg", wpa_cli_cmd_wps_reg,
   1357 	  cli_cmd_flag_sensitive,
   1358 	  "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
   1359 	{ "driver", wpa_cli_cmd_driver,
   1360 	  cli_cmd_flag_none,
   1361 	  "<command> = driver private commands" },
   1362 	{ NULL, NULL, cli_cmd_flag_none, NULL }
   1363 };
   1364 
   1365 
   1366 /*
   1367  * Prints command usage, lines are padded with the specified string.
   1368  */
   1369 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
   1370 {
   1371 	char c;
   1372 	size_t n;
   1373 
   1374 	printf("%s%s ", pad, cmd->cmd);
   1375 	for (n = 0; (c = cmd->usage[n]); n++) {
   1376 		printf("%c", c);
   1377 		if (c == '\n')
   1378 			printf("%s", pad);
   1379 	}
   1380 	printf("\n");
   1381 }
   1382 
   1383 
   1384 static void print_help(void)
   1385 {
   1386 	int n;
   1387 	printf("commands:\n");
   1388 	for (n = 0; wpa_cli_commands[n].cmd; n++)
   1389 		print_cmd_help(&wpa_cli_commands[n], "  ");
   1390 }
   1391 
   1392 
   1393 #ifdef CONFIG_READLINE
   1394 static int cmd_has_sensitive_data(const char *cmd)
   1395 {
   1396 	const char *c, *delim;
   1397 	int n;
   1398 	size_t len;
   1399 
   1400 	delim = os_strchr(cmd, ' ');
   1401 	if (delim)
   1402 		len = delim - cmd;
   1403 	else
   1404 		len = os_strlen(cmd);
   1405 
   1406 	for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
   1407 		if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
   1408 			return (wpa_cli_commands[n].flags &
   1409 				cli_cmd_flag_sensitive);
   1410 	}
   1411 	return 0;
   1412 }
   1413 #endif /* CONFIG_READLINE */
   1414 
   1415 
   1416 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1417 {
   1418 	struct wpa_cli_cmd *cmd, *match = NULL;
   1419 	int count;
   1420 	int ret = 0;
   1421 
   1422 	count = 0;
   1423 	cmd = wpa_cli_commands;
   1424 	while (cmd->cmd) {
   1425 		if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
   1426 		{
   1427 			match = cmd;
   1428 			if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
   1429 				/* we have an exact match */
   1430 				count = 1;
   1431 				break;
   1432 			}
   1433 			count++;
   1434 		}
   1435 		cmd++;
   1436 	}
   1437 
   1438 	if (count > 1) {
   1439 		printf("Ambiguous command '%s'; possible commands:", argv[0]);
   1440 		cmd = wpa_cli_commands;
   1441 		while (cmd->cmd) {
   1442 			if (os_strncasecmp(cmd->cmd, argv[0],
   1443 					   os_strlen(argv[0])) == 0) {
   1444 				printf(" %s", cmd->cmd);
   1445 			}
   1446 			cmd++;
   1447 		}
   1448 		printf("\n");
   1449 		ret = 1;
   1450 	} else if (count == 0) {
   1451 		printf("Unknown command '%s'\n", argv[0]);
   1452 		ret = 1;
   1453 	} else {
   1454         if( os_strncasecmp( "level", argv[0], os_strlen(argv[0]) ) == 0 )  {
   1455             ctrl = monitor_conn;
   1456         }
   1457 		ret = match->handler(ctrl, argc - 1, &argv[1]);
   1458 	}
   1459 
   1460 	return ret;
   1461 }
   1462 
   1463 
   1464 static int str_match(const char *a, const char *b)
   1465 {
   1466 	return os_strncmp(a, b, os_strlen(b)) == 0;
   1467 }
   1468 
   1469 
   1470 static int wpa_cli_exec(const char *program, const char *arg1,
   1471 			const char *arg2)
   1472 {
   1473 	char *cmd;
   1474 	size_t len;
   1475 	int res;
   1476 	int ret = 0;
   1477 
   1478 	len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
   1479 	cmd = os_malloc(len);
   1480 	if (cmd == NULL)
   1481 		return -1;
   1482 	res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
   1483 	if (res < 0 || (size_t) res >= len) {
   1484 		os_free(cmd);
   1485 		return -1;
   1486 	}
   1487 	cmd[len - 1] = '\0';
   1488 #ifndef _WIN32_WCE
   1489 	if (system(cmd) < 0)
   1490 		ret = -1;
   1491 #endif /* _WIN32_WCE */
   1492 	os_free(cmd);
   1493 
   1494 	return ret;
   1495 }
   1496 
   1497 
   1498 static void wpa_cli_action_process(const char *msg)
   1499 {
   1500 	const char *pos;
   1501 	char *copy = NULL, *id, *pos2;
   1502 
   1503 	pos = msg;
   1504 	if (*pos == '<') {
   1505 		/* skip priority */
   1506 		pos = os_strchr(pos, '>');
   1507 		if (pos)
   1508 			pos++;
   1509 		else
   1510 			pos = msg;
   1511 	}
   1512 
   1513 	if (str_match(pos, WPA_EVENT_CONNECTED)) {
   1514 		int new_id = -1;
   1515 		os_unsetenv("WPA_ID");
   1516 		os_unsetenv("WPA_ID_STR");
   1517 		os_unsetenv("WPA_CTRL_DIR");
   1518 
   1519 		pos = os_strstr(pos, "[id=");
   1520 		if (pos)
   1521 			copy = os_strdup(pos + 4);
   1522 
   1523 		if (copy) {
   1524 			pos2 = id = copy;
   1525 			while (*pos2 && *pos2 != ' ')
   1526 				pos2++;
   1527 			*pos2++ = '\0';
   1528 			new_id = atoi(id);
   1529 			os_setenv("WPA_ID", id, 1);
   1530 			while (*pos2 && *pos2 != '=')
   1531 				pos2++;
   1532 			if (*pos2 == '=')
   1533 				pos2++;
   1534 			id = pos2;
   1535 			while (*pos2 && *pos2 != ']')
   1536 				pos2++;
   1537 			*pos2 = '\0';
   1538 			os_setenv("WPA_ID_STR", id, 1);
   1539 			os_free(copy);
   1540 		}
   1541 
   1542 		os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
   1543 
   1544 		if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
   1545 			wpa_cli_connected = 1;
   1546 			wpa_cli_last_id = new_id;
   1547 			wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
   1548 		}
   1549 	} else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
   1550 		if (wpa_cli_connected) {
   1551 			wpa_cli_connected = 0;
   1552 			wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
   1553 		}
   1554 	} else if (str_match(pos, WPA_EVENT_TERMINATING)) {
   1555 		printf("wpa_supplicant is terminating - stop monitoring\n");
   1556 		wpa_cli_quit = 1;
   1557 	}
   1558 }
   1559 
   1560 
   1561 #ifndef CONFIG_ANSI_C_EXTRA
   1562 static void wpa_cli_action_cb(char *msg, size_t len)
   1563 {
   1564 	wpa_cli_action_process(msg);
   1565 }
   1566 #endif /* CONFIG_ANSI_C_EXTRA */
   1567 
   1568 
   1569 static void wpa_cli_reconnect(void)
   1570 {
   1571 	wpa_cli_close_connection();
   1572 	ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
   1573 	if (ctrl_conn) {
   1574 		printf("Connection to wpa_supplicant re-established\n");
   1575 		if (wpa_ctrl_attach(monitor_conn) == 0) {
   1576 			wpa_cli_attached = 1;
   1577 		} else {
   1578 			printf("Warning: Failed to attach to "
   1579 			       "wpa_supplicant.\n");
   1580 		}
   1581 	}
   1582 }
   1583 
   1584 
   1585 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
   1586 				 int action_monitor)
   1587 {
   1588 	int first = 1;
   1589 	if (ctrl == NULL) {
   1590 		wpa_cli_reconnect();
   1591 		return;
   1592 	}
   1593 	while (wpa_ctrl_pending(ctrl) > 0) {
   1594 		char buf[256];
   1595 		size_t len = sizeof(buf) - 1;
   1596 		if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
   1597 			buf[len] = '\0';
   1598 			if (action_monitor)
   1599 				wpa_cli_action_process(buf);
   1600 			else {
   1601 				if (in_read && first)
   1602 					printf("\n");
   1603 				first = 0;
   1604 				printf("%s\n", buf);
   1605 			}
   1606 		} else {
   1607 			printf("Could not read pending message.\n");
   1608 			break;
   1609 		}
   1610 	}
   1611 
   1612 	if (wpa_ctrl_pending(ctrl) < 0) {
   1613 		printf("Connection to wpa_supplicant lost - trying to "
   1614 		       "reconnect\n");
   1615 		wpa_cli_reconnect();
   1616 	}
   1617 }
   1618 
   1619 
   1620 #ifdef CONFIG_READLINE
   1621 static char * wpa_cli_cmd_gen(const char *text, int state)
   1622 {
   1623 	static int i, len;
   1624 	const char *cmd;
   1625 
   1626 	if (state == 0) {
   1627 		i = 0;
   1628 		len = os_strlen(text);
   1629 	}
   1630 
   1631 	while ((cmd = wpa_cli_commands[i].cmd)) {
   1632 		i++;
   1633 		if (os_strncasecmp(cmd, text, len) == 0)
   1634 			return os_strdup(cmd);
   1635 	}
   1636 
   1637 	return NULL;
   1638 }
   1639 
   1640 
   1641 static char * wpa_cli_dummy_gen(const char *text, int state)
   1642 {
   1643 	return NULL;
   1644 }
   1645 
   1646 
   1647 static char ** wpa_cli_completion(const char *text, int start, int end)
   1648 {
   1649 	return rl_completion_matches(text, start == 0 ?
   1650 				     wpa_cli_cmd_gen : wpa_cli_dummy_gen);
   1651 }
   1652 #endif /* CONFIG_READLINE */
   1653 
   1654 
   1655 static void wpa_cli_interactive(void)
   1656 {
   1657 #define max_args 10
   1658 	char cmdbuf[256], *cmd, *argv[max_args], *pos;
   1659 	int argc;
   1660 #ifdef CONFIG_READLINE
   1661 	char *home, *hfile = NULL;
   1662 #endif /* CONFIG_READLINE */
   1663 
   1664 	printf("\nInteractive mode\n\n");
   1665 
   1666 #ifdef CONFIG_READLINE
   1667 	rl_attempted_completion_function = wpa_cli_completion;
   1668 	home = getenv("HOME");
   1669 	if (home) {
   1670 		const char *fname = ".wpa_cli_history";
   1671 		int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
   1672 		hfile = os_malloc(hfile_len);
   1673 		if (hfile) {
   1674 			int res;
   1675 			res = os_snprintf(hfile, hfile_len, "%s/%s", home,
   1676 					  fname);
   1677 			if (res >= 0 && res < hfile_len) {
   1678 				hfile[hfile_len - 1] = '\0';
   1679 				read_history(hfile);
   1680 				stifle_history(100);
   1681 			}
   1682 		}
   1683 	}
   1684 #endif /* CONFIG_READLINE */
   1685 
   1686 	do {
   1687 		wpa_cli_recv_pending(monitor_conn, 0, 0);
   1688 #ifndef CONFIG_NATIVE_WINDOWS
   1689 		alarm(ping_interval);
   1690 #endif /* CONFIG_NATIVE_WINDOWS */
   1691 #ifdef CONFIG_READLINE
   1692 		cmd = readline("> ");
   1693 		if (cmd && *cmd) {
   1694 			HIST_ENTRY *h;
   1695 			while (next_history())
   1696 				;
   1697 			h = previous_history();
   1698 			if (h == NULL || os_strcmp(cmd, h->line) != 0)
   1699 				add_history(cmd);
   1700 			next_history();
   1701 		}
   1702 #else /* CONFIG_READLINE */
   1703 		printf("> ");
   1704 		cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
   1705 #endif /* CONFIG_READLINE */
   1706 #ifndef CONFIG_NATIVE_WINDOWS
   1707 		alarm(0);
   1708 #endif /* CONFIG_NATIVE_WINDOWS */
   1709 		if (cmd == NULL)
   1710 			break;
   1711 		wpa_cli_recv_pending(monitor_conn, 0, 0);
   1712 		pos = cmd;
   1713 		while (*pos != '\0') {
   1714 			if (*pos == '\n') {
   1715 				*pos = '\0';
   1716 				break;
   1717 			}
   1718 			pos++;
   1719 		}
   1720 		argc = 0;
   1721 		pos = cmd;
   1722 		for (;;) {
   1723 			while (*pos == ' ')
   1724 				pos++;
   1725 			if (*pos == '\0')
   1726 				break;
   1727 			argv[argc] = pos;
   1728 			argc++;
   1729 			if (argc == max_args)
   1730 				break;
   1731 			if (*pos == '"') {
   1732 				char *pos2 = os_strrchr(pos, '"');
   1733 				if (pos2)
   1734 					pos = pos2 + 1;
   1735 			}
   1736 			while (*pos != '\0' && *pos != ' ')
   1737 				pos++;
   1738 			if (*pos == ' ')
   1739 				*pos++ = '\0';
   1740 		}
   1741 		if (argc)
   1742 			wpa_request(ctrl_conn, argc, argv);
   1743 
   1744 		if (cmd != cmdbuf)
   1745 			os_free(cmd);
   1746 	} while (!wpa_cli_quit);
   1747 
   1748 #ifdef CONFIG_READLINE
   1749 	if (hfile) {
   1750 		/* Save command history, excluding lines that may contain
   1751 		 * passwords. */
   1752 		HIST_ENTRY *h;
   1753 		history_set_pos(0);
   1754 		while ((h = current_history())) {
   1755 			char *p = h->line;
   1756 			while (*p == ' ' || *p == '\t')
   1757 				p++;
   1758 			if (cmd_has_sensitive_data(p)) {
   1759 				h = remove_history(where_history());
   1760 				if (h) {
   1761 					os_free(h->line);
   1762 					os_free(h->data);
   1763 					os_free(h);
   1764 				} else
   1765 					next_history();
   1766 			} else
   1767 				next_history();
   1768 		}
   1769 		write_history(hfile);
   1770 		os_free(hfile);
   1771 	}
   1772 #endif /* CONFIG_READLINE */
   1773 }
   1774 
   1775 
   1776 static void wpa_cli_action(struct wpa_ctrl *ctrl)
   1777 {
   1778 #ifdef CONFIG_ANSI_C_EXTRA
   1779 	/* TODO: ANSI C version(?) */
   1780 	printf("Action processing not supported in ANSI C build.\n");
   1781 #else /* CONFIG_ANSI_C_EXTRA */
   1782 	fd_set rfds;
   1783 	int fd, res;
   1784 	struct timeval tv;
   1785 	char buf[256]; /* note: large enough to fit in unsolicited messages */
   1786 	size_t len;
   1787 
   1788 	fd = wpa_ctrl_get_fd(ctrl);
   1789 
   1790 	while (!wpa_cli_quit) {
   1791 		FD_ZERO(&rfds);
   1792 		FD_SET(fd, &rfds);
   1793 		tv.tv_sec = ping_interval;
   1794 		tv.tv_usec = 0;
   1795 		res = select(fd + 1, &rfds, NULL, NULL, &tv);
   1796 		if (res < 0 && errno != EINTR) {
   1797 			perror("select");
   1798 			break;
   1799 		}
   1800 
   1801 		if (FD_ISSET(fd, &rfds))
   1802 			wpa_cli_recv_pending(ctrl, 0, 1);
   1803 		else {
   1804 			/* verify that connection is still working */
   1805 			len = sizeof(buf) - 1;
   1806 			if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
   1807 					     wpa_cli_action_cb) < 0 ||
   1808 			    len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
   1809 				printf("wpa_supplicant did not reply to PING "
   1810 				       "command - exiting\n");
   1811 				break;
   1812 			}
   1813 		}
   1814 	}
   1815 #endif /* CONFIG_ANSI_C_EXTRA */
   1816 }
   1817 
   1818 
   1819 static void wpa_cli_cleanup(void)
   1820 {
   1821 	wpa_cli_close_connection();
   1822 	if (pid_file)
   1823 		os_daemonize_terminate(pid_file);
   1824 
   1825 	os_program_deinit();
   1826 }
   1827 
   1828 static void wpa_cli_terminate(int sig)
   1829 {
   1830 	wpa_cli_cleanup();
   1831 	exit(0);
   1832 }
   1833 
   1834 
   1835 #ifndef CONFIG_NATIVE_WINDOWS
   1836 static void wpa_cli_alarm(int sig)
   1837 {
   1838 	if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
   1839 		printf("Connection to wpa_supplicant lost - trying to "
   1840 		       "reconnect\n");
   1841 		wpa_cli_close_connection();
   1842 	}
   1843 	if (!monitor_conn)
   1844 		wpa_cli_reconnect();
   1845 	if (monitor_conn)
   1846 		wpa_cli_recv_pending(monitor_conn, 1, 0);
   1847 	alarm(ping_interval);
   1848 }
   1849 #endif /* CONFIG_NATIVE_WINDOWS */
   1850 
   1851 
   1852 static char * wpa_cli_get_default_ifname(void)
   1853 {
   1854 	char *ifname = NULL;
   1855 
   1856 #ifdef CONFIG_CTRL_IFACE_UNIX
   1857 	struct dirent *dent;
   1858 	DIR *dir = opendir(ctrl_iface_dir);
   1859 	if (!dir) {
   1860 #ifdef ANDROID
   1861 		char ifprop[PROPERTY_VALUE_MAX];
   1862 		if (property_get("wifi.interface", ifprop, NULL) != 0) {
   1863 			ifname = os_strdup(ifprop);
   1864 			printf("Using interface '%s'\n", ifname);
   1865 			return ifname;
   1866 		}
   1867 #endif
   1868 		return NULL;
   1869 	}
   1870 	while ((dent = readdir(dir))) {
   1871 #ifdef _DIRENT_HAVE_D_TYPE
   1872 		/*
   1873 		 * Skip the file if it is not a socket. Also accept
   1874 		 * DT_UNKNOWN (0) in case the C library or underlying
   1875 		 * file system does not support d_type.
   1876 		 */
   1877 		if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
   1878 			continue;
   1879 #endif /* _DIRENT_HAVE_D_TYPE */
   1880 		if (os_strcmp(dent->d_name, ".") == 0 ||
   1881 		    os_strcmp(dent->d_name, "..") == 0)
   1882 			continue;
   1883 		printf("Selected interface '%s'\n", dent->d_name);
   1884 		ifname = os_strdup(dent->d_name);
   1885 		break;
   1886 	}
   1887 	closedir(dir);
   1888 #endif /* CONFIG_CTRL_IFACE_UNIX */
   1889 
   1890 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
   1891 	char buf[4096], *pos;
   1892 	size_t len;
   1893 	struct wpa_ctrl *ctrl;
   1894 	int ret;
   1895 
   1896 	ctrl = wpa_ctrl_open(NULL);
   1897 	if (ctrl == NULL)
   1898 		return NULL;
   1899 
   1900 	len = sizeof(buf) - 1;
   1901 	ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
   1902 	if (ret >= 0) {
   1903 		buf[len] = '\0';
   1904 		pos = os_strchr(buf, '\n');
   1905 		if (pos)
   1906 			*pos = '\0';
   1907 		ifname = os_strdup(buf);
   1908 	}
   1909 	wpa_ctrl_close(ctrl);
   1910 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   1911 
   1912 	return ifname;
   1913 }
   1914 
   1915 
   1916 int main(int argc, char *argv[])
   1917 {
   1918 	int interactive;
   1919 	int warning_displayed = 0;
   1920 	int c;
   1921 	int daemonize = 0;
   1922 	int ret = 0;
   1923 	const char *global = NULL;
   1924 
   1925 	if (os_program_init())
   1926 		return -1;
   1927 
   1928 	for (;;) {
   1929 		c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
   1930 		if (c < 0)
   1931 			break;
   1932 		switch (c) {
   1933 		case 'a':
   1934 			action_file = optarg;
   1935 			break;
   1936 		case 'B':
   1937 			daemonize = 1;
   1938 			break;
   1939 		case 'g':
   1940 			global = optarg;
   1941 			break;
   1942 		case 'G':
   1943 			ping_interval = atoi(optarg);
   1944 			break;
   1945 		case 'h':
   1946 			usage();
   1947 			return 0;
   1948 		case 'v':
   1949 			printf("%s\n", wpa_cli_version);
   1950 			return 0;
   1951 		case 'i':
   1952 			os_free(ctrl_ifname);
   1953 			ctrl_ifname = os_strdup(optarg);
   1954 			break;
   1955 		case 'p':
   1956 			ctrl_iface_dir = optarg;
   1957 			break;
   1958 		case 'P':
   1959 			pid_file = optarg;
   1960 			break;
   1961 		default:
   1962 			usage();
   1963 			return -1;
   1964 		}
   1965 	}
   1966 
   1967 	interactive = (argc == optind) && (action_file == NULL);
   1968 
   1969 	if (interactive)
   1970 		printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
   1971 
   1972 	if (global) {
   1973 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
   1974 		ctrl_conn = wpa_ctrl_open(NULL);
   1975 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   1976 		ctrl_conn = wpa_ctrl_open(global);
   1977 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   1978 		if (ctrl_conn == NULL) {
   1979 			perror("Failed to connect to wpa_supplicant - "
   1980 			       "wpa_ctrl_open");
   1981 			return -1;
   1982 		}
   1983 	}
   1984 
   1985 	for (; !global;) {
   1986 		if (ctrl_ifname == NULL)
   1987 			ctrl_ifname = wpa_cli_get_default_ifname();
   1988 		ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
   1989 		if (ctrl_conn) {
   1990 			if (warning_displayed)
   1991 				printf("Connection established.\n");
   1992 			break;
   1993 		}
   1994 
   1995 		if (!interactive) {
   1996 			perror("Failed to connect to wpa_supplicant - "
   1997 			       "wpa_ctrl_open");
   1998 			return -1;
   1999 		}
   2000 
   2001 		if (!warning_displayed) {
   2002 			printf("Could not connect to wpa_supplicant - "
   2003 			       "re-trying\n");
   2004 			warning_displayed = 1;
   2005 		}
   2006 		os_sleep(1, 0);
   2007 		continue;
   2008 	}
   2009 
   2010 #ifndef _WIN32_WCE
   2011 	signal(SIGINT, wpa_cli_terminate);
   2012 	signal(SIGTERM, wpa_cli_terminate);
   2013 #endif /* _WIN32_WCE */
   2014 #ifndef CONFIG_NATIVE_WINDOWS
   2015 	signal(SIGALRM, wpa_cli_alarm);
   2016 #endif /* CONFIG_NATIVE_WINDOWS */
   2017 
   2018 	if (interactive || action_file) {
   2019 		if (wpa_ctrl_attach(monitor_conn) == 0) {
   2020 			wpa_cli_attached = 1;
   2021 		} else {
   2022 			printf("Warning: Failed to attach to "
   2023 			       "wpa_supplicant.\n");
   2024 			if (!interactive)
   2025 				return -1;
   2026 		}
   2027 	}
   2028 
   2029 	if (daemonize && os_daemonize(pid_file))
   2030 		return -1;
   2031 
   2032 	if (interactive)
   2033 		wpa_cli_interactive();
   2034 	else if (action_file)
   2035 		wpa_cli_action(ctrl_conn);
   2036 	else
   2037 		ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
   2038 
   2039 	os_free(ctrl_ifname);
   2040 	wpa_cli_cleanup();
   2041 
   2042 	return ret;
   2043 }
   2044 
   2045 #else /* CONFIG_CTRL_IFACE */
   2046 int main(int argc, char *argv[])
   2047 {
   2048 	printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
   2049 	return -1;
   2050 }
   2051 #endif /* CONFIG_CTRL_IFACE */
   2052