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/system/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_scan_interval(struct wpa_ctrl *ctrl, int argc,
    752 				     char *argv[])
    753 {
    754 	char cmd[256];
    755 	int res;
    756 
    757 	if (argc != 1) {
    758 		printf("Invalid SCAN_INTERVAL command: needs one argument "
    759 		       "scan_interval value)\n");
    760 		return -1;
    761 	}
    762 	res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
    763 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    764 		printf("Too long SCAN_INTERVAL command.\n");
    765 		return -1;
    766 	}
    767 	return wpa_ctrl_command(ctrl, cmd);
    768 }
    769 
    770 
    771 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
    772 {
    773 	char cmd[256], *pos, *end;
    774 	int i, ret;
    775 
    776 	end = cmd + sizeof(cmd);
    777 	pos = cmd;
    778 	ret = os_snprintf(pos, end - pos, "BLACKLIST");
    779 	if (ret < 0 || ret >= end - pos) {
    780 		printf("Too long BLACKLIST command.\n");
    781 		return -1;
    782 	}
    783 	pos += ret;
    784 	for (i = 0; i < argc; i++) {
    785 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    786 		if (ret < 0 || ret >= end - pos) {
    787 			printf("Too long BLACKLIST command.\n");
    788 			return -1;
    789 		}
    790 		pos += ret;
    791 	}
    792 
    793 	return wpa_ctrl_command(ctrl, cmd);
    794 }
    795 
    796 
    797 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
    798 {
    799 	char cmd[256], *pos, *end;
    800 	int i, ret;
    801 
    802 	end = cmd + sizeof(cmd);
    803 	pos = cmd;
    804 	ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
    805 	if (ret < 0 || ret >= end - pos) {
    806 		printf("Too long LOG_LEVEL command.\n");
    807 		return -1;
    808 	}
    809 	pos += ret;
    810 	for (i = 0; i < argc; i++) {
    811 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
    812 		if (ret < 0 || ret >= end - pos) {
    813 			printf("Too long LOG_LEVEL command.\n");
    814 			return -1;
    815 		}
    816 		pos += ret;
    817 	}
    818 
    819 	return wpa_ctrl_command(ctrl, cmd);
    820 }
    821 #endif /* ANDROID */
    822 
    823 
    824 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
    825 				     char *argv[])
    826 {
    827 	return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
    828 }
    829 
    830 
    831 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
    832 				      char *argv[])
    833 {
    834 	char cmd[32];
    835 	int res;
    836 
    837 	if (argc < 1) {
    838 		printf("Invalid SELECT_NETWORK command: needs one argument "
    839 		       "(network id)\n");
    840 		return -1;
    841 	}
    842 
    843 	res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
    844 	if (res < 0 || (size_t) res >= sizeof(cmd))
    845 		return -1;
    846 	cmd[sizeof(cmd) - 1] = '\0';
    847 
    848 	return wpa_ctrl_command(ctrl, cmd);
    849 }
    850 
    851 
    852 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
    853 				      char *argv[])
    854 {
    855 	char cmd[32];
    856 	int res;
    857 
    858 	if (argc < 1) {
    859 		printf("Invalid ENABLE_NETWORK command: needs one argument "
    860 		       "(network id)\n");
    861 		return -1;
    862 	}
    863 
    864 	res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
    865 	if (res < 0 || (size_t) res >= sizeof(cmd))
    866 		return -1;
    867 	cmd[sizeof(cmd) - 1] = '\0';
    868 
    869 	return wpa_ctrl_command(ctrl, cmd);
    870 }
    871 
    872 
    873 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
    874 				       char *argv[])
    875 {
    876 	char cmd[32];
    877 	int res;
    878 
    879 	if (argc < 1) {
    880 		printf("Invalid DISABLE_NETWORK command: needs one argument "
    881 		       "(network id)\n");
    882 		return -1;
    883 	}
    884 
    885 	res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
    886 	if (res < 0 || (size_t) res >= sizeof(cmd))
    887 		return -1;
    888 	cmd[sizeof(cmd) - 1] = '\0';
    889 
    890 	return wpa_ctrl_command(ctrl, cmd);
    891 }
    892 
    893 
    894 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
    895 				   char *argv[])
    896 {
    897 	return wpa_ctrl_command(ctrl, "ADD_NETWORK");
    898 }
    899 
    900 
    901 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
    902 				      char *argv[])
    903 {
    904 	char cmd[32];
    905 	int res;
    906 
    907 	if (argc < 1) {
    908 		printf("Invalid REMOVE_NETWORK command: needs one argument "
    909 		       "(network id)\n");
    910 		return -1;
    911 	}
    912 
    913 	res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
    914 	if (res < 0 || (size_t) res >= sizeof(cmd))
    915 		return -1;
    916 	cmd[sizeof(cmd) - 1] = '\0';
    917 
    918 	return wpa_ctrl_command(ctrl, cmd);
    919 }
    920 
    921 
    922 static void wpa_cli_show_network_variables(void)
    923 {
    924 	printf("set_network variables:\n"
    925 	       "  ssid (network name, SSID)\n"
    926 	       "  psk (WPA passphrase or pre-shared key)\n"
    927 	       "  key_mgmt (key management protocol)\n"
    928 	       "  identity (EAP identity)\n"
    929 	       "  password (EAP password)\n"
    930 	       "  ...\n"
    931 	       "\n"
    932 	       "Note: Values are entered in the same format as the "
    933 	       "configuration file is using,\n"
    934 	       "i.e., strings values need to be inside double quotation "
    935 	       "marks.\n"
    936 	       "For example: set_network 1 ssid \"network name\"\n"
    937 	       "\n"
    938 	       "Please see wpa_supplicant.conf documentation for full list "
    939 	       "of\navailable variables.\n");
    940 }
    941 
    942 
    943 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
    944 				   char *argv[])
    945 {
    946 	char cmd[256];
    947 	int res;
    948 
    949 	if (argc == 0) {
    950 		wpa_cli_show_network_variables();
    951 		return 0;
    952 	}
    953 
    954 	if (argc != 3) {
    955 		printf("Invalid SET_NETWORK command: needs three arguments\n"
    956 		       "(network id, variable name, and value)\n");
    957 		return -1;
    958 	}
    959 
    960 	res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
    961 			  argv[0], argv[1], argv[2]);
    962 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    963 		printf("Too long SET_NETWORK command.\n");
    964 		return -1;
    965 	}
    966 	return wpa_ctrl_command(ctrl, cmd);
    967 }
    968 
    969 
    970 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
    971 				   char *argv[])
    972 {
    973 	char cmd[256];
    974 	int res;
    975 
    976 	if (argc == 0) {
    977 		wpa_cli_show_network_variables();
    978 		return 0;
    979 	}
    980 
    981 	if (argc != 2) {
    982 		printf("Invalid GET_NETWORK command: needs two arguments\n"
    983 		       "(network id and variable name)\n");
    984 		return -1;
    985 	}
    986 
    987 	res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
    988 			  argv[0], argv[1]);
    989 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    990 		printf("Too long GET_NETWORK command.\n");
    991 		return -1;
    992 	}
    993 	return wpa_ctrl_command(ctrl, cmd);
    994 }
    995 
    996 
    997 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
    998 				  char *argv[])
    999 {
   1000 	return wpa_ctrl_command(ctrl, "DISCONNECT");
   1001 }
   1002 
   1003 
   1004 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
   1005 				  char *argv[])
   1006 {
   1007 	return wpa_ctrl_command(ctrl, "RECONNECT");
   1008 }
   1009 
   1010 
   1011 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
   1012 				   char *argv[])
   1013 {
   1014 	return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
   1015 }
   1016 
   1017 
   1018 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1019 {
   1020 	return wpa_ctrl_command(ctrl, "SCAN");
   1021 }
   1022 
   1023 
   1024 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
   1025 				    char *argv[])
   1026 {
   1027 	return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
   1028 }
   1029 
   1030 
   1031 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1032 {
   1033 	char cmd[64];
   1034 	int res;
   1035 
   1036 	if (argc != 1) {
   1037 		printf("Invalid BSS command: need one argument (index or "
   1038 		       "BSSID)\n");
   1039 		return -1;
   1040 	}
   1041 
   1042 	res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
   1043 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1044 		return -1;
   1045 	cmd[sizeof(cmd) - 1] = '\0';
   1046 
   1047 	return wpa_ctrl_command(ctrl, cmd);
   1048 }
   1049 
   1050 
   1051 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
   1052 				      char *argv[])
   1053 {
   1054 	char cmd[64];
   1055 	int res;
   1056 
   1057 	if (argc < 1 || argc > 2) {
   1058 		printf("Invalid GET_CAPABILITY command: need either one or "
   1059 		       "two arguments\n");
   1060 		return -1;
   1061 	}
   1062 
   1063 	if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
   1064 		printf("Invalid GET_CAPABILITY command: second argument, "
   1065 		       "if any, must be 'strict'\n");
   1066 		return -1;
   1067 	}
   1068 
   1069 	res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
   1070 			  (argc == 2) ? " strict" : "");
   1071 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1072 		return -1;
   1073 	cmd[sizeof(cmd) - 1] = '\0';
   1074 
   1075 	return wpa_ctrl_command(ctrl, cmd);
   1076 }
   1077 
   1078 
   1079 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
   1080 {
   1081 	printf("Available interfaces:\n");
   1082 	return wpa_ctrl_command(ctrl, "INTERFACES");
   1083 }
   1084 
   1085 
   1086 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1087 {
   1088 	if (argc < 1) {
   1089 		wpa_cli_list_interfaces(ctrl);
   1090 		return 0;
   1091 	}
   1092 
   1093 	wpa_cli_close_connection();
   1094 	os_free(ctrl_ifname);
   1095 	ctrl_ifname = os_strdup(argv[0]);
   1096 
   1097 	if ((ctrl_conn = wpa_cli_open_connection(ctrl_ifname)) != NULL) {
   1098 		printf("Connected to interface '%s.\n", ctrl_ifname);
   1099 		if (wpa_ctrl_attach(monitor_conn) == 0) {
   1100 			wpa_cli_attached = 1;
   1101 		} else {
   1102 			printf("Warning: Failed to attach to "
   1103 			       "wpa_supplicant.\n");
   1104 		}
   1105 	} else {
   1106 		printf("Could not connect to interface '%s' - re-trying\n",
   1107 		       ctrl_ifname);
   1108 	}
   1109 	return 0;
   1110 }
   1111 
   1112 
   1113 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
   1114 				   char *argv[])
   1115 {
   1116 	return wpa_ctrl_command(ctrl, "RECONFIGURE");
   1117 }
   1118 
   1119 
   1120 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
   1121 				 char *argv[])
   1122 {
   1123 	return wpa_ctrl_command(ctrl, "TERMINATE");
   1124 }
   1125 
   1126 
   1127 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
   1128 				     char *argv[])
   1129 {
   1130 	char cmd[256];
   1131 	int res;
   1132 
   1133 	if (argc < 1) {
   1134 		printf("Invalid INTERFACE_ADD command: needs at least one "
   1135 		       "argument (interface name)\n"
   1136 		       "All arguments: ifname confname driver ctrl_interface "
   1137 		       "driver_param bridge_name\n");
   1138 		return -1;
   1139 	}
   1140 
   1141 	/*
   1142 	 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
   1143 	 * <driver_param>TAB<bridge_name>
   1144 	 */
   1145 	res = os_snprintf(cmd, sizeof(cmd),
   1146 			  "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
   1147 			  argv[0],
   1148 			  argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
   1149 			  argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
   1150 			  argc > 5 ? argv[5] : "");
   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_remove(struct wpa_ctrl *ctrl, int argc,
   1159 					char *argv[])
   1160 {
   1161 	char cmd[128];
   1162 	int res;
   1163 
   1164 	if (argc != 1) {
   1165 		printf("Invalid INTERFACE_REMOVE command: needs one argument "
   1166 		       "(interface name)\n");
   1167 		return -1;
   1168 	}
   1169 
   1170 	res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
   1171 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1172 		return -1;
   1173 	cmd[sizeof(cmd) - 1] = '\0';
   1174 	return wpa_ctrl_command(ctrl, cmd);
   1175 }
   1176 
   1177 
   1178 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
   1179 				      char *argv[])
   1180 {
   1181 	return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
   1182 }
   1183 
   1184 
   1185 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc,
   1186 				      char *argv[])
   1187 {
   1188 	char cmd[32];
   1189 
   1190 	if (argc < 1) {
   1191 		printf("Invalid DRIVER command: needs one argument (cmd)\n");
   1192 		return -1;
   1193 	}
   1194 
   1195 	if (argc > 1)
   1196 		os_snprintf(cmd, sizeof(cmd), "DRIVER %s %s", argv[0], argv[1]);
   1197 	else
   1198 		os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
   1199 	cmd[sizeof(cmd) - 1] = '\0';
   1200 
   1201 	return wpa_ctrl_command(ctrl, cmd);
   1202 }
   1203 
   1204 
   1205 enum wpa_cli_cmd_flags {
   1206 	cli_cmd_flag_none		= 0x00,
   1207 	cli_cmd_flag_sensitive		= 0x01
   1208 };
   1209 
   1210 struct wpa_cli_cmd {
   1211 	const char *cmd;
   1212 	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
   1213 	enum wpa_cli_cmd_flags flags;
   1214 	const char *usage;
   1215 };
   1216 
   1217 static struct wpa_cli_cmd wpa_cli_commands[] = {
   1218 	{ "status", wpa_cli_cmd_status,
   1219 	  cli_cmd_flag_none,
   1220 	  "[verbose] = get current WPA/EAPOL/EAP status" },
   1221 	{ "ping", wpa_cli_cmd_ping,
   1222 	  cli_cmd_flag_none,
   1223 	  "= pings wpa_supplicant" },
   1224 	{ "mib", wpa_cli_cmd_mib,
   1225 	  cli_cmd_flag_none,
   1226 	  "= get MIB variables (dot1x, dot11)" },
   1227 	{ "help", wpa_cli_cmd_help,
   1228 	  cli_cmd_flag_none,
   1229 	  "= show this usage help" },
   1230 	{ "interface", wpa_cli_cmd_interface,
   1231 	  cli_cmd_flag_none,
   1232 	  "[ifname] = show interfaces/select interface" },
   1233 	{ "level", wpa_cli_cmd_level,
   1234 	  cli_cmd_flag_none,
   1235 	  "<debug level> = change debug level" },
   1236 	{ "license", wpa_cli_cmd_license,
   1237 	  cli_cmd_flag_none,
   1238 	  "= show full wpa_cli license" },
   1239 	{ "quit", wpa_cli_cmd_quit,
   1240 	  cli_cmd_flag_none,
   1241 	  "= exit wpa_cli" },
   1242 	{ "set", wpa_cli_cmd_set,
   1243 	  cli_cmd_flag_none,
   1244 	  "= set variables (shows list of variables when run without "
   1245 	  "arguments)" },
   1246 	{ "logon", wpa_cli_cmd_logon,
   1247 	  cli_cmd_flag_none,
   1248 	  "= IEEE 802.1X EAPOL state machine logon" },
   1249 	{ "logoff", wpa_cli_cmd_logoff,
   1250 	  cli_cmd_flag_none,
   1251 	  "= IEEE 802.1X EAPOL state machine logoff" },
   1252 	{ "pmksa", wpa_cli_cmd_pmksa,
   1253 	  cli_cmd_flag_none,
   1254 	  "= show PMKSA cache" },
   1255 	{ "reassociate", wpa_cli_cmd_reassociate,
   1256 	  cli_cmd_flag_none,
   1257 	  "= force reassociation" },
   1258 	{ "preauthenticate", wpa_cli_cmd_preauthenticate,
   1259 	  cli_cmd_flag_none,
   1260 	  "<BSSID> = force preauthentication" },
   1261 	{ "identity", wpa_cli_cmd_identity,
   1262 	  cli_cmd_flag_none,
   1263 	  "<network id> <identity> = configure identity for an SSID" },
   1264 	{ "password", wpa_cli_cmd_password,
   1265 	  cli_cmd_flag_sensitive,
   1266 	  "<network id> <password> = configure password for an SSID" },
   1267 	{ "new_password", wpa_cli_cmd_new_password,
   1268 	  cli_cmd_flag_sensitive,
   1269 	  "<network id> <password> = change password for an SSID" },
   1270 	{ "pin", wpa_cli_cmd_pin,
   1271 	  cli_cmd_flag_sensitive,
   1272 	  "<network id> <pin> = configure pin for an SSID" },
   1273 	{ "otp", wpa_cli_cmd_otp,
   1274 	  cli_cmd_flag_sensitive,
   1275 	  "<network id> <password> = configure one-time-password for an SSID"
   1276 	},
   1277 	{ "passphrase", wpa_cli_cmd_passphrase,
   1278 	  cli_cmd_flag_sensitive,
   1279 	  "<network id> <passphrase> = configure private key passphrase\n"
   1280 	  "  for an SSID" },
   1281 	{ "bssid", wpa_cli_cmd_bssid,
   1282 	  cli_cmd_flag_none,
   1283 	  "<network id> <BSSID> = set preferred BSSID for an SSID" },
   1284 #ifdef ANDROID
   1285 	{ "scan_interval", wpa_cli_cmd_scan_interval,
   1286 	  cli_cmd_flag_none,
   1287 	  "<value> = set scan_interval parameter" },
   1288 	{ "blacklist", wpa_cli_cmd_blacklist,
   1289 	  cli_cmd_flag_none,
   1290 	  "<BSSID> = add a BSSID to the blacklist\n"
   1291 	  "blacklist clear = clear the blacklist\n"
   1292 	  "blacklist = display the blacklist" },
   1293 	{ "log_level", wpa_cli_cmd_log_level,
   1294 	  cli_cmd_flag_none,
   1295 	  "<level> [<timestamp>] = update the log level/timestamp of wpa_supplicant\n"
   1296 	  "log_level = display the current log level and log options" },
   1297 #endif
   1298     { "list_networks", wpa_cli_cmd_list_networks,
   1299 	  cli_cmd_flag_none,
   1300 	  "= list configured networks" },
   1301 	{ "select_network", wpa_cli_cmd_select_network,
   1302 	  cli_cmd_flag_none,
   1303 	  "<network id> = select a network (disable others)" },
   1304 	{ "enable_network", wpa_cli_cmd_enable_network,
   1305 	  cli_cmd_flag_none,
   1306 	  "<network id> = enable a network" },
   1307 	{ "disable_network", wpa_cli_cmd_disable_network,
   1308 	  cli_cmd_flag_none,
   1309 	  "<network id> = disable a network" },
   1310 	{ "add_network", wpa_cli_cmd_add_network,
   1311 	  cli_cmd_flag_none,
   1312 	  "= add a network" },
   1313 	{ "remove_network", wpa_cli_cmd_remove_network,
   1314 	  cli_cmd_flag_none,
   1315 	  "<network id> = remove a network" },
   1316 	{ "set_network", wpa_cli_cmd_set_network,
   1317 	  cli_cmd_flag_sensitive,
   1318 	  "<network id> <variable> <value> = set network variables (shows\n"
   1319 	  "  list of variables when run without arguments)" },
   1320 	{ "get_network", wpa_cli_cmd_get_network,
   1321 	  cli_cmd_flag_none,
   1322 	  "<network id> <variable> = get network variables" },
   1323 	{ "save_config", wpa_cli_cmd_save_config,
   1324 	  cli_cmd_flag_none,
   1325 	  "= save the current configuration" },
   1326 	{ "disconnect", wpa_cli_cmd_disconnect,
   1327 	  cli_cmd_flag_none,
   1328 	  "= disconnect and wait for reassociate/reconnect command before\n"
   1329 	  "  connecting" },
   1330 	{ "reconnect", wpa_cli_cmd_reconnect,
   1331 	  cli_cmd_flag_none,
   1332 	  "= like reassociate, but only takes effect if already disconnected"
   1333 	},
   1334 	{ "scan", wpa_cli_cmd_scan,
   1335 	  cli_cmd_flag_none,
   1336 	  "= request new BSS scan" },
   1337 	{ "scan_results", wpa_cli_cmd_scan_results,
   1338 	  cli_cmd_flag_none,
   1339 	  "= get latest scan results" },
   1340 	{ "bss", wpa_cli_cmd_bss,
   1341 	  cli_cmd_flag_none,
   1342 	  "<<idx> | <bssid>> = get detailed scan result info" },
   1343 	{ "get_capability", wpa_cli_cmd_get_capability,
   1344 	  cli_cmd_flag_none,
   1345 	  "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
   1346 	{ "reconfigure", wpa_cli_cmd_reconfigure,
   1347 	  cli_cmd_flag_none,
   1348 	  "= force wpa_supplicant to re-read its configuration file" },
   1349 	{ "terminate", wpa_cli_cmd_terminate,
   1350 	  cli_cmd_flag_none,
   1351 	  "= terminate wpa_supplicant" },
   1352 	{ "interface_add", wpa_cli_cmd_interface_add,
   1353 	  cli_cmd_flag_none,
   1354 	  "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
   1355 	  "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
   1356 	  "  are optional" },
   1357 	{ "interface_remove", wpa_cli_cmd_interface_remove,
   1358 	  cli_cmd_flag_none,
   1359 	  "<ifname> = removes the interface" },
   1360 	{ "interface_list", wpa_cli_cmd_interface_list,
   1361 	  cli_cmd_flag_none,
   1362 	  "= list available interfaces" },
   1363 	{ "ap_scan", wpa_cli_cmd_ap_scan,
   1364 	  cli_cmd_flag_none,
   1365 	  "<value> = set ap_scan parameter" },
   1366 	{ "stkstart", wpa_cli_cmd_stkstart,
   1367 	  cli_cmd_flag_none,
   1368 	  "<addr> = request STK negotiation with <addr>" },
   1369 	{ "ft_ds", wpa_cli_cmd_ft_ds,
   1370 	  cli_cmd_flag_none,
   1371 	  "<addr> = request over-the-DS FT with <addr>" },
   1372 	{ "wps_pbc", wpa_cli_cmd_wps_pbc,
   1373 	  cli_cmd_flag_none,
   1374 	  "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
   1375 	{ "wps_pin", wpa_cli_cmd_wps_pin,
   1376 	  cli_cmd_flag_sensitive,
   1377 	  "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
   1378 	  "hardcoded)" },
   1379 	{ "wps_reg", wpa_cli_cmd_wps_reg,
   1380 	  cli_cmd_flag_sensitive,
   1381 	  "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
   1382 	{ "driver", wpa_cli_cmd_driver,
   1383 	  cli_cmd_flag_none,
   1384 	  "<command> = driver private commands" },
   1385 	{ NULL, NULL, cli_cmd_flag_none, NULL }
   1386 };
   1387 
   1388 
   1389 /*
   1390  * Prints command usage, lines are padded with the specified string.
   1391  */
   1392 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
   1393 {
   1394 	char c;
   1395 	size_t n;
   1396 
   1397 	printf("%s%s ", pad, cmd->cmd);
   1398 	for (n = 0; (c = cmd->usage[n]); n++) {
   1399 		printf("%c", c);
   1400 		if (c == '\n')
   1401 			printf("%s", pad);
   1402 	}
   1403 	printf("\n");
   1404 }
   1405 
   1406 
   1407 static void print_help(void)
   1408 {
   1409 	int n;
   1410 	printf("commands:\n");
   1411 	for (n = 0; wpa_cli_commands[n].cmd; n++)
   1412 		print_cmd_help(&wpa_cli_commands[n], "  ");
   1413 }
   1414 
   1415 
   1416 #ifdef CONFIG_READLINE
   1417 static int cmd_has_sensitive_data(const char *cmd)
   1418 {
   1419 	const char *c, *delim;
   1420 	int n;
   1421 	size_t len;
   1422 
   1423 	delim = os_strchr(cmd, ' ');
   1424 	if (delim)
   1425 		len = delim - cmd;
   1426 	else
   1427 		len = os_strlen(cmd);
   1428 
   1429 	for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
   1430 		if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
   1431 			return (wpa_cli_commands[n].flags &
   1432 				cli_cmd_flag_sensitive);
   1433 	}
   1434 	return 0;
   1435 }
   1436 #endif /* CONFIG_READLINE */
   1437 
   1438 
   1439 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1440 {
   1441 	struct wpa_cli_cmd *cmd, *match = NULL;
   1442 	int count;
   1443 	int ret = 0;
   1444 
   1445 	count = 0;
   1446 	cmd = wpa_cli_commands;
   1447 	while (cmd->cmd) {
   1448 		if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
   1449 		{
   1450 			match = cmd;
   1451 			if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
   1452 				/* we have an exact match */
   1453 				count = 1;
   1454 				break;
   1455 			}
   1456 			count++;
   1457 		}
   1458 		cmd++;
   1459 	}
   1460 
   1461 	if (count > 1) {
   1462 		printf("Ambiguous command '%s'; possible commands:", argv[0]);
   1463 		cmd = wpa_cli_commands;
   1464 		while (cmd->cmd) {
   1465 			if (os_strncasecmp(cmd->cmd, argv[0],
   1466 					   os_strlen(argv[0])) == 0) {
   1467 				printf(" %s", cmd->cmd);
   1468 			}
   1469 			cmd++;
   1470 		}
   1471 		printf("\n");
   1472 		ret = 1;
   1473 	} else if (count == 0) {
   1474 		printf("Unknown command '%s'\n", argv[0]);
   1475 		ret = 1;
   1476 	} else {
   1477         if( os_strncasecmp( "level", argv[0], os_strlen(argv[0]) ) == 0 )  {
   1478             ctrl = monitor_conn;
   1479         }
   1480 		ret = match->handler(ctrl, argc - 1, &argv[1]);
   1481 	}
   1482 
   1483 	return ret;
   1484 }
   1485 
   1486 
   1487 static int str_match(const char *a, const char *b)
   1488 {
   1489 	return os_strncmp(a, b, os_strlen(b)) == 0;
   1490 }
   1491 
   1492 
   1493 static int wpa_cli_exec(const char *program, const char *arg1,
   1494 			const char *arg2)
   1495 {
   1496 	char *cmd;
   1497 	size_t len;
   1498 	int res;
   1499 	int ret = 0;
   1500 
   1501 	len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
   1502 	cmd = os_malloc(len);
   1503 	if (cmd == NULL)
   1504 		return -1;
   1505 	res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
   1506 	if (res < 0 || (size_t) res >= len) {
   1507 		os_free(cmd);
   1508 		return -1;
   1509 	}
   1510 	cmd[len - 1] = '\0';
   1511 #ifndef _WIN32_WCE
   1512 	if (system(cmd) < 0)
   1513 		ret = -1;
   1514 #endif /* _WIN32_WCE */
   1515 	os_free(cmd);
   1516 
   1517 	return ret;
   1518 }
   1519 
   1520 
   1521 static void wpa_cli_action_process(const char *msg)
   1522 {
   1523 	const char *pos;
   1524 	char *copy = NULL, *id, *pos2;
   1525 
   1526 	pos = msg;
   1527 	if (*pos == '<') {
   1528 		/* skip priority */
   1529 		pos = os_strchr(pos, '>');
   1530 		if (pos)
   1531 			pos++;
   1532 		else
   1533 			pos = msg;
   1534 	}
   1535 
   1536 	if (str_match(pos, WPA_EVENT_CONNECTED)) {
   1537 		int new_id = -1;
   1538 		os_unsetenv("WPA_ID");
   1539 		os_unsetenv("WPA_ID_STR");
   1540 		os_unsetenv("WPA_CTRL_DIR");
   1541 
   1542 		pos = os_strstr(pos, "[id=");
   1543 		if (pos)
   1544 			copy = os_strdup(pos + 4);
   1545 
   1546 		if (copy) {
   1547 			pos2 = id = copy;
   1548 			while (*pos2 && *pos2 != ' ')
   1549 				pos2++;
   1550 			*pos2++ = '\0';
   1551 			new_id = atoi(id);
   1552 			os_setenv("WPA_ID", id, 1);
   1553 			while (*pos2 && *pos2 != '=')
   1554 				pos2++;
   1555 			if (*pos2 == '=')
   1556 				pos2++;
   1557 			id = pos2;
   1558 			while (*pos2 && *pos2 != ']')
   1559 				pos2++;
   1560 			*pos2 = '\0';
   1561 			os_setenv("WPA_ID_STR", id, 1);
   1562 			os_free(copy);
   1563 		}
   1564 
   1565 		os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
   1566 
   1567 		if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
   1568 			wpa_cli_connected = 1;
   1569 			wpa_cli_last_id = new_id;
   1570 			wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
   1571 		}
   1572 	} else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
   1573 		if (wpa_cli_connected) {
   1574 			wpa_cli_connected = 0;
   1575 			wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
   1576 		}
   1577 	} else if (str_match(pos, WPA_EVENT_TERMINATING)) {
   1578 		printf("wpa_supplicant is terminating - stop monitoring\n");
   1579 		wpa_cli_quit = 1;
   1580 	}
   1581 }
   1582 
   1583 
   1584 #ifndef CONFIG_ANSI_C_EXTRA
   1585 static void wpa_cli_action_cb(char *msg, size_t len)
   1586 {
   1587 	wpa_cli_action_process(msg);
   1588 }
   1589 #endif /* CONFIG_ANSI_C_EXTRA */
   1590 
   1591 
   1592 static void wpa_cli_reconnect(void)
   1593 {
   1594 	wpa_cli_close_connection();
   1595 	ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
   1596 	if (ctrl_conn) {
   1597 		printf("Connection to wpa_supplicant re-established\n");
   1598 		if (wpa_ctrl_attach(monitor_conn) == 0) {
   1599 			wpa_cli_attached = 1;
   1600 		} else {
   1601 			printf("Warning: Failed to attach to "
   1602 			       "wpa_supplicant.\n");
   1603 		}
   1604 	}
   1605 }
   1606 
   1607 
   1608 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
   1609 				 int action_monitor)
   1610 {
   1611 	int first = 1;
   1612 	if (ctrl == NULL) {
   1613 		wpa_cli_reconnect();
   1614 		return;
   1615 	}
   1616 	while (wpa_ctrl_pending(ctrl) > 0) {
   1617 		char buf[256];
   1618 		size_t len = sizeof(buf) - 1;
   1619 		if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
   1620 			buf[len] = '\0';
   1621 			if (action_monitor)
   1622 				wpa_cli_action_process(buf);
   1623 			else {
   1624 				if (in_read && first)
   1625 					printf("\n");
   1626 				first = 0;
   1627 				printf("%s\n", buf);
   1628 			}
   1629 		} else {
   1630 			printf("Could not read pending message.\n");
   1631 			break;
   1632 		}
   1633 	}
   1634 
   1635 	if (wpa_ctrl_pending(ctrl) < 0) {
   1636 		printf("Connection to wpa_supplicant lost - trying to "
   1637 		       "reconnect\n");
   1638 		wpa_cli_reconnect();
   1639 	}
   1640 }
   1641 
   1642 
   1643 #ifdef CONFIG_READLINE
   1644 static char * wpa_cli_cmd_gen(const char *text, int state)
   1645 {
   1646 	static int i, len;
   1647 	const char *cmd;
   1648 
   1649 	if (state == 0) {
   1650 		i = 0;
   1651 		len = os_strlen(text);
   1652 	}
   1653 
   1654 	while ((cmd = wpa_cli_commands[i].cmd)) {
   1655 		i++;
   1656 		if (os_strncasecmp(cmd, text, len) == 0)
   1657 			return os_strdup(cmd);
   1658 	}
   1659 
   1660 	return NULL;
   1661 }
   1662 
   1663 
   1664 static char * wpa_cli_dummy_gen(const char *text, int state)
   1665 {
   1666 	return NULL;
   1667 }
   1668 
   1669 
   1670 static char ** wpa_cli_completion(const char *text, int start, int end)
   1671 {
   1672 	return rl_completion_matches(text, start == 0 ?
   1673 				     wpa_cli_cmd_gen : wpa_cli_dummy_gen);
   1674 }
   1675 #endif /* CONFIG_READLINE */
   1676 
   1677 
   1678 static void wpa_cli_interactive(void)
   1679 {
   1680 #define max_args 10
   1681 	char cmdbuf[256], *cmd, *argv[max_args], *pos;
   1682 	int argc;
   1683 #ifdef CONFIG_READLINE
   1684 	char *home, *hfile = NULL;
   1685 #endif /* CONFIG_READLINE */
   1686 
   1687 	printf("\nInteractive mode\n\n");
   1688 
   1689 #ifdef CONFIG_READLINE
   1690 	rl_attempted_completion_function = wpa_cli_completion;
   1691 	home = getenv("HOME");
   1692 	if (home) {
   1693 		const char *fname = ".wpa_cli_history";
   1694 		int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
   1695 		hfile = os_malloc(hfile_len);
   1696 		if (hfile) {
   1697 			int res;
   1698 			res = os_snprintf(hfile, hfile_len, "%s/%s", home,
   1699 					  fname);
   1700 			if (res >= 0 && res < hfile_len) {
   1701 				hfile[hfile_len - 1] = '\0';
   1702 				read_history(hfile);
   1703 				stifle_history(100);
   1704 			}
   1705 		}
   1706 	}
   1707 #endif /* CONFIG_READLINE */
   1708 
   1709 	do {
   1710 		wpa_cli_recv_pending(monitor_conn, 0, 0);
   1711 #ifndef CONFIG_NATIVE_WINDOWS
   1712 		alarm(ping_interval);
   1713 #endif /* CONFIG_NATIVE_WINDOWS */
   1714 #ifdef CONFIG_READLINE
   1715 		cmd = readline("> ");
   1716 		if (cmd && *cmd) {
   1717 			HIST_ENTRY *h;
   1718 			while (next_history())
   1719 				;
   1720 			h = previous_history();
   1721 			if (h == NULL || os_strcmp(cmd, h->line) != 0)
   1722 				add_history(cmd);
   1723 			next_history();
   1724 		}
   1725 #else /* CONFIG_READLINE */
   1726 		printf("> ");
   1727 		cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
   1728 #endif /* CONFIG_READLINE */
   1729 #ifndef CONFIG_NATIVE_WINDOWS
   1730 		alarm(0);
   1731 #endif /* CONFIG_NATIVE_WINDOWS */
   1732 		if (cmd == NULL)
   1733 			break;
   1734 		wpa_cli_recv_pending(monitor_conn, 0, 0);
   1735 		pos = cmd;
   1736 		while (*pos != '\0') {
   1737 			if (*pos == '\n') {
   1738 				*pos = '\0';
   1739 				break;
   1740 			}
   1741 			pos++;
   1742 		}
   1743 		argc = 0;
   1744 		pos = cmd;
   1745 		for (;;) {
   1746 			while (*pos == ' ')
   1747 				pos++;
   1748 			if (*pos == '\0')
   1749 				break;
   1750 			argv[argc] = pos;
   1751 			argc++;
   1752 			if (argc == max_args)
   1753 				break;
   1754 			if (*pos == '"') {
   1755 				char *pos2 = os_strrchr(pos, '"');
   1756 				if (pos2)
   1757 					pos = pos2 + 1;
   1758 			}
   1759 			while (*pos != '\0' && *pos != ' ')
   1760 				pos++;
   1761 			if (*pos == ' ')
   1762 				*pos++ = '\0';
   1763 		}
   1764 		if (argc)
   1765 			wpa_request(ctrl_conn, argc, argv);
   1766 
   1767 		if (cmd != cmdbuf)
   1768 			os_free(cmd);
   1769 	} while (!wpa_cli_quit);
   1770 
   1771 #ifdef CONFIG_READLINE
   1772 	if (hfile) {
   1773 		/* Save command history, excluding lines that may contain
   1774 		 * passwords. */
   1775 		HIST_ENTRY *h;
   1776 		history_set_pos(0);
   1777 		while ((h = current_history())) {
   1778 			char *p = h->line;
   1779 			while (*p == ' ' || *p == '\t')
   1780 				p++;
   1781 			if (cmd_has_sensitive_data(p)) {
   1782 				h = remove_history(where_history());
   1783 				if (h) {
   1784 					os_free(h->line);
   1785 					os_free(h->data);
   1786 					os_free(h);
   1787 				} else
   1788 					next_history();
   1789 			} else
   1790 				next_history();
   1791 		}
   1792 		write_history(hfile);
   1793 		os_free(hfile);
   1794 	}
   1795 #endif /* CONFIG_READLINE */
   1796 }
   1797 
   1798 
   1799 static void wpa_cli_action(struct wpa_ctrl *ctrl)
   1800 {
   1801 #ifdef CONFIG_ANSI_C_EXTRA
   1802 	/* TODO: ANSI C version(?) */
   1803 	printf("Action processing not supported in ANSI C build.\n");
   1804 #else /* CONFIG_ANSI_C_EXTRA */
   1805 	fd_set rfds;
   1806 	int fd, res;
   1807 	struct timeval tv;
   1808 	char buf[256]; /* note: large enough to fit in unsolicited messages */
   1809 	size_t len;
   1810 
   1811 	fd = wpa_ctrl_get_fd(ctrl);
   1812 
   1813 	while (!wpa_cli_quit) {
   1814 		FD_ZERO(&rfds);
   1815 		FD_SET(fd, &rfds);
   1816 		tv.tv_sec = ping_interval;
   1817 		tv.tv_usec = 0;
   1818 		res = select(fd + 1, &rfds, NULL, NULL, &tv);
   1819 		if (res < 0 && errno != EINTR) {
   1820 			perror("select");
   1821 			break;
   1822 		}
   1823 
   1824 		if (FD_ISSET(fd, &rfds))
   1825 			wpa_cli_recv_pending(ctrl, 0, 1);
   1826 		else {
   1827 			/* verify that connection is still working */
   1828 			len = sizeof(buf) - 1;
   1829 			if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
   1830 					     wpa_cli_action_cb) < 0 ||
   1831 			    len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
   1832 				printf("wpa_supplicant did not reply to PING "
   1833 				       "command - exiting\n");
   1834 				break;
   1835 			}
   1836 		}
   1837 	}
   1838 #endif /* CONFIG_ANSI_C_EXTRA */
   1839 }
   1840 
   1841 
   1842 static void wpa_cli_cleanup(void)
   1843 {
   1844 	wpa_cli_close_connection();
   1845 	if (pid_file)
   1846 		os_daemonize_terminate(pid_file);
   1847 
   1848 	os_program_deinit();
   1849 }
   1850 
   1851 static void wpa_cli_terminate(int sig)
   1852 {
   1853 	wpa_cli_cleanup();
   1854 	exit(0);
   1855 }
   1856 
   1857 
   1858 #ifndef CONFIG_NATIVE_WINDOWS
   1859 static void wpa_cli_alarm(int sig)
   1860 {
   1861 	if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
   1862 		printf("Connection to wpa_supplicant lost - trying to "
   1863 		       "reconnect\n");
   1864 		wpa_cli_close_connection();
   1865 	}
   1866 	if (!monitor_conn)
   1867 		wpa_cli_reconnect();
   1868 	if (monitor_conn)
   1869 		wpa_cli_recv_pending(monitor_conn, 1, 0);
   1870 	alarm(ping_interval);
   1871 }
   1872 #endif /* CONFIG_NATIVE_WINDOWS */
   1873 
   1874 
   1875 static char * wpa_cli_get_default_ifname(void)
   1876 {
   1877 	char *ifname = NULL;
   1878 
   1879 #ifdef CONFIG_CTRL_IFACE_UNIX
   1880 	struct dirent *dent;
   1881 	DIR *dir = opendir(ctrl_iface_dir);
   1882 	if (!dir) {
   1883 #ifdef ANDROID
   1884 		char ifprop[PROPERTY_VALUE_MAX];
   1885 		if (property_get("wifi.interface", ifprop, NULL) != 0) {
   1886 			ifname = os_strdup(ifprop);
   1887 			printf("Using interface '%s'\n", ifname);
   1888 			return ifname;
   1889 		}
   1890 #endif
   1891 		return NULL;
   1892 	}
   1893 	while ((dent = readdir(dir))) {
   1894 #ifdef _DIRENT_HAVE_D_TYPE
   1895 		/*
   1896 		 * Skip the file if it is not a socket. Also accept
   1897 		 * DT_UNKNOWN (0) in case the C library or underlying
   1898 		 * file system does not support d_type.
   1899 		 */
   1900 		if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
   1901 			continue;
   1902 #endif /* _DIRENT_HAVE_D_TYPE */
   1903 		if (os_strcmp(dent->d_name, ".") == 0 ||
   1904 		    os_strcmp(dent->d_name, "..") == 0)
   1905 			continue;
   1906 		printf("Selected interface '%s'\n", dent->d_name);
   1907 		ifname = os_strdup(dent->d_name);
   1908 		break;
   1909 	}
   1910 	closedir(dir);
   1911 #endif /* CONFIG_CTRL_IFACE_UNIX */
   1912 
   1913 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
   1914 	char buf[4096], *pos;
   1915 	size_t len;
   1916 	struct wpa_ctrl *ctrl;
   1917 	int ret;
   1918 
   1919 	ctrl = wpa_ctrl_open(NULL);
   1920 	if (ctrl == NULL)
   1921 		return NULL;
   1922 
   1923 	len = sizeof(buf) - 1;
   1924 	ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
   1925 	if (ret >= 0) {
   1926 		buf[len] = '\0';
   1927 		pos = os_strchr(buf, '\n');
   1928 		if (pos)
   1929 			*pos = '\0';
   1930 		ifname = os_strdup(buf);
   1931 	}
   1932 	wpa_ctrl_close(ctrl);
   1933 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   1934 
   1935 	return ifname;
   1936 }
   1937 
   1938 
   1939 int main(int argc, char *argv[])
   1940 {
   1941 	int interactive;
   1942 	int warning_displayed = 0;
   1943 	int c;
   1944 	int daemonize = 0;
   1945 	int ret = 0;
   1946 	const char *global = NULL;
   1947 
   1948 	if (os_program_init())
   1949 		return -1;
   1950 
   1951 	for (;;) {
   1952 		c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
   1953 		if (c < 0)
   1954 			break;
   1955 		switch (c) {
   1956 		case 'a':
   1957 			action_file = optarg;
   1958 			break;
   1959 		case 'B':
   1960 			daemonize = 1;
   1961 			break;
   1962 		case 'g':
   1963 			global = optarg;
   1964 			break;
   1965 		case 'G':
   1966 			ping_interval = atoi(optarg);
   1967 			break;
   1968 		case 'h':
   1969 			usage();
   1970 			return 0;
   1971 		case 'v':
   1972 			printf("%s\n", wpa_cli_version);
   1973 			return 0;
   1974 		case 'i':
   1975 			os_free(ctrl_ifname);
   1976 			ctrl_ifname = os_strdup(optarg);
   1977 			break;
   1978 		case 'p':
   1979 			ctrl_iface_dir = optarg;
   1980 			break;
   1981 		case 'P':
   1982 			pid_file = optarg;
   1983 			break;
   1984 		default:
   1985 			usage();
   1986 			return -1;
   1987 		}
   1988 	}
   1989 
   1990 	interactive = (argc == optind) && (action_file == NULL);
   1991 
   1992 	if (interactive)
   1993 		printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
   1994 
   1995 	if (global) {
   1996 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
   1997 		ctrl_conn = wpa_ctrl_open(NULL);
   1998 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   1999 		ctrl_conn = wpa_ctrl_open(global);
   2000 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   2001 		if (ctrl_conn == NULL) {
   2002 			perror("Failed to connect to wpa_supplicant - "
   2003 			       "wpa_ctrl_open");
   2004 			return -1;
   2005 		}
   2006 	}
   2007 
   2008 	for (; !global;) {
   2009 		if (ctrl_ifname == NULL)
   2010 			ctrl_ifname = wpa_cli_get_default_ifname();
   2011 		ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
   2012 		if (ctrl_conn) {
   2013 			if (warning_displayed)
   2014 				printf("Connection established.\n");
   2015 			break;
   2016 		}
   2017 
   2018 		if (!interactive) {
   2019 			perror("Failed to connect to wpa_supplicant - "
   2020 			       "wpa_ctrl_open");
   2021 			return -1;
   2022 		}
   2023 
   2024 		if (!warning_displayed) {
   2025 			printf("Could not connect to wpa_supplicant - "
   2026 			       "re-trying\n");
   2027 			warning_displayed = 1;
   2028 		}
   2029 		os_sleep(1, 0);
   2030 		continue;
   2031 	}
   2032 
   2033 #ifndef _WIN32_WCE
   2034 	signal(SIGINT, wpa_cli_terminate);
   2035 	signal(SIGTERM, wpa_cli_terminate);
   2036 #endif /* _WIN32_WCE */
   2037 #ifndef CONFIG_NATIVE_WINDOWS
   2038 	signal(SIGALRM, wpa_cli_alarm);
   2039 #endif /* CONFIG_NATIVE_WINDOWS */
   2040 
   2041 	if (interactive || action_file) {
   2042 		if (wpa_ctrl_attach(monitor_conn) == 0) {
   2043 			wpa_cli_attached = 1;
   2044 		} else {
   2045 			printf("Warning: Failed to attach to "
   2046 			       "wpa_supplicant.\n");
   2047 			if (!interactive)
   2048 				return -1;
   2049 		}
   2050 	}
   2051 
   2052 	if (daemonize && os_daemonize(pid_file))
   2053 		return -1;
   2054 
   2055 	if (interactive)
   2056 		wpa_cli_interactive();
   2057 	else if (action_file)
   2058 		wpa_cli_action(ctrl_conn);
   2059 	else
   2060 		ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
   2061 
   2062 	os_free(ctrl_ifname);
   2063 	wpa_cli_cleanup();
   2064 
   2065 	return ret;
   2066 }
   2067 
   2068 #else /* CONFIG_CTRL_IFACE */
   2069 int main(int argc, char *argv[])
   2070 {
   2071 	printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
   2072 	return -1;
   2073 }
   2074 #endif /* CONFIG_CTRL_IFACE */
   2075