Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * WPA Supplicant - command line interface for wpa_supplicant daemon
      3  * Copyright (c) 2004-2011, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 
     11 #ifdef CONFIG_CTRL_IFACE
     12 
     13 #ifdef CONFIG_CTRL_IFACE_UNIX
     14 #include <dirent.h>
     15 #endif /* CONFIG_CTRL_IFACE_UNIX */
     16 
     17 #include "common/wpa_ctrl.h"
     18 #include "utils/common.h"
     19 #include "utils/eloop.h"
     20 #include "utils/edit.h"
     21 #include "utils/list.h"
     22 #include "common/version.h"
     23 #ifdef ANDROID
     24 #include <cutils/properties.h>
     25 #endif /* ANDROID */
     26 
     27 
     28 static const char *wpa_cli_version =
     29 "wpa_cli v" VERSION_STR "\n"
     30 "Copyright (c) 2004-2012, Jouni Malinen <j (at) w1.fi> and contributors";
     31 
     32 
     33 static const char *wpa_cli_license =
     34 "This software may be distributed under the terms of the BSD license.\n"
     35 "See README for more details.\n";
     36 
     37 static const char *wpa_cli_full_license =
     38 "This software may be distributed under the terms of the BSD license.\n"
     39 "\n"
     40 "Redistribution and use in source and binary forms, with or without\n"
     41 "modification, are permitted provided that the following conditions are\n"
     42 "met:\n"
     43 "\n"
     44 "1. Redistributions of source code must retain the above copyright\n"
     45 "   notice, this list of conditions and the following disclaimer.\n"
     46 "\n"
     47 "2. Redistributions in binary form must reproduce the above copyright\n"
     48 "   notice, this list of conditions and the following disclaimer in the\n"
     49 "   documentation and/or other materials provided with the distribution.\n"
     50 "\n"
     51 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
     52 "   names of its contributors may be used to endorse or promote products\n"
     53 "   derived from this software without specific prior written permission.\n"
     54 "\n"
     55 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
     56 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
     57 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
     58 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
     59 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
     60 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
     61 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
     62 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
     63 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
     64 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
     65 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
     66 "\n";
     67 
     68 static struct wpa_ctrl *ctrl_conn;
     69 static struct wpa_ctrl *mon_conn;
     70 static int wpa_cli_quit = 0;
     71 static int wpa_cli_attached = 0;
     72 static int wpa_cli_connected = 0;
     73 static int wpa_cli_last_id = 0;
     74 #ifndef CONFIG_CTRL_IFACE_DIR
     75 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
     76 #endif /* CONFIG_CTRL_IFACE_DIR */
     77 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
     78 static char *ctrl_ifname = NULL;
     79 static const char *pid_file = NULL;
     80 static const char *action_file = NULL;
     81 static int ping_interval = 5;
     82 static int interactive = 0;
     83 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
     84 static char* redirect_interface = NULL;
     85 #endif
     86 
     87 struct cli_txt_entry {
     88 	struct dl_list list;
     89 	char *txt;
     90 };
     91 
     92 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
     93 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
     94 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
     95 
     96 
     97 static void print_help(void);
     98 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
     99 
    100 
    101 static void usage(void)
    102 {
    103 	printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
    104 	       "[-a<action file>] \\\n"
    105 	       "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>]  "
    106 	       "[command..]\n"
    107 	       "  -h = help (show this usage text)\n"
    108 	       "  -v = shown version information\n"
    109 	       "  -a = run in daemon mode executing the action file based on "
    110 	       "events from\n"
    111 	       "       wpa_supplicant\n"
    112 	       "  -B = run a daemon in the background\n"
    113 	       "  default path: " CONFIG_CTRL_IFACE_DIR "\n"
    114 	       "  default interface: first interface found in socket path\n");
    115 	print_help();
    116 }
    117 
    118 
    119 static void cli_txt_list_free(struct cli_txt_entry *e)
    120 {
    121 	dl_list_del(&e->list);
    122 	os_free(e->txt);
    123 	os_free(e);
    124 }
    125 
    126 
    127 static void cli_txt_list_flush(struct dl_list *list)
    128 {
    129 	struct cli_txt_entry *e;
    130 	while ((e = dl_list_first(list, struct cli_txt_entry, list)))
    131 		cli_txt_list_free(e);
    132 }
    133 
    134 
    135 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
    136 					       const char *txt)
    137 {
    138 	struct cli_txt_entry *e;
    139 	dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
    140 		if (os_strcmp(e->txt, txt) == 0)
    141 			return e;
    142 	}
    143 	return NULL;
    144 }
    145 
    146 
    147 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
    148 {
    149 	struct cli_txt_entry *e;
    150 	e = cli_txt_list_get(txt_list, txt);
    151 	if (e)
    152 		cli_txt_list_free(e);
    153 }
    154 
    155 
    156 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
    157 {
    158 	u8 addr[ETH_ALEN];
    159 	char buf[18];
    160 	if (hwaddr_aton(txt, addr) < 0)
    161 		return;
    162 	os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
    163 	cli_txt_list_del(txt_list, buf);
    164 }
    165 
    166 
    167 #ifdef CONFIG_P2P
    168 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
    169 {
    170 	const char *end;
    171 	char *buf;
    172 	end = os_strchr(txt, ' ');
    173 	if (end == NULL)
    174 		end = txt + os_strlen(txt);
    175 	buf = os_malloc(end - txt + 1);
    176 	if (buf == NULL)
    177 		return;
    178 	os_memcpy(buf, txt, end - txt);
    179 	buf[end - txt] = '\0';
    180 	cli_txt_list_del(txt_list, buf);
    181 	os_free(buf);
    182 }
    183 #endif /* CONFIG_P2P */
    184 
    185 
    186 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
    187 {
    188 	struct cli_txt_entry *e;
    189 	e = cli_txt_list_get(txt_list, txt);
    190 	if (e)
    191 		return 0;
    192 	e = os_zalloc(sizeof(*e));
    193 	if (e == NULL)
    194 		return -1;
    195 	e->txt = os_strdup(txt);
    196 	if (e->txt == NULL) {
    197 		os_free(e);
    198 		return -1;
    199 	}
    200 	dl_list_add(txt_list, &e->list);
    201 	return 0;
    202 }
    203 
    204 
    205 #ifdef CONFIG_P2P
    206 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
    207 {
    208 	u8 addr[ETH_ALEN];
    209 	char buf[18];
    210 	if (hwaddr_aton(txt, addr) < 0)
    211 		return -1;
    212 	os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
    213 	return cli_txt_list_add(txt_list, buf);
    214 }
    215 
    216 
    217 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
    218 {
    219 	const char *end;
    220 	char *buf;
    221 	int ret;
    222 	end = os_strchr(txt, ' ');
    223 	if (end == NULL)
    224 		end = txt + os_strlen(txt);
    225 	buf = os_malloc(end - txt + 1);
    226 	if (buf == NULL)
    227 		return -1;
    228 	os_memcpy(buf, txt, end - txt);
    229 	buf[end - txt] = '\0';
    230 	ret = cli_txt_list_add(txt_list, buf);
    231 	os_free(buf);
    232 	return ret;
    233 }
    234 #endif /* CONFIG_P2P */
    235 
    236 
    237 static char ** cli_txt_list_array(struct dl_list *txt_list)
    238 {
    239 	unsigned int i, count = dl_list_len(txt_list);
    240 	char **res;
    241 	struct cli_txt_entry *e;
    242 
    243 	res = os_zalloc((count + 1) * sizeof(char *));
    244 	if (res == NULL)
    245 		return NULL;
    246 
    247 	i = 0;
    248 	dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
    249 		res[i] = os_strdup(e->txt);
    250 		if (res[i] == NULL)
    251 			break;
    252 		i++;
    253 	}
    254 
    255 	return res;
    256 }
    257 
    258 
    259 static int get_cmd_arg_num(const char *str, int pos)
    260 {
    261 	int arg = 0, i;
    262 
    263 	for (i = 0; i <= pos; i++) {
    264 		if (str[i] != ' ') {
    265 			arg++;
    266 			while (i <= pos && str[i] != ' ')
    267 				i++;
    268 		}
    269 	}
    270 
    271 	if (arg > 0)
    272 		arg--;
    273 	return arg;
    274 }
    275 
    276 
    277 static int str_starts(const char *src, const char *match)
    278 {
    279 	return os_strncmp(src, match, os_strlen(match)) == 0;
    280 }
    281 
    282 
    283 static int wpa_cli_show_event(const char *event)
    284 {
    285 	const char *start;
    286 
    287 	start = os_strchr(event, '>');
    288 	if (start == NULL)
    289 		return 1;
    290 
    291 	start++;
    292 	/*
    293 	 * Skip BSS added/removed events since they can be relatively frequent
    294 	 * and are likely of not much use for an interactive user.
    295 	 */
    296 	if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
    297 	    str_starts(start, WPA_EVENT_BSS_REMOVED))
    298 		return 0;
    299 
    300 	return 1;
    301 }
    302 
    303 
    304 static int wpa_cli_open_connection(const char *ifname, int attach)
    305 {
    306 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
    307 	ctrl_conn = wpa_ctrl_open(ifname);
    308 	if (ctrl_conn == NULL)
    309 		return -1;
    310 
    311 	if (attach && interactive)
    312 		mon_conn = wpa_ctrl_open(ifname);
    313 	else
    314 		mon_conn = NULL;
    315 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
    316 	char *cfile = NULL;
    317 	int flen, res;
    318 
    319 	if (ifname == NULL)
    320 		return -1;
    321 
    322 #ifdef ANDROID
    323 	if (access(ctrl_iface_dir, F_OK) < 0) {
    324 		cfile = os_strdup(ifname);
    325 		if (cfile == NULL)
    326 			return -1;
    327 	}
    328 #endif /* ANDROID */
    329 
    330 	if (cfile == NULL) {
    331 		flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
    332 		cfile = os_malloc(flen);
    333 		if (cfile == NULL)
    334 			return -1;
    335 		res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
    336 				  ifname);
    337 		if (res < 0 || res >= flen) {
    338 			os_free(cfile);
    339 			return -1;
    340 		}
    341 	}
    342 
    343 	ctrl_conn = wpa_ctrl_open(cfile);
    344 	if (ctrl_conn == NULL) {
    345 		os_free(cfile);
    346 		return -1;
    347 	}
    348 
    349 	if (attach && interactive)
    350 		mon_conn = wpa_ctrl_open(cfile);
    351 	else
    352 		mon_conn = NULL;
    353 	os_free(cfile);
    354 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
    355 
    356 	if (mon_conn) {
    357 		if (wpa_ctrl_attach(mon_conn) == 0) {
    358 			wpa_cli_attached = 1;
    359 			if (interactive)
    360 				eloop_register_read_sock(
    361 					wpa_ctrl_get_fd(mon_conn),
    362 					wpa_cli_mon_receive, NULL, NULL);
    363 		} else {
    364 			printf("Warning: Failed to attach to "
    365 			       "wpa_supplicant.\n");
    366 			return -1;
    367 		}
    368 	}
    369 
    370 	return 0;
    371 }
    372 
    373 
    374 static void wpa_cli_close_connection(void)
    375 {
    376 	if (ctrl_conn == NULL)
    377 		return;
    378 
    379 	if (wpa_cli_attached) {
    380 		wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
    381 		wpa_cli_attached = 0;
    382 	}
    383 	wpa_ctrl_close(ctrl_conn);
    384 	ctrl_conn = NULL;
    385 	if (mon_conn) {
    386 		eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
    387 		wpa_ctrl_close(mon_conn);
    388 		mon_conn = NULL;
    389 	}
    390 }
    391 
    392 
    393 static void wpa_cli_msg_cb(char *msg, size_t len)
    394 {
    395 	printf("%s\n", msg);
    396 }
    397 
    398 
    399 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
    400 {
    401 #ifdef ANDROID
    402 	char buf[4096];
    403 #else
    404 	char buf[2048];
    405 #endif
    406 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
    407 	char _cmd[256];
    408 #endif
    409 	size_t len;
    410 	int ret;
    411 
    412 	if (ctrl_conn == NULL) {
    413 		printf("Not connected to wpa_supplicant - command dropped.\n");
    414 		return -1;
    415 	}
    416 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
    417 	if (redirect_interface) {
    418 		char *arg;
    419 		arg = os_strchr(cmd, ' ');
    420 		if (arg) {
    421 			*arg++ = '\0';
    422 			ret = os_snprintf(_cmd, sizeof(_cmd), "%s %s %s", cmd, redirect_interface, arg);
    423 		}
    424 		else {
    425 			ret = os_snprintf(_cmd, sizeof(_cmd), "%s %s", cmd, redirect_interface);
    426 		}
    427 		cmd = _cmd;
    428 		os_free(redirect_interface);
    429 		redirect_interface = NULL;
    430 	}
    431 #endif
    432 	len = sizeof(buf) - 1;
    433 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
    434 			       wpa_cli_msg_cb);
    435 	if (ret == -2) {
    436 		printf("'%s' command timed out.\n", cmd);
    437 		return -2;
    438 	} else if (ret < 0) {
    439 		printf("'%s' command failed.\n", cmd);
    440 		return -1;
    441 	}
    442 	if (print) {
    443 		buf[len] = '\0';
    444 		printf("%s", buf);
    445 		if (interactive && len > 0 && buf[len - 1] != '\n')
    446 			printf("\n");
    447 	}
    448 	return 0;
    449 }
    450 
    451 
    452 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
    453 {
    454 	return _wpa_ctrl_command(ctrl, cmd, 1);
    455 }
    456 
    457 
    458 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
    459 {
    460 	if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
    461 		return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
    462 	if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
    463 		return wpa_ctrl_command(ctrl, "STATUS-WPS");
    464 	return wpa_ctrl_command(ctrl, "STATUS");
    465 }
    466 
    467 
    468 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
    469 {
    470 	return wpa_ctrl_command(ctrl, "PING");
    471 }
    472 
    473 
    474 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
    475 {
    476 	return wpa_ctrl_command(ctrl, "RELOG");
    477 }
    478 
    479 
    480 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
    481 {
    482 	char cmd[256];
    483 	int ret;
    484 	if (argc == 0)
    485 		return -1;
    486 	ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
    487 	if (ret < 0 || (size_t) ret >= sizeof(cmd))
    488 		return -1;
    489 	return wpa_ctrl_command(ctrl, cmd);
    490 }
    491 
    492 
    493 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
    494 {
    495 	return wpa_ctrl_command(ctrl, "MIB");
    496 }
    497 
    498 
    499 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
    500 {
    501 	return wpa_ctrl_command(ctrl, "PMKSA");
    502 }
    503 
    504 
    505 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
    506 {
    507 	print_help();
    508 	return 0;
    509 }
    510 
    511 
    512 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
    513 {
    514 	printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
    515 	return 0;
    516 }
    517 
    518 
    519 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
    520 {
    521 	wpa_cli_quit = 1;
    522 	if (interactive)
    523 		eloop_terminate();
    524 	return 0;
    525 }
    526 
    527 
    528 static void wpa_cli_show_variables(void)
    529 {
    530 	printf("set variables:\n"
    531 	       "  EAPOL::heldPeriod (EAPOL state machine held period, "
    532 	       "in seconds)\n"
    533 	       "  EAPOL::authPeriod (EAPOL state machine authentication "
    534 	       "period, in seconds)\n"
    535 	       "  EAPOL::startPeriod (EAPOL state machine start period, in "
    536 	       "seconds)\n"
    537 	       "  EAPOL::maxStart (EAPOL state machine maximum start "
    538 	       "attempts)\n");
    539 	printf("  dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
    540 	       "seconds)\n"
    541 	       "  dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
    542 	       " threshold\n\tpercentage)\n"
    543 	       "  dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
    544 	       "security\n\tassociation in seconds)\n");
    545 }
    546 
    547 
    548 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
    549 {
    550 	char cmd[256];
    551 	int res;
    552 
    553 	if (argc == 0) {
    554 		wpa_cli_show_variables();
    555 		return 0;
    556 	}
    557 
    558 	if (argc != 1 && argc != 2) {
    559 		printf("Invalid SET command: needs two arguments (variable "
    560 		       "name and value)\n");
    561 		return -1;
    562 	}
    563 
    564 	if (argc == 1)
    565 		res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
    566 	else
    567 		res = os_snprintf(cmd, sizeof(cmd), "SET %s %s",
    568 				  argv[0], argv[1]);
    569 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    570 		printf("Too long SET command.\n");
    571 		return -1;
    572 	}
    573 	return wpa_ctrl_command(ctrl, cmd);
    574 }
    575 
    576 
    577 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
    578 {
    579 	char cmd[256];
    580 	int res;
    581 
    582 	if (argc != 1) {
    583 		printf("Invalid GET command: need one argument (variable "
    584 		       "name)\n");
    585 		return -1;
    586 	}
    587 
    588 	res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
    589 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    590 		printf("Too long GET command.\n");
    591 		return -1;
    592 	}
    593 	return wpa_ctrl_command(ctrl, cmd);
    594 }
    595 
    596 
    597 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
    598 {
    599 	return wpa_ctrl_command(ctrl, "LOGOFF");
    600 }
    601 
    602 
    603 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
    604 {
    605 	return wpa_ctrl_command(ctrl, "LOGON");
    606 }
    607 
    608 
    609 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
    610 				   char *argv[])
    611 {
    612 	return wpa_ctrl_command(ctrl, "REASSOCIATE");
    613 }
    614 
    615 
    616 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
    617 				       char *argv[])
    618 {
    619 	char cmd[256];
    620 	int res;
    621 
    622 	if (argc != 1) {
    623 		printf("Invalid PREAUTH command: needs one argument "
    624 		       "(BSSID)\n");
    625 		return -1;
    626 	}
    627 
    628 	res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
    629 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    630 		printf("Too long PREAUTH command.\n");
    631 		return -1;
    632 	}
    633 	return wpa_ctrl_command(ctrl, cmd);
    634 }
    635 
    636 
    637 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
    638 {
    639 	char cmd[256];
    640 	int res;
    641 
    642 	if (argc != 1) {
    643 		printf("Invalid AP_SCAN command: needs one argument (ap_scan "
    644 		       "value)\n");
    645 		return -1;
    646 	}
    647 	res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
    648 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    649 		printf("Too long AP_SCAN command.\n");
    650 		return -1;
    651 	}
    652 	return wpa_ctrl_command(ctrl, cmd);
    653 }
    654 
    655 
    656 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
    657 				     char *argv[])
    658 {
    659 	char cmd[256];
    660 	int res;
    661 
    662 	if (argc != 1) {
    663 		printf("Invalid SCAN_INTERVAL command: needs one argument "
    664 		       "scan_interval value)\n");
    665 		return -1;
    666 	}
    667 	res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
    668 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    669 		printf("Too long SCAN_INTERVAL command.\n");
    670 		return -1;
    671 	}
    672 	return wpa_ctrl_command(ctrl, cmd);
    673 }
    674 
    675 
    676 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
    677 				      char *argv[])
    678 {
    679 	char cmd[256];
    680 	int res;
    681 
    682 	if (argc != 1) {
    683 		printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
    684 		       "(bss_expire_age value)\n");
    685 		return -1;
    686 	}
    687 	res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
    688 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    689 		printf("Too long BSS_EXPIRE_AGE command.\n");
    690 		return -1;
    691 	}
    692 	return wpa_ctrl_command(ctrl, cmd);
    693 }
    694 
    695 
    696 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
    697 				        char *argv[])
    698 {
    699 	char cmd[256];
    700 	int res;
    701 
    702 	if (argc != 1) {
    703 		printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
    704 		       "(bss_expire_count value)\n");
    705 		return -1;
    706 	}
    707 	res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
    708 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    709 		printf("Too long BSS_EXPIRE_COUNT command.\n");
    710 		return -1;
    711 	}
    712 	return wpa_ctrl_command(ctrl, cmd);
    713 }
    714 
    715 
    716 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
    717 				char *argv[])
    718 {
    719 	char cmd[256];
    720 	int res;
    721 
    722 	if (argc != 1) {
    723 		printf("Invalid STKSTART command: needs one argument "
    724 		       "(Peer STA MAC address)\n");
    725 		return -1;
    726 	}
    727 
    728 	res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
    729 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    730 		printf("Too long STKSTART command.\n");
    731 		return -1;
    732 	}
    733 	return wpa_ctrl_command(ctrl, cmd);
    734 }
    735 
    736 
    737 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
    738 {
    739 	char cmd[256];
    740 	int res;
    741 
    742 	if (argc != 1) {
    743 		printf("Invalid FT_DS command: needs one argument "
    744 		       "(Target AP MAC address)\n");
    745 		return -1;
    746 	}
    747 
    748 	res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
    749 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    750 		printf("Too long FT_DS command.\n");
    751 		return -1;
    752 	}
    753 	return wpa_ctrl_command(ctrl, cmd);
    754 }
    755 
    756 
    757 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
    758 {
    759 	char cmd[256];
    760 	int res;
    761 
    762 	if (argc == 0) {
    763 		/* Any BSSID */
    764 		return wpa_ctrl_command(ctrl, "WPS_PBC");
    765 	}
    766 
    767 	/* Specific BSSID */
    768 	res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
    769 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    770 		printf("Too long WPS_PBC command.\n");
    771 		return -1;
    772 	}
    773 	return wpa_ctrl_command(ctrl, cmd);
    774 }
    775 
    776 
    777 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
    778 {
    779 	char cmd[256];
    780 	int res;
    781 
    782 	if (argc == 0) {
    783 		printf("Invalid WPS_PIN command: need one or two arguments:\n"
    784 		       "- BSSID: use 'any' to select any\n"
    785 		       "- PIN: optional, used only with devices that have no "
    786 		       "display\n");
    787 		return -1;
    788 	}
    789 
    790 	if (argc == 1) {
    791 		/* Use dynamically generated PIN (returned as reply) */
    792 		res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
    793 		if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    794 			printf("Too long WPS_PIN command.\n");
    795 			return -1;
    796 		}
    797 		return wpa_ctrl_command(ctrl, cmd);
    798 	}
    799 
    800 	/* Use hardcoded PIN from a label */
    801 	res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
    802 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    803 		printf("Too long WPS_PIN command.\n");
    804 		return -1;
    805 	}
    806 	return wpa_ctrl_command(ctrl, cmd);
    807 }
    808 
    809 
    810 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
    811 				     char *argv[])
    812 {
    813 	char cmd[256];
    814 	int res;
    815 
    816 	if (argc != 1 && argc != 2) {
    817 		printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
    818 		       "- PIN to be verified\n");
    819 		return -1;
    820 	}
    821 
    822 	if (argc == 2)
    823 		res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
    824 				  argv[0], argv[1]);
    825 	else
    826 		res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
    827 				  argv[0]);
    828 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    829 		printf("Too long WPS_CHECK_PIN command.\n");
    830 		return -1;
    831 	}
    832 	return wpa_ctrl_command(ctrl, cmd);
    833 }
    834 
    835 
    836 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
    837 				  char *argv[])
    838 {
    839 	return wpa_ctrl_command(ctrl, "WPS_CANCEL");
    840 }
    841 
    842 
    843 #ifdef CONFIG_WPS_OOB
    844 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
    845 {
    846 	char cmd[256];
    847 	int res;
    848 
    849 	if (argc != 3 && argc != 4) {
    850 		printf("Invalid WPS_OOB command: need three or four "
    851 		       "arguments:\n"
    852 		       "- DEV_TYPE: use 'ufd' or 'nfc'\n"
    853 		       "- PATH: path of OOB device like '/mnt'\n"
    854 		       "- METHOD: OOB method 'pin-e' or 'pin-r', "
    855 		       "'cred'\n"
    856 		       "- DEV_NAME: (only for NFC) device name like "
    857 		       "'pn531'\n");
    858 		return -1;
    859 	}
    860 
    861 	if (argc == 3)
    862 		res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
    863 				  argv[0], argv[1], argv[2]);
    864 	else
    865 		res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
    866 				  argv[0], argv[1], argv[2], argv[3]);
    867 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    868 		printf("Too long WPS_OOB command.\n");
    869 		return -1;
    870 	}
    871 	return wpa_ctrl_command(ctrl, cmd);
    872 }
    873 #endif /* CONFIG_WPS_OOB */
    874 
    875 
    876 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
    877 {
    878 	char cmd[256];
    879 	int res;
    880 
    881 	if (argc == 2)
    882 		res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
    883 				  argv[0], argv[1]);
    884 	else if (argc == 5 || argc == 6) {
    885 		char ssid_hex[2 * 32 + 1];
    886 		char key_hex[2 * 64 + 1];
    887 		int i;
    888 
    889 		ssid_hex[0] = '\0';
    890 		for (i = 0; i < 32; i++) {
    891 			if (argv[2][i] == '\0')
    892 				break;
    893 			os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
    894 		}
    895 
    896 		key_hex[0] = '\0';
    897 		if (argc == 6) {
    898 			for (i = 0; i < 64; i++) {
    899 				if (argv[5][i] == '\0')
    900 					break;
    901 				os_snprintf(&key_hex[i * 2], 3, "%02x",
    902 					    argv[5][i]);
    903 			}
    904 		}
    905 
    906 		res = os_snprintf(cmd, sizeof(cmd),
    907 				  "WPS_REG %s %s %s %s %s %s",
    908 				  argv[0], argv[1], ssid_hex, argv[3], argv[4],
    909 				  key_hex);
    910 	} else {
    911 		printf("Invalid WPS_REG command: need two arguments:\n"
    912 		       "- BSSID of the target AP\n"
    913 		       "- AP PIN\n");
    914 		printf("Alternatively, six arguments can be used to "
    915 		       "reconfigure the AP:\n"
    916 		       "- BSSID of the target AP\n"
    917 		       "- AP PIN\n"
    918 		       "- new SSID\n"
    919 		       "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
    920 		       "- new encr (NONE, WEP, TKIP, CCMP)\n"
    921 		       "- new key\n");
    922 		return -1;
    923 	}
    924 
    925 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    926 		printf("Too long WPS_REG command.\n");
    927 		return -1;
    928 	}
    929 	return wpa_ctrl_command(ctrl, cmd);
    930 }
    931 
    932 
    933 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
    934 				  char *argv[])
    935 {
    936 	char cmd[256];
    937 	int res;
    938 
    939 	if (argc < 1) {
    940 		printf("Invalid WPS_AP_PIN command: needs at least one "
    941 		       "argument\n");
    942 		return -1;
    943 	}
    944 
    945 	if (argc > 2)
    946 		res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
    947 				  argv[0], argv[1], argv[2]);
    948 	else if (argc > 1)
    949 		res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
    950 				  argv[0], argv[1]);
    951 	else
    952 		res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
    953 				  argv[0]);
    954 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    955 		printf("Too long WPS_AP_PIN command.\n");
    956 		return -1;
    957 	}
    958 	return wpa_ctrl_command(ctrl, cmd);
    959 }
    960 
    961 
    962 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
    963 				    char *argv[])
    964 {
    965 	char cmd[100];
    966 	if (argc > 0) {
    967 		os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
    968 		return wpa_ctrl_command(ctrl, cmd);
    969 	}
    970 	return wpa_ctrl_command(ctrl, "WPS_ER_START");
    971 }
    972 
    973 
    974 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
    975 				   char *argv[])
    976 {
    977 	return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
    978 
    979 }
    980 
    981 
    982 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
    983 				  char *argv[])
    984 {
    985 	char cmd[256];
    986 	int res;
    987 
    988 	if (argc < 2) {
    989 		printf("Invalid WPS_ER_PIN command: need at least two "
    990 		       "arguments:\n"
    991 		       "- UUID: use 'any' to select any\n"
    992 		       "- PIN: Enrollee PIN\n"
    993 		       "optional: - Enrollee MAC address\n");
    994 		return -1;
    995 	}
    996 
    997 	if (argc > 2)
    998 		res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
    999 				  argv[0], argv[1], argv[2]);
   1000 	else
   1001 		res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
   1002 				  argv[0], argv[1]);
   1003 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1004 		printf("Too long WPS_ER_PIN command.\n");
   1005 		return -1;
   1006 	}
   1007 	return wpa_ctrl_command(ctrl, cmd);
   1008 }
   1009 
   1010 
   1011 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
   1012 				  char *argv[])
   1013 {
   1014 	char cmd[256];
   1015 	int res;
   1016 
   1017 	if (argc != 1) {
   1018 		printf("Invalid WPS_ER_PBC command: need one argument:\n"
   1019 		       "- UUID: Specify the Enrollee\n");
   1020 		return -1;
   1021 	}
   1022 
   1023 	res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
   1024 			  argv[0]);
   1025 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1026 		printf("Too long WPS_ER_PBC command.\n");
   1027 		return -1;
   1028 	}
   1029 	return wpa_ctrl_command(ctrl, cmd);
   1030 }
   1031 
   1032 
   1033 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
   1034 				    char *argv[])
   1035 {
   1036 	char cmd[256];
   1037 	int res;
   1038 
   1039 	if (argc != 2) {
   1040 		printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
   1041 		       "- UUID: specify which AP to use\n"
   1042 		       "- PIN: AP PIN\n");
   1043 		return -1;
   1044 	}
   1045 
   1046 	res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
   1047 			  argv[0], argv[1]);
   1048 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1049 		printf("Too long WPS_ER_LEARN command.\n");
   1050 		return -1;
   1051 	}
   1052 	return wpa_ctrl_command(ctrl, cmd);
   1053 }
   1054 
   1055 
   1056 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
   1057 					 char *argv[])
   1058 {
   1059 	char cmd[256];
   1060 	int res;
   1061 
   1062 	if (argc != 2) {
   1063 		printf("Invalid WPS_ER_SET_CONFIG command: need two "
   1064 		       "arguments:\n"
   1065 		       "- UUID: specify which AP to use\n"
   1066 		       "- Network configuration id\n");
   1067 		return -1;
   1068 	}
   1069 
   1070 	res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
   1071 			  argv[0], argv[1]);
   1072 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1073 		printf("Too long WPS_ER_SET_CONFIG command.\n");
   1074 		return -1;
   1075 	}
   1076 	return wpa_ctrl_command(ctrl, cmd);
   1077 }
   1078 
   1079 
   1080 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
   1081 				     char *argv[])
   1082 {
   1083 	char cmd[256];
   1084 	int res;
   1085 
   1086 	if (argc == 5 || argc == 6) {
   1087 		char ssid_hex[2 * 32 + 1];
   1088 		char key_hex[2 * 64 + 1];
   1089 		int i;
   1090 
   1091 		ssid_hex[0] = '\0';
   1092 		for (i = 0; i < 32; i++) {
   1093 			if (argv[2][i] == '\0')
   1094 				break;
   1095 			os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
   1096 		}
   1097 
   1098 		key_hex[0] = '\0';
   1099 		if (argc == 6) {
   1100 			for (i = 0; i < 64; i++) {
   1101 				if (argv[5][i] == '\0')
   1102 					break;
   1103 				os_snprintf(&key_hex[i * 2], 3, "%02x",
   1104 					    argv[5][i]);
   1105 			}
   1106 		}
   1107 
   1108 		res = os_snprintf(cmd, sizeof(cmd),
   1109 				  "WPS_ER_CONFIG %s %s %s %s %s %s",
   1110 				  argv[0], argv[1], ssid_hex, argv[3], argv[4],
   1111 				  key_hex);
   1112 	} else {
   1113 		printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
   1114 		       "- AP UUID\n"
   1115 		       "- AP PIN\n"
   1116 		       "- new SSID\n"
   1117 		       "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
   1118 		       "- new encr (NONE, WEP, TKIP, CCMP)\n"
   1119 		       "- new key\n");
   1120 		return -1;
   1121 	}
   1122 
   1123 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1124 		printf("Too long WPS_ER_CONFIG command.\n");
   1125 		return -1;
   1126 	}
   1127 	return wpa_ctrl_command(ctrl, cmd);
   1128 }
   1129 
   1130 
   1131 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1132 {
   1133 	char cmd[256];
   1134 	int res;
   1135 
   1136 	if (argc != 1) {
   1137 		printf("Invalid IBSS_RSN command: needs one argument "
   1138 		       "(Peer STA MAC address)\n");
   1139 		return -1;
   1140 	}
   1141 
   1142 	res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
   1143 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1144 		printf("Too long IBSS_RSN command.\n");
   1145 		return -1;
   1146 	}
   1147 	return wpa_ctrl_command(ctrl, cmd);
   1148 }
   1149 
   1150 
   1151 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1152 {
   1153 	char cmd[256];
   1154 	int res;
   1155 
   1156 	if (argc != 1) {
   1157 		printf("Invalid LEVEL command: needs one argument (debug "
   1158 		       "level)\n");
   1159 		return -1;
   1160 	}
   1161 	res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
   1162 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1163 		printf("Too long LEVEL command.\n");
   1164 		return -1;
   1165 	}
   1166 	return wpa_ctrl_command(ctrl, cmd);
   1167 }
   1168 
   1169 
   1170 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1171 {
   1172 	char cmd[256], *pos, *end;
   1173 	int i, ret;
   1174 
   1175 	if (argc < 2) {
   1176 		printf("Invalid IDENTITY command: needs two arguments "
   1177 		       "(network id and identity)\n");
   1178 		return -1;
   1179 	}
   1180 
   1181 	end = cmd + sizeof(cmd);
   1182 	pos = cmd;
   1183 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
   1184 			  argv[0], argv[1]);
   1185 	if (ret < 0 || ret >= end - pos) {
   1186 		printf("Too long IDENTITY command.\n");
   1187 		return -1;
   1188 	}
   1189 	pos += ret;
   1190 	for (i = 2; i < argc; i++) {
   1191 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1192 		if (ret < 0 || ret >= end - pos) {
   1193 			printf("Too long IDENTITY command.\n");
   1194 			return -1;
   1195 		}
   1196 		pos += ret;
   1197 	}
   1198 
   1199 	return wpa_ctrl_command(ctrl, cmd);
   1200 }
   1201 
   1202 
   1203 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1204 {
   1205 	char cmd[256], *pos, *end;
   1206 	int i, ret;
   1207 
   1208 	if (argc < 2) {
   1209 		printf("Invalid PASSWORD command: needs two arguments "
   1210 		       "(network id and password)\n");
   1211 		return -1;
   1212 	}
   1213 
   1214 	end = cmd + sizeof(cmd);
   1215 	pos = cmd;
   1216 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
   1217 			  argv[0], argv[1]);
   1218 	if (ret < 0 || ret >= end - pos) {
   1219 		printf("Too long PASSWORD command.\n");
   1220 		return -1;
   1221 	}
   1222 	pos += ret;
   1223 	for (i = 2; i < argc; i++) {
   1224 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1225 		if (ret < 0 || ret >= end - pos) {
   1226 			printf("Too long PASSWORD command.\n");
   1227 			return -1;
   1228 		}
   1229 		pos += ret;
   1230 	}
   1231 
   1232 	return wpa_ctrl_command(ctrl, cmd);
   1233 }
   1234 
   1235 
   1236 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
   1237 				    char *argv[])
   1238 {
   1239 	char cmd[256], *pos, *end;
   1240 	int i, ret;
   1241 
   1242 	if (argc < 2) {
   1243 		printf("Invalid NEW_PASSWORD command: needs two arguments "
   1244 		       "(network id and password)\n");
   1245 		return -1;
   1246 	}
   1247 
   1248 	end = cmd + sizeof(cmd);
   1249 	pos = cmd;
   1250 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
   1251 			  argv[0], argv[1]);
   1252 	if (ret < 0 || ret >= end - pos) {
   1253 		printf("Too long NEW_PASSWORD command.\n");
   1254 		return -1;
   1255 	}
   1256 	pos += ret;
   1257 	for (i = 2; i < argc; i++) {
   1258 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1259 		if (ret < 0 || ret >= end - pos) {
   1260 			printf("Too long NEW_PASSWORD command.\n");
   1261 			return -1;
   1262 		}
   1263 		pos += ret;
   1264 	}
   1265 
   1266 	return wpa_ctrl_command(ctrl, cmd);
   1267 }
   1268 
   1269 
   1270 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1271 {
   1272 	char cmd[256], *pos, *end;
   1273 	int i, ret;
   1274 
   1275 	if (argc < 2) {
   1276 		printf("Invalid PIN command: needs two arguments "
   1277 		       "(network id and pin)\n");
   1278 		return -1;
   1279 	}
   1280 
   1281 	end = cmd + sizeof(cmd);
   1282 	pos = cmd;
   1283 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
   1284 			  argv[0], argv[1]);
   1285 	if (ret < 0 || ret >= end - pos) {
   1286 		printf("Too long PIN command.\n");
   1287 		return -1;
   1288 	}
   1289 	pos += ret;
   1290 	for (i = 2; i < argc; i++) {
   1291 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1292 		if (ret < 0 || ret >= end - pos) {
   1293 			printf("Too long PIN command.\n");
   1294 			return -1;
   1295 		}
   1296 		pos += ret;
   1297 	}
   1298 	return wpa_ctrl_command(ctrl, cmd);
   1299 }
   1300 
   1301 
   1302 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1303 {
   1304 	char cmd[256], *pos, *end;
   1305 	int i, ret;
   1306 
   1307 	if (argc < 2) {
   1308 		printf("Invalid OTP command: needs two arguments (network "
   1309 		       "id and password)\n");
   1310 		return -1;
   1311 	}
   1312 
   1313 	end = cmd + sizeof(cmd);
   1314 	pos = cmd;
   1315 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
   1316 			  argv[0], argv[1]);
   1317 	if (ret < 0 || ret >= end - pos) {
   1318 		printf("Too long OTP command.\n");
   1319 		return -1;
   1320 	}
   1321 	pos += ret;
   1322 	for (i = 2; i < argc; i++) {
   1323 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1324 		if (ret < 0 || ret >= end - pos) {
   1325 			printf("Too long OTP command.\n");
   1326 			return -1;
   1327 		}
   1328 		pos += ret;
   1329 	}
   1330 
   1331 	return wpa_ctrl_command(ctrl, cmd);
   1332 }
   1333 
   1334 
   1335 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
   1336 				  char *argv[])
   1337 {
   1338 	char cmd[256], *pos, *end;
   1339 	int i, ret;
   1340 
   1341 	if (argc < 2) {
   1342 		printf("Invalid PASSPHRASE command: needs two arguments "
   1343 		       "(network id and passphrase)\n");
   1344 		return -1;
   1345 	}
   1346 
   1347 	end = cmd + sizeof(cmd);
   1348 	pos = cmd;
   1349 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
   1350 			  argv[0], argv[1]);
   1351 	if (ret < 0 || ret >= end - pos) {
   1352 		printf("Too long PASSPHRASE command.\n");
   1353 		return -1;
   1354 	}
   1355 	pos += ret;
   1356 	for (i = 2; i < argc; i++) {
   1357 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1358 		if (ret < 0 || ret >= end - pos) {
   1359 			printf("Too long PASSPHRASE command.\n");
   1360 			return -1;
   1361 		}
   1362 		pos += ret;
   1363 	}
   1364 
   1365 	return wpa_ctrl_command(ctrl, cmd);
   1366 }
   1367 
   1368 
   1369 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1370 {
   1371 	char cmd[256], *pos, *end;
   1372 	int i, ret;
   1373 
   1374 	if (argc < 2) {
   1375 		printf("Invalid BSSID command: needs two arguments (network "
   1376 		       "id and BSSID)\n");
   1377 		return -1;
   1378 	}
   1379 
   1380 	end = cmd + sizeof(cmd);
   1381 	pos = cmd;
   1382 	ret = os_snprintf(pos, end - pos, "BSSID");
   1383 	if (ret < 0 || ret >= end - pos) {
   1384 		printf("Too long BSSID command.\n");
   1385 		return -1;
   1386 	}
   1387 	pos += ret;
   1388 	for (i = 0; i < argc; i++) {
   1389 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1390 		if (ret < 0 || ret >= end - pos) {
   1391 			printf("Too long BSSID command.\n");
   1392 			return -1;
   1393 		}
   1394 		pos += ret;
   1395 	}
   1396 
   1397 	return wpa_ctrl_command(ctrl, cmd);
   1398 }
   1399 
   1400 
   1401 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1402 {
   1403 	char cmd[256], *pos, *end;
   1404 	int i, ret;
   1405 
   1406 	end = cmd + sizeof(cmd);
   1407 	pos = cmd;
   1408 	ret = os_snprintf(pos, end - pos, "BLACKLIST");
   1409 	if (ret < 0 || ret >= end - pos) {
   1410 		printf("Too long BLACKLIST command.\n");
   1411 		return -1;
   1412 	}
   1413 	pos += ret;
   1414 	for (i = 0; i < argc; i++) {
   1415 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1416 		if (ret < 0 || ret >= end - pos) {
   1417 			printf("Too long BLACKLIST command.\n");
   1418 			return -1;
   1419 		}
   1420 		pos += ret;
   1421 	}
   1422 
   1423 	return wpa_ctrl_command(ctrl, cmd);
   1424 }
   1425 
   1426 
   1427 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1428 {
   1429 	char cmd[256], *pos, *end;
   1430 	int i, ret;
   1431 
   1432 	end = cmd + sizeof(cmd);
   1433 	pos = cmd;
   1434 	ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
   1435 	if (ret < 0 || ret >= end - pos) {
   1436 		printf("Too long LOG_LEVEL command.\n");
   1437 		return -1;
   1438 	}
   1439 	pos += ret;
   1440 	for (i = 0; i < argc; i++) {
   1441 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1442 		if (ret < 0 || ret >= end - pos) {
   1443 			printf("Too long LOG_LEVEL command.\n");
   1444 			return -1;
   1445 		}
   1446 		pos += ret;
   1447 	}
   1448 
   1449 	return wpa_ctrl_command(ctrl, cmd);
   1450 }
   1451 
   1452 
   1453 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
   1454 				     char *argv[])
   1455 {
   1456 	return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
   1457 }
   1458 
   1459 
   1460 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
   1461 				      char *argv[])
   1462 {
   1463 	char cmd[32];
   1464 	int res;
   1465 
   1466 	if (argc < 1) {
   1467 		printf("Invalid SELECT_NETWORK command: needs one argument "
   1468 		       "(network id)\n");
   1469 		return -1;
   1470 	}
   1471 
   1472 	res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
   1473 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1474 		return -1;
   1475 	cmd[sizeof(cmd) - 1] = '\0';
   1476 
   1477 	return wpa_ctrl_command(ctrl, cmd);
   1478 }
   1479 
   1480 
   1481 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
   1482 				      char *argv[])
   1483 {
   1484 	char cmd[32];
   1485 	int res;
   1486 
   1487 	if (argc < 1) {
   1488 		printf("Invalid ENABLE_NETWORK command: needs one argument "
   1489 		       "(network id)\n");
   1490 		return -1;
   1491 	}
   1492 
   1493 	res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
   1494 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1495 		return -1;
   1496 	cmd[sizeof(cmd) - 1] = '\0';
   1497 
   1498 	return wpa_ctrl_command(ctrl, cmd);
   1499 }
   1500 
   1501 
   1502 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
   1503 				       char *argv[])
   1504 {
   1505 	char cmd[32];
   1506 	int res;
   1507 
   1508 	if (argc < 1) {
   1509 		printf("Invalid DISABLE_NETWORK command: needs one argument "
   1510 		       "(network id)\n");
   1511 		return -1;
   1512 	}
   1513 
   1514 	res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
   1515 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1516 		return -1;
   1517 	cmd[sizeof(cmd) - 1] = '\0';
   1518 
   1519 	return wpa_ctrl_command(ctrl, cmd);
   1520 }
   1521 
   1522 
   1523 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
   1524 				   char *argv[])
   1525 {
   1526 	return wpa_ctrl_command(ctrl, "ADD_NETWORK");
   1527 }
   1528 
   1529 
   1530 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
   1531 				      char *argv[])
   1532 {
   1533 	char cmd[32];
   1534 	int res;
   1535 
   1536 	if (argc < 1) {
   1537 		printf("Invalid REMOVE_NETWORK command: needs one argument "
   1538 		       "(network id)\n");
   1539 		return -1;
   1540 	}
   1541 
   1542 	res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
   1543 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1544 		return -1;
   1545 	cmd[sizeof(cmd) - 1] = '\0';
   1546 
   1547 	return wpa_ctrl_command(ctrl, cmd);
   1548 }
   1549 
   1550 
   1551 static void wpa_cli_show_network_variables(void)
   1552 {
   1553 	printf("set_network variables:\n"
   1554 	       "  ssid (network name, SSID)\n"
   1555 	       "  psk (WPA passphrase or pre-shared key)\n"
   1556 	       "  key_mgmt (key management protocol)\n"
   1557 	       "  identity (EAP identity)\n"
   1558 	       "  password (EAP password)\n"
   1559 	       "  ...\n"
   1560 	       "\n"
   1561 	       "Note: Values are entered in the same format as the "
   1562 	       "configuration file is using,\n"
   1563 	       "i.e., strings values need to be inside double quotation "
   1564 	       "marks.\n"
   1565 	       "For example: set_network 1 ssid \"network name\"\n"
   1566 	       "\n"
   1567 	       "Please see wpa_supplicant.conf documentation for full list "
   1568 	       "of\navailable variables.\n");
   1569 }
   1570 
   1571 
   1572 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
   1573 				   char *argv[])
   1574 {
   1575 	char cmd[256];
   1576 	int res;
   1577 
   1578 	if (argc == 0) {
   1579 		wpa_cli_show_network_variables();
   1580 		return 0;
   1581 	}
   1582 
   1583 	if (argc != 3) {
   1584 		printf("Invalid SET_NETWORK command: needs three arguments\n"
   1585 		       "(network id, variable name, and value)\n");
   1586 		return -1;
   1587 	}
   1588 
   1589 	res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
   1590 			  argv[0], argv[1], argv[2]);
   1591 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1592 		printf("Too long SET_NETWORK command.\n");
   1593 		return -1;
   1594 	}
   1595 	return wpa_ctrl_command(ctrl, cmd);
   1596 }
   1597 
   1598 
   1599 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
   1600 				   char *argv[])
   1601 {
   1602 	char cmd[256];
   1603 	int res;
   1604 
   1605 	if (argc == 0) {
   1606 		wpa_cli_show_network_variables();
   1607 		return 0;
   1608 	}
   1609 
   1610 	if (argc != 2) {
   1611 		printf("Invalid GET_NETWORK command: needs two arguments\n"
   1612 		       "(network id and variable name)\n");
   1613 		return -1;
   1614 	}
   1615 
   1616 	res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
   1617 			  argv[0], argv[1]);
   1618 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1619 		printf("Too long GET_NETWORK command.\n");
   1620 		return -1;
   1621 	}
   1622 	return wpa_ctrl_command(ctrl, cmd);
   1623 }
   1624 
   1625 
   1626 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
   1627 				  char *argv[])
   1628 {
   1629 	return wpa_ctrl_command(ctrl, "DISCONNECT");
   1630 }
   1631 
   1632 
   1633 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
   1634 				  char *argv[])
   1635 {
   1636 	return wpa_ctrl_command(ctrl, "RECONNECT");
   1637 }
   1638 
   1639 
   1640 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
   1641 				   char *argv[])
   1642 {
   1643 	return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
   1644 }
   1645 
   1646 
   1647 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1648 {
   1649 	return wpa_ctrl_command(ctrl, "SCAN");
   1650 }
   1651 
   1652 
   1653 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
   1654 				    char *argv[])
   1655 {
   1656 	return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
   1657 }
   1658 
   1659 
   1660 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1661 {
   1662 	char cmd[64];
   1663 	int res;
   1664 
   1665 	if (argc < 1) {
   1666 		printf("Invalid BSS command: need at least one argument"
   1667 		       "(index or BSSID)\n");
   1668 		return -1;
   1669 	}
   1670 
   1671 	res = os_snprintf(cmd, sizeof(cmd), "BSS %s\t%s\t%s", argv[0],
   1672 			  argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "");
   1673 
   1674 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1675 		return -1;
   1676 	cmd[sizeof(cmd) - 1] = '\0';
   1677 
   1678 	return wpa_ctrl_command(ctrl, cmd);
   1679 }
   1680 
   1681 
   1682 static char ** wpa_cli_complete_bss(const char *str, int pos)
   1683 {
   1684 	int arg = get_cmd_arg_num(str, pos);
   1685 	char **res = NULL;
   1686 
   1687 	switch (arg) {
   1688 	case 1:
   1689 		res = cli_txt_list_array(&bsses);
   1690 		break;
   1691 	}
   1692 
   1693 	return res;
   1694 }
   1695 
   1696 
   1697 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
   1698 				      char *argv[])
   1699 {
   1700 	char cmd[64];
   1701 	int res;
   1702 
   1703 	if (argc < 1 || argc > 2) {
   1704 		printf("Invalid GET_CAPABILITY command: need either one or "
   1705 		       "two arguments\n");
   1706 		return -1;
   1707 	}
   1708 
   1709 	if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
   1710 		printf("Invalid GET_CAPABILITY command: second argument, "
   1711 		       "if any, must be 'strict'\n");
   1712 		return -1;
   1713 	}
   1714 
   1715 	res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
   1716 			  (argc == 2) ? " strict" : "");
   1717 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1718 		return -1;
   1719 	cmd[sizeof(cmd) - 1] = '\0';
   1720 
   1721 	return wpa_ctrl_command(ctrl, cmd);
   1722 }
   1723 
   1724 
   1725 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
   1726 {
   1727 	printf("Available interfaces:\n");
   1728 	return wpa_ctrl_command(ctrl, "INTERFACES");
   1729 }
   1730 
   1731 
   1732 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1733 {
   1734 	if (argc < 1) {
   1735 		wpa_cli_list_interfaces(ctrl);
   1736 		return 0;
   1737 	}
   1738 
   1739 	wpa_cli_close_connection();
   1740 	os_free(ctrl_ifname);
   1741 	ctrl_ifname = os_strdup(argv[0]);
   1742 
   1743 	if (wpa_cli_open_connection(ctrl_ifname, 1)) {
   1744 		printf("Connected to interface '%s.\n", ctrl_ifname);
   1745 	} else {
   1746 		printf("Could not connect to interface '%s' - re-trying\n",
   1747 		       ctrl_ifname);
   1748 	}
   1749 	return 0;
   1750 }
   1751 
   1752 
   1753 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
   1754 				   char *argv[])
   1755 {
   1756 	return wpa_ctrl_command(ctrl, "RECONFIGURE");
   1757 }
   1758 
   1759 
   1760 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
   1761 				 char *argv[])
   1762 {
   1763 	return wpa_ctrl_command(ctrl, "TERMINATE");
   1764 }
   1765 
   1766 
   1767 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
   1768 				     char *argv[])
   1769 {
   1770 	char cmd[256];
   1771 	int res;
   1772 
   1773 	if (argc < 1) {
   1774 		printf("Invalid INTERFACE_ADD command: needs at least one "
   1775 		       "argument (interface name)\n"
   1776 		       "All arguments: ifname confname driver ctrl_interface "
   1777 		       "driver_param bridge_name\n");
   1778 		return -1;
   1779 	}
   1780 
   1781 	/*
   1782 	 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
   1783 	 * <driver_param>TAB<bridge_name>
   1784 	 */
   1785 	res = os_snprintf(cmd, sizeof(cmd),
   1786 			  "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
   1787 			  argv[0],
   1788 			  argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
   1789 			  argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
   1790 			  argc > 5 ? argv[5] : "");
   1791 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1792 		return -1;
   1793 	cmd[sizeof(cmd) - 1] = '\0';
   1794 	return wpa_ctrl_command(ctrl, cmd);
   1795 }
   1796 
   1797 
   1798 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
   1799 					char *argv[])
   1800 {
   1801 	char cmd[128];
   1802 	int res;
   1803 
   1804 	if (argc != 1) {
   1805 		printf("Invalid INTERFACE_REMOVE command: needs one argument "
   1806 		       "(interface name)\n");
   1807 		return -1;
   1808 	}
   1809 
   1810 	res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
   1811 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1812 		return -1;
   1813 	cmd[sizeof(cmd) - 1] = '\0';
   1814 	return wpa_ctrl_command(ctrl, cmd);
   1815 }
   1816 
   1817 
   1818 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
   1819 				      char *argv[])
   1820 {
   1821 	return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
   1822 }
   1823 
   1824 
   1825 #ifdef CONFIG_AP
   1826 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1827 {
   1828 	char buf[64];
   1829 	if (argc != 1) {
   1830 		printf("Invalid 'sta' command - exactly one argument, STA "
   1831 		       "address, is required.\n");
   1832 		return -1;
   1833 	}
   1834 	os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
   1835 	return wpa_ctrl_command(ctrl, buf);
   1836 }
   1837 
   1838 
   1839 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
   1840 				char *addr, size_t addr_len)
   1841 {
   1842 	char buf[4096], *pos;
   1843 	size_t len;
   1844 	int ret;
   1845 
   1846 	if (ctrl_conn == NULL) {
   1847 		printf("Not connected to hostapd - command dropped.\n");
   1848 		return -1;
   1849 	}
   1850 	len = sizeof(buf) - 1;
   1851 	ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
   1852 			       wpa_cli_msg_cb);
   1853 	if (ret == -2) {
   1854 		printf("'%s' command timed out.\n", cmd);
   1855 		return -2;
   1856 	} else if (ret < 0) {
   1857 		printf("'%s' command failed.\n", cmd);
   1858 		return -1;
   1859 	}
   1860 
   1861 	buf[len] = '\0';
   1862 	if (memcmp(buf, "FAIL", 4) == 0)
   1863 		return -1;
   1864 	printf("%s", buf);
   1865 
   1866 	pos = buf;
   1867 	while (*pos != '\0' && *pos != '\n')
   1868 		pos++;
   1869 	*pos = '\0';
   1870 	os_strlcpy(addr, buf, addr_len);
   1871 	return 0;
   1872 }
   1873 
   1874 
   1875 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1876 {
   1877 	char addr[32], cmd[64];
   1878 
   1879 	if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
   1880 		return 0;
   1881 	do {
   1882 		os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
   1883 	} while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
   1884 
   1885 	return -1;
   1886 }
   1887 #endif /* CONFIG_AP */
   1888 
   1889 
   1890 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1891 {
   1892 	return wpa_ctrl_command(ctrl, "SUSPEND");
   1893 }
   1894 
   1895 
   1896 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1897 {
   1898 	return wpa_ctrl_command(ctrl, "RESUME");
   1899 }
   1900 
   1901 
   1902 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1903 {
   1904 	return wpa_ctrl_command(ctrl, "DROP_SA");
   1905 }
   1906 
   1907 
   1908 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1909 {
   1910 	char cmd[128];
   1911 	int res;
   1912 
   1913 	if (argc != 1) {
   1914 		printf("Invalid ROAM command: needs one argument "
   1915 		       "(target AP's BSSID)\n");
   1916 		return -1;
   1917 	}
   1918 
   1919 	res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
   1920 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1921 		printf("Too long ROAM command.\n");
   1922 		return -1;
   1923 	}
   1924 	return wpa_ctrl_command(ctrl, cmd);
   1925 }
   1926 
   1927 
   1928 #ifdef CONFIG_P2P
   1929 
   1930 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1931 {
   1932 	char cmd[128];
   1933 	int res;
   1934 
   1935 	if (argc == 0)
   1936 		return wpa_ctrl_command(ctrl, "P2P_FIND");
   1937 
   1938 	if (argc > 2)
   1939 		res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s",
   1940 				  argv[0], argv[1], argv[2]);
   1941 	else if (argc > 1)
   1942 		res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
   1943 				  argv[0], argv[1]);
   1944 	else
   1945 		res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
   1946 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1947 		return -1;
   1948 	cmd[sizeof(cmd) - 1] = '\0';
   1949 	return wpa_ctrl_command(ctrl, cmd);
   1950 }
   1951 
   1952 
   1953 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
   1954 				     char *argv[])
   1955 {
   1956 	return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
   1957 }
   1958 
   1959 
   1960 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
   1961 				   char *argv[])
   1962 {
   1963 	char cmd[128];
   1964 	int res;
   1965 
   1966 	if (argc < 2) {
   1967 		printf("Invalid P2P_CONNECT command: needs at least two "
   1968 		       "arguments (address and pbc/PIN)\n");
   1969 		return -1;
   1970 	}
   1971 
   1972 	if (argc > 4)
   1973 		res = os_snprintf(cmd, sizeof(cmd),
   1974 				  "P2P_CONNECT %s %s %s %s %s",
   1975 				  argv[0], argv[1], argv[2], argv[3],
   1976 				  argv[4]);
   1977 	else if (argc > 3)
   1978 		res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
   1979 				  argv[0], argv[1], argv[2], argv[3]);
   1980 	else if (argc > 2)
   1981 		res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
   1982 				  argv[0], argv[1], argv[2]);
   1983 	else
   1984 		res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
   1985 				  argv[0], argv[1]);
   1986 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1987 		return -1;
   1988 	cmd[sizeof(cmd) - 1] = '\0';
   1989 	return wpa_ctrl_command(ctrl, cmd);
   1990 }
   1991 
   1992 
   1993 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
   1994 {
   1995 	int arg = get_cmd_arg_num(str, pos);
   1996 	char **res = NULL;
   1997 
   1998 	switch (arg) {
   1999 	case 1:
   2000 		res = cli_txt_list_array(&p2p_peers);
   2001 		break;
   2002 	}
   2003 
   2004 	return res;
   2005 }
   2006 
   2007 
   2008 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
   2009 				  char *argv[])
   2010 {
   2011 	char cmd[128];
   2012 	int res;
   2013 
   2014 	if (argc == 0)
   2015 		return wpa_ctrl_command(ctrl, "P2P_LISTEN");
   2016 
   2017 	res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
   2018 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2019 		return -1;
   2020 	cmd[sizeof(cmd) - 1] = '\0';
   2021 	return wpa_ctrl_command(ctrl, cmd);
   2022 }
   2023 
   2024 
   2025 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
   2026 					char *argv[])
   2027 {
   2028 	char cmd[128];
   2029 	int res;
   2030 
   2031 	if (argc != 1) {
   2032 		printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
   2033 		       "(interface name)\n");
   2034 		return -1;
   2035 	}
   2036 
   2037 	res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
   2038 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2039 		return -1;
   2040 	cmd[sizeof(cmd) - 1] = '\0';
   2041 	return wpa_ctrl_command(ctrl, cmd);
   2042 }
   2043 
   2044 
   2045 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
   2046 {
   2047 	int arg = get_cmd_arg_num(str, pos);
   2048 	char **res = NULL;
   2049 
   2050 	switch (arg) {
   2051 	case 1:
   2052 		res = cli_txt_list_array(&p2p_groups);
   2053 		break;
   2054 	}
   2055 
   2056 	return res;
   2057 }
   2058 
   2059 
   2060 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
   2061 					char *argv[])
   2062 {
   2063 	char cmd[128];
   2064 	int res;
   2065 
   2066 	if (argc == 0)
   2067 		return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
   2068 
   2069 	if (argc > 1)
   2070 		res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
   2071 				  argv[0], argv[1]);
   2072 	else
   2073 		res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
   2074 				  argv[0]);
   2075 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2076 		return -1;
   2077 	cmd[sizeof(cmd) - 1] = '\0';
   2078 	return wpa_ctrl_command(ctrl, cmd);
   2079 }
   2080 
   2081 
   2082 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
   2083 				     char *argv[])
   2084 {
   2085 	char cmd[128];
   2086 	int res;
   2087 
   2088 	if (argc != 2 && argc != 3) {
   2089 		printf("Invalid P2P_PROV_DISC command: needs at least "
   2090 		       "two arguments, address and config method\n"
   2091 		       "(display, keypad, or pbc) and an optional join\n");
   2092 		return -1;
   2093 	}
   2094 
   2095 	if (argc == 3)
   2096 		res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
   2097 				  argv[0], argv[1], argv[2]);
   2098 	else
   2099 		res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
   2100 				  argv[0], argv[1]);
   2101 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2102 		return -1;
   2103 	cmd[sizeof(cmd) - 1] = '\0';
   2104 	return wpa_ctrl_command(ctrl, cmd);
   2105 }
   2106 
   2107 
   2108 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
   2109 					  char *argv[])
   2110 {
   2111 	return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
   2112 }
   2113 
   2114 
   2115 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
   2116 					 char *argv[])
   2117 {
   2118 	char cmd[4096];
   2119 	int res;
   2120 
   2121 	if (argc != 2 && argc != 4) {
   2122 		printf("Invalid P2P_SERV_DISC_REQ command: needs two "
   2123 		       "arguments (address and TLVs) or four arguments "
   2124 		       "(address, \"upnp\", version, search target "
   2125 		       "(SSDP ST:)\n");
   2126 		return -1;
   2127 	}
   2128 
   2129 	if (argc == 4)
   2130 		res = os_snprintf(cmd, sizeof(cmd),
   2131 				  "P2P_SERV_DISC_REQ %s %s %s %s",
   2132 				  argv[0], argv[1], argv[2], argv[3]);
   2133 	else
   2134 		res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
   2135 				  argv[0], argv[1]);
   2136 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2137 		return -1;
   2138 	cmd[sizeof(cmd) - 1] = '\0';
   2139 	return wpa_ctrl_command(ctrl, cmd);
   2140 }
   2141 
   2142 
   2143 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
   2144 						int argc, char *argv[])
   2145 {
   2146 	char cmd[128];
   2147 	int res;
   2148 
   2149 	if (argc != 1) {
   2150 		printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
   2151 		       "argument (pending request identifier)\n");
   2152 		return -1;
   2153 	}
   2154 
   2155 	res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
   2156 			  argv[0]);
   2157 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2158 		return -1;
   2159 	cmd[sizeof(cmd) - 1] = '\0';
   2160 	return wpa_ctrl_command(ctrl, cmd);
   2161 }
   2162 
   2163 
   2164 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
   2165 					  char *argv[])
   2166 {
   2167 	char cmd[4096];
   2168 	int res;
   2169 
   2170 	if (argc != 4) {
   2171 		printf("Invalid P2P_SERV_DISC_RESP command: needs four "
   2172 		       "arguments (freq, address, dialog token, and TLVs)\n");
   2173 		return -1;
   2174 	}
   2175 
   2176 	res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
   2177 			  argv[0], argv[1], argv[2], argv[3]);
   2178 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2179 		return -1;
   2180 	cmd[sizeof(cmd) - 1] = '\0';
   2181 	return wpa_ctrl_command(ctrl, cmd);
   2182 }
   2183 
   2184 
   2185 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
   2186 					  char *argv[])
   2187 {
   2188 	return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
   2189 }
   2190 
   2191 
   2192 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
   2193 					      int argc, char *argv[])
   2194 {
   2195 	char cmd[128];
   2196 	int res;
   2197 
   2198 	if (argc != 1) {
   2199 		printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
   2200 		       "argument (external processing: 0/1)\n");
   2201 		return -1;
   2202 	}
   2203 
   2204 	res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
   2205 			  argv[0]);
   2206 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2207 		return -1;
   2208 	cmd[sizeof(cmd) - 1] = '\0';
   2209 	return wpa_ctrl_command(ctrl, cmd);
   2210 }
   2211 
   2212 
   2213 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
   2214 					 char *argv[])
   2215 {
   2216 	return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
   2217 }
   2218 
   2219 
   2220 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
   2221 				       char *argv[])
   2222 {
   2223 	char cmd[4096];
   2224 	int res;
   2225 
   2226 	if (argc != 3 && argc != 4) {
   2227 		printf("Invalid P2P_SERVICE_ADD command: needs three or four "
   2228 		       "arguments\n");
   2229 		return -1;
   2230 	}
   2231 
   2232 	if (argc == 4)
   2233 		res = os_snprintf(cmd, sizeof(cmd),
   2234 				  "P2P_SERVICE_ADD %s %s %s %s",
   2235 				  argv[0], argv[1], argv[2], argv[3]);
   2236 	else
   2237 		res = os_snprintf(cmd, sizeof(cmd),
   2238 				  "P2P_SERVICE_ADD %s %s %s",
   2239 				  argv[0], argv[1], argv[2]);
   2240 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2241 		return -1;
   2242 	cmd[sizeof(cmd) - 1] = '\0';
   2243 	return wpa_ctrl_command(ctrl, cmd);
   2244 }
   2245 
   2246 
   2247 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
   2248 				       char *argv[])
   2249 {
   2250 	char cmd[4096];
   2251 	int res;
   2252 
   2253 	if (argc != 2 && argc != 3) {
   2254 		printf("Invalid P2P_SERVICE_DEL command: needs two or three "
   2255 		       "arguments\n");
   2256 		return -1;
   2257 	}
   2258 
   2259 	if (argc == 3)
   2260 		res = os_snprintf(cmd, sizeof(cmd),
   2261 				  "P2P_SERVICE_DEL %s %s %s",
   2262 				  argv[0], argv[1], argv[2]);
   2263 	else
   2264 		res = os_snprintf(cmd, sizeof(cmd),
   2265 				  "P2P_SERVICE_DEL %s %s",
   2266 				  argv[0], argv[1]);
   2267 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2268 		return -1;
   2269 	cmd[sizeof(cmd) - 1] = '\0';
   2270 	return wpa_ctrl_command(ctrl, cmd);
   2271 }
   2272 
   2273 
   2274 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
   2275 				  int argc, char *argv[])
   2276 {
   2277 	char cmd[128];
   2278 	int res;
   2279 
   2280 	if (argc != 1) {
   2281 		printf("Invalid P2P_REJECT command: needs one argument "
   2282 		       "(peer address)\n");
   2283 		return -1;
   2284 	}
   2285 
   2286 	res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
   2287 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2288 		return -1;
   2289 	cmd[sizeof(cmd) - 1] = '\0';
   2290 	return wpa_ctrl_command(ctrl, cmd);
   2291 }
   2292 
   2293 
   2294 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
   2295 				  int argc, char *argv[])
   2296 {
   2297 	char cmd[128];
   2298 	int res;
   2299 
   2300 	if (argc < 1) {
   2301 		printf("Invalid P2P_INVITE command: needs at least one "
   2302 		       "argument\n");
   2303 		return -1;
   2304 	}
   2305 
   2306 	if (argc > 2)
   2307 		res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
   2308 				  argv[0], argv[1], argv[2]);
   2309 	else if (argc > 1)
   2310 		res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
   2311 				  argv[0], argv[1]);
   2312 	else
   2313 		res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
   2314 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2315 		return -1;
   2316 	cmd[sizeof(cmd) - 1] = '\0';
   2317 	return wpa_ctrl_command(ctrl, cmd);
   2318 }
   2319 
   2320 
   2321 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2322 {
   2323 	char buf[64];
   2324 	if (argc != 1) {
   2325 		printf("Invalid 'p2p_peer' command - exactly one argument, "
   2326 		       "P2P peer device address, is required.\n");
   2327 		return -1;
   2328 	}
   2329 	os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
   2330 	return wpa_ctrl_command(ctrl, buf);
   2331 }
   2332 
   2333 
   2334 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
   2335 {
   2336 	int arg = get_cmd_arg_num(str, pos);
   2337 	char **res = NULL;
   2338 
   2339 	switch (arg) {
   2340 	case 1:
   2341 		res = cli_txt_list_array(&p2p_peers);
   2342 		break;
   2343 	}
   2344 
   2345 	return res;
   2346 }
   2347 
   2348 
   2349 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
   2350 				     char *addr, size_t addr_len,
   2351 				     int discovered)
   2352 {
   2353 	char buf[4096], *pos;
   2354 	size_t len;
   2355 	int ret;
   2356 
   2357 	if (ctrl_conn == NULL)
   2358 		return -1;
   2359 	len = sizeof(buf) - 1;
   2360 	ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
   2361 			       wpa_cli_msg_cb);
   2362 	if (ret == -2) {
   2363 		printf("'%s' command timed out.\n", cmd);
   2364 		return -2;
   2365 	} else if (ret < 0) {
   2366 		printf("'%s' command failed.\n", cmd);
   2367 		return -1;
   2368 	}
   2369 
   2370 	buf[len] = '\0';
   2371 	if (memcmp(buf, "FAIL", 4) == 0)
   2372 		return -1;
   2373 
   2374 	pos = buf;
   2375 	while (*pos != '\0' && *pos != '\n')
   2376 		pos++;
   2377 	*pos++ = '\0';
   2378 	os_strlcpy(addr, buf, addr_len);
   2379 	if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
   2380 		printf("%s\n", addr);
   2381 	return 0;
   2382 }
   2383 
   2384 
   2385 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2386 {
   2387 	char addr[32], cmd[64];
   2388 	int discovered;
   2389 
   2390 	discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
   2391 
   2392 	if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
   2393 				      addr, sizeof(addr), discovered))
   2394 		return -1;
   2395 	do {
   2396 		os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
   2397 	} while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
   2398 			 discovered) == 0);
   2399 
   2400 	return 0;
   2401 }
   2402 
   2403 
   2404 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2405 {
   2406 	char cmd[100];
   2407 	int res;
   2408 
   2409 	if (argc != 2) {
   2410 		printf("Invalid P2P_SET command: needs two arguments (field, "
   2411 		       "value)\n");
   2412 		return -1;
   2413 	}
   2414 
   2415 	res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
   2416 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2417 		return -1;
   2418 	cmd[sizeof(cmd) - 1] = '\0';
   2419 	return wpa_ctrl_command(ctrl, cmd);
   2420 }
   2421 
   2422 
   2423 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2424 {
   2425 	return wpa_ctrl_command(ctrl, "P2P_FLUSH");
   2426 }
   2427 
   2428 
   2429 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
   2430 				  char *argv[])
   2431 {
   2432 	return wpa_ctrl_command(ctrl, "P2P_CANCEL");
   2433 }
   2434 
   2435 
   2436 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
   2437 				       char *argv[])
   2438 {
   2439 	char cmd[100];
   2440 	int res;
   2441 
   2442 	if (argc != 1) {
   2443 		printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
   2444 		       "(peer address)\n");
   2445 		return -1;
   2446 	}
   2447 
   2448 	res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
   2449 
   2450 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2451 		return -1;
   2452 
   2453 	cmd[sizeof(cmd) - 1] = '\0';
   2454 	return wpa_ctrl_command(ctrl, cmd);
   2455 }
   2456 
   2457 
   2458 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
   2459 					char *argv[])
   2460 {
   2461 	char cmd[100];
   2462 	int res;
   2463 
   2464 	if (argc != 0 && argc != 2 && argc != 4) {
   2465 		printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
   2466 		       "(preferred duration, interval; in microsecods).\n"
   2467 		       "Optional second pair can be used to provide "
   2468 		       "acceptable values.\n");
   2469 		return -1;
   2470 	}
   2471 
   2472 	if (argc == 4)
   2473 		res = os_snprintf(cmd, sizeof(cmd),
   2474 				  "P2P_PRESENCE_REQ %s %s %s %s",
   2475 				  argv[0], argv[1], argv[2], argv[3]);
   2476 	else if (argc == 2)
   2477 		res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
   2478 				  argv[0], argv[1]);
   2479 	else
   2480 		res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
   2481 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2482 		return -1;
   2483 	cmd[sizeof(cmd) - 1] = '\0';
   2484 	return wpa_ctrl_command(ctrl, cmd);
   2485 }
   2486 
   2487 
   2488 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
   2489 				      char *argv[])
   2490 {
   2491 	char cmd[100];
   2492 	int res;
   2493 
   2494 	if (argc != 0 && argc != 2) {
   2495 		printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
   2496 		       "(availability period, availability interval; in "
   2497 		       "millisecods).\n"
   2498 		       "Extended Listen Timing can be cancelled with this "
   2499 		       "command when used without parameters.\n");
   2500 		return -1;
   2501 	}
   2502 
   2503 	if (argc == 2)
   2504 		res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
   2505 				  argv[0], argv[1]);
   2506 	else
   2507 		res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
   2508 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2509 		return -1;
   2510 	cmd[sizeof(cmd) - 1] = '\0';
   2511 	return wpa_ctrl_command(ctrl, cmd);
   2512 }
   2513 
   2514 #endif /* CONFIG_P2P */
   2515 
   2516 
   2517 #ifdef CONFIG_INTERWORKING
   2518 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
   2519 				  char *argv[])
   2520 {
   2521 	return wpa_ctrl_command(ctrl, "FETCH_ANQP");
   2522 }
   2523 
   2524 
   2525 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
   2526 				       char *argv[])
   2527 {
   2528 	return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
   2529 }
   2530 
   2531 
   2532 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
   2533 					   char *argv[])
   2534 {
   2535 	char cmd[100];
   2536 	int res;
   2537 
   2538 	if (argc == 0)
   2539 		return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
   2540 
   2541 	res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
   2542 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2543 		return -1;
   2544 	cmd[sizeof(cmd) - 1] = '\0';
   2545 	return wpa_ctrl_command(ctrl, cmd);
   2546 }
   2547 
   2548 
   2549 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
   2550 					    char *argv[])
   2551 {
   2552 	char cmd[100];
   2553 	int res;
   2554 
   2555 	if (argc != 1) {
   2556 		printf("Invalid INTERWORKING_CONNECT commands: needs one "
   2557 		       "argument (BSSID)\n");
   2558 		return -1;
   2559 	}
   2560 
   2561 	res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
   2562 			  argv[0]);
   2563 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2564 		return -1;
   2565 	cmd[sizeof(cmd) - 1] = '\0';
   2566 	return wpa_ctrl_command(ctrl, cmd);
   2567 }
   2568 
   2569 
   2570 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2571 {
   2572 	char cmd[100];
   2573 	int res;
   2574 
   2575 	if (argc != 2) {
   2576 		printf("Invalid ANQP_GET command: needs two arguments "
   2577 		       "(addr and info id list)\n");
   2578 		return -1;
   2579 	}
   2580 
   2581 	res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
   2582 			  argv[0], argv[1]);
   2583 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2584 		return -1;
   2585 	cmd[sizeof(cmd) - 1] = '\0';
   2586 	return wpa_ctrl_command(ctrl, cmd);
   2587 }
   2588 #endif /* CONFIG_INTERWORKING */
   2589 
   2590 
   2591 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
   2592 				       char *argv[])
   2593 {
   2594 	char cmd[256];
   2595 	int res;
   2596 
   2597 	if (argc != 1) {
   2598 		printf("Invalid STA_AUTOCONNECT command: needs one argument "
   2599 		       "(0/1 = disable/enable automatic reconnection)\n");
   2600 		return -1;
   2601 	}
   2602 	res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
   2603 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   2604 		printf("Too long STA_AUTOCONNECT command.\n");
   2605 		return -1;
   2606 	}
   2607 	return wpa_ctrl_command(ctrl, cmd);
   2608 }
   2609 
   2610 
   2611 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
   2612 				     char *argv[])
   2613 {
   2614 	char cmd[256];
   2615 	int res;
   2616 
   2617 	if (argc != 1) {
   2618 		printf("Invalid TDLS_DISCOVER command: needs one argument "
   2619 		       "(Peer STA MAC address)\n");
   2620 		return -1;
   2621 	}
   2622 
   2623 	res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
   2624 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   2625 		printf("Too long TDLS_DISCOVER command.\n");
   2626 		return -1;
   2627 	}
   2628 	return wpa_ctrl_command(ctrl, cmd);
   2629 }
   2630 
   2631 
   2632 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
   2633 				  char *argv[])
   2634 {
   2635 	char cmd[256];
   2636 	int res;
   2637 
   2638 	if (argc != 1) {
   2639 		printf("Invalid TDLS_SETUP command: needs one argument "
   2640 		       "(Peer STA MAC address)\n");
   2641 		return -1;
   2642 	}
   2643 
   2644 	res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
   2645 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   2646 		printf("Too long TDLS_SETUP command.\n");
   2647 		return -1;
   2648 	}
   2649 	return wpa_ctrl_command(ctrl, cmd);
   2650 }
   2651 
   2652 
   2653 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
   2654 				     char *argv[])
   2655 {
   2656 	char cmd[256];
   2657 	int res;
   2658 
   2659 	if (argc != 1) {
   2660 		printf("Invalid TDLS_TEARDOWN command: needs one argument "
   2661 		       "(Peer STA MAC address)\n");
   2662 		return -1;
   2663 	}
   2664 
   2665 	res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
   2666 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   2667 		printf("Too long TDLS_TEARDOWN command.\n");
   2668 		return -1;
   2669 	}
   2670 	return wpa_ctrl_command(ctrl, cmd);
   2671 }
   2672 
   2673 
   2674 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
   2675 				   char *argv[])
   2676 {
   2677 	return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
   2678 }
   2679 
   2680 
   2681 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
   2682 				      char *argv[])
   2683 {
   2684 	return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
   2685 }
   2686 
   2687 #ifdef ANDROID
   2688 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2689 {
   2690 	char cmd[256];
   2691 	int i;
   2692 	int len;
   2693 
   2694 	if (argc < 1) {
   2695 		printf("Invalid DRIVER command: needs one argument (cmd)\n");
   2696 		return -1;
   2697 	}
   2698 
   2699 	len = os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
   2700 	for (i=1; i < argc; i++)
   2701 		len += os_snprintf(cmd + len, sizeof(cmd) - len, " %s", argv[i]);
   2702 	cmd[sizeof(cmd) - 1] = '\0';
   2703 	printf("%s: %s\n", __func__, cmd);
   2704 	return wpa_ctrl_command(ctrl, cmd);
   2705 }
   2706 #endif
   2707 
   2708 enum wpa_cli_cmd_flags {
   2709 	cli_cmd_flag_none		= 0x00,
   2710 	cli_cmd_flag_sensitive		= 0x01
   2711 };
   2712 
   2713 struct wpa_cli_cmd {
   2714 	const char *cmd;
   2715 	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
   2716 	enum wpa_cli_cmd_flags flags;
   2717 	const char *usage;
   2718 };
   2719 
   2720 static struct wpa_cli_cmd wpa_cli_commands[] = {
   2721 	{ "status", wpa_cli_cmd_status,
   2722 	  cli_cmd_flag_none,
   2723 	  "[verbose] = get current WPA/EAPOL/EAP status" },
   2724 	{ "ping", wpa_cli_cmd_ping,
   2725 	  cli_cmd_flag_none,
   2726 	  "= pings wpa_supplicant" },
   2727 	{ "relog", wpa_cli_cmd_relog,
   2728 	  cli_cmd_flag_none,
   2729 	  "= re-open log-file (allow rolling logs)" },
   2730 	{ "note", wpa_cli_cmd_note,
   2731 	  cli_cmd_flag_none,
   2732 	  "<text> = add a note to wpa_supplicant debug log" },
   2733 	{ "mib", wpa_cli_cmd_mib,
   2734 	  cli_cmd_flag_none,
   2735 	  "= get MIB variables (dot1x, dot11)" },
   2736 	{ "help", wpa_cli_cmd_help,
   2737 	  cli_cmd_flag_none,
   2738 	  "= show this usage help" },
   2739 	{ "interface", wpa_cli_cmd_interface,
   2740 	  cli_cmd_flag_none,
   2741 	  "[ifname] = show interfaces/select interface" },
   2742 	{ "level", wpa_cli_cmd_level,
   2743 	  cli_cmd_flag_none,
   2744 	  "<debug level> = change debug level" },
   2745 	{ "license", wpa_cli_cmd_license,
   2746 	  cli_cmd_flag_none,
   2747 	  "= show full wpa_cli license" },
   2748 	{ "quit", wpa_cli_cmd_quit,
   2749 	  cli_cmd_flag_none,
   2750 	  "= exit wpa_cli" },
   2751 	{ "set", wpa_cli_cmd_set,
   2752 	  cli_cmd_flag_none,
   2753 	  "= set variables (shows list of variables when run without "
   2754 	  "arguments)" },
   2755 	{ "get", wpa_cli_cmd_get,
   2756 	  cli_cmd_flag_none,
   2757 	  "<name> = get information" },
   2758 	{ "logon", wpa_cli_cmd_logon,
   2759 	  cli_cmd_flag_none,
   2760 	  "= IEEE 802.1X EAPOL state machine logon" },
   2761 	{ "logoff", wpa_cli_cmd_logoff,
   2762 	  cli_cmd_flag_none,
   2763 	  "= IEEE 802.1X EAPOL state machine logoff" },
   2764 	{ "pmksa", wpa_cli_cmd_pmksa,
   2765 	  cli_cmd_flag_none,
   2766 	  "= show PMKSA cache" },
   2767 	{ "reassociate", wpa_cli_cmd_reassociate,
   2768 	  cli_cmd_flag_none,
   2769 	  "= force reassociation" },
   2770 	{ "preauthenticate", wpa_cli_cmd_preauthenticate,
   2771 	  cli_cmd_flag_none,
   2772 	  "<BSSID> = force preauthentication" },
   2773 	{ "identity", wpa_cli_cmd_identity,
   2774 	  cli_cmd_flag_none,
   2775 	  "<network id> <identity> = configure identity for an SSID" },
   2776 	{ "password", wpa_cli_cmd_password,
   2777 	  cli_cmd_flag_sensitive,
   2778 	  "<network id> <password> = configure password for an SSID" },
   2779 	{ "new_password", wpa_cli_cmd_new_password,
   2780 	  cli_cmd_flag_sensitive,
   2781 	  "<network id> <password> = change password for an SSID" },
   2782 	{ "pin", wpa_cli_cmd_pin,
   2783 	  cli_cmd_flag_sensitive,
   2784 	  "<network id> <pin> = configure pin for an SSID" },
   2785 	{ "otp", wpa_cli_cmd_otp,
   2786 	  cli_cmd_flag_sensitive,
   2787 	  "<network id> <password> = configure one-time-password for an SSID"
   2788 	},
   2789 	{ "passphrase", wpa_cli_cmd_passphrase,
   2790 	  cli_cmd_flag_sensitive,
   2791 	  "<network id> <passphrase> = configure private key passphrase\n"
   2792 	  "  for an SSID" },
   2793 	{ "bssid", wpa_cli_cmd_bssid,
   2794 	  cli_cmd_flag_none,
   2795 	  "<network id> <BSSID> = set preferred BSSID for an SSID" },
   2796 	{ "blacklist", wpa_cli_cmd_blacklist,
   2797 	  cli_cmd_flag_none,
   2798 	  "<BSSID> = add a BSSID to the blacklist\n"
   2799 	  "blacklist clear = clear the blacklist\n"
   2800 	  "blacklist = display the blacklist" },
   2801 	{ "log_level", wpa_cli_cmd_log_level,
   2802 	  cli_cmd_flag_none,
   2803 	  "<level> [<timestamp>] = update the log level/timestamp\n"
   2804 	  "log_level = display the current log level and log options" },
   2805 	{ "list_networks", wpa_cli_cmd_list_networks,
   2806 	  cli_cmd_flag_none,
   2807 	  "= list configured networks" },
   2808 	{ "select_network", wpa_cli_cmd_select_network,
   2809 	  cli_cmd_flag_none,
   2810 	  "<network id> = select a network (disable others)" },
   2811 	{ "enable_network", wpa_cli_cmd_enable_network,
   2812 	  cli_cmd_flag_none,
   2813 	  "<network id> = enable a network" },
   2814 	{ "disable_network", wpa_cli_cmd_disable_network,
   2815 	  cli_cmd_flag_none,
   2816 	  "<network id> = disable a network" },
   2817 	{ "add_network", wpa_cli_cmd_add_network,
   2818 	  cli_cmd_flag_none,
   2819 	  "= add a network" },
   2820 	{ "remove_network", wpa_cli_cmd_remove_network,
   2821 	  cli_cmd_flag_none,
   2822 	  "<network id> = remove a network" },
   2823 	{ "set_network", wpa_cli_cmd_set_network,
   2824 	  cli_cmd_flag_sensitive,
   2825 	  "<network id> <variable> <value> = set network variables (shows\n"
   2826 	  "  list of variables when run without arguments)" },
   2827 	{ "get_network", wpa_cli_cmd_get_network,
   2828 	  cli_cmd_flag_none,
   2829 	  "<network id> <variable> = get network variables" },
   2830 	{ "save_config", wpa_cli_cmd_save_config,
   2831 	  cli_cmd_flag_none,
   2832 	  "= save the current configuration" },
   2833 	{ "disconnect", wpa_cli_cmd_disconnect,
   2834 	  cli_cmd_flag_none,
   2835 	  "= disconnect and wait for reassociate/reconnect command before\n"
   2836 	  "  connecting" },
   2837 	{ "reconnect", wpa_cli_cmd_reconnect,
   2838 	  cli_cmd_flag_none,
   2839 	  "= like reassociate, but only takes effect if already disconnected"
   2840 	},
   2841 	{ "scan", wpa_cli_cmd_scan,
   2842 	  cli_cmd_flag_none,
   2843 	  "= request new BSS scan" },
   2844 	{ "scan_results", wpa_cli_cmd_scan_results,
   2845 	  cli_cmd_flag_none,
   2846 	  "= get latest scan results" },
   2847 	{ "bss", wpa_cli_cmd_bss,
   2848 	  cli_cmd_flag_none,
   2849 	  "<<idx> | <bssid>> = get detailed scan result info" },
   2850 	{ "get_capability", wpa_cli_cmd_get_capability,
   2851 	  cli_cmd_flag_none,
   2852 	  "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
   2853 	{ "reconfigure", wpa_cli_cmd_reconfigure,
   2854 	  cli_cmd_flag_none,
   2855 	  "= force wpa_supplicant to re-read its configuration file" },
   2856 	{ "terminate", wpa_cli_cmd_terminate,
   2857 	  cli_cmd_flag_none,
   2858 	  "= terminate wpa_supplicant" },
   2859 	{ "interface_add", wpa_cli_cmd_interface_add,
   2860 	  cli_cmd_flag_none,
   2861 	  "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
   2862 	  "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
   2863 	  "  are optional" },
   2864 	{ "interface_remove", wpa_cli_cmd_interface_remove,
   2865 	  cli_cmd_flag_none,
   2866 	  "<ifname> = removes the interface" },
   2867 	{ "interface_list", wpa_cli_cmd_interface_list,
   2868 	  cli_cmd_flag_none,
   2869 	  "= list available interfaces" },
   2870 	{ "ap_scan", wpa_cli_cmd_ap_scan,
   2871 	  cli_cmd_flag_none,
   2872 	  "<value> = set ap_scan parameter" },
   2873 	{ "scan_interval", wpa_cli_cmd_scan_interval,
   2874 	  cli_cmd_flag_none,
   2875 	  "<value> = set scan_interval parameter (in seconds)" },
   2876 	{ "bss_expire_age", wpa_cli_cmd_bss_expire_age,
   2877 	  cli_cmd_flag_none,
   2878 	  "<value> = set BSS expiration age parameter" },
   2879 	{ "bss_expire_count", wpa_cli_cmd_bss_expire_count,
   2880 	  cli_cmd_flag_none,
   2881 	  "<value> = set BSS expiration scan count parameter" },
   2882 	{ "stkstart", wpa_cli_cmd_stkstart,
   2883 	  cli_cmd_flag_none,
   2884 	  "<addr> = request STK negotiation with <addr>" },
   2885 	{ "ft_ds", wpa_cli_cmd_ft_ds,
   2886 	  cli_cmd_flag_none,
   2887 	  "<addr> = request over-the-DS FT with <addr>" },
   2888 	{ "wps_pbc", wpa_cli_cmd_wps_pbc,
   2889 	  cli_cmd_flag_none,
   2890 	  "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
   2891 	{ "wps_pin", wpa_cli_cmd_wps_pin,
   2892 	  cli_cmd_flag_sensitive,
   2893 	  "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
   2894 	  "hardcoded)" },
   2895 	{ "wps_check_pin", wpa_cli_cmd_wps_check_pin,
   2896 	  cli_cmd_flag_sensitive,
   2897 	  "<PIN> = verify PIN checksum" },
   2898 	{ "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
   2899 	  "Cancels the pending WPS operation" },
   2900 #ifdef CONFIG_WPS_OOB
   2901 	{ "wps_oob", wpa_cli_cmd_wps_oob,
   2902 	  cli_cmd_flag_sensitive,
   2903 	  "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
   2904 #endif /* CONFIG_WPS_OOB */
   2905 	{ "wps_reg", wpa_cli_cmd_wps_reg,
   2906 	  cli_cmd_flag_sensitive,
   2907 	  "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
   2908 	{ "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
   2909 	  cli_cmd_flag_sensitive,
   2910 	  "[params..] = enable/disable AP PIN" },
   2911 	{ "wps_er_start", wpa_cli_cmd_wps_er_start,
   2912 	  cli_cmd_flag_none,
   2913 	  "[IP address] = start Wi-Fi Protected Setup External Registrar" },
   2914 	{ "wps_er_stop", wpa_cli_cmd_wps_er_stop,
   2915 	  cli_cmd_flag_none,
   2916 	  "= stop Wi-Fi Protected Setup External Registrar" },
   2917 	{ "wps_er_pin", wpa_cli_cmd_wps_er_pin,
   2918 	  cli_cmd_flag_sensitive,
   2919 	  "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
   2920 	{ "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
   2921 	  cli_cmd_flag_none,
   2922 	  "<UUID> = accept an Enrollee PBC using External Registrar" },
   2923 	{ "wps_er_learn", wpa_cli_cmd_wps_er_learn,
   2924 	  cli_cmd_flag_sensitive,
   2925 	  "<UUID> <PIN> = learn AP configuration" },
   2926 	{ "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
   2927 	  cli_cmd_flag_none,
   2928 	  "<UUID> <network id> = set AP configuration for enrolling" },
   2929 	{ "wps_er_config", wpa_cli_cmd_wps_er_config,
   2930 	  cli_cmd_flag_sensitive,
   2931 	  "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
   2932 	{ "ibss_rsn", wpa_cli_cmd_ibss_rsn,
   2933 	  cli_cmd_flag_none,
   2934 	  "<addr> = request RSN authentication with <addr> in IBSS" },
   2935 #ifdef CONFIG_AP
   2936 	{ "sta", wpa_cli_cmd_sta,
   2937 	  cli_cmd_flag_none,
   2938 	  "<addr> = get information about an associated station (AP)" },
   2939 	{ "all_sta", wpa_cli_cmd_all_sta,
   2940 	  cli_cmd_flag_none,
   2941 	  "= get information about all associated stations (AP)" },
   2942 #endif /* CONFIG_AP */
   2943 	{ "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
   2944 	  "= notification of suspend/hibernate" },
   2945 	{ "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
   2946 	  "= notification of resume/thaw" },
   2947 	{ "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
   2948 	  "= drop SA without deauth/disassoc (test command)" },
   2949 	{ "roam", wpa_cli_cmd_roam,
   2950 	  cli_cmd_flag_none,
   2951 	  "<addr> = roam to the specified BSS" },
   2952 #ifdef CONFIG_P2P
   2953 	{ "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
   2954 	  "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
   2955 	{ "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
   2956 	  "= stop P2P Devices search" },
   2957 	{ "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
   2958 	  "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
   2959 	{ "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
   2960 	  "[timeout] = listen for P2P Devices for up-to timeout seconds" },
   2961 	{ "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
   2962 	  "<ifname> = remove P2P group interface (terminate group if GO)" },
   2963 	{ "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
   2964 	  "= add a new P2P group (local end as GO)" },
   2965 	{ "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
   2966 	  "<addr> <method> = request provisioning discovery" },
   2967 	{ "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
   2968 	  cli_cmd_flag_none,
   2969 	  "= get the passphrase for a group (GO only)" },
   2970 	{ "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
   2971 	  cli_cmd_flag_none,
   2972 	  "<addr> <TLVs> = schedule service discovery request" },
   2973 	{ "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
   2974 	  cli_cmd_flag_none,
   2975 	  "<id> = cancel pending service discovery request" },
   2976 	{ "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
   2977 	  cli_cmd_flag_none,
   2978 	  "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
   2979 	{ "p2p_service_update", wpa_cli_cmd_p2p_service_update,
   2980 	  cli_cmd_flag_none,
   2981 	  "= indicate change in local services" },
   2982 	{ "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
   2983 	  cli_cmd_flag_none,
   2984 	  "<external> = set external processing of service discovery" },
   2985 	{ "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
   2986 	  cli_cmd_flag_none,
   2987 	  "= remove all stored service entries" },
   2988 	{ "p2p_service_add", wpa_cli_cmd_p2p_service_add,
   2989 	  cli_cmd_flag_none,
   2990 	  "<bonjour|upnp> <query|version> <response|service> = add a local "
   2991 	  "service" },
   2992 	{ "p2p_service_del", wpa_cli_cmd_p2p_service_del,
   2993 	  cli_cmd_flag_none,
   2994 	  "<bonjour|upnp> <query|version> [|service] = remove a local "
   2995 	  "service" },
   2996 	{ "p2p_reject", wpa_cli_cmd_p2p_reject,
   2997 	  cli_cmd_flag_none,
   2998 	  "<addr> = reject connection attempts from a specific peer" },
   2999 	{ "p2p_invite", wpa_cli_cmd_p2p_invite,
   3000 	  cli_cmd_flag_none,
   3001 	  "<cmd> [peer=addr] = invite peer" },
   3002 	{ "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
   3003 	  "[discovered] = list known (optionally, only fully discovered) P2P "
   3004 	  "peers" },
   3005 	{ "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
   3006 	  "<address> = show information about known P2P peer" },
   3007 	{ "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
   3008 	  "<field> <value> = set a P2P parameter" },
   3009 	{ "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
   3010 	  "= flush P2P state" },
   3011 	{ "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
   3012 	  "= cancel P2P group formation" },
   3013 	{ "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
   3014 	  "<address> = unauthorize a peer" },
   3015 	{ "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
   3016 	  "[<duration> <interval>] [<duration> <interval>] = request GO "
   3017 	  "presence" },
   3018 	{ "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
   3019 	  "[<period> <interval>] = set extended listen timing" },
   3020 #endif /* CONFIG_P2P */
   3021 
   3022 #ifdef CONFIG_INTERWORKING
   3023 	{ "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
   3024 	  "= fetch ANQP information for all APs" },
   3025 	{ "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
   3026 	  "= stop fetch_anqp operation" },
   3027 	{ "interworking_select", wpa_cli_cmd_interworking_select,
   3028 	  cli_cmd_flag_none,
   3029 	  "[auto] = perform Interworking network selection" },
   3030 	{ "interworking_connect", wpa_cli_cmd_interworking_connect,
   3031 	  cli_cmd_flag_none,
   3032 	  "<BSSID> = connect using Interworking credentials" },
   3033 	{ "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
   3034 	  "<addr> <info id>[,<info id>]... = request ANQP information" },
   3035 #endif /* CONFIG_INTERWORKING */
   3036 	{ "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
   3037 	  "<0/1> = disable/enable automatic reconnection" },
   3038 	{ "tdls_discover", wpa_cli_cmd_tdls_discover,
   3039 	  cli_cmd_flag_none,
   3040 	  "<addr> = request TDLS discovery with <addr>" },
   3041 	{ "tdls_setup", wpa_cli_cmd_tdls_setup,
   3042 	  cli_cmd_flag_none,
   3043 	  "<addr> = request TDLS setup with <addr>" },
   3044 	{ "tdls_teardown", wpa_cli_cmd_tdls_teardown,
   3045 	  cli_cmd_flag_none,
   3046 	  "<addr> = tear down TDLS with <addr>" },
   3047 	{ "signal_poll", wpa_cli_cmd_signal_poll,
   3048 	  cli_cmd_flag_none,
   3049 	  "= get signal parameters" },
   3050 	{ "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
   3051 	  "= trigger IEEE 802.1X/EAPOL reauthentication" },
   3052 #ifdef ANDROID
   3053 	{ "driver", wpa_cli_cmd_driver,
   3054 	  cli_cmd_flag_none,
   3055 	  "<command> = driver private commands" },
   3056 #endif
   3057 	{ NULL, NULL, cli_cmd_flag_none, NULL }
   3058 };
   3059 
   3060 
   3061 /*
   3062  * Prints command usage, lines are padded with the specified string.
   3063  */
   3064 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
   3065 {
   3066 	char c;
   3067 	size_t n;
   3068 
   3069 	printf("%s%s ", pad, cmd->cmd);
   3070 	for (n = 0; (c = cmd->usage[n]); n++) {
   3071 		printf("%c", c);
   3072 		if (c == '\n')
   3073 			printf("%s", pad);
   3074 	}
   3075 	printf("\n");
   3076 }
   3077 
   3078 
   3079 static void print_help(void)
   3080 {
   3081 	int n;
   3082 	printf("commands:\n");
   3083 	for (n = 0; wpa_cli_commands[n].cmd; n++)
   3084 		print_cmd_help(&wpa_cli_commands[n], "  ");
   3085 }
   3086 
   3087 
   3088 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
   3089 {
   3090 	const char *c, *delim;
   3091 	int n;
   3092 	size_t len;
   3093 
   3094 	delim = os_strchr(cmd, ' ');
   3095 	if (delim)
   3096 		len = delim - cmd;
   3097 	else
   3098 		len = os_strlen(cmd);
   3099 
   3100 	for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
   3101 		if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
   3102 			return (wpa_cli_commands[n].flags &
   3103 				cli_cmd_flag_sensitive);
   3104 	}
   3105 	return 0;
   3106 }
   3107 
   3108 
   3109 static char ** wpa_list_cmd_list(void)
   3110 {
   3111 	char **res;
   3112 	int i, count;
   3113 
   3114 	count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
   3115 	res = os_zalloc(count * sizeof(char *));
   3116 	if (res == NULL)
   3117 		return NULL;
   3118 
   3119 	for (i = 0; wpa_cli_commands[i].cmd; i++) {
   3120 		res[i] = os_strdup(wpa_cli_commands[i].cmd);
   3121 		if (res[i] == NULL)
   3122 			break;
   3123 	}
   3124 
   3125 	return res;
   3126 }
   3127 
   3128 
   3129 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
   3130 				      int pos)
   3131 {
   3132 	int i;
   3133 
   3134 	if (os_strcasecmp(cmd, "bss") == 0)
   3135 		return wpa_cli_complete_bss(str, pos);
   3136 #ifdef CONFIG_P2P
   3137 	if (os_strcasecmp(cmd, "p2p_connect") == 0)
   3138 		return wpa_cli_complete_p2p_connect(str, pos);
   3139 	if (os_strcasecmp(cmd, "p2p_peer") == 0)
   3140 		return wpa_cli_complete_p2p_peer(str, pos);
   3141 	if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
   3142 		return wpa_cli_complete_p2p_group_remove(str, pos);
   3143 #endif /* CONFIG_P2P */
   3144 
   3145 	for (i = 0; wpa_cli_commands[i].cmd; i++) {
   3146 		if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
   3147 			edit_clear_line();
   3148 			printf("\r%s\n", wpa_cli_commands[i].usage);
   3149 			edit_redraw();
   3150 			break;
   3151 		}
   3152 	}
   3153 
   3154 	return NULL;
   3155 }
   3156 
   3157 
   3158 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
   3159 {
   3160 	char **res;
   3161 	const char *end;
   3162 	char *cmd;
   3163 
   3164 	end = os_strchr(str, ' ');
   3165 	if (end == NULL || str + pos < end)
   3166 		return wpa_list_cmd_list();
   3167 
   3168 	cmd = os_malloc(pos + 1);
   3169 	if (cmd == NULL)
   3170 		return NULL;
   3171 	os_memcpy(cmd, str, pos);
   3172 	cmd[end - str] = '\0';
   3173 	res = wpa_cli_cmd_completion(cmd, str, pos);
   3174 	os_free(cmd);
   3175 	return res;
   3176 }
   3177 
   3178 
   3179 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
   3180 {
   3181 	struct wpa_cli_cmd *cmd, *match = NULL;
   3182 	int count;
   3183 	int ret = 0;
   3184 
   3185 	count = 0;
   3186 	cmd = wpa_cli_commands;
   3187 	while (cmd->cmd) {
   3188 		if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
   3189 		{
   3190 			match = cmd;
   3191 			if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
   3192 				/* we have an exact match */
   3193 				count = 1;
   3194 				break;
   3195 			}
   3196 			count++;
   3197 		}
   3198 		cmd++;
   3199 	}
   3200 
   3201 	if (count > 1) {
   3202 		printf("Ambiguous command '%s'; possible commands:", argv[0]);
   3203 		cmd = wpa_cli_commands;
   3204 		while (cmd->cmd) {
   3205 			if (os_strncasecmp(cmd->cmd, argv[0],
   3206 					   os_strlen(argv[0])) == 0) {
   3207 				printf(" %s", cmd->cmd);
   3208 			}
   3209 			cmd++;
   3210 		}
   3211 		printf("\n");
   3212 		ret = 1;
   3213 	} else if (count == 0) {
   3214 		printf("Unknown command '%s'\n", argv[0]);
   3215 		ret = 1;
   3216 	} else {
   3217 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
   3218 		if ( (argc >= 2) && (os_strncmp(argv[1], "interface=", 10) == 0)) {
   3219 			redirect_interface = os_strdup(argv[1]);
   3220 			ret = match->handler(ctrl, argc - 2, &argv[2]);
   3221 		}
   3222 		else
   3223 #endif
   3224 		ret = match->handler(ctrl, argc - 1, &argv[1]);
   3225 	}
   3226 
   3227 	return ret;
   3228 }
   3229 
   3230 
   3231 static int str_match(const char *a, const char *b)
   3232 {
   3233 	return os_strncmp(a, b, os_strlen(b)) == 0;
   3234 }
   3235 
   3236 
   3237 static int wpa_cli_exec(const char *program, const char *arg1,
   3238 			const char *arg2)
   3239 {
   3240 	char *cmd;
   3241 	size_t len;
   3242 	int res;
   3243 	int ret = 0;
   3244 
   3245 	len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
   3246 	cmd = os_malloc(len);
   3247 	if (cmd == NULL)
   3248 		return -1;
   3249 	res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
   3250 	if (res < 0 || (size_t) res >= len) {
   3251 		os_free(cmd);
   3252 		return -1;
   3253 	}
   3254 	cmd[len - 1] = '\0';
   3255 #ifndef _WIN32_WCE
   3256 	if (system(cmd) < 0)
   3257 		ret = -1;
   3258 #endif /* _WIN32_WCE */
   3259 	os_free(cmd);
   3260 
   3261 	return ret;
   3262 }
   3263 
   3264 
   3265 static void wpa_cli_action_process(const char *msg)
   3266 {
   3267 	const char *pos;
   3268 	char *copy = NULL, *id, *pos2;
   3269 
   3270 	pos = msg;
   3271 	if (*pos == '<') {
   3272 		/* skip priority */
   3273 		pos = os_strchr(pos, '>');
   3274 		if (pos)
   3275 			pos++;
   3276 		else
   3277 			pos = msg;
   3278 	}
   3279 
   3280 	if (str_match(pos, WPA_EVENT_CONNECTED)) {
   3281 		int new_id = -1;
   3282 		os_unsetenv("WPA_ID");
   3283 		os_unsetenv("WPA_ID_STR");
   3284 		os_unsetenv("WPA_CTRL_DIR");
   3285 
   3286 		pos = os_strstr(pos, "[id=");
   3287 		if (pos)
   3288 			copy = os_strdup(pos + 4);
   3289 
   3290 		if (copy) {
   3291 			pos2 = id = copy;
   3292 			while (*pos2 && *pos2 != ' ')
   3293 				pos2++;
   3294 			*pos2++ = '\0';
   3295 			new_id = atoi(id);
   3296 			os_setenv("WPA_ID", id, 1);
   3297 			while (*pos2 && *pos2 != '=')
   3298 				pos2++;
   3299 			if (*pos2 == '=')
   3300 				pos2++;
   3301 			id = pos2;
   3302 			while (*pos2 && *pos2 != ']')
   3303 				pos2++;
   3304 			*pos2 = '\0';
   3305 			os_setenv("WPA_ID_STR", id, 1);
   3306 			os_free(copy);
   3307 		}
   3308 
   3309 		os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
   3310 
   3311 		if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
   3312 			wpa_cli_connected = 1;
   3313 			wpa_cli_last_id = new_id;
   3314 			wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
   3315 		}
   3316 	} else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
   3317 		if (wpa_cli_connected) {
   3318 			wpa_cli_connected = 0;
   3319 			wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
   3320 		}
   3321 	} else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
   3322 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3323 	} else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
   3324 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3325 	} else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
   3326 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3327 	} else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
   3328 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3329 	} else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
   3330 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3331 	} else if (str_match(pos, WPS_EVENT_SUCCESS)) {
   3332 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3333 	} else if (str_match(pos, WPS_EVENT_FAIL)) {
   3334 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3335 	} else if (str_match(pos, AP_STA_CONNECTED)) {
   3336 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3337 	} else if (str_match(pos, AP_STA_DISCONNECTED)) {
   3338 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3339 	} else if (str_match(pos, WPA_EVENT_TERMINATING)) {
   3340 		printf("wpa_supplicant is terminating - stop monitoring\n");
   3341 		wpa_cli_quit = 1;
   3342 	}
   3343 }
   3344 
   3345 
   3346 #ifndef CONFIG_ANSI_C_EXTRA
   3347 static void wpa_cli_action_cb(char *msg, size_t len)
   3348 {
   3349 	wpa_cli_action_process(msg);
   3350 }
   3351 #endif /* CONFIG_ANSI_C_EXTRA */
   3352 
   3353 
   3354 static void wpa_cli_reconnect(void)
   3355 {
   3356 	wpa_cli_close_connection();
   3357 	wpa_cli_open_connection(ctrl_ifname, 1);
   3358 }
   3359 
   3360 
   3361 static void cli_event(const char *str)
   3362 {
   3363 	const char *start, *s;
   3364 
   3365 	start = os_strchr(str, '>');
   3366 	if (start == NULL)
   3367 		return;
   3368 
   3369 	start++;
   3370 
   3371 	if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
   3372 		s = os_strchr(start, ' ');
   3373 		if (s == NULL)
   3374 			return;
   3375 		s = os_strchr(s + 1, ' ');
   3376 		if (s == NULL)
   3377 			return;
   3378 		cli_txt_list_add(&bsses, s + 1);
   3379 		return;
   3380 	}
   3381 
   3382 	if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
   3383 		s = os_strchr(start, ' ');
   3384 		if (s == NULL)
   3385 			return;
   3386 		s = os_strchr(s + 1, ' ');
   3387 		if (s == NULL)
   3388 			return;
   3389 		cli_txt_list_del_addr(&bsses, s + 1);
   3390 		return;
   3391 	}
   3392 
   3393 #ifdef CONFIG_P2P
   3394 	if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
   3395 		s = os_strstr(start, " p2p_dev_addr=");
   3396 		if (s == NULL)
   3397 			return;
   3398 		cli_txt_list_add_addr(&p2p_peers, s + 14);
   3399 		return;
   3400 	}
   3401 
   3402 	if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
   3403 		s = os_strstr(start, " p2p_dev_addr=");
   3404 		if (s == NULL)
   3405 			return;
   3406 		cli_txt_list_del_addr(&p2p_peers, s + 14);
   3407 		return;
   3408 	}
   3409 
   3410 	if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
   3411 		s = os_strchr(start, ' ');
   3412 		if (s == NULL)
   3413 			return;
   3414 		cli_txt_list_add_word(&p2p_groups, s + 1);
   3415 		return;
   3416 	}
   3417 
   3418 	if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
   3419 		s = os_strchr(start, ' ');
   3420 		if (s == NULL)
   3421 			return;
   3422 		cli_txt_list_del_word(&p2p_groups, s + 1);
   3423 		return;
   3424 	}
   3425 #endif /* CONFIG_P2P */
   3426 }
   3427 
   3428 
   3429 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
   3430 {
   3431 	if (ctrl_conn == NULL) {
   3432 		wpa_cli_reconnect();
   3433 		return;
   3434 	}
   3435 	while (wpa_ctrl_pending(ctrl) > 0) {
   3436 		char buf[256];
   3437 		size_t len = sizeof(buf) - 1;
   3438 		if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
   3439 			buf[len] = '\0';
   3440 			if (action_monitor)
   3441 				wpa_cli_action_process(buf);
   3442 			else {
   3443 				cli_event(buf);
   3444 				if (wpa_cli_show_event(buf)) {
   3445 					edit_clear_line();
   3446 					printf("\r%s\n", buf);
   3447 					edit_redraw();
   3448 				}
   3449 			}
   3450 		} else {
   3451 			printf("Could not read pending message.\n");
   3452 			break;
   3453 		}
   3454 	}
   3455 
   3456 	if (wpa_ctrl_pending(ctrl) < 0) {
   3457 		printf("Connection to wpa_supplicant lost - trying to "
   3458 		       "reconnect\n");
   3459 		wpa_cli_reconnect();
   3460 	}
   3461 }
   3462 
   3463 #define max_args 10
   3464 
   3465 static int tokenize_cmd(char *cmd, char *argv[])
   3466 {
   3467 	char *pos;
   3468 	int argc = 0;
   3469 
   3470 	pos = cmd;
   3471 	for (;;) {
   3472 		while (*pos == ' ')
   3473 			pos++;
   3474 		if (*pos == '\0')
   3475 			break;
   3476 		argv[argc] = pos;
   3477 		argc++;
   3478 		if (argc == max_args)
   3479 			break;
   3480 		if (*pos == '"') {
   3481 			char *pos2 = os_strrchr(pos, '"');
   3482 			if (pos2)
   3483 				pos = pos2 + 1;
   3484 		}
   3485 		while (*pos != '\0' && *pos != ' ')
   3486 			pos++;
   3487 		if (*pos == ' ')
   3488 			*pos++ = '\0';
   3489 	}
   3490 
   3491 	return argc;
   3492 }
   3493 
   3494 
   3495 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
   3496 {
   3497 	if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
   3498 		printf("Connection to wpa_supplicant lost - trying to "
   3499 		       "reconnect\n");
   3500 		wpa_cli_close_connection();
   3501 	}
   3502 	if (!ctrl_conn)
   3503 		wpa_cli_reconnect();
   3504 	eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
   3505 }
   3506 
   3507 
   3508 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
   3509 {
   3510 	eloop_terminate();
   3511 }
   3512 
   3513 
   3514 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
   3515 {
   3516 	wpa_cli_recv_pending(mon_conn, 0);
   3517 }
   3518 
   3519 
   3520 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
   3521 {
   3522 	char *argv[max_args];
   3523 	int argc;
   3524 	argc = tokenize_cmd(cmd, argv);
   3525 	if (argc)
   3526 		wpa_request(ctrl_conn, argc, argv);
   3527 }
   3528 
   3529 
   3530 static void wpa_cli_edit_eof_cb(void *ctx)
   3531 {
   3532 	eloop_terminate();
   3533 }
   3534 
   3535 
   3536 static void wpa_cli_interactive(void)
   3537 {
   3538 	char *home, *hfile = NULL;
   3539 
   3540 	printf("\nInteractive mode\n\n");
   3541 
   3542 	home = getenv("HOME");
   3543 	if (home) {
   3544 		const char *fname = ".wpa_cli_history";
   3545 		int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
   3546 		hfile = os_malloc(hfile_len);
   3547 		if (hfile)
   3548 			os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
   3549 	}
   3550 
   3551 	eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
   3552 	edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
   3553 		  wpa_cli_edit_completion_cb, NULL, hfile);
   3554 	eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
   3555 
   3556 	eloop_run();
   3557 
   3558 	cli_txt_list_flush(&p2p_peers);
   3559 	cli_txt_list_flush(&p2p_groups);
   3560 	cli_txt_list_flush(&bsses);
   3561 	edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
   3562 	os_free(hfile);
   3563 	eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
   3564 	wpa_cli_close_connection();
   3565 }
   3566 
   3567 
   3568 static void wpa_cli_action(struct wpa_ctrl *ctrl)
   3569 {
   3570 #ifdef CONFIG_ANSI_C_EXTRA
   3571 	/* TODO: ANSI C version(?) */
   3572 	printf("Action processing not supported in ANSI C build.\n");
   3573 #else /* CONFIG_ANSI_C_EXTRA */
   3574 	fd_set rfds;
   3575 	int fd, res;
   3576 	struct timeval tv;
   3577 	char buf[256]; /* note: large enough to fit in unsolicited messages */
   3578 	size_t len;
   3579 
   3580 	fd = wpa_ctrl_get_fd(ctrl);
   3581 
   3582 	while (!wpa_cli_quit) {
   3583 		FD_ZERO(&rfds);
   3584 		FD_SET(fd, &rfds);
   3585 		tv.tv_sec = ping_interval;
   3586 		tv.tv_usec = 0;
   3587 		res = select(fd + 1, &rfds, NULL, NULL, &tv);
   3588 		if (res < 0 && errno != EINTR) {
   3589 			perror("select");
   3590 			break;
   3591 		}
   3592 
   3593 		if (FD_ISSET(fd, &rfds))
   3594 			wpa_cli_recv_pending(ctrl, 1);
   3595 		else {
   3596 			/* verify that connection is still working */
   3597 			len = sizeof(buf) - 1;
   3598 			if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
   3599 					     wpa_cli_action_cb) < 0 ||
   3600 			    len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
   3601 				printf("wpa_supplicant did not reply to PING "
   3602 				       "command - exiting\n");
   3603 				break;
   3604 			}
   3605 		}
   3606 	}
   3607 #endif /* CONFIG_ANSI_C_EXTRA */
   3608 }
   3609 
   3610 
   3611 static void wpa_cli_cleanup(void)
   3612 {
   3613 	wpa_cli_close_connection();
   3614 	if (pid_file)
   3615 		os_daemonize_terminate(pid_file);
   3616 
   3617 	os_program_deinit();
   3618 }
   3619 
   3620 static void wpa_cli_terminate(int sig)
   3621 {
   3622 	wpa_cli_cleanup();
   3623 	exit(0);
   3624 }
   3625 
   3626 
   3627 static char * wpa_cli_get_default_ifname(void)
   3628 {
   3629 	char *ifname = NULL;
   3630 
   3631 #ifdef CONFIG_CTRL_IFACE_UNIX
   3632 	struct dirent *dent;
   3633 	DIR *dir = opendir(ctrl_iface_dir);
   3634 	if (!dir) {
   3635 #ifdef ANDROID
   3636 		char ifprop[PROPERTY_VALUE_MAX];
   3637 		if (property_get("wifi.interface", ifprop, NULL) != 0) {
   3638 			ifname = os_strdup(ifprop);
   3639 			printf("Using interface '%s'\n", ifname);
   3640 			return ifname;
   3641 		}
   3642 #endif /* ANDROID */
   3643 		return NULL;
   3644 	}
   3645 	while ((dent = readdir(dir))) {
   3646 #ifdef _DIRENT_HAVE_D_TYPE
   3647 		/*
   3648 		 * Skip the file if it is not a socket. Also accept
   3649 		 * DT_UNKNOWN (0) in case the C library or underlying
   3650 		 * file system does not support d_type.
   3651 		 */
   3652 		if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
   3653 			continue;
   3654 #endif /* _DIRENT_HAVE_D_TYPE */
   3655 		if (os_strcmp(dent->d_name, ".") == 0 ||
   3656 		    os_strcmp(dent->d_name, "..") == 0)
   3657 			continue;
   3658 		printf("Selected interface '%s'\n", dent->d_name);
   3659 		ifname = os_strdup(dent->d_name);
   3660 		break;
   3661 	}
   3662 	closedir(dir);
   3663 #endif /* CONFIG_CTRL_IFACE_UNIX */
   3664 
   3665 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
   3666 #ifdef ANDROID
   3667 	char buf[4096], *pos;
   3668 #else
   3669 	char buf[2048], *pos;
   3670 #endif
   3671 	size_t len;
   3672 	struct wpa_ctrl *ctrl;
   3673 	int ret;
   3674 
   3675 	ctrl = wpa_ctrl_open(NULL);
   3676 	if (ctrl == NULL)
   3677 		return NULL;
   3678 
   3679 	len = sizeof(buf) - 1;
   3680 	ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
   3681 	if (ret >= 0) {
   3682 		buf[len] = '\0';
   3683 		pos = os_strchr(buf, '\n');
   3684 		if (pos)
   3685 			*pos = '\0';
   3686 		ifname = os_strdup(buf);
   3687 	}
   3688 	wpa_ctrl_close(ctrl);
   3689 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   3690 
   3691 	return ifname;
   3692 }
   3693 
   3694 
   3695 int main(int argc, char *argv[])
   3696 {
   3697 	int warning_displayed = 0;
   3698 	int c;
   3699 	int daemonize = 0;
   3700 	int ret = 0;
   3701 	const char *global = NULL;
   3702 
   3703 	if (os_program_init())
   3704 		return -1;
   3705 
   3706 	for (;;) {
   3707 		c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
   3708 		if (c < 0)
   3709 			break;
   3710 		switch (c) {
   3711 		case 'a':
   3712 			action_file = optarg;
   3713 			break;
   3714 		case 'B':
   3715 			daemonize = 1;
   3716 			break;
   3717 		case 'g':
   3718 			global = optarg;
   3719 			break;
   3720 		case 'G':
   3721 			ping_interval = atoi(optarg);
   3722 			break;
   3723 		case 'h':
   3724 			usage();
   3725 			return 0;
   3726 		case 'v':
   3727 			printf("%s\n", wpa_cli_version);
   3728 			return 0;
   3729 		case 'i':
   3730 			os_free(ctrl_ifname);
   3731 			ctrl_ifname = os_strdup(optarg);
   3732 			break;
   3733 		case 'p':
   3734 			ctrl_iface_dir = optarg;
   3735 			break;
   3736 		case 'P':
   3737 			pid_file = optarg;
   3738 			break;
   3739 		default:
   3740 			usage();
   3741 			return -1;
   3742 		}
   3743 	}
   3744 
   3745 	interactive = (argc == optind) && (action_file == NULL);
   3746 
   3747 	if (interactive)
   3748 		printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
   3749 
   3750 	if (eloop_init())
   3751 		return -1;
   3752 
   3753 	if (global) {
   3754 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
   3755 		ctrl_conn = wpa_ctrl_open(NULL);
   3756 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   3757 		ctrl_conn = wpa_ctrl_open(global);
   3758 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   3759 		if (ctrl_conn == NULL) {
   3760 			perror("Failed to connect to wpa_supplicant - "
   3761 			       "wpa_ctrl_open");
   3762 			return -1;
   3763 		}
   3764 	}
   3765 
   3766 #ifndef _WIN32_WCE
   3767 	signal(SIGINT, wpa_cli_terminate);
   3768 	signal(SIGTERM, wpa_cli_terminate);
   3769 #endif /* _WIN32_WCE */
   3770 
   3771 	if (ctrl_ifname == NULL)
   3772 		ctrl_ifname = wpa_cli_get_default_ifname();
   3773 
   3774 	if (interactive) {
   3775 		for (; !global;) {
   3776 			if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
   3777 				if (warning_displayed)
   3778 					printf("Connection established.\n");
   3779 				break;
   3780 			}
   3781 
   3782 			if (!warning_displayed) {
   3783 				printf("Could not connect to wpa_supplicant - "
   3784 				       "re-trying\n");
   3785 				warning_displayed = 1;
   3786 			}
   3787 			os_sleep(1, 0);
   3788 			continue;
   3789 		}
   3790 	} else {
   3791 		if (!global &&
   3792 		    wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
   3793 			perror("Failed to connect to wpa_supplicant - "
   3794 			       "wpa_ctrl_open");
   3795 			return -1;
   3796 		}
   3797 
   3798 		if (action_file) {
   3799 			if (wpa_ctrl_attach(ctrl_conn) == 0) {
   3800 				wpa_cli_attached = 1;
   3801 			} else {
   3802 				printf("Warning: Failed to attach to "
   3803 				       "wpa_supplicant.\n");
   3804 				return -1;
   3805 			}
   3806 		}
   3807 	}
   3808 
   3809 	if (daemonize && os_daemonize(pid_file))
   3810 		return -1;
   3811 
   3812 	if (interactive)
   3813 		wpa_cli_interactive();
   3814 	else if (action_file)
   3815 		wpa_cli_action(ctrl_conn);
   3816 	else
   3817 		ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
   3818 
   3819 	os_free(ctrl_ifname);
   3820 	eloop_destroy();
   3821 	wpa_cli_cleanup();
   3822 
   3823 	return ret;
   3824 }
   3825 
   3826 #else /* CONFIG_CTRL_IFACE */
   3827 int main(int argc, char *argv[])
   3828 {
   3829 	printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
   3830 	return -1;
   3831 }
   3832 #endif /* CONFIG_CTRL_IFACE */
   3833