wpa_cli.c revision 281806
1189251Ssam/* 2189251Ssam * WPA Supplicant - command line interface for wpa_supplicant daemon 3281806Srpaulo * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> 4189251Ssam * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7189251Ssam */ 8189251Ssam 9189251Ssam#include "includes.h" 10189251Ssam 11189251Ssam#ifdef CONFIG_CTRL_IFACE 12189251Ssam 13189251Ssam#ifdef CONFIG_CTRL_IFACE_UNIX 14189251Ssam#include <dirent.h> 15189251Ssam#endif /* CONFIG_CTRL_IFACE_UNIX */ 16189251Ssam 17214734Srpaulo#include "common/wpa_ctrl.h" 18252726Srpaulo#include "utils/common.h" 19252726Srpaulo#include "utils/eloop.h" 20252726Srpaulo#include "utils/edit.h" 21252726Srpaulo#include "utils/list.h" 22214734Srpaulo#include "common/version.h" 23252726Srpaulo#include "common/ieee802_11_defs.h" 24252726Srpaulo#ifdef ANDROID 25252726Srpaulo#include <cutils/properties.h> 26252726Srpaulo#endif /* ANDROID */ 27189251Ssam 28189251Ssam 29189251Ssamstatic const char *wpa_cli_version = 30189251Ssam"wpa_cli v" VERSION_STR "\n" 31281806Srpaulo"Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> and contributors"; 32189251Ssam 33189251Ssam 34189251Ssamstatic const char *wpa_cli_license = 35252726Srpaulo"This software may be distributed under the terms of the BSD license.\n" 36252726Srpaulo"See README for more details.\n"; 37189251Ssam 38189251Ssamstatic const char *wpa_cli_full_license = 39252726Srpaulo"This software may be distributed under the terms of the BSD license.\n" 40189251Ssam"\n" 41189251Ssam"Redistribution and use in source and binary forms, with or without\n" 42189251Ssam"modification, are permitted provided that the following conditions are\n" 43189251Ssam"met:\n" 44189251Ssam"\n" 45189251Ssam"1. Redistributions of source code must retain the above copyright\n" 46189251Ssam" notice, this list of conditions and the following disclaimer.\n" 47189251Ssam"\n" 48189251Ssam"2. Redistributions in binary form must reproduce the above copyright\n" 49189251Ssam" notice, this list of conditions and the following disclaimer in the\n" 50189251Ssam" documentation and/or other materials provided with the distribution.\n" 51189251Ssam"\n" 52189251Ssam"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n" 53189251Ssam" names of its contributors may be used to endorse or promote products\n" 54189251Ssam" derived from this software without specific prior written permission.\n" 55189251Ssam"\n" 56189251Ssam"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" 57189251Ssam"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" 58189251Ssam"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" 59189251Ssam"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" 60189251Ssam"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" 61189251Ssam"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" 62189251Ssam"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" 63189251Ssam"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" 64189251Ssam"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" 65189251Ssam"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" 66189251Ssam"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" 67189251Ssam"\n"; 68189251Ssam 69189251Ssamstatic struct wpa_ctrl *ctrl_conn; 70214734Srpaulostatic struct wpa_ctrl *mon_conn; 71189251Ssamstatic int wpa_cli_quit = 0; 72189251Ssamstatic int wpa_cli_attached = 0; 73281806Srpaulostatic int wpa_cli_connected = -1; 74189251Ssamstatic int wpa_cli_last_id = 0; 75252726Srpaulo#ifndef CONFIG_CTRL_IFACE_DIR 76252726Srpaulo#define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant" 77252726Srpaulo#endif /* CONFIG_CTRL_IFACE_DIR */ 78252726Srpaulostatic const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR; 79189251Ssamstatic char *ctrl_ifname = NULL; 80189251Ssamstatic const char *pid_file = NULL; 81189251Ssamstatic const char *action_file = NULL; 82189251Ssamstatic int ping_interval = 5; 83214734Srpaulostatic int interactive = 0; 84281806Srpaulostatic char *ifname_prefix = NULL; 85189251Ssam 86252726Srpaulostruct cli_txt_entry { 87252726Srpaulo struct dl_list list; 88252726Srpaulo char *txt; 89252726Srpaulo}; 90189251Ssam 91252726Srpaulostatic DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */ 92252726Srpaulostatic DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */ 93252726Srpaulostatic DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */ 94281806Srpaulostatic DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */ 95189251Ssam 96189251Ssam 97252726Srpaulostatic void print_help(const char *cmd); 98252726Srpaulostatic void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx); 99252726Srpaulostatic void wpa_cli_close_connection(void); 100252726Srpaulostatic char * wpa_cli_get_default_ifname(void); 101252726Srpaulostatic char ** wpa_list_cmd_list(void); 102252726Srpaulo 103252726Srpaulo 104189251Ssamstatic void usage(void) 105189251Ssam{ 106189251Ssam printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] " 107189251Ssam "[-a<action file>] \\\n" 108189251Ssam " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] " 109189251Ssam "[command..]\n" 110189251Ssam " -h = help (show this usage text)\n" 111189251Ssam " -v = shown version information\n" 112189251Ssam " -a = run in daemon mode executing the action file based on " 113189251Ssam "events from\n" 114189251Ssam " wpa_supplicant\n" 115189251Ssam " -B = run a daemon in the background\n" 116252726Srpaulo " default path: " CONFIG_CTRL_IFACE_DIR "\n" 117189251Ssam " default interface: first interface found in socket path\n"); 118252726Srpaulo print_help(NULL); 119189251Ssam} 120189251Ssam 121189251Ssam 122252726Srpaulostatic void cli_txt_list_free(struct cli_txt_entry *e) 123252726Srpaulo{ 124252726Srpaulo dl_list_del(&e->list); 125252726Srpaulo os_free(e->txt); 126252726Srpaulo os_free(e); 127252726Srpaulo} 128214734Srpaulo 129252726Srpaulo 130252726Srpaulostatic void cli_txt_list_flush(struct dl_list *list) 131189251Ssam{ 132252726Srpaulo struct cli_txt_entry *e; 133252726Srpaulo while ((e = dl_list_first(list, struct cli_txt_entry, list))) 134252726Srpaulo cli_txt_list_free(e); 135214734Srpaulo} 136214734Srpaulo 137252726Srpaulo 138252726Srpaulostatic struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list, 139252726Srpaulo const char *txt) 140214734Srpaulo{ 141252726Srpaulo struct cli_txt_entry *e; 142252726Srpaulo dl_list_for_each(e, txt_list, struct cli_txt_entry, list) { 143252726Srpaulo if (os_strcmp(e->txt, txt) == 0) 144252726Srpaulo return e; 145252726Srpaulo } 146252726Srpaulo return NULL; 147252726Srpaulo} 148214734Srpaulo 149214734Srpaulo 150252726Srpaulostatic void cli_txt_list_del(struct dl_list *txt_list, const char *txt) 151252726Srpaulo{ 152252726Srpaulo struct cli_txt_entry *e; 153252726Srpaulo e = cli_txt_list_get(txt_list, txt); 154252726Srpaulo if (e) 155252726Srpaulo cli_txt_list_free(e); 156252726Srpaulo} 157252726Srpaulo 158252726Srpaulo 159252726Srpaulostatic void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt) 160252726Srpaulo{ 161252726Srpaulo u8 addr[ETH_ALEN]; 162252726Srpaulo char buf[18]; 163252726Srpaulo if (hwaddr_aton(txt, addr) < 0) 164252726Srpaulo return; 165252726Srpaulo os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 166252726Srpaulo cli_txt_list_del(txt_list, buf); 167252726Srpaulo} 168252726Srpaulo 169252726Srpaulo 170252726Srpaulo#ifdef CONFIG_P2P 171252726Srpaulostatic void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt) 172252726Srpaulo{ 173252726Srpaulo const char *end; 174252726Srpaulo char *buf; 175252726Srpaulo end = os_strchr(txt, ' '); 176252726Srpaulo if (end == NULL) 177252726Srpaulo end = txt + os_strlen(txt); 178281806Srpaulo buf = dup_binstr(txt, end - txt); 179252726Srpaulo if (buf == NULL) 180252726Srpaulo return; 181252726Srpaulo cli_txt_list_del(txt_list, buf); 182252726Srpaulo os_free(buf); 183252726Srpaulo} 184252726Srpaulo#endif /* CONFIG_P2P */ 185252726Srpaulo 186252726Srpaulo 187252726Srpaulostatic int cli_txt_list_add(struct dl_list *txt_list, const char *txt) 188252726Srpaulo{ 189252726Srpaulo struct cli_txt_entry *e; 190252726Srpaulo e = cli_txt_list_get(txt_list, txt); 191252726Srpaulo if (e) 192252726Srpaulo return 0; 193252726Srpaulo e = os_zalloc(sizeof(*e)); 194252726Srpaulo if (e == NULL) 195252726Srpaulo return -1; 196252726Srpaulo e->txt = os_strdup(txt); 197252726Srpaulo if (e->txt == NULL) { 198252726Srpaulo os_free(e); 199252726Srpaulo return -1; 200252726Srpaulo } 201252726Srpaulo dl_list_add(txt_list, &e->list); 202252726Srpaulo return 0; 203252726Srpaulo} 204252726Srpaulo 205252726Srpaulo 206252726Srpaulo#ifdef CONFIG_P2P 207252726Srpaulostatic int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt) 208252726Srpaulo{ 209252726Srpaulo u8 addr[ETH_ALEN]; 210252726Srpaulo char buf[18]; 211252726Srpaulo if (hwaddr_aton(txt, addr) < 0) 212252726Srpaulo return -1; 213252726Srpaulo os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 214252726Srpaulo return cli_txt_list_add(txt_list, buf); 215252726Srpaulo} 216252726Srpaulo 217252726Srpaulo 218252726Srpaulostatic int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt) 219252726Srpaulo{ 220252726Srpaulo const char *end; 221252726Srpaulo char *buf; 222252726Srpaulo int ret; 223252726Srpaulo end = os_strchr(txt, ' '); 224252726Srpaulo if (end == NULL) 225252726Srpaulo end = txt + os_strlen(txt); 226281806Srpaulo buf = dup_binstr(txt, end - txt); 227252726Srpaulo if (buf == NULL) 228252726Srpaulo return -1; 229252726Srpaulo ret = cli_txt_list_add(txt_list, buf); 230252726Srpaulo os_free(buf); 231252726Srpaulo return ret; 232252726Srpaulo} 233252726Srpaulo#endif /* CONFIG_P2P */ 234252726Srpaulo 235252726Srpaulo 236252726Srpaulostatic char ** cli_txt_list_array(struct dl_list *txt_list) 237252726Srpaulo{ 238252726Srpaulo unsigned int i, count = dl_list_len(txt_list); 239252726Srpaulo char **res; 240252726Srpaulo struct cli_txt_entry *e; 241252726Srpaulo 242252726Srpaulo res = os_calloc(count + 1, sizeof(char *)); 243252726Srpaulo if (res == NULL) 244252726Srpaulo return NULL; 245252726Srpaulo 246252726Srpaulo i = 0; 247252726Srpaulo dl_list_for_each(e, txt_list, struct cli_txt_entry, list) { 248252726Srpaulo res[i] = os_strdup(e->txt); 249252726Srpaulo if (res[i] == NULL) 250214734Srpaulo break; 251252726Srpaulo i++; 252252726Srpaulo } 253252726Srpaulo 254252726Srpaulo return res; 255252726Srpaulo} 256252726Srpaulo 257252726Srpaulo 258252726Srpaulostatic int get_cmd_arg_num(const char *str, int pos) 259252726Srpaulo{ 260252726Srpaulo int arg = 0, i; 261252726Srpaulo 262252726Srpaulo for (i = 0; i <= pos; i++) { 263252726Srpaulo if (str[i] != ' ') { 264252726Srpaulo arg++; 265252726Srpaulo while (i <= pos && str[i] != ' ') 266252726Srpaulo i++; 267214734Srpaulo } 268214734Srpaulo } 269252726Srpaulo 270252726Srpaulo if (arg > 0) 271252726Srpaulo arg--; 272252726Srpaulo return arg; 273214734Srpaulo} 274214734Srpaulo 275214734Srpaulo 276252726Srpaulostatic int str_starts(const char *src, const char *match) 277252726Srpaulo{ 278252726Srpaulo return os_strncmp(src, match, os_strlen(match)) == 0; 279252726Srpaulo} 280252726Srpaulo 281252726Srpaulo 282252726Srpaulostatic int wpa_cli_show_event(const char *event) 283252726Srpaulo{ 284252726Srpaulo const char *start; 285252726Srpaulo 286252726Srpaulo start = os_strchr(event, '>'); 287252726Srpaulo if (start == NULL) 288252726Srpaulo return 1; 289252726Srpaulo 290252726Srpaulo start++; 291252726Srpaulo /* 292252726Srpaulo * Skip BSS added/removed events since they can be relatively frequent 293252726Srpaulo * and are likely of not much use for an interactive user. 294252726Srpaulo */ 295252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_ADDED) || 296252726Srpaulo str_starts(start, WPA_EVENT_BSS_REMOVED)) 297252726Srpaulo return 0; 298252726Srpaulo 299252726Srpaulo return 1; 300252726Srpaulo} 301252726Srpaulo 302252726Srpaulo 303214734Srpaulostatic int wpa_cli_open_connection(const char *ifname, int attach) 304214734Srpaulo{ 305189251Ssam#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE) 306189251Ssam ctrl_conn = wpa_ctrl_open(ifname); 307214734Srpaulo if (ctrl_conn == NULL) 308214734Srpaulo return -1; 309214734Srpaulo 310214734Srpaulo if (attach && interactive) 311214734Srpaulo mon_conn = wpa_ctrl_open(ifname); 312214734Srpaulo else 313214734Srpaulo mon_conn = NULL; 314189251Ssam#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 315252726Srpaulo char *cfile = NULL; 316189251Ssam int flen, res; 317189251Ssam 318189251Ssam if (ifname == NULL) 319214734Srpaulo return -1; 320189251Ssam 321252726Srpaulo#ifdef ANDROID 322252726Srpaulo if (access(ctrl_iface_dir, F_OK) < 0) { 323252726Srpaulo cfile = os_strdup(ifname); 324252726Srpaulo if (cfile == NULL) 325252726Srpaulo return -1; 326189251Ssam } 327252726Srpaulo#endif /* ANDROID */ 328189251Ssam 329252726Srpaulo if (cfile == NULL) { 330252726Srpaulo flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2; 331252726Srpaulo cfile = os_malloc(flen); 332252726Srpaulo if (cfile == NULL) 333252726Srpaulo return -1; 334252726Srpaulo res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, 335252726Srpaulo ifname); 336281806Srpaulo if (os_snprintf_error(flen, res)) { 337252726Srpaulo os_free(cfile); 338252726Srpaulo return -1; 339252726Srpaulo } 340252726Srpaulo } 341252726Srpaulo 342189251Ssam ctrl_conn = wpa_ctrl_open(cfile); 343214734Srpaulo if (ctrl_conn == NULL) { 344214734Srpaulo os_free(cfile); 345214734Srpaulo return -1; 346214734Srpaulo } 347214734Srpaulo 348214734Srpaulo if (attach && interactive) 349214734Srpaulo mon_conn = wpa_ctrl_open(cfile); 350214734Srpaulo else 351214734Srpaulo mon_conn = NULL; 352189251Ssam os_free(cfile); 353189251Ssam#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 354214734Srpaulo 355214734Srpaulo if (mon_conn) { 356214734Srpaulo if (wpa_ctrl_attach(mon_conn) == 0) { 357214734Srpaulo wpa_cli_attached = 1; 358252726Srpaulo if (interactive) 359252726Srpaulo eloop_register_read_sock( 360252726Srpaulo wpa_ctrl_get_fd(mon_conn), 361252726Srpaulo wpa_cli_mon_receive, NULL, NULL); 362214734Srpaulo } else { 363214734Srpaulo printf("Warning: Failed to attach to " 364214734Srpaulo "wpa_supplicant.\n"); 365252726Srpaulo wpa_cli_close_connection(); 366214734Srpaulo return -1; 367214734Srpaulo } 368214734Srpaulo } 369214734Srpaulo 370214734Srpaulo return 0; 371189251Ssam} 372189251Ssam 373189251Ssam 374189251Ssamstatic void wpa_cli_close_connection(void) 375189251Ssam{ 376189251Ssam if (ctrl_conn == NULL) 377189251Ssam return; 378189251Ssam 379189251Ssam if (wpa_cli_attached) { 380214734Srpaulo wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn); 381189251Ssam wpa_cli_attached = 0; 382189251Ssam } 383189251Ssam wpa_ctrl_close(ctrl_conn); 384189251Ssam ctrl_conn = NULL; 385214734Srpaulo if (mon_conn) { 386252726Srpaulo eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn)); 387214734Srpaulo wpa_ctrl_close(mon_conn); 388214734Srpaulo mon_conn = NULL; 389214734Srpaulo } 390189251Ssam} 391189251Ssam 392189251Ssam 393189251Ssamstatic void wpa_cli_msg_cb(char *msg, size_t len) 394189251Ssam{ 395189251Ssam printf("%s\n", msg); 396189251Ssam} 397189251Ssam 398189251Ssam 399189251Ssamstatic int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print) 400189251Ssam{ 401281806Srpaulo char buf[4096]; 402189251Ssam size_t len; 403189251Ssam int ret; 404189251Ssam 405189251Ssam if (ctrl_conn == NULL) { 406189251Ssam printf("Not connected to wpa_supplicant - command dropped.\n"); 407189251Ssam return -1; 408189251Ssam } 409281806Srpaulo if (ifname_prefix) { 410281806Srpaulo os_snprintf(buf, sizeof(buf), "IFNAME=%s %s", 411281806Srpaulo ifname_prefix, cmd); 412281806Srpaulo buf[sizeof(buf) - 1] = '\0'; 413281806Srpaulo cmd = buf; 414281806Srpaulo } 415189251Ssam len = sizeof(buf) - 1; 416189251Ssam ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 417189251Ssam wpa_cli_msg_cb); 418189251Ssam if (ret == -2) { 419189251Ssam printf("'%s' command timed out.\n", cmd); 420189251Ssam return -2; 421189251Ssam } else if (ret < 0) { 422189251Ssam printf("'%s' command failed.\n", cmd); 423189251Ssam return -1; 424189251Ssam } 425189251Ssam if (print) { 426189251Ssam buf[len] = '\0'; 427189251Ssam printf("%s", buf); 428252726Srpaulo if (interactive && len > 0 && buf[len - 1] != '\n') 429252726Srpaulo printf("\n"); 430189251Ssam } 431189251Ssam return 0; 432189251Ssam} 433189251Ssam 434189251Ssam 435189251Ssamstatic int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd) 436189251Ssam{ 437189251Ssam return _wpa_ctrl_command(ctrl, cmd, 1); 438189251Ssam} 439189251Ssam 440189251Ssam 441252726Srpaulostatic int write_cmd(char *buf, size_t buflen, const char *cmd, int argc, 442252726Srpaulo char *argv[]) 443252726Srpaulo{ 444252726Srpaulo int i, res; 445252726Srpaulo char *pos, *end; 446252726Srpaulo 447252726Srpaulo pos = buf; 448252726Srpaulo end = buf + buflen; 449252726Srpaulo 450252726Srpaulo res = os_snprintf(pos, end - pos, "%s", cmd); 451281806Srpaulo if (os_snprintf_error(end - pos, res)) 452252726Srpaulo goto fail; 453252726Srpaulo pos += res; 454252726Srpaulo 455252726Srpaulo for (i = 0; i < argc; i++) { 456252726Srpaulo res = os_snprintf(pos, end - pos, " %s", argv[i]); 457281806Srpaulo if (os_snprintf_error(end - pos, res)) 458252726Srpaulo goto fail; 459252726Srpaulo pos += res; 460252726Srpaulo } 461252726Srpaulo 462252726Srpaulo buf[buflen - 1] = '\0'; 463252726Srpaulo return 0; 464252726Srpaulo 465252726Srpaulofail: 466252726Srpaulo printf("Too long command\n"); 467252726Srpaulo return -1; 468252726Srpaulo} 469252726Srpaulo 470252726Srpaulo 471252726Srpaulostatic int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args, 472252726Srpaulo int argc, char *argv[]) 473252726Srpaulo{ 474281806Srpaulo char buf[4096]; 475252726Srpaulo if (argc < min_args) { 476252726Srpaulo printf("Invalid %s command - at least %d argument%s " 477252726Srpaulo "required.\n", cmd, min_args, 478252726Srpaulo min_args > 1 ? "s are" : " is"); 479252726Srpaulo return -1; 480252726Srpaulo } 481252726Srpaulo if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0) 482252726Srpaulo return -1; 483252726Srpaulo return wpa_ctrl_command(ctrl, buf); 484252726Srpaulo} 485252726Srpaulo 486252726Srpaulo 487252726Srpaulostatic int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[]) 488252726Srpaulo{ 489252726Srpaulo return wpa_ctrl_command(ctrl, "IFNAME"); 490252726Srpaulo} 491252726Srpaulo 492252726Srpaulo 493189251Ssamstatic int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) 494189251Ssam{ 495252726Srpaulo if (argc > 0 && os_strcmp(argv[0], "verbose") == 0) 496252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS-VERBOSE"); 497252726Srpaulo if (argc > 0 && os_strcmp(argv[0], "wps") == 0) 498252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS-WPS"); 499281806Srpaulo if (argc > 0 && os_strcmp(argv[0], "driver") == 0) 500281806Srpaulo return wpa_ctrl_command(ctrl, "STATUS-DRIVER"); 501252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS"); 502189251Ssam} 503189251Ssam 504189251Ssam 505189251Ssamstatic int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[]) 506189251Ssam{ 507189251Ssam return wpa_ctrl_command(ctrl, "PING"); 508189251Ssam} 509189251Ssam 510189251Ssam 511252726Srpaulostatic int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[]) 512252726Srpaulo{ 513252726Srpaulo return wpa_ctrl_command(ctrl, "RELOG"); 514252726Srpaulo} 515252726Srpaulo 516252726Srpaulo 517252726Srpaulostatic int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[]) 518252726Srpaulo{ 519252726Srpaulo return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv); 520252726Srpaulo} 521252726Srpaulo 522252726Srpaulo 523189251Ssamstatic int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[]) 524189251Ssam{ 525189251Ssam return wpa_ctrl_command(ctrl, "MIB"); 526189251Ssam} 527189251Ssam 528189251Ssam 529189251Ssamstatic int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 530189251Ssam{ 531189251Ssam return wpa_ctrl_command(ctrl, "PMKSA"); 532189251Ssam} 533189251Ssam 534189251Ssam 535281806Srpaulostatic int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc, 536281806Srpaulo char *argv[]) 537281806Srpaulo{ 538281806Srpaulo return wpa_ctrl_command(ctrl, "PMKSA_FLUSH"); 539281806Srpaulo} 540281806Srpaulo 541281806Srpaulo 542189251Ssamstatic int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[]) 543189251Ssam{ 544252726Srpaulo print_help(argc > 0 ? argv[0] : NULL); 545189251Ssam return 0; 546189251Ssam} 547189251Ssam 548189251Ssam 549252726Srpaulostatic char ** wpa_cli_complete_help(const char *str, int pos) 550252726Srpaulo{ 551252726Srpaulo int arg = get_cmd_arg_num(str, pos); 552252726Srpaulo char **res = NULL; 553252726Srpaulo 554252726Srpaulo switch (arg) { 555252726Srpaulo case 1: 556252726Srpaulo res = wpa_list_cmd_list(); 557252726Srpaulo break; 558252726Srpaulo } 559252726Srpaulo 560252726Srpaulo return res; 561252726Srpaulo} 562252726Srpaulo 563252726Srpaulo 564189251Ssamstatic int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[]) 565189251Ssam{ 566189251Ssam printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license); 567189251Ssam return 0; 568189251Ssam} 569189251Ssam 570189251Ssam 571189251Ssamstatic int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[]) 572189251Ssam{ 573189251Ssam wpa_cli_quit = 1; 574252726Srpaulo if (interactive) 575252726Srpaulo eloop_terminate(); 576189251Ssam return 0; 577189251Ssam} 578189251Ssam 579189251Ssam 580189251Ssamstatic int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 581189251Ssam{ 582189251Ssam char cmd[256]; 583189251Ssam int res; 584189251Ssam 585281806Srpaulo if (argc == 1) { 586281806Srpaulo res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]); 587281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 588281806Srpaulo printf("Too long SET command.\n"); 589281806Srpaulo return -1; 590281806Srpaulo } 591281806Srpaulo return wpa_ctrl_command(ctrl, cmd); 592189251Ssam } 593189251Ssam 594281806Srpaulo return wpa_cli_cmd(ctrl, "SET", 2, argc, argv); 595281806Srpaulo} 596281806Srpaulo 597281806Srpaulo 598281806Srpaulostatic char ** wpa_cli_complete_set(const char *str, int pos) 599281806Srpaulo{ 600281806Srpaulo int arg = get_cmd_arg_num(str, pos); 601281806Srpaulo const char *fields[] = { 602281806Srpaulo /* runtime values */ 603281806Srpaulo "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod", 604281806Srpaulo "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime", 605281806Srpaulo "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout", 606281806Srpaulo "wps_fragment_size", "wps_version_number", "ampdu", 607281806Srpaulo "tdls_testing", "tdls_disabled", "pno", "radio_disabled", 608281806Srpaulo "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps", 609281806Srpaulo "no_keep_alive", 610281806Srpaulo /* global configuration parameters */ 611281806Srpaulo "eapol_version", "ap_scan", "disable_scan_offload", 612281806Srpaulo "fast_reauth", "opensc_engine_path", "pkcs11_engine_path", 613281806Srpaulo "pkcs11_module_path", "openssl_ciphers", 614281806Srpaulo "pcsc_reader", "pcsc_pin", 615281806Srpaulo "driver_param", "dot11RSNAConfigPMKLifetime", 616281806Srpaulo "dot11RSNAConfigPMKReauthThreshold", 617281806Srpaulo "dot11RSNAConfigSATimeout", 618281806Srpaulo "update_config", "load_dynamic_eap", "uuid", "device_name", 619281806Srpaulo "manufacturer", "model_name", "model_number", "serial_number", 620281806Srpaulo "device_type", "os_version", "config_methods", 621281806Srpaulo "wps_cred_processing", "wps_vendor_ext_m1", "sec_device_type", 622281806Srpaulo "p2p_listen_reg_class", "p2p_listen_channel", 623281806Srpaulo "p2p_oper_reg_class", "p2p_oper_channel", 624281806Srpaulo "p2p_go_intent", "p2p_ssid_postfix", "persistent_reconnect", 625281806Srpaulo "p2p_intra_bss", "p2p_group_idle", "p2p_pref_chan", 626281806Srpaulo "p2p_no_go_freq", 627281806Srpaulo "p2p_go_ht40", "p2p_disabled", "p2p_no_group_iface", 628281806Srpaulo "p2p_go_vht", 629281806Srpaulo "p2p_ignore_shared_freq", "country", "bss_max_count", 630281806Srpaulo "bss_expiration_age", "bss_expiration_scan_count", 631281806Srpaulo "filter_ssids", "filter_rssi", "max_num_sta", 632281806Srpaulo "disassoc_low_ack", "hs20", "interworking", "hessid", 633281806Srpaulo "access_network_type", "pbc_in_m1", "autoscan", 634281806Srpaulo "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", "wps_nfc_dh_privkey", 635281806Srpaulo "wps_nfc_dev_pw", "ext_password_backend", 636281806Srpaulo "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", 637281806Srpaulo "sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements", 638281806Srpaulo "ignore_old_scan_res", "freq_list", "external_sim", 639281806Srpaulo "tdls_external_control", "p2p_search_delay" 640281806Srpaulo }; 641281806Srpaulo int i, num_fields = ARRAY_SIZE(fields); 642281806Srpaulo 643281806Srpaulo if (arg == 1) { 644281806Srpaulo char **res = os_calloc(num_fields + 1, sizeof(char *)); 645281806Srpaulo if (res == NULL) 646281806Srpaulo return NULL; 647281806Srpaulo for (i = 0; i < num_fields; i++) { 648281806Srpaulo res[i] = os_strdup(fields[i]); 649281806Srpaulo if (res[i] == NULL) 650281806Srpaulo return res; 651281806Srpaulo } 652281806Srpaulo return res; 653189251Ssam } 654189251Ssam 655281806Srpaulo if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0) 656281806Srpaulo return cli_txt_list_array(&bsses); 657281806Srpaulo 658281806Srpaulo return NULL; 659189251Ssam} 660189251Ssam 661281806Srpaulostatic int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[]) 662281806Srpaulo{ 663281806Srpaulo return wpa_ctrl_command(ctrl, "DUMP"); 664281806Srpaulo} 665189251Ssam 666281806Srpaulo 667252726Srpaulostatic int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 668252726Srpaulo{ 669252726Srpaulo return wpa_cli_cmd(ctrl, "GET", 1, argc, argv); 670252726Srpaulo} 671252726Srpaulo 672252726Srpaulo 673189251Ssamstatic int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[]) 674189251Ssam{ 675189251Ssam return wpa_ctrl_command(ctrl, "LOGOFF"); 676189251Ssam} 677189251Ssam 678189251Ssam 679189251Ssamstatic int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[]) 680189251Ssam{ 681189251Ssam return wpa_ctrl_command(ctrl, "LOGON"); 682189251Ssam} 683189251Ssam 684189251Ssam 685189251Ssamstatic int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc, 686189251Ssam char *argv[]) 687189251Ssam{ 688189251Ssam return wpa_ctrl_command(ctrl, "REASSOCIATE"); 689189251Ssam} 690189251Ssam 691189251Ssam 692281806Srpaulostatic int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[]) 693281806Srpaulo{ 694281806Srpaulo return wpa_ctrl_command(ctrl, "REATTACH"); 695281806Srpaulo} 696281806Srpaulo 697281806Srpaulo 698189251Ssamstatic int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc, 699189251Ssam char *argv[]) 700189251Ssam{ 701252726Srpaulo return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv); 702252726Srpaulo} 703189251Ssam 704189251Ssam 705252726Srpaulostatic int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 706252726Srpaulo{ 707252726Srpaulo return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv); 708189251Ssam} 709189251Ssam 710189251Ssam 711252726Srpaulostatic int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc, 712252726Srpaulo char *argv[]) 713189251Ssam{ 714252726Srpaulo return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv); 715252726Srpaulo} 716252726Srpaulo 717252726Srpaulo 718252726Srpaulostatic int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc, 719252726Srpaulo char *argv[]) 720252726Srpaulo{ 721252726Srpaulo return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv); 722252726Srpaulo} 723252726Srpaulo 724252726Srpaulo 725252726Srpaulostatic int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc, 726252726Srpaulo char *argv[]) 727252726Srpaulo{ 728252726Srpaulo return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv); 729252726Srpaulo} 730252726Srpaulo 731252726Srpaulo 732252726Srpaulostatic int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 733252726Srpaulo{ 734189251Ssam char cmd[256]; 735189251Ssam int res; 736189251Ssam 737252726Srpaulo if (argc < 1) 738252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0"); 739252726Srpaulo else 740252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]); 741281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 742252726Srpaulo printf("Too long BSS_FLUSH command.\n"); 743189251Ssam return -1; 744189251Ssam } 745189251Ssam return wpa_ctrl_command(ctrl, cmd); 746189251Ssam} 747189251Ssam 748189251Ssam 749189251Ssamstatic int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc, 750189251Ssam char *argv[]) 751189251Ssam{ 752252726Srpaulo return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv); 753252726Srpaulo} 754189251Ssam 755252726Srpaulo 756252726Srpaulostatic int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[]) 757252726Srpaulo{ 758252726Srpaulo return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv); 759252726Srpaulo} 760252726Srpaulo 761252726Srpaulo 762252726Srpaulostatic int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 763252726Srpaulo{ 764252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv); 765252726Srpaulo} 766252726Srpaulo 767252726Srpaulo 768252726Srpaulostatic int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 769252726Srpaulo{ 770252726Srpaulo if (argc == 0) { 771252726Srpaulo printf("Invalid WPS_PIN command: need one or two arguments:\n" 772252726Srpaulo "- BSSID: use 'any' to select any\n" 773252726Srpaulo "- PIN: optional, used only with devices that have no " 774252726Srpaulo "display\n"); 775189251Ssam return -1; 776189251Ssam } 777189251Ssam 778252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv); 779189251Ssam} 780189251Ssam 781189251Ssam 782252726Srpaulostatic int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc, 783252726Srpaulo char *argv[]) 784189251Ssam{ 785252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv); 786252726Srpaulo} 787189251Ssam 788252726Srpaulo 789252726Srpaulostatic int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc, 790252726Srpaulo char *argv[]) 791252726Srpaulo{ 792252726Srpaulo return wpa_ctrl_command(ctrl, "WPS_CANCEL"); 793252726Srpaulo} 794252726Srpaulo 795252726Srpaulo 796252726Srpaulo#ifdef CONFIG_WPS_NFC 797252726Srpaulo 798252726Srpaulostatic int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 799252726Srpaulo{ 800252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv); 801252726Srpaulo} 802252726Srpaulo 803252726Srpaulo 804281806Srpaulostatic int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 805281806Srpaulo char *argv[]) 806281806Srpaulo{ 807281806Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv); 808281806Srpaulo} 809281806Srpaulo 810281806Srpaulo 811252726Srpaulostatic int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc, 812252726Srpaulo char *argv[]) 813252726Srpaulo{ 814252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv); 815252726Srpaulo} 816252726Srpaulo 817252726Srpaulo 818252726Srpaulostatic int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc, 819252726Srpaulo char *argv[]) 820252726Srpaulo{ 821252726Srpaulo int ret; 822252726Srpaulo char *buf; 823252726Srpaulo size_t buflen; 824252726Srpaulo 825189251Ssam if (argc != 1) { 826252726Srpaulo printf("Invalid 'wps_nfc_tag_read' command - one argument " 827252726Srpaulo "is required.\n"); 828189251Ssam return -1; 829189251Ssam } 830189251Ssam 831252726Srpaulo buflen = 18 + os_strlen(argv[0]); 832252726Srpaulo buf = os_malloc(buflen); 833252726Srpaulo if (buf == NULL) 834189251Ssam return -1; 835252726Srpaulo os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]); 836252726Srpaulo 837252726Srpaulo ret = wpa_ctrl_command(ctrl, buf); 838252726Srpaulo os_free(buf); 839252726Srpaulo 840252726Srpaulo return ret; 841189251Ssam} 842189251Ssam 843189251Ssam 844252726Srpaulostatic int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc, 845252726Srpaulo char *argv[]) 846189251Ssam{ 847252726Srpaulo return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv); 848252726Srpaulo} 849189251Ssam 850189251Ssam 851252726Srpaulostatic int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc, 852252726Srpaulo char *argv[]) 853252726Srpaulo{ 854252726Srpaulo return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv); 855189251Ssam} 856189251Ssam 857189251Ssam 858281806Srpaulostatic int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc, 859252726Srpaulo char *argv[]) 860189251Ssam{ 861281806Srpaulo return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv); 862189251Ssam} 863189251Ssam 864252726Srpaulo#endif /* CONFIG_WPS_NFC */ 865214734Srpaulo 866252726Srpaulo 867189251Ssamstatic int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[]) 868189251Ssam{ 869189251Ssam char cmd[256]; 870189251Ssam int res; 871189251Ssam 872214734Srpaulo if (argc == 2) 873214734Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", 874214734Srpaulo argv[0], argv[1]); 875252726Srpaulo else if (argc == 5 || argc == 6) { 876214734Srpaulo char ssid_hex[2 * 32 + 1]; 877214734Srpaulo char key_hex[2 * 64 + 1]; 878214734Srpaulo int i; 879214734Srpaulo 880214734Srpaulo ssid_hex[0] = '\0'; 881214734Srpaulo for (i = 0; i < 32; i++) { 882214734Srpaulo if (argv[2][i] == '\0') 883214734Srpaulo break; 884214734Srpaulo os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 885214734Srpaulo } 886214734Srpaulo 887214734Srpaulo key_hex[0] = '\0'; 888252726Srpaulo if (argc == 6) { 889252726Srpaulo for (i = 0; i < 64; i++) { 890252726Srpaulo if (argv[5][i] == '\0') 891252726Srpaulo break; 892252726Srpaulo os_snprintf(&key_hex[i * 2], 3, "%02x", 893252726Srpaulo argv[5][i]); 894252726Srpaulo } 895214734Srpaulo } 896214734Srpaulo 897214734Srpaulo res = os_snprintf(cmd, sizeof(cmd), 898214734Srpaulo "WPS_REG %s %s %s %s %s %s", 899214734Srpaulo argv[0], argv[1], ssid_hex, argv[3], argv[4], 900214734Srpaulo key_hex); 901214734Srpaulo } else { 902189251Ssam printf("Invalid WPS_REG command: need two arguments:\n" 903252726Srpaulo "- BSSID of the target AP\n" 904189251Ssam "- AP PIN\n"); 905214734Srpaulo printf("Alternatively, six arguments can be used to " 906214734Srpaulo "reconfigure the AP:\n" 907252726Srpaulo "- BSSID of the target AP\n" 908214734Srpaulo "- AP PIN\n" 909214734Srpaulo "- new SSID\n" 910214734Srpaulo "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 911214734Srpaulo "- new encr (NONE, WEP, TKIP, CCMP)\n" 912214734Srpaulo "- new key\n"); 913189251Ssam return -1; 914189251Ssam } 915189251Ssam 916281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 917189251Ssam printf("Too long WPS_REG command.\n"); 918189251Ssam return -1; 919189251Ssam } 920189251Ssam return wpa_ctrl_command(ctrl, cmd); 921189251Ssam} 922189251Ssam 923189251Ssam 924252726Srpaulostatic int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc, 925252726Srpaulo char *argv[]) 926252726Srpaulo{ 927252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv); 928252726Srpaulo} 929252726Srpaulo 930252726Srpaulo 931214734Srpaulostatic int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc, 932214734Srpaulo char *argv[]) 933214734Srpaulo{ 934252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv); 935214734Srpaulo} 936214734Srpaulo 937214734Srpaulo 938214734Srpaulostatic int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc, 939214734Srpaulo char *argv[]) 940214734Srpaulo{ 941214734Srpaulo return wpa_ctrl_command(ctrl, "WPS_ER_STOP"); 942214734Srpaulo 943214734Srpaulo} 944214734Srpaulo 945214734Srpaulo 946214734Srpaulostatic int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc, 947214734Srpaulo char *argv[]) 948214734Srpaulo{ 949252726Srpaulo if (argc < 2) { 950252726Srpaulo printf("Invalid WPS_ER_PIN command: need at least two " 951252726Srpaulo "arguments:\n" 952214734Srpaulo "- UUID: use 'any' to select any\n" 953252726Srpaulo "- PIN: Enrollee PIN\n" 954252726Srpaulo "optional: - Enrollee MAC address\n"); 955214734Srpaulo return -1; 956214734Srpaulo } 957214734Srpaulo 958252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv); 959214734Srpaulo} 960214734Srpaulo 961214734Srpaulo 962214734Srpaulostatic int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc, 963214734Srpaulo char *argv[]) 964214734Srpaulo{ 965252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv); 966214734Srpaulo} 967214734Srpaulo 968214734Srpaulo 969214734Srpaulostatic int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc, 970214734Srpaulo char *argv[]) 971214734Srpaulo{ 972214734Srpaulo if (argc != 2) { 973214734Srpaulo printf("Invalid WPS_ER_LEARN command: need two arguments:\n" 974214734Srpaulo "- UUID: specify which AP to use\n" 975214734Srpaulo "- PIN: AP PIN\n"); 976214734Srpaulo return -1; 977214734Srpaulo } 978214734Srpaulo 979252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv); 980252726Srpaulo} 981252726Srpaulo 982252726Srpaulo 983252726Srpaulostatic int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc, 984252726Srpaulo char *argv[]) 985252726Srpaulo{ 986252726Srpaulo if (argc != 2) { 987252726Srpaulo printf("Invalid WPS_ER_SET_CONFIG command: need two " 988252726Srpaulo "arguments:\n" 989252726Srpaulo "- UUID: specify which AP to use\n" 990252726Srpaulo "- Network configuration id\n"); 991214734Srpaulo return -1; 992214734Srpaulo } 993252726Srpaulo 994252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv); 995214734Srpaulo} 996214734Srpaulo 997214734Srpaulo 998252726Srpaulostatic int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc, 999252726Srpaulo char *argv[]) 1000214734Srpaulo{ 1001214734Srpaulo char cmd[256]; 1002214734Srpaulo int res; 1003214734Srpaulo 1004252726Srpaulo if (argc == 5 || argc == 6) { 1005252726Srpaulo char ssid_hex[2 * 32 + 1]; 1006252726Srpaulo char key_hex[2 * 64 + 1]; 1007252726Srpaulo int i; 1008252726Srpaulo 1009252726Srpaulo ssid_hex[0] = '\0'; 1010252726Srpaulo for (i = 0; i < 32; i++) { 1011252726Srpaulo if (argv[2][i] == '\0') 1012252726Srpaulo break; 1013252726Srpaulo os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 1014252726Srpaulo } 1015252726Srpaulo 1016252726Srpaulo key_hex[0] = '\0'; 1017252726Srpaulo if (argc == 6) { 1018252726Srpaulo for (i = 0; i < 64; i++) { 1019252726Srpaulo if (argv[5][i] == '\0') 1020252726Srpaulo break; 1021252726Srpaulo os_snprintf(&key_hex[i * 2], 3, "%02x", 1022252726Srpaulo argv[5][i]); 1023252726Srpaulo } 1024252726Srpaulo } 1025252726Srpaulo 1026252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 1027252726Srpaulo "WPS_ER_CONFIG %s %s %s %s %s %s", 1028252726Srpaulo argv[0], argv[1], ssid_hex, argv[3], argv[4], 1029252726Srpaulo key_hex); 1030252726Srpaulo } else { 1031252726Srpaulo printf("Invalid WPS_ER_CONFIG command: need six arguments:\n" 1032252726Srpaulo "- AP UUID\n" 1033252726Srpaulo "- AP PIN\n" 1034252726Srpaulo "- new SSID\n" 1035252726Srpaulo "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 1036252726Srpaulo "- new encr (NONE, WEP, TKIP, CCMP)\n" 1037252726Srpaulo "- new key\n"); 1038214734Srpaulo return -1; 1039214734Srpaulo } 1040214734Srpaulo 1041281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 1042252726Srpaulo printf("Too long WPS_ER_CONFIG command.\n"); 1043214734Srpaulo return -1; 1044214734Srpaulo } 1045214734Srpaulo return wpa_ctrl_command(ctrl, cmd); 1046214734Srpaulo} 1047214734Srpaulo 1048214734Srpaulo 1049252726Srpaulo#ifdef CONFIG_WPS_NFC 1050252726Srpaulostatic int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 1051252726Srpaulo char *argv[]) 1052189251Ssam{ 1053252726Srpaulo if (argc != 2) { 1054252726Srpaulo printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two " 1055252726Srpaulo "arguments:\n" 1056252726Srpaulo "- WPS/NDEF: token format\n" 1057252726Srpaulo "- UUID: specify which AP to use\n"); 1058189251Ssam return -1; 1059189251Ssam } 1060252726Srpaulo 1061252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv); 1062189251Ssam} 1063252726Srpaulo#endif /* CONFIG_WPS_NFC */ 1064189251Ssam 1065189251Ssam 1066252726Srpaulostatic int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1067252726Srpaulo{ 1068252726Srpaulo return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv); 1069252726Srpaulo} 1070252726Srpaulo 1071252726Srpaulo 1072252726Srpaulostatic int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1073252726Srpaulo{ 1074252726Srpaulo return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv); 1075252726Srpaulo} 1076252726Srpaulo 1077252726Srpaulo 1078189251Ssamstatic int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1079189251Ssam{ 1080189251Ssam char cmd[256], *pos, *end; 1081189251Ssam int i, ret; 1082189251Ssam 1083189251Ssam if (argc < 2) { 1084189251Ssam printf("Invalid IDENTITY command: needs two arguments " 1085189251Ssam "(network id and identity)\n"); 1086189251Ssam return -1; 1087189251Ssam } 1088189251Ssam 1089189251Ssam end = cmd + sizeof(cmd); 1090189251Ssam pos = cmd; 1091189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s", 1092189251Ssam argv[0], argv[1]); 1093281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1094189251Ssam printf("Too long IDENTITY command.\n"); 1095189251Ssam return -1; 1096189251Ssam } 1097189251Ssam pos += ret; 1098189251Ssam for (i = 2; i < argc; i++) { 1099189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1100281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1101189251Ssam printf("Too long IDENTITY command.\n"); 1102189251Ssam return -1; 1103189251Ssam } 1104189251Ssam pos += ret; 1105189251Ssam } 1106189251Ssam 1107189251Ssam return wpa_ctrl_command(ctrl, cmd); 1108189251Ssam} 1109189251Ssam 1110189251Ssam 1111189251Ssamstatic int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1112189251Ssam{ 1113189251Ssam char cmd[256], *pos, *end; 1114189251Ssam int i, ret; 1115189251Ssam 1116189251Ssam if (argc < 2) { 1117189251Ssam printf("Invalid PASSWORD command: needs two arguments " 1118189251Ssam "(network id and password)\n"); 1119189251Ssam return -1; 1120189251Ssam } 1121189251Ssam 1122189251Ssam end = cmd + sizeof(cmd); 1123189251Ssam pos = cmd; 1124189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s", 1125189251Ssam argv[0], argv[1]); 1126281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1127189251Ssam printf("Too long PASSWORD command.\n"); 1128189251Ssam return -1; 1129189251Ssam } 1130189251Ssam pos += ret; 1131189251Ssam for (i = 2; i < argc; i++) { 1132189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1133281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1134189251Ssam printf("Too long PASSWORD command.\n"); 1135189251Ssam return -1; 1136189251Ssam } 1137189251Ssam pos += ret; 1138189251Ssam } 1139189251Ssam 1140189251Ssam return wpa_ctrl_command(ctrl, cmd); 1141189251Ssam} 1142189251Ssam 1143189251Ssam 1144189251Ssamstatic int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc, 1145189251Ssam char *argv[]) 1146189251Ssam{ 1147189251Ssam char cmd[256], *pos, *end; 1148189251Ssam int i, ret; 1149189251Ssam 1150189251Ssam if (argc < 2) { 1151189251Ssam printf("Invalid NEW_PASSWORD command: needs two arguments " 1152189251Ssam "(network id and password)\n"); 1153189251Ssam return -1; 1154189251Ssam } 1155189251Ssam 1156189251Ssam end = cmd + sizeof(cmd); 1157189251Ssam pos = cmd; 1158189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s", 1159189251Ssam argv[0], argv[1]); 1160281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1161189251Ssam printf("Too long NEW_PASSWORD command.\n"); 1162189251Ssam return -1; 1163189251Ssam } 1164189251Ssam pos += ret; 1165189251Ssam for (i = 2; i < argc; i++) { 1166189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1167281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1168189251Ssam printf("Too long NEW_PASSWORD command.\n"); 1169189251Ssam return -1; 1170189251Ssam } 1171189251Ssam pos += ret; 1172189251Ssam } 1173189251Ssam 1174189251Ssam return wpa_ctrl_command(ctrl, cmd); 1175189251Ssam} 1176189251Ssam 1177189251Ssam 1178189251Ssamstatic int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1179189251Ssam{ 1180189251Ssam char cmd[256], *pos, *end; 1181189251Ssam int i, ret; 1182189251Ssam 1183189251Ssam if (argc < 2) { 1184189251Ssam printf("Invalid PIN command: needs two arguments " 1185189251Ssam "(network id and pin)\n"); 1186189251Ssam return -1; 1187189251Ssam } 1188189251Ssam 1189189251Ssam end = cmd + sizeof(cmd); 1190189251Ssam pos = cmd; 1191189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s", 1192189251Ssam argv[0], argv[1]); 1193281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1194189251Ssam printf("Too long PIN command.\n"); 1195189251Ssam return -1; 1196189251Ssam } 1197189251Ssam pos += ret; 1198189251Ssam for (i = 2; i < argc; i++) { 1199189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1200281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1201189251Ssam printf("Too long PIN command.\n"); 1202189251Ssam return -1; 1203189251Ssam } 1204189251Ssam pos += ret; 1205189251Ssam } 1206189251Ssam return wpa_ctrl_command(ctrl, cmd); 1207189251Ssam} 1208189251Ssam 1209189251Ssam 1210189251Ssamstatic int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1211189251Ssam{ 1212189251Ssam char cmd[256], *pos, *end; 1213189251Ssam int i, ret; 1214189251Ssam 1215189251Ssam if (argc < 2) { 1216189251Ssam printf("Invalid OTP command: needs two arguments (network " 1217189251Ssam "id and password)\n"); 1218189251Ssam return -1; 1219189251Ssam } 1220189251Ssam 1221189251Ssam end = cmd + sizeof(cmd); 1222189251Ssam pos = cmd; 1223189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s", 1224189251Ssam argv[0], argv[1]); 1225281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1226189251Ssam printf("Too long OTP command.\n"); 1227189251Ssam return -1; 1228189251Ssam } 1229189251Ssam pos += ret; 1230189251Ssam for (i = 2; i < argc; i++) { 1231189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1232281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1233189251Ssam printf("Too long OTP command.\n"); 1234189251Ssam return -1; 1235189251Ssam } 1236189251Ssam pos += ret; 1237189251Ssam } 1238189251Ssam 1239189251Ssam return wpa_ctrl_command(ctrl, cmd); 1240189251Ssam} 1241189251Ssam 1242189251Ssam 1243281806Srpaulostatic int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1244281806Srpaulo{ 1245281806Srpaulo char cmd[256], *pos, *end; 1246281806Srpaulo int i, ret; 1247281806Srpaulo 1248281806Srpaulo if (argc < 2) { 1249281806Srpaulo printf("Invalid SIM command: needs two arguments " 1250281806Srpaulo "(network id and SIM operation response)\n"); 1251281806Srpaulo return -1; 1252281806Srpaulo } 1253281806Srpaulo 1254281806Srpaulo end = cmd + sizeof(cmd); 1255281806Srpaulo pos = cmd; 1256281806Srpaulo ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s", 1257281806Srpaulo argv[0], argv[1]); 1258281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1259281806Srpaulo printf("Too long SIM command.\n"); 1260281806Srpaulo return -1; 1261281806Srpaulo } 1262281806Srpaulo pos += ret; 1263281806Srpaulo for (i = 2; i < argc; i++) { 1264281806Srpaulo ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1265281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1266281806Srpaulo printf("Too long SIM command.\n"); 1267281806Srpaulo return -1; 1268281806Srpaulo } 1269281806Srpaulo pos += ret; 1270281806Srpaulo } 1271281806Srpaulo return wpa_ctrl_command(ctrl, cmd); 1272281806Srpaulo} 1273281806Srpaulo 1274281806Srpaulo 1275189251Ssamstatic int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc, 1276189251Ssam char *argv[]) 1277189251Ssam{ 1278189251Ssam char cmd[256], *pos, *end; 1279189251Ssam int i, ret; 1280189251Ssam 1281189251Ssam if (argc < 2) { 1282189251Ssam printf("Invalid PASSPHRASE command: needs two arguments " 1283189251Ssam "(network id and passphrase)\n"); 1284189251Ssam return -1; 1285189251Ssam } 1286189251Ssam 1287189251Ssam end = cmd + sizeof(cmd); 1288189251Ssam pos = cmd; 1289189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s", 1290189251Ssam argv[0], argv[1]); 1291281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1292189251Ssam printf("Too long PASSPHRASE command.\n"); 1293189251Ssam return -1; 1294189251Ssam } 1295189251Ssam pos += ret; 1296189251Ssam for (i = 2; i < argc; i++) { 1297189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1298281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1299189251Ssam printf("Too long PASSPHRASE command.\n"); 1300189251Ssam return -1; 1301189251Ssam } 1302189251Ssam pos += ret; 1303189251Ssam } 1304189251Ssam 1305189251Ssam return wpa_ctrl_command(ctrl, cmd); 1306189251Ssam} 1307189251Ssam 1308189251Ssam 1309189251Ssamstatic int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1310189251Ssam{ 1311189251Ssam if (argc < 2) { 1312189251Ssam printf("Invalid BSSID command: needs two arguments (network " 1313189251Ssam "id and BSSID)\n"); 1314189251Ssam return -1; 1315189251Ssam } 1316189251Ssam 1317252726Srpaulo return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv); 1318252726Srpaulo} 1319189251Ssam 1320252726Srpaulo 1321252726Srpaulostatic int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1322252726Srpaulo{ 1323252726Srpaulo return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv); 1324189251Ssam} 1325189251Ssam 1326189251Ssam 1327252726Srpaulostatic int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1328252726Srpaulo{ 1329252726Srpaulo return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv); 1330252726Srpaulo} 1331252726Srpaulo 1332252726Srpaulo 1333189251Ssamstatic int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc, 1334189251Ssam char *argv[]) 1335189251Ssam{ 1336189251Ssam return wpa_ctrl_command(ctrl, "LIST_NETWORKS"); 1337189251Ssam} 1338189251Ssam 1339189251Ssam 1340189251Ssamstatic int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc, 1341189251Ssam char *argv[]) 1342189251Ssam{ 1343252726Srpaulo return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv); 1344189251Ssam} 1345189251Ssam 1346189251Ssam 1347189251Ssamstatic int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc, 1348189251Ssam char *argv[]) 1349189251Ssam{ 1350252726Srpaulo return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv); 1351189251Ssam} 1352189251Ssam 1353189251Ssam 1354189251Ssamstatic int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc, 1355189251Ssam char *argv[]) 1356189251Ssam{ 1357252726Srpaulo return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv); 1358189251Ssam} 1359189251Ssam 1360189251Ssam 1361189251Ssamstatic int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc, 1362189251Ssam char *argv[]) 1363189251Ssam{ 1364189251Ssam return wpa_ctrl_command(ctrl, "ADD_NETWORK"); 1365189251Ssam} 1366189251Ssam 1367189251Ssam 1368189251Ssamstatic int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc, 1369189251Ssam char *argv[]) 1370189251Ssam{ 1371252726Srpaulo return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv); 1372189251Ssam} 1373189251Ssam 1374189251Ssam 1375189251Ssamstatic void wpa_cli_show_network_variables(void) 1376189251Ssam{ 1377189251Ssam printf("set_network variables:\n" 1378189251Ssam " ssid (network name, SSID)\n" 1379189251Ssam " psk (WPA passphrase or pre-shared key)\n" 1380189251Ssam " key_mgmt (key management protocol)\n" 1381189251Ssam " identity (EAP identity)\n" 1382189251Ssam " password (EAP password)\n" 1383189251Ssam " ...\n" 1384189251Ssam "\n" 1385189251Ssam "Note: Values are entered in the same format as the " 1386189251Ssam "configuration file is using,\n" 1387189251Ssam "i.e., strings values need to be inside double quotation " 1388189251Ssam "marks.\n" 1389189251Ssam "For example: set_network 1 ssid \"network name\"\n" 1390189251Ssam "\n" 1391189251Ssam "Please see wpa_supplicant.conf documentation for full list " 1392189251Ssam "of\navailable variables.\n"); 1393189251Ssam} 1394189251Ssam 1395189251Ssam 1396189251Ssamstatic int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc, 1397189251Ssam char *argv[]) 1398189251Ssam{ 1399189251Ssam if (argc == 0) { 1400189251Ssam wpa_cli_show_network_variables(); 1401189251Ssam return 0; 1402189251Ssam } 1403189251Ssam 1404252726Srpaulo if (argc < 3) { 1405189251Ssam printf("Invalid SET_NETWORK command: needs three arguments\n" 1406189251Ssam "(network id, variable name, and value)\n"); 1407189251Ssam return -1; 1408189251Ssam } 1409189251Ssam 1410252726Srpaulo return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv); 1411189251Ssam} 1412189251Ssam 1413189251Ssam 1414189251Ssamstatic int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc, 1415189251Ssam char *argv[]) 1416189251Ssam{ 1417189251Ssam if (argc == 0) { 1418189251Ssam wpa_cli_show_network_variables(); 1419189251Ssam return 0; 1420189251Ssam } 1421189251Ssam 1422189251Ssam if (argc != 2) { 1423189251Ssam printf("Invalid GET_NETWORK command: needs two arguments\n" 1424189251Ssam "(network id and variable name)\n"); 1425189251Ssam return -1; 1426189251Ssam } 1427189251Ssam 1428252726Srpaulo return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv); 1429252726Srpaulo} 1430252726Srpaulo 1431252726Srpaulo 1432281806Srpaulostatic int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc, 1433281806Srpaulo char *argv[]) 1434281806Srpaulo{ 1435281806Srpaulo if (argc == 0) { 1436281806Srpaulo wpa_cli_show_network_variables(); 1437281806Srpaulo return 0; 1438281806Srpaulo } 1439281806Srpaulo 1440281806Srpaulo if (argc < 3) { 1441281806Srpaulo printf("Invalid DUP_NETWORK command: needs three arguments\n" 1442281806Srpaulo "(src netid, dest netid, and variable name)\n"); 1443281806Srpaulo return -1; 1444281806Srpaulo } 1445281806Srpaulo 1446281806Srpaulo return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv); 1447281806Srpaulo} 1448281806Srpaulo 1449281806Srpaulo 1450252726Srpaulostatic int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc, 1451252726Srpaulo char *argv[]) 1452252726Srpaulo{ 1453252726Srpaulo return wpa_ctrl_command(ctrl, "LIST_CREDS"); 1454252726Srpaulo} 1455252726Srpaulo 1456252726Srpaulo 1457252726Srpaulostatic int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1458252726Srpaulo{ 1459252726Srpaulo return wpa_ctrl_command(ctrl, "ADD_CRED"); 1460252726Srpaulo} 1461252726Srpaulo 1462252726Srpaulo 1463252726Srpaulostatic int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc, 1464252726Srpaulo char *argv[]) 1465252726Srpaulo{ 1466252726Srpaulo return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv); 1467252726Srpaulo} 1468252726Srpaulo 1469252726Srpaulo 1470252726Srpaulostatic int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1471252726Srpaulo{ 1472252726Srpaulo if (argc != 3) { 1473252726Srpaulo printf("Invalid SET_CRED command: needs three arguments\n" 1474252726Srpaulo "(cred id, variable name, and value)\n"); 1475189251Ssam return -1; 1476189251Ssam } 1477252726Srpaulo 1478252726Srpaulo return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv); 1479189251Ssam} 1480189251Ssam 1481189251Ssam 1482281806Srpaulostatic int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1483281806Srpaulo{ 1484281806Srpaulo if (argc != 2) { 1485281806Srpaulo printf("Invalid GET_CRED command: needs two arguments\n" 1486281806Srpaulo "(cred id, variable name)\n"); 1487281806Srpaulo return -1; 1488281806Srpaulo } 1489281806Srpaulo 1490281806Srpaulo return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv); 1491281806Srpaulo} 1492281806Srpaulo 1493281806Srpaulo 1494189251Ssamstatic int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc, 1495189251Ssam char *argv[]) 1496189251Ssam{ 1497189251Ssam return wpa_ctrl_command(ctrl, "DISCONNECT"); 1498189251Ssam} 1499189251Ssam 1500189251Ssam 1501189251Ssamstatic int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc, 1502189251Ssam char *argv[]) 1503189251Ssam{ 1504189251Ssam return wpa_ctrl_command(ctrl, "RECONNECT"); 1505189251Ssam} 1506189251Ssam 1507189251Ssam 1508189251Ssamstatic int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc, 1509189251Ssam char *argv[]) 1510189251Ssam{ 1511189251Ssam return wpa_ctrl_command(ctrl, "SAVE_CONFIG"); 1512189251Ssam} 1513189251Ssam 1514189251Ssam 1515189251Ssamstatic int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1516189251Ssam{ 1517281806Srpaulo return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv); 1518189251Ssam} 1519189251Ssam 1520189251Ssam 1521189251Ssamstatic int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc, 1522189251Ssam char *argv[]) 1523189251Ssam{ 1524189251Ssam return wpa_ctrl_command(ctrl, "SCAN_RESULTS"); 1525189251Ssam} 1526189251Ssam 1527189251Ssam 1528189251Ssamstatic int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1529189251Ssam{ 1530252726Srpaulo return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv); 1531252726Srpaulo} 1532189251Ssam 1533252726Srpaulo 1534252726Srpaulostatic char ** wpa_cli_complete_bss(const char *str, int pos) 1535252726Srpaulo{ 1536252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1537252726Srpaulo char **res = NULL; 1538252726Srpaulo 1539252726Srpaulo switch (arg) { 1540252726Srpaulo case 1: 1541252726Srpaulo res = cli_txt_list_array(&bsses); 1542252726Srpaulo break; 1543189251Ssam } 1544189251Ssam 1545252726Srpaulo return res; 1546189251Ssam} 1547189251Ssam 1548189251Ssam 1549189251Ssamstatic int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc, 1550189251Ssam char *argv[]) 1551189251Ssam{ 1552189251Ssam if (argc < 1 || argc > 2) { 1553189251Ssam printf("Invalid GET_CAPABILITY command: need either one or " 1554189251Ssam "two arguments\n"); 1555189251Ssam return -1; 1556189251Ssam } 1557189251Ssam 1558189251Ssam if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) { 1559189251Ssam printf("Invalid GET_CAPABILITY command: second argument, " 1560189251Ssam "if any, must be 'strict'\n"); 1561189251Ssam return -1; 1562189251Ssam } 1563189251Ssam 1564252726Srpaulo return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv); 1565189251Ssam} 1566189251Ssam 1567189251Ssam 1568189251Ssamstatic int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl) 1569189251Ssam{ 1570189251Ssam printf("Available interfaces:\n"); 1571189251Ssam return wpa_ctrl_command(ctrl, "INTERFACES"); 1572189251Ssam} 1573189251Ssam 1574189251Ssam 1575189251Ssamstatic int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1576189251Ssam{ 1577189251Ssam if (argc < 1) { 1578189251Ssam wpa_cli_list_interfaces(ctrl); 1579189251Ssam return 0; 1580189251Ssam } 1581189251Ssam 1582189251Ssam wpa_cli_close_connection(); 1583189251Ssam os_free(ctrl_ifname); 1584189251Ssam ctrl_ifname = os_strdup(argv[0]); 1585281806Srpaulo if (!ctrl_ifname) { 1586281806Srpaulo printf("Failed to allocate memory\n"); 1587281806Srpaulo return 0; 1588281806Srpaulo } 1589189251Ssam 1590281806Srpaulo if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) { 1591189251Ssam printf("Connected to interface '%s.\n", ctrl_ifname); 1592189251Ssam } else { 1593189251Ssam printf("Could not connect to interface '%s' - re-trying\n", 1594189251Ssam ctrl_ifname); 1595189251Ssam } 1596189251Ssam return 0; 1597189251Ssam} 1598189251Ssam 1599189251Ssam 1600189251Ssamstatic int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc, 1601189251Ssam char *argv[]) 1602189251Ssam{ 1603189251Ssam return wpa_ctrl_command(ctrl, "RECONFIGURE"); 1604189251Ssam} 1605189251Ssam 1606189251Ssam 1607189251Ssamstatic int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc, 1608189251Ssam char *argv[]) 1609189251Ssam{ 1610189251Ssam return wpa_ctrl_command(ctrl, "TERMINATE"); 1611189251Ssam} 1612189251Ssam 1613189251Ssam 1614189251Ssamstatic int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc, 1615189251Ssam char *argv[]) 1616189251Ssam{ 1617189251Ssam char cmd[256]; 1618189251Ssam int res; 1619189251Ssam 1620189251Ssam if (argc < 1) { 1621189251Ssam printf("Invalid INTERFACE_ADD command: needs at least one " 1622189251Ssam "argument (interface name)\n" 1623189251Ssam "All arguments: ifname confname driver ctrl_interface " 1624189251Ssam "driver_param bridge_name\n"); 1625189251Ssam return -1; 1626189251Ssam } 1627189251Ssam 1628189251Ssam /* 1629189251Ssam * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB 1630189251Ssam * <driver_param>TAB<bridge_name> 1631189251Ssam */ 1632189251Ssam res = os_snprintf(cmd, sizeof(cmd), 1633189251Ssam "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s", 1634189251Ssam argv[0], 1635189251Ssam argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "", 1636189251Ssam argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "", 1637189251Ssam argc > 5 ? argv[5] : ""); 1638281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 1639189251Ssam return -1; 1640189251Ssam cmd[sizeof(cmd) - 1] = '\0'; 1641189251Ssam return wpa_ctrl_command(ctrl, cmd); 1642189251Ssam} 1643189251Ssam 1644189251Ssam 1645189251Ssamstatic int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc, 1646189251Ssam char *argv[]) 1647189251Ssam{ 1648252726Srpaulo return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv); 1649189251Ssam} 1650189251Ssam 1651189251Ssam 1652189251Ssamstatic int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc, 1653189251Ssam char *argv[]) 1654189251Ssam{ 1655189251Ssam return wpa_ctrl_command(ctrl, "INTERFACE_LIST"); 1656189251Ssam} 1657189251Ssam 1658189251Ssam 1659214734Srpaulo#ifdef CONFIG_AP 1660214734Srpaulostatic int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1661214734Srpaulo{ 1662252726Srpaulo return wpa_cli_cmd(ctrl, "STA", 1, argc, argv); 1663214734Srpaulo} 1664214734Srpaulo 1665214734Srpaulo 1666214734Srpaulostatic int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd, 1667214734Srpaulo char *addr, size_t addr_len) 1668214734Srpaulo{ 1669214734Srpaulo char buf[4096], *pos; 1670214734Srpaulo size_t len; 1671214734Srpaulo int ret; 1672214734Srpaulo 1673214734Srpaulo if (ctrl_conn == NULL) { 1674214734Srpaulo printf("Not connected to hostapd - command dropped.\n"); 1675214734Srpaulo return -1; 1676214734Srpaulo } 1677214734Srpaulo len = sizeof(buf) - 1; 1678252726Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 1679214734Srpaulo wpa_cli_msg_cb); 1680214734Srpaulo if (ret == -2) { 1681214734Srpaulo printf("'%s' command timed out.\n", cmd); 1682214734Srpaulo return -2; 1683214734Srpaulo } else if (ret < 0) { 1684214734Srpaulo printf("'%s' command failed.\n", cmd); 1685214734Srpaulo return -1; 1686214734Srpaulo } 1687214734Srpaulo 1688214734Srpaulo buf[len] = '\0'; 1689252726Srpaulo if (os_memcmp(buf, "FAIL", 4) == 0) 1690214734Srpaulo return -1; 1691214734Srpaulo printf("%s", buf); 1692214734Srpaulo 1693214734Srpaulo pos = buf; 1694214734Srpaulo while (*pos != '\0' && *pos != '\n') 1695214734Srpaulo pos++; 1696214734Srpaulo *pos = '\0'; 1697214734Srpaulo os_strlcpy(addr, buf, addr_len); 1698214734Srpaulo return 0; 1699214734Srpaulo} 1700214734Srpaulo 1701214734Srpaulo 1702214734Srpaulostatic int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1703214734Srpaulo{ 1704214734Srpaulo char addr[32], cmd[64]; 1705214734Srpaulo 1706214734Srpaulo if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr))) 1707214734Srpaulo return 0; 1708214734Srpaulo do { 1709214734Srpaulo os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 1710214734Srpaulo } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0); 1711214734Srpaulo 1712214734Srpaulo return -1; 1713214734Srpaulo} 1714252726Srpaulo 1715252726Srpaulo 1716252726Srpaulostatic int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc, 1717252726Srpaulo char *argv[]) 1718252726Srpaulo{ 1719252726Srpaulo return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv); 1720252726Srpaulo} 1721252726Srpaulo 1722252726Srpaulo 1723252726Srpaulostatic int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, 1724252726Srpaulo char *argv[]) 1725252726Srpaulo{ 1726252726Srpaulo return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv); 1727252726Srpaulo} 1728281806Srpaulo 1729281806Srpaulostatic int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc, 1730281806Srpaulo char *argv[]) 1731281806Srpaulo{ 1732281806Srpaulo return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv); 1733281806Srpaulo} 1734281806Srpaulo 1735214734Srpaulo#endif /* CONFIG_AP */ 1736214734Srpaulo 1737214734Srpaulo 1738214734Srpaulostatic int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1739214734Srpaulo{ 1740214734Srpaulo return wpa_ctrl_command(ctrl, "SUSPEND"); 1741214734Srpaulo} 1742214734Srpaulo 1743214734Srpaulo 1744214734Srpaulostatic int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1745214734Srpaulo{ 1746214734Srpaulo return wpa_ctrl_command(ctrl, "RESUME"); 1747214734Srpaulo} 1748214734Srpaulo 1749214734Srpaulo 1750281806Srpaulo#ifdef CONFIG_TESTING_OPTIONS 1751214734Srpaulostatic int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1752214734Srpaulo{ 1753214734Srpaulo return wpa_ctrl_command(ctrl, "DROP_SA"); 1754214734Srpaulo} 1755281806Srpaulo#endif /* CONFIG_TESTING_OPTIONS */ 1756214734Srpaulo 1757214734Srpaulo 1758214734Srpaulostatic int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1759214734Srpaulo{ 1760252726Srpaulo return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv); 1761252726Srpaulo} 1762252726Srpaulo 1763252726Srpaulo 1764281806Srpaulo#ifdef CONFIG_MESH 1765281806Srpaulo 1766281806Srpaulostatic int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc, 1767281806Srpaulo char *argv[]) 1768281806Srpaulo{ 1769281806Srpaulo return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv); 1770281806Srpaulo} 1771281806Srpaulo 1772281806Srpaulo 1773281806Srpaulostatic int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc, 1774281806Srpaulo char *argv[]) 1775281806Srpaulo{ 1776281806Srpaulo return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv); 1777281806Srpaulo} 1778281806Srpaulo 1779281806Srpaulo 1780281806Srpaulostatic int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc, 1781281806Srpaulo char *argv[]) 1782281806Srpaulo{ 1783281806Srpaulo return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv); 1784281806Srpaulo} 1785281806Srpaulo 1786281806Srpaulo#endif /* CONFIG_MESH */ 1787281806Srpaulo 1788281806Srpaulo 1789252726Srpaulo#ifdef CONFIG_P2P 1790252726Srpaulo 1791252726Srpaulostatic int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1792252726Srpaulo{ 1793252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv); 1794252726Srpaulo} 1795252726Srpaulo 1796252726Srpaulo 1797252726Srpaulostatic char ** wpa_cli_complete_p2p_find(const char *str, int pos) 1798252726Srpaulo{ 1799252726Srpaulo char **res = NULL; 1800252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1801252726Srpaulo 1802252726Srpaulo res = os_calloc(6, sizeof(char *)); 1803252726Srpaulo if (res == NULL) 1804252726Srpaulo return NULL; 1805252726Srpaulo res[0] = os_strdup("type=social"); 1806252726Srpaulo if (res[0] == NULL) { 1807252726Srpaulo os_free(res); 1808252726Srpaulo return NULL; 1809252726Srpaulo } 1810252726Srpaulo res[1] = os_strdup("type=progressive"); 1811252726Srpaulo if (res[1] == NULL) 1812252726Srpaulo return res; 1813252726Srpaulo res[2] = os_strdup("delay="); 1814252726Srpaulo if (res[2] == NULL) 1815252726Srpaulo return res; 1816252726Srpaulo res[3] = os_strdup("dev_id="); 1817252726Srpaulo if (res[3] == NULL) 1818252726Srpaulo return res; 1819252726Srpaulo if (arg == 1) 1820252726Srpaulo res[4] = os_strdup("[timeout]"); 1821252726Srpaulo 1822252726Srpaulo return res; 1823252726Srpaulo} 1824252726Srpaulo 1825252726Srpaulo 1826252726Srpaulostatic int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc, 1827252726Srpaulo char *argv[]) 1828252726Srpaulo{ 1829252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_STOP_FIND"); 1830252726Srpaulo} 1831252726Srpaulo 1832252726Srpaulo 1833281806Srpaulostatic int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc, 1834281806Srpaulo char *argv[]) 1835281806Srpaulo{ 1836281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv); 1837281806Srpaulo} 1838281806Srpaulo 1839281806Srpaulo 1840281806Srpaulostatic int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc, 1841281806Srpaulo char *argv[]) 1842281806Srpaulo{ 1843281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv); 1844281806Srpaulo} 1845281806Srpaulo 1846281806Srpaulo 1847252726Srpaulostatic int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc, 1848252726Srpaulo char *argv[]) 1849252726Srpaulo{ 1850252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv); 1851252726Srpaulo} 1852252726Srpaulo 1853252726Srpaulo 1854252726Srpaulostatic char ** wpa_cli_complete_p2p_connect(const char *str, int pos) 1855252726Srpaulo{ 1856252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1857252726Srpaulo char **res = NULL; 1858252726Srpaulo 1859252726Srpaulo switch (arg) { 1860252726Srpaulo case 1: 1861252726Srpaulo res = cli_txt_list_array(&p2p_peers); 1862252726Srpaulo break; 1863252726Srpaulo } 1864252726Srpaulo 1865252726Srpaulo return res; 1866252726Srpaulo} 1867252726Srpaulo 1868252726Srpaulo 1869252726Srpaulostatic int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc, 1870252726Srpaulo char *argv[]) 1871252726Srpaulo{ 1872252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv); 1873252726Srpaulo} 1874252726Srpaulo 1875252726Srpaulo 1876252726Srpaulostatic int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc, 1877252726Srpaulo char *argv[]) 1878252726Srpaulo{ 1879252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv); 1880252726Srpaulo} 1881252726Srpaulo 1882252726Srpaulo 1883252726Srpaulostatic char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos) 1884252726Srpaulo{ 1885252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1886252726Srpaulo char **res = NULL; 1887252726Srpaulo 1888252726Srpaulo switch (arg) { 1889252726Srpaulo case 1: 1890252726Srpaulo res = cli_txt_list_array(&p2p_groups); 1891252726Srpaulo break; 1892252726Srpaulo } 1893252726Srpaulo 1894252726Srpaulo return res; 1895252726Srpaulo} 1896252726Srpaulo 1897252726Srpaulo 1898252726Srpaulostatic int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc, 1899252726Srpaulo char *argv[]) 1900252726Srpaulo{ 1901252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv); 1902252726Srpaulo} 1903252726Srpaulo 1904252726Srpaulo 1905252726Srpaulostatic int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc, 1906252726Srpaulo char *argv[]) 1907252726Srpaulo{ 1908252726Srpaulo if (argc != 2 && argc != 3) { 1909252726Srpaulo printf("Invalid P2P_PROV_DISC command: needs at least " 1910252726Srpaulo "two arguments, address and config method\n" 1911252726Srpaulo "(display, keypad, or pbc) and an optional join\n"); 1912252726Srpaulo return -1; 1913252726Srpaulo } 1914252726Srpaulo 1915252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv); 1916252726Srpaulo} 1917252726Srpaulo 1918252726Srpaulo 1919252726Srpaulostatic int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc, 1920252726Srpaulo char *argv[]) 1921252726Srpaulo{ 1922252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE"); 1923252726Srpaulo} 1924252726Srpaulo 1925252726Srpaulo 1926252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc, 1927252726Srpaulo char *argv[]) 1928252726Srpaulo{ 1929252726Srpaulo char cmd[4096]; 1930252726Srpaulo 1931281806Srpaulo if (argc < 2) { 1932252726Srpaulo printf("Invalid P2P_SERV_DISC_REQ command: needs two " 1933281806Srpaulo "or more arguments (address and TLVs)\n"); 1934252726Srpaulo return -1; 1935252726Srpaulo } 1936252726Srpaulo 1937252726Srpaulo if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0) 1938252726Srpaulo return -1; 1939252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 1940252726Srpaulo} 1941252726Srpaulo 1942252726Srpaulo 1943252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl, 1944252726Srpaulo int argc, char *argv[]) 1945252726Srpaulo{ 1946252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv); 1947252726Srpaulo} 1948252726Srpaulo 1949252726Srpaulo 1950252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc, 1951252726Srpaulo char *argv[]) 1952252726Srpaulo{ 1953252726Srpaulo char cmd[4096]; 1954214734Srpaulo int res; 1955214734Srpaulo 1956252726Srpaulo if (argc != 4) { 1957252726Srpaulo printf("Invalid P2P_SERV_DISC_RESP command: needs four " 1958252726Srpaulo "arguments (freq, address, dialog token, and TLVs)\n"); 1959252726Srpaulo return -1; 1960252726Srpaulo } 1961252726Srpaulo 1962252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s", 1963252726Srpaulo argv[0], argv[1], argv[2], argv[3]); 1964281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 1965252726Srpaulo return -1; 1966252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 1967252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 1968252726Srpaulo} 1969252726Srpaulo 1970252726Srpaulo 1971252726Srpaulostatic int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc, 1972252726Srpaulo char *argv[]) 1973252726Srpaulo{ 1974252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE"); 1975252726Srpaulo} 1976252726Srpaulo 1977252726Srpaulo 1978252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl, 1979252726Srpaulo int argc, char *argv[]) 1980252726Srpaulo{ 1981252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv); 1982252726Srpaulo} 1983252726Srpaulo 1984252726Srpaulo 1985252726Srpaulostatic int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc, 1986252726Srpaulo char *argv[]) 1987252726Srpaulo{ 1988252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH"); 1989252726Srpaulo} 1990252726Srpaulo 1991252726Srpaulo 1992252726Srpaulostatic int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc, 1993252726Srpaulo char *argv[]) 1994252726Srpaulo{ 1995281806Srpaulo if (argc < 3) { 1996281806Srpaulo printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n"); 1997281806Srpaulo return -1; 1998281806Srpaulo } 1999252726Srpaulo 2000281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv); 2001281806Srpaulo} 2002281806Srpaulo 2003281806Srpaulo 2004281806Srpaulostatic int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc, 2005281806Srpaulo char *argv[]) 2006281806Srpaulo{ 2007281806Srpaulo if (argc < 5 || argc > 6) { 2008281806Srpaulo printf("Invalid P2P_SERVICE_REP command: needs 5-6 " 2009252726Srpaulo "arguments\n"); 2010252726Srpaulo return -1; 2011252726Srpaulo } 2012252726Srpaulo 2013281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv); 2014252726Srpaulo} 2015252726Srpaulo 2016252726Srpaulo 2017252726Srpaulostatic int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc, 2018252726Srpaulo char *argv[]) 2019252726Srpaulo{ 2020252726Srpaulo char cmd[4096]; 2021252726Srpaulo int res; 2022252726Srpaulo 2023252726Srpaulo if (argc != 2 && argc != 3) { 2024252726Srpaulo printf("Invalid P2P_SERVICE_DEL command: needs two or three " 2025252726Srpaulo "arguments\n"); 2026252726Srpaulo return -1; 2027252726Srpaulo } 2028252726Srpaulo 2029252726Srpaulo if (argc == 3) 2030252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 2031252726Srpaulo "P2P_SERVICE_DEL %s %s %s", 2032252726Srpaulo argv[0], argv[1], argv[2]); 2033252726Srpaulo else 2034252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 2035252726Srpaulo "P2P_SERVICE_DEL %s %s", 2036252726Srpaulo argv[0], argv[1]); 2037281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2038252726Srpaulo return -1; 2039252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2040252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2041252726Srpaulo} 2042252726Srpaulo 2043252726Srpaulo 2044252726Srpaulostatic int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl, 2045252726Srpaulo int argc, char *argv[]) 2046252726Srpaulo{ 2047252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv); 2048252726Srpaulo} 2049252726Srpaulo 2050252726Srpaulo 2051252726Srpaulostatic int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl, 2052252726Srpaulo int argc, char *argv[]) 2053252726Srpaulo{ 2054252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv); 2055252726Srpaulo} 2056252726Srpaulo 2057252726Srpaulo 2058252726Srpaulostatic int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2059252726Srpaulo{ 2060252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv); 2061252726Srpaulo} 2062252726Srpaulo 2063252726Srpaulo 2064252726Srpaulostatic char ** wpa_cli_complete_p2p_peer(const char *str, int pos) 2065252726Srpaulo{ 2066252726Srpaulo int arg = get_cmd_arg_num(str, pos); 2067252726Srpaulo char **res = NULL; 2068252726Srpaulo 2069252726Srpaulo switch (arg) { 2070252726Srpaulo case 1: 2071252726Srpaulo res = cli_txt_list_array(&p2p_peers); 2072252726Srpaulo break; 2073252726Srpaulo } 2074252726Srpaulo 2075252726Srpaulo return res; 2076252726Srpaulo} 2077252726Srpaulo 2078252726Srpaulo 2079252726Srpaulostatic int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd, 2080252726Srpaulo char *addr, size_t addr_len, 2081252726Srpaulo int discovered) 2082252726Srpaulo{ 2083252726Srpaulo char buf[4096], *pos; 2084252726Srpaulo size_t len; 2085252726Srpaulo int ret; 2086252726Srpaulo 2087252726Srpaulo if (ctrl_conn == NULL) 2088252726Srpaulo return -1; 2089252726Srpaulo len = sizeof(buf) - 1; 2090252726Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 2091252726Srpaulo wpa_cli_msg_cb); 2092252726Srpaulo if (ret == -2) { 2093252726Srpaulo printf("'%s' command timed out.\n", cmd); 2094252726Srpaulo return -2; 2095252726Srpaulo } else if (ret < 0) { 2096252726Srpaulo printf("'%s' command failed.\n", cmd); 2097252726Srpaulo return -1; 2098252726Srpaulo } 2099252726Srpaulo 2100252726Srpaulo buf[len] = '\0'; 2101252726Srpaulo if (os_memcmp(buf, "FAIL", 4) == 0) 2102252726Srpaulo return -1; 2103252726Srpaulo 2104252726Srpaulo pos = buf; 2105252726Srpaulo while (*pos != '\0' && *pos != '\n') 2106252726Srpaulo pos++; 2107252726Srpaulo *pos++ = '\0'; 2108252726Srpaulo os_strlcpy(addr, buf, addr_len); 2109252726Srpaulo if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL) 2110252726Srpaulo printf("%s\n", addr); 2111252726Srpaulo return 0; 2112252726Srpaulo} 2113252726Srpaulo 2114252726Srpaulo 2115252726Srpaulostatic int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2116252726Srpaulo{ 2117252726Srpaulo char addr[32], cmd[64]; 2118252726Srpaulo int discovered; 2119252726Srpaulo 2120252726Srpaulo discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0; 2121252726Srpaulo 2122252726Srpaulo if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST", 2123252726Srpaulo addr, sizeof(addr), discovered)) 2124252726Srpaulo return -1; 2125252726Srpaulo do { 2126252726Srpaulo os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr); 2127252726Srpaulo } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr), 2128252726Srpaulo discovered) == 0); 2129252726Srpaulo 2130252726Srpaulo return 0; 2131252726Srpaulo} 2132252726Srpaulo 2133252726Srpaulo 2134252726Srpaulostatic int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2135252726Srpaulo{ 2136252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv); 2137252726Srpaulo} 2138252726Srpaulo 2139252726Srpaulo 2140281806Srpaulostatic char ** wpa_cli_complete_p2p_set(const char *str, int pos) 2141281806Srpaulo{ 2142281806Srpaulo int arg = get_cmd_arg_num(str, pos); 2143281806Srpaulo const char *fields[] = { 2144281806Srpaulo "discoverability", 2145281806Srpaulo "managed", 2146281806Srpaulo "listen_channel", 2147281806Srpaulo "ssid_postfix", 2148281806Srpaulo "noa", 2149281806Srpaulo "ps", 2150281806Srpaulo "oppps", 2151281806Srpaulo "ctwindow", 2152281806Srpaulo "disabled", 2153281806Srpaulo "conc_pref", 2154281806Srpaulo "force_long_sd", 2155281806Srpaulo "peer_filter", 2156281806Srpaulo "cross_connect", 2157281806Srpaulo "go_apsd", 2158281806Srpaulo "client_apsd", 2159281806Srpaulo "disallow_freq", 2160281806Srpaulo "disc_int", 2161281806Srpaulo "per_sta_psk", 2162281806Srpaulo }; 2163281806Srpaulo int i, num_fields = ARRAY_SIZE(fields); 2164281806Srpaulo 2165281806Srpaulo if (arg == 1) { 2166281806Srpaulo char **res = os_calloc(num_fields + 1, sizeof(char *)); 2167281806Srpaulo if (res == NULL) 2168281806Srpaulo return NULL; 2169281806Srpaulo for (i = 0; i < num_fields; i++) { 2170281806Srpaulo res[i] = os_strdup(fields[i]); 2171281806Srpaulo if (res[i] == NULL) 2172281806Srpaulo return res; 2173281806Srpaulo } 2174281806Srpaulo return res; 2175281806Srpaulo } 2176281806Srpaulo 2177281806Srpaulo if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0) 2178281806Srpaulo return cli_txt_list_array(&p2p_peers); 2179281806Srpaulo 2180281806Srpaulo return NULL; 2181281806Srpaulo} 2182281806Srpaulo 2183281806Srpaulo 2184252726Srpaulostatic int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2185252726Srpaulo{ 2186252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_FLUSH"); 2187252726Srpaulo} 2188252726Srpaulo 2189252726Srpaulo 2190252726Srpaulostatic int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc, 2191252726Srpaulo char *argv[]) 2192252726Srpaulo{ 2193252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_CANCEL"); 2194252726Srpaulo} 2195252726Srpaulo 2196252726Srpaulo 2197252726Srpaulostatic int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc, 2198252726Srpaulo char *argv[]) 2199252726Srpaulo{ 2200252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv); 2201252726Srpaulo} 2202252726Srpaulo 2203252726Srpaulo 2204252726Srpaulostatic int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, 2205252726Srpaulo char *argv[]) 2206252726Srpaulo{ 2207252726Srpaulo if (argc != 0 && argc != 2 && argc != 4) { 2208252726Srpaulo printf("Invalid P2P_PRESENCE_REQ command: needs two arguments " 2209252726Srpaulo "(preferred duration, interval; in microsecods).\n" 2210252726Srpaulo "Optional second pair can be used to provide " 2211252726Srpaulo "acceptable values.\n"); 2212252726Srpaulo return -1; 2213252726Srpaulo } 2214252726Srpaulo 2215252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv); 2216252726Srpaulo} 2217252726Srpaulo 2218252726Srpaulo 2219252726Srpaulostatic int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc, 2220252726Srpaulo char *argv[]) 2221252726Srpaulo{ 2222252726Srpaulo if (argc != 0 && argc != 2) { 2223252726Srpaulo printf("Invalid P2P_EXT_LISTEN command: needs two arguments " 2224252726Srpaulo "(availability period, availability interval; in " 2225252726Srpaulo "millisecods).\n" 2226252726Srpaulo "Extended Listen Timing can be cancelled with this " 2227252726Srpaulo "command when used without parameters.\n"); 2228252726Srpaulo return -1; 2229252726Srpaulo } 2230252726Srpaulo 2231252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv); 2232252726Srpaulo} 2233252726Srpaulo 2234281806Srpaulo 2235281806Srpaulostatic int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc, 2236281806Srpaulo char *argv[]) 2237281806Srpaulo{ 2238281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv); 2239281806Srpaulo} 2240281806Srpaulo 2241252726Srpaulo#endif /* CONFIG_P2P */ 2242252726Srpaulo 2243252726Srpaulo#ifdef CONFIG_WIFI_DISPLAY 2244252726Srpaulo 2245252726Srpaulostatic int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc, 2246252726Srpaulo char *argv[]) 2247252726Srpaulo{ 2248252726Srpaulo char cmd[100]; 2249252726Srpaulo int res; 2250252726Srpaulo 2251252726Srpaulo if (argc != 1 && argc != 2) { 2252252726Srpaulo printf("Invalid WFD_SUBELEM_SET command: needs one or two " 2253252726Srpaulo "arguments (subelem, hexdump)\n"); 2254252726Srpaulo return -1; 2255252726Srpaulo } 2256252726Srpaulo 2257252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s", 2258252726Srpaulo argv[0], argc > 1 ? argv[1] : ""); 2259281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2260252726Srpaulo return -1; 2261252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2262252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2263252726Srpaulo} 2264252726Srpaulo 2265252726Srpaulo 2266252726Srpaulostatic int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc, 2267252726Srpaulo char *argv[]) 2268252726Srpaulo{ 2269252726Srpaulo char cmd[100]; 2270252726Srpaulo int res; 2271252726Srpaulo 2272214734Srpaulo if (argc != 1) { 2273252726Srpaulo printf("Invalid WFD_SUBELEM_GET command: needs one " 2274252726Srpaulo "argument (subelem)\n"); 2275214734Srpaulo return -1; 2276214734Srpaulo } 2277214734Srpaulo 2278252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s", 2279252726Srpaulo argv[0]); 2280281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2281214734Srpaulo return -1; 2282252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2283252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2284252726Srpaulo} 2285252726Srpaulo#endif /* CONFIG_WIFI_DISPLAY */ 2286252726Srpaulo 2287252726Srpaulo 2288252726Srpaulo#ifdef CONFIG_INTERWORKING 2289252726Srpaulostatic int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2290252726Srpaulo char *argv[]) 2291252726Srpaulo{ 2292252726Srpaulo return wpa_ctrl_command(ctrl, "FETCH_ANQP"); 2293252726Srpaulo} 2294252726Srpaulo 2295252726Srpaulo 2296252726Srpaulostatic int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2297252726Srpaulo char *argv[]) 2298252726Srpaulo{ 2299252726Srpaulo return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP"); 2300252726Srpaulo} 2301252726Srpaulo 2302252726Srpaulo 2303252726Srpaulostatic int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc, 2304252726Srpaulo char *argv[]) 2305252726Srpaulo{ 2306252726Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv); 2307252726Srpaulo} 2308252726Srpaulo 2309252726Srpaulo 2310252726Srpaulostatic int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc, 2311252726Srpaulo char *argv[]) 2312252726Srpaulo{ 2313252726Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv); 2314252726Srpaulo} 2315252726Srpaulo 2316252726Srpaulo 2317281806Srpaulostatic int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc, 2318281806Srpaulo char *argv[]) 2319281806Srpaulo{ 2320281806Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv); 2321281806Srpaulo} 2322281806Srpaulo 2323281806Srpaulo 2324252726Srpaulostatic int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2325252726Srpaulo{ 2326252726Srpaulo return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv); 2327252726Srpaulo} 2328252726Srpaulo 2329252726Srpaulo 2330252726Srpaulostatic int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc, 2331252726Srpaulo char *argv[]) 2332252726Srpaulo{ 2333252726Srpaulo return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv); 2334252726Srpaulo} 2335252726Srpaulo 2336252726Srpaulo 2337252726Srpaulostatic int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc, 2338252726Srpaulo char *argv[]) 2339252726Srpaulo{ 2340252726Srpaulo return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv); 2341252726Srpaulo} 2342252726Srpaulo#endif /* CONFIG_INTERWORKING */ 2343252726Srpaulo 2344252726Srpaulo 2345252726Srpaulo#ifdef CONFIG_HS20 2346252726Srpaulo 2347252726Srpaulostatic int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc, 2348252726Srpaulo char *argv[]) 2349252726Srpaulo{ 2350252726Srpaulo return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv); 2351252726Srpaulo} 2352252726Srpaulo 2353252726Srpaulo 2354252726Srpaulostatic int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, 2355252726Srpaulo char *argv[]) 2356252726Srpaulo{ 2357252726Srpaulo char cmd[512]; 2358252726Srpaulo 2359252726Srpaulo if (argc == 0) { 2360252726Srpaulo printf("Command needs one or two arguments (dst mac addr and " 2361252726Srpaulo "optional home realm)\n"); 2362252726Srpaulo return -1; 2363214734Srpaulo } 2364252726Srpaulo 2365252726Srpaulo if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST", 2366252726Srpaulo argc, argv) < 0) 2367252726Srpaulo return -1; 2368252726Srpaulo 2369214734Srpaulo return wpa_ctrl_command(ctrl, cmd); 2370214734Srpaulo} 2371214734Srpaulo 2372281806Srpaulo 2373281806Srpaulostatic int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc, 2374281806Srpaulo char *argv[]) 2375281806Srpaulo{ 2376281806Srpaulo char cmd[512]; 2377281806Srpaulo 2378281806Srpaulo if (argc < 2) { 2379281806Srpaulo printf("Command needs two arguments (dst mac addr and " 2380281806Srpaulo "icon name)\n"); 2381281806Srpaulo return -1; 2382281806Srpaulo } 2383281806Srpaulo 2384281806Srpaulo if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0) 2385281806Srpaulo return -1; 2386281806Srpaulo 2387281806Srpaulo return wpa_ctrl_command(ctrl, cmd); 2388281806Srpaulo} 2389281806Srpaulo 2390281806Srpaulo 2391281806Srpaulostatic int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2392281806Srpaulo{ 2393281806Srpaulo return wpa_ctrl_command(ctrl, "FETCH_OSU"); 2394281806Srpaulo} 2395281806Srpaulo 2396281806Srpaulo 2397281806Srpaulostatic int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc, 2398281806Srpaulo char *argv[]) 2399281806Srpaulo{ 2400281806Srpaulo return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU"); 2401281806Srpaulo} 2402281806Srpaulo 2403252726Srpaulo#endif /* CONFIG_HS20 */ 2404214734Srpaulo 2405252726Srpaulo 2406252726Srpaulostatic int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc, 2407252726Srpaulo char *argv[]) 2408252726Srpaulo{ 2409252726Srpaulo return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv); 2410252726Srpaulo} 2411252726Srpaulo 2412252726Srpaulo 2413252726Srpaulostatic int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc, 2414252726Srpaulo char *argv[]) 2415252726Srpaulo{ 2416252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv); 2417252726Srpaulo} 2418252726Srpaulo 2419252726Srpaulo 2420252726Srpaulostatic int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc, 2421252726Srpaulo char *argv[]) 2422252726Srpaulo{ 2423252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv); 2424252726Srpaulo} 2425252726Srpaulo 2426252726Srpaulo 2427252726Srpaulostatic int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc, 2428252726Srpaulo char *argv[]) 2429252726Srpaulo{ 2430252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv); 2431252726Srpaulo} 2432252726Srpaulo 2433252726Srpaulo 2434281806Srpaulostatic int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc, 2435281806Srpaulo char *argv[]) 2436281806Srpaulo{ 2437281806Srpaulo return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv); 2438281806Srpaulo} 2439281806Srpaulo 2440281806Srpaulo 2441281806Srpaulostatic int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc, 2442281806Srpaulo char *argv[]) 2443281806Srpaulo{ 2444281806Srpaulo return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv); 2445281806Srpaulo} 2446281806Srpaulo 2447281806Srpaulo 2448281806Srpaulostatic int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc, 2449281806Srpaulo char *argv[]) 2450281806Srpaulo{ 2451281806Srpaulo return wpa_ctrl_command(ctrl, "WMM_AC_STATUS"); 2452281806Srpaulo} 2453281806Srpaulo 2454281806Srpaulo 2455281806Srpaulostatic int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc, 2456281806Srpaulo char *argv[]) 2457281806Srpaulo{ 2458281806Srpaulo return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv); 2459281806Srpaulo} 2460281806Srpaulo 2461281806Srpaulo 2462281806Srpaulostatic int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc, 2463281806Srpaulo char *argv[]) 2464281806Srpaulo{ 2465281806Srpaulo return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv); 2466281806Srpaulo} 2467281806Srpaulo 2468281806Srpaulo 2469252726Srpaulostatic int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc, 2470252726Srpaulo char *argv[]) 2471252726Srpaulo{ 2472252726Srpaulo return wpa_ctrl_command(ctrl, "SIGNAL_POLL"); 2473252726Srpaulo} 2474252726Srpaulo 2475252726Srpaulo 2476252726Srpaulostatic int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc, 2477252726Srpaulo char *argv[]) 2478252726Srpaulo{ 2479252726Srpaulo return wpa_ctrl_command(ctrl, "PKTCNT_POLL"); 2480252726Srpaulo} 2481252726Srpaulo 2482252726Srpaulo 2483252726Srpaulostatic int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc, 2484252726Srpaulo char *argv[]) 2485252726Srpaulo{ 2486252726Srpaulo return wpa_ctrl_command(ctrl, "REAUTHENTICATE"); 2487252726Srpaulo} 2488252726Srpaulo 2489252726Srpaulo 2490252726Srpaulo#ifdef CONFIG_AUTOSCAN 2491252726Srpaulo 2492252726Srpaulostatic int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2493252726Srpaulo{ 2494252726Srpaulo if (argc == 0) 2495252726Srpaulo return wpa_ctrl_command(ctrl, "AUTOSCAN "); 2496252726Srpaulo 2497252726Srpaulo return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv); 2498252726Srpaulo} 2499252726Srpaulo 2500252726Srpaulo#endif /* CONFIG_AUTOSCAN */ 2501252726Srpaulo 2502252726Srpaulo 2503252726Srpaulo#ifdef CONFIG_WNM 2504252726Srpaulo 2505252726Srpaulostatic int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2506252726Srpaulo{ 2507252726Srpaulo return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv); 2508252726Srpaulo} 2509252726Srpaulo 2510281806Srpaulo 2511281806Srpaulostatic int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2512281806Srpaulo{ 2513281806Srpaulo return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv); 2514281806Srpaulo} 2515281806Srpaulo 2516252726Srpaulo#endif /* CONFIG_WNM */ 2517252726Srpaulo 2518252726Srpaulo 2519252726Srpaulostatic int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2520252726Srpaulo{ 2521252726Srpaulo if (argc == 0) 2522252726Srpaulo return -1; 2523252726Srpaulo return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]); 2524252726Srpaulo} 2525252726Srpaulo 2526252726Srpaulo 2527281806Srpaulo#ifdef ANDROID 2528281806Srpaulostatic int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2529281806Srpaulo{ 2530281806Srpaulo return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv); 2531281806Srpaulo} 2532281806Srpaulo#endif /* ANDROID */ 2533281806Srpaulo 2534281806Srpaulo 2535281806Srpaulostatic int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2536281806Srpaulo{ 2537281806Srpaulo return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv); 2538281806Srpaulo} 2539281806Srpaulo 2540281806Srpaulo 2541281806Srpaulostatic int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2542281806Srpaulo{ 2543281806Srpaulo return wpa_ctrl_command(ctrl, "FLUSH"); 2544281806Srpaulo} 2545281806Srpaulo 2546281806Srpaulo 2547281806Srpaulostatic int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2548281806Srpaulo{ 2549281806Srpaulo return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv); 2550281806Srpaulo} 2551281806Srpaulo 2552281806Srpaulo 2553281806Srpaulostatic int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc, 2554281806Srpaulo char *argv[]) 2555281806Srpaulo{ 2556281806Srpaulo return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv); 2557281806Srpaulo} 2558281806Srpaulo 2559281806Srpaulo 2560281806Srpaulostatic int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2561281806Srpaulo{ 2562281806Srpaulo return wpa_ctrl_command(ctrl, "ERP_FLUSH"); 2563281806Srpaulo} 2564281806Srpaulo 2565281806Srpaulo 2566281806Srpaulostatic int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc, 2567281806Srpaulo char *argv[]) 2568281806Srpaulo{ 2569281806Srpaulo return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv); 2570281806Srpaulo} 2571281806Srpaulo 2572281806Srpaulo 2573189251Ssamenum wpa_cli_cmd_flags { 2574189251Ssam cli_cmd_flag_none = 0x00, 2575189251Ssam cli_cmd_flag_sensitive = 0x01 2576189251Ssam}; 2577189251Ssam 2578189251Ssamstruct wpa_cli_cmd { 2579189251Ssam const char *cmd; 2580189251Ssam int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); 2581252726Srpaulo char ** (*completion)(const char *str, int pos); 2582189251Ssam enum wpa_cli_cmd_flags flags; 2583189251Ssam const char *usage; 2584189251Ssam}; 2585189251Ssam 2586189251Ssamstatic struct wpa_cli_cmd wpa_cli_commands[] = { 2587252726Srpaulo { "status", wpa_cli_cmd_status, NULL, 2588189251Ssam cli_cmd_flag_none, 2589189251Ssam "[verbose] = get current WPA/EAPOL/EAP status" }, 2590252726Srpaulo { "ifname", wpa_cli_cmd_ifname, NULL, 2591189251Ssam cli_cmd_flag_none, 2592252726Srpaulo "= get current interface name" }, 2593252726Srpaulo { "ping", wpa_cli_cmd_ping, NULL, 2594252726Srpaulo cli_cmd_flag_none, 2595189251Ssam "= pings wpa_supplicant" }, 2596252726Srpaulo { "relog", wpa_cli_cmd_relog, NULL, 2597189251Ssam cli_cmd_flag_none, 2598252726Srpaulo "= re-open log-file (allow rolling logs)" }, 2599252726Srpaulo { "note", wpa_cli_cmd_note, NULL, 2600252726Srpaulo cli_cmd_flag_none, 2601252726Srpaulo "<text> = add a note to wpa_supplicant debug log" }, 2602252726Srpaulo { "mib", wpa_cli_cmd_mib, NULL, 2603252726Srpaulo cli_cmd_flag_none, 2604189251Ssam "= get MIB variables (dot1x, dot11)" }, 2605252726Srpaulo { "help", wpa_cli_cmd_help, wpa_cli_complete_help, 2606189251Ssam cli_cmd_flag_none, 2607252726Srpaulo "[command] = show usage help" }, 2608252726Srpaulo { "interface", wpa_cli_cmd_interface, NULL, 2609189251Ssam cli_cmd_flag_none, 2610189251Ssam "[ifname] = show interfaces/select interface" }, 2611252726Srpaulo { "level", wpa_cli_cmd_level, NULL, 2612189251Ssam cli_cmd_flag_none, 2613189251Ssam "<debug level> = change debug level" }, 2614252726Srpaulo { "license", wpa_cli_cmd_license, NULL, 2615189251Ssam cli_cmd_flag_none, 2616189251Ssam "= show full wpa_cli license" }, 2617252726Srpaulo { "quit", wpa_cli_cmd_quit, NULL, 2618189251Ssam cli_cmd_flag_none, 2619189251Ssam "= exit wpa_cli" }, 2620281806Srpaulo { "set", wpa_cli_cmd_set, wpa_cli_complete_set, 2621189251Ssam cli_cmd_flag_none, 2622189251Ssam "= set variables (shows list of variables when run without " 2623189251Ssam "arguments)" }, 2624281806Srpaulo { "dump", wpa_cli_cmd_dump, NULL, 2625281806Srpaulo cli_cmd_flag_none, 2626281806Srpaulo "= dump config variables" }, 2627252726Srpaulo { "get", wpa_cli_cmd_get, NULL, 2628189251Ssam cli_cmd_flag_none, 2629252726Srpaulo "<name> = get information" }, 2630252726Srpaulo { "logon", wpa_cli_cmd_logon, NULL, 2631252726Srpaulo cli_cmd_flag_none, 2632189251Ssam "= IEEE 802.1X EAPOL state machine logon" }, 2633252726Srpaulo { "logoff", wpa_cli_cmd_logoff, NULL, 2634189251Ssam cli_cmd_flag_none, 2635189251Ssam "= IEEE 802.1X EAPOL state machine logoff" }, 2636252726Srpaulo { "pmksa", wpa_cli_cmd_pmksa, NULL, 2637189251Ssam cli_cmd_flag_none, 2638189251Ssam "= show PMKSA cache" }, 2639281806Srpaulo { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL, 2640281806Srpaulo cli_cmd_flag_none, 2641281806Srpaulo "= flush PMKSA cache entries" }, 2642252726Srpaulo { "reassociate", wpa_cli_cmd_reassociate, NULL, 2643189251Ssam cli_cmd_flag_none, 2644189251Ssam "= force reassociation" }, 2645281806Srpaulo { "reattach", wpa_cli_cmd_reattach, NULL, 2646281806Srpaulo cli_cmd_flag_none, 2647281806Srpaulo "= force reassociation back to the same BSS" }, 2648252726Srpaulo { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss, 2649189251Ssam cli_cmd_flag_none, 2650189251Ssam "<BSSID> = force preauthentication" }, 2651252726Srpaulo { "identity", wpa_cli_cmd_identity, NULL, 2652189251Ssam cli_cmd_flag_none, 2653189251Ssam "<network id> <identity> = configure identity for an SSID" }, 2654252726Srpaulo { "password", wpa_cli_cmd_password, NULL, 2655189251Ssam cli_cmd_flag_sensitive, 2656189251Ssam "<network id> <password> = configure password for an SSID" }, 2657252726Srpaulo { "new_password", wpa_cli_cmd_new_password, NULL, 2658189251Ssam cli_cmd_flag_sensitive, 2659189251Ssam "<network id> <password> = change password for an SSID" }, 2660252726Srpaulo { "pin", wpa_cli_cmd_pin, NULL, 2661189251Ssam cli_cmd_flag_sensitive, 2662189251Ssam "<network id> <pin> = configure pin for an SSID" }, 2663252726Srpaulo { "otp", wpa_cli_cmd_otp, NULL, 2664189251Ssam cli_cmd_flag_sensitive, 2665189251Ssam "<network id> <password> = configure one-time-password for an SSID" 2666189251Ssam }, 2667252726Srpaulo { "passphrase", wpa_cli_cmd_passphrase, NULL, 2668189251Ssam cli_cmd_flag_sensitive, 2669189251Ssam "<network id> <passphrase> = configure private key passphrase\n" 2670189251Ssam " for an SSID" }, 2671281806Srpaulo { "sim", wpa_cli_cmd_sim, NULL, 2672281806Srpaulo cli_cmd_flag_sensitive, 2673281806Srpaulo "<network id> <pin> = report SIM operation result" }, 2674252726Srpaulo { "bssid", wpa_cli_cmd_bssid, NULL, 2675189251Ssam cli_cmd_flag_none, 2676189251Ssam "<network id> <BSSID> = set preferred BSSID for an SSID" }, 2677252726Srpaulo { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss, 2678189251Ssam cli_cmd_flag_none, 2679252726Srpaulo "<BSSID> = add a BSSID to the blacklist\n" 2680252726Srpaulo "blacklist clear = clear the blacklist\n" 2681252726Srpaulo "blacklist = display the blacklist" }, 2682252726Srpaulo { "log_level", wpa_cli_cmd_log_level, NULL, 2683252726Srpaulo cli_cmd_flag_none, 2684252726Srpaulo "<level> [<timestamp>] = update the log level/timestamp\n" 2685252726Srpaulo "log_level = display the current log level and log options" }, 2686252726Srpaulo { "list_networks", wpa_cli_cmd_list_networks, NULL, 2687252726Srpaulo cli_cmd_flag_none, 2688189251Ssam "= list configured networks" }, 2689252726Srpaulo { "select_network", wpa_cli_cmd_select_network, NULL, 2690189251Ssam cli_cmd_flag_none, 2691189251Ssam "<network id> = select a network (disable others)" }, 2692252726Srpaulo { "enable_network", wpa_cli_cmd_enable_network, NULL, 2693189251Ssam cli_cmd_flag_none, 2694189251Ssam "<network id> = enable a network" }, 2695252726Srpaulo { "disable_network", wpa_cli_cmd_disable_network, NULL, 2696189251Ssam cli_cmd_flag_none, 2697189251Ssam "<network id> = disable a network" }, 2698252726Srpaulo { "add_network", wpa_cli_cmd_add_network, NULL, 2699189251Ssam cli_cmd_flag_none, 2700189251Ssam "= add a network" }, 2701252726Srpaulo { "remove_network", wpa_cli_cmd_remove_network, NULL, 2702189251Ssam cli_cmd_flag_none, 2703189251Ssam "<network id> = remove a network" }, 2704252726Srpaulo { "set_network", wpa_cli_cmd_set_network, NULL, 2705189251Ssam cli_cmd_flag_sensitive, 2706189251Ssam "<network id> <variable> <value> = set network variables (shows\n" 2707189251Ssam " list of variables when run without arguments)" }, 2708252726Srpaulo { "get_network", wpa_cli_cmd_get_network, NULL, 2709189251Ssam cli_cmd_flag_none, 2710189251Ssam "<network id> <variable> = get network variables" }, 2711281806Srpaulo { "dup_network", wpa_cli_cmd_dup_network, NULL, 2712281806Srpaulo cli_cmd_flag_none, 2713281806Srpaulo "<src network id> <dst network id> <variable> = duplicate network variables" 2714281806Srpaulo }, 2715252726Srpaulo { "list_creds", wpa_cli_cmd_list_creds, NULL, 2716189251Ssam cli_cmd_flag_none, 2717252726Srpaulo "= list configured credentials" }, 2718252726Srpaulo { "add_cred", wpa_cli_cmd_add_cred, NULL, 2719252726Srpaulo cli_cmd_flag_none, 2720252726Srpaulo "= add a credential" }, 2721252726Srpaulo { "remove_cred", wpa_cli_cmd_remove_cred, NULL, 2722252726Srpaulo cli_cmd_flag_none, 2723252726Srpaulo "<cred id> = remove a credential" }, 2724252726Srpaulo { "set_cred", wpa_cli_cmd_set_cred, NULL, 2725252726Srpaulo cli_cmd_flag_sensitive, 2726252726Srpaulo "<cred id> <variable> <value> = set credential variables" }, 2727281806Srpaulo { "get_cred", wpa_cli_cmd_get_cred, NULL, 2728281806Srpaulo cli_cmd_flag_none, 2729281806Srpaulo "<cred id> <variable> = get credential variables" }, 2730252726Srpaulo { "save_config", wpa_cli_cmd_save_config, NULL, 2731252726Srpaulo cli_cmd_flag_none, 2732189251Ssam "= save the current configuration" }, 2733252726Srpaulo { "disconnect", wpa_cli_cmd_disconnect, NULL, 2734189251Ssam cli_cmd_flag_none, 2735189251Ssam "= disconnect and wait for reassociate/reconnect command before\n" 2736189251Ssam " connecting" }, 2737252726Srpaulo { "reconnect", wpa_cli_cmd_reconnect, NULL, 2738189251Ssam cli_cmd_flag_none, 2739189251Ssam "= like reassociate, but only takes effect if already disconnected" 2740189251Ssam }, 2741252726Srpaulo { "scan", wpa_cli_cmd_scan, NULL, 2742189251Ssam cli_cmd_flag_none, 2743189251Ssam "= request new BSS scan" }, 2744252726Srpaulo { "scan_results", wpa_cli_cmd_scan_results, NULL, 2745189251Ssam cli_cmd_flag_none, 2746189251Ssam "= get latest scan results" }, 2747252726Srpaulo { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss, 2748189251Ssam cli_cmd_flag_none, 2749189251Ssam "<<idx> | <bssid>> = get detailed scan result info" }, 2750252726Srpaulo { "get_capability", wpa_cli_cmd_get_capability, NULL, 2751189251Ssam cli_cmd_flag_none, 2752281806Srpaulo "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> " 2753252726Srpaulo "= get capabilies" }, 2754252726Srpaulo { "reconfigure", wpa_cli_cmd_reconfigure, NULL, 2755189251Ssam cli_cmd_flag_none, 2756189251Ssam "= force wpa_supplicant to re-read its configuration file" }, 2757252726Srpaulo { "terminate", wpa_cli_cmd_terminate, NULL, 2758189251Ssam cli_cmd_flag_none, 2759189251Ssam "= terminate wpa_supplicant" }, 2760252726Srpaulo { "interface_add", wpa_cli_cmd_interface_add, NULL, 2761189251Ssam cli_cmd_flag_none, 2762189251Ssam "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n" 2763189251Ssam " <bridge_name> = adds new interface, all parameters but <ifname>\n" 2764189251Ssam " are optional" }, 2765252726Srpaulo { "interface_remove", wpa_cli_cmd_interface_remove, NULL, 2766189251Ssam cli_cmd_flag_none, 2767189251Ssam "<ifname> = removes the interface" }, 2768252726Srpaulo { "interface_list", wpa_cli_cmd_interface_list, NULL, 2769189251Ssam cli_cmd_flag_none, 2770189251Ssam "= list available interfaces" }, 2771252726Srpaulo { "ap_scan", wpa_cli_cmd_ap_scan, NULL, 2772189251Ssam cli_cmd_flag_none, 2773189251Ssam "<value> = set ap_scan parameter" }, 2774252726Srpaulo { "scan_interval", wpa_cli_cmd_scan_interval, NULL, 2775189251Ssam cli_cmd_flag_none, 2776252726Srpaulo "<value> = set scan_interval parameter (in seconds)" }, 2777252726Srpaulo { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL, 2778252726Srpaulo cli_cmd_flag_none, 2779252726Srpaulo "<value> = set BSS expiration age parameter" }, 2780252726Srpaulo { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL, 2781252726Srpaulo cli_cmd_flag_none, 2782252726Srpaulo "<value> = set BSS expiration scan count parameter" }, 2783252726Srpaulo { "bss_flush", wpa_cli_cmd_bss_flush, NULL, 2784252726Srpaulo cli_cmd_flag_none, 2785252726Srpaulo "<value> = set BSS flush age (0 by default)" }, 2786252726Srpaulo { "stkstart", wpa_cli_cmd_stkstart, NULL, 2787252726Srpaulo cli_cmd_flag_none, 2788189251Ssam "<addr> = request STK negotiation with <addr>" }, 2789252726Srpaulo { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss, 2790189251Ssam cli_cmd_flag_none, 2791189251Ssam "<addr> = request over-the-DS FT with <addr>" }, 2792252726Srpaulo { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss, 2793189251Ssam cli_cmd_flag_none, 2794189251Ssam "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" }, 2795252726Srpaulo { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss, 2796189251Ssam cli_cmd_flag_sensitive, 2797189251Ssam "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " 2798189251Ssam "hardcoded)" }, 2799252726Srpaulo { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL, 2800214734Srpaulo cli_cmd_flag_sensitive, 2801252726Srpaulo "<PIN> = verify PIN checksum" }, 2802252726Srpaulo { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none, 2803252726Srpaulo "Cancels the pending WPS operation" }, 2804252726Srpaulo#ifdef CONFIG_WPS_NFC 2805252726Srpaulo { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss, 2806252726Srpaulo cli_cmd_flag_none, 2807252726Srpaulo "[BSSID] = start Wi-Fi Protected Setup: NFC" }, 2808281806Srpaulo { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL, 2809281806Srpaulo cli_cmd_flag_none, 2810281806Srpaulo "<WPS|NDEF> = build configuration token" }, 2811252726Srpaulo { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL, 2812252726Srpaulo cli_cmd_flag_none, 2813252726Srpaulo "<WPS|NDEF> = create password token" }, 2814252726Srpaulo { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL, 2815189251Ssam cli_cmd_flag_sensitive, 2816252726Srpaulo "<hexdump of payload> = report read NFC tag with WPS data" }, 2817252726Srpaulo { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL, 2818252726Srpaulo cli_cmd_flag_none, 2819252726Srpaulo "<NDEF> <WPS> = create NFC handover request" }, 2820252726Srpaulo { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL, 2821252726Srpaulo cli_cmd_flag_none, 2822252726Srpaulo "<NDEF> <WPS> = create NFC handover select" }, 2823281806Srpaulo { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL, 2824252726Srpaulo cli_cmd_flag_none, 2825281806Srpaulo "<role> <type> <hexdump of req> <hexdump of sel> = report completed " 2826281806Srpaulo "NFC handover" }, 2827252726Srpaulo#endif /* CONFIG_WPS_NFC */ 2828252726Srpaulo { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss, 2829252726Srpaulo cli_cmd_flag_sensitive, 2830189251Ssam "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, 2831252726Srpaulo { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL, 2832252726Srpaulo cli_cmd_flag_sensitive, 2833252726Srpaulo "[params..] = enable/disable AP PIN" }, 2834252726Srpaulo { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL, 2835214734Srpaulo cli_cmd_flag_none, 2836252726Srpaulo "[IP address] = start Wi-Fi Protected Setup External Registrar" }, 2837252726Srpaulo { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL, 2838214734Srpaulo cli_cmd_flag_none, 2839214734Srpaulo "= stop Wi-Fi Protected Setup External Registrar" }, 2840252726Srpaulo { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL, 2841214734Srpaulo cli_cmd_flag_sensitive, 2842214734Srpaulo "<UUID> <PIN> = add an Enrollee PIN to External Registrar" }, 2843252726Srpaulo { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL, 2844214734Srpaulo cli_cmd_flag_none, 2845214734Srpaulo "<UUID> = accept an Enrollee PBC using External Registrar" }, 2846252726Srpaulo { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL, 2847214734Srpaulo cli_cmd_flag_sensitive, 2848214734Srpaulo "<UUID> <PIN> = learn AP configuration" }, 2849252726Srpaulo { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL, 2850214734Srpaulo cli_cmd_flag_none, 2851252726Srpaulo "<UUID> <network id> = set AP configuration for enrolling" }, 2852252726Srpaulo { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL, 2853252726Srpaulo cli_cmd_flag_sensitive, 2854252726Srpaulo "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" }, 2855252726Srpaulo#ifdef CONFIG_WPS_NFC 2856252726Srpaulo { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL, 2857252726Srpaulo cli_cmd_flag_none, 2858252726Srpaulo "<WPS/NDEF> <UUID> = build NFC configuration token" }, 2859252726Srpaulo#endif /* CONFIG_WPS_NFC */ 2860252726Srpaulo { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL, 2861252726Srpaulo cli_cmd_flag_none, 2862214734Srpaulo "<addr> = request RSN authentication with <addr> in IBSS" }, 2863214734Srpaulo#ifdef CONFIG_AP 2864252726Srpaulo { "sta", wpa_cli_cmd_sta, NULL, 2865214734Srpaulo cli_cmd_flag_none, 2866214734Srpaulo "<addr> = get information about an associated station (AP)" }, 2867252726Srpaulo { "all_sta", wpa_cli_cmd_all_sta, NULL, 2868214734Srpaulo cli_cmd_flag_none, 2869214734Srpaulo "= get information about all associated stations (AP)" }, 2870252726Srpaulo { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL, 2871252726Srpaulo cli_cmd_flag_none, 2872252726Srpaulo "<addr> = deauthenticate a station" }, 2873252726Srpaulo { "disassociate", wpa_cli_cmd_disassociate, NULL, 2874252726Srpaulo cli_cmd_flag_none, 2875252726Srpaulo "<addr> = disassociate a station" }, 2876281806Srpaulo { "chan_switch", wpa_cli_cmd_chanswitch, NULL, 2877281806Srpaulo cli_cmd_flag_none, 2878281806Srpaulo "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]" 2879281806Srpaulo " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]" 2880281806Srpaulo " = CSA parameters" }, 2881214734Srpaulo#endif /* CONFIG_AP */ 2882252726Srpaulo { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none, 2883214734Srpaulo "= notification of suspend/hibernate" }, 2884252726Srpaulo { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none, 2885214734Srpaulo "= notification of resume/thaw" }, 2886281806Srpaulo#ifdef CONFIG_TESTING_OPTIONS 2887252726Srpaulo { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none, 2888214734Srpaulo "= drop SA without deauth/disassoc (test command)" }, 2889281806Srpaulo#endif /* CONFIG_TESTING_OPTIONS */ 2890252726Srpaulo { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss, 2891214734Srpaulo cli_cmd_flag_none, 2892214734Srpaulo "<addr> = roam to the specified BSS" }, 2893281806Srpaulo#ifdef CONFIG_MESH 2894281806Srpaulo { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL, 2895281806Srpaulo cli_cmd_flag_none, 2896281806Srpaulo "[ifname] = Create a new mesh interface" }, 2897281806Srpaulo { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL, 2898281806Srpaulo cli_cmd_flag_none, 2899281806Srpaulo "<network id> = join a mesh network (disable others)" }, 2900281806Srpaulo { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL, 2901281806Srpaulo cli_cmd_flag_none, 2902281806Srpaulo "<ifname> = Remove mesh group interface" }, 2903281806Srpaulo#endif /* CONFIG_MESH */ 2904252726Srpaulo#ifdef CONFIG_P2P 2905252726Srpaulo { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find, 2906252726Srpaulo cli_cmd_flag_none, 2907252726Srpaulo "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" }, 2908252726Srpaulo { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none, 2909252726Srpaulo "= stop P2P Devices search" }, 2910281806Srpaulo { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL, 2911281806Srpaulo cli_cmd_flag_none, 2912281806Srpaulo "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" }, 2913281806Srpaulo { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL, 2914281806Srpaulo cli_cmd_flag_none, 2915281806Srpaulo "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" }, 2916252726Srpaulo { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect, 2917252726Srpaulo cli_cmd_flag_none, 2918252726Srpaulo "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" }, 2919252726Srpaulo { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none, 2920252726Srpaulo "[timeout] = listen for P2P Devices for up-to timeout seconds" }, 2921252726Srpaulo { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, 2922252726Srpaulo wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none, 2923252726Srpaulo "<ifname> = remove P2P group interface (terminate group if GO)" }, 2924252726Srpaulo { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none, 2925252726Srpaulo "[ht40] = add a new P2P group (local end as GO)" }, 2926252726Srpaulo { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, 2927252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 2928252726Srpaulo "<addr> <method> = request provisioning discovery" }, 2929252726Srpaulo { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL, 2930252726Srpaulo cli_cmd_flag_none, 2931252726Srpaulo "= get the passphrase for a group (GO only)" }, 2932252726Srpaulo { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req, 2933252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 2934252726Srpaulo "<addr> <TLVs> = schedule service discovery request" }, 2935252726Srpaulo { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req, 2936252726Srpaulo NULL, cli_cmd_flag_none, 2937252726Srpaulo "<id> = cancel pending service discovery request" }, 2938252726Srpaulo { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL, 2939252726Srpaulo cli_cmd_flag_none, 2940252726Srpaulo "<freq> <addr> <dialog token> <TLVs> = service discovery response" }, 2941252726Srpaulo { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL, 2942252726Srpaulo cli_cmd_flag_none, 2943252726Srpaulo "= indicate change in local services" }, 2944252726Srpaulo { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL, 2945252726Srpaulo cli_cmd_flag_none, 2946252726Srpaulo "<external> = set external processing of service discovery" }, 2947252726Srpaulo { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL, 2948252726Srpaulo cli_cmd_flag_none, 2949252726Srpaulo "= remove all stored service entries" }, 2950252726Srpaulo { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL, 2951252726Srpaulo cli_cmd_flag_none, 2952281806Srpaulo "<bonjour|upnp|asp> <query|version> <response|service> = add a local " 2953252726Srpaulo "service" }, 2954281806Srpaulo { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL, 2955281806Srpaulo cli_cmd_flag_none, 2956281806Srpaulo "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace " 2957281806Srpaulo "local ASP service" }, 2958252726Srpaulo { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL, 2959252726Srpaulo cli_cmd_flag_none, 2960252726Srpaulo "<bonjour|upnp> <query|version> [|service] = remove a local " 2961252726Srpaulo "service" }, 2962252726Srpaulo { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer, 2963252726Srpaulo cli_cmd_flag_none, 2964252726Srpaulo "<addr> = reject connection attempts from a specific peer" }, 2965252726Srpaulo { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL, 2966252726Srpaulo cli_cmd_flag_none, 2967252726Srpaulo "<cmd> [peer=addr] = invite peer" }, 2968252726Srpaulo { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none, 2969252726Srpaulo "[discovered] = list known (optionally, only fully discovered) P2P " 2970252726Srpaulo "peers" }, 2971252726Srpaulo { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer, 2972252726Srpaulo cli_cmd_flag_none, 2973252726Srpaulo "<address> = show information about known P2P peer" }, 2974281806Srpaulo { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set, 2975281806Srpaulo cli_cmd_flag_none, 2976252726Srpaulo "<field> <value> = set a P2P parameter" }, 2977252726Srpaulo { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none, 2978252726Srpaulo "= flush P2P state" }, 2979252726Srpaulo { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none, 2980252726Srpaulo "= cancel P2P group formation" }, 2981252726Srpaulo { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, 2982252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 2983252726Srpaulo "<address> = unauthorize a peer" }, 2984252726Srpaulo { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL, 2985252726Srpaulo cli_cmd_flag_none, 2986252726Srpaulo "[<duration> <interval>] [<duration> <interval>] = request GO " 2987252726Srpaulo "presence" }, 2988252726Srpaulo { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL, 2989252726Srpaulo cli_cmd_flag_none, 2990252726Srpaulo "[<period> <interval>] = set extended listen timing" }, 2991281806Srpaulo { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client, 2992281806Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 2993281806Srpaulo "<address|iface=address> = remove a peer from all groups" }, 2994252726Srpaulo#endif /* CONFIG_P2P */ 2995252726Srpaulo#ifdef CONFIG_WIFI_DISPLAY 2996252726Srpaulo { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL, 2997252726Srpaulo cli_cmd_flag_none, 2998252726Srpaulo "<subelem> [contents] = set Wi-Fi Display subelement" }, 2999252726Srpaulo { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL, 3000252726Srpaulo cli_cmd_flag_none, 3001252726Srpaulo "<subelem> = get Wi-Fi Display subelement" }, 3002252726Srpaulo#endif /* CONFIG_WIFI_DISPLAY */ 3003252726Srpaulo#ifdef CONFIG_INTERWORKING 3004252726Srpaulo { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none, 3005252726Srpaulo "= fetch ANQP information for all APs" }, 3006252726Srpaulo { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL, 3007252726Srpaulo cli_cmd_flag_none, 3008252726Srpaulo "= stop fetch_anqp operation" }, 3009252726Srpaulo { "interworking_select", wpa_cli_cmd_interworking_select, NULL, 3010252726Srpaulo cli_cmd_flag_none, 3011252726Srpaulo "[auto] = perform Interworking network selection" }, 3012252726Srpaulo { "interworking_connect", wpa_cli_cmd_interworking_connect, 3013252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3014252726Srpaulo "<BSSID> = connect using Interworking credentials" }, 3015281806Srpaulo { "interworking_add_network", wpa_cli_cmd_interworking_add_network, 3016281806Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3017281806Srpaulo "<BSSID> = connect using Interworking credentials" }, 3018252726Srpaulo { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss, 3019252726Srpaulo cli_cmd_flag_none, 3020252726Srpaulo "<addr> <info id>[,<info id>]... = request ANQP information" }, 3021252726Srpaulo { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss, 3022252726Srpaulo cli_cmd_flag_none, 3023252726Srpaulo "<addr> <AdvProtoID> [QueryReq] = GAS request" }, 3024252726Srpaulo { "gas_response_get", wpa_cli_cmd_gas_response_get, 3025252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3026252726Srpaulo "<addr> <dialog token> [start,len] = Fetch last GAS response" }, 3027252726Srpaulo#endif /* CONFIG_INTERWORKING */ 3028252726Srpaulo#ifdef CONFIG_HS20 3029252726Srpaulo { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss, 3030252726Srpaulo cli_cmd_flag_none, 3031252726Srpaulo "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information" 3032252726Srpaulo }, 3033252726Srpaulo { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list, 3034252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3035252726Srpaulo "<addr> <home realm> = get HS20 nai home realm list" }, 3036281806Srpaulo { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request, 3037281806Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3038281806Srpaulo "<addr> <icon name> = get Hotspot 2.0 OSU icon" }, 3039281806Srpaulo { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none, 3040281806Srpaulo "= fetch OSU provider information from all APs" }, 3041281806Srpaulo { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL, 3042281806Srpaulo cli_cmd_flag_none, 3043281806Srpaulo "= cancel fetch_osu command" }, 3044252726Srpaulo#endif /* CONFIG_HS20 */ 3045252726Srpaulo { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL, 3046252726Srpaulo cli_cmd_flag_none, 3047252726Srpaulo "<0/1> = disable/enable automatic reconnection" }, 3048252726Srpaulo { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL, 3049252726Srpaulo cli_cmd_flag_none, 3050252726Srpaulo "<addr> = request TDLS discovery with <addr>" }, 3051252726Srpaulo { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL, 3052252726Srpaulo cli_cmd_flag_none, 3053252726Srpaulo "<addr> = request TDLS setup with <addr>" }, 3054252726Srpaulo { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL, 3055252726Srpaulo cli_cmd_flag_none, 3056252726Srpaulo "<addr> = tear down TDLS with <addr>" }, 3057281806Srpaulo { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL, 3058281806Srpaulo cli_cmd_flag_none, 3059281806Srpaulo "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] " 3060281806Srpaulo "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] " 3061281806Srpaulo "= add WMM-AC traffic stream" }, 3062281806Srpaulo { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL, 3063281806Srpaulo cli_cmd_flag_none, 3064281806Srpaulo "<tsid> = delete WMM-AC traffic stream" }, 3065281806Srpaulo { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL, 3066281806Srpaulo cli_cmd_flag_none, 3067281806Srpaulo "= show status for Wireless Multi-Media Admission-Control" }, 3068281806Srpaulo { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL, 3069281806Srpaulo cli_cmd_flag_none, 3070281806Srpaulo "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] " 3071281806Srpaulo "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching " 3072281806Srpaulo "with TDLS peer" }, 3073281806Srpaulo { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL, 3074281806Srpaulo cli_cmd_flag_none, 3075281806Srpaulo "<addr> = disable channel switching with TDLS peer <addr>" }, 3076252726Srpaulo { "signal_poll", wpa_cli_cmd_signal_poll, NULL, 3077252726Srpaulo cli_cmd_flag_none, 3078252726Srpaulo "= get signal parameters" }, 3079252726Srpaulo { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL, 3080252726Srpaulo cli_cmd_flag_none, 3081252726Srpaulo "= get TX/RX packet counters" }, 3082252726Srpaulo { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL, 3083252726Srpaulo cli_cmd_flag_none, 3084252726Srpaulo "= trigger IEEE 802.1X/EAPOL reauthentication" }, 3085252726Srpaulo#ifdef CONFIG_AUTOSCAN 3086252726Srpaulo { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none, 3087252726Srpaulo "[params] = Set or unset (if none) autoscan parameters" }, 3088252726Srpaulo#endif /* CONFIG_AUTOSCAN */ 3089252726Srpaulo#ifdef CONFIG_WNM 3090252726Srpaulo { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none, 3091252726Srpaulo "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" }, 3092281806Srpaulo { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none, 3093281806Srpaulo "<query reason> = Send BSS Transition Management Query" }, 3094252726Srpaulo#endif /* CONFIG_WNM */ 3095252726Srpaulo { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive, 3096252726Srpaulo "<params..> = Sent unprocessed command" }, 3097281806Srpaulo { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none, 3098281806Srpaulo "= flush wpa_supplicant state" }, 3099281806Srpaulo#ifdef ANDROID 3100281806Srpaulo { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none, 3101281806Srpaulo "<command> = driver private commands" }, 3102281806Srpaulo#endif /* ANDROID */ 3103281806Srpaulo { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none, 3104281806Srpaulo "= radio_work <show/add/done>" }, 3105281806Srpaulo { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none, 3106281806Srpaulo "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command" 3107281806Srpaulo }, 3108281806Srpaulo { "neighbor_rep_request", 3109281806Srpaulo wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none, 3110281806Srpaulo "[ssid=<SSID>] = Trigger request to AP for neighboring AP report " 3111281806Srpaulo "(with optional given SSID, default: current SSID)" 3112281806Srpaulo }, 3113281806Srpaulo { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none, 3114281806Srpaulo "= flush ERP keys" }, 3115281806Srpaulo { "mac_rand_scan", 3116281806Srpaulo wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none, 3117281806Srpaulo "<scan|sched|pno|all> enable=<0/1> [addr=mac-address " 3118281806Srpaulo "mask=mac-address-mask] = scan MAC randomization" 3119281806Srpaulo }, 3120252726Srpaulo { NULL, NULL, NULL, cli_cmd_flag_none, NULL } 3121189251Ssam}; 3122189251Ssam 3123189251Ssam 3124189251Ssam/* 3125189251Ssam * Prints command usage, lines are padded with the specified string. 3126189251Ssam */ 3127189251Ssamstatic void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad) 3128189251Ssam{ 3129189251Ssam char c; 3130189251Ssam size_t n; 3131189251Ssam 3132189251Ssam printf("%s%s ", pad, cmd->cmd); 3133189251Ssam for (n = 0; (c = cmd->usage[n]); n++) { 3134189251Ssam printf("%c", c); 3135189251Ssam if (c == '\n') 3136189251Ssam printf("%s", pad); 3137189251Ssam } 3138189251Ssam printf("\n"); 3139189251Ssam} 3140189251Ssam 3141189251Ssam 3142252726Srpaulostatic void print_help(const char *cmd) 3143189251Ssam{ 3144189251Ssam int n; 3145189251Ssam printf("commands:\n"); 3146252726Srpaulo for (n = 0; wpa_cli_commands[n].cmd; n++) { 3147252726Srpaulo if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd)) 3148252726Srpaulo print_cmd_help(&wpa_cli_commands[n], " "); 3149252726Srpaulo } 3150189251Ssam} 3151189251Ssam 3152189251Ssam 3153252726Srpaulostatic int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd) 3154189251Ssam{ 3155189251Ssam const char *c, *delim; 3156189251Ssam int n; 3157189251Ssam size_t len; 3158189251Ssam 3159189251Ssam delim = os_strchr(cmd, ' '); 3160189251Ssam if (delim) 3161189251Ssam len = delim - cmd; 3162189251Ssam else 3163189251Ssam len = os_strlen(cmd); 3164189251Ssam 3165189251Ssam for (n = 0; (c = wpa_cli_commands[n].cmd); n++) { 3166189251Ssam if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c)) 3167189251Ssam return (wpa_cli_commands[n].flags & 3168189251Ssam cli_cmd_flag_sensitive); 3169189251Ssam } 3170189251Ssam return 0; 3171189251Ssam} 3172189251Ssam 3173189251Ssam 3174252726Srpaulostatic char ** wpa_list_cmd_list(void) 3175252726Srpaulo{ 3176252726Srpaulo char **res; 3177252726Srpaulo int i, count; 3178281806Srpaulo struct cli_txt_entry *e; 3179252726Srpaulo 3180281806Srpaulo count = ARRAY_SIZE(wpa_cli_commands); 3181281806Srpaulo count += dl_list_len(&p2p_groups); 3182281806Srpaulo count += dl_list_len(&ifnames); 3183281806Srpaulo res = os_calloc(count + 1, sizeof(char *)); 3184252726Srpaulo if (res == NULL) 3185252726Srpaulo return NULL; 3186252726Srpaulo 3187252726Srpaulo for (i = 0; wpa_cli_commands[i].cmd; i++) { 3188252726Srpaulo res[i] = os_strdup(wpa_cli_commands[i].cmd); 3189252726Srpaulo if (res[i] == NULL) 3190252726Srpaulo break; 3191252726Srpaulo } 3192252726Srpaulo 3193281806Srpaulo dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) { 3194281806Srpaulo size_t len = 8 + os_strlen(e->txt); 3195281806Srpaulo res[i] = os_malloc(len); 3196281806Srpaulo if (res[i] == NULL) 3197281806Srpaulo break; 3198281806Srpaulo os_snprintf(res[i], len, "ifname=%s", e->txt); 3199281806Srpaulo i++; 3200281806Srpaulo } 3201281806Srpaulo 3202281806Srpaulo dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) { 3203281806Srpaulo res[i] = os_strdup(e->txt); 3204281806Srpaulo if (res[i] == NULL) 3205281806Srpaulo break; 3206281806Srpaulo i++; 3207281806Srpaulo } 3208281806Srpaulo 3209252726Srpaulo return res; 3210252726Srpaulo} 3211252726Srpaulo 3212252726Srpaulo 3213252726Srpaulostatic char ** wpa_cli_cmd_completion(const char *cmd, const char *str, 3214252726Srpaulo int pos) 3215252726Srpaulo{ 3216252726Srpaulo int i; 3217252726Srpaulo 3218252726Srpaulo for (i = 0; wpa_cli_commands[i].cmd; i++) { 3219252726Srpaulo if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) { 3220252726Srpaulo if (wpa_cli_commands[i].completion) 3221252726Srpaulo return wpa_cli_commands[i].completion(str, 3222252726Srpaulo pos); 3223252726Srpaulo edit_clear_line(); 3224252726Srpaulo printf("\r%s\n", wpa_cli_commands[i].usage); 3225252726Srpaulo edit_redraw(); 3226252726Srpaulo break; 3227252726Srpaulo } 3228252726Srpaulo } 3229252726Srpaulo 3230252726Srpaulo return NULL; 3231252726Srpaulo} 3232252726Srpaulo 3233252726Srpaulo 3234252726Srpaulostatic char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos) 3235252726Srpaulo{ 3236252726Srpaulo char **res; 3237252726Srpaulo const char *end; 3238252726Srpaulo char *cmd; 3239252726Srpaulo 3240281806Srpaulo if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) { 3241281806Srpaulo end = os_strchr(str, ' '); 3242281806Srpaulo if (end && pos > end - str) { 3243281806Srpaulo pos -= end - str + 1; 3244281806Srpaulo str = end + 1; 3245281806Srpaulo } 3246281806Srpaulo } 3247281806Srpaulo 3248252726Srpaulo end = os_strchr(str, ' '); 3249252726Srpaulo if (end == NULL || str + pos < end) 3250252726Srpaulo return wpa_list_cmd_list(); 3251252726Srpaulo 3252252726Srpaulo cmd = os_malloc(pos + 1); 3253252726Srpaulo if (cmd == NULL) 3254252726Srpaulo return NULL; 3255252726Srpaulo os_memcpy(cmd, str, pos); 3256252726Srpaulo cmd[end - str] = '\0'; 3257252726Srpaulo res = wpa_cli_cmd_completion(cmd, str, pos); 3258252726Srpaulo os_free(cmd); 3259252726Srpaulo return res; 3260252726Srpaulo} 3261252726Srpaulo 3262252726Srpaulo 3263189251Ssamstatic int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) 3264189251Ssam{ 3265189251Ssam struct wpa_cli_cmd *cmd, *match = NULL; 3266189251Ssam int count; 3267189251Ssam int ret = 0; 3268189251Ssam 3269281806Srpaulo if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) { 3270281806Srpaulo ifname_prefix = argv[0] + 7; 3271281806Srpaulo argv = &argv[1]; 3272281806Srpaulo argc--; 3273281806Srpaulo } else 3274281806Srpaulo ifname_prefix = NULL; 3275281806Srpaulo 3276281806Srpaulo if (argc == 0) 3277281806Srpaulo return -1; 3278281806Srpaulo 3279189251Ssam count = 0; 3280189251Ssam cmd = wpa_cli_commands; 3281189251Ssam while (cmd->cmd) { 3282189251Ssam if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0) 3283189251Ssam { 3284189251Ssam match = cmd; 3285189251Ssam if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { 3286189251Ssam /* we have an exact match */ 3287189251Ssam count = 1; 3288189251Ssam break; 3289189251Ssam } 3290189251Ssam count++; 3291189251Ssam } 3292189251Ssam cmd++; 3293189251Ssam } 3294189251Ssam 3295189251Ssam if (count > 1) { 3296189251Ssam printf("Ambiguous command '%s'; possible commands:", argv[0]); 3297189251Ssam cmd = wpa_cli_commands; 3298189251Ssam while (cmd->cmd) { 3299189251Ssam if (os_strncasecmp(cmd->cmd, argv[0], 3300189251Ssam os_strlen(argv[0])) == 0) { 3301189251Ssam printf(" %s", cmd->cmd); 3302189251Ssam } 3303189251Ssam cmd++; 3304189251Ssam } 3305189251Ssam printf("\n"); 3306189251Ssam ret = 1; 3307189251Ssam } else if (count == 0) { 3308189251Ssam printf("Unknown command '%s'\n", argv[0]); 3309189251Ssam ret = 1; 3310189251Ssam } else { 3311189251Ssam ret = match->handler(ctrl, argc - 1, &argv[1]); 3312189251Ssam } 3313189251Ssam 3314189251Ssam return ret; 3315189251Ssam} 3316189251Ssam 3317189251Ssam 3318189251Ssamstatic int str_match(const char *a, const char *b) 3319189251Ssam{ 3320189251Ssam return os_strncmp(a, b, os_strlen(b)) == 0; 3321189251Ssam} 3322189251Ssam 3323189251Ssam 3324189251Ssamstatic int wpa_cli_exec(const char *program, const char *arg1, 3325189251Ssam const char *arg2) 3326189251Ssam{ 3327281806Srpaulo char *arg; 3328189251Ssam size_t len; 3329189251Ssam int res; 3330189251Ssam 3331281806Srpaulo len = os_strlen(arg1) + os_strlen(arg2) + 2; 3332281806Srpaulo arg = os_malloc(len); 3333281806Srpaulo if (arg == NULL) 3334189251Ssam return -1; 3335281806Srpaulo os_snprintf(arg, len, "%s %s", arg1, arg2); 3336281806Srpaulo res = os_exec(program, arg, 1); 3337281806Srpaulo os_free(arg); 3338189251Ssam 3339281806Srpaulo return res; 3340189251Ssam} 3341189251Ssam 3342189251Ssam 3343189251Ssamstatic void wpa_cli_action_process(const char *msg) 3344189251Ssam{ 3345189251Ssam const char *pos; 3346189251Ssam char *copy = NULL, *id, *pos2; 3347281806Srpaulo const char *ifname = ctrl_ifname; 3348281806Srpaulo char ifname_buf[100]; 3349189251Ssam 3350189251Ssam pos = msg; 3351281806Srpaulo if (os_strncmp(pos, "IFNAME=", 7) == 0) { 3352281806Srpaulo const char *end; 3353281806Srpaulo end = os_strchr(pos + 7, ' '); 3354281806Srpaulo if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) { 3355281806Srpaulo pos += 7; 3356281806Srpaulo os_memcpy(ifname_buf, pos, end - pos); 3357281806Srpaulo ifname_buf[end - pos] = '\0'; 3358281806Srpaulo ifname = ifname_buf; 3359281806Srpaulo pos = end + 1; 3360281806Srpaulo } 3361281806Srpaulo } 3362189251Ssam if (*pos == '<') { 3363281806Srpaulo const char *prev = pos; 3364189251Ssam /* skip priority */ 3365189251Ssam pos = os_strchr(pos, '>'); 3366189251Ssam if (pos) 3367189251Ssam pos++; 3368189251Ssam else 3369281806Srpaulo pos = prev; 3370189251Ssam } 3371189251Ssam 3372189251Ssam if (str_match(pos, WPA_EVENT_CONNECTED)) { 3373189251Ssam int new_id = -1; 3374189251Ssam os_unsetenv("WPA_ID"); 3375189251Ssam os_unsetenv("WPA_ID_STR"); 3376189251Ssam os_unsetenv("WPA_CTRL_DIR"); 3377189251Ssam 3378189251Ssam pos = os_strstr(pos, "[id="); 3379189251Ssam if (pos) 3380189251Ssam copy = os_strdup(pos + 4); 3381189251Ssam 3382189251Ssam if (copy) { 3383189251Ssam pos2 = id = copy; 3384189251Ssam while (*pos2 && *pos2 != ' ') 3385189251Ssam pos2++; 3386189251Ssam *pos2++ = '\0'; 3387189251Ssam new_id = atoi(id); 3388189251Ssam os_setenv("WPA_ID", id, 1); 3389189251Ssam while (*pos2 && *pos2 != '=') 3390189251Ssam pos2++; 3391189251Ssam if (*pos2 == '=') 3392189251Ssam pos2++; 3393189251Ssam id = pos2; 3394189251Ssam while (*pos2 && *pos2 != ']') 3395189251Ssam pos2++; 3396189251Ssam *pos2 = '\0'; 3397189251Ssam os_setenv("WPA_ID_STR", id, 1); 3398189251Ssam os_free(copy); 3399189251Ssam } 3400189251Ssam 3401189251Ssam os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); 3402189251Ssam 3403281806Srpaulo if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) { 3404189251Ssam wpa_cli_connected = 1; 3405189251Ssam wpa_cli_last_id = new_id; 3406281806Srpaulo wpa_cli_exec(action_file, ifname, "CONNECTED"); 3407189251Ssam } 3408189251Ssam } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) { 3409189251Ssam if (wpa_cli_connected) { 3410189251Ssam wpa_cli_connected = 0; 3411281806Srpaulo wpa_cli_exec(action_file, ifname, "DISCONNECTED"); 3412189251Ssam } 3413281806Srpaulo } else if (str_match(pos, MESH_GROUP_STARTED)) { 3414281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3415281806Srpaulo } else if (str_match(pos, MESH_GROUP_REMOVED)) { 3416281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3417281806Srpaulo } else if (str_match(pos, MESH_PEER_CONNECTED)) { 3418281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3419281806Srpaulo } else if (str_match(pos, MESH_PEER_DISCONNECTED)) { 3420281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3421252726Srpaulo } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) { 3422281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3423252726Srpaulo } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) { 3424281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3425252726Srpaulo } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) { 3426281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3427252726Srpaulo } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) { 3428281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3429252726Srpaulo } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) { 3430281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3431252726Srpaulo } else if (str_match(pos, WPS_EVENT_SUCCESS)) { 3432281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3433252726Srpaulo } else if (str_match(pos, WPS_EVENT_FAIL)) { 3434281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3435252726Srpaulo } else if (str_match(pos, AP_STA_CONNECTED)) { 3436281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3437252726Srpaulo } else if (str_match(pos, AP_STA_DISCONNECTED)) { 3438281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3439281806Srpaulo } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) { 3440281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3441281806Srpaulo } else if (str_match(pos, HS20_SUBSCRIPTION_REMEDIATION)) { 3442281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3443281806Srpaulo } else if (str_match(pos, HS20_DEAUTH_IMMINENT_NOTICE)) { 3444281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3445189251Ssam } else if (str_match(pos, WPA_EVENT_TERMINATING)) { 3446189251Ssam printf("wpa_supplicant is terminating - stop monitoring\n"); 3447189251Ssam wpa_cli_quit = 1; 3448189251Ssam } 3449189251Ssam} 3450189251Ssam 3451189251Ssam 3452189251Ssam#ifndef CONFIG_ANSI_C_EXTRA 3453189251Ssamstatic void wpa_cli_action_cb(char *msg, size_t len) 3454189251Ssam{ 3455189251Ssam wpa_cli_action_process(msg); 3456189251Ssam} 3457189251Ssam#endif /* CONFIG_ANSI_C_EXTRA */ 3458189251Ssam 3459189251Ssam 3460189251Ssamstatic void wpa_cli_reconnect(void) 3461189251Ssam{ 3462189251Ssam wpa_cli_close_connection(); 3463252726Srpaulo if (wpa_cli_open_connection(ctrl_ifname, 1) < 0) 3464252726Srpaulo return; 3465252726Srpaulo 3466252726Srpaulo if (interactive) { 3467252726Srpaulo edit_clear_line(); 3468252726Srpaulo printf("\rConnection to wpa_supplicant re-established\n"); 3469252726Srpaulo edit_redraw(); 3470252726Srpaulo } 3471189251Ssam} 3472189251Ssam 3473189251Ssam 3474252726Srpaulostatic void cli_event(const char *str) 3475189251Ssam{ 3476252726Srpaulo const char *start, *s; 3477252726Srpaulo 3478252726Srpaulo start = os_strchr(str, '>'); 3479252726Srpaulo if (start == NULL) 3480252726Srpaulo return; 3481252726Srpaulo 3482252726Srpaulo start++; 3483252726Srpaulo 3484252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_ADDED)) { 3485252726Srpaulo s = os_strchr(start, ' '); 3486252726Srpaulo if (s == NULL) 3487252726Srpaulo return; 3488252726Srpaulo s = os_strchr(s + 1, ' '); 3489252726Srpaulo if (s == NULL) 3490252726Srpaulo return; 3491252726Srpaulo cli_txt_list_add(&bsses, s + 1); 3492252726Srpaulo return; 3493252726Srpaulo } 3494252726Srpaulo 3495252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_REMOVED)) { 3496252726Srpaulo s = os_strchr(start, ' '); 3497252726Srpaulo if (s == NULL) 3498252726Srpaulo return; 3499252726Srpaulo s = os_strchr(s + 1, ' '); 3500252726Srpaulo if (s == NULL) 3501252726Srpaulo return; 3502252726Srpaulo cli_txt_list_del_addr(&bsses, s + 1); 3503252726Srpaulo return; 3504252726Srpaulo } 3505252726Srpaulo 3506252726Srpaulo#ifdef CONFIG_P2P 3507252726Srpaulo if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) { 3508252726Srpaulo s = os_strstr(start, " p2p_dev_addr="); 3509252726Srpaulo if (s == NULL) 3510252726Srpaulo return; 3511252726Srpaulo cli_txt_list_add_addr(&p2p_peers, s + 14); 3512252726Srpaulo return; 3513252726Srpaulo } 3514252726Srpaulo 3515252726Srpaulo if (str_starts(start, P2P_EVENT_DEVICE_LOST)) { 3516252726Srpaulo s = os_strstr(start, " p2p_dev_addr="); 3517252726Srpaulo if (s == NULL) 3518252726Srpaulo return; 3519252726Srpaulo cli_txt_list_del_addr(&p2p_peers, s + 14); 3520252726Srpaulo return; 3521252726Srpaulo } 3522252726Srpaulo 3523252726Srpaulo if (str_starts(start, P2P_EVENT_GROUP_STARTED)) { 3524252726Srpaulo s = os_strchr(start, ' '); 3525252726Srpaulo if (s == NULL) 3526252726Srpaulo return; 3527252726Srpaulo cli_txt_list_add_word(&p2p_groups, s + 1); 3528252726Srpaulo return; 3529252726Srpaulo } 3530252726Srpaulo 3531252726Srpaulo if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) { 3532252726Srpaulo s = os_strchr(start, ' '); 3533252726Srpaulo if (s == NULL) 3534252726Srpaulo return; 3535252726Srpaulo cli_txt_list_del_word(&p2p_groups, s + 1); 3536252726Srpaulo return; 3537252726Srpaulo } 3538252726Srpaulo#endif /* CONFIG_P2P */ 3539252726Srpaulo} 3540252726Srpaulo 3541252726Srpaulo 3542252726Srpaulostatic int check_terminating(const char *msg) 3543252726Srpaulo{ 3544252726Srpaulo const char *pos = msg; 3545252726Srpaulo 3546252726Srpaulo if (*pos == '<') { 3547252726Srpaulo /* skip priority */ 3548252726Srpaulo pos = os_strchr(pos, '>'); 3549252726Srpaulo if (pos) 3550252726Srpaulo pos++; 3551252726Srpaulo else 3552252726Srpaulo pos = msg; 3553252726Srpaulo } 3554252726Srpaulo 3555252726Srpaulo if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) { 3556252726Srpaulo edit_clear_line(); 3557252726Srpaulo printf("\rConnection to wpa_supplicant lost - trying to " 3558252726Srpaulo "reconnect\n"); 3559252726Srpaulo edit_redraw(); 3560252726Srpaulo wpa_cli_attached = 0; 3561252726Srpaulo wpa_cli_close_connection(); 3562252726Srpaulo return 1; 3563252726Srpaulo } 3564252726Srpaulo 3565252726Srpaulo return 0; 3566252726Srpaulo} 3567252726Srpaulo 3568252726Srpaulo 3569252726Srpaulostatic void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor) 3570252726Srpaulo{ 3571189251Ssam if (ctrl_conn == NULL) { 3572189251Ssam wpa_cli_reconnect(); 3573189251Ssam return; 3574189251Ssam } 3575189251Ssam while (wpa_ctrl_pending(ctrl) > 0) { 3576281806Srpaulo char buf[4096]; 3577189251Ssam size_t len = sizeof(buf) - 1; 3578189251Ssam if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { 3579189251Ssam buf[len] = '\0'; 3580189251Ssam if (action_monitor) 3581189251Ssam wpa_cli_action_process(buf); 3582189251Ssam else { 3583252726Srpaulo cli_event(buf); 3584252726Srpaulo if (wpa_cli_show_event(buf)) { 3585252726Srpaulo edit_clear_line(); 3586252726Srpaulo printf("\r%s\n", buf); 3587252726Srpaulo edit_redraw(); 3588252726Srpaulo } 3589252726Srpaulo 3590252726Srpaulo if (interactive && check_terminating(buf) > 0) 3591252726Srpaulo return; 3592189251Ssam } 3593189251Ssam } else { 3594189251Ssam printf("Could not read pending message.\n"); 3595189251Ssam break; 3596189251Ssam } 3597189251Ssam } 3598189251Ssam 3599189251Ssam if (wpa_ctrl_pending(ctrl) < 0) { 3600189251Ssam printf("Connection to wpa_supplicant lost - trying to " 3601189251Ssam "reconnect\n"); 3602189251Ssam wpa_cli_reconnect(); 3603189251Ssam } 3604189251Ssam} 3605189251Ssam 3606252726Srpaulo#define max_args 10 3607189251Ssam 3608252726Srpaulostatic int tokenize_cmd(char *cmd, char *argv[]) 3609189251Ssam{ 3610252726Srpaulo char *pos; 3611252726Srpaulo int argc = 0; 3612189251Ssam 3613252726Srpaulo pos = cmd; 3614252726Srpaulo for (;;) { 3615252726Srpaulo while (*pos == ' ') 3616252726Srpaulo pos++; 3617252726Srpaulo if (*pos == '\0') 3618252726Srpaulo break; 3619252726Srpaulo argv[argc] = pos; 3620252726Srpaulo argc++; 3621252726Srpaulo if (argc == max_args) 3622252726Srpaulo break; 3623252726Srpaulo if (*pos == '"') { 3624252726Srpaulo char *pos2 = os_strrchr(pos, '"'); 3625252726Srpaulo if (pos2) 3626252726Srpaulo pos = pos2 + 1; 3627252726Srpaulo } 3628252726Srpaulo while (*pos != '\0' && *pos != ' ') 3629252726Srpaulo pos++; 3630252726Srpaulo if (*pos == ' ') 3631252726Srpaulo *pos++ = '\0'; 3632189251Ssam } 3633189251Ssam 3634252726Srpaulo return argc; 3635189251Ssam} 3636189251Ssam 3637189251Ssam 3638252726Srpaulostatic void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx) 3639189251Ssam{ 3640281806Srpaulo if (ctrl_conn) { 3641281806Srpaulo int res; 3642281806Srpaulo char *prefix = ifname_prefix; 3643281806Srpaulo 3644281806Srpaulo ifname_prefix = NULL; 3645281806Srpaulo res = _wpa_ctrl_command(ctrl_conn, "PING", 0); 3646281806Srpaulo ifname_prefix = prefix; 3647281806Srpaulo if (res) { 3648281806Srpaulo printf("Connection to wpa_supplicant lost - trying to " 3649281806Srpaulo "reconnect\n"); 3650281806Srpaulo wpa_cli_close_connection(); 3651281806Srpaulo } 3652214734Srpaulo } 3653252726Srpaulo if (!ctrl_conn) 3654252726Srpaulo wpa_cli_reconnect(); 3655252726Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 3656189251Ssam} 3657189251Ssam 3658189251Ssam 3659252726Srpaulostatic void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx) 3660214734Srpaulo{ 3661252726Srpaulo wpa_cli_recv_pending(mon_conn, 0); 3662252726Srpaulo} 3663214734Srpaulo 3664214734Srpaulo 3665252726Srpaulostatic void wpa_cli_edit_cmd_cb(void *ctx, char *cmd) 3666252726Srpaulo{ 3667252726Srpaulo char *argv[max_args]; 3668252726Srpaulo int argc; 3669252726Srpaulo argc = tokenize_cmd(cmd, argv); 3670252726Srpaulo if (argc) 3671252726Srpaulo wpa_request(ctrl_conn, argc, argv); 3672214734Srpaulo} 3673214734Srpaulo 3674214734Srpaulo 3675252726Srpaulostatic void wpa_cli_edit_eof_cb(void *ctx) 3676189251Ssam{ 3677252726Srpaulo eloop_terminate(); 3678189251Ssam} 3679189251Ssam 3680189251Ssam 3681252726Srpaulostatic int warning_displayed = 0; 3682252726Srpaulostatic char *hfile = NULL; 3683252726Srpaulostatic int edit_started = 0; 3684252726Srpaulo 3685252726Srpaulostatic void start_edit(void) 3686189251Ssam{ 3687252726Srpaulo char *home; 3688252726Srpaulo char *ps = NULL; 3689189251Ssam 3690252726Srpaulo#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE 3691252726Srpaulo ps = wpa_ctrl_get_remote_ifname(ctrl_conn); 3692252726Srpaulo#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ 3693189251Ssam 3694189251Ssam home = getenv("HOME"); 3695189251Ssam if (home) { 3696189251Ssam const char *fname = ".wpa_cli_history"; 3697189251Ssam int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; 3698189251Ssam hfile = os_malloc(hfile_len); 3699252726Srpaulo if (hfile) 3700252726Srpaulo os_snprintf(hfile, hfile_len, "%s/%s", home, fname); 3701189251Ssam } 3702189251Ssam 3703252726Srpaulo if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, 3704252726Srpaulo wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) { 3705252726Srpaulo eloop_terminate(); 3706252726Srpaulo return; 3707252726Srpaulo } 3708189251Ssam 3709252726Srpaulo edit_started = 1; 3710252726Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 3711252726Srpaulo} 3712189251Ssam 3713252726Srpaulo 3714281806Srpaulostatic void update_bssid_list(struct wpa_ctrl *ctrl) 3715281806Srpaulo{ 3716281806Srpaulo char buf[4096]; 3717281806Srpaulo size_t len = sizeof(buf); 3718281806Srpaulo int ret; 3719281806Srpaulo char *cmd = "BSS RANGE=ALL MASK=0x2"; 3720281806Srpaulo char *pos, *end; 3721281806Srpaulo 3722281806Srpaulo if (ctrl == NULL) 3723281806Srpaulo return; 3724281806Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 3725281806Srpaulo if (ret < 0) 3726281806Srpaulo return; 3727281806Srpaulo buf[len] = '\0'; 3728281806Srpaulo 3729281806Srpaulo pos = buf; 3730281806Srpaulo while (pos) { 3731281806Srpaulo pos = os_strstr(pos, "bssid="); 3732281806Srpaulo if (pos == NULL) 3733281806Srpaulo break; 3734281806Srpaulo pos += 6; 3735281806Srpaulo end = os_strchr(pos, '\n'); 3736281806Srpaulo if (end == NULL) 3737281806Srpaulo break; 3738281806Srpaulo *end = '\0'; 3739281806Srpaulo cli_txt_list_add(&bsses, pos); 3740281806Srpaulo pos = end + 1; 3741281806Srpaulo } 3742281806Srpaulo} 3743281806Srpaulo 3744281806Srpaulo 3745281806Srpaulostatic void update_ifnames(struct wpa_ctrl *ctrl) 3746281806Srpaulo{ 3747281806Srpaulo char buf[4096]; 3748281806Srpaulo size_t len = sizeof(buf); 3749281806Srpaulo int ret; 3750281806Srpaulo char *cmd = "INTERFACES"; 3751281806Srpaulo char *pos, *end; 3752281806Srpaulo char txt[200]; 3753281806Srpaulo 3754281806Srpaulo cli_txt_list_flush(&ifnames); 3755281806Srpaulo 3756281806Srpaulo if (ctrl == NULL) 3757281806Srpaulo return; 3758281806Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 3759281806Srpaulo if (ret < 0) 3760281806Srpaulo return; 3761281806Srpaulo buf[len] = '\0'; 3762281806Srpaulo 3763281806Srpaulo pos = buf; 3764281806Srpaulo while (pos) { 3765281806Srpaulo end = os_strchr(pos, '\n'); 3766281806Srpaulo if (end == NULL) 3767281806Srpaulo break; 3768281806Srpaulo *end = '\0'; 3769281806Srpaulo ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos); 3770281806Srpaulo if (!os_snprintf_error(sizeof(txt), ret)) 3771281806Srpaulo cli_txt_list_add(&ifnames, txt); 3772281806Srpaulo pos = end + 1; 3773281806Srpaulo } 3774281806Srpaulo} 3775281806Srpaulo 3776281806Srpaulo 3777252726Srpaulostatic void try_connection(void *eloop_ctx, void *timeout_ctx) 3778252726Srpaulo{ 3779281806Srpaulo if (ctrl_conn) 3780281806Srpaulo goto done; 3781281806Srpaulo 3782252726Srpaulo if (ctrl_ifname == NULL) 3783252726Srpaulo ctrl_ifname = wpa_cli_get_default_ifname(); 3784252726Srpaulo 3785252726Srpaulo if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) { 3786252726Srpaulo if (!warning_displayed) { 3787252726Srpaulo printf("Could not connect to wpa_supplicant: " 3788281806Srpaulo "%s - re-trying\n", 3789281806Srpaulo ctrl_ifname ? ctrl_ifname : "(nil)"); 3790252726Srpaulo warning_displayed = 1; 3791189251Ssam } 3792252726Srpaulo eloop_register_timeout(1, 0, try_connection, NULL, NULL); 3793252726Srpaulo return; 3794189251Ssam } 3795252726Srpaulo 3796281806Srpaulo update_bssid_list(ctrl_conn); 3797281806Srpaulo 3798252726Srpaulo if (warning_displayed) 3799252726Srpaulo printf("Connection established.\n"); 3800252726Srpaulo 3801281806Srpaulodone: 3802252726Srpaulo start_edit(); 3803189251Ssam} 3804189251Ssam 3805189251Ssam 3806252726Srpaulostatic void wpa_cli_interactive(void) 3807252726Srpaulo{ 3808252726Srpaulo printf("\nInteractive mode\n\n"); 3809252726Srpaulo 3810252726Srpaulo eloop_register_timeout(0, 0, try_connection, NULL, NULL); 3811252726Srpaulo eloop_run(); 3812252726Srpaulo eloop_cancel_timeout(try_connection, NULL, NULL); 3813252726Srpaulo 3814252726Srpaulo cli_txt_list_flush(&p2p_peers); 3815252726Srpaulo cli_txt_list_flush(&p2p_groups); 3816252726Srpaulo cli_txt_list_flush(&bsses); 3817281806Srpaulo cli_txt_list_flush(&ifnames); 3818252726Srpaulo if (edit_started) 3819252726Srpaulo edit_deinit(hfile, wpa_cli_edit_filter_history_cb); 3820252726Srpaulo os_free(hfile); 3821252726Srpaulo eloop_cancel_timeout(wpa_cli_ping, NULL, NULL); 3822252726Srpaulo wpa_cli_close_connection(); 3823252726Srpaulo} 3824252726Srpaulo 3825252726Srpaulo 3826189251Ssamstatic void wpa_cli_action(struct wpa_ctrl *ctrl) 3827189251Ssam{ 3828189251Ssam#ifdef CONFIG_ANSI_C_EXTRA 3829189251Ssam /* TODO: ANSI C version(?) */ 3830189251Ssam printf("Action processing not supported in ANSI C build.\n"); 3831189251Ssam#else /* CONFIG_ANSI_C_EXTRA */ 3832189251Ssam fd_set rfds; 3833189251Ssam int fd, res; 3834189251Ssam struct timeval tv; 3835189251Ssam char buf[256]; /* note: large enough to fit in unsolicited messages */ 3836189251Ssam size_t len; 3837189251Ssam 3838189251Ssam fd = wpa_ctrl_get_fd(ctrl); 3839189251Ssam 3840189251Ssam while (!wpa_cli_quit) { 3841189251Ssam FD_ZERO(&rfds); 3842189251Ssam FD_SET(fd, &rfds); 3843189251Ssam tv.tv_sec = ping_interval; 3844189251Ssam tv.tv_usec = 0; 3845189251Ssam res = select(fd + 1, &rfds, NULL, NULL, &tv); 3846189251Ssam if (res < 0 && errno != EINTR) { 3847189251Ssam perror("select"); 3848189251Ssam break; 3849189251Ssam } 3850189251Ssam 3851189251Ssam if (FD_ISSET(fd, &rfds)) 3852252726Srpaulo wpa_cli_recv_pending(ctrl, 1); 3853189251Ssam else { 3854189251Ssam /* verify that connection is still working */ 3855189251Ssam len = sizeof(buf) - 1; 3856189251Ssam if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, 3857189251Ssam wpa_cli_action_cb) < 0 || 3858189251Ssam len < 4 || os_memcmp(buf, "PONG", 4) != 0) { 3859189251Ssam printf("wpa_supplicant did not reply to PING " 3860189251Ssam "command - exiting\n"); 3861189251Ssam break; 3862189251Ssam } 3863189251Ssam } 3864189251Ssam } 3865189251Ssam#endif /* CONFIG_ANSI_C_EXTRA */ 3866189251Ssam} 3867189251Ssam 3868189251Ssam 3869189251Ssamstatic void wpa_cli_cleanup(void) 3870189251Ssam{ 3871189251Ssam wpa_cli_close_connection(); 3872189251Ssam if (pid_file) 3873189251Ssam os_daemonize_terminate(pid_file); 3874189251Ssam 3875189251Ssam os_program_deinit(); 3876189251Ssam} 3877189251Ssam 3878189251Ssam 3879252726Srpaulostatic void wpa_cli_terminate(int sig, void *ctx) 3880214734Srpaulo{ 3881252726Srpaulo eloop_terminate(); 3882214734Srpaulo} 3883214734Srpaulo 3884214734Srpaulo 3885189251Ssamstatic char * wpa_cli_get_default_ifname(void) 3886189251Ssam{ 3887189251Ssam char *ifname = NULL; 3888189251Ssam 3889189251Ssam#ifdef CONFIG_CTRL_IFACE_UNIX 3890189251Ssam struct dirent *dent; 3891189251Ssam DIR *dir = opendir(ctrl_iface_dir); 3892252726Srpaulo if (!dir) { 3893252726Srpaulo#ifdef ANDROID 3894252726Srpaulo char ifprop[PROPERTY_VALUE_MAX]; 3895252726Srpaulo if (property_get("wifi.interface", ifprop, NULL) != 0) { 3896252726Srpaulo ifname = os_strdup(ifprop); 3897252726Srpaulo printf("Using interface '%s'\n", ifname); 3898252726Srpaulo return ifname; 3899252726Srpaulo } 3900252726Srpaulo#endif /* ANDROID */ 3901189251Ssam return NULL; 3902252726Srpaulo } 3903189251Ssam while ((dent = readdir(dir))) { 3904189251Ssam#ifdef _DIRENT_HAVE_D_TYPE 3905189251Ssam /* 3906189251Ssam * Skip the file if it is not a socket. Also accept 3907189251Ssam * DT_UNKNOWN (0) in case the C library or underlying 3908189251Ssam * file system does not support d_type. 3909189251Ssam */ 3910189251Ssam if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) 3911189251Ssam continue; 3912189251Ssam#endif /* _DIRENT_HAVE_D_TYPE */ 3913189251Ssam if (os_strcmp(dent->d_name, ".") == 0 || 3914189251Ssam os_strcmp(dent->d_name, "..") == 0) 3915189251Ssam continue; 3916189251Ssam printf("Selected interface '%s'\n", dent->d_name); 3917189251Ssam ifname = os_strdup(dent->d_name); 3918189251Ssam break; 3919189251Ssam } 3920189251Ssam closedir(dir); 3921189251Ssam#endif /* CONFIG_CTRL_IFACE_UNIX */ 3922189251Ssam 3923189251Ssam#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 3924281806Srpaulo char buf[4096], *pos; 3925189251Ssam size_t len; 3926189251Ssam struct wpa_ctrl *ctrl; 3927189251Ssam int ret; 3928189251Ssam 3929189251Ssam ctrl = wpa_ctrl_open(NULL); 3930189251Ssam if (ctrl == NULL) 3931189251Ssam return NULL; 3932189251Ssam 3933189251Ssam len = sizeof(buf) - 1; 3934189251Ssam ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); 3935189251Ssam if (ret >= 0) { 3936189251Ssam buf[len] = '\0'; 3937189251Ssam pos = os_strchr(buf, '\n'); 3938189251Ssam if (pos) 3939189251Ssam *pos = '\0'; 3940189251Ssam ifname = os_strdup(buf); 3941189251Ssam } 3942189251Ssam wpa_ctrl_close(ctrl); 3943189251Ssam#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 3944189251Ssam 3945189251Ssam return ifname; 3946189251Ssam} 3947189251Ssam 3948189251Ssam 3949189251Ssamint main(int argc, char *argv[]) 3950189251Ssam{ 3951189251Ssam int c; 3952189251Ssam int daemonize = 0; 3953189251Ssam int ret = 0; 3954189251Ssam const char *global = NULL; 3955189251Ssam 3956189251Ssam if (os_program_init()) 3957189251Ssam return -1; 3958189251Ssam 3959189251Ssam for (;;) { 3960189251Ssam c = getopt(argc, argv, "a:Bg:G:hi:p:P:v"); 3961189251Ssam if (c < 0) 3962189251Ssam break; 3963189251Ssam switch (c) { 3964189251Ssam case 'a': 3965189251Ssam action_file = optarg; 3966189251Ssam break; 3967189251Ssam case 'B': 3968189251Ssam daemonize = 1; 3969189251Ssam break; 3970189251Ssam case 'g': 3971189251Ssam global = optarg; 3972189251Ssam break; 3973189251Ssam case 'G': 3974189251Ssam ping_interval = atoi(optarg); 3975189251Ssam break; 3976189251Ssam case 'h': 3977189251Ssam usage(); 3978189251Ssam return 0; 3979189251Ssam case 'v': 3980189251Ssam printf("%s\n", wpa_cli_version); 3981189251Ssam return 0; 3982189251Ssam case 'i': 3983189251Ssam os_free(ctrl_ifname); 3984189251Ssam ctrl_ifname = os_strdup(optarg); 3985189251Ssam break; 3986189251Ssam case 'p': 3987189251Ssam ctrl_iface_dir = optarg; 3988189251Ssam break; 3989189251Ssam case 'P': 3990189251Ssam pid_file = optarg; 3991189251Ssam break; 3992189251Ssam default: 3993189251Ssam usage(); 3994189251Ssam return -1; 3995189251Ssam } 3996189251Ssam } 3997189251Ssam 3998189251Ssam interactive = (argc == optind) && (action_file == NULL); 3999189251Ssam 4000189251Ssam if (interactive) 4001189251Ssam printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license); 4002189251Ssam 4003252726Srpaulo if (eloop_init()) 4004252726Srpaulo return -1; 4005252726Srpaulo 4006189251Ssam if (global) { 4007189251Ssam#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4008189251Ssam ctrl_conn = wpa_ctrl_open(NULL); 4009189251Ssam#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4010189251Ssam ctrl_conn = wpa_ctrl_open(global); 4011189251Ssam#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4012189251Ssam if (ctrl_conn == NULL) { 4013252726Srpaulo fprintf(stderr, "Failed to connect to wpa_supplicant " 4014252726Srpaulo "global interface: %s error: %s\n", 4015252726Srpaulo global, strerror(errno)); 4016189251Ssam return -1; 4017189251Ssam } 4018281806Srpaulo 4019281806Srpaulo if (interactive) { 4020281806Srpaulo update_ifnames(ctrl_conn); 4021281806Srpaulo mon_conn = wpa_ctrl_open(global); 4022281806Srpaulo if (mon_conn) { 4023281806Srpaulo if (wpa_ctrl_attach(mon_conn) == 0) { 4024281806Srpaulo wpa_cli_attached = 1; 4025281806Srpaulo eloop_register_read_sock( 4026281806Srpaulo wpa_ctrl_get_fd(mon_conn), 4027281806Srpaulo wpa_cli_mon_receive, 4028281806Srpaulo NULL, NULL); 4029281806Srpaulo } else { 4030281806Srpaulo printf("Failed to open monitor " 4031281806Srpaulo "connection through global " 4032281806Srpaulo "control interface\n"); 4033281806Srpaulo } 4034281806Srpaulo } 4035281806Srpaulo } 4036189251Ssam } 4037189251Ssam 4038252726Srpaulo eloop_register_signal_terminate(wpa_cli_terminate, NULL); 4039189251Ssam 4040214734Srpaulo if (ctrl_ifname == NULL) 4041214734Srpaulo ctrl_ifname = wpa_cli_get_default_ifname(); 4042214734Srpaulo 4043214734Srpaulo if (interactive) { 4044252726Srpaulo wpa_cli_interactive(); 4045214734Srpaulo } else { 4046214734Srpaulo if (!global && 4047214734Srpaulo wpa_cli_open_connection(ctrl_ifname, 0) < 0) { 4048252726Srpaulo fprintf(stderr, "Failed to connect to non-global " 4049252726Srpaulo "ctrl_ifname: %s error: %s\n", 4050281806Srpaulo ctrl_ifname ? ctrl_ifname : "(nil)", 4051281806Srpaulo strerror(errno)); 4052214734Srpaulo return -1; 4053214734Srpaulo } 4054214734Srpaulo 4055214734Srpaulo if (action_file) { 4056214734Srpaulo if (wpa_ctrl_attach(ctrl_conn) == 0) { 4057214734Srpaulo wpa_cli_attached = 1; 4058214734Srpaulo } else { 4059214734Srpaulo printf("Warning: Failed to attach to " 4060214734Srpaulo "wpa_supplicant.\n"); 4061189251Ssam return -1; 4062214734Srpaulo } 4063189251Ssam } 4064189251Ssam 4065252726Srpaulo if (daemonize && os_daemonize(pid_file)) 4066252726Srpaulo return -1; 4067189251Ssam 4068252726Srpaulo if (action_file) 4069252726Srpaulo wpa_cli_action(ctrl_conn); 4070252726Srpaulo else 4071252726Srpaulo ret = wpa_request(ctrl_conn, argc - optind, 4072252726Srpaulo &argv[optind]); 4073252726Srpaulo } 4074189251Ssam 4075189251Ssam os_free(ctrl_ifname); 4076252726Srpaulo eloop_destroy(); 4077189251Ssam wpa_cli_cleanup(); 4078189251Ssam 4079189251Ssam return ret; 4080189251Ssam} 4081189251Ssam 4082189251Ssam#else /* CONFIG_CTRL_IFACE */ 4083189251Ssamint main(int argc, char *argv[]) 4084189251Ssam{ 4085189251Ssam printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n"); 4086189251Ssam return -1; 4087189251Ssam} 4088189251Ssam#endif /* CONFIG_CTRL_IFACE */ 4089