wpa_cli.c revision 252726
1189251Ssam/* 2189251Ssam * WPA Supplicant - command line interface for wpa_supplicant daemon 3252726Srpaulo * Copyright (c) 2004-2012, 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" 31252726Srpaulo"Copyright (c) 2004-2012, 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; 73189251Ssamstatic int wpa_cli_connected = 0; 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; 84189251Ssam 85252726Srpaulostruct cli_txt_entry { 86252726Srpaulo struct dl_list list; 87252726Srpaulo char *txt; 88252726Srpaulo}; 89189251Ssam 90252726Srpaulostatic DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */ 91252726Srpaulostatic DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */ 92252726Srpaulostatic DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */ 93189251Ssam 94189251Ssam 95252726Srpaulostatic void print_help(const char *cmd); 96252726Srpaulostatic void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx); 97252726Srpaulostatic void wpa_cli_close_connection(void); 98252726Srpaulostatic char * wpa_cli_get_default_ifname(void); 99252726Srpaulostatic char ** wpa_list_cmd_list(void); 100252726Srpaulo 101252726Srpaulo 102189251Ssamstatic void usage(void) 103189251Ssam{ 104189251Ssam printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] " 105189251Ssam "[-a<action file>] \\\n" 106189251Ssam " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] " 107189251Ssam "[command..]\n" 108189251Ssam " -h = help (show this usage text)\n" 109189251Ssam " -v = shown version information\n" 110189251Ssam " -a = run in daemon mode executing the action file based on " 111189251Ssam "events from\n" 112189251Ssam " wpa_supplicant\n" 113189251Ssam " -B = run a daemon in the background\n" 114252726Srpaulo " default path: " CONFIG_CTRL_IFACE_DIR "\n" 115189251Ssam " default interface: first interface found in socket path\n"); 116252726Srpaulo print_help(NULL); 117189251Ssam} 118189251Ssam 119189251Ssam 120252726Srpaulostatic void cli_txt_list_free(struct cli_txt_entry *e) 121252726Srpaulo{ 122252726Srpaulo dl_list_del(&e->list); 123252726Srpaulo os_free(e->txt); 124252726Srpaulo os_free(e); 125252726Srpaulo} 126214734Srpaulo 127252726Srpaulo 128252726Srpaulostatic void cli_txt_list_flush(struct dl_list *list) 129189251Ssam{ 130252726Srpaulo struct cli_txt_entry *e; 131252726Srpaulo while ((e = dl_list_first(list, struct cli_txt_entry, list))) 132252726Srpaulo cli_txt_list_free(e); 133214734Srpaulo} 134214734Srpaulo 135252726Srpaulo 136252726Srpaulostatic struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list, 137252726Srpaulo const char *txt) 138214734Srpaulo{ 139252726Srpaulo struct cli_txt_entry *e; 140252726Srpaulo dl_list_for_each(e, txt_list, struct cli_txt_entry, list) { 141252726Srpaulo if (os_strcmp(e->txt, txt) == 0) 142252726Srpaulo return e; 143252726Srpaulo } 144252726Srpaulo return NULL; 145252726Srpaulo} 146214734Srpaulo 147214734Srpaulo 148252726Srpaulostatic void cli_txt_list_del(struct dl_list *txt_list, const char *txt) 149252726Srpaulo{ 150252726Srpaulo struct cli_txt_entry *e; 151252726Srpaulo e = cli_txt_list_get(txt_list, txt); 152252726Srpaulo if (e) 153252726Srpaulo cli_txt_list_free(e); 154252726Srpaulo} 155252726Srpaulo 156252726Srpaulo 157252726Srpaulostatic void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt) 158252726Srpaulo{ 159252726Srpaulo u8 addr[ETH_ALEN]; 160252726Srpaulo char buf[18]; 161252726Srpaulo if (hwaddr_aton(txt, addr) < 0) 162252726Srpaulo return; 163252726Srpaulo os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 164252726Srpaulo cli_txt_list_del(txt_list, buf); 165252726Srpaulo} 166252726Srpaulo 167252726Srpaulo 168252726Srpaulo#ifdef CONFIG_P2P 169252726Srpaulostatic void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt) 170252726Srpaulo{ 171252726Srpaulo const char *end; 172252726Srpaulo char *buf; 173252726Srpaulo end = os_strchr(txt, ' '); 174252726Srpaulo if (end == NULL) 175252726Srpaulo end = txt + os_strlen(txt); 176252726Srpaulo buf = os_malloc(end - txt + 1); 177252726Srpaulo if (buf == NULL) 178252726Srpaulo return; 179252726Srpaulo os_memcpy(buf, txt, end - txt); 180252726Srpaulo buf[end - txt] = '\0'; 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); 226252726Srpaulo buf = os_malloc(end - txt + 1); 227252726Srpaulo if (buf == NULL) 228252726Srpaulo return -1; 229252726Srpaulo os_memcpy(buf, txt, end - txt); 230252726Srpaulo buf[end - txt] = '\0'; 231252726Srpaulo ret = cli_txt_list_add(txt_list, buf); 232252726Srpaulo os_free(buf); 233252726Srpaulo return ret; 234252726Srpaulo} 235252726Srpaulo#endif /* CONFIG_P2P */ 236252726Srpaulo 237252726Srpaulo 238252726Srpaulostatic char ** cli_txt_list_array(struct dl_list *txt_list) 239252726Srpaulo{ 240252726Srpaulo unsigned int i, count = dl_list_len(txt_list); 241252726Srpaulo char **res; 242252726Srpaulo struct cli_txt_entry *e; 243252726Srpaulo 244252726Srpaulo res = os_calloc(count + 1, sizeof(char *)); 245252726Srpaulo if (res == NULL) 246252726Srpaulo return NULL; 247252726Srpaulo 248252726Srpaulo i = 0; 249252726Srpaulo dl_list_for_each(e, txt_list, struct cli_txt_entry, list) { 250252726Srpaulo res[i] = os_strdup(e->txt); 251252726Srpaulo if (res[i] == NULL) 252214734Srpaulo break; 253252726Srpaulo i++; 254252726Srpaulo } 255252726Srpaulo 256252726Srpaulo return res; 257252726Srpaulo} 258252726Srpaulo 259252726Srpaulo 260252726Srpaulostatic int get_cmd_arg_num(const char *str, int pos) 261252726Srpaulo{ 262252726Srpaulo int arg = 0, i; 263252726Srpaulo 264252726Srpaulo for (i = 0; i <= pos; i++) { 265252726Srpaulo if (str[i] != ' ') { 266252726Srpaulo arg++; 267252726Srpaulo while (i <= pos && str[i] != ' ') 268252726Srpaulo i++; 269214734Srpaulo } 270214734Srpaulo } 271252726Srpaulo 272252726Srpaulo if (arg > 0) 273252726Srpaulo arg--; 274252726Srpaulo return arg; 275214734Srpaulo} 276214734Srpaulo 277214734Srpaulo 278252726Srpaulostatic int str_starts(const char *src, const char *match) 279252726Srpaulo{ 280252726Srpaulo return os_strncmp(src, match, os_strlen(match)) == 0; 281252726Srpaulo} 282252726Srpaulo 283252726Srpaulo 284252726Srpaulostatic int wpa_cli_show_event(const char *event) 285252726Srpaulo{ 286252726Srpaulo const char *start; 287252726Srpaulo 288252726Srpaulo start = os_strchr(event, '>'); 289252726Srpaulo if (start == NULL) 290252726Srpaulo return 1; 291252726Srpaulo 292252726Srpaulo start++; 293252726Srpaulo /* 294252726Srpaulo * Skip BSS added/removed events since they can be relatively frequent 295252726Srpaulo * and are likely of not much use for an interactive user. 296252726Srpaulo */ 297252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_ADDED) || 298252726Srpaulo str_starts(start, WPA_EVENT_BSS_REMOVED)) 299252726Srpaulo return 0; 300252726Srpaulo 301252726Srpaulo return 1; 302252726Srpaulo} 303252726Srpaulo 304252726Srpaulo 305214734Srpaulostatic int wpa_cli_open_connection(const char *ifname, int attach) 306214734Srpaulo{ 307189251Ssam#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE) 308189251Ssam ctrl_conn = wpa_ctrl_open(ifname); 309214734Srpaulo if (ctrl_conn == NULL) 310214734Srpaulo return -1; 311214734Srpaulo 312214734Srpaulo if (attach && interactive) 313214734Srpaulo mon_conn = wpa_ctrl_open(ifname); 314214734Srpaulo else 315214734Srpaulo mon_conn = NULL; 316189251Ssam#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 317252726Srpaulo char *cfile = NULL; 318189251Ssam int flen, res; 319189251Ssam 320189251Ssam if (ifname == NULL) 321214734Srpaulo return -1; 322189251Ssam 323252726Srpaulo#ifdef ANDROID 324252726Srpaulo if (access(ctrl_iface_dir, F_OK) < 0) { 325252726Srpaulo cfile = os_strdup(ifname); 326252726Srpaulo if (cfile == NULL) 327252726Srpaulo return -1; 328189251Ssam } 329252726Srpaulo#endif /* ANDROID */ 330189251Ssam 331252726Srpaulo if (cfile == NULL) { 332252726Srpaulo flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2; 333252726Srpaulo cfile = os_malloc(flen); 334252726Srpaulo if (cfile == NULL) 335252726Srpaulo return -1; 336252726Srpaulo res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, 337252726Srpaulo ifname); 338252726Srpaulo if (res < 0 || res >= flen) { 339252726Srpaulo os_free(cfile); 340252726Srpaulo return -1; 341252726Srpaulo } 342252726Srpaulo } 343252726Srpaulo 344189251Ssam ctrl_conn = wpa_ctrl_open(cfile); 345214734Srpaulo if (ctrl_conn == NULL) { 346214734Srpaulo os_free(cfile); 347214734Srpaulo return -1; 348214734Srpaulo } 349214734Srpaulo 350214734Srpaulo if (attach && interactive) 351214734Srpaulo mon_conn = wpa_ctrl_open(cfile); 352214734Srpaulo else 353214734Srpaulo mon_conn = NULL; 354189251Ssam os_free(cfile); 355189251Ssam#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 356214734Srpaulo 357214734Srpaulo if (mon_conn) { 358214734Srpaulo if (wpa_ctrl_attach(mon_conn) == 0) { 359214734Srpaulo wpa_cli_attached = 1; 360252726Srpaulo if (interactive) 361252726Srpaulo eloop_register_read_sock( 362252726Srpaulo wpa_ctrl_get_fd(mon_conn), 363252726Srpaulo wpa_cli_mon_receive, NULL, NULL); 364214734Srpaulo } else { 365214734Srpaulo printf("Warning: Failed to attach to " 366214734Srpaulo "wpa_supplicant.\n"); 367252726Srpaulo wpa_cli_close_connection(); 368214734Srpaulo return -1; 369214734Srpaulo } 370214734Srpaulo } 371214734Srpaulo 372214734Srpaulo return 0; 373189251Ssam} 374189251Ssam 375189251Ssam 376189251Ssamstatic void wpa_cli_close_connection(void) 377189251Ssam{ 378189251Ssam if (ctrl_conn == NULL) 379189251Ssam return; 380189251Ssam 381189251Ssam if (wpa_cli_attached) { 382214734Srpaulo wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn); 383189251Ssam wpa_cli_attached = 0; 384189251Ssam } 385189251Ssam wpa_ctrl_close(ctrl_conn); 386189251Ssam ctrl_conn = NULL; 387214734Srpaulo if (mon_conn) { 388252726Srpaulo eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn)); 389214734Srpaulo wpa_ctrl_close(mon_conn); 390214734Srpaulo mon_conn = NULL; 391214734Srpaulo } 392189251Ssam} 393189251Ssam 394189251Ssam 395189251Ssamstatic void wpa_cli_msg_cb(char *msg, size_t len) 396189251Ssam{ 397189251Ssam printf("%s\n", msg); 398189251Ssam} 399189251Ssam 400189251Ssam 401189251Ssamstatic int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print) 402189251Ssam{ 403189251Ssam char buf[2048]; 404189251Ssam size_t len; 405189251Ssam int ret; 406189251Ssam 407189251Ssam if (ctrl_conn == NULL) { 408189251Ssam printf("Not connected to wpa_supplicant - command dropped.\n"); 409189251Ssam return -1; 410189251Ssam } 411189251Ssam len = sizeof(buf) - 1; 412189251Ssam ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 413189251Ssam wpa_cli_msg_cb); 414189251Ssam if (ret == -2) { 415189251Ssam printf("'%s' command timed out.\n", cmd); 416189251Ssam return -2; 417189251Ssam } else if (ret < 0) { 418189251Ssam printf("'%s' command failed.\n", cmd); 419189251Ssam return -1; 420189251Ssam } 421189251Ssam if (print) { 422189251Ssam buf[len] = '\0'; 423189251Ssam printf("%s", buf); 424252726Srpaulo if (interactive && len > 0 && buf[len - 1] != '\n') 425252726Srpaulo printf("\n"); 426189251Ssam } 427189251Ssam return 0; 428189251Ssam} 429189251Ssam 430189251Ssam 431189251Ssamstatic int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd) 432189251Ssam{ 433189251Ssam return _wpa_ctrl_command(ctrl, cmd, 1); 434189251Ssam} 435189251Ssam 436189251Ssam 437252726Srpaulostatic int write_cmd(char *buf, size_t buflen, const char *cmd, int argc, 438252726Srpaulo char *argv[]) 439252726Srpaulo{ 440252726Srpaulo int i, res; 441252726Srpaulo char *pos, *end; 442252726Srpaulo 443252726Srpaulo pos = buf; 444252726Srpaulo end = buf + buflen; 445252726Srpaulo 446252726Srpaulo res = os_snprintf(pos, end - pos, "%s", cmd); 447252726Srpaulo if (res < 0 || res >= end - pos) 448252726Srpaulo goto fail; 449252726Srpaulo pos += res; 450252726Srpaulo 451252726Srpaulo for (i = 0; i < argc; i++) { 452252726Srpaulo res = os_snprintf(pos, end - pos, " %s", argv[i]); 453252726Srpaulo if (res < 0 || res >= end - pos) 454252726Srpaulo goto fail; 455252726Srpaulo pos += res; 456252726Srpaulo } 457252726Srpaulo 458252726Srpaulo buf[buflen - 1] = '\0'; 459252726Srpaulo return 0; 460252726Srpaulo 461252726Srpaulofail: 462252726Srpaulo printf("Too long command\n"); 463252726Srpaulo return -1; 464252726Srpaulo} 465252726Srpaulo 466252726Srpaulo 467252726Srpaulostatic int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args, 468252726Srpaulo int argc, char *argv[]) 469252726Srpaulo{ 470252726Srpaulo char buf[256]; 471252726Srpaulo if (argc < min_args) { 472252726Srpaulo printf("Invalid %s command - at least %d argument%s " 473252726Srpaulo "required.\n", cmd, min_args, 474252726Srpaulo min_args > 1 ? "s are" : " is"); 475252726Srpaulo return -1; 476252726Srpaulo } 477252726Srpaulo if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0) 478252726Srpaulo return -1; 479252726Srpaulo return wpa_ctrl_command(ctrl, buf); 480252726Srpaulo} 481252726Srpaulo 482252726Srpaulo 483252726Srpaulostatic int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[]) 484252726Srpaulo{ 485252726Srpaulo return wpa_ctrl_command(ctrl, "IFNAME"); 486252726Srpaulo} 487252726Srpaulo 488252726Srpaulo 489189251Ssamstatic int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) 490189251Ssam{ 491252726Srpaulo if (argc > 0 && os_strcmp(argv[0], "verbose") == 0) 492252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS-VERBOSE"); 493252726Srpaulo if (argc > 0 && os_strcmp(argv[0], "wps") == 0) 494252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS-WPS"); 495252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS"); 496189251Ssam} 497189251Ssam 498189251Ssam 499189251Ssamstatic int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[]) 500189251Ssam{ 501189251Ssam return wpa_ctrl_command(ctrl, "PING"); 502189251Ssam} 503189251Ssam 504189251Ssam 505252726Srpaulostatic int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[]) 506252726Srpaulo{ 507252726Srpaulo return wpa_ctrl_command(ctrl, "RELOG"); 508252726Srpaulo} 509252726Srpaulo 510252726Srpaulo 511252726Srpaulostatic int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[]) 512252726Srpaulo{ 513252726Srpaulo return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv); 514252726Srpaulo} 515252726Srpaulo 516252726Srpaulo 517189251Ssamstatic int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[]) 518189251Ssam{ 519189251Ssam return wpa_ctrl_command(ctrl, "MIB"); 520189251Ssam} 521189251Ssam 522189251Ssam 523189251Ssamstatic int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 524189251Ssam{ 525189251Ssam return wpa_ctrl_command(ctrl, "PMKSA"); 526189251Ssam} 527189251Ssam 528189251Ssam 529189251Ssamstatic int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[]) 530189251Ssam{ 531252726Srpaulo print_help(argc > 0 ? argv[0] : NULL); 532189251Ssam return 0; 533189251Ssam} 534189251Ssam 535189251Ssam 536252726Srpaulostatic char ** wpa_cli_complete_help(const char *str, int pos) 537252726Srpaulo{ 538252726Srpaulo int arg = get_cmd_arg_num(str, pos); 539252726Srpaulo char **res = NULL; 540252726Srpaulo 541252726Srpaulo switch (arg) { 542252726Srpaulo case 1: 543252726Srpaulo res = wpa_list_cmd_list(); 544252726Srpaulo break; 545252726Srpaulo } 546252726Srpaulo 547252726Srpaulo return res; 548252726Srpaulo} 549252726Srpaulo 550252726Srpaulo 551189251Ssamstatic int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[]) 552189251Ssam{ 553189251Ssam printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license); 554189251Ssam return 0; 555189251Ssam} 556189251Ssam 557189251Ssam 558189251Ssamstatic int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[]) 559189251Ssam{ 560189251Ssam wpa_cli_quit = 1; 561252726Srpaulo if (interactive) 562252726Srpaulo eloop_terminate(); 563189251Ssam return 0; 564189251Ssam} 565189251Ssam 566189251Ssam 567189251Ssamstatic void wpa_cli_show_variables(void) 568189251Ssam{ 569189251Ssam printf("set variables:\n" 570189251Ssam " EAPOL::heldPeriod (EAPOL state machine held period, " 571189251Ssam "in seconds)\n" 572189251Ssam " EAPOL::authPeriod (EAPOL state machine authentication " 573189251Ssam "period, in seconds)\n" 574189251Ssam " EAPOL::startPeriod (EAPOL state machine start period, in " 575189251Ssam "seconds)\n" 576189251Ssam " EAPOL::maxStart (EAPOL state machine maximum start " 577189251Ssam "attempts)\n"); 578189251Ssam printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in " 579189251Ssam "seconds)\n" 580189251Ssam " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication" 581189251Ssam " threshold\n\tpercentage)\n" 582189251Ssam " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing " 583189251Ssam "security\n\tassociation in seconds)\n"); 584189251Ssam} 585189251Ssam 586189251Ssam 587189251Ssamstatic int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 588189251Ssam{ 589189251Ssam char cmd[256]; 590189251Ssam int res; 591189251Ssam 592189251Ssam if (argc == 0) { 593189251Ssam wpa_cli_show_variables(); 594189251Ssam return 0; 595189251Ssam } 596189251Ssam 597252726Srpaulo if (argc != 1 && argc != 2) { 598189251Ssam printf("Invalid SET command: needs two arguments (variable " 599189251Ssam "name and value)\n"); 600189251Ssam return -1; 601189251Ssam } 602189251Ssam 603252726Srpaulo if (argc == 1) 604252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]); 605252726Srpaulo else 606252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", 607252726Srpaulo argv[0], argv[1]); 608189251Ssam if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 609189251Ssam printf("Too long SET command.\n"); 610189251Ssam return -1; 611189251Ssam } 612189251Ssam return wpa_ctrl_command(ctrl, cmd); 613189251Ssam} 614189251Ssam 615189251Ssam 616252726Srpaulostatic int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 617252726Srpaulo{ 618252726Srpaulo return wpa_cli_cmd(ctrl, "GET", 1, argc, argv); 619252726Srpaulo} 620252726Srpaulo 621252726Srpaulo 622189251Ssamstatic int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[]) 623189251Ssam{ 624189251Ssam return wpa_ctrl_command(ctrl, "LOGOFF"); 625189251Ssam} 626189251Ssam 627189251Ssam 628189251Ssamstatic int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[]) 629189251Ssam{ 630189251Ssam return wpa_ctrl_command(ctrl, "LOGON"); 631189251Ssam} 632189251Ssam 633189251Ssam 634189251Ssamstatic int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc, 635189251Ssam char *argv[]) 636189251Ssam{ 637189251Ssam return wpa_ctrl_command(ctrl, "REASSOCIATE"); 638189251Ssam} 639189251Ssam 640189251Ssam 641189251Ssamstatic int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc, 642189251Ssam char *argv[]) 643189251Ssam{ 644252726Srpaulo return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv); 645252726Srpaulo} 646189251Ssam 647189251Ssam 648252726Srpaulostatic int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 649252726Srpaulo{ 650252726Srpaulo return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv); 651189251Ssam} 652189251Ssam 653189251Ssam 654252726Srpaulostatic int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc, 655252726Srpaulo char *argv[]) 656189251Ssam{ 657252726Srpaulo return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv); 658252726Srpaulo} 659252726Srpaulo 660252726Srpaulo 661252726Srpaulostatic int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc, 662252726Srpaulo char *argv[]) 663252726Srpaulo{ 664252726Srpaulo return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv); 665252726Srpaulo} 666252726Srpaulo 667252726Srpaulo 668252726Srpaulostatic int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc, 669252726Srpaulo char *argv[]) 670252726Srpaulo{ 671252726Srpaulo return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv); 672252726Srpaulo} 673252726Srpaulo 674252726Srpaulo 675252726Srpaulostatic int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 676252726Srpaulo{ 677189251Ssam char cmd[256]; 678189251Ssam int res; 679189251Ssam 680252726Srpaulo if (argc < 1) 681252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0"); 682252726Srpaulo else 683252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]); 684189251Ssam if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 685252726Srpaulo printf("Too long BSS_FLUSH command.\n"); 686189251Ssam return -1; 687189251Ssam } 688189251Ssam return wpa_ctrl_command(ctrl, cmd); 689189251Ssam} 690189251Ssam 691189251Ssam 692189251Ssamstatic int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc, 693189251Ssam char *argv[]) 694189251Ssam{ 695252726Srpaulo return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv); 696252726Srpaulo} 697189251Ssam 698252726Srpaulo 699252726Srpaulostatic int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[]) 700252726Srpaulo{ 701252726Srpaulo return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv); 702252726Srpaulo} 703252726Srpaulo 704252726Srpaulo 705252726Srpaulostatic int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 706252726Srpaulo{ 707252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv); 708252726Srpaulo} 709252726Srpaulo 710252726Srpaulo 711252726Srpaulostatic int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 712252726Srpaulo{ 713252726Srpaulo if (argc == 0) { 714252726Srpaulo printf("Invalid WPS_PIN command: need one or two arguments:\n" 715252726Srpaulo "- BSSID: use 'any' to select any\n" 716252726Srpaulo "- PIN: optional, used only with devices that have no " 717252726Srpaulo "display\n"); 718189251Ssam return -1; 719189251Ssam } 720189251Ssam 721252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv); 722189251Ssam} 723189251Ssam 724189251Ssam 725252726Srpaulostatic int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc, 726252726Srpaulo char *argv[]) 727189251Ssam{ 728252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv); 729252726Srpaulo} 730189251Ssam 731252726Srpaulo 732252726Srpaulostatic int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc, 733252726Srpaulo char *argv[]) 734252726Srpaulo{ 735252726Srpaulo return wpa_ctrl_command(ctrl, "WPS_CANCEL"); 736252726Srpaulo} 737252726Srpaulo 738252726Srpaulo 739252726Srpaulo#ifdef CONFIG_WPS_NFC 740252726Srpaulo 741252726Srpaulostatic int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 742252726Srpaulo{ 743252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv); 744252726Srpaulo} 745252726Srpaulo 746252726Srpaulo 747252726Srpaulostatic int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc, 748252726Srpaulo char *argv[]) 749252726Srpaulo{ 750252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv); 751252726Srpaulo} 752252726Srpaulo 753252726Srpaulo 754252726Srpaulostatic int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc, 755252726Srpaulo char *argv[]) 756252726Srpaulo{ 757252726Srpaulo int ret; 758252726Srpaulo char *buf; 759252726Srpaulo size_t buflen; 760252726Srpaulo 761189251Ssam if (argc != 1) { 762252726Srpaulo printf("Invalid 'wps_nfc_tag_read' command - one argument " 763252726Srpaulo "is required.\n"); 764189251Ssam return -1; 765189251Ssam } 766189251Ssam 767252726Srpaulo buflen = 18 + os_strlen(argv[0]); 768252726Srpaulo buf = os_malloc(buflen); 769252726Srpaulo if (buf == NULL) 770189251Ssam return -1; 771252726Srpaulo os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]); 772252726Srpaulo 773252726Srpaulo ret = wpa_ctrl_command(ctrl, buf); 774252726Srpaulo os_free(buf); 775252726Srpaulo 776252726Srpaulo return ret; 777189251Ssam} 778189251Ssam 779189251Ssam 780252726Srpaulostatic int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc, 781252726Srpaulo char *argv[]) 782189251Ssam{ 783252726Srpaulo return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv); 784252726Srpaulo} 785189251Ssam 786189251Ssam 787252726Srpaulostatic int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc, 788252726Srpaulo char *argv[]) 789252726Srpaulo{ 790252726Srpaulo return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv); 791189251Ssam} 792189251Ssam 793189251Ssam 794252726Srpaulostatic int wpa_cli_cmd_nfc_rx_handover_req(struct wpa_ctrl *ctrl, int argc, 795252726Srpaulo char *argv[]) 796189251Ssam{ 797252726Srpaulo int ret; 798252726Srpaulo char *buf; 799252726Srpaulo size_t buflen; 800189251Ssam 801252726Srpaulo if (argc != 1) { 802252726Srpaulo printf("Invalid 'nfc_rx_handover_req' command - one argument " 803252726Srpaulo "is required.\n"); 804189251Ssam return -1; 805189251Ssam } 806189251Ssam 807252726Srpaulo buflen = 21 + os_strlen(argv[0]); 808252726Srpaulo buf = os_malloc(buflen); 809252726Srpaulo if (buf == NULL) 810252726Srpaulo return -1; 811252726Srpaulo os_snprintf(buf, buflen, "NFC_RX_HANDOVER_REQ %s", argv[0]); 812189251Ssam 813252726Srpaulo ret = wpa_ctrl_command(ctrl, buf); 814252726Srpaulo os_free(buf); 815252726Srpaulo 816252726Srpaulo return ret; 817189251Ssam} 818189251Ssam 819189251Ssam 820252726Srpaulostatic int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl *ctrl, int argc, 821252726Srpaulo char *argv[]) 822214734Srpaulo{ 823252726Srpaulo int ret; 824252726Srpaulo char *buf; 825252726Srpaulo size_t buflen; 826214734Srpaulo 827252726Srpaulo if (argc != 1) { 828252726Srpaulo printf("Invalid 'nfc_rx_handover_sel' command - one argument " 829252726Srpaulo "is required.\n"); 830214734Srpaulo return -1; 831214734Srpaulo } 832214734Srpaulo 833252726Srpaulo buflen = 21 + os_strlen(argv[0]); 834252726Srpaulo buf = os_malloc(buflen); 835252726Srpaulo if (buf == NULL) 836214734Srpaulo return -1; 837252726Srpaulo os_snprintf(buf, buflen, "NFC_RX_HANDOVER_SEL %s", argv[0]); 838252726Srpaulo 839252726Srpaulo ret = wpa_ctrl_command(ctrl, buf); 840252726Srpaulo os_free(buf); 841252726Srpaulo 842252726Srpaulo return ret; 843214734Srpaulo} 844214734Srpaulo 845252726Srpaulo#endif /* CONFIG_WPS_NFC */ 846214734Srpaulo 847252726Srpaulo 848189251Ssamstatic int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[]) 849189251Ssam{ 850189251Ssam char cmd[256]; 851189251Ssam int res; 852189251Ssam 853214734Srpaulo if (argc == 2) 854214734Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", 855214734Srpaulo argv[0], argv[1]); 856252726Srpaulo else if (argc == 5 || argc == 6) { 857214734Srpaulo char ssid_hex[2 * 32 + 1]; 858214734Srpaulo char key_hex[2 * 64 + 1]; 859214734Srpaulo int i; 860214734Srpaulo 861214734Srpaulo ssid_hex[0] = '\0'; 862214734Srpaulo for (i = 0; i < 32; i++) { 863214734Srpaulo if (argv[2][i] == '\0') 864214734Srpaulo break; 865214734Srpaulo os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 866214734Srpaulo } 867214734Srpaulo 868214734Srpaulo key_hex[0] = '\0'; 869252726Srpaulo if (argc == 6) { 870252726Srpaulo for (i = 0; i < 64; i++) { 871252726Srpaulo if (argv[5][i] == '\0') 872252726Srpaulo break; 873252726Srpaulo os_snprintf(&key_hex[i * 2], 3, "%02x", 874252726Srpaulo argv[5][i]); 875252726Srpaulo } 876214734Srpaulo } 877214734Srpaulo 878214734Srpaulo res = os_snprintf(cmd, sizeof(cmd), 879214734Srpaulo "WPS_REG %s %s %s %s %s %s", 880214734Srpaulo argv[0], argv[1], ssid_hex, argv[3], argv[4], 881214734Srpaulo key_hex); 882214734Srpaulo } else { 883189251Ssam printf("Invalid WPS_REG command: need two arguments:\n" 884252726Srpaulo "- BSSID of the target AP\n" 885189251Ssam "- AP PIN\n"); 886214734Srpaulo printf("Alternatively, six arguments can be used to " 887214734Srpaulo "reconfigure the AP:\n" 888252726Srpaulo "- BSSID of the target AP\n" 889214734Srpaulo "- AP PIN\n" 890214734Srpaulo "- new SSID\n" 891214734Srpaulo "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 892214734Srpaulo "- new encr (NONE, WEP, TKIP, CCMP)\n" 893214734Srpaulo "- new key\n"); 894189251Ssam return -1; 895189251Ssam } 896189251Ssam 897189251Ssam if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 898189251Ssam printf("Too long WPS_REG command.\n"); 899189251Ssam return -1; 900189251Ssam } 901189251Ssam return wpa_ctrl_command(ctrl, cmd); 902189251Ssam} 903189251Ssam 904189251Ssam 905252726Srpaulostatic int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc, 906252726Srpaulo char *argv[]) 907252726Srpaulo{ 908252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv); 909252726Srpaulo} 910252726Srpaulo 911252726Srpaulo 912214734Srpaulostatic int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc, 913214734Srpaulo char *argv[]) 914214734Srpaulo{ 915252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv); 916214734Srpaulo} 917214734Srpaulo 918214734Srpaulo 919214734Srpaulostatic int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc, 920214734Srpaulo char *argv[]) 921214734Srpaulo{ 922214734Srpaulo return wpa_ctrl_command(ctrl, "WPS_ER_STOP"); 923214734Srpaulo 924214734Srpaulo} 925214734Srpaulo 926214734Srpaulo 927214734Srpaulostatic int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc, 928214734Srpaulo char *argv[]) 929214734Srpaulo{ 930252726Srpaulo if (argc < 2) { 931252726Srpaulo printf("Invalid WPS_ER_PIN command: need at least two " 932252726Srpaulo "arguments:\n" 933214734Srpaulo "- UUID: use 'any' to select any\n" 934252726Srpaulo "- PIN: Enrollee PIN\n" 935252726Srpaulo "optional: - Enrollee MAC address\n"); 936214734Srpaulo return -1; 937214734Srpaulo } 938214734Srpaulo 939252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv); 940214734Srpaulo} 941214734Srpaulo 942214734Srpaulo 943214734Srpaulostatic int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc, 944214734Srpaulo char *argv[]) 945214734Srpaulo{ 946252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv); 947214734Srpaulo} 948214734Srpaulo 949214734Srpaulo 950214734Srpaulostatic int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc, 951214734Srpaulo char *argv[]) 952214734Srpaulo{ 953214734Srpaulo if (argc != 2) { 954214734Srpaulo printf("Invalid WPS_ER_LEARN command: need two arguments:\n" 955214734Srpaulo "- UUID: specify which AP to use\n" 956214734Srpaulo "- PIN: AP PIN\n"); 957214734Srpaulo return -1; 958214734Srpaulo } 959214734Srpaulo 960252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv); 961252726Srpaulo} 962252726Srpaulo 963252726Srpaulo 964252726Srpaulostatic int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc, 965252726Srpaulo char *argv[]) 966252726Srpaulo{ 967252726Srpaulo if (argc != 2) { 968252726Srpaulo printf("Invalid WPS_ER_SET_CONFIG command: need two " 969252726Srpaulo "arguments:\n" 970252726Srpaulo "- UUID: specify which AP to use\n" 971252726Srpaulo "- Network configuration id\n"); 972214734Srpaulo return -1; 973214734Srpaulo } 974252726Srpaulo 975252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv); 976214734Srpaulo} 977214734Srpaulo 978214734Srpaulo 979252726Srpaulostatic int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc, 980252726Srpaulo char *argv[]) 981214734Srpaulo{ 982214734Srpaulo char cmd[256]; 983214734Srpaulo int res; 984214734Srpaulo 985252726Srpaulo if (argc == 5 || argc == 6) { 986252726Srpaulo char ssid_hex[2 * 32 + 1]; 987252726Srpaulo char key_hex[2 * 64 + 1]; 988252726Srpaulo int i; 989252726Srpaulo 990252726Srpaulo ssid_hex[0] = '\0'; 991252726Srpaulo for (i = 0; i < 32; i++) { 992252726Srpaulo if (argv[2][i] == '\0') 993252726Srpaulo break; 994252726Srpaulo os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 995252726Srpaulo } 996252726Srpaulo 997252726Srpaulo key_hex[0] = '\0'; 998252726Srpaulo if (argc == 6) { 999252726Srpaulo for (i = 0; i < 64; i++) { 1000252726Srpaulo if (argv[5][i] == '\0') 1001252726Srpaulo break; 1002252726Srpaulo os_snprintf(&key_hex[i * 2], 3, "%02x", 1003252726Srpaulo argv[5][i]); 1004252726Srpaulo } 1005252726Srpaulo } 1006252726Srpaulo 1007252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 1008252726Srpaulo "WPS_ER_CONFIG %s %s %s %s %s %s", 1009252726Srpaulo argv[0], argv[1], ssid_hex, argv[3], argv[4], 1010252726Srpaulo key_hex); 1011252726Srpaulo } else { 1012252726Srpaulo printf("Invalid WPS_ER_CONFIG command: need six arguments:\n" 1013252726Srpaulo "- AP UUID\n" 1014252726Srpaulo "- AP PIN\n" 1015252726Srpaulo "- new SSID\n" 1016252726Srpaulo "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 1017252726Srpaulo "- new encr (NONE, WEP, TKIP, CCMP)\n" 1018252726Srpaulo "- new key\n"); 1019214734Srpaulo return -1; 1020214734Srpaulo } 1021214734Srpaulo 1022214734Srpaulo if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 1023252726Srpaulo printf("Too long WPS_ER_CONFIG command.\n"); 1024214734Srpaulo return -1; 1025214734Srpaulo } 1026214734Srpaulo return wpa_ctrl_command(ctrl, cmd); 1027214734Srpaulo} 1028214734Srpaulo 1029214734Srpaulo 1030252726Srpaulo#ifdef CONFIG_WPS_NFC 1031252726Srpaulostatic int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 1032252726Srpaulo char *argv[]) 1033189251Ssam{ 1034252726Srpaulo if (argc != 2) { 1035252726Srpaulo printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two " 1036252726Srpaulo "arguments:\n" 1037252726Srpaulo "- WPS/NDEF: token format\n" 1038252726Srpaulo "- UUID: specify which AP to use\n"); 1039189251Ssam return -1; 1040189251Ssam } 1041252726Srpaulo 1042252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv); 1043189251Ssam} 1044252726Srpaulo#endif /* CONFIG_WPS_NFC */ 1045189251Ssam 1046189251Ssam 1047252726Srpaulostatic int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1048252726Srpaulo{ 1049252726Srpaulo return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv); 1050252726Srpaulo} 1051252726Srpaulo 1052252726Srpaulo 1053252726Srpaulostatic int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1054252726Srpaulo{ 1055252726Srpaulo return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv); 1056252726Srpaulo} 1057252726Srpaulo 1058252726Srpaulo 1059189251Ssamstatic int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1060189251Ssam{ 1061189251Ssam char cmd[256], *pos, *end; 1062189251Ssam int i, ret; 1063189251Ssam 1064189251Ssam if (argc < 2) { 1065189251Ssam printf("Invalid IDENTITY command: needs two arguments " 1066189251Ssam "(network id and identity)\n"); 1067189251Ssam return -1; 1068189251Ssam } 1069189251Ssam 1070189251Ssam end = cmd + sizeof(cmd); 1071189251Ssam pos = cmd; 1072189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s", 1073189251Ssam argv[0], argv[1]); 1074189251Ssam if (ret < 0 || ret >= end - pos) { 1075189251Ssam printf("Too long IDENTITY command.\n"); 1076189251Ssam return -1; 1077189251Ssam } 1078189251Ssam pos += ret; 1079189251Ssam for (i = 2; i < argc; i++) { 1080189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1081189251Ssam if (ret < 0 || ret >= end - pos) { 1082189251Ssam printf("Too long IDENTITY command.\n"); 1083189251Ssam return -1; 1084189251Ssam } 1085189251Ssam pos += ret; 1086189251Ssam } 1087189251Ssam 1088189251Ssam return wpa_ctrl_command(ctrl, cmd); 1089189251Ssam} 1090189251Ssam 1091189251Ssam 1092189251Ssamstatic int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1093189251Ssam{ 1094189251Ssam char cmd[256], *pos, *end; 1095189251Ssam int i, ret; 1096189251Ssam 1097189251Ssam if (argc < 2) { 1098189251Ssam printf("Invalid PASSWORD command: needs two arguments " 1099189251Ssam "(network id and password)\n"); 1100189251Ssam return -1; 1101189251Ssam } 1102189251Ssam 1103189251Ssam end = cmd + sizeof(cmd); 1104189251Ssam pos = cmd; 1105189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s", 1106189251Ssam argv[0], argv[1]); 1107189251Ssam if (ret < 0 || ret >= end - pos) { 1108189251Ssam printf("Too long PASSWORD command.\n"); 1109189251Ssam return -1; 1110189251Ssam } 1111189251Ssam pos += ret; 1112189251Ssam for (i = 2; i < argc; i++) { 1113189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1114189251Ssam if (ret < 0 || ret >= end - pos) { 1115189251Ssam printf("Too long PASSWORD command.\n"); 1116189251Ssam return -1; 1117189251Ssam } 1118189251Ssam pos += ret; 1119189251Ssam } 1120189251Ssam 1121189251Ssam return wpa_ctrl_command(ctrl, cmd); 1122189251Ssam} 1123189251Ssam 1124189251Ssam 1125189251Ssamstatic int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc, 1126189251Ssam char *argv[]) 1127189251Ssam{ 1128189251Ssam char cmd[256], *pos, *end; 1129189251Ssam int i, ret; 1130189251Ssam 1131189251Ssam if (argc < 2) { 1132189251Ssam printf("Invalid NEW_PASSWORD command: needs two arguments " 1133189251Ssam "(network id and password)\n"); 1134189251Ssam return -1; 1135189251Ssam } 1136189251Ssam 1137189251Ssam end = cmd + sizeof(cmd); 1138189251Ssam pos = cmd; 1139189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s", 1140189251Ssam argv[0], argv[1]); 1141189251Ssam if (ret < 0 || ret >= end - pos) { 1142189251Ssam printf("Too long NEW_PASSWORD command.\n"); 1143189251Ssam return -1; 1144189251Ssam } 1145189251Ssam pos += ret; 1146189251Ssam for (i = 2; i < argc; i++) { 1147189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1148189251Ssam if (ret < 0 || ret >= end - pos) { 1149189251Ssam printf("Too long NEW_PASSWORD command.\n"); 1150189251Ssam return -1; 1151189251Ssam } 1152189251Ssam pos += ret; 1153189251Ssam } 1154189251Ssam 1155189251Ssam return wpa_ctrl_command(ctrl, cmd); 1156189251Ssam} 1157189251Ssam 1158189251Ssam 1159189251Ssamstatic int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1160189251Ssam{ 1161189251Ssam char cmd[256], *pos, *end; 1162189251Ssam int i, ret; 1163189251Ssam 1164189251Ssam if (argc < 2) { 1165189251Ssam printf("Invalid PIN command: needs two arguments " 1166189251Ssam "(network id and pin)\n"); 1167189251Ssam return -1; 1168189251Ssam } 1169189251Ssam 1170189251Ssam end = cmd + sizeof(cmd); 1171189251Ssam pos = cmd; 1172189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s", 1173189251Ssam argv[0], argv[1]); 1174189251Ssam if (ret < 0 || ret >= end - pos) { 1175189251Ssam printf("Too long PIN command.\n"); 1176189251Ssam return -1; 1177189251Ssam } 1178189251Ssam pos += ret; 1179189251Ssam for (i = 2; i < argc; i++) { 1180189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1181189251Ssam if (ret < 0 || ret >= end - pos) { 1182189251Ssam printf("Too long PIN command.\n"); 1183189251Ssam return -1; 1184189251Ssam } 1185189251Ssam pos += ret; 1186189251Ssam } 1187189251Ssam return wpa_ctrl_command(ctrl, cmd); 1188189251Ssam} 1189189251Ssam 1190189251Ssam 1191189251Ssamstatic int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1192189251Ssam{ 1193189251Ssam char cmd[256], *pos, *end; 1194189251Ssam int i, ret; 1195189251Ssam 1196189251Ssam if (argc < 2) { 1197189251Ssam printf("Invalid OTP command: needs two arguments (network " 1198189251Ssam "id and password)\n"); 1199189251Ssam return -1; 1200189251Ssam } 1201189251Ssam 1202189251Ssam end = cmd + sizeof(cmd); 1203189251Ssam pos = cmd; 1204189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s", 1205189251Ssam argv[0], argv[1]); 1206189251Ssam if (ret < 0 || ret >= end - pos) { 1207189251Ssam printf("Too long OTP command.\n"); 1208189251Ssam return -1; 1209189251Ssam } 1210189251Ssam pos += ret; 1211189251Ssam for (i = 2; i < argc; i++) { 1212189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1213189251Ssam if (ret < 0 || ret >= end - pos) { 1214189251Ssam printf("Too long OTP command.\n"); 1215189251Ssam return -1; 1216189251Ssam } 1217189251Ssam pos += ret; 1218189251Ssam } 1219189251Ssam 1220189251Ssam return wpa_ctrl_command(ctrl, cmd); 1221189251Ssam} 1222189251Ssam 1223189251Ssam 1224189251Ssamstatic int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc, 1225189251Ssam char *argv[]) 1226189251Ssam{ 1227189251Ssam char cmd[256], *pos, *end; 1228189251Ssam int i, ret; 1229189251Ssam 1230189251Ssam if (argc < 2) { 1231189251Ssam printf("Invalid PASSPHRASE command: needs two arguments " 1232189251Ssam "(network id and passphrase)\n"); 1233189251Ssam return -1; 1234189251Ssam } 1235189251Ssam 1236189251Ssam end = cmd + sizeof(cmd); 1237189251Ssam pos = cmd; 1238189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s", 1239189251Ssam argv[0], argv[1]); 1240189251Ssam if (ret < 0 || ret >= end - pos) { 1241189251Ssam printf("Too long PASSPHRASE command.\n"); 1242189251Ssam return -1; 1243189251Ssam } 1244189251Ssam pos += ret; 1245189251Ssam for (i = 2; i < argc; i++) { 1246189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1247189251Ssam if (ret < 0 || ret >= end - pos) { 1248189251Ssam printf("Too long PASSPHRASE command.\n"); 1249189251Ssam return -1; 1250189251Ssam } 1251189251Ssam pos += ret; 1252189251Ssam } 1253189251Ssam 1254189251Ssam return wpa_ctrl_command(ctrl, cmd); 1255189251Ssam} 1256189251Ssam 1257189251Ssam 1258189251Ssamstatic int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1259189251Ssam{ 1260189251Ssam if (argc < 2) { 1261189251Ssam printf("Invalid BSSID command: needs two arguments (network " 1262189251Ssam "id and BSSID)\n"); 1263189251Ssam return -1; 1264189251Ssam } 1265189251Ssam 1266252726Srpaulo return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv); 1267252726Srpaulo} 1268189251Ssam 1269252726Srpaulo 1270252726Srpaulostatic int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1271252726Srpaulo{ 1272252726Srpaulo return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv); 1273189251Ssam} 1274189251Ssam 1275189251Ssam 1276252726Srpaulostatic int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1277252726Srpaulo{ 1278252726Srpaulo return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv); 1279252726Srpaulo} 1280252726Srpaulo 1281252726Srpaulo 1282189251Ssamstatic int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc, 1283189251Ssam char *argv[]) 1284189251Ssam{ 1285189251Ssam return wpa_ctrl_command(ctrl, "LIST_NETWORKS"); 1286189251Ssam} 1287189251Ssam 1288189251Ssam 1289189251Ssamstatic int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc, 1290189251Ssam char *argv[]) 1291189251Ssam{ 1292252726Srpaulo return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv); 1293189251Ssam} 1294189251Ssam 1295189251Ssam 1296189251Ssamstatic int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc, 1297189251Ssam char *argv[]) 1298189251Ssam{ 1299252726Srpaulo return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv); 1300189251Ssam} 1301189251Ssam 1302189251Ssam 1303189251Ssamstatic int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc, 1304189251Ssam char *argv[]) 1305189251Ssam{ 1306252726Srpaulo return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv); 1307189251Ssam} 1308189251Ssam 1309189251Ssam 1310189251Ssamstatic int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc, 1311189251Ssam char *argv[]) 1312189251Ssam{ 1313189251Ssam return wpa_ctrl_command(ctrl, "ADD_NETWORK"); 1314189251Ssam} 1315189251Ssam 1316189251Ssam 1317189251Ssamstatic int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc, 1318189251Ssam char *argv[]) 1319189251Ssam{ 1320252726Srpaulo return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv); 1321189251Ssam} 1322189251Ssam 1323189251Ssam 1324189251Ssamstatic void wpa_cli_show_network_variables(void) 1325189251Ssam{ 1326189251Ssam printf("set_network variables:\n" 1327189251Ssam " ssid (network name, SSID)\n" 1328189251Ssam " psk (WPA passphrase or pre-shared key)\n" 1329189251Ssam " key_mgmt (key management protocol)\n" 1330189251Ssam " identity (EAP identity)\n" 1331189251Ssam " password (EAP password)\n" 1332189251Ssam " ...\n" 1333189251Ssam "\n" 1334189251Ssam "Note: Values are entered in the same format as the " 1335189251Ssam "configuration file is using,\n" 1336189251Ssam "i.e., strings values need to be inside double quotation " 1337189251Ssam "marks.\n" 1338189251Ssam "For example: set_network 1 ssid \"network name\"\n" 1339189251Ssam "\n" 1340189251Ssam "Please see wpa_supplicant.conf documentation for full list " 1341189251Ssam "of\navailable variables.\n"); 1342189251Ssam} 1343189251Ssam 1344189251Ssam 1345189251Ssamstatic int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc, 1346189251Ssam char *argv[]) 1347189251Ssam{ 1348189251Ssam if (argc == 0) { 1349189251Ssam wpa_cli_show_network_variables(); 1350189251Ssam return 0; 1351189251Ssam } 1352189251Ssam 1353252726Srpaulo if (argc < 3) { 1354189251Ssam printf("Invalid SET_NETWORK command: needs three arguments\n" 1355189251Ssam "(network id, variable name, and value)\n"); 1356189251Ssam return -1; 1357189251Ssam } 1358189251Ssam 1359252726Srpaulo return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv); 1360189251Ssam} 1361189251Ssam 1362189251Ssam 1363189251Ssamstatic int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc, 1364189251Ssam char *argv[]) 1365189251Ssam{ 1366189251Ssam if (argc == 0) { 1367189251Ssam wpa_cli_show_network_variables(); 1368189251Ssam return 0; 1369189251Ssam } 1370189251Ssam 1371189251Ssam if (argc != 2) { 1372189251Ssam printf("Invalid GET_NETWORK command: needs two arguments\n" 1373189251Ssam "(network id and variable name)\n"); 1374189251Ssam return -1; 1375189251Ssam } 1376189251Ssam 1377252726Srpaulo return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv); 1378252726Srpaulo} 1379252726Srpaulo 1380252726Srpaulo 1381252726Srpaulostatic int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc, 1382252726Srpaulo char *argv[]) 1383252726Srpaulo{ 1384252726Srpaulo return wpa_ctrl_command(ctrl, "LIST_CREDS"); 1385252726Srpaulo} 1386252726Srpaulo 1387252726Srpaulo 1388252726Srpaulostatic int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1389252726Srpaulo{ 1390252726Srpaulo return wpa_ctrl_command(ctrl, "ADD_CRED"); 1391252726Srpaulo} 1392252726Srpaulo 1393252726Srpaulo 1394252726Srpaulostatic int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc, 1395252726Srpaulo char *argv[]) 1396252726Srpaulo{ 1397252726Srpaulo return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv); 1398252726Srpaulo} 1399252726Srpaulo 1400252726Srpaulo 1401252726Srpaulostatic int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1402252726Srpaulo{ 1403252726Srpaulo if (argc != 3) { 1404252726Srpaulo printf("Invalid SET_CRED command: needs three arguments\n" 1405252726Srpaulo "(cred id, variable name, and value)\n"); 1406189251Ssam return -1; 1407189251Ssam } 1408252726Srpaulo 1409252726Srpaulo return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv); 1410189251Ssam} 1411189251Ssam 1412189251Ssam 1413189251Ssamstatic int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc, 1414189251Ssam char *argv[]) 1415189251Ssam{ 1416189251Ssam return wpa_ctrl_command(ctrl, "DISCONNECT"); 1417189251Ssam} 1418189251Ssam 1419189251Ssam 1420189251Ssamstatic int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc, 1421189251Ssam char *argv[]) 1422189251Ssam{ 1423189251Ssam return wpa_ctrl_command(ctrl, "RECONNECT"); 1424189251Ssam} 1425189251Ssam 1426189251Ssam 1427189251Ssamstatic int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc, 1428189251Ssam char *argv[]) 1429189251Ssam{ 1430189251Ssam return wpa_ctrl_command(ctrl, "SAVE_CONFIG"); 1431189251Ssam} 1432189251Ssam 1433189251Ssam 1434189251Ssamstatic int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1435189251Ssam{ 1436189251Ssam return wpa_ctrl_command(ctrl, "SCAN"); 1437189251Ssam} 1438189251Ssam 1439189251Ssam 1440189251Ssamstatic int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc, 1441189251Ssam char *argv[]) 1442189251Ssam{ 1443189251Ssam return wpa_ctrl_command(ctrl, "SCAN_RESULTS"); 1444189251Ssam} 1445189251Ssam 1446189251Ssam 1447189251Ssamstatic int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1448189251Ssam{ 1449252726Srpaulo return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv); 1450252726Srpaulo} 1451189251Ssam 1452252726Srpaulo 1453252726Srpaulostatic char ** wpa_cli_complete_bss(const char *str, int pos) 1454252726Srpaulo{ 1455252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1456252726Srpaulo char **res = NULL; 1457252726Srpaulo 1458252726Srpaulo switch (arg) { 1459252726Srpaulo case 1: 1460252726Srpaulo res = cli_txt_list_array(&bsses); 1461252726Srpaulo break; 1462189251Ssam } 1463189251Ssam 1464252726Srpaulo return res; 1465189251Ssam} 1466189251Ssam 1467189251Ssam 1468189251Ssamstatic int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc, 1469189251Ssam char *argv[]) 1470189251Ssam{ 1471189251Ssam if (argc < 1 || argc > 2) { 1472189251Ssam printf("Invalid GET_CAPABILITY command: need either one or " 1473189251Ssam "two arguments\n"); 1474189251Ssam return -1; 1475189251Ssam } 1476189251Ssam 1477189251Ssam if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) { 1478189251Ssam printf("Invalid GET_CAPABILITY command: second argument, " 1479189251Ssam "if any, must be 'strict'\n"); 1480189251Ssam return -1; 1481189251Ssam } 1482189251Ssam 1483252726Srpaulo return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv); 1484189251Ssam} 1485189251Ssam 1486189251Ssam 1487189251Ssamstatic int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl) 1488189251Ssam{ 1489189251Ssam printf("Available interfaces:\n"); 1490189251Ssam return wpa_ctrl_command(ctrl, "INTERFACES"); 1491189251Ssam} 1492189251Ssam 1493189251Ssam 1494189251Ssamstatic int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1495189251Ssam{ 1496189251Ssam if (argc < 1) { 1497189251Ssam wpa_cli_list_interfaces(ctrl); 1498189251Ssam return 0; 1499189251Ssam } 1500189251Ssam 1501189251Ssam wpa_cli_close_connection(); 1502189251Ssam os_free(ctrl_ifname); 1503189251Ssam ctrl_ifname = os_strdup(argv[0]); 1504189251Ssam 1505214734Srpaulo if (wpa_cli_open_connection(ctrl_ifname, 1)) { 1506189251Ssam printf("Connected to interface '%s.\n", ctrl_ifname); 1507189251Ssam } else { 1508189251Ssam printf("Could not connect to interface '%s' - re-trying\n", 1509189251Ssam ctrl_ifname); 1510189251Ssam } 1511189251Ssam return 0; 1512189251Ssam} 1513189251Ssam 1514189251Ssam 1515189251Ssamstatic int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc, 1516189251Ssam char *argv[]) 1517189251Ssam{ 1518189251Ssam return wpa_ctrl_command(ctrl, "RECONFIGURE"); 1519189251Ssam} 1520189251Ssam 1521189251Ssam 1522189251Ssamstatic int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc, 1523189251Ssam char *argv[]) 1524189251Ssam{ 1525189251Ssam return wpa_ctrl_command(ctrl, "TERMINATE"); 1526189251Ssam} 1527189251Ssam 1528189251Ssam 1529189251Ssamstatic int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc, 1530189251Ssam char *argv[]) 1531189251Ssam{ 1532189251Ssam char cmd[256]; 1533189251Ssam int res; 1534189251Ssam 1535189251Ssam if (argc < 1) { 1536189251Ssam printf("Invalid INTERFACE_ADD command: needs at least one " 1537189251Ssam "argument (interface name)\n" 1538189251Ssam "All arguments: ifname confname driver ctrl_interface " 1539189251Ssam "driver_param bridge_name\n"); 1540189251Ssam return -1; 1541189251Ssam } 1542189251Ssam 1543189251Ssam /* 1544189251Ssam * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB 1545189251Ssam * <driver_param>TAB<bridge_name> 1546189251Ssam */ 1547189251Ssam res = os_snprintf(cmd, sizeof(cmd), 1548189251Ssam "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s", 1549189251Ssam argv[0], 1550189251Ssam argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "", 1551189251Ssam argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "", 1552189251Ssam argc > 5 ? argv[5] : ""); 1553189251Ssam if (res < 0 || (size_t) res >= sizeof(cmd)) 1554189251Ssam return -1; 1555189251Ssam cmd[sizeof(cmd) - 1] = '\0'; 1556189251Ssam return wpa_ctrl_command(ctrl, cmd); 1557189251Ssam} 1558189251Ssam 1559189251Ssam 1560189251Ssamstatic int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc, 1561189251Ssam char *argv[]) 1562189251Ssam{ 1563252726Srpaulo return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv); 1564189251Ssam} 1565189251Ssam 1566189251Ssam 1567189251Ssamstatic int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc, 1568189251Ssam char *argv[]) 1569189251Ssam{ 1570189251Ssam return wpa_ctrl_command(ctrl, "INTERFACE_LIST"); 1571189251Ssam} 1572189251Ssam 1573189251Ssam 1574214734Srpaulo#ifdef CONFIG_AP 1575214734Srpaulostatic int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1576214734Srpaulo{ 1577252726Srpaulo return wpa_cli_cmd(ctrl, "STA", 1, argc, argv); 1578214734Srpaulo} 1579214734Srpaulo 1580214734Srpaulo 1581214734Srpaulostatic int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd, 1582214734Srpaulo char *addr, size_t addr_len) 1583214734Srpaulo{ 1584214734Srpaulo char buf[4096], *pos; 1585214734Srpaulo size_t len; 1586214734Srpaulo int ret; 1587214734Srpaulo 1588214734Srpaulo if (ctrl_conn == NULL) { 1589214734Srpaulo printf("Not connected to hostapd - command dropped.\n"); 1590214734Srpaulo return -1; 1591214734Srpaulo } 1592214734Srpaulo len = sizeof(buf) - 1; 1593252726Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 1594214734Srpaulo wpa_cli_msg_cb); 1595214734Srpaulo if (ret == -2) { 1596214734Srpaulo printf("'%s' command timed out.\n", cmd); 1597214734Srpaulo return -2; 1598214734Srpaulo } else if (ret < 0) { 1599214734Srpaulo printf("'%s' command failed.\n", cmd); 1600214734Srpaulo return -1; 1601214734Srpaulo } 1602214734Srpaulo 1603214734Srpaulo buf[len] = '\0'; 1604252726Srpaulo if (os_memcmp(buf, "FAIL", 4) == 0) 1605214734Srpaulo return -1; 1606214734Srpaulo printf("%s", buf); 1607214734Srpaulo 1608214734Srpaulo pos = buf; 1609214734Srpaulo while (*pos != '\0' && *pos != '\n') 1610214734Srpaulo pos++; 1611214734Srpaulo *pos = '\0'; 1612214734Srpaulo os_strlcpy(addr, buf, addr_len); 1613214734Srpaulo return 0; 1614214734Srpaulo} 1615214734Srpaulo 1616214734Srpaulo 1617214734Srpaulostatic int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1618214734Srpaulo{ 1619214734Srpaulo char addr[32], cmd[64]; 1620214734Srpaulo 1621214734Srpaulo if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr))) 1622214734Srpaulo return 0; 1623214734Srpaulo do { 1624214734Srpaulo os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 1625214734Srpaulo } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0); 1626214734Srpaulo 1627214734Srpaulo return -1; 1628214734Srpaulo} 1629252726Srpaulo 1630252726Srpaulo 1631252726Srpaulostatic int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc, 1632252726Srpaulo char *argv[]) 1633252726Srpaulo{ 1634252726Srpaulo return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv); 1635252726Srpaulo} 1636252726Srpaulo 1637252726Srpaulo 1638252726Srpaulostatic int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, 1639252726Srpaulo char *argv[]) 1640252726Srpaulo{ 1641252726Srpaulo return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv); 1642252726Srpaulo} 1643214734Srpaulo#endif /* CONFIG_AP */ 1644214734Srpaulo 1645214734Srpaulo 1646214734Srpaulostatic int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1647214734Srpaulo{ 1648214734Srpaulo return wpa_ctrl_command(ctrl, "SUSPEND"); 1649214734Srpaulo} 1650214734Srpaulo 1651214734Srpaulo 1652214734Srpaulostatic int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1653214734Srpaulo{ 1654214734Srpaulo return wpa_ctrl_command(ctrl, "RESUME"); 1655214734Srpaulo} 1656214734Srpaulo 1657214734Srpaulo 1658214734Srpaulostatic int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1659214734Srpaulo{ 1660214734Srpaulo return wpa_ctrl_command(ctrl, "DROP_SA"); 1661214734Srpaulo} 1662214734Srpaulo 1663214734Srpaulo 1664214734Srpaulostatic int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1665214734Srpaulo{ 1666252726Srpaulo return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv); 1667252726Srpaulo} 1668252726Srpaulo 1669252726Srpaulo 1670252726Srpaulo#ifdef CONFIG_P2P 1671252726Srpaulo 1672252726Srpaulostatic int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1673252726Srpaulo{ 1674252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv); 1675252726Srpaulo} 1676252726Srpaulo 1677252726Srpaulo 1678252726Srpaulostatic char ** wpa_cli_complete_p2p_find(const char *str, int pos) 1679252726Srpaulo{ 1680252726Srpaulo char **res = NULL; 1681252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1682252726Srpaulo 1683252726Srpaulo res = os_calloc(6, sizeof(char *)); 1684252726Srpaulo if (res == NULL) 1685252726Srpaulo return NULL; 1686252726Srpaulo res[0] = os_strdup("type=social"); 1687252726Srpaulo if (res[0] == NULL) { 1688252726Srpaulo os_free(res); 1689252726Srpaulo return NULL; 1690252726Srpaulo } 1691252726Srpaulo res[1] = os_strdup("type=progressive"); 1692252726Srpaulo if (res[1] == NULL) 1693252726Srpaulo return res; 1694252726Srpaulo res[2] = os_strdup("delay="); 1695252726Srpaulo if (res[2] == NULL) 1696252726Srpaulo return res; 1697252726Srpaulo res[3] = os_strdup("dev_id="); 1698252726Srpaulo if (res[3] == NULL) 1699252726Srpaulo return res; 1700252726Srpaulo if (arg == 1) 1701252726Srpaulo res[4] = os_strdup("[timeout]"); 1702252726Srpaulo 1703252726Srpaulo return res; 1704252726Srpaulo} 1705252726Srpaulo 1706252726Srpaulo 1707252726Srpaulostatic int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc, 1708252726Srpaulo char *argv[]) 1709252726Srpaulo{ 1710252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_STOP_FIND"); 1711252726Srpaulo} 1712252726Srpaulo 1713252726Srpaulo 1714252726Srpaulostatic int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc, 1715252726Srpaulo char *argv[]) 1716252726Srpaulo{ 1717252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv); 1718252726Srpaulo} 1719252726Srpaulo 1720252726Srpaulo 1721252726Srpaulostatic char ** wpa_cli_complete_p2p_connect(const char *str, int pos) 1722252726Srpaulo{ 1723252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1724252726Srpaulo char **res = NULL; 1725252726Srpaulo 1726252726Srpaulo switch (arg) { 1727252726Srpaulo case 1: 1728252726Srpaulo res = cli_txt_list_array(&p2p_peers); 1729252726Srpaulo break; 1730252726Srpaulo } 1731252726Srpaulo 1732252726Srpaulo return res; 1733252726Srpaulo} 1734252726Srpaulo 1735252726Srpaulo 1736252726Srpaulostatic int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc, 1737252726Srpaulo char *argv[]) 1738252726Srpaulo{ 1739252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv); 1740252726Srpaulo} 1741252726Srpaulo 1742252726Srpaulo 1743252726Srpaulostatic int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc, 1744252726Srpaulo char *argv[]) 1745252726Srpaulo{ 1746252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv); 1747252726Srpaulo} 1748252726Srpaulo 1749252726Srpaulo 1750252726Srpaulostatic char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos) 1751252726Srpaulo{ 1752252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1753252726Srpaulo char **res = NULL; 1754252726Srpaulo 1755252726Srpaulo switch (arg) { 1756252726Srpaulo case 1: 1757252726Srpaulo res = cli_txt_list_array(&p2p_groups); 1758252726Srpaulo break; 1759252726Srpaulo } 1760252726Srpaulo 1761252726Srpaulo return res; 1762252726Srpaulo} 1763252726Srpaulo 1764252726Srpaulo 1765252726Srpaulostatic int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc, 1766252726Srpaulo char *argv[]) 1767252726Srpaulo{ 1768252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv); 1769252726Srpaulo} 1770252726Srpaulo 1771252726Srpaulo 1772252726Srpaulostatic int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc, 1773252726Srpaulo char *argv[]) 1774252726Srpaulo{ 1775252726Srpaulo if (argc != 2 && argc != 3) { 1776252726Srpaulo printf("Invalid P2P_PROV_DISC command: needs at least " 1777252726Srpaulo "two arguments, address and config method\n" 1778252726Srpaulo "(display, keypad, or pbc) and an optional join\n"); 1779252726Srpaulo return -1; 1780252726Srpaulo } 1781252726Srpaulo 1782252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv); 1783252726Srpaulo} 1784252726Srpaulo 1785252726Srpaulo 1786252726Srpaulostatic int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc, 1787252726Srpaulo char *argv[]) 1788252726Srpaulo{ 1789252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE"); 1790252726Srpaulo} 1791252726Srpaulo 1792252726Srpaulo 1793252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc, 1794252726Srpaulo char *argv[]) 1795252726Srpaulo{ 1796252726Srpaulo char cmd[4096]; 1797252726Srpaulo 1798252726Srpaulo if (argc != 2 && argc != 4) { 1799252726Srpaulo printf("Invalid P2P_SERV_DISC_REQ command: needs two " 1800252726Srpaulo "arguments (address and TLVs) or four arguments " 1801252726Srpaulo "(address, \"upnp\", version, search target " 1802252726Srpaulo "(SSDP ST:)\n"); 1803252726Srpaulo return -1; 1804252726Srpaulo } 1805252726Srpaulo 1806252726Srpaulo if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0) 1807252726Srpaulo return -1; 1808252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 1809252726Srpaulo} 1810252726Srpaulo 1811252726Srpaulo 1812252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl, 1813252726Srpaulo int argc, char *argv[]) 1814252726Srpaulo{ 1815252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv); 1816252726Srpaulo} 1817252726Srpaulo 1818252726Srpaulo 1819252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc, 1820252726Srpaulo char *argv[]) 1821252726Srpaulo{ 1822252726Srpaulo char cmd[4096]; 1823214734Srpaulo int res; 1824214734Srpaulo 1825252726Srpaulo if (argc != 4) { 1826252726Srpaulo printf("Invalid P2P_SERV_DISC_RESP command: needs four " 1827252726Srpaulo "arguments (freq, address, dialog token, and TLVs)\n"); 1828252726Srpaulo return -1; 1829252726Srpaulo } 1830252726Srpaulo 1831252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s", 1832252726Srpaulo argv[0], argv[1], argv[2], argv[3]); 1833252726Srpaulo if (res < 0 || (size_t) res >= sizeof(cmd)) 1834252726Srpaulo return -1; 1835252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 1836252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 1837252726Srpaulo} 1838252726Srpaulo 1839252726Srpaulo 1840252726Srpaulostatic int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc, 1841252726Srpaulo char *argv[]) 1842252726Srpaulo{ 1843252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE"); 1844252726Srpaulo} 1845252726Srpaulo 1846252726Srpaulo 1847252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl, 1848252726Srpaulo int argc, char *argv[]) 1849252726Srpaulo{ 1850252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv); 1851252726Srpaulo} 1852252726Srpaulo 1853252726Srpaulo 1854252726Srpaulostatic int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc, 1855252726Srpaulo char *argv[]) 1856252726Srpaulo{ 1857252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH"); 1858252726Srpaulo} 1859252726Srpaulo 1860252726Srpaulo 1861252726Srpaulostatic int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc, 1862252726Srpaulo char *argv[]) 1863252726Srpaulo{ 1864252726Srpaulo char cmd[4096]; 1865252726Srpaulo int res; 1866252726Srpaulo 1867252726Srpaulo if (argc != 3 && argc != 4) { 1868252726Srpaulo printf("Invalid P2P_SERVICE_ADD command: needs three or four " 1869252726Srpaulo "arguments\n"); 1870252726Srpaulo return -1; 1871252726Srpaulo } 1872252726Srpaulo 1873252726Srpaulo if (argc == 4) 1874252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 1875252726Srpaulo "P2P_SERVICE_ADD %s %s %s %s", 1876252726Srpaulo argv[0], argv[1], argv[2], argv[3]); 1877252726Srpaulo else 1878252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 1879252726Srpaulo "P2P_SERVICE_ADD %s %s %s", 1880252726Srpaulo argv[0], argv[1], argv[2]); 1881252726Srpaulo if (res < 0 || (size_t) res >= sizeof(cmd)) 1882252726Srpaulo return -1; 1883252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 1884252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 1885252726Srpaulo} 1886252726Srpaulo 1887252726Srpaulo 1888252726Srpaulostatic int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc, 1889252726Srpaulo char *argv[]) 1890252726Srpaulo{ 1891252726Srpaulo char cmd[4096]; 1892252726Srpaulo int res; 1893252726Srpaulo 1894252726Srpaulo if (argc != 2 && argc != 3) { 1895252726Srpaulo printf("Invalid P2P_SERVICE_DEL command: needs two or three " 1896252726Srpaulo "arguments\n"); 1897252726Srpaulo return -1; 1898252726Srpaulo } 1899252726Srpaulo 1900252726Srpaulo if (argc == 3) 1901252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 1902252726Srpaulo "P2P_SERVICE_DEL %s %s %s", 1903252726Srpaulo argv[0], argv[1], argv[2]); 1904252726Srpaulo else 1905252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 1906252726Srpaulo "P2P_SERVICE_DEL %s %s", 1907252726Srpaulo argv[0], argv[1]); 1908252726Srpaulo if (res < 0 || (size_t) res >= sizeof(cmd)) 1909252726Srpaulo return -1; 1910252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 1911252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 1912252726Srpaulo} 1913252726Srpaulo 1914252726Srpaulo 1915252726Srpaulostatic int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl, 1916252726Srpaulo int argc, char *argv[]) 1917252726Srpaulo{ 1918252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv); 1919252726Srpaulo} 1920252726Srpaulo 1921252726Srpaulo 1922252726Srpaulostatic int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl, 1923252726Srpaulo int argc, char *argv[]) 1924252726Srpaulo{ 1925252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv); 1926252726Srpaulo} 1927252726Srpaulo 1928252726Srpaulo 1929252726Srpaulostatic int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1930252726Srpaulo{ 1931252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv); 1932252726Srpaulo} 1933252726Srpaulo 1934252726Srpaulo 1935252726Srpaulostatic char ** wpa_cli_complete_p2p_peer(const char *str, int pos) 1936252726Srpaulo{ 1937252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1938252726Srpaulo char **res = NULL; 1939252726Srpaulo 1940252726Srpaulo switch (arg) { 1941252726Srpaulo case 1: 1942252726Srpaulo res = cli_txt_list_array(&p2p_peers); 1943252726Srpaulo break; 1944252726Srpaulo } 1945252726Srpaulo 1946252726Srpaulo return res; 1947252726Srpaulo} 1948252726Srpaulo 1949252726Srpaulo 1950252726Srpaulostatic int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd, 1951252726Srpaulo char *addr, size_t addr_len, 1952252726Srpaulo int discovered) 1953252726Srpaulo{ 1954252726Srpaulo char buf[4096], *pos; 1955252726Srpaulo size_t len; 1956252726Srpaulo int ret; 1957252726Srpaulo 1958252726Srpaulo if (ctrl_conn == NULL) 1959252726Srpaulo return -1; 1960252726Srpaulo len = sizeof(buf) - 1; 1961252726Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 1962252726Srpaulo wpa_cli_msg_cb); 1963252726Srpaulo if (ret == -2) { 1964252726Srpaulo printf("'%s' command timed out.\n", cmd); 1965252726Srpaulo return -2; 1966252726Srpaulo } else if (ret < 0) { 1967252726Srpaulo printf("'%s' command failed.\n", cmd); 1968252726Srpaulo return -1; 1969252726Srpaulo } 1970252726Srpaulo 1971252726Srpaulo buf[len] = '\0'; 1972252726Srpaulo if (os_memcmp(buf, "FAIL", 4) == 0) 1973252726Srpaulo return -1; 1974252726Srpaulo 1975252726Srpaulo pos = buf; 1976252726Srpaulo while (*pos != '\0' && *pos != '\n') 1977252726Srpaulo pos++; 1978252726Srpaulo *pos++ = '\0'; 1979252726Srpaulo os_strlcpy(addr, buf, addr_len); 1980252726Srpaulo if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL) 1981252726Srpaulo printf("%s\n", addr); 1982252726Srpaulo return 0; 1983252726Srpaulo} 1984252726Srpaulo 1985252726Srpaulo 1986252726Srpaulostatic int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1987252726Srpaulo{ 1988252726Srpaulo char addr[32], cmd[64]; 1989252726Srpaulo int discovered; 1990252726Srpaulo 1991252726Srpaulo discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0; 1992252726Srpaulo 1993252726Srpaulo if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST", 1994252726Srpaulo addr, sizeof(addr), discovered)) 1995252726Srpaulo return -1; 1996252726Srpaulo do { 1997252726Srpaulo os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr); 1998252726Srpaulo } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr), 1999252726Srpaulo discovered) == 0); 2000252726Srpaulo 2001252726Srpaulo return 0; 2002252726Srpaulo} 2003252726Srpaulo 2004252726Srpaulo 2005252726Srpaulostatic int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2006252726Srpaulo{ 2007252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv); 2008252726Srpaulo} 2009252726Srpaulo 2010252726Srpaulo 2011252726Srpaulostatic int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2012252726Srpaulo{ 2013252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_FLUSH"); 2014252726Srpaulo} 2015252726Srpaulo 2016252726Srpaulo 2017252726Srpaulostatic int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc, 2018252726Srpaulo char *argv[]) 2019252726Srpaulo{ 2020252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_CANCEL"); 2021252726Srpaulo} 2022252726Srpaulo 2023252726Srpaulo 2024252726Srpaulostatic int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc, 2025252726Srpaulo char *argv[]) 2026252726Srpaulo{ 2027252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv); 2028252726Srpaulo} 2029252726Srpaulo 2030252726Srpaulo 2031252726Srpaulostatic int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, 2032252726Srpaulo char *argv[]) 2033252726Srpaulo{ 2034252726Srpaulo if (argc != 0 && argc != 2 && argc != 4) { 2035252726Srpaulo printf("Invalid P2P_PRESENCE_REQ command: needs two arguments " 2036252726Srpaulo "(preferred duration, interval; in microsecods).\n" 2037252726Srpaulo "Optional second pair can be used to provide " 2038252726Srpaulo "acceptable values.\n"); 2039252726Srpaulo return -1; 2040252726Srpaulo } 2041252726Srpaulo 2042252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv); 2043252726Srpaulo} 2044252726Srpaulo 2045252726Srpaulo 2046252726Srpaulostatic int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc, 2047252726Srpaulo char *argv[]) 2048252726Srpaulo{ 2049252726Srpaulo if (argc != 0 && argc != 2) { 2050252726Srpaulo printf("Invalid P2P_EXT_LISTEN command: needs two arguments " 2051252726Srpaulo "(availability period, availability interval; in " 2052252726Srpaulo "millisecods).\n" 2053252726Srpaulo "Extended Listen Timing can be cancelled with this " 2054252726Srpaulo "command when used without parameters.\n"); 2055252726Srpaulo return -1; 2056252726Srpaulo } 2057252726Srpaulo 2058252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv); 2059252726Srpaulo} 2060252726Srpaulo 2061252726Srpaulo#endif /* CONFIG_P2P */ 2062252726Srpaulo 2063252726Srpaulo#ifdef CONFIG_WIFI_DISPLAY 2064252726Srpaulo 2065252726Srpaulostatic int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc, 2066252726Srpaulo char *argv[]) 2067252726Srpaulo{ 2068252726Srpaulo char cmd[100]; 2069252726Srpaulo int res; 2070252726Srpaulo 2071252726Srpaulo if (argc != 1 && argc != 2) { 2072252726Srpaulo printf("Invalid WFD_SUBELEM_SET command: needs one or two " 2073252726Srpaulo "arguments (subelem, hexdump)\n"); 2074252726Srpaulo return -1; 2075252726Srpaulo } 2076252726Srpaulo 2077252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s", 2078252726Srpaulo argv[0], argc > 1 ? argv[1] : ""); 2079252726Srpaulo if (res < 0 || (size_t) res >= sizeof(cmd)) 2080252726Srpaulo return -1; 2081252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2082252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2083252726Srpaulo} 2084252726Srpaulo 2085252726Srpaulo 2086252726Srpaulostatic int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc, 2087252726Srpaulo char *argv[]) 2088252726Srpaulo{ 2089252726Srpaulo char cmd[100]; 2090252726Srpaulo int res; 2091252726Srpaulo 2092214734Srpaulo if (argc != 1) { 2093252726Srpaulo printf("Invalid WFD_SUBELEM_GET command: needs one " 2094252726Srpaulo "argument (subelem)\n"); 2095214734Srpaulo return -1; 2096214734Srpaulo } 2097214734Srpaulo 2098252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s", 2099252726Srpaulo argv[0]); 2100252726Srpaulo if (res < 0 || (size_t) res >= sizeof(cmd)) 2101214734Srpaulo return -1; 2102252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2103252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2104252726Srpaulo} 2105252726Srpaulo#endif /* CONFIG_WIFI_DISPLAY */ 2106252726Srpaulo 2107252726Srpaulo 2108252726Srpaulo#ifdef CONFIG_INTERWORKING 2109252726Srpaulostatic int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2110252726Srpaulo char *argv[]) 2111252726Srpaulo{ 2112252726Srpaulo return wpa_ctrl_command(ctrl, "FETCH_ANQP"); 2113252726Srpaulo} 2114252726Srpaulo 2115252726Srpaulo 2116252726Srpaulostatic int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2117252726Srpaulo char *argv[]) 2118252726Srpaulo{ 2119252726Srpaulo return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP"); 2120252726Srpaulo} 2121252726Srpaulo 2122252726Srpaulo 2123252726Srpaulostatic int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc, 2124252726Srpaulo char *argv[]) 2125252726Srpaulo{ 2126252726Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv); 2127252726Srpaulo} 2128252726Srpaulo 2129252726Srpaulo 2130252726Srpaulostatic int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc, 2131252726Srpaulo char *argv[]) 2132252726Srpaulo{ 2133252726Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv); 2134252726Srpaulo} 2135252726Srpaulo 2136252726Srpaulo 2137252726Srpaulostatic int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2138252726Srpaulo{ 2139252726Srpaulo return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv); 2140252726Srpaulo} 2141252726Srpaulo 2142252726Srpaulo 2143252726Srpaulostatic int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc, 2144252726Srpaulo char *argv[]) 2145252726Srpaulo{ 2146252726Srpaulo return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv); 2147252726Srpaulo} 2148252726Srpaulo 2149252726Srpaulo 2150252726Srpaulostatic int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc, 2151252726Srpaulo char *argv[]) 2152252726Srpaulo{ 2153252726Srpaulo return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv); 2154252726Srpaulo} 2155252726Srpaulo#endif /* CONFIG_INTERWORKING */ 2156252726Srpaulo 2157252726Srpaulo 2158252726Srpaulo#ifdef CONFIG_HS20 2159252726Srpaulo 2160252726Srpaulostatic int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc, 2161252726Srpaulo char *argv[]) 2162252726Srpaulo{ 2163252726Srpaulo return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv); 2164252726Srpaulo} 2165252726Srpaulo 2166252726Srpaulo 2167252726Srpaulostatic int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, 2168252726Srpaulo char *argv[]) 2169252726Srpaulo{ 2170252726Srpaulo char cmd[512]; 2171252726Srpaulo 2172252726Srpaulo if (argc == 0) { 2173252726Srpaulo printf("Command needs one or two arguments (dst mac addr and " 2174252726Srpaulo "optional home realm)\n"); 2175252726Srpaulo return -1; 2176214734Srpaulo } 2177252726Srpaulo 2178252726Srpaulo if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST", 2179252726Srpaulo argc, argv) < 0) 2180252726Srpaulo return -1; 2181252726Srpaulo 2182214734Srpaulo return wpa_ctrl_command(ctrl, cmd); 2183214734Srpaulo} 2184214734Srpaulo 2185252726Srpaulo#endif /* CONFIG_HS20 */ 2186214734Srpaulo 2187252726Srpaulo 2188252726Srpaulostatic int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc, 2189252726Srpaulo char *argv[]) 2190252726Srpaulo{ 2191252726Srpaulo return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv); 2192252726Srpaulo} 2193252726Srpaulo 2194252726Srpaulo 2195252726Srpaulostatic int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc, 2196252726Srpaulo char *argv[]) 2197252726Srpaulo{ 2198252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv); 2199252726Srpaulo} 2200252726Srpaulo 2201252726Srpaulo 2202252726Srpaulostatic int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc, 2203252726Srpaulo char *argv[]) 2204252726Srpaulo{ 2205252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv); 2206252726Srpaulo} 2207252726Srpaulo 2208252726Srpaulo 2209252726Srpaulostatic int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc, 2210252726Srpaulo char *argv[]) 2211252726Srpaulo{ 2212252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv); 2213252726Srpaulo} 2214252726Srpaulo 2215252726Srpaulo 2216252726Srpaulostatic int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc, 2217252726Srpaulo char *argv[]) 2218252726Srpaulo{ 2219252726Srpaulo return wpa_ctrl_command(ctrl, "SIGNAL_POLL"); 2220252726Srpaulo} 2221252726Srpaulo 2222252726Srpaulo 2223252726Srpaulostatic int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc, 2224252726Srpaulo char *argv[]) 2225252726Srpaulo{ 2226252726Srpaulo return wpa_ctrl_command(ctrl, "PKTCNT_POLL"); 2227252726Srpaulo} 2228252726Srpaulo 2229252726Srpaulo 2230252726Srpaulostatic int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc, 2231252726Srpaulo char *argv[]) 2232252726Srpaulo{ 2233252726Srpaulo return wpa_ctrl_command(ctrl, "REAUTHENTICATE"); 2234252726Srpaulo} 2235252726Srpaulo 2236252726Srpaulo 2237252726Srpaulo#ifdef CONFIG_AUTOSCAN 2238252726Srpaulo 2239252726Srpaulostatic int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2240252726Srpaulo{ 2241252726Srpaulo if (argc == 0) 2242252726Srpaulo return wpa_ctrl_command(ctrl, "AUTOSCAN "); 2243252726Srpaulo 2244252726Srpaulo return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv); 2245252726Srpaulo} 2246252726Srpaulo 2247252726Srpaulo#endif /* CONFIG_AUTOSCAN */ 2248252726Srpaulo 2249252726Srpaulo 2250252726Srpaulo#ifdef CONFIG_WNM 2251252726Srpaulo 2252252726Srpaulostatic int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2253252726Srpaulo{ 2254252726Srpaulo return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv); 2255252726Srpaulo} 2256252726Srpaulo 2257252726Srpaulo#endif /* CONFIG_WNM */ 2258252726Srpaulo 2259252726Srpaulo 2260252726Srpaulostatic int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2261252726Srpaulo{ 2262252726Srpaulo if (argc == 0) 2263252726Srpaulo return -1; 2264252726Srpaulo return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]); 2265252726Srpaulo} 2266252726Srpaulo 2267252726Srpaulo 2268189251Ssamenum wpa_cli_cmd_flags { 2269189251Ssam cli_cmd_flag_none = 0x00, 2270189251Ssam cli_cmd_flag_sensitive = 0x01 2271189251Ssam}; 2272189251Ssam 2273189251Ssamstruct wpa_cli_cmd { 2274189251Ssam const char *cmd; 2275189251Ssam int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); 2276252726Srpaulo char ** (*completion)(const char *str, int pos); 2277189251Ssam enum wpa_cli_cmd_flags flags; 2278189251Ssam const char *usage; 2279189251Ssam}; 2280189251Ssam 2281189251Ssamstatic struct wpa_cli_cmd wpa_cli_commands[] = { 2282252726Srpaulo { "status", wpa_cli_cmd_status, NULL, 2283189251Ssam cli_cmd_flag_none, 2284189251Ssam "[verbose] = get current WPA/EAPOL/EAP status" }, 2285252726Srpaulo { "ifname", wpa_cli_cmd_ifname, NULL, 2286189251Ssam cli_cmd_flag_none, 2287252726Srpaulo "= get current interface name" }, 2288252726Srpaulo { "ping", wpa_cli_cmd_ping, NULL, 2289252726Srpaulo cli_cmd_flag_none, 2290189251Ssam "= pings wpa_supplicant" }, 2291252726Srpaulo { "relog", wpa_cli_cmd_relog, NULL, 2292189251Ssam cli_cmd_flag_none, 2293252726Srpaulo "= re-open log-file (allow rolling logs)" }, 2294252726Srpaulo { "note", wpa_cli_cmd_note, NULL, 2295252726Srpaulo cli_cmd_flag_none, 2296252726Srpaulo "<text> = add a note to wpa_supplicant debug log" }, 2297252726Srpaulo { "mib", wpa_cli_cmd_mib, NULL, 2298252726Srpaulo cli_cmd_flag_none, 2299189251Ssam "= get MIB variables (dot1x, dot11)" }, 2300252726Srpaulo { "help", wpa_cli_cmd_help, wpa_cli_complete_help, 2301189251Ssam cli_cmd_flag_none, 2302252726Srpaulo "[command] = show usage help" }, 2303252726Srpaulo { "interface", wpa_cli_cmd_interface, NULL, 2304189251Ssam cli_cmd_flag_none, 2305189251Ssam "[ifname] = show interfaces/select interface" }, 2306252726Srpaulo { "level", wpa_cli_cmd_level, NULL, 2307189251Ssam cli_cmd_flag_none, 2308189251Ssam "<debug level> = change debug level" }, 2309252726Srpaulo { "license", wpa_cli_cmd_license, NULL, 2310189251Ssam cli_cmd_flag_none, 2311189251Ssam "= show full wpa_cli license" }, 2312252726Srpaulo { "quit", wpa_cli_cmd_quit, NULL, 2313189251Ssam cli_cmd_flag_none, 2314189251Ssam "= exit wpa_cli" }, 2315252726Srpaulo { "set", wpa_cli_cmd_set, NULL, 2316189251Ssam cli_cmd_flag_none, 2317189251Ssam "= set variables (shows list of variables when run without " 2318189251Ssam "arguments)" }, 2319252726Srpaulo { "get", wpa_cli_cmd_get, NULL, 2320189251Ssam cli_cmd_flag_none, 2321252726Srpaulo "<name> = get information" }, 2322252726Srpaulo { "logon", wpa_cli_cmd_logon, NULL, 2323252726Srpaulo cli_cmd_flag_none, 2324189251Ssam "= IEEE 802.1X EAPOL state machine logon" }, 2325252726Srpaulo { "logoff", wpa_cli_cmd_logoff, NULL, 2326189251Ssam cli_cmd_flag_none, 2327189251Ssam "= IEEE 802.1X EAPOL state machine logoff" }, 2328252726Srpaulo { "pmksa", wpa_cli_cmd_pmksa, NULL, 2329189251Ssam cli_cmd_flag_none, 2330189251Ssam "= show PMKSA cache" }, 2331252726Srpaulo { "reassociate", wpa_cli_cmd_reassociate, NULL, 2332189251Ssam cli_cmd_flag_none, 2333189251Ssam "= force reassociation" }, 2334252726Srpaulo { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss, 2335189251Ssam cli_cmd_flag_none, 2336189251Ssam "<BSSID> = force preauthentication" }, 2337252726Srpaulo { "identity", wpa_cli_cmd_identity, NULL, 2338189251Ssam cli_cmd_flag_none, 2339189251Ssam "<network id> <identity> = configure identity for an SSID" }, 2340252726Srpaulo { "password", wpa_cli_cmd_password, NULL, 2341189251Ssam cli_cmd_flag_sensitive, 2342189251Ssam "<network id> <password> = configure password for an SSID" }, 2343252726Srpaulo { "new_password", wpa_cli_cmd_new_password, NULL, 2344189251Ssam cli_cmd_flag_sensitive, 2345189251Ssam "<network id> <password> = change password for an SSID" }, 2346252726Srpaulo { "pin", wpa_cli_cmd_pin, NULL, 2347189251Ssam cli_cmd_flag_sensitive, 2348189251Ssam "<network id> <pin> = configure pin for an SSID" }, 2349252726Srpaulo { "otp", wpa_cli_cmd_otp, NULL, 2350189251Ssam cli_cmd_flag_sensitive, 2351189251Ssam "<network id> <password> = configure one-time-password for an SSID" 2352189251Ssam }, 2353252726Srpaulo { "passphrase", wpa_cli_cmd_passphrase, NULL, 2354189251Ssam cli_cmd_flag_sensitive, 2355189251Ssam "<network id> <passphrase> = configure private key passphrase\n" 2356189251Ssam " for an SSID" }, 2357252726Srpaulo { "bssid", wpa_cli_cmd_bssid, NULL, 2358189251Ssam cli_cmd_flag_none, 2359189251Ssam "<network id> <BSSID> = set preferred BSSID for an SSID" }, 2360252726Srpaulo { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss, 2361189251Ssam cli_cmd_flag_none, 2362252726Srpaulo "<BSSID> = add a BSSID to the blacklist\n" 2363252726Srpaulo "blacklist clear = clear the blacklist\n" 2364252726Srpaulo "blacklist = display the blacklist" }, 2365252726Srpaulo { "log_level", wpa_cli_cmd_log_level, NULL, 2366252726Srpaulo cli_cmd_flag_none, 2367252726Srpaulo "<level> [<timestamp>] = update the log level/timestamp\n" 2368252726Srpaulo "log_level = display the current log level and log options" }, 2369252726Srpaulo { "list_networks", wpa_cli_cmd_list_networks, NULL, 2370252726Srpaulo cli_cmd_flag_none, 2371189251Ssam "= list configured networks" }, 2372252726Srpaulo { "select_network", wpa_cli_cmd_select_network, NULL, 2373189251Ssam cli_cmd_flag_none, 2374189251Ssam "<network id> = select a network (disable others)" }, 2375252726Srpaulo { "enable_network", wpa_cli_cmd_enable_network, NULL, 2376189251Ssam cli_cmd_flag_none, 2377189251Ssam "<network id> = enable a network" }, 2378252726Srpaulo { "disable_network", wpa_cli_cmd_disable_network, NULL, 2379189251Ssam cli_cmd_flag_none, 2380189251Ssam "<network id> = disable a network" }, 2381252726Srpaulo { "add_network", wpa_cli_cmd_add_network, NULL, 2382189251Ssam cli_cmd_flag_none, 2383189251Ssam "= add a network" }, 2384252726Srpaulo { "remove_network", wpa_cli_cmd_remove_network, NULL, 2385189251Ssam cli_cmd_flag_none, 2386189251Ssam "<network id> = remove a network" }, 2387252726Srpaulo { "set_network", wpa_cli_cmd_set_network, NULL, 2388189251Ssam cli_cmd_flag_sensitive, 2389189251Ssam "<network id> <variable> <value> = set network variables (shows\n" 2390189251Ssam " list of variables when run without arguments)" }, 2391252726Srpaulo { "get_network", wpa_cli_cmd_get_network, NULL, 2392189251Ssam cli_cmd_flag_none, 2393189251Ssam "<network id> <variable> = get network variables" }, 2394252726Srpaulo { "list_creds", wpa_cli_cmd_list_creds, NULL, 2395189251Ssam cli_cmd_flag_none, 2396252726Srpaulo "= list configured credentials" }, 2397252726Srpaulo { "add_cred", wpa_cli_cmd_add_cred, NULL, 2398252726Srpaulo cli_cmd_flag_none, 2399252726Srpaulo "= add a credential" }, 2400252726Srpaulo { "remove_cred", wpa_cli_cmd_remove_cred, NULL, 2401252726Srpaulo cli_cmd_flag_none, 2402252726Srpaulo "<cred id> = remove a credential" }, 2403252726Srpaulo { "set_cred", wpa_cli_cmd_set_cred, NULL, 2404252726Srpaulo cli_cmd_flag_sensitive, 2405252726Srpaulo "<cred id> <variable> <value> = set credential variables" }, 2406252726Srpaulo { "save_config", wpa_cli_cmd_save_config, NULL, 2407252726Srpaulo cli_cmd_flag_none, 2408189251Ssam "= save the current configuration" }, 2409252726Srpaulo { "disconnect", wpa_cli_cmd_disconnect, NULL, 2410189251Ssam cli_cmd_flag_none, 2411189251Ssam "= disconnect and wait for reassociate/reconnect command before\n" 2412189251Ssam " connecting" }, 2413252726Srpaulo { "reconnect", wpa_cli_cmd_reconnect, NULL, 2414189251Ssam cli_cmd_flag_none, 2415189251Ssam "= like reassociate, but only takes effect if already disconnected" 2416189251Ssam }, 2417252726Srpaulo { "scan", wpa_cli_cmd_scan, NULL, 2418189251Ssam cli_cmd_flag_none, 2419189251Ssam "= request new BSS scan" }, 2420252726Srpaulo { "scan_results", wpa_cli_cmd_scan_results, NULL, 2421189251Ssam cli_cmd_flag_none, 2422189251Ssam "= get latest scan results" }, 2423252726Srpaulo { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss, 2424189251Ssam cli_cmd_flag_none, 2425189251Ssam "<<idx> | <bssid>> = get detailed scan result info" }, 2426252726Srpaulo { "get_capability", wpa_cli_cmd_get_capability, NULL, 2427189251Ssam cli_cmd_flag_none, 2428252726Srpaulo "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels> " 2429252726Srpaulo "= get capabilies" }, 2430252726Srpaulo { "reconfigure", wpa_cli_cmd_reconfigure, NULL, 2431189251Ssam cli_cmd_flag_none, 2432189251Ssam "= force wpa_supplicant to re-read its configuration file" }, 2433252726Srpaulo { "terminate", wpa_cli_cmd_terminate, NULL, 2434189251Ssam cli_cmd_flag_none, 2435189251Ssam "= terminate wpa_supplicant" }, 2436252726Srpaulo { "interface_add", wpa_cli_cmd_interface_add, NULL, 2437189251Ssam cli_cmd_flag_none, 2438189251Ssam "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n" 2439189251Ssam " <bridge_name> = adds new interface, all parameters but <ifname>\n" 2440189251Ssam " are optional" }, 2441252726Srpaulo { "interface_remove", wpa_cli_cmd_interface_remove, NULL, 2442189251Ssam cli_cmd_flag_none, 2443189251Ssam "<ifname> = removes the interface" }, 2444252726Srpaulo { "interface_list", wpa_cli_cmd_interface_list, NULL, 2445189251Ssam cli_cmd_flag_none, 2446189251Ssam "= list available interfaces" }, 2447252726Srpaulo { "ap_scan", wpa_cli_cmd_ap_scan, NULL, 2448189251Ssam cli_cmd_flag_none, 2449189251Ssam "<value> = set ap_scan parameter" }, 2450252726Srpaulo { "scan_interval", wpa_cli_cmd_scan_interval, NULL, 2451189251Ssam cli_cmd_flag_none, 2452252726Srpaulo "<value> = set scan_interval parameter (in seconds)" }, 2453252726Srpaulo { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL, 2454252726Srpaulo cli_cmd_flag_none, 2455252726Srpaulo "<value> = set BSS expiration age parameter" }, 2456252726Srpaulo { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL, 2457252726Srpaulo cli_cmd_flag_none, 2458252726Srpaulo "<value> = set BSS expiration scan count parameter" }, 2459252726Srpaulo { "bss_flush", wpa_cli_cmd_bss_flush, NULL, 2460252726Srpaulo cli_cmd_flag_none, 2461252726Srpaulo "<value> = set BSS flush age (0 by default)" }, 2462252726Srpaulo { "stkstart", wpa_cli_cmd_stkstart, NULL, 2463252726Srpaulo cli_cmd_flag_none, 2464189251Ssam "<addr> = request STK negotiation with <addr>" }, 2465252726Srpaulo { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss, 2466189251Ssam cli_cmd_flag_none, 2467189251Ssam "<addr> = request over-the-DS FT with <addr>" }, 2468252726Srpaulo { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss, 2469189251Ssam cli_cmd_flag_none, 2470189251Ssam "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" }, 2471252726Srpaulo { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss, 2472189251Ssam cli_cmd_flag_sensitive, 2473189251Ssam "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " 2474189251Ssam "hardcoded)" }, 2475252726Srpaulo { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL, 2476214734Srpaulo cli_cmd_flag_sensitive, 2477252726Srpaulo "<PIN> = verify PIN checksum" }, 2478252726Srpaulo { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none, 2479252726Srpaulo "Cancels the pending WPS operation" }, 2480252726Srpaulo#ifdef CONFIG_WPS_NFC 2481252726Srpaulo { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss, 2482252726Srpaulo cli_cmd_flag_none, 2483252726Srpaulo "[BSSID] = start Wi-Fi Protected Setup: NFC" }, 2484252726Srpaulo { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL, 2485252726Srpaulo cli_cmd_flag_none, 2486252726Srpaulo "<WPS|NDEF> = create password token" }, 2487252726Srpaulo { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL, 2488189251Ssam cli_cmd_flag_sensitive, 2489252726Srpaulo "<hexdump of payload> = report read NFC tag with WPS data" }, 2490252726Srpaulo { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL, 2491252726Srpaulo cli_cmd_flag_none, 2492252726Srpaulo "<NDEF> <WPS> = create NFC handover request" }, 2493252726Srpaulo { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL, 2494252726Srpaulo cli_cmd_flag_none, 2495252726Srpaulo "<NDEF> <WPS> = create NFC handover select" }, 2496252726Srpaulo { "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req, NULL, 2497252726Srpaulo cli_cmd_flag_none, 2498252726Srpaulo "<hexdump of payload> = report received NFC handover request" }, 2499252726Srpaulo { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL, 2500252726Srpaulo cli_cmd_flag_none, 2501252726Srpaulo "<hexdump of payload> = report received NFC handover select" }, 2502252726Srpaulo#endif /* CONFIG_WPS_NFC */ 2503252726Srpaulo { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss, 2504252726Srpaulo cli_cmd_flag_sensitive, 2505189251Ssam "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, 2506252726Srpaulo { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL, 2507252726Srpaulo cli_cmd_flag_sensitive, 2508252726Srpaulo "[params..] = enable/disable AP PIN" }, 2509252726Srpaulo { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL, 2510214734Srpaulo cli_cmd_flag_none, 2511252726Srpaulo "[IP address] = start Wi-Fi Protected Setup External Registrar" }, 2512252726Srpaulo { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL, 2513214734Srpaulo cli_cmd_flag_none, 2514214734Srpaulo "= stop Wi-Fi Protected Setup External Registrar" }, 2515252726Srpaulo { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL, 2516214734Srpaulo cli_cmd_flag_sensitive, 2517214734Srpaulo "<UUID> <PIN> = add an Enrollee PIN to External Registrar" }, 2518252726Srpaulo { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL, 2519214734Srpaulo cli_cmd_flag_none, 2520214734Srpaulo "<UUID> = accept an Enrollee PBC using External Registrar" }, 2521252726Srpaulo { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL, 2522214734Srpaulo cli_cmd_flag_sensitive, 2523214734Srpaulo "<UUID> <PIN> = learn AP configuration" }, 2524252726Srpaulo { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL, 2525214734Srpaulo cli_cmd_flag_none, 2526252726Srpaulo "<UUID> <network id> = set AP configuration for enrolling" }, 2527252726Srpaulo { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL, 2528252726Srpaulo cli_cmd_flag_sensitive, 2529252726Srpaulo "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" }, 2530252726Srpaulo#ifdef CONFIG_WPS_NFC 2531252726Srpaulo { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL, 2532252726Srpaulo cli_cmd_flag_none, 2533252726Srpaulo "<WPS/NDEF> <UUID> = build NFC configuration token" }, 2534252726Srpaulo#endif /* CONFIG_WPS_NFC */ 2535252726Srpaulo { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL, 2536252726Srpaulo cli_cmd_flag_none, 2537214734Srpaulo "<addr> = request RSN authentication with <addr> in IBSS" }, 2538214734Srpaulo#ifdef CONFIG_AP 2539252726Srpaulo { "sta", wpa_cli_cmd_sta, NULL, 2540214734Srpaulo cli_cmd_flag_none, 2541214734Srpaulo "<addr> = get information about an associated station (AP)" }, 2542252726Srpaulo { "all_sta", wpa_cli_cmd_all_sta, NULL, 2543214734Srpaulo cli_cmd_flag_none, 2544214734Srpaulo "= get information about all associated stations (AP)" }, 2545252726Srpaulo { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL, 2546252726Srpaulo cli_cmd_flag_none, 2547252726Srpaulo "<addr> = deauthenticate a station" }, 2548252726Srpaulo { "disassociate", wpa_cli_cmd_disassociate, NULL, 2549252726Srpaulo cli_cmd_flag_none, 2550252726Srpaulo "<addr> = disassociate a station" }, 2551214734Srpaulo#endif /* CONFIG_AP */ 2552252726Srpaulo { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none, 2553214734Srpaulo "= notification of suspend/hibernate" }, 2554252726Srpaulo { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none, 2555214734Srpaulo "= notification of resume/thaw" }, 2556252726Srpaulo { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none, 2557214734Srpaulo "= drop SA without deauth/disassoc (test command)" }, 2558252726Srpaulo { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss, 2559214734Srpaulo cli_cmd_flag_none, 2560214734Srpaulo "<addr> = roam to the specified BSS" }, 2561252726Srpaulo#ifdef CONFIG_P2P 2562252726Srpaulo { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find, 2563252726Srpaulo cli_cmd_flag_none, 2564252726Srpaulo "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" }, 2565252726Srpaulo { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none, 2566252726Srpaulo "= stop P2P Devices search" }, 2567252726Srpaulo { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect, 2568252726Srpaulo cli_cmd_flag_none, 2569252726Srpaulo "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" }, 2570252726Srpaulo { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none, 2571252726Srpaulo "[timeout] = listen for P2P Devices for up-to timeout seconds" }, 2572252726Srpaulo { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, 2573252726Srpaulo wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none, 2574252726Srpaulo "<ifname> = remove P2P group interface (terminate group if GO)" }, 2575252726Srpaulo { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none, 2576252726Srpaulo "[ht40] = add a new P2P group (local end as GO)" }, 2577252726Srpaulo { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, 2578252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 2579252726Srpaulo "<addr> <method> = request provisioning discovery" }, 2580252726Srpaulo { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL, 2581252726Srpaulo cli_cmd_flag_none, 2582252726Srpaulo "= get the passphrase for a group (GO only)" }, 2583252726Srpaulo { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req, 2584252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 2585252726Srpaulo "<addr> <TLVs> = schedule service discovery request" }, 2586252726Srpaulo { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req, 2587252726Srpaulo NULL, cli_cmd_flag_none, 2588252726Srpaulo "<id> = cancel pending service discovery request" }, 2589252726Srpaulo { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL, 2590252726Srpaulo cli_cmd_flag_none, 2591252726Srpaulo "<freq> <addr> <dialog token> <TLVs> = service discovery response" }, 2592252726Srpaulo { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL, 2593252726Srpaulo cli_cmd_flag_none, 2594252726Srpaulo "= indicate change in local services" }, 2595252726Srpaulo { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL, 2596252726Srpaulo cli_cmd_flag_none, 2597252726Srpaulo "<external> = set external processing of service discovery" }, 2598252726Srpaulo { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL, 2599252726Srpaulo cli_cmd_flag_none, 2600252726Srpaulo "= remove all stored service entries" }, 2601252726Srpaulo { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL, 2602252726Srpaulo cli_cmd_flag_none, 2603252726Srpaulo "<bonjour|upnp> <query|version> <response|service> = add a local " 2604252726Srpaulo "service" }, 2605252726Srpaulo { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL, 2606252726Srpaulo cli_cmd_flag_none, 2607252726Srpaulo "<bonjour|upnp> <query|version> [|service] = remove a local " 2608252726Srpaulo "service" }, 2609252726Srpaulo { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer, 2610252726Srpaulo cli_cmd_flag_none, 2611252726Srpaulo "<addr> = reject connection attempts from a specific peer" }, 2612252726Srpaulo { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL, 2613252726Srpaulo cli_cmd_flag_none, 2614252726Srpaulo "<cmd> [peer=addr] = invite peer" }, 2615252726Srpaulo { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none, 2616252726Srpaulo "[discovered] = list known (optionally, only fully discovered) P2P " 2617252726Srpaulo "peers" }, 2618252726Srpaulo { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer, 2619252726Srpaulo cli_cmd_flag_none, 2620252726Srpaulo "<address> = show information about known P2P peer" }, 2621252726Srpaulo { "p2p_set", wpa_cli_cmd_p2p_set, NULL, cli_cmd_flag_none, 2622252726Srpaulo "<field> <value> = set a P2P parameter" }, 2623252726Srpaulo { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none, 2624252726Srpaulo "= flush P2P state" }, 2625252726Srpaulo { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none, 2626252726Srpaulo "= cancel P2P group formation" }, 2627252726Srpaulo { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, 2628252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 2629252726Srpaulo "<address> = unauthorize a peer" }, 2630252726Srpaulo { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL, 2631252726Srpaulo cli_cmd_flag_none, 2632252726Srpaulo "[<duration> <interval>] [<duration> <interval>] = request GO " 2633252726Srpaulo "presence" }, 2634252726Srpaulo { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL, 2635252726Srpaulo cli_cmd_flag_none, 2636252726Srpaulo "[<period> <interval>] = set extended listen timing" }, 2637252726Srpaulo#endif /* CONFIG_P2P */ 2638252726Srpaulo#ifdef CONFIG_WIFI_DISPLAY 2639252726Srpaulo { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL, 2640252726Srpaulo cli_cmd_flag_none, 2641252726Srpaulo "<subelem> [contents] = set Wi-Fi Display subelement" }, 2642252726Srpaulo { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL, 2643252726Srpaulo cli_cmd_flag_none, 2644252726Srpaulo "<subelem> = get Wi-Fi Display subelement" }, 2645252726Srpaulo#endif /* CONFIG_WIFI_DISPLAY */ 2646252726Srpaulo#ifdef CONFIG_INTERWORKING 2647252726Srpaulo { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none, 2648252726Srpaulo "= fetch ANQP information for all APs" }, 2649252726Srpaulo { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL, 2650252726Srpaulo cli_cmd_flag_none, 2651252726Srpaulo "= stop fetch_anqp operation" }, 2652252726Srpaulo { "interworking_select", wpa_cli_cmd_interworking_select, NULL, 2653252726Srpaulo cli_cmd_flag_none, 2654252726Srpaulo "[auto] = perform Interworking network selection" }, 2655252726Srpaulo { "interworking_connect", wpa_cli_cmd_interworking_connect, 2656252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 2657252726Srpaulo "<BSSID> = connect using Interworking credentials" }, 2658252726Srpaulo { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss, 2659252726Srpaulo cli_cmd_flag_none, 2660252726Srpaulo "<addr> <info id>[,<info id>]... = request ANQP information" }, 2661252726Srpaulo { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss, 2662252726Srpaulo cli_cmd_flag_none, 2663252726Srpaulo "<addr> <AdvProtoID> [QueryReq] = GAS request" }, 2664252726Srpaulo { "gas_response_get", wpa_cli_cmd_gas_response_get, 2665252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 2666252726Srpaulo "<addr> <dialog token> [start,len] = Fetch last GAS response" }, 2667252726Srpaulo#endif /* CONFIG_INTERWORKING */ 2668252726Srpaulo#ifdef CONFIG_HS20 2669252726Srpaulo { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss, 2670252726Srpaulo cli_cmd_flag_none, 2671252726Srpaulo "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information" 2672252726Srpaulo }, 2673252726Srpaulo { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list, 2674252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 2675252726Srpaulo "<addr> <home realm> = get HS20 nai home realm list" }, 2676252726Srpaulo#endif /* CONFIG_HS20 */ 2677252726Srpaulo { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL, 2678252726Srpaulo cli_cmd_flag_none, 2679252726Srpaulo "<0/1> = disable/enable automatic reconnection" }, 2680252726Srpaulo { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL, 2681252726Srpaulo cli_cmd_flag_none, 2682252726Srpaulo "<addr> = request TDLS discovery with <addr>" }, 2683252726Srpaulo { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL, 2684252726Srpaulo cli_cmd_flag_none, 2685252726Srpaulo "<addr> = request TDLS setup with <addr>" }, 2686252726Srpaulo { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL, 2687252726Srpaulo cli_cmd_flag_none, 2688252726Srpaulo "<addr> = tear down TDLS with <addr>" }, 2689252726Srpaulo { "signal_poll", wpa_cli_cmd_signal_poll, NULL, 2690252726Srpaulo cli_cmd_flag_none, 2691252726Srpaulo "= get signal parameters" }, 2692252726Srpaulo { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL, 2693252726Srpaulo cli_cmd_flag_none, 2694252726Srpaulo "= get TX/RX packet counters" }, 2695252726Srpaulo { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL, 2696252726Srpaulo cli_cmd_flag_none, 2697252726Srpaulo "= trigger IEEE 802.1X/EAPOL reauthentication" }, 2698252726Srpaulo#ifdef CONFIG_AUTOSCAN 2699252726Srpaulo { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none, 2700252726Srpaulo "[params] = Set or unset (if none) autoscan parameters" }, 2701252726Srpaulo#endif /* CONFIG_AUTOSCAN */ 2702252726Srpaulo#ifdef CONFIG_WNM 2703252726Srpaulo { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none, 2704252726Srpaulo "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" }, 2705252726Srpaulo#endif /* CONFIG_WNM */ 2706252726Srpaulo { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive, 2707252726Srpaulo "<params..> = Sent unprocessed command" }, 2708252726Srpaulo { NULL, NULL, NULL, cli_cmd_flag_none, NULL } 2709189251Ssam}; 2710189251Ssam 2711189251Ssam 2712189251Ssam/* 2713189251Ssam * Prints command usage, lines are padded with the specified string. 2714189251Ssam */ 2715189251Ssamstatic void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad) 2716189251Ssam{ 2717189251Ssam char c; 2718189251Ssam size_t n; 2719189251Ssam 2720189251Ssam printf("%s%s ", pad, cmd->cmd); 2721189251Ssam for (n = 0; (c = cmd->usage[n]); n++) { 2722189251Ssam printf("%c", c); 2723189251Ssam if (c == '\n') 2724189251Ssam printf("%s", pad); 2725189251Ssam } 2726189251Ssam printf("\n"); 2727189251Ssam} 2728189251Ssam 2729189251Ssam 2730252726Srpaulostatic void print_help(const char *cmd) 2731189251Ssam{ 2732189251Ssam int n; 2733189251Ssam printf("commands:\n"); 2734252726Srpaulo for (n = 0; wpa_cli_commands[n].cmd; n++) { 2735252726Srpaulo if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd)) 2736252726Srpaulo print_cmd_help(&wpa_cli_commands[n], " "); 2737252726Srpaulo } 2738189251Ssam} 2739189251Ssam 2740189251Ssam 2741252726Srpaulostatic int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd) 2742189251Ssam{ 2743189251Ssam const char *c, *delim; 2744189251Ssam int n; 2745189251Ssam size_t len; 2746189251Ssam 2747189251Ssam delim = os_strchr(cmd, ' '); 2748189251Ssam if (delim) 2749189251Ssam len = delim - cmd; 2750189251Ssam else 2751189251Ssam len = os_strlen(cmd); 2752189251Ssam 2753189251Ssam for (n = 0; (c = wpa_cli_commands[n].cmd); n++) { 2754189251Ssam if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c)) 2755189251Ssam return (wpa_cli_commands[n].flags & 2756189251Ssam cli_cmd_flag_sensitive); 2757189251Ssam } 2758189251Ssam return 0; 2759189251Ssam} 2760189251Ssam 2761189251Ssam 2762252726Srpaulostatic char ** wpa_list_cmd_list(void) 2763252726Srpaulo{ 2764252726Srpaulo char **res; 2765252726Srpaulo int i, count; 2766252726Srpaulo 2767252726Srpaulo count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]); 2768252726Srpaulo res = os_calloc(count, sizeof(char *)); 2769252726Srpaulo if (res == NULL) 2770252726Srpaulo return NULL; 2771252726Srpaulo 2772252726Srpaulo for (i = 0; wpa_cli_commands[i].cmd; i++) { 2773252726Srpaulo res[i] = os_strdup(wpa_cli_commands[i].cmd); 2774252726Srpaulo if (res[i] == NULL) 2775252726Srpaulo break; 2776252726Srpaulo } 2777252726Srpaulo 2778252726Srpaulo return res; 2779252726Srpaulo} 2780252726Srpaulo 2781252726Srpaulo 2782252726Srpaulostatic char ** wpa_cli_cmd_completion(const char *cmd, const char *str, 2783252726Srpaulo int pos) 2784252726Srpaulo{ 2785252726Srpaulo int i; 2786252726Srpaulo 2787252726Srpaulo for (i = 0; wpa_cli_commands[i].cmd; i++) { 2788252726Srpaulo if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) { 2789252726Srpaulo if (wpa_cli_commands[i].completion) 2790252726Srpaulo return wpa_cli_commands[i].completion(str, 2791252726Srpaulo pos); 2792252726Srpaulo edit_clear_line(); 2793252726Srpaulo printf("\r%s\n", wpa_cli_commands[i].usage); 2794252726Srpaulo edit_redraw(); 2795252726Srpaulo break; 2796252726Srpaulo } 2797252726Srpaulo } 2798252726Srpaulo 2799252726Srpaulo return NULL; 2800252726Srpaulo} 2801252726Srpaulo 2802252726Srpaulo 2803252726Srpaulostatic char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos) 2804252726Srpaulo{ 2805252726Srpaulo char **res; 2806252726Srpaulo const char *end; 2807252726Srpaulo char *cmd; 2808252726Srpaulo 2809252726Srpaulo end = os_strchr(str, ' '); 2810252726Srpaulo if (end == NULL || str + pos < end) 2811252726Srpaulo return wpa_list_cmd_list(); 2812252726Srpaulo 2813252726Srpaulo cmd = os_malloc(pos + 1); 2814252726Srpaulo if (cmd == NULL) 2815252726Srpaulo return NULL; 2816252726Srpaulo os_memcpy(cmd, str, pos); 2817252726Srpaulo cmd[end - str] = '\0'; 2818252726Srpaulo res = wpa_cli_cmd_completion(cmd, str, pos); 2819252726Srpaulo os_free(cmd); 2820252726Srpaulo return res; 2821252726Srpaulo} 2822252726Srpaulo 2823252726Srpaulo 2824189251Ssamstatic int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2825189251Ssam{ 2826189251Ssam struct wpa_cli_cmd *cmd, *match = NULL; 2827189251Ssam int count; 2828189251Ssam int ret = 0; 2829189251Ssam 2830189251Ssam count = 0; 2831189251Ssam cmd = wpa_cli_commands; 2832189251Ssam while (cmd->cmd) { 2833189251Ssam if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0) 2834189251Ssam { 2835189251Ssam match = cmd; 2836189251Ssam if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { 2837189251Ssam /* we have an exact match */ 2838189251Ssam count = 1; 2839189251Ssam break; 2840189251Ssam } 2841189251Ssam count++; 2842189251Ssam } 2843189251Ssam cmd++; 2844189251Ssam } 2845189251Ssam 2846189251Ssam if (count > 1) { 2847189251Ssam printf("Ambiguous command '%s'; possible commands:", argv[0]); 2848189251Ssam cmd = wpa_cli_commands; 2849189251Ssam while (cmd->cmd) { 2850189251Ssam if (os_strncasecmp(cmd->cmd, argv[0], 2851189251Ssam os_strlen(argv[0])) == 0) { 2852189251Ssam printf(" %s", cmd->cmd); 2853189251Ssam } 2854189251Ssam cmd++; 2855189251Ssam } 2856189251Ssam printf("\n"); 2857189251Ssam ret = 1; 2858189251Ssam } else if (count == 0) { 2859189251Ssam printf("Unknown command '%s'\n", argv[0]); 2860189251Ssam ret = 1; 2861189251Ssam } else { 2862189251Ssam ret = match->handler(ctrl, argc - 1, &argv[1]); 2863189251Ssam } 2864189251Ssam 2865189251Ssam return ret; 2866189251Ssam} 2867189251Ssam 2868189251Ssam 2869189251Ssamstatic int str_match(const char *a, const char *b) 2870189251Ssam{ 2871189251Ssam return os_strncmp(a, b, os_strlen(b)) == 0; 2872189251Ssam} 2873189251Ssam 2874189251Ssam 2875189251Ssamstatic int wpa_cli_exec(const char *program, const char *arg1, 2876189251Ssam const char *arg2) 2877189251Ssam{ 2878189251Ssam char *cmd; 2879189251Ssam size_t len; 2880189251Ssam int res; 2881189251Ssam int ret = 0; 2882189251Ssam 2883189251Ssam len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3; 2884189251Ssam cmd = os_malloc(len); 2885189251Ssam if (cmd == NULL) 2886189251Ssam return -1; 2887189251Ssam res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2); 2888189251Ssam if (res < 0 || (size_t) res >= len) { 2889189251Ssam os_free(cmd); 2890189251Ssam return -1; 2891189251Ssam } 2892189251Ssam cmd[len - 1] = '\0'; 2893189251Ssam#ifndef _WIN32_WCE 2894189251Ssam if (system(cmd) < 0) 2895189251Ssam ret = -1; 2896189251Ssam#endif /* _WIN32_WCE */ 2897189251Ssam os_free(cmd); 2898189251Ssam 2899189251Ssam return ret; 2900189251Ssam} 2901189251Ssam 2902189251Ssam 2903189251Ssamstatic void wpa_cli_action_process(const char *msg) 2904189251Ssam{ 2905189251Ssam const char *pos; 2906189251Ssam char *copy = NULL, *id, *pos2; 2907189251Ssam 2908189251Ssam pos = msg; 2909189251Ssam if (*pos == '<') { 2910189251Ssam /* skip priority */ 2911189251Ssam pos = os_strchr(pos, '>'); 2912189251Ssam if (pos) 2913189251Ssam pos++; 2914189251Ssam else 2915189251Ssam pos = msg; 2916189251Ssam } 2917189251Ssam 2918189251Ssam if (str_match(pos, WPA_EVENT_CONNECTED)) { 2919189251Ssam int new_id = -1; 2920189251Ssam os_unsetenv("WPA_ID"); 2921189251Ssam os_unsetenv("WPA_ID_STR"); 2922189251Ssam os_unsetenv("WPA_CTRL_DIR"); 2923189251Ssam 2924189251Ssam pos = os_strstr(pos, "[id="); 2925189251Ssam if (pos) 2926189251Ssam copy = os_strdup(pos + 4); 2927189251Ssam 2928189251Ssam if (copy) { 2929189251Ssam pos2 = id = copy; 2930189251Ssam while (*pos2 && *pos2 != ' ') 2931189251Ssam pos2++; 2932189251Ssam *pos2++ = '\0'; 2933189251Ssam new_id = atoi(id); 2934189251Ssam os_setenv("WPA_ID", id, 1); 2935189251Ssam while (*pos2 && *pos2 != '=') 2936189251Ssam pos2++; 2937189251Ssam if (*pos2 == '=') 2938189251Ssam pos2++; 2939189251Ssam id = pos2; 2940189251Ssam while (*pos2 && *pos2 != ']') 2941189251Ssam pos2++; 2942189251Ssam *pos2 = '\0'; 2943189251Ssam os_setenv("WPA_ID_STR", id, 1); 2944189251Ssam os_free(copy); 2945189251Ssam } 2946189251Ssam 2947189251Ssam os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); 2948189251Ssam 2949189251Ssam if (!wpa_cli_connected || new_id != wpa_cli_last_id) { 2950189251Ssam wpa_cli_connected = 1; 2951189251Ssam wpa_cli_last_id = new_id; 2952189251Ssam wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED"); 2953189251Ssam } 2954189251Ssam } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) { 2955189251Ssam if (wpa_cli_connected) { 2956189251Ssam wpa_cli_connected = 0; 2957189251Ssam wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED"); 2958189251Ssam } 2959252726Srpaulo } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) { 2960252726Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 2961252726Srpaulo } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) { 2962252726Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 2963252726Srpaulo } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) { 2964252726Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 2965252726Srpaulo } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) { 2966252726Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 2967252726Srpaulo } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) { 2968252726Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 2969252726Srpaulo } else if (str_match(pos, WPS_EVENT_SUCCESS)) { 2970252726Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 2971252726Srpaulo } else if (str_match(pos, WPS_EVENT_FAIL)) { 2972252726Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 2973252726Srpaulo } else if (str_match(pos, AP_STA_CONNECTED)) { 2974252726Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 2975252726Srpaulo } else if (str_match(pos, AP_STA_DISCONNECTED)) { 2976252726Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 2977189251Ssam } else if (str_match(pos, WPA_EVENT_TERMINATING)) { 2978189251Ssam printf("wpa_supplicant is terminating - stop monitoring\n"); 2979189251Ssam wpa_cli_quit = 1; 2980189251Ssam } 2981189251Ssam} 2982189251Ssam 2983189251Ssam 2984189251Ssam#ifndef CONFIG_ANSI_C_EXTRA 2985189251Ssamstatic void wpa_cli_action_cb(char *msg, size_t len) 2986189251Ssam{ 2987189251Ssam wpa_cli_action_process(msg); 2988189251Ssam} 2989189251Ssam#endif /* CONFIG_ANSI_C_EXTRA */ 2990189251Ssam 2991189251Ssam 2992189251Ssamstatic void wpa_cli_reconnect(void) 2993189251Ssam{ 2994189251Ssam wpa_cli_close_connection(); 2995252726Srpaulo if (wpa_cli_open_connection(ctrl_ifname, 1) < 0) 2996252726Srpaulo return; 2997252726Srpaulo 2998252726Srpaulo if (interactive) { 2999252726Srpaulo edit_clear_line(); 3000252726Srpaulo printf("\rConnection to wpa_supplicant re-established\n"); 3001252726Srpaulo edit_redraw(); 3002252726Srpaulo } 3003189251Ssam} 3004189251Ssam 3005189251Ssam 3006252726Srpaulostatic void cli_event(const char *str) 3007189251Ssam{ 3008252726Srpaulo const char *start, *s; 3009252726Srpaulo 3010252726Srpaulo start = os_strchr(str, '>'); 3011252726Srpaulo if (start == NULL) 3012252726Srpaulo return; 3013252726Srpaulo 3014252726Srpaulo start++; 3015252726Srpaulo 3016252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_ADDED)) { 3017252726Srpaulo s = os_strchr(start, ' '); 3018252726Srpaulo if (s == NULL) 3019252726Srpaulo return; 3020252726Srpaulo s = os_strchr(s + 1, ' '); 3021252726Srpaulo if (s == NULL) 3022252726Srpaulo return; 3023252726Srpaulo cli_txt_list_add(&bsses, s + 1); 3024252726Srpaulo return; 3025252726Srpaulo } 3026252726Srpaulo 3027252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_REMOVED)) { 3028252726Srpaulo s = os_strchr(start, ' '); 3029252726Srpaulo if (s == NULL) 3030252726Srpaulo return; 3031252726Srpaulo s = os_strchr(s + 1, ' '); 3032252726Srpaulo if (s == NULL) 3033252726Srpaulo return; 3034252726Srpaulo cli_txt_list_del_addr(&bsses, s + 1); 3035252726Srpaulo return; 3036252726Srpaulo } 3037252726Srpaulo 3038252726Srpaulo#ifdef CONFIG_P2P 3039252726Srpaulo if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) { 3040252726Srpaulo s = os_strstr(start, " p2p_dev_addr="); 3041252726Srpaulo if (s == NULL) 3042252726Srpaulo return; 3043252726Srpaulo cli_txt_list_add_addr(&p2p_peers, s + 14); 3044252726Srpaulo return; 3045252726Srpaulo } 3046252726Srpaulo 3047252726Srpaulo if (str_starts(start, P2P_EVENT_DEVICE_LOST)) { 3048252726Srpaulo s = os_strstr(start, " p2p_dev_addr="); 3049252726Srpaulo if (s == NULL) 3050252726Srpaulo return; 3051252726Srpaulo cli_txt_list_del_addr(&p2p_peers, s + 14); 3052252726Srpaulo return; 3053252726Srpaulo } 3054252726Srpaulo 3055252726Srpaulo if (str_starts(start, P2P_EVENT_GROUP_STARTED)) { 3056252726Srpaulo s = os_strchr(start, ' '); 3057252726Srpaulo if (s == NULL) 3058252726Srpaulo return; 3059252726Srpaulo cli_txt_list_add_word(&p2p_groups, s + 1); 3060252726Srpaulo return; 3061252726Srpaulo } 3062252726Srpaulo 3063252726Srpaulo if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) { 3064252726Srpaulo s = os_strchr(start, ' '); 3065252726Srpaulo if (s == NULL) 3066252726Srpaulo return; 3067252726Srpaulo cli_txt_list_del_word(&p2p_groups, s + 1); 3068252726Srpaulo return; 3069252726Srpaulo } 3070252726Srpaulo#endif /* CONFIG_P2P */ 3071252726Srpaulo} 3072252726Srpaulo 3073252726Srpaulo 3074252726Srpaulostatic int check_terminating(const char *msg) 3075252726Srpaulo{ 3076252726Srpaulo const char *pos = msg; 3077252726Srpaulo 3078252726Srpaulo if (*pos == '<') { 3079252726Srpaulo /* skip priority */ 3080252726Srpaulo pos = os_strchr(pos, '>'); 3081252726Srpaulo if (pos) 3082252726Srpaulo pos++; 3083252726Srpaulo else 3084252726Srpaulo pos = msg; 3085252726Srpaulo } 3086252726Srpaulo 3087252726Srpaulo if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) { 3088252726Srpaulo edit_clear_line(); 3089252726Srpaulo printf("\rConnection to wpa_supplicant lost - trying to " 3090252726Srpaulo "reconnect\n"); 3091252726Srpaulo edit_redraw(); 3092252726Srpaulo wpa_cli_attached = 0; 3093252726Srpaulo wpa_cli_close_connection(); 3094252726Srpaulo return 1; 3095252726Srpaulo } 3096252726Srpaulo 3097252726Srpaulo return 0; 3098252726Srpaulo} 3099252726Srpaulo 3100252726Srpaulo 3101252726Srpaulostatic void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor) 3102252726Srpaulo{ 3103189251Ssam if (ctrl_conn == NULL) { 3104189251Ssam wpa_cli_reconnect(); 3105189251Ssam return; 3106189251Ssam } 3107189251Ssam while (wpa_ctrl_pending(ctrl) > 0) { 3108189251Ssam char buf[256]; 3109189251Ssam size_t len = sizeof(buf) - 1; 3110189251Ssam if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { 3111189251Ssam buf[len] = '\0'; 3112189251Ssam if (action_monitor) 3113189251Ssam wpa_cli_action_process(buf); 3114189251Ssam else { 3115252726Srpaulo cli_event(buf); 3116252726Srpaulo if (wpa_cli_show_event(buf)) { 3117252726Srpaulo edit_clear_line(); 3118252726Srpaulo printf("\r%s\n", buf); 3119252726Srpaulo edit_redraw(); 3120252726Srpaulo } 3121252726Srpaulo 3122252726Srpaulo if (interactive && check_terminating(buf) > 0) 3123252726Srpaulo return; 3124189251Ssam } 3125189251Ssam } else { 3126189251Ssam printf("Could not read pending message.\n"); 3127189251Ssam break; 3128189251Ssam } 3129189251Ssam } 3130189251Ssam 3131189251Ssam if (wpa_ctrl_pending(ctrl) < 0) { 3132189251Ssam printf("Connection to wpa_supplicant lost - trying to " 3133189251Ssam "reconnect\n"); 3134189251Ssam wpa_cli_reconnect(); 3135189251Ssam } 3136189251Ssam} 3137189251Ssam 3138252726Srpaulo#define max_args 10 3139189251Ssam 3140252726Srpaulostatic int tokenize_cmd(char *cmd, char *argv[]) 3141189251Ssam{ 3142252726Srpaulo char *pos; 3143252726Srpaulo int argc = 0; 3144189251Ssam 3145252726Srpaulo pos = cmd; 3146252726Srpaulo for (;;) { 3147252726Srpaulo while (*pos == ' ') 3148252726Srpaulo pos++; 3149252726Srpaulo if (*pos == '\0') 3150252726Srpaulo break; 3151252726Srpaulo argv[argc] = pos; 3152252726Srpaulo argc++; 3153252726Srpaulo if (argc == max_args) 3154252726Srpaulo break; 3155252726Srpaulo if (*pos == '"') { 3156252726Srpaulo char *pos2 = os_strrchr(pos, '"'); 3157252726Srpaulo if (pos2) 3158252726Srpaulo pos = pos2 + 1; 3159252726Srpaulo } 3160252726Srpaulo while (*pos != '\0' && *pos != ' ') 3161252726Srpaulo pos++; 3162252726Srpaulo if (*pos == ' ') 3163252726Srpaulo *pos++ = '\0'; 3164189251Ssam } 3165189251Ssam 3166252726Srpaulo return argc; 3167189251Ssam} 3168189251Ssam 3169189251Ssam 3170252726Srpaulostatic void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx) 3171189251Ssam{ 3172252726Srpaulo if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) { 3173252726Srpaulo printf("Connection to wpa_supplicant lost - trying to " 3174252726Srpaulo "reconnect\n"); 3175252726Srpaulo wpa_cli_close_connection(); 3176214734Srpaulo } 3177252726Srpaulo if (!ctrl_conn) 3178252726Srpaulo wpa_cli_reconnect(); 3179252726Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 3180189251Ssam} 3181189251Ssam 3182189251Ssam 3183252726Srpaulostatic void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx) 3184214734Srpaulo{ 3185252726Srpaulo wpa_cli_recv_pending(mon_conn, 0); 3186252726Srpaulo} 3187214734Srpaulo 3188214734Srpaulo 3189252726Srpaulostatic void wpa_cli_edit_cmd_cb(void *ctx, char *cmd) 3190252726Srpaulo{ 3191252726Srpaulo char *argv[max_args]; 3192252726Srpaulo int argc; 3193252726Srpaulo argc = tokenize_cmd(cmd, argv); 3194252726Srpaulo if (argc) 3195252726Srpaulo wpa_request(ctrl_conn, argc, argv); 3196214734Srpaulo} 3197214734Srpaulo 3198214734Srpaulo 3199252726Srpaulostatic void wpa_cli_edit_eof_cb(void *ctx) 3200189251Ssam{ 3201252726Srpaulo eloop_terminate(); 3202189251Ssam} 3203189251Ssam 3204189251Ssam 3205252726Srpaulostatic int warning_displayed = 0; 3206252726Srpaulostatic char *hfile = NULL; 3207252726Srpaulostatic int edit_started = 0; 3208252726Srpaulo 3209252726Srpaulostatic void start_edit(void) 3210189251Ssam{ 3211252726Srpaulo char *home; 3212252726Srpaulo char *ps = NULL; 3213189251Ssam 3214252726Srpaulo#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE 3215252726Srpaulo ps = wpa_ctrl_get_remote_ifname(ctrl_conn); 3216252726Srpaulo#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ 3217189251Ssam 3218189251Ssam home = getenv("HOME"); 3219189251Ssam if (home) { 3220189251Ssam const char *fname = ".wpa_cli_history"; 3221189251Ssam int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; 3222189251Ssam hfile = os_malloc(hfile_len); 3223252726Srpaulo if (hfile) 3224252726Srpaulo os_snprintf(hfile, hfile_len, "%s/%s", home, fname); 3225189251Ssam } 3226189251Ssam 3227252726Srpaulo if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, 3228252726Srpaulo wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) { 3229252726Srpaulo eloop_terminate(); 3230252726Srpaulo return; 3231252726Srpaulo } 3232189251Ssam 3233252726Srpaulo edit_started = 1; 3234252726Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 3235252726Srpaulo} 3236189251Ssam 3237252726Srpaulo 3238252726Srpaulostatic void try_connection(void *eloop_ctx, void *timeout_ctx) 3239252726Srpaulo{ 3240252726Srpaulo if (ctrl_ifname == NULL) 3241252726Srpaulo ctrl_ifname = wpa_cli_get_default_ifname(); 3242252726Srpaulo 3243252726Srpaulo if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) { 3244252726Srpaulo if (!warning_displayed) { 3245252726Srpaulo printf("Could not connect to wpa_supplicant: " 3246252726Srpaulo "%s - re-trying\n", ctrl_ifname); 3247252726Srpaulo warning_displayed = 1; 3248189251Ssam } 3249252726Srpaulo eloop_register_timeout(1, 0, try_connection, NULL, NULL); 3250252726Srpaulo return; 3251189251Ssam } 3252252726Srpaulo 3253252726Srpaulo if (warning_displayed) 3254252726Srpaulo printf("Connection established.\n"); 3255252726Srpaulo 3256252726Srpaulo start_edit(); 3257189251Ssam} 3258189251Ssam 3259189251Ssam 3260252726Srpaulostatic void wpa_cli_interactive(void) 3261252726Srpaulo{ 3262252726Srpaulo printf("\nInteractive mode\n\n"); 3263252726Srpaulo 3264252726Srpaulo eloop_register_timeout(0, 0, try_connection, NULL, NULL); 3265252726Srpaulo eloop_run(); 3266252726Srpaulo eloop_cancel_timeout(try_connection, NULL, NULL); 3267252726Srpaulo 3268252726Srpaulo cli_txt_list_flush(&p2p_peers); 3269252726Srpaulo cli_txt_list_flush(&p2p_groups); 3270252726Srpaulo cli_txt_list_flush(&bsses); 3271252726Srpaulo if (edit_started) 3272252726Srpaulo edit_deinit(hfile, wpa_cli_edit_filter_history_cb); 3273252726Srpaulo os_free(hfile); 3274252726Srpaulo eloop_cancel_timeout(wpa_cli_ping, NULL, NULL); 3275252726Srpaulo wpa_cli_close_connection(); 3276252726Srpaulo} 3277252726Srpaulo 3278252726Srpaulo 3279189251Ssamstatic void wpa_cli_action(struct wpa_ctrl *ctrl) 3280189251Ssam{ 3281189251Ssam#ifdef CONFIG_ANSI_C_EXTRA 3282189251Ssam /* TODO: ANSI C version(?) */ 3283189251Ssam printf("Action processing not supported in ANSI C build.\n"); 3284189251Ssam#else /* CONFIG_ANSI_C_EXTRA */ 3285189251Ssam fd_set rfds; 3286189251Ssam int fd, res; 3287189251Ssam struct timeval tv; 3288189251Ssam char buf[256]; /* note: large enough to fit in unsolicited messages */ 3289189251Ssam size_t len; 3290189251Ssam 3291189251Ssam fd = wpa_ctrl_get_fd(ctrl); 3292189251Ssam 3293189251Ssam while (!wpa_cli_quit) { 3294189251Ssam FD_ZERO(&rfds); 3295189251Ssam FD_SET(fd, &rfds); 3296189251Ssam tv.tv_sec = ping_interval; 3297189251Ssam tv.tv_usec = 0; 3298189251Ssam res = select(fd + 1, &rfds, NULL, NULL, &tv); 3299189251Ssam if (res < 0 && errno != EINTR) { 3300189251Ssam perror("select"); 3301189251Ssam break; 3302189251Ssam } 3303189251Ssam 3304189251Ssam if (FD_ISSET(fd, &rfds)) 3305252726Srpaulo wpa_cli_recv_pending(ctrl, 1); 3306189251Ssam else { 3307189251Ssam /* verify that connection is still working */ 3308189251Ssam len = sizeof(buf) - 1; 3309189251Ssam if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, 3310189251Ssam wpa_cli_action_cb) < 0 || 3311189251Ssam len < 4 || os_memcmp(buf, "PONG", 4) != 0) { 3312189251Ssam printf("wpa_supplicant did not reply to PING " 3313189251Ssam "command - exiting\n"); 3314189251Ssam break; 3315189251Ssam } 3316189251Ssam } 3317189251Ssam } 3318189251Ssam#endif /* CONFIG_ANSI_C_EXTRA */ 3319189251Ssam} 3320189251Ssam 3321189251Ssam 3322189251Ssamstatic void wpa_cli_cleanup(void) 3323189251Ssam{ 3324189251Ssam wpa_cli_close_connection(); 3325189251Ssam if (pid_file) 3326189251Ssam os_daemonize_terminate(pid_file); 3327189251Ssam 3328189251Ssam os_program_deinit(); 3329189251Ssam} 3330189251Ssam 3331189251Ssam 3332252726Srpaulostatic void wpa_cli_terminate(int sig, void *ctx) 3333214734Srpaulo{ 3334252726Srpaulo eloop_terminate(); 3335214734Srpaulo} 3336214734Srpaulo 3337214734Srpaulo 3338189251Ssamstatic char * wpa_cli_get_default_ifname(void) 3339189251Ssam{ 3340189251Ssam char *ifname = NULL; 3341189251Ssam 3342189251Ssam#ifdef CONFIG_CTRL_IFACE_UNIX 3343189251Ssam struct dirent *dent; 3344189251Ssam DIR *dir = opendir(ctrl_iface_dir); 3345252726Srpaulo if (!dir) { 3346252726Srpaulo#ifdef ANDROID 3347252726Srpaulo char ifprop[PROPERTY_VALUE_MAX]; 3348252726Srpaulo if (property_get("wifi.interface", ifprop, NULL) != 0) { 3349252726Srpaulo ifname = os_strdup(ifprop); 3350252726Srpaulo printf("Using interface '%s'\n", ifname); 3351252726Srpaulo return ifname; 3352252726Srpaulo } 3353252726Srpaulo#endif /* ANDROID */ 3354189251Ssam return NULL; 3355252726Srpaulo } 3356189251Ssam while ((dent = readdir(dir))) { 3357189251Ssam#ifdef _DIRENT_HAVE_D_TYPE 3358189251Ssam /* 3359189251Ssam * Skip the file if it is not a socket. Also accept 3360189251Ssam * DT_UNKNOWN (0) in case the C library or underlying 3361189251Ssam * file system does not support d_type. 3362189251Ssam */ 3363189251Ssam if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) 3364189251Ssam continue; 3365189251Ssam#endif /* _DIRENT_HAVE_D_TYPE */ 3366189251Ssam if (os_strcmp(dent->d_name, ".") == 0 || 3367189251Ssam os_strcmp(dent->d_name, "..") == 0) 3368189251Ssam continue; 3369189251Ssam printf("Selected interface '%s'\n", dent->d_name); 3370189251Ssam ifname = os_strdup(dent->d_name); 3371189251Ssam break; 3372189251Ssam } 3373189251Ssam closedir(dir); 3374189251Ssam#endif /* CONFIG_CTRL_IFACE_UNIX */ 3375189251Ssam 3376189251Ssam#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 3377189251Ssam char buf[2048], *pos; 3378189251Ssam size_t len; 3379189251Ssam struct wpa_ctrl *ctrl; 3380189251Ssam int ret; 3381189251Ssam 3382189251Ssam ctrl = wpa_ctrl_open(NULL); 3383189251Ssam if (ctrl == NULL) 3384189251Ssam return NULL; 3385189251Ssam 3386189251Ssam len = sizeof(buf) - 1; 3387189251Ssam ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); 3388189251Ssam if (ret >= 0) { 3389189251Ssam buf[len] = '\0'; 3390189251Ssam pos = os_strchr(buf, '\n'); 3391189251Ssam if (pos) 3392189251Ssam *pos = '\0'; 3393189251Ssam ifname = os_strdup(buf); 3394189251Ssam } 3395189251Ssam wpa_ctrl_close(ctrl); 3396189251Ssam#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 3397189251Ssam 3398189251Ssam return ifname; 3399189251Ssam} 3400189251Ssam 3401189251Ssam 3402189251Ssamint main(int argc, char *argv[]) 3403189251Ssam{ 3404189251Ssam int c; 3405189251Ssam int daemonize = 0; 3406189251Ssam int ret = 0; 3407189251Ssam const char *global = NULL; 3408189251Ssam 3409189251Ssam if (os_program_init()) 3410189251Ssam return -1; 3411189251Ssam 3412189251Ssam for (;;) { 3413189251Ssam c = getopt(argc, argv, "a:Bg:G:hi:p:P:v"); 3414189251Ssam if (c < 0) 3415189251Ssam break; 3416189251Ssam switch (c) { 3417189251Ssam case 'a': 3418189251Ssam action_file = optarg; 3419189251Ssam break; 3420189251Ssam case 'B': 3421189251Ssam daemonize = 1; 3422189251Ssam break; 3423189251Ssam case 'g': 3424189251Ssam global = optarg; 3425189251Ssam break; 3426189251Ssam case 'G': 3427189251Ssam ping_interval = atoi(optarg); 3428189251Ssam break; 3429189251Ssam case 'h': 3430189251Ssam usage(); 3431189251Ssam return 0; 3432189251Ssam case 'v': 3433189251Ssam printf("%s\n", wpa_cli_version); 3434189251Ssam return 0; 3435189251Ssam case 'i': 3436189251Ssam os_free(ctrl_ifname); 3437189251Ssam ctrl_ifname = os_strdup(optarg); 3438189251Ssam break; 3439189251Ssam case 'p': 3440189251Ssam ctrl_iface_dir = optarg; 3441189251Ssam break; 3442189251Ssam case 'P': 3443189251Ssam pid_file = optarg; 3444189251Ssam break; 3445189251Ssam default: 3446189251Ssam usage(); 3447189251Ssam return -1; 3448189251Ssam } 3449189251Ssam } 3450189251Ssam 3451189251Ssam interactive = (argc == optind) && (action_file == NULL); 3452189251Ssam 3453189251Ssam if (interactive) 3454189251Ssam printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license); 3455189251Ssam 3456252726Srpaulo if (eloop_init()) 3457252726Srpaulo return -1; 3458252726Srpaulo 3459189251Ssam if (global) { 3460189251Ssam#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 3461189251Ssam ctrl_conn = wpa_ctrl_open(NULL); 3462189251Ssam#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 3463189251Ssam ctrl_conn = wpa_ctrl_open(global); 3464189251Ssam#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 3465189251Ssam if (ctrl_conn == NULL) { 3466252726Srpaulo fprintf(stderr, "Failed to connect to wpa_supplicant " 3467252726Srpaulo "global interface: %s error: %s\n", 3468252726Srpaulo global, strerror(errno)); 3469189251Ssam return -1; 3470189251Ssam } 3471189251Ssam } 3472189251Ssam 3473252726Srpaulo eloop_register_signal_terminate(wpa_cli_terminate, NULL); 3474189251Ssam 3475214734Srpaulo if (ctrl_ifname == NULL) 3476214734Srpaulo ctrl_ifname = wpa_cli_get_default_ifname(); 3477214734Srpaulo 3478214734Srpaulo if (interactive) { 3479252726Srpaulo wpa_cli_interactive(); 3480214734Srpaulo } else { 3481214734Srpaulo if (!global && 3482214734Srpaulo wpa_cli_open_connection(ctrl_ifname, 0) < 0) { 3483252726Srpaulo fprintf(stderr, "Failed to connect to non-global " 3484252726Srpaulo "ctrl_ifname: %s error: %s\n", 3485252726Srpaulo ctrl_ifname, strerror(errno)); 3486214734Srpaulo return -1; 3487214734Srpaulo } 3488214734Srpaulo 3489214734Srpaulo if (action_file) { 3490214734Srpaulo if (wpa_ctrl_attach(ctrl_conn) == 0) { 3491214734Srpaulo wpa_cli_attached = 1; 3492214734Srpaulo } else { 3493214734Srpaulo printf("Warning: Failed to attach to " 3494214734Srpaulo "wpa_supplicant.\n"); 3495189251Ssam return -1; 3496214734Srpaulo } 3497189251Ssam } 3498189251Ssam 3499252726Srpaulo if (daemonize && os_daemonize(pid_file)) 3500252726Srpaulo return -1; 3501189251Ssam 3502252726Srpaulo if (action_file) 3503252726Srpaulo wpa_cli_action(ctrl_conn); 3504252726Srpaulo else 3505252726Srpaulo ret = wpa_request(ctrl_conn, argc - optind, 3506252726Srpaulo &argv[optind]); 3507252726Srpaulo } 3508189251Ssam 3509189251Ssam os_free(ctrl_ifname); 3510252726Srpaulo eloop_destroy(); 3511189251Ssam wpa_cli_cleanup(); 3512189251Ssam 3513189251Ssam return ret; 3514189251Ssam} 3515189251Ssam 3516189251Ssam#else /* CONFIG_CTRL_IFACE */ 3517189251Ssamint main(int argc, char *argv[]) 3518189251Ssam{ 3519189251Ssam printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n"); 3520189251Ssam return -1; 3521189251Ssam} 3522189251Ssam#endif /* CONFIG_CTRL_IFACE */ 3523