1 /* 2 * WPA Supplicant - command line interface for wpa_supplicant daemon 3 * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #ifdef CONFIG_CTRL_IFACE 12 13 #ifdef CONFIG_CTRL_IFACE_UNIX 14 #include <dirent.h> 15 #endif /* CONFIG_CTRL_IFACE_UNIX */ 16 17 #include "common/cli.h" 18 #include "common/wpa_ctrl.h" 19 #include "utils/common.h" 20 #include "utils/eloop.h" 21 #include "utils/edit.h" 22 #include "utils/list.h" 23 #include "common/version.h" 24 #include "common/ieee802_11_defs.h" 25 #ifdef ANDROID 26 #include <cutils/properties.h> 27 #endif /* ANDROID */ 28 29 30 static const char *const wpa_cli_version = 31 "wpa_cli v" VERSION_STR "\n" 32 "Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> and contributors"; 33 34 #define VENDOR_ELEM_FRAME_ID \ 35 " 0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \ 36 "3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, " \ 37 "7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, " \ 38 "11: Assoc Req (P2P), 12: Assoc Resp (P2P)" 39 40 static struct wpa_ctrl *ctrl_conn; 41 static struct wpa_ctrl *mon_conn; 42 static int wpa_cli_quit = 0; 43 static int wpa_cli_attached = 0; 44 static int wpa_cli_connected = -1; 45 static int wpa_cli_last_id = 0; 46 #ifndef CONFIG_CTRL_IFACE_DIR 47 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant" 48 #endif /* CONFIG_CTRL_IFACE_DIR */ 49 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR; 50 static const char *client_socket_dir = NULL; 51 static char *ctrl_ifname = NULL; 52 static const char *global = NULL; 53 static const char *pid_file = NULL; 54 static const char *action_file = NULL; 55 static int ping_interval = 5; 56 static int interactive = 0; 57 static char *ifname_prefix = NULL; 58 59 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */ 60 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */ 61 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */ 62 static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */ 63 static DEFINE_DL_LIST(networks); /* struct cli_txt_entry */ 64 static DEFINE_DL_LIST(creds); /* struct cli_txt_entry */ 65 #ifdef CONFIG_AP 66 static DEFINE_DL_LIST(stations); /* struct cli_txt_entry */ 67 #endif /* CONFIG_AP */ 68 69 70 static void print_help(const char *cmd); 71 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx); 72 static void wpa_cli_close_connection(void); 73 static char * wpa_cli_get_default_ifname(void); 74 static char ** wpa_list_cmd_list(void); 75 static void update_creds(struct wpa_ctrl *ctrl); 76 static void update_networks(struct wpa_ctrl *ctrl); 77 static void update_stations(struct wpa_ctrl *ctrl); 78 static void update_ifnames(struct wpa_ctrl *ctrl); 79 80 81 static void usage(void) 82 { 83 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] " 84 "[-a<action file>] \\\n" 85 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] " 86 "\\\n" 87 " [-s<wpa_client_socket_file_path>] " 88 "[command..]\n" 89 " -h = help (show this usage text)\n" 90 " -v = shown version information\n" 91 " -a = run in daemon mode executing the action file based on " 92 "events from\n" 93 " wpa_supplicant\n" 94 " -B = run a daemon in the background\n" 95 " default path: " CONFIG_CTRL_IFACE_DIR "\n" 96 " default interface: first interface found in socket path\n"); 97 print_help(NULL); 98 } 99 100 101 static int wpa_cli_show_event(const char *event) 102 { 103 const char *start; 104 105 start = os_strchr(event, '>'); 106 if (start == NULL) 107 return 1; 108 109 start++; 110 /* 111 * Skip BSS added/removed events since they can be relatively frequent 112 * and are likely of not much use for an interactive user. 113 */ 114 if (str_starts(start, WPA_EVENT_BSS_ADDED) || 115 str_starts(start, WPA_EVENT_BSS_REMOVED)) 116 return 0; 117 118 return 1; 119 } 120 121 122 static int wpa_cli_open_connection(const char *ifname, int attach) 123 { 124 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE) 125 ctrl_conn = wpa_ctrl_open(ifname); 126 if (ctrl_conn == NULL) 127 return -1; 128 129 if (attach && interactive) 130 mon_conn = wpa_ctrl_open(ifname); 131 else 132 mon_conn = NULL; 133 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 134 char *cfile = NULL; 135 int flen, res; 136 137 if (ifname == NULL) 138 return -1; 139 140 #ifdef ANDROID 141 if (access(ctrl_iface_dir, F_OK) < 0) { 142 cfile = os_strdup(ifname); 143 if (cfile == NULL) 144 return -1; 145 } 146 #endif /* ANDROID */ 147 148 if (client_socket_dir && client_socket_dir[0] && 149 access(client_socket_dir, F_OK) < 0) { 150 perror(client_socket_dir); 151 os_free(cfile); 152 return -1; 153 } 154 155 if (cfile == NULL) { 156 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2; 157 cfile = os_malloc(flen); 158 if (cfile == NULL) 159 return -1; 160 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, 161 ifname); 162 if (os_snprintf_error(flen, res)) { 163 os_free(cfile); 164 return -1; 165 } 166 } 167 168 ctrl_conn = wpa_ctrl_open2(cfile, client_socket_dir); 169 if (ctrl_conn == NULL) { 170 os_free(cfile); 171 return -1; 172 } 173 174 if (attach && interactive) 175 mon_conn = wpa_ctrl_open2(cfile, client_socket_dir); 176 else 177 mon_conn = NULL; 178 os_free(cfile); 179 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 180 181 if (mon_conn) { 182 if (wpa_ctrl_attach(mon_conn) == 0) { 183 wpa_cli_attached = 1; 184 if (interactive) 185 eloop_register_read_sock( 186 wpa_ctrl_get_fd(mon_conn), 187 wpa_cli_mon_receive, NULL, NULL); 188 } else { 189 printf("Warning: Failed to attach to " 190 "wpa_supplicant.\n"); 191 wpa_cli_close_connection(); 192 return -1; 193 } 194 } 195 196 return 0; 197 } 198 199 200 static void wpa_cli_close_connection(void) 201 { 202 if (ctrl_conn == NULL) 203 return; 204 205 if (wpa_cli_attached) { 206 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn); 207 wpa_cli_attached = 0; 208 } 209 wpa_ctrl_close(ctrl_conn); 210 ctrl_conn = NULL; 211 if (mon_conn) { 212 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn)); 213 wpa_ctrl_close(mon_conn); 214 mon_conn = NULL; 215 } 216 } 217 218 static const char *skip_priority(const char *msg) 219 { 220 const char *pos = msg; 221 222 if (*msg != '<') 223 return msg; 224 225 for (pos = msg + 1; isdigit((unsigned char)*pos); pos++) 226 continue; 227 228 if (*pos != '>') 229 return msg; 230 231 return ++pos; 232 } 233 234 static const char *fmttime(char *buf, size_t buflen) 235 { 236 struct timeval tv; 237 struct tm tm; 238 time_t t; 239 240 if (buflen <= 8) 241 return NULL; 242 243 (void)gettimeofday(&tv, NULL); 244 t = (time_t)tv.tv_sec; 245 (void)localtime_r(&t, &tm); 246 (void)strftime(buf, buflen, "%H:%M:%S", &tm); 247 (void)snprintf(buf + 8, buflen - 8, ".%.3d", (int)(tv.tv_usec / 1000)); 248 return buf; 249 } 250 251 static void wpa_cli_msg_cb(char *msg, size_t len) 252 { 253 char tbuf[32]; 254 printf("%s: %s\n", fmttime(tbuf, sizeof(tbuf)), skip_priority(msg)); 255 } 256 257 258 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, int print) 259 { 260 char buf[4096]; 261 size_t len; 262 int ret; 263 264 if (ctrl_conn == NULL) { 265 printf("Not connected to wpa_supplicant - command dropped.\n"); 266 return -1; 267 } 268 if (ifname_prefix) { 269 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s", 270 ifname_prefix, cmd); 271 buf[sizeof(buf) - 1] = '\0'; 272 cmd = buf; 273 } 274 len = sizeof(buf) - 1; 275 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 276 wpa_cli_msg_cb); 277 if (ret == -2) { 278 printf("'%s' command timed out.\n", cmd); 279 return -2; 280 } else if (ret < 0) { 281 printf("'%s' command failed.\n", cmd); 282 return -1; 283 } 284 if (print) { 285 buf[len] = '\0'; 286 wpa_cli_msg_cb(buf, 0); 287 } 288 return 0; 289 } 290 291 292 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd) 293 { 294 return _wpa_ctrl_command(ctrl, cmd, 1); 295 } 296 297 298 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args, 299 int argc, char *argv[]) 300 { 301 char buf[4096]; 302 if (argc < min_args) { 303 printf("Invalid %s command - at least %d argument%s " 304 "required.\n", cmd, min_args, 305 min_args > 1 ? "s are" : " is"); 306 return -1; 307 } 308 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0) 309 return -1; 310 return wpa_ctrl_command(ctrl, buf); 311 } 312 313 314 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[]) 315 { 316 return wpa_ctrl_command(ctrl, "IFNAME"); 317 } 318 319 320 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) 321 { 322 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0) 323 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE"); 324 if (argc > 0 && os_strcmp(argv[0], "wps") == 0) 325 return wpa_ctrl_command(ctrl, "STATUS-WPS"); 326 if (argc > 0 && os_strcmp(argv[0], "driver") == 0) 327 return wpa_ctrl_command(ctrl, "STATUS-DRIVER"); 328 #ifdef ANDROID 329 if (argc > 0 && os_strcmp(argv[0], "no_events") == 0) 330 return wpa_ctrl_command(ctrl, "STATUS-NO_EVENTS"); 331 #endif /* ANDROID */ 332 return wpa_ctrl_command(ctrl, "STATUS"); 333 } 334 335 336 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[]) 337 { 338 return wpa_ctrl_command(ctrl, "PING"); 339 } 340 341 342 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[]) 343 { 344 return wpa_ctrl_command(ctrl, "RELOG"); 345 } 346 347 348 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[]) 349 { 350 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv); 351 } 352 353 354 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[]) 355 { 356 return wpa_ctrl_command(ctrl, "MIB"); 357 } 358 359 360 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 361 { 362 return wpa_ctrl_command(ctrl, "PMKSA"); 363 } 364 365 366 static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc, 367 char *argv[]) 368 { 369 return wpa_ctrl_command(ctrl, "PMKSA_FLUSH"); 370 } 371 372 373 #ifdef CONFIG_PMKSA_CACHE_EXTERNAL 374 375 static int wpa_cli_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 376 { 377 return wpa_cli_cmd(ctrl, "PMKSA_GET", 1, argc, argv); 378 } 379 380 381 static int wpa_cli_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, char *argv[]) 382 { 383 return wpa_cli_cmd(ctrl, "PMKSA_ADD", 8, argc, argv); 384 } 385 386 387 #ifdef CONFIG_MESH 388 389 static int wpa_cli_mesh_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, 390 char *argv[]) 391 { 392 return wpa_cli_cmd(ctrl, "MESH_PMKSA_GET", 1, argc, argv); 393 } 394 395 396 static int wpa_cli_mesh_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, 397 char *argv[]) 398 { 399 return wpa_cli_cmd(ctrl, "MESH_PMKSA_ADD", 4, argc, argv); 400 } 401 402 #endif /* CONFIG_MESH */ 403 #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ 404 405 406 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[]) 407 { 408 print_help(argc > 0 ? argv[0] : NULL); 409 return 0; 410 } 411 412 413 static char ** wpa_cli_complete_help(const char *str, int pos) 414 { 415 int arg = get_cmd_arg_num(str, pos); 416 char **res = NULL; 417 418 switch (arg) { 419 case 1: 420 res = wpa_list_cmd_list(); 421 break; 422 } 423 424 return res; 425 } 426 427 428 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[]) 429 { 430 printf("%s\n\n%s\n", wpa_cli_version, cli_full_license); 431 return 0; 432 } 433 434 435 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[]) 436 { 437 wpa_cli_quit = 1; 438 if (interactive) 439 eloop_terminate(); 440 return 0; 441 } 442 443 444 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 445 { 446 char cmd[256]; 447 int res; 448 449 if (argc == 1) { 450 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]); 451 if (os_snprintf_error(sizeof(cmd), res)) { 452 printf("Too long SET command.\n"); 453 return -1; 454 } 455 return wpa_ctrl_command(ctrl, cmd); 456 } 457 458 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv); 459 } 460 461 462 static char ** wpa_cli_complete_set(const char *str, int pos) 463 { 464 int arg = get_cmd_arg_num(str, pos); 465 const char *fields[] = { 466 /* runtime values */ 467 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod", 468 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime", 469 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout", 470 "wps_fragment_size", "wps_version_number", "ampdu", 471 "tdls_testing", "tdls_disabled", "pno", "radio_disabled", 472 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps", 473 "no_keep_alive", 474 /* global configuration parameters */ 475 #ifdef CONFIG_CTRL_IFACE 476 "ctrl_interface", "no_ctrl_interface", "ctrl_interface_group", 477 #endif /* CONFIG_CTRL_IFACE */ 478 "eapol_version", "ap_scan", "bgscan", 479 #ifdef CONFIG_MESH 480 "user_mpm", "max_peer_links", "mesh_max_inactivity", 481 "dot11RSNASAERetransPeriod", 482 #endif /* CONFIG_MESH */ 483 "disable_scan_offload", "fast_reauth", "opensc_engine_path", 484 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers", 485 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param", 486 "dot11RSNAConfigPMKLifetime", 487 "dot11RSNAConfigPMKReauthThreshold", 488 "dot11RSNAConfigSATimeout", 489 #ifndef CONFIG_NO_CONFIG_WRITE 490 "update_config", 491 #endif /* CONFIG_NO_CONFIG_WRITE */ 492 "load_dynamic_eap", 493 #ifdef CONFIG_WPS 494 "uuid", "device_name", "manufacturer", "model_name", 495 "model_number", "serial_number", "device_type", "os_version", 496 "config_methods", "wps_cred_processing", "wps_vendor_ext_m1", 497 #endif /* CONFIG_WPS */ 498 #ifdef CONFIG_P2P 499 "sec_device_type", 500 "p2p_listen_reg_class", "p2p_listen_channel", 501 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent", 502 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss", 503 "p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan", 504 "p2p_no_go_freq", "p2p_add_cli_chan", 505 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht", 506 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface", 507 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask", 508 "ip_addr_start", "ip_addr_end", 509 #endif /* CONFIG_P2P */ 510 "country", "bss_max_count", "bss_expiration_age", 511 "bss_expiration_scan_count", "filter_ssids", "filter_rssi", 512 "max_num_sta", "disassoc_low_ack", "ap_isolate", 513 #ifdef CONFIG_HS20 514 "hs20", 515 #endif /* CONFIG_HS20 */ 516 "interworking", "hessid", "access_network_type", "pbc_in_m1", 517 "go_interworking", "go_access_network_type", "go_internet", 518 "go_venue_group", "go_venue_type", 519 "autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", 520 "wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend", 521 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", 522 "sae_groups", "dtim_period", "beacon_int", 523 "ap_vendor_elements", "ignore_old_scan_res", "freq_list", 524 "scan_cur_freq", "sched_scan_interval", 525 "tdls_external_control", "osu_dir", "wowlan_triggers", 526 "p2p_search_delay", "mac_addr", "rand_addr_lifetime", 527 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan", 528 "reassoc_same_bss_optim", "wps_priority", 529 #ifdef CONFIG_TESTING_OPTIONS 530 "ignore_auth_resp", 531 #endif /* CONFIG_TESTING_OPTIONS */ 532 "relative_rssi", "relative_band_adjust", 533 }; 534 int i, num_fields = ARRAY_SIZE(fields); 535 536 if (arg == 1) { 537 char **res = os_calloc(num_fields + 1, sizeof(char *)); 538 if (res == NULL) 539 return NULL; 540 for (i = 0; i < num_fields; i++) { 541 res[i] = os_strdup(fields[i]); 542 if (res[i] == NULL) 543 return res; 544 } 545 return res; 546 } 547 548 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0) 549 return cli_txt_list_array(&bsses); 550 551 return NULL; 552 } 553 554 static int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[]) 555 { 556 return wpa_ctrl_command(ctrl, "DUMP"); 557 } 558 559 560 static int wpa_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc, 561 char *argv[]) 562 { 563 return wpa_ctrl_command(ctrl, "DRIVER_FLAGS"); 564 } 565 566 567 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 568 { 569 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv); 570 } 571 572 573 static char ** wpa_cli_complete_get(const char *str, int pos) 574 { 575 int arg = get_cmd_arg_num(str, pos); 576 const char *fields[] = { 577 #ifdef CONFIG_CTRL_IFACE 578 "ctrl_interface", "ctrl_interface_group", 579 #endif /* CONFIG_CTRL_IFACE */ 580 "eapol_version", "ap_scan", 581 #ifdef CONFIG_MESH 582 "user_mpm", "max_peer_links", "mesh_max_inactivity", 583 #endif /* CONFIG_MESH */ 584 "disable_scan_offload", "fast_reauth", "opensc_engine_path", 585 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers", 586 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param", 587 "dot11RSNAConfigPMKLifetime", 588 "dot11RSNAConfigPMKReauthThreshold", 589 "dot11RSNAConfigSATimeout", 590 #ifndef CONFIG_NO_CONFIG_WRITE 591 "update_config", 592 #endif /* CONFIG_NO_CONFIG_WRITE */ 593 #ifdef CONFIG_WPS 594 "device_name", "manufacturer", "model_name", "model_number", 595 "serial_number", "config_methods", "wps_cred_processing", 596 #endif /* CONFIG_WPS */ 597 #ifdef CONFIG_P2P 598 "p2p_listen_reg_class", "p2p_listen_channel", 599 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent", 600 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss", 601 "p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan", 602 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht", 603 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface", 604 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask", 605 "ip_addr_start", "ip_addr_end", 606 #endif /* CONFIG_P2P */ 607 "bss_max_count", "bss_expiration_age", 608 "bss_expiration_scan_count", "filter_ssids", "filter_rssi", 609 "max_num_sta", "disassoc_low_ack", "ap_isolate", 610 #ifdef CONFIG_HS20 611 "hs20", 612 #endif /* CONFIG_HS20 */ 613 "interworking", "access_network_type", "pbc_in_m1", "autoscan", 614 "go_interworking", "go_access_network_type", "go_internet", 615 "go_venue_group", "go_venue_type", 616 "wps_nfc_dev_pw_id", "ext_password_backend", 617 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", 618 "dtim_period", "beacon_int", "ignore_old_scan_res", 619 "scan_cur_freq", "sched_scan_interval", 620 "sched_scan_start_delay", 621 "tdls_external_control", "osu_dir", "wowlan_triggers", 622 "p2p_search_delay", "mac_addr", "rand_addr_lifetime", 623 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan", 624 "reassoc_same_bss_optim" 625 }; 626 int i, num_fields = ARRAY_SIZE(fields); 627 628 if (arg == 1) { 629 char **res = os_calloc(num_fields + 1, sizeof(char *)); 630 if (res == NULL) 631 return NULL; 632 for (i = 0; i < num_fields; i++) { 633 res[i] = os_strdup(fields[i]); 634 if (res[i] == NULL) 635 return res; 636 } 637 return res; 638 } 639 640 return NULL; 641 } 642 643 644 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[]) 645 { 646 return wpa_ctrl_command(ctrl, "LOGOFF"); 647 } 648 649 650 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[]) 651 { 652 return wpa_ctrl_command(ctrl, "LOGON"); 653 } 654 655 656 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc, 657 char *argv[]) 658 { 659 return wpa_ctrl_command(ctrl, "REASSOCIATE"); 660 } 661 662 663 static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[]) 664 { 665 return wpa_ctrl_command(ctrl, "REATTACH"); 666 } 667 668 669 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc, 670 char *argv[]) 671 { 672 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv); 673 } 674 675 676 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 677 { 678 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv); 679 } 680 681 682 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc, 683 char *argv[]) 684 { 685 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv); 686 } 687 688 689 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc, 690 char *argv[]) 691 { 692 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv); 693 } 694 695 696 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc, 697 char *argv[]) 698 { 699 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv); 700 } 701 702 703 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 704 { 705 char cmd[256]; 706 int res; 707 708 if (argc < 1) 709 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0"); 710 else 711 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]); 712 if (os_snprintf_error(sizeof(cmd), res)) { 713 printf("Too long BSS_FLUSH command.\n"); 714 return -1; 715 } 716 return wpa_ctrl_command(ctrl, cmd); 717 } 718 719 720 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[]) 721 { 722 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv); 723 } 724 725 726 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 727 { 728 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv); 729 } 730 731 732 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 733 { 734 if (argc == 0) { 735 printf("Invalid WPS_PIN command: need one or two arguments:\n" 736 "- BSSID: use 'any' to select any\n" 737 "- PIN: optional, used only with devices that have no " 738 "display\n"); 739 return -1; 740 } 741 742 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv); 743 } 744 745 746 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc, 747 char *argv[]) 748 { 749 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv); 750 } 751 752 753 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc, 754 char *argv[]) 755 { 756 return wpa_ctrl_command(ctrl, "WPS_CANCEL"); 757 } 758 759 760 #ifdef CONFIG_WPS_NFC 761 762 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 763 { 764 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv); 765 } 766 767 768 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 769 char *argv[]) 770 { 771 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv); 772 } 773 774 775 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc, 776 char *argv[]) 777 { 778 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv); 779 } 780 781 782 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc, 783 char *argv[]) 784 { 785 int ret; 786 char *buf; 787 size_t buflen; 788 789 if (argc != 1) { 790 printf("Invalid 'wps_nfc_tag_read' command - one argument " 791 "is required.\n"); 792 return -1; 793 } 794 795 buflen = 18 + os_strlen(argv[0]); 796 buf = os_malloc(buflen); 797 if (buf == NULL) 798 return -1; 799 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]); 800 801 ret = wpa_ctrl_command(ctrl, buf); 802 os_free(buf); 803 804 return ret; 805 } 806 807 808 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc, 809 char *argv[]) 810 { 811 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv); 812 } 813 814 815 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc, 816 char *argv[]) 817 { 818 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv); 819 } 820 821 822 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc, 823 char *argv[]) 824 { 825 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv); 826 } 827 828 #endif /* CONFIG_WPS_NFC */ 829 830 831 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[]) 832 { 833 char cmd[256]; 834 int res; 835 836 if (argc == 2) 837 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", 838 argv[0], argv[1]); 839 else if (argc == 5 || argc == 6) { 840 char ssid_hex[2 * SSID_MAX_LEN + 1]; 841 char key_hex[2 * 64 + 1]; 842 int i; 843 844 ssid_hex[0] = '\0'; 845 for (i = 0; i < SSID_MAX_LEN; i++) { 846 if (argv[2][i] == '\0') 847 break; 848 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 849 } 850 851 key_hex[0] = '\0'; 852 if (argc == 6) { 853 for (i = 0; i < 64; i++) { 854 if (argv[5][i] == '\0') 855 break; 856 os_snprintf(&key_hex[i * 2], 3, "%02x", 857 argv[5][i]); 858 } 859 } 860 861 res = os_snprintf(cmd, sizeof(cmd), 862 "WPS_REG %s %s %s %s %s %s", 863 argv[0], argv[1], ssid_hex, argv[3], argv[4], 864 key_hex); 865 } else { 866 printf("Invalid WPS_REG command: need two arguments:\n" 867 "- BSSID of the target AP\n" 868 "- AP PIN\n"); 869 printf("Alternatively, six arguments can be used to " 870 "reconfigure the AP:\n" 871 "- BSSID of the target AP\n" 872 "- AP PIN\n" 873 "- new SSID\n" 874 "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 875 "- new encr (NONE, WEP, TKIP, CCMP)\n" 876 "- new key\n"); 877 return -1; 878 } 879 880 if (os_snprintf_error(sizeof(cmd), res)) { 881 printf("Too long WPS_REG command.\n"); 882 return -1; 883 } 884 return wpa_ctrl_command(ctrl, cmd); 885 } 886 887 888 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc, 889 char *argv[]) 890 { 891 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv); 892 } 893 894 895 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc, 896 char *argv[]) 897 { 898 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv); 899 } 900 901 902 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc, 903 char *argv[]) 904 { 905 return wpa_ctrl_command(ctrl, "WPS_ER_STOP"); 906 907 } 908 909 910 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc, 911 char *argv[]) 912 { 913 if (argc < 2) { 914 printf("Invalid WPS_ER_PIN command: need at least two " 915 "arguments:\n" 916 "- UUID: use 'any' to select any\n" 917 "- PIN: Enrollee PIN\n" 918 "optional: - Enrollee MAC address\n"); 919 return -1; 920 } 921 922 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv); 923 } 924 925 926 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc, 927 char *argv[]) 928 { 929 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv); 930 } 931 932 933 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc, 934 char *argv[]) 935 { 936 if (argc != 2) { 937 printf("Invalid WPS_ER_LEARN command: need two arguments:\n" 938 "- UUID: specify which AP to use\n" 939 "- PIN: AP PIN\n"); 940 return -1; 941 } 942 943 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv); 944 } 945 946 947 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc, 948 char *argv[]) 949 { 950 if (argc != 2) { 951 printf("Invalid WPS_ER_SET_CONFIG command: need two " 952 "arguments:\n" 953 "- UUID: specify which AP to use\n" 954 "- Network configuration id\n"); 955 return -1; 956 } 957 958 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv); 959 } 960 961 962 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc, 963 char *argv[]) 964 { 965 char cmd[256]; 966 int res; 967 968 if (argc == 5 || argc == 6) { 969 char ssid_hex[2 * SSID_MAX_LEN + 1]; 970 char key_hex[2 * 64 + 1]; 971 int i; 972 973 ssid_hex[0] = '\0'; 974 for (i = 0; i < SSID_MAX_LEN; i++) { 975 if (argv[2][i] == '\0') 976 break; 977 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 978 } 979 980 key_hex[0] = '\0'; 981 if (argc == 6) { 982 for (i = 0; i < 64; i++) { 983 if (argv[5][i] == '\0') 984 break; 985 os_snprintf(&key_hex[i * 2], 3, "%02x", 986 argv[5][i]); 987 } 988 } 989 990 res = os_snprintf(cmd, sizeof(cmd), 991 "WPS_ER_CONFIG %s %s %s %s %s %s", 992 argv[0], argv[1], ssid_hex, argv[3], argv[4], 993 key_hex); 994 } else { 995 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n" 996 "- AP UUID\n" 997 "- AP PIN\n" 998 "- new SSID\n" 999 "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 1000 "- new encr (NONE, WEP, TKIP, CCMP)\n" 1001 "- new key\n"); 1002 return -1; 1003 } 1004 1005 if (os_snprintf_error(sizeof(cmd), res)) { 1006 printf("Too long WPS_ER_CONFIG command.\n"); 1007 return -1; 1008 } 1009 return wpa_ctrl_command(ctrl, cmd); 1010 } 1011 1012 1013 #ifdef CONFIG_WPS_NFC 1014 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 1015 char *argv[]) 1016 { 1017 if (argc != 2) { 1018 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two " 1019 "arguments:\n" 1020 "- WPS/NDEF: token format\n" 1021 "- UUID: specify which AP to use\n"); 1022 return -1; 1023 } 1024 1025 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv); 1026 } 1027 #endif /* CONFIG_WPS_NFC */ 1028 1029 1030 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1031 { 1032 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv); 1033 } 1034 1035 1036 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1037 { 1038 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv); 1039 } 1040 1041 1042 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1043 { 1044 char cmd[256], *pos, *end; 1045 int i, ret; 1046 1047 if (argc < 2) { 1048 printf("Invalid IDENTITY command: needs two arguments " 1049 "(network id and identity)\n"); 1050 return -1; 1051 } 1052 1053 end = cmd + sizeof(cmd); 1054 pos = cmd; 1055 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s", 1056 argv[0], argv[1]); 1057 if (os_snprintf_error(end - pos, ret)) { 1058 printf("Too long IDENTITY command.\n"); 1059 return -1; 1060 } 1061 pos += ret; 1062 for (i = 2; i < argc; i++) { 1063 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1064 if (os_snprintf_error(end - pos, ret)) { 1065 printf("Too long IDENTITY command.\n"); 1066 return -1; 1067 } 1068 pos += ret; 1069 } 1070 1071 return wpa_ctrl_command(ctrl, cmd); 1072 } 1073 1074 1075 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1076 { 1077 char cmd[256], *pos, *end; 1078 int i, ret; 1079 1080 if (argc < 2) { 1081 printf("Invalid PASSWORD command: needs two arguments " 1082 "(network id and password)\n"); 1083 return -1; 1084 } 1085 1086 end = cmd + sizeof(cmd); 1087 pos = cmd; 1088 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s", 1089 argv[0], argv[1]); 1090 if (os_snprintf_error(end - pos, ret)) { 1091 printf("Too long PASSWORD command.\n"); 1092 return -1; 1093 } 1094 pos += ret; 1095 for (i = 2; i < argc; i++) { 1096 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1097 if (os_snprintf_error(end - pos, ret)) { 1098 printf("Too long PASSWORD command.\n"); 1099 return -1; 1100 } 1101 pos += ret; 1102 } 1103 1104 return wpa_ctrl_command(ctrl, cmd); 1105 } 1106 1107 1108 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc, 1109 char *argv[]) 1110 { 1111 char cmd[256], *pos, *end; 1112 int i, ret; 1113 1114 if (argc < 2) { 1115 printf("Invalid NEW_PASSWORD command: needs two arguments " 1116 "(network id and password)\n"); 1117 return -1; 1118 } 1119 1120 end = cmd + sizeof(cmd); 1121 pos = cmd; 1122 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s", 1123 argv[0], argv[1]); 1124 if (os_snprintf_error(end - pos, ret)) { 1125 printf("Too long NEW_PASSWORD command.\n"); 1126 return -1; 1127 } 1128 pos += ret; 1129 for (i = 2; i < argc; i++) { 1130 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1131 if (os_snprintf_error(end - pos, ret)) { 1132 printf("Too long NEW_PASSWORD command.\n"); 1133 return -1; 1134 } 1135 pos += ret; 1136 } 1137 1138 return wpa_ctrl_command(ctrl, cmd); 1139 } 1140 1141 1142 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1143 { 1144 char cmd[256], *pos, *end; 1145 int i, ret; 1146 1147 if (argc < 2) { 1148 printf("Invalid PIN command: needs two arguments " 1149 "(network id and pin)\n"); 1150 return -1; 1151 } 1152 1153 end = cmd + sizeof(cmd); 1154 pos = cmd; 1155 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s", 1156 argv[0], argv[1]); 1157 if (os_snprintf_error(end - pos, ret)) { 1158 printf("Too long PIN command.\n"); 1159 return -1; 1160 } 1161 pos += ret; 1162 for (i = 2; i < argc; i++) { 1163 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1164 if (os_snprintf_error(end - pos, ret)) { 1165 printf("Too long PIN command.\n"); 1166 return -1; 1167 } 1168 pos += ret; 1169 } 1170 return wpa_ctrl_command(ctrl, cmd); 1171 } 1172 1173 1174 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1175 { 1176 char cmd[256], *pos, *end; 1177 int i, ret; 1178 1179 if (argc < 2) { 1180 printf("Invalid OTP command: needs two arguments (network " 1181 "id and password)\n"); 1182 return -1; 1183 } 1184 1185 end = cmd + sizeof(cmd); 1186 pos = cmd; 1187 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s", 1188 argv[0], argv[1]); 1189 if (os_snprintf_error(end - pos, ret)) { 1190 printf("Too long OTP command.\n"); 1191 return -1; 1192 } 1193 pos += ret; 1194 for (i = 2; i < argc; i++) { 1195 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1196 if (os_snprintf_error(end - pos, ret)) { 1197 printf("Too long OTP command.\n"); 1198 return -1; 1199 } 1200 pos += ret; 1201 } 1202 1203 return wpa_ctrl_command(ctrl, cmd); 1204 } 1205 1206 1207 static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1208 { 1209 char cmd[256], *pos, *end; 1210 int i, ret; 1211 1212 if (argc < 2) { 1213 printf("Invalid SIM command: needs two arguments " 1214 "(network id and SIM operation response)\n"); 1215 return -1; 1216 } 1217 1218 end = cmd + sizeof(cmd); 1219 pos = cmd; 1220 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s", 1221 argv[0], argv[1]); 1222 if (os_snprintf_error(end - pos, ret)) { 1223 printf("Too long SIM command.\n"); 1224 return -1; 1225 } 1226 pos += ret; 1227 for (i = 2; i < argc; i++) { 1228 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1229 if (os_snprintf_error(end - pos, ret)) { 1230 printf("Too long SIM command.\n"); 1231 return -1; 1232 } 1233 pos += ret; 1234 } 1235 return wpa_ctrl_command(ctrl, cmd); 1236 } 1237 1238 1239 static int wpa_cli_cmd_psk_passphrase(struct wpa_ctrl *ctrl, int argc, 1240 char *argv[]) 1241 { 1242 char cmd[256], *pos, *end; 1243 int i, ret; 1244 1245 if (argc < 2) { 1246 printf("Invalid PSK_PASSPHRASE command: needs two arguments (network id and PSK/passphrase)\n"); 1247 return -1; 1248 } 1249 1250 end = cmd + sizeof(cmd); 1251 pos = cmd; 1252 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PSK_PASSPHRASE-%s:%s", 1253 argv[0], argv[1]); 1254 if (os_snprintf_error(end - pos, ret)) { 1255 printf("Too long PSK_PASSPHRASE command.\n"); 1256 return -1; 1257 } 1258 pos += ret; 1259 for (i = 2; i < argc; i++) { 1260 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1261 if (os_snprintf_error(end - pos, ret)) { 1262 printf("Too long PSK_PASSPHRASE command.\n"); 1263 return -1; 1264 } 1265 pos += ret; 1266 } 1267 1268 return wpa_ctrl_command(ctrl, cmd); 1269 } 1270 1271 1272 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc, 1273 char *argv[]) 1274 { 1275 char cmd[256], *pos, *end; 1276 int i, ret; 1277 1278 if (argc < 2) { 1279 printf("Invalid PASSPHRASE command: needs two arguments " 1280 "(network id and passphrase)\n"); 1281 return -1; 1282 } 1283 1284 end = cmd + sizeof(cmd); 1285 pos = cmd; 1286 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s", 1287 argv[0], argv[1]); 1288 if (os_snprintf_error(end - pos, ret)) { 1289 printf("Too long PASSPHRASE command.\n"); 1290 return -1; 1291 } 1292 pos += ret; 1293 for (i = 2; i < argc; i++) { 1294 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1295 if (os_snprintf_error(end - pos, ret)) { 1296 printf("Too long PASSPHRASE command.\n"); 1297 return -1; 1298 } 1299 pos += ret; 1300 } 1301 1302 return wpa_ctrl_command(ctrl, cmd); 1303 } 1304 1305 1306 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1307 { 1308 if (argc < 2) { 1309 printf("Invalid BSSID command: needs two arguments (network " 1310 "id and BSSID)\n"); 1311 return -1; 1312 } 1313 1314 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv); 1315 } 1316 1317 1318 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1319 { 1320 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv); 1321 } 1322 1323 1324 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1325 { 1326 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv); 1327 } 1328 1329 1330 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc, 1331 char *argv[]) 1332 { 1333 return wpa_ctrl_command(ctrl, "LIST_NETWORKS"); 1334 } 1335 1336 1337 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc, 1338 char *argv[]) 1339 { 1340 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv); 1341 } 1342 1343 1344 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc, 1345 char *argv[]) 1346 { 1347 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv); 1348 } 1349 1350 1351 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc, 1352 char *argv[]) 1353 { 1354 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv); 1355 } 1356 1357 1358 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc, 1359 char *argv[]) 1360 { 1361 int res = wpa_ctrl_command(ctrl, "ADD_NETWORK"); 1362 if (interactive) 1363 update_networks(ctrl); 1364 return res; 1365 } 1366 1367 1368 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc, 1369 char *argv[]) 1370 { 1371 int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv); 1372 if (interactive) 1373 update_networks(ctrl); 1374 return res; 1375 } 1376 1377 1378 static void wpa_cli_show_network_variables(void) 1379 { 1380 printf("set_network variables:\n" 1381 " ssid (network name, SSID)\n" 1382 " psk (WPA passphrase or pre-shared key)\n" 1383 " key_mgmt (key management protocol)\n" 1384 " identity (EAP identity)\n" 1385 " password (EAP password)\n" 1386 " ...\n" 1387 "\n" 1388 "Note: Values are entered in the same format as the " 1389 "configuration file is using,\n" 1390 "i.e., strings values need to be inside double quotation " 1391 "marks.\n" 1392 "For example: set_network 1 ssid \"network name\"\n" 1393 "\n" 1394 "Please see wpa_supplicant.conf documentation for full list " 1395 "of\navailable variables.\n"); 1396 } 1397 1398 1399 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc, 1400 char *argv[]) 1401 { 1402 if (argc == 0) { 1403 wpa_cli_show_network_variables(); 1404 return 0; 1405 } 1406 1407 if (argc < 3) { 1408 printf("Invalid SET_NETWORK command: needs three arguments\n" 1409 "(network id, variable name, and value)\n"); 1410 return -1; 1411 } 1412 1413 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv); 1414 } 1415 1416 1417 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc, 1418 char *argv[]) 1419 { 1420 if (argc == 0) { 1421 wpa_cli_show_network_variables(); 1422 return 0; 1423 } 1424 1425 if (argc != 2) { 1426 printf("Invalid GET_NETWORK command: needs two arguments\n" 1427 "(network id and variable name)\n"); 1428 return -1; 1429 } 1430 1431 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv); 1432 } 1433 1434 1435 static const char *network_fields[] = { 1436 "ssid", "scan_ssid", "bssid", "bssid_blacklist", 1437 "bssid_whitelist", "psk", "proto", "key_mgmt", 1438 "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq", 1439 "freq_list", "max_oper_chwidth", "ht40", "vht", "vht_center_freq1", 1440 "vht_center_freq2", "ht", 1441 #ifdef IEEE8021X_EAPOL 1442 "eap", "identity", "anonymous_identity", "password", "ca_cert", 1443 "ca_path", "client_cert", "private_key", "private_key_passwd", 1444 "dh_file", "subject_match", "altsubject_match", 1445 "check_cert_subject", 1446 "domain_suffix_match", "domain_match", "ca_cert2", "ca_path2", 1447 "client_cert2", "private_key2", "private_key2_passwd", 1448 "dh_file2", "subject_match2", "altsubject_match2", 1449 "check_cert_subject2", 1450 "domain_suffix_match2", "domain_match2", "phase1", "phase2", 1451 "pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id", 1452 "pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id", 1453 "engine", "engine2", "eapol_flags", "sim_num", 1454 "openssl_ciphers", "erp", 1455 #endif /* IEEE8021X_EAPOL */ 1456 "wep_key0", "wep_key1", "wep_key2", "wep_key3", 1457 "wep_tx_keyidx", "priority", 1458 #ifdef IEEE8021X_EAPOL 1459 "eap_workaround", "pac_file", "fragment_size", "ocsp", 1460 #endif /* IEEE8021X_EAPOL */ 1461 #ifdef CONFIG_MESH 1462 "mode", "no_auto_peer", "mesh_rssi_threshold", 1463 #else /* CONFIG_MESH */ 1464 "mode", 1465 #endif /* CONFIG_MESH */ 1466 "proactive_key_caching", "disabled", "id_str", 1467 #ifdef CONFIG_IEEE80211W 1468 "ieee80211w", 1469 #endif /* CONFIG_IEEE80211W */ 1470 "mixed_cell", "frequency", "fixed_freq", 1471 #ifdef CONFIG_MESH 1472 "mesh_basic_rates", "dot11MeshMaxRetries", 1473 "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout", 1474 "dot11MeshHoldingTimeout", 1475 #endif /* CONFIG_MESH */ 1476 "wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid", 1477 #ifdef CONFIG_P2P 1478 "go_p2p_dev_addr", "p2p_client_list", "psk_list", 1479 #endif /* CONFIG_P2P */ 1480 #ifdef CONFIG_HT_OVERRIDES 1481 "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc", 1482 "ht40_intolerant", "disable_max_amsdu", "ampdu_factor", 1483 "ampdu_density", "ht_mcs", "rx_stbc", "tx_stbc", 1484 #endif /* CONFIG_HT_OVERRIDES */ 1485 #ifdef CONFIG_VHT_OVERRIDES 1486 "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1", 1487 "vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4", 1488 "vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7", 1489 "vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2", 1490 "vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5", 1491 "vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8", 1492 #endif /* CONFIG_VHT_OVERRIDES */ 1493 "ap_max_inactivity", "dtim_period", "beacon_int", 1494 #ifdef CONFIG_MACSEC 1495 "macsec_policy", 1496 "macsec_integ_only", 1497 "macsec_replay_protect", 1498 "macsec_replay_window", 1499 "macsec_port", 1500 "mka_priority", 1501 #endif /* CONFIG_MACSEC */ 1502 #ifdef CONFIG_HS20 1503 "update_identifier", 1504 #endif /* CONFIG_HS20 */ 1505 "mac_addr", "pbss", "wps_disabled" 1506 }; 1507 1508 1509 static char ** wpa_cli_complete_network(const char *str, int pos) 1510 { 1511 int arg = get_cmd_arg_num(str, pos); 1512 int i, num_fields = ARRAY_SIZE(network_fields); 1513 char **res = NULL; 1514 1515 switch (arg) { 1516 case 1: 1517 res = cli_txt_list_array(&networks); 1518 break; 1519 case 2: 1520 res = os_calloc(num_fields + 1, sizeof(char *)); 1521 if (res == NULL) 1522 return NULL; 1523 for (i = 0; i < num_fields; i++) { 1524 res[i] = os_strdup(network_fields[i]); 1525 if (res[i] == NULL) 1526 break; 1527 } 1528 } 1529 return res; 1530 } 1531 1532 1533 static char ** wpa_cli_complete_network_id(const char *str, int pos) 1534 { 1535 int arg = get_cmd_arg_num(str, pos); 1536 if (arg == 1) 1537 return cli_txt_list_array(&networks); 1538 return NULL; 1539 } 1540 1541 1542 static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc, 1543 char *argv[]) 1544 { 1545 if (argc == 0) { 1546 wpa_cli_show_network_variables(); 1547 return 0; 1548 } 1549 1550 if (argc < 3) { 1551 printf("Invalid DUP_NETWORK command: needs three arguments\n" 1552 "(src netid, dest netid, and variable name)\n"); 1553 return -1; 1554 } 1555 1556 return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv); 1557 } 1558 1559 1560 static char ** wpa_cli_complete_dup_network(const char *str, int pos) 1561 { 1562 int arg = get_cmd_arg_num(str, pos); 1563 int i, num_fields = ARRAY_SIZE(network_fields); 1564 char **res = NULL; 1565 1566 switch (arg) { 1567 case 1: 1568 case 2: 1569 res = cli_txt_list_array(&networks); 1570 break; 1571 case 3: 1572 res = os_calloc(num_fields + 1, sizeof(char *)); 1573 if (res == NULL) 1574 return NULL; 1575 for (i = 0; i < num_fields; i++) { 1576 res[i] = os_strdup(network_fields[i]); 1577 if (res[i] == NULL) 1578 break; 1579 } 1580 } 1581 return res; 1582 } 1583 1584 1585 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc, 1586 char *argv[]) 1587 { 1588 return wpa_ctrl_command(ctrl, "LIST_CREDS"); 1589 } 1590 1591 1592 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1593 { 1594 int res = wpa_ctrl_command(ctrl, "ADD_CRED"); 1595 if (interactive) 1596 update_creds(ctrl); 1597 return res; 1598 } 1599 1600 1601 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc, 1602 char *argv[]) 1603 { 1604 int res = wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv); 1605 if (interactive) 1606 update_creds(ctrl); 1607 return res; 1608 } 1609 1610 1611 static const char * const cred_fields[] = { 1612 "temporary", "priority", "sp_priority", "pcsc", "eap", 1613 "update_identifier", "min_dl_bandwidth_home", "min_ul_bandwidth_home", 1614 "min_dl_bandwidth_roaming", "min_ul_bandwidth_roaming", "max_bss_load", 1615 "req_conn_capab", "ocsp", "sim_num", "realm", "username", "password", 1616 "ca_cert", "client_cert", "private_key", "private_key_passwd", "imsi", 1617 "milenage", "domain_suffix_match", "domain", "phase1", "phase2", 1618 "roaming_consortium", "required_roaming_consortium", "excluded_ssid", 1619 "roaming_partner", "provisioning_sp" 1620 }; 1621 1622 1623 static char ** wpa_cli_complete_cred(const char *str, int pos) 1624 { 1625 int arg = get_cmd_arg_num(str, pos); 1626 int i, num_fields = ARRAY_SIZE(cred_fields); 1627 char **res = NULL; 1628 1629 switch (arg) { 1630 case 1: 1631 res = cli_txt_list_array(&creds); 1632 break; 1633 case 2: 1634 res = os_calloc(num_fields + 1, sizeof(char *)); 1635 if (res == NULL) 1636 return NULL; 1637 for (i = 0; i < num_fields; i++) { 1638 res[i] = os_strdup(cred_fields[i]); 1639 if (res[i] == NULL) 1640 break; 1641 } 1642 } 1643 return res; 1644 } 1645 1646 1647 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1648 { 1649 if (argc != 3) { 1650 printf("Invalid SET_CRED command: needs three arguments\n" 1651 "(cred id, variable name, and value)\n"); 1652 return -1; 1653 } 1654 1655 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv); 1656 } 1657 1658 1659 static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1660 { 1661 if (argc != 2) { 1662 printf("Invalid GET_CRED command: needs two arguments\n" 1663 "(cred id, variable name)\n"); 1664 return -1; 1665 } 1666 1667 return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv); 1668 } 1669 1670 1671 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc, 1672 char *argv[]) 1673 { 1674 return wpa_ctrl_command(ctrl, "DISCONNECT"); 1675 } 1676 1677 1678 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc, 1679 char *argv[]) 1680 { 1681 return wpa_ctrl_command(ctrl, "RECONNECT"); 1682 } 1683 1684 1685 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc, 1686 char *argv[]) 1687 { 1688 return wpa_ctrl_command(ctrl, "SAVE_CONFIG"); 1689 } 1690 1691 1692 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1693 { 1694 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv); 1695 } 1696 1697 1698 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc, 1699 char *argv[]) 1700 { 1701 return wpa_ctrl_command(ctrl, "SCAN_RESULTS"); 1702 } 1703 1704 1705 static int wpa_cli_cmd_abort_scan(struct wpa_ctrl *ctrl, int argc, 1706 char *argv[]) 1707 { 1708 return wpa_ctrl_command(ctrl, "ABORT_SCAN"); 1709 } 1710 1711 1712 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1713 { 1714 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv); 1715 } 1716 1717 1718 static char ** wpa_cli_complete_bss(const char *str, int pos) 1719 { 1720 int arg = get_cmd_arg_num(str, pos); 1721 char **res = NULL; 1722 1723 switch (arg) { 1724 case 1: 1725 res = cli_txt_list_array(&bsses); 1726 break; 1727 } 1728 1729 return res; 1730 } 1731 1732 1733 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc, 1734 char *argv[]) 1735 { 1736 if (argc < 1 || argc > 2) { 1737 printf("Invalid GET_CAPABILITY command: need either one or " 1738 "two arguments\n"); 1739 return -1; 1740 } 1741 1742 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) { 1743 printf("Invalid GET_CAPABILITY command: second argument, " 1744 "if any, must be 'strict'\n"); 1745 return -1; 1746 } 1747 1748 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv); 1749 } 1750 1751 1752 static char ** wpa_cli_complete_get_capability(const char *str, int pos) 1753 { 1754 int arg = get_cmd_arg_num(str, pos); 1755 const char *fields[] = { 1756 "eap", "pairwise", "group", "group_mgmt", "key_mgmt", 1757 "proto", "auth_alg", "modes", "channels", "freq", 1758 #ifdef CONFIG_TDLS 1759 "tdls", 1760 #endif /* CONFIG_TDLS */ 1761 #ifdef CONFIG_ERP 1762 "erp", 1763 #endif /* CONFIG_ERP */ 1764 #ifdef CONFIG_FIPS 1765 "fips", 1766 #endif /* CONFIG_FIPS */ 1767 #ifdef CONFIG_ACS 1768 "acs", 1769 #endif /* CONFIG_ACS */ 1770 }; 1771 int i, num_fields = ARRAY_SIZE(fields); 1772 char **res = NULL; 1773 1774 if (arg == 1) { 1775 res = os_calloc(num_fields + 1, sizeof(char *)); 1776 if (res == NULL) 1777 return NULL; 1778 for (i = 0; i < num_fields; i++) { 1779 res[i] = os_strdup(fields[i]); 1780 if (res[i] == NULL) 1781 return res; 1782 } 1783 } 1784 if (arg == 2) { 1785 res = os_calloc(1 + 1, sizeof(char *)); 1786 if (res == NULL) 1787 return NULL; 1788 res[0] = os_strdup("strict"); 1789 } 1790 return res; 1791 } 1792 1793 1794 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl) 1795 { 1796 printf("Available interfaces:\n"); 1797 return wpa_ctrl_command(ctrl, "INTERFACES"); 1798 } 1799 1800 1801 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1802 { 1803 if (argc < 1) { 1804 wpa_cli_list_interfaces(ctrl); 1805 return 0; 1806 } 1807 1808 wpa_cli_close_connection(); 1809 os_free(ctrl_ifname); 1810 ctrl_ifname = os_strdup(argv[0]); 1811 if (!ctrl_ifname) { 1812 printf("Failed to allocate memory\n"); 1813 return 0; 1814 } 1815 1816 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) { 1817 printf("Connected to interface '%s.\n", ctrl_ifname); 1818 } else { 1819 printf("Could not connect to interface '%s' - re-trying\n", 1820 ctrl_ifname); 1821 } 1822 return 0; 1823 } 1824 1825 1826 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc, 1827 char *argv[]) 1828 { 1829 return wpa_ctrl_command(ctrl, "RECONFIGURE"); 1830 } 1831 1832 1833 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc, 1834 char *argv[]) 1835 { 1836 return wpa_ctrl_command(ctrl, "TERMINATE"); 1837 } 1838 1839 1840 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc, 1841 char *argv[]) 1842 { 1843 char cmd[256]; 1844 int res; 1845 1846 if (argc < 1) { 1847 printf("Invalid INTERFACE_ADD command: needs at least one " 1848 "argument (interface name)\n" 1849 "All arguments: ifname confname driver ctrl_interface " 1850 "driver_param bridge_name [create]\n"); 1851 return -1; 1852 } 1853 1854 /* 1855 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB 1856 * <driver_param>TAB<bridge_name>[TAB<create>[TAB<type>]] 1857 */ 1858 res = os_snprintf(cmd, sizeof(cmd), 1859 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s", 1860 argv[0], 1861 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "", 1862 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "", 1863 argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "", 1864 argc > 7 ? argv[7] : ""); 1865 if (os_snprintf_error(sizeof(cmd), res)) 1866 return -1; 1867 cmd[sizeof(cmd) - 1] = '\0'; 1868 return wpa_ctrl_command(ctrl, cmd); 1869 } 1870 1871 1872 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc, 1873 char *argv[]) 1874 { 1875 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv); 1876 } 1877 1878 1879 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc, 1880 char *argv[]) 1881 { 1882 return wpa_ctrl_command(ctrl, "INTERFACE_LIST"); 1883 } 1884 1885 1886 #ifdef CONFIG_AP 1887 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1888 { 1889 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv); 1890 } 1891 1892 1893 static char ** wpa_cli_complete_sta(const char *str, int pos) 1894 { 1895 int arg = get_cmd_arg_num(str, pos); 1896 char **res = NULL; 1897 1898 switch (arg) { 1899 case 1: 1900 res = cli_txt_list_array(&stations); 1901 break; 1902 } 1903 1904 return res; 1905 } 1906 1907 1908 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd, 1909 char *addr, size_t addr_len, int print) 1910 { 1911 char buf[4096], *pos; 1912 size_t len; 1913 int ret; 1914 1915 if (ctrl_conn == NULL) { 1916 printf("Not connected to hostapd - command dropped.\n"); 1917 return -1; 1918 } 1919 if (ifname_prefix) { 1920 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s", 1921 ifname_prefix, cmd); 1922 buf[sizeof(buf) - 1] = '\0'; 1923 cmd = buf; 1924 } 1925 len = sizeof(buf) - 1; 1926 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 1927 wpa_cli_msg_cb); 1928 if (ret == -2) { 1929 printf("'%s' command timed out.\n", cmd); 1930 return -2; 1931 } else if (ret < 0) { 1932 printf("'%s' command failed.\n", cmd); 1933 return -1; 1934 } 1935 1936 buf[len] = '\0'; 1937 if (os_memcmp(buf, "FAIL", 4) == 0 || 1938 os_memcmp(buf, "UNKNOWN COMMAND", 15) == 0) 1939 return -1; 1940 if (print) 1941 printf("%s", buf); 1942 1943 pos = buf; 1944 while (*pos != '\0' && *pos != '\n') 1945 pos++; 1946 *pos = '\0'; 1947 os_strlcpy(addr, buf, addr_len); 1948 return 0; 1949 } 1950 1951 1952 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1953 { 1954 char addr[32], cmd[64]; 1955 1956 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 1)) 1957 return 0; 1958 do { 1959 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 1960 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 1) == 0); 1961 1962 return -1; 1963 } 1964 1965 1966 static int wpa_cli_cmd_list_sta(struct wpa_ctrl *ctrl, int argc, 1967 char *argv[]) 1968 { 1969 char addr[32], cmd[64]; 1970 1971 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) 1972 return 0; 1973 do { 1974 if (os_strcmp(addr, "") != 0) 1975 printf("%s\n", addr); 1976 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 1977 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); 1978 1979 return 0; 1980 } 1981 1982 1983 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc, 1984 char *argv[]) 1985 { 1986 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv); 1987 } 1988 1989 1990 static char ** wpa_cli_complete_deauthenticate(const char *str, int pos) 1991 { 1992 int arg = get_cmd_arg_num(str, pos); 1993 char **res = NULL; 1994 1995 switch (arg) { 1996 case 1: 1997 res = cli_txt_list_array(&stations); 1998 break; 1999 } 2000 2001 return res; 2002 } 2003 2004 2005 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, 2006 char *argv[]) 2007 { 2008 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv); 2009 } 2010 2011 2012 static char ** wpa_cli_complete_disassociate(const char *str, int pos) 2013 { 2014 int arg = get_cmd_arg_num(str, pos); 2015 char **res = NULL; 2016 2017 switch (arg) { 2018 case 1: 2019 res = cli_txt_list_array(&stations); 2020 break; 2021 } 2022 2023 return res; 2024 } 2025 2026 2027 static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc, 2028 char *argv[]) 2029 { 2030 return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv); 2031 } 2032 2033 #endif /* CONFIG_AP */ 2034 2035 2036 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2037 { 2038 return wpa_ctrl_command(ctrl, "SUSPEND"); 2039 } 2040 2041 2042 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2043 { 2044 return wpa_ctrl_command(ctrl, "RESUME"); 2045 } 2046 2047 2048 #ifdef CONFIG_TESTING_OPTIONS 2049 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2050 { 2051 return wpa_ctrl_command(ctrl, "DROP_SA"); 2052 } 2053 #endif /* CONFIG_TESTING_OPTIONS */ 2054 2055 2056 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2057 { 2058 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv); 2059 } 2060 2061 2062 #ifdef CONFIG_MESH 2063 2064 static int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc, 2065 char *argv[]) 2066 { 2067 return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv); 2068 } 2069 2070 2071 static int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc, 2072 char *argv[]) 2073 { 2074 return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv); 2075 } 2076 2077 2078 static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc, 2079 char *argv[]) 2080 { 2081 return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv); 2082 } 2083 2084 2085 static int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc, 2086 char *argv[]) 2087 { 2088 return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv); 2089 } 2090 2091 2092 static int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc, 2093 char *argv[]) 2094 { 2095 return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv); 2096 } 2097 2098 2099 static int wpa_cli_cmd_mesh_link_probe(struct wpa_ctrl *ctrl, int argc, 2100 char *argv[]) 2101 { 2102 return wpa_cli_cmd(ctrl, "MESH_LINK_PROBE", 1, argc, argv); 2103 } 2104 2105 #endif /* CONFIG_MESH */ 2106 2107 2108 #ifdef CONFIG_P2P 2109 2110 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2111 { 2112 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv); 2113 } 2114 2115 2116 static char ** wpa_cli_complete_p2p_find(const char *str, int pos) 2117 { 2118 char **res = NULL; 2119 int arg = get_cmd_arg_num(str, pos); 2120 2121 res = os_calloc(6, sizeof(char *)); 2122 if (res == NULL) 2123 return NULL; 2124 res[0] = os_strdup("type=social"); 2125 if (res[0] == NULL) { 2126 os_free(res); 2127 return NULL; 2128 } 2129 res[1] = os_strdup("type=progressive"); 2130 if (res[1] == NULL) 2131 return res; 2132 res[2] = os_strdup("delay="); 2133 if (res[2] == NULL) 2134 return res; 2135 res[3] = os_strdup("dev_id="); 2136 if (res[3] == NULL) 2137 return res; 2138 if (arg == 1) 2139 res[4] = os_strdup("[timeout]"); 2140 2141 return res; 2142 } 2143 2144 2145 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc, 2146 char *argv[]) 2147 { 2148 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND"); 2149 } 2150 2151 2152 static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc, 2153 char *argv[]) 2154 { 2155 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv); 2156 } 2157 2158 2159 static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc, 2160 char *argv[]) 2161 { 2162 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv); 2163 } 2164 2165 2166 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc, 2167 char *argv[]) 2168 { 2169 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv); 2170 } 2171 2172 2173 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos) 2174 { 2175 int arg = get_cmd_arg_num(str, pos); 2176 char **res = NULL; 2177 2178 switch (arg) { 2179 case 1: 2180 res = cli_txt_list_array(&p2p_peers); 2181 break; 2182 } 2183 2184 return res; 2185 } 2186 2187 2188 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc, 2189 char *argv[]) 2190 { 2191 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv); 2192 } 2193 2194 2195 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc, 2196 char *argv[]) 2197 { 2198 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv); 2199 } 2200 2201 2202 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos) 2203 { 2204 int arg = get_cmd_arg_num(str, pos); 2205 char **res = NULL; 2206 2207 switch (arg) { 2208 case 1: 2209 res = cli_txt_list_array(&p2p_groups); 2210 break; 2211 } 2212 2213 return res; 2214 } 2215 2216 2217 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc, 2218 char *argv[]) 2219 { 2220 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv); 2221 } 2222 2223 2224 static int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc, 2225 char *argv[]) 2226 { 2227 return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv); 2228 } 2229 2230 2231 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc, 2232 char *argv[]) 2233 { 2234 if (argc != 2 && argc != 3) { 2235 printf("Invalid P2P_PROV_DISC command: needs at least " 2236 "two arguments, address and config method\n" 2237 "(display, keypad, or pbc) and an optional join\n"); 2238 return -1; 2239 } 2240 2241 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv); 2242 } 2243 2244 2245 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc, 2246 char *argv[]) 2247 { 2248 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE"); 2249 } 2250 2251 2252 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc, 2253 char *argv[]) 2254 { 2255 char cmd[4096]; 2256 2257 if (argc < 2) { 2258 printf("Invalid P2P_SERV_DISC_REQ command: needs two " 2259 "or more arguments (address and TLVs)\n"); 2260 return -1; 2261 } 2262 2263 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0) 2264 return -1; 2265 return wpa_ctrl_command(ctrl, cmd); 2266 } 2267 2268 2269 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl, 2270 int argc, char *argv[]) 2271 { 2272 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv); 2273 } 2274 2275 2276 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc, 2277 char *argv[]) 2278 { 2279 char cmd[4096]; 2280 int res; 2281 2282 if (argc != 4) { 2283 printf("Invalid P2P_SERV_DISC_RESP command: needs four " 2284 "arguments (freq, address, dialog token, and TLVs)\n"); 2285 return -1; 2286 } 2287 2288 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s", 2289 argv[0], argv[1], argv[2], argv[3]); 2290 if (os_snprintf_error(sizeof(cmd), res)) 2291 return -1; 2292 cmd[sizeof(cmd) - 1] = '\0'; 2293 return wpa_ctrl_command(ctrl, cmd); 2294 } 2295 2296 2297 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc, 2298 char *argv[]) 2299 { 2300 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE"); 2301 } 2302 2303 2304 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl, 2305 int argc, char *argv[]) 2306 { 2307 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv); 2308 } 2309 2310 2311 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc, 2312 char *argv[]) 2313 { 2314 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH"); 2315 } 2316 2317 2318 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc, 2319 char *argv[]) 2320 { 2321 if (argc < 3) { 2322 printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n"); 2323 return -1; 2324 } 2325 2326 return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv); 2327 } 2328 2329 2330 static int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc, 2331 char *argv[]) 2332 { 2333 if (argc < 5 || argc > 6) { 2334 printf("Invalid P2P_SERVICE_REP command: needs 5-6 " 2335 "arguments\n"); 2336 return -1; 2337 } 2338 2339 return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv); 2340 } 2341 2342 2343 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc, 2344 char *argv[]) 2345 { 2346 char cmd[4096]; 2347 int res; 2348 2349 if (argc != 2 && argc != 3) { 2350 printf("Invalid P2P_SERVICE_DEL command: needs two or three " 2351 "arguments\n"); 2352 return -1; 2353 } 2354 2355 if (argc == 3) 2356 res = os_snprintf(cmd, sizeof(cmd), 2357 "P2P_SERVICE_DEL %s %s %s", 2358 argv[0], argv[1], argv[2]); 2359 else 2360 res = os_snprintf(cmd, sizeof(cmd), 2361 "P2P_SERVICE_DEL %s %s", 2362 argv[0], argv[1]); 2363 if (os_snprintf_error(sizeof(cmd), res)) 2364 return -1; 2365 cmd[sizeof(cmd) - 1] = '\0'; 2366 return wpa_ctrl_command(ctrl, cmd); 2367 } 2368 2369 2370 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl, 2371 int argc, char *argv[]) 2372 { 2373 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv); 2374 } 2375 2376 2377 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl, 2378 int argc, char *argv[]) 2379 { 2380 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv); 2381 } 2382 2383 2384 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2385 { 2386 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv); 2387 } 2388 2389 2390 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos) 2391 { 2392 int arg = get_cmd_arg_num(str, pos); 2393 char **res = NULL; 2394 2395 switch (arg) { 2396 case 1: 2397 res = cli_txt_list_array(&p2p_peers); 2398 break; 2399 } 2400 2401 return res; 2402 } 2403 2404 2405 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, const char *cmd, 2406 char *addr, size_t addr_len, 2407 int discovered) 2408 { 2409 char buf[4096], *pos; 2410 size_t len; 2411 int ret; 2412 2413 if (ctrl_conn == NULL) 2414 return -1; 2415 len = sizeof(buf) - 1; 2416 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 2417 wpa_cli_msg_cb); 2418 if (ret == -2) { 2419 printf("'%s' command timed out.\n", cmd); 2420 return -2; 2421 } else if (ret < 0) { 2422 printf("'%s' command failed.\n", cmd); 2423 return -1; 2424 } 2425 2426 buf[len] = '\0'; 2427 if (os_memcmp(buf, "FAIL", 4) == 0) 2428 return -1; 2429 2430 pos = buf; 2431 while (*pos != '\0' && *pos != '\n') 2432 pos++; 2433 *pos++ = '\0'; 2434 os_strlcpy(addr, buf, addr_len); 2435 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL) 2436 printf("%s\n", addr); 2437 return 0; 2438 } 2439 2440 2441 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2442 { 2443 char addr[32], cmd[64]; 2444 int discovered; 2445 2446 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0; 2447 2448 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST", 2449 addr, sizeof(addr), discovered)) 2450 return -1; 2451 do { 2452 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr); 2453 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr), 2454 discovered) == 0); 2455 2456 return 0; 2457 } 2458 2459 2460 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2461 { 2462 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv); 2463 } 2464 2465 2466 static char ** wpa_cli_complete_p2p_set(const char *str, int pos) 2467 { 2468 int arg = get_cmd_arg_num(str, pos); 2469 const char *fields[] = { 2470 "discoverability", 2471 "managed", 2472 "listen_channel", 2473 "ssid_postfix", 2474 "noa", 2475 "ps", 2476 "oppps", 2477 "ctwindow", 2478 "disabled", 2479 "conc_pref", 2480 "force_long_sd", 2481 "peer_filter", 2482 "cross_connect", 2483 "go_apsd", 2484 "client_apsd", 2485 "disallow_freq", 2486 "disc_int", 2487 "per_sta_psk", 2488 }; 2489 int i, num_fields = ARRAY_SIZE(fields); 2490 2491 if (arg == 1) { 2492 char **res = os_calloc(num_fields + 1, sizeof(char *)); 2493 if (res == NULL) 2494 return NULL; 2495 for (i = 0; i < num_fields; i++) { 2496 res[i] = os_strdup(fields[i]); 2497 if (res[i] == NULL) 2498 return res; 2499 } 2500 return res; 2501 } 2502 2503 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0) 2504 return cli_txt_list_array(&p2p_peers); 2505 2506 return NULL; 2507 } 2508 2509 2510 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2511 { 2512 return wpa_ctrl_command(ctrl, "P2P_FLUSH"); 2513 } 2514 2515 2516 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc, 2517 char *argv[]) 2518 { 2519 return wpa_ctrl_command(ctrl, "P2P_CANCEL"); 2520 } 2521 2522 2523 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc, 2524 char *argv[]) 2525 { 2526 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv); 2527 } 2528 2529 2530 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, 2531 char *argv[]) 2532 { 2533 if (argc != 0 && argc != 2 && argc != 4) { 2534 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments " 2535 "(preferred duration, interval; in microsecods).\n" 2536 "Optional second pair can be used to provide " 2537 "acceptable values.\n"); 2538 return -1; 2539 } 2540 2541 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv); 2542 } 2543 2544 2545 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc, 2546 char *argv[]) 2547 { 2548 if (argc != 0 && argc != 2) { 2549 printf("Invalid P2P_EXT_LISTEN command: needs two arguments " 2550 "(availability period, availability interval; in " 2551 "millisecods).\n" 2552 "Extended Listen Timing can be cancelled with this " 2553 "command when used without parameters.\n"); 2554 return -1; 2555 } 2556 2557 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv); 2558 } 2559 2560 2561 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc, 2562 char *argv[]) 2563 { 2564 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv); 2565 } 2566 2567 #endif /* CONFIG_P2P */ 2568 2569 2570 static int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc, 2571 char *argv[]) 2572 { 2573 return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv); 2574 } 2575 2576 2577 static int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc, 2578 char *argv[]) 2579 { 2580 return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv); 2581 } 2582 2583 2584 static int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc, 2585 char *argv[]) 2586 { 2587 return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv); 2588 } 2589 2590 2591 #ifdef CONFIG_WIFI_DISPLAY 2592 2593 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc, 2594 char *argv[]) 2595 { 2596 char cmd[100]; 2597 int res; 2598 2599 if (argc != 1 && argc != 2) { 2600 printf("Invalid WFD_SUBELEM_SET command: needs one or two " 2601 "arguments (subelem, hexdump)\n"); 2602 return -1; 2603 } 2604 2605 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s", 2606 argv[0], argc > 1 ? argv[1] : ""); 2607 if (os_snprintf_error(sizeof(cmd), res)) 2608 return -1; 2609 cmd[sizeof(cmd) - 1] = '\0'; 2610 return wpa_ctrl_command(ctrl, cmd); 2611 } 2612 2613 2614 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc, 2615 char *argv[]) 2616 { 2617 char cmd[100]; 2618 int res; 2619 2620 if (argc != 1) { 2621 printf("Invalid WFD_SUBELEM_GET command: needs one " 2622 "argument (subelem)\n"); 2623 return -1; 2624 } 2625 2626 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s", 2627 argv[0]); 2628 if (os_snprintf_error(sizeof(cmd), res)) 2629 return -1; 2630 cmd[sizeof(cmd) - 1] = '\0'; 2631 return wpa_ctrl_command(ctrl, cmd); 2632 } 2633 #endif /* CONFIG_WIFI_DISPLAY */ 2634 2635 2636 #ifdef CONFIG_INTERWORKING 2637 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2638 char *argv[]) 2639 { 2640 return wpa_ctrl_command(ctrl, "FETCH_ANQP"); 2641 } 2642 2643 2644 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2645 char *argv[]) 2646 { 2647 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP"); 2648 } 2649 2650 2651 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc, 2652 char *argv[]) 2653 { 2654 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv); 2655 } 2656 2657 2658 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc, 2659 char *argv[]) 2660 { 2661 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv); 2662 } 2663 2664 2665 static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc, 2666 char *argv[]) 2667 { 2668 return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv); 2669 } 2670 2671 2672 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2673 { 2674 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv); 2675 } 2676 2677 2678 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc, 2679 char *argv[]) 2680 { 2681 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv); 2682 } 2683 2684 2685 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc, 2686 char *argv[]) 2687 { 2688 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv); 2689 } 2690 #endif /* CONFIG_INTERWORKING */ 2691 2692 2693 #ifdef CONFIG_HS20 2694 2695 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc, 2696 char *argv[]) 2697 { 2698 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv); 2699 } 2700 2701 2702 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, 2703 char *argv[]) 2704 { 2705 char cmd[512]; 2706 2707 if (argc == 0) { 2708 printf("Command needs one or two arguments (dst mac addr and " 2709 "optional home realm)\n"); 2710 return -1; 2711 } 2712 2713 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST", 2714 argc, argv) < 0) 2715 return -1; 2716 2717 return wpa_ctrl_command(ctrl, cmd); 2718 } 2719 2720 2721 static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc, 2722 char *argv[]) 2723 { 2724 char cmd[512]; 2725 2726 if (argc < 2) { 2727 printf("Command needs two arguments (dst mac addr and " 2728 "icon name)\n"); 2729 return -1; 2730 } 2731 2732 if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0) 2733 return -1; 2734 2735 return wpa_ctrl_command(ctrl, cmd); 2736 } 2737 2738 2739 static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2740 { 2741 return wpa_ctrl_command(ctrl, "FETCH_OSU"); 2742 } 2743 2744 2745 static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc, 2746 char *argv[]) 2747 { 2748 return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU"); 2749 } 2750 2751 #endif /* CONFIG_HS20 */ 2752 2753 2754 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc, 2755 char *argv[]) 2756 { 2757 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv); 2758 } 2759 2760 2761 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc, 2762 char *argv[]) 2763 { 2764 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv); 2765 } 2766 2767 2768 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc, 2769 char *argv[]) 2770 { 2771 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv); 2772 } 2773 2774 2775 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc, 2776 char *argv[]) 2777 { 2778 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv); 2779 } 2780 2781 2782 static int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc, 2783 char *argv[]) 2784 { 2785 return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv); 2786 } 2787 2788 2789 static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc, 2790 char *argv[]) 2791 { 2792 return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv); 2793 } 2794 2795 2796 static int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc, 2797 char *argv[]) 2798 { 2799 return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv); 2800 } 2801 2802 2803 static int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc, 2804 char *argv[]) 2805 { 2806 return wpa_ctrl_command(ctrl, "WMM_AC_STATUS"); 2807 } 2808 2809 2810 static int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc, 2811 char *argv[]) 2812 { 2813 return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv); 2814 } 2815 2816 2817 static int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc, 2818 char *argv[]) 2819 { 2820 return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv); 2821 } 2822 2823 2824 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc, 2825 char *argv[]) 2826 { 2827 return wpa_ctrl_command(ctrl, "SIGNAL_POLL"); 2828 } 2829 2830 2831 static int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc, 2832 char *argv[]) 2833 { 2834 return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv); 2835 } 2836 2837 2838 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc, 2839 char *argv[]) 2840 { 2841 return wpa_ctrl_command(ctrl, "PKTCNT_POLL"); 2842 } 2843 2844 2845 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc, 2846 char *argv[]) 2847 { 2848 return wpa_ctrl_command(ctrl, "REAUTHENTICATE"); 2849 } 2850 2851 2852 #ifdef CONFIG_AUTOSCAN 2853 2854 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2855 { 2856 if (argc == 0) 2857 return wpa_ctrl_command(ctrl, "AUTOSCAN "); 2858 2859 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv); 2860 } 2861 2862 #endif /* CONFIG_AUTOSCAN */ 2863 2864 2865 #ifdef CONFIG_WNM 2866 2867 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2868 { 2869 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv); 2870 } 2871 2872 2873 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2874 { 2875 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv); 2876 } 2877 2878 #endif /* CONFIG_WNM */ 2879 2880 2881 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2882 { 2883 if (argc == 0) 2884 return -1; 2885 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]); 2886 } 2887 2888 2889 #ifdef ANDROID 2890 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2891 { 2892 return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv); 2893 } 2894 #endif /* ANDROID */ 2895 2896 2897 static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2898 { 2899 return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv); 2900 } 2901 2902 2903 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2904 { 2905 return wpa_ctrl_command(ctrl, "FLUSH"); 2906 } 2907 2908 2909 static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2910 { 2911 return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv); 2912 } 2913 2914 2915 static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc, 2916 char *argv[]) 2917 { 2918 return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv); 2919 } 2920 2921 2922 static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2923 { 2924 return wpa_ctrl_command(ctrl, "ERP_FLUSH"); 2925 } 2926 2927 2928 static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc, 2929 char *argv[]) 2930 { 2931 return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv); 2932 } 2933 2934 2935 static int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc, 2936 char *argv[]) 2937 { 2938 return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv); 2939 } 2940 2941 2942 static int wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl *ctrl, int argc, 2943 char *argv[]) 2944 { 2945 return wpa_cli_cmd(ctrl, "P2P_LO_START", 4, argc, argv); 2946 } 2947 2948 2949 static int wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl *ctrl, int argc, 2950 char *argv[]) 2951 { 2952 return wpa_cli_cmd(ctrl, "P2P_LO_STOP", 0, argc, argv); 2953 } 2954 2955 2956 #ifdef CONFIG_DPP 2957 2958 static int wpa_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc, 2959 char *argv[]) 2960 { 2961 return wpa_cli_cmd(ctrl, "DPP_QR_CODE", 1, argc, argv); 2962 } 2963 2964 2965 static int wpa_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl *ctrl, int argc, 2966 char *argv[]) 2967 { 2968 return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GEN", 1, argc, argv); 2969 } 2970 2971 2972 static int wpa_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl *ctrl, int argc, 2973 char *argv[]) 2974 { 2975 return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_REMOVE", 1, argc, argv); 2976 } 2977 2978 2979 static int wpa_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl *ctrl, int argc, 2980 char *argv[]) 2981 { 2982 return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GET_URI", 1, argc, argv); 2983 } 2984 2985 2986 static int wpa_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl *ctrl, int argc, 2987 char *argv[]) 2988 { 2989 return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_INFO", 1, argc, argv); 2990 } 2991 2992 2993 static int wpa_cli_cmd_dpp_auth_init(struct wpa_ctrl *ctrl, int argc, 2994 char *argv[]) 2995 { 2996 return wpa_cli_cmd(ctrl, "DPP_AUTH_INIT", 1, argc, argv); 2997 } 2998 2999 3000 static int wpa_cli_cmd_dpp_listen(struct wpa_ctrl *ctrl, int argc, 3001 char *argv[]) 3002 { 3003 return wpa_cli_cmd(ctrl, "DPP_LISTEN", 1, argc, argv); 3004 } 3005 3006 3007 static int wpa_cli_cmd_dpp_stop_listen(struct wpa_ctrl *ctrl, int argc, 3008 char *argv[]) 3009 { 3010 return wpa_ctrl_command(ctrl, "DPP_STOP_LISTEN"); 3011 } 3012 3013 3014 static int wpa_cli_cmd_dpp_configurator_add(struct wpa_ctrl *ctrl, int argc, 3015 char *argv[]) 3016 { 3017 return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_ADD", 0, argc, argv); 3018 } 3019 3020 3021 static int wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, int argc, 3022 char *argv[]) 3023 { 3024 return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_REMOVE", 1, argc, argv); 3025 } 3026 3027 3028 static int wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, int argc, 3029 char *argv[]) 3030 { 3031 return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_GET_KEY", 1, argc, argv); 3032 } 3033 3034 3035 static int wpa_cli_cmd_dpp_configurator_sign(struct wpa_ctrl *ctrl, int argc, 3036 char *argv[]) 3037 { 3038 return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_SIGN", 1, argc, argv); 3039 } 3040 3041 3042 static int wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc, 3043 char *argv[]) 3044 { 3045 return wpa_cli_cmd(ctrl, "DPP_PKEX_ADD", 1, argc, argv); 3046 } 3047 3048 3049 static int wpa_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc, 3050 char *argv[]) 3051 { 3052 return wpa_cli_cmd(ctrl, "DPP_PKEX_REMOVE", 1, argc, argv); 3053 } 3054 3055 #endif /* CONFIG_DPP */ 3056 3057 3058 enum wpa_cli_cmd_flags { 3059 cli_cmd_flag_none = 0x00, 3060 cli_cmd_flag_sensitive = 0x01 3061 }; 3062 3063 struct wpa_cli_cmd { 3064 const char *cmd; 3065 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); 3066 char ** (*completion)(const char *str, int pos); 3067 enum wpa_cli_cmd_flags flags; 3068 const char *usage; 3069 }; 3070 3071 static const struct wpa_cli_cmd wpa_cli_commands[] = { 3072 { "status", wpa_cli_cmd_status, NULL, 3073 cli_cmd_flag_none, 3074 "[verbose] = get current WPA/EAPOL/EAP status" }, 3075 { "ifname", wpa_cli_cmd_ifname, NULL, 3076 cli_cmd_flag_none, 3077 "= get current interface name" }, 3078 { "ping", wpa_cli_cmd_ping, NULL, 3079 cli_cmd_flag_none, 3080 "= pings wpa_supplicant" }, 3081 { "relog", wpa_cli_cmd_relog, NULL, 3082 cli_cmd_flag_none, 3083 "= re-open log-file (allow rolling logs)" }, 3084 { "note", wpa_cli_cmd_note, NULL, 3085 cli_cmd_flag_none, 3086 "<text> = add a note to wpa_supplicant debug log" }, 3087 { "mib", wpa_cli_cmd_mib, NULL, 3088 cli_cmd_flag_none, 3089 "= get MIB variables (dot1x, dot11)" }, 3090 { "help", wpa_cli_cmd_help, wpa_cli_complete_help, 3091 cli_cmd_flag_none, 3092 "[command] = show usage help" }, 3093 { "interface", wpa_cli_cmd_interface, NULL, 3094 cli_cmd_flag_none, 3095 "[ifname] = show interfaces/select interface" }, 3096 { "level", wpa_cli_cmd_level, NULL, 3097 cli_cmd_flag_none, 3098 "<debug level> = change debug level" }, 3099 { "license", wpa_cli_cmd_license, NULL, 3100 cli_cmd_flag_none, 3101 "= show full wpa_cli license" }, 3102 { "quit", wpa_cli_cmd_quit, NULL, 3103 cli_cmd_flag_none, 3104 "= exit wpa_cli" }, 3105 { "set", wpa_cli_cmd_set, wpa_cli_complete_set, 3106 cli_cmd_flag_none, 3107 "= set variables (shows list of variables when run without " 3108 "arguments)" }, 3109 { "dump", wpa_cli_cmd_dump, NULL, 3110 cli_cmd_flag_none, 3111 "= dump config variables" }, 3112 { "get", wpa_cli_cmd_get, wpa_cli_complete_get, 3113 cli_cmd_flag_none, 3114 "<name> = get information" }, 3115 { "driver_flags", wpa_cli_cmd_driver_flags, NULL, 3116 cli_cmd_flag_none, 3117 "= list driver flags" }, 3118 { "logon", wpa_cli_cmd_logon, NULL, 3119 cli_cmd_flag_none, 3120 "= IEEE 802.1X EAPOL state machine logon" }, 3121 { "logoff", wpa_cli_cmd_logoff, NULL, 3122 cli_cmd_flag_none, 3123 "= IEEE 802.1X EAPOL state machine logoff" }, 3124 { "pmksa", wpa_cli_cmd_pmksa, NULL, 3125 cli_cmd_flag_none, 3126 "= show PMKSA cache" }, 3127 { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL, 3128 cli_cmd_flag_none, 3129 "= flush PMKSA cache entries" }, 3130 #ifdef CONFIG_PMKSA_CACHE_EXTERNAL 3131 { "pmksa_get", wpa_cli_cmd_pmksa_get, NULL, 3132 cli_cmd_flag_none, 3133 "<network_id> = fetch all stored PMKSA cache entries" }, 3134 { "pmksa_add", wpa_cli_cmd_pmksa_add, NULL, 3135 cli_cmd_flag_sensitive, 3136 "<network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds> <expiration in seconds> <akmp> <opportunistic> = store PMKSA cache entry from external storage" }, 3137 #ifdef CONFIG_MESH 3138 { "mesh_pmksa_get", wpa_cli_mesh_cmd_pmksa_get, NULL, 3139 cli_cmd_flag_none, 3140 "<peer MAC address | any> = fetch all stored mesh PMKSA cache entries" }, 3141 { "mesh_pmksa_add", wpa_cli_mesh_cmd_pmksa_add, NULL, 3142 cli_cmd_flag_sensitive, 3143 "<BSSID> <PMKID> <PMK> <expiration in seconds> = store mesh PMKSA cache entry from external storage" }, 3144 #endif /* CONFIG_MESH */ 3145 #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ 3146 { "reassociate", wpa_cli_cmd_reassociate, NULL, 3147 cli_cmd_flag_none, 3148 "= force reassociation" }, 3149 { "reattach", wpa_cli_cmd_reattach, NULL, 3150 cli_cmd_flag_none, 3151 "= force reassociation back to the same BSS" }, 3152 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss, 3153 cli_cmd_flag_none, 3154 "<BSSID> = force preauthentication" }, 3155 { "identity", wpa_cli_cmd_identity, wpa_cli_complete_network_id, 3156 cli_cmd_flag_none, 3157 "<network id> <identity> = configure identity for an SSID" }, 3158 { "password", wpa_cli_cmd_password, wpa_cli_complete_network_id, 3159 cli_cmd_flag_sensitive, 3160 "<network id> <password> = configure password for an SSID" }, 3161 { "new_password", wpa_cli_cmd_new_password, 3162 wpa_cli_complete_network_id, cli_cmd_flag_sensitive, 3163 "<network id> <password> = change password for an SSID" }, 3164 { "pin", wpa_cli_cmd_pin, wpa_cli_complete_network_id, 3165 cli_cmd_flag_sensitive, 3166 "<network id> <pin> = configure pin for an SSID" }, 3167 { "otp", wpa_cli_cmd_otp, wpa_cli_complete_network_id, 3168 cli_cmd_flag_sensitive, 3169 "<network id> <password> = configure one-time-password for an SSID" 3170 }, 3171 { "psk_passphrase", wpa_cli_cmd_psk_passphrase, 3172 wpa_cli_complete_network_id, cli_cmd_flag_sensitive, 3173 "<network id> <PSK/passphrase> = configure PSK/passphrase for an SSID" }, 3174 { "passphrase", wpa_cli_cmd_passphrase, wpa_cli_complete_network_id, 3175 cli_cmd_flag_sensitive, 3176 "<network id> <passphrase> = configure private key passphrase\n" 3177 " for an SSID" }, 3178 { "sim", wpa_cli_cmd_sim, wpa_cli_complete_network_id, 3179 cli_cmd_flag_sensitive, 3180 "<network id> <pin> = report SIM operation result" }, 3181 { "bssid", wpa_cli_cmd_bssid, wpa_cli_complete_network_id, 3182 cli_cmd_flag_none, 3183 "<network id> <BSSID> = set preferred BSSID for an SSID" }, 3184 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss, 3185 cli_cmd_flag_none, 3186 "<BSSID> = add a BSSID to the blacklist\n" 3187 "blacklist clear = clear the blacklist\n" 3188 "blacklist = display the blacklist" }, 3189 { "log_level", wpa_cli_cmd_log_level, NULL, 3190 cli_cmd_flag_none, 3191 "<level> [<timestamp>] = update the log level/timestamp\n" 3192 "log_level = display the current log level and log options" }, 3193 { "list_networks", wpa_cli_cmd_list_networks, NULL, 3194 cli_cmd_flag_none, 3195 "= list configured networks" }, 3196 { "select_network", wpa_cli_cmd_select_network, 3197 wpa_cli_complete_network_id, 3198 cli_cmd_flag_none, 3199 "<network id> = select a network (disable others)" }, 3200 { "enable_network", wpa_cli_cmd_enable_network, 3201 wpa_cli_complete_network_id, 3202 cli_cmd_flag_none, 3203 "<network id> = enable a network" }, 3204 { "disable_network", wpa_cli_cmd_disable_network, 3205 wpa_cli_complete_network_id, 3206 cli_cmd_flag_none, 3207 "<network id> = disable a network" }, 3208 { "add_network", wpa_cli_cmd_add_network, NULL, 3209 cli_cmd_flag_none, 3210 "= add a network" }, 3211 { "remove_network", wpa_cli_cmd_remove_network, 3212 wpa_cli_complete_network_id, 3213 cli_cmd_flag_none, 3214 "<network id> = remove a network" }, 3215 { "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network, 3216 cli_cmd_flag_sensitive, 3217 "<network id> <variable> <value> = set network variables (shows\n" 3218 " list of variables when run without arguments)" }, 3219 { "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network, 3220 cli_cmd_flag_none, 3221 "<network id> <variable> = get network variables" }, 3222 { "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network, 3223 cli_cmd_flag_none, 3224 "<src network id> <dst network id> <variable> = duplicate network variables" 3225 }, 3226 { "list_creds", wpa_cli_cmd_list_creds, NULL, 3227 cli_cmd_flag_none, 3228 "= list configured credentials" }, 3229 { "add_cred", wpa_cli_cmd_add_cred, NULL, 3230 cli_cmd_flag_none, 3231 "= add a credential" }, 3232 { "remove_cred", wpa_cli_cmd_remove_cred, NULL, 3233 cli_cmd_flag_none, 3234 "<cred id> = remove a credential" }, 3235 { "set_cred", wpa_cli_cmd_set_cred, wpa_cli_complete_cred, 3236 cli_cmd_flag_sensitive, 3237 "<cred id> <variable> <value> = set credential variables" }, 3238 { "get_cred", wpa_cli_cmd_get_cred, wpa_cli_complete_cred, 3239 cli_cmd_flag_none, 3240 "<cred id> <variable> = get credential variables" }, 3241 { "save_config", wpa_cli_cmd_save_config, NULL, 3242 cli_cmd_flag_none, 3243 "= save the current configuration" }, 3244 { "disconnect", wpa_cli_cmd_disconnect, NULL, 3245 cli_cmd_flag_none, 3246 "= disconnect and wait for reassociate/reconnect command before\n" 3247 " connecting" }, 3248 { "reconnect", wpa_cli_cmd_reconnect, NULL, 3249 cli_cmd_flag_none, 3250 "= like reassociate, but only takes effect if already disconnected" 3251 }, 3252 { "scan", wpa_cli_cmd_scan, NULL, 3253 cli_cmd_flag_none, 3254 "= request new BSS scan" }, 3255 { "scan_results", wpa_cli_cmd_scan_results, NULL, 3256 cli_cmd_flag_none, 3257 "= get latest scan results" }, 3258 { "abort_scan", wpa_cli_cmd_abort_scan, NULL, 3259 cli_cmd_flag_none, 3260 "= request ongoing scan to be aborted" }, 3261 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss, 3262 cli_cmd_flag_none, 3263 "<<idx> | <bssid>> = get detailed scan result info" }, 3264 { "get_capability", wpa_cli_cmd_get_capability, 3265 wpa_cli_complete_get_capability, cli_cmd_flag_none, 3266 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> " 3267 "= get capabilities" }, 3268 { "reconfigure", wpa_cli_cmd_reconfigure, NULL, 3269 cli_cmd_flag_none, 3270 "= force wpa_supplicant to re-read its configuration file" }, 3271 { "terminate", wpa_cli_cmd_terminate, NULL, 3272 cli_cmd_flag_none, 3273 "= terminate wpa_supplicant" }, 3274 { "interface_add", wpa_cli_cmd_interface_add, NULL, 3275 cli_cmd_flag_none, 3276 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n" 3277 " <bridge_name> <create> <type> = adds new interface, all " 3278 "parameters but\n" 3279 " <ifname> are optional. Supported types are station ('sta') and " 3280 "AP ('ap')" }, 3281 { "interface_remove", wpa_cli_cmd_interface_remove, NULL, 3282 cli_cmd_flag_none, 3283 "<ifname> = removes the interface" }, 3284 { "interface_list", wpa_cli_cmd_interface_list, NULL, 3285 cli_cmd_flag_none, 3286 "= list available interfaces" }, 3287 { "ap_scan", wpa_cli_cmd_ap_scan, NULL, 3288 cli_cmd_flag_none, 3289 "<value> = set ap_scan parameter" }, 3290 { "scan_interval", wpa_cli_cmd_scan_interval, NULL, 3291 cli_cmd_flag_none, 3292 "<value> = set scan_interval parameter (in seconds)" }, 3293 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL, 3294 cli_cmd_flag_none, 3295 "<value> = set BSS expiration age parameter" }, 3296 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL, 3297 cli_cmd_flag_none, 3298 "<value> = set BSS expiration scan count parameter" }, 3299 { "bss_flush", wpa_cli_cmd_bss_flush, NULL, 3300 cli_cmd_flag_none, 3301 "<value> = set BSS flush age (0 by default)" }, 3302 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss, 3303 cli_cmd_flag_none, 3304 "<addr> = request over-the-DS FT with <addr>" }, 3305 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss, 3306 cli_cmd_flag_none, 3307 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" }, 3308 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss, 3309 cli_cmd_flag_sensitive, 3310 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " 3311 "hardcoded)" }, 3312 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL, 3313 cli_cmd_flag_sensitive, 3314 "<PIN> = verify PIN checksum" }, 3315 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none, 3316 "Cancels the pending WPS operation" }, 3317 #ifdef CONFIG_WPS_NFC 3318 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss, 3319 cli_cmd_flag_none, 3320 "[BSSID] = start Wi-Fi Protected Setup: NFC" }, 3321 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL, 3322 cli_cmd_flag_none, 3323 "<WPS|NDEF> = build configuration token" }, 3324 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL, 3325 cli_cmd_flag_none, 3326 "<WPS|NDEF> = create password token" }, 3327 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL, 3328 cli_cmd_flag_sensitive, 3329 "<hexdump of payload> = report read NFC tag with WPS data" }, 3330 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL, 3331 cli_cmd_flag_none, 3332 "<NDEF> <WPS> = create NFC handover request" }, 3333 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL, 3334 cli_cmd_flag_none, 3335 "<NDEF> <WPS> = create NFC handover select" }, 3336 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL, 3337 cli_cmd_flag_none, 3338 "<role> <type> <hexdump of req> <hexdump of sel> = report completed " 3339 "NFC handover" }, 3340 #endif /* CONFIG_WPS_NFC */ 3341 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss, 3342 cli_cmd_flag_sensitive, 3343 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, 3344 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL, 3345 cli_cmd_flag_sensitive, 3346 "[params..] = enable/disable AP PIN" }, 3347 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL, 3348 cli_cmd_flag_none, 3349 "[IP address] = start Wi-Fi Protected Setup External Registrar" }, 3350 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL, 3351 cli_cmd_flag_none, 3352 "= stop Wi-Fi Protected Setup External Registrar" }, 3353 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL, 3354 cli_cmd_flag_sensitive, 3355 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" }, 3356 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL, 3357 cli_cmd_flag_none, 3358 "<UUID> = accept an Enrollee PBC using External Registrar" }, 3359 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL, 3360 cli_cmd_flag_sensitive, 3361 "<UUID> <PIN> = learn AP configuration" }, 3362 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL, 3363 cli_cmd_flag_none, 3364 "<UUID> <network id> = set AP configuration for enrolling" }, 3365 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL, 3366 cli_cmd_flag_sensitive, 3367 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" }, 3368 #ifdef CONFIG_WPS_NFC 3369 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL, 3370 cli_cmd_flag_none, 3371 "<WPS/NDEF> <UUID> = build NFC configuration token" }, 3372 #endif /* CONFIG_WPS_NFC */ 3373 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL, 3374 cli_cmd_flag_none, 3375 "<addr> = request RSN authentication with <addr> in IBSS" }, 3376 #ifdef CONFIG_AP 3377 { "sta", wpa_cli_cmd_sta, wpa_cli_complete_sta, 3378 cli_cmd_flag_none, 3379 "<addr> = get information about an associated station (AP)" }, 3380 { "all_sta", wpa_cli_cmd_all_sta, NULL, 3381 cli_cmd_flag_none, 3382 "= get information about all associated stations (AP)" }, 3383 { "list_sta", wpa_cli_cmd_list_sta, NULL, 3384 cli_cmd_flag_none, 3385 "= list all stations (AP)" }, 3386 { "deauthenticate", wpa_cli_cmd_deauthenticate, 3387 wpa_cli_complete_deauthenticate, cli_cmd_flag_none, 3388 "<addr> = deauthenticate a station" }, 3389 { "disassociate", wpa_cli_cmd_disassociate, 3390 wpa_cli_complete_disassociate, cli_cmd_flag_none, 3391 "<addr> = disassociate a station" }, 3392 { "chan_switch", wpa_cli_cmd_chanswitch, NULL, 3393 cli_cmd_flag_none, 3394 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]" 3395 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]" 3396 " = CSA parameters" }, 3397 #endif /* CONFIG_AP */ 3398 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none, 3399 "= notification of suspend/hibernate" }, 3400 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none, 3401 "= notification of resume/thaw" }, 3402 #ifdef CONFIG_TESTING_OPTIONS 3403 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none, 3404 "= drop SA without deauth/disassoc (test command)" }, 3405 #endif /* CONFIG_TESTING_OPTIONS */ 3406 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss, 3407 cli_cmd_flag_none, 3408 "<addr> = roam to the specified BSS" }, 3409 #ifdef CONFIG_MESH 3410 { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL, 3411 cli_cmd_flag_none, 3412 "[ifname] = Create a new mesh interface" }, 3413 { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL, 3414 cli_cmd_flag_none, 3415 "<network id> = join a mesh network (disable others)" }, 3416 { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL, 3417 cli_cmd_flag_none, 3418 "<ifname> = Remove mesh group interface" }, 3419 { "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL, 3420 cli_cmd_flag_none, 3421 "<addr> = Remove a mesh peer" }, 3422 { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL, 3423 cli_cmd_flag_none, 3424 "<addr> [duration=<seconds>] = Add a mesh peer" }, 3425 { "mesh_link_probe", wpa_cli_cmd_mesh_link_probe, NULL, 3426 cli_cmd_flag_none, 3427 "<addr> [payload=<hex dump of payload>] = Probe a mesh link for a given peer by injecting a frame." }, 3428 #endif /* CONFIG_MESH */ 3429 #ifdef CONFIG_P2P 3430 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find, 3431 cli_cmd_flag_none, 3432 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" }, 3433 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none, 3434 "= stop P2P Devices search" }, 3435 { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL, 3436 cli_cmd_flag_none, 3437 "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" }, 3438 { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL, 3439 cli_cmd_flag_none, 3440 "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" }, 3441 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect, 3442 cli_cmd_flag_none, 3443 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" }, 3444 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none, 3445 "[timeout] = listen for P2P Devices for up-to timeout seconds" }, 3446 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, 3447 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none, 3448 "<ifname> = remove P2P group interface (terminate group if GO)" }, 3449 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none, 3450 "[ht40] = add a new P2P group (local end as GO)" }, 3451 { "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL, 3452 cli_cmd_flag_none, 3453 "<dev_addr> = Get peer interface address on local GO using peer Device Address" }, 3454 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, 3455 wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3456 "<addr> <method> = request provisioning discovery" }, 3457 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL, 3458 cli_cmd_flag_none, 3459 "= get the passphrase for a group (GO only)" }, 3460 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req, 3461 wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3462 "<addr> <TLVs> = schedule service discovery request" }, 3463 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req, 3464 NULL, cli_cmd_flag_none, 3465 "<id> = cancel pending service discovery request" }, 3466 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL, 3467 cli_cmd_flag_none, 3468 "<freq> <addr> <dialog token> <TLVs> = service discovery response" }, 3469 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL, 3470 cli_cmd_flag_none, 3471 "= indicate change in local services" }, 3472 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL, 3473 cli_cmd_flag_none, 3474 "<external> = set external processing of service discovery" }, 3475 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL, 3476 cli_cmd_flag_none, 3477 "= remove all stored service entries" }, 3478 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL, 3479 cli_cmd_flag_none, 3480 "<bonjour|upnp|asp> <query|version> <response|service> = add a local " 3481 "service" }, 3482 { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL, 3483 cli_cmd_flag_none, 3484 "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace " 3485 "local ASP service" }, 3486 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL, 3487 cli_cmd_flag_none, 3488 "<bonjour|upnp> <query|version> [|service] = remove a local " 3489 "service" }, 3490 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer, 3491 cli_cmd_flag_none, 3492 "<addr> = reject connection attempts from a specific peer" }, 3493 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL, 3494 cli_cmd_flag_none, 3495 "<cmd> [peer=addr] = invite peer" }, 3496 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none, 3497 "[discovered] = list known (optionally, only fully discovered) P2P " 3498 "peers" }, 3499 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer, 3500 cli_cmd_flag_none, 3501 "<address> = show information about known P2P peer" }, 3502 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set, 3503 cli_cmd_flag_none, 3504 "<field> <value> = set a P2P parameter" }, 3505 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none, 3506 "= flush P2P state" }, 3507 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none, 3508 "= cancel P2P group formation" }, 3509 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, 3510 wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3511 "<address> = unauthorize a peer" }, 3512 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL, 3513 cli_cmd_flag_none, 3514 "[<duration> <interval>] [<duration> <interval>] = request GO " 3515 "presence" }, 3516 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL, 3517 cli_cmd_flag_none, 3518 "[<period> <interval>] = set extended listen timing" }, 3519 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client, 3520 wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3521 "<address|iface=address> = remove a peer from all groups" }, 3522 #endif /* CONFIG_P2P */ 3523 { "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL, 3524 cli_cmd_flag_none, 3525 "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n" 3526 VENDOR_ELEM_FRAME_ID }, 3527 { "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL, 3528 cli_cmd_flag_none, 3529 "<frame id> = get vendor specific IE(s) to frame(s)\n" 3530 VENDOR_ELEM_FRAME_ID }, 3531 { "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL, 3532 cli_cmd_flag_none, 3533 "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n" 3534 VENDOR_ELEM_FRAME_ID }, 3535 #ifdef CONFIG_WIFI_DISPLAY 3536 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL, 3537 cli_cmd_flag_none, 3538 "<subelem> [contents] = set Wi-Fi Display subelement" }, 3539 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL, 3540 cli_cmd_flag_none, 3541 "<subelem> = get Wi-Fi Display subelement" }, 3542 #endif /* CONFIG_WIFI_DISPLAY */ 3543 #ifdef CONFIG_INTERWORKING 3544 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none, 3545 "= fetch ANQP information for all APs" }, 3546 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL, 3547 cli_cmd_flag_none, 3548 "= stop fetch_anqp operation" }, 3549 { "interworking_select", wpa_cli_cmd_interworking_select, NULL, 3550 cli_cmd_flag_none, 3551 "[auto] = perform Interworking network selection" }, 3552 { "interworking_connect", wpa_cli_cmd_interworking_connect, 3553 wpa_cli_complete_bss, cli_cmd_flag_none, 3554 "<BSSID> = connect using Interworking credentials" }, 3555 { "interworking_add_network", wpa_cli_cmd_interworking_add_network, 3556 wpa_cli_complete_bss, cli_cmd_flag_none, 3557 "<BSSID> = connect using Interworking credentials" }, 3558 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss, 3559 cli_cmd_flag_none, 3560 "<addr> <info id>[,<info id>]... = request ANQP information" }, 3561 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss, 3562 cli_cmd_flag_none, 3563 "<addr> <AdvProtoID> [QueryReq] = GAS request" }, 3564 { "gas_response_get", wpa_cli_cmd_gas_response_get, 3565 wpa_cli_complete_bss, cli_cmd_flag_none, 3566 "<addr> <dialog token> [start,len] = Fetch last GAS response" }, 3567 #endif /* CONFIG_INTERWORKING */ 3568 #ifdef CONFIG_HS20 3569 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss, 3570 cli_cmd_flag_none, 3571 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information" 3572 }, 3573 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list, 3574 wpa_cli_complete_bss, cli_cmd_flag_none, 3575 "<addr> <home realm> = get HS20 nai home realm list" }, 3576 { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request, 3577 wpa_cli_complete_bss, cli_cmd_flag_none, 3578 "<addr> <icon name> = get Hotspot 2.0 OSU icon" }, 3579 { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none, 3580 "= fetch OSU provider information from all APs" }, 3581 { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL, 3582 cli_cmd_flag_none, 3583 "= cancel fetch_osu command" }, 3584 #endif /* CONFIG_HS20 */ 3585 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL, 3586 cli_cmd_flag_none, 3587 "<0/1> = disable/enable automatic reconnection" }, 3588 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL, 3589 cli_cmd_flag_none, 3590 "<addr> = request TDLS discovery with <addr>" }, 3591 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL, 3592 cli_cmd_flag_none, 3593 "<addr> = request TDLS setup with <addr>" }, 3594 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL, 3595 cli_cmd_flag_none, 3596 "<addr> = tear down TDLS with <addr>" }, 3597 { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL, 3598 cli_cmd_flag_none, 3599 "<addr> = TDLS link status with <addr>" }, 3600 { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL, 3601 cli_cmd_flag_none, 3602 "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] " 3603 "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] " 3604 "= add WMM-AC traffic stream" }, 3605 { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL, 3606 cli_cmd_flag_none, 3607 "<tsid> = delete WMM-AC traffic stream" }, 3608 { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL, 3609 cli_cmd_flag_none, 3610 "= show status for Wireless Multi-Media Admission-Control" }, 3611 { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL, 3612 cli_cmd_flag_none, 3613 "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] " 3614 "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching " 3615 "with TDLS peer" }, 3616 { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL, 3617 cli_cmd_flag_none, 3618 "<addr> = disable channel switching with TDLS peer <addr>" }, 3619 { "signal_poll", wpa_cli_cmd_signal_poll, NULL, 3620 cli_cmd_flag_none, 3621 "= get signal parameters" }, 3622 { "signal_monitor", wpa_cli_cmd_signal_monitor, NULL, 3623 cli_cmd_flag_none, 3624 "= set signal monitor parameters" }, 3625 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL, 3626 cli_cmd_flag_none, 3627 "= get TX/RX packet counters" }, 3628 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL, 3629 cli_cmd_flag_none, 3630 "= trigger IEEE 802.1X/EAPOL reauthentication" }, 3631 #ifdef CONFIG_AUTOSCAN 3632 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none, 3633 "[params] = Set or unset (if none) autoscan parameters" }, 3634 #endif /* CONFIG_AUTOSCAN */ 3635 #ifdef CONFIG_WNM 3636 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none, 3637 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" }, 3638 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none, 3639 "<query reason> [list]" 3640 " [neighbor=<BSSID>,<BSSID information>,<operating class>,<channel number>,<PHY type>[,<hexdump of optional subelements>]" 3641 " = Send BSS Transition Management Query" }, 3642 #endif /* CONFIG_WNM */ 3643 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive, 3644 "<params..> = Sent unprocessed command" }, 3645 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none, 3646 "= flush wpa_supplicant state" }, 3647 #ifdef ANDROID 3648 { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none, 3649 "<command> = driver private commands" }, 3650 #endif /* ANDROID */ 3651 { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none, 3652 "= radio_work <show/add/done>" }, 3653 { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none, 3654 "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command" 3655 }, 3656 { "neighbor_rep_request", 3657 wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none, 3658 "[ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring AP report (with optional given SSID in hex or enclosed in double quotes, default: current SSID; with optional LCI and location civic request)" 3659 }, 3660 { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none, 3661 "= flush ERP keys" }, 3662 { "mac_rand_scan", 3663 wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none, 3664 "<scan|sched|pno|all> enable=<0/1> [addr=mac-address " 3665 "mask=mac-address-mask] = scan MAC randomization" 3666 }, 3667 { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL, 3668 cli_cmd_flag_none, 3669 "<interface type> = retrieve preferred freq list for the specified interface type" }, 3670 { "p2p_lo_start", wpa_cli_cmd_p2p_lo_start, NULL, 3671 cli_cmd_flag_none, 3672 "<freq> <period> <interval> <count> = start P2P listen offload" }, 3673 { "p2p_lo_stop", wpa_cli_cmd_p2p_lo_stop, NULL, 3674 cli_cmd_flag_none, 3675 "= stop P2P listen offload" }, 3676 #ifdef CONFIG_DPP 3677 { "dpp_qr_code", wpa_cli_cmd_dpp_qr_code, NULL, cli_cmd_flag_none, 3678 "report a scanned DPP URI from a QR Code" }, 3679 { "dpp_bootstrap_gen", wpa_cli_cmd_dpp_bootstrap_gen, NULL, 3680 cli_cmd_flag_sensitive, 3681 "type=<qrcode> [chan=..] [mac=..] [info=..] [curve=..] [key=..] = generate DPP bootstrap information" }, 3682 { "dpp_bootstrap_remove", wpa_cli_cmd_dpp_bootstrap_remove, NULL, 3683 cli_cmd_flag_none, 3684 "*|<id> = remove DPP bootstrap information" }, 3685 { "dpp_bootstrap_get_uri", wpa_cli_cmd_dpp_bootstrap_get_uri, NULL, 3686 cli_cmd_flag_none, 3687 "<id> = get DPP bootstrap URI" }, 3688 { "dpp_bootstrap_info", wpa_cli_cmd_dpp_bootstrap_info, NULL, 3689 cli_cmd_flag_none, 3690 "<id> = show DPP bootstrap information" }, 3691 { "dpp_auth_init", wpa_cli_cmd_dpp_auth_init, NULL, cli_cmd_flag_none, 3692 "peer=<id> [own=<id>] = initiate DPP bootstrapping" }, 3693 { "dpp_listen", wpa_cli_cmd_dpp_listen, NULL, cli_cmd_flag_none, 3694 "<freq in MHz> = start DPP listen" }, 3695 { "dpp_stop_listen", wpa_cli_cmd_dpp_stop_listen, NULL, 3696 cli_cmd_flag_none, 3697 "= stop DPP listen" }, 3698 { "dpp_configurator_add", wpa_cli_cmd_dpp_configurator_add, NULL, 3699 cli_cmd_flag_sensitive, 3700 "[curve=..] [key=..] = add DPP configurator" }, 3701 { "dpp_configurator_remove", wpa_cli_cmd_dpp_configurator_remove, NULL, 3702 cli_cmd_flag_none, 3703 "*|<id> = remove DPP configurator" }, 3704 { "dpp_configurator_get_key", wpa_cli_cmd_dpp_configurator_get_key, 3705 NULL, cli_cmd_flag_none, 3706 "<id> = Get DPP configurator's private key" }, 3707 { "dpp_configurator_sign", wpa_cli_cmd_dpp_configurator_sign, NULL, 3708 cli_cmd_flag_none, 3709 "conf=<role> configurator=<id> = generate self DPP configuration" }, 3710 { "dpp_pkex_add", wpa_cli_cmd_dpp_pkex_add, NULL, 3711 cli_cmd_flag_sensitive, 3712 "add PKEX code" }, 3713 { "dpp_pkex_remove", wpa_cli_cmd_dpp_pkex_remove, NULL, 3714 cli_cmd_flag_none, 3715 "*|<id> = remove DPP pkex information" }, 3716 #endif /* CONFIG_DPP */ 3717 { NULL, NULL, NULL, cli_cmd_flag_none, NULL } 3718 }; 3719 3720 3721 /* 3722 * Prints command usage, lines are padded with the specified string. 3723 */ 3724 static void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad) 3725 { 3726 char c; 3727 size_t n; 3728 3729 printf("%s%s ", pad, cmd->cmd); 3730 for (n = 0; (c = cmd->usage[n]); n++) { 3731 printf("%c", c); 3732 if (c == '\n') 3733 printf("%s", pad); 3734 } 3735 printf("\n"); 3736 } 3737 3738 3739 static void print_help(const char *cmd) 3740 { 3741 int n; 3742 printf("commands:\n"); 3743 for (n = 0; wpa_cli_commands[n].cmd; n++) { 3744 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd)) 3745 print_cmd_help(&wpa_cli_commands[n], " "); 3746 } 3747 } 3748 3749 3750 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd) 3751 { 3752 const char *c, *delim; 3753 int n; 3754 size_t len; 3755 3756 delim = os_strchr(cmd, ' '); 3757 if (delim) 3758 len = delim - cmd; 3759 else 3760 len = os_strlen(cmd); 3761 3762 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) { 3763 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c)) 3764 return (wpa_cli_commands[n].flags & 3765 cli_cmd_flag_sensitive); 3766 } 3767 return 0; 3768 } 3769 3770 3771 static char ** wpa_list_cmd_list(void) 3772 { 3773 char **res; 3774 int i, count; 3775 struct cli_txt_entry *e; 3776 3777 count = ARRAY_SIZE(wpa_cli_commands); 3778 count += dl_list_len(&p2p_groups); 3779 count += dl_list_len(&ifnames); 3780 res = os_calloc(count + 1, sizeof(char *)); 3781 if (res == NULL) 3782 return NULL; 3783 3784 for (i = 0; wpa_cli_commands[i].cmd; i++) { 3785 res[i] = os_strdup(wpa_cli_commands[i].cmd); 3786 if (res[i] == NULL) 3787 break; 3788 } 3789 3790 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) { 3791 size_t len = 8 + os_strlen(e->txt); 3792 res[i] = os_malloc(len); 3793 if (res[i] == NULL) 3794 break; 3795 os_snprintf(res[i], len, "ifname=%s", e->txt); 3796 i++; 3797 } 3798 3799 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) { 3800 res[i] = os_strdup(e->txt); 3801 if (res[i] == NULL) 3802 break; 3803 i++; 3804 } 3805 3806 return res; 3807 } 3808 3809 3810 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str, 3811 int pos) 3812 { 3813 int i; 3814 3815 for (i = 0; wpa_cli_commands[i].cmd; i++) { 3816 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) { 3817 if (wpa_cli_commands[i].completion) 3818 return wpa_cli_commands[i].completion(str, 3819 pos); 3820 edit_clear_line(); 3821 printf("\r%s\n", wpa_cli_commands[i].usage); 3822 edit_redraw(); 3823 break; 3824 } 3825 } 3826 3827 return NULL; 3828 } 3829 3830 3831 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos) 3832 { 3833 char **res; 3834 const char *end; 3835 char *cmd; 3836 3837 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) { 3838 end = os_strchr(str, ' '); 3839 if (end && pos > end - str) { 3840 pos -= end - str + 1; 3841 str = end + 1; 3842 } 3843 } 3844 3845 end = os_strchr(str, ' '); 3846 if (end == NULL || str + pos < end) 3847 return wpa_list_cmd_list(); 3848 3849 cmd = os_malloc(pos + 1); 3850 if (cmd == NULL) 3851 return NULL; 3852 os_memcpy(cmd, str, pos); 3853 cmd[end - str] = '\0'; 3854 res = wpa_cli_cmd_completion(cmd, str, pos); 3855 os_free(cmd); 3856 return res; 3857 } 3858 3859 3860 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) 3861 { 3862 const struct wpa_cli_cmd *cmd, *match = NULL; 3863 int count; 3864 int ret = 0; 3865 3866 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) { 3867 ifname_prefix = argv[0] + 7; 3868 argv = &argv[1]; 3869 argc--; 3870 } else 3871 ifname_prefix = NULL; 3872 3873 if (argc == 0) 3874 return -1; 3875 3876 count = 0; 3877 cmd = wpa_cli_commands; 3878 while (cmd->cmd) { 3879 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0) 3880 { 3881 match = cmd; 3882 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { 3883 /* we have an exact match */ 3884 count = 1; 3885 break; 3886 } 3887 count++; 3888 } 3889 cmd++; 3890 } 3891 3892 if (count > 1) { 3893 printf("Ambiguous command '%s'; possible commands:", argv[0]); 3894 cmd = wpa_cli_commands; 3895 while (cmd->cmd) { 3896 if (os_strncasecmp(cmd->cmd, argv[0], 3897 os_strlen(argv[0])) == 0) { 3898 printf(" %s", cmd->cmd); 3899 } 3900 cmd++; 3901 } 3902 printf("\n"); 3903 ret = 1; 3904 } else if (count == 0) { 3905 printf("Unknown command '%s'\n", argv[0]); 3906 ret = 1; 3907 } else { 3908 ret = match->handler(ctrl, argc - 1, &argv[1]); 3909 } 3910 3911 return ret; 3912 } 3913 3914 3915 static int wpa_cli_exec(const char *program, const char *arg1, 3916 const char *arg2) 3917 { 3918 char *arg; 3919 size_t len; 3920 int res; 3921 3922 /* If no interface is specified, set the global */ 3923 if (!arg1) 3924 arg1 = "global"; 3925 3926 len = os_strlen(arg1) + os_strlen(arg2) + 2; 3927 arg = os_malloc(len); 3928 if (arg == NULL) 3929 return -1; 3930 os_snprintf(arg, len, "%s %s", arg1, arg2); 3931 res = os_exec(program, arg, 1); 3932 os_free(arg); 3933 3934 return res; 3935 } 3936 3937 3938 static void wpa_cli_action_process(const char *msg) 3939 { 3940 const char *pos; 3941 char *copy = NULL, *id, *pos2; 3942 const char *ifname = ctrl_ifname; 3943 char ifname_buf[100]; 3944 3945 if (eloop_terminated()) 3946 return; 3947 3948 pos = msg; 3949 if (os_strncmp(pos, "IFNAME=", 7) == 0) { 3950 const char *end; 3951 end = os_strchr(pos + 7, ' '); 3952 if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) { 3953 pos += 7; 3954 os_memcpy(ifname_buf, pos, end - pos); 3955 ifname_buf[end - pos] = '\0'; 3956 ifname = ifname_buf; 3957 pos = end + 1; 3958 } 3959 } 3960 pos = skip_priority(msg); 3961 3962 if (str_starts(pos, WPA_EVENT_CONNECTED)) { 3963 int new_id = -1; 3964 char *id, *copy; 3965 os_unsetenv("WPA_ID"); 3966 os_unsetenv("WPA_ID_STR"); 3967 os_unsetenv("WPA_CTRL_DIR"); 3968 3969 pos = os_strstr(pos, "[id="); 3970 copy = pos ? os_strdup(pos + 4) : NULL; 3971 3972 if (copy) { 3973 char *pos2 = id = copy; 3974 while (*pos2 && *pos2 != ' ') 3975 pos2++; 3976 *pos2++ = '\0'; 3977 new_id = atoi(id); 3978 os_setenv("WPA_ID", id, 1); 3979 while (*pos2 && *pos2 != '=') 3980 pos2++; 3981 if (*pos2 == '=') 3982 pos2++; 3983 id = pos2; 3984 while (*pos2 && *pos2 != ']') 3985 pos2++; 3986 *pos2 = '\0'; 3987 os_setenv("WPA_ID_STR", id, 1); 3988 os_free(copy); 3989 } 3990 3991 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); 3992 3993 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) { 3994 wpa_cli_connected = 1; 3995 wpa_cli_last_id = new_id; 3996 wpa_cli_exec(action_file, ifname, "CONNECTED"); 3997 } 3998 } else if (str_starts(pos, WPA_EVENT_DISCONNECTED)) { 3999 if (wpa_cli_connected) { 4000 wpa_cli_connected = 0; 4001 wpa_cli_exec(action_file, ifname, "DISCONNECTED"); 4002 } 4003 } else if (str_starts(pos, WPA_EVENT_CHANNEL_SWITCH_STARTED)) { 4004 wpa_cli_exec(action_file, ctrl_ifname, pos); 4005 } else if (str_starts(pos, AP_EVENT_ENABLED)) { 4006 wpa_cli_exec(action_file, ctrl_ifname, pos); 4007 } else if (str_starts(pos, AP_EVENT_DISABLED)) { 4008 wpa_cli_exec(action_file, ctrl_ifname, pos); 4009 } else if (str_starts(pos, MESH_GROUP_STARTED)) { 4010 wpa_cli_exec(action_file, ctrl_ifname, pos); 4011 } else if (str_starts(pos, MESH_GROUP_REMOVED)) { 4012 wpa_cli_exec(action_file, ctrl_ifname, pos); 4013 } else if (str_starts(pos, MESH_PEER_CONNECTED)) { 4014 wpa_cli_exec(action_file, ctrl_ifname, pos); 4015 } else if (str_starts(pos, MESH_PEER_DISCONNECTED)) { 4016 wpa_cli_exec(action_file, ctrl_ifname, pos); 4017 } else if (str_starts(pos, P2P_EVENT_GROUP_STARTED)) { 4018 wpa_cli_exec(action_file, ifname, pos); 4019 } else if (str_starts(pos, P2P_EVENT_GROUP_REMOVED)) { 4020 wpa_cli_exec(action_file, ifname, pos); 4021 } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) { 4022 wpa_cli_exec(action_file, ifname, pos); 4023 } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) { 4024 wpa_cli_exec(action_file, ifname, pos); 4025 } else if (str_starts(pos, P2P_EVENT_GO_NEG_FAILURE)) { 4026 wpa_cli_exec(action_file, ifname, pos); 4027 } else if (str_starts(pos, WPS_EVENT_SUCCESS)) { 4028 wpa_cli_exec(action_file, ifname, pos); 4029 } else if (str_starts(pos, WPS_EVENT_ACTIVE)) { 4030 wpa_cli_exec(action_file, ifname, pos); 4031 } else if (str_starts(pos, WPS_EVENT_TIMEOUT)) { 4032 wpa_cli_exec(action_file, ifname, pos); 4033 } else if (str_starts(pos, WPS_EVENT_FAIL)) { 4034 wpa_cli_exec(action_file, ifname, pos); 4035 } else if (str_starts(pos, AP_STA_CONNECTED)) { 4036 wpa_cli_exec(action_file, ifname, pos); 4037 } else if (str_starts(pos, AP_STA_DISCONNECTED)) { 4038 wpa_cli_exec(action_file, ifname, pos); 4039 } else if (str_starts(pos, ESS_DISASSOC_IMMINENT)) { 4040 wpa_cli_exec(action_file, ifname, pos); 4041 } else if (str_starts(pos, HS20_SUBSCRIPTION_REMEDIATION)) { 4042 wpa_cli_exec(action_file, ifname, pos); 4043 } else if (str_starts(pos, HS20_DEAUTH_IMMINENT_NOTICE)) { 4044 wpa_cli_exec(action_file, ifname, pos); 4045 } else if (str_starts(pos, HS20_T_C_ACCEPTANCE)) { 4046 wpa_cli_exec(action_file, ifname, pos); 4047 } else if (str_starts(pos, DPP_EVENT_CONF_RECEIVED)) { 4048 wpa_cli_exec(action_file, ifname, pos); 4049 } else if (str_starts(pos, DPP_EVENT_CONFOBJ_AKM)) { 4050 wpa_cli_exec(action_file, ifname, pos); 4051 } else if (str_starts(pos, DPP_EVENT_CONFOBJ_SSID)) { 4052 wpa_cli_exec(action_file, ifname, pos); 4053 } else if (str_starts(pos, DPP_EVENT_CONNECTOR)) { 4054 wpa_cli_exec(action_file, ifname, pos); 4055 } else if (str_starts(pos, DPP_EVENT_CONFOBJ_PASS)) { 4056 wpa_cli_exec(action_file, ifname, pos); 4057 } else if (str_starts(pos, DPP_EVENT_CONFOBJ_PSK)) { 4058 wpa_cli_exec(action_file, ifname, pos); 4059 } else if (str_starts(pos, DPP_EVENT_C_SIGN_KEY)) { 4060 wpa_cli_exec(action_file, ifname, pos); 4061 } else if (str_starts(pos, DPP_EVENT_NET_ACCESS_KEY)) { 4062 wpa_cli_exec(action_file, ifname, pos); 4063 } else if (str_starts(pos, WPA_EVENT_TERMINATING)) { 4064 printf("wpa_supplicant is terminating - stop monitoring\n"); 4065 wpa_cli_quit = 1; 4066 } 4067 } 4068 4069 4070 #ifndef CONFIG_ANSI_C_EXTRA 4071 static void wpa_cli_action_cb(char *msg, size_t len) 4072 { 4073 wpa_cli_action_process(msg); 4074 } 4075 #endif /* CONFIG_ANSI_C_EXTRA */ 4076 4077 4078 static int wpa_cli_open_global_ctrl(void) 4079 { 4080 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4081 ctrl_conn = wpa_ctrl_open(NULL); 4082 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4083 ctrl_conn = wpa_ctrl_open(global); 4084 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4085 if (!ctrl_conn) { 4086 fprintf(stderr, 4087 "Failed to connect to wpa_supplicant global interface: %s error: %s\n", 4088 global, strerror(errno)); 4089 return -1; 4090 } 4091 4092 if (interactive) { 4093 update_ifnames(ctrl_conn); 4094 mon_conn = wpa_ctrl_open(global); 4095 if (mon_conn) { 4096 if (wpa_ctrl_attach(mon_conn) == 0) { 4097 wpa_cli_attached = 1; 4098 eloop_register_read_sock( 4099 wpa_ctrl_get_fd(mon_conn), 4100 wpa_cli_mon_receive, 4101 NULL, NULL); 4102 } else { 4103 printf("Failed to open monitor connection through global control interface\n"); 4104 } 4105 } 4106 update_stations(ctrl_conn); 4107 } 4108 4109 return 0; 4110 } 4111 4112 4113 static void wpa_cli_reconnect(void) 4114 { 4115 wpa_cli_close_connection(); 4116 if ((global && wpa_cli_open_global_ctrl() < 0) || 4117 (!global && wpa_cli_open_connection(ctrl_ifname, 1) < 0)) 4118 return; 4119 4120 if (interactive) { 4121 edit_clear_line(); 4122 printf("\rConnection to wpa_supplicant re-established\n"); 4123 edit_redraw(); 4124 update_stations(ctrl_conn); 4125 } 4126 } 4127 4128 4129 static void cli_event(const char *str) 4130 { 4131 const char *start, *s; 4132 4133 start = os_strchr(str, '>'); 4134 if (start == NULL) 4135 return; 4136 4137 start++; 4138 4139 if (str_starts(start, WPA_EVENT_BSS_ADDED)) { 4140 s = os_strchr(start, ' '); 4141 if (s == NULL) 4142 return; 4143 s = os_strchr(s + 1, ' '); 4144 if (s == NULL) 4145 return; 4146 cli_txt_list_add(&bsses, s + 1); 4147 return; 4148 } 4149 4150 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) { 4151 s = os_strchr(start, ' '); 4152 if (s == NULL) 4153 return; 4154 s = os_strchr(s + 1, ' '); 4155 if (s == NULL) 4156 return; 4157 cli_txt_list_del_addr(&bsses, s + 1); 4158 return; 4159 } 4160 4161 #ifdef CONFIG_P2P 4162 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) { 4163 s = os_strstr(start, " p2p_dev_addr="); 4164 if (s == NULL) 4165 return; 4166 cli_txt_list_add_addr(&p2p_peers, s + 14); 4167 return; 4168 } 4169 4170 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) { 4171 s = os_strstr(start, " p2p_dev_addr="); 4172 if (s == NULL) 4173 return; 4174 cli_txt_list_del_addr(&p2p_peers, s + 14); 4175 return; 4176 } 4177 4178 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) { 4179 s = os_strchr(start, ' '); 4180 if (s == NULL) 4181 return; 4182 cli_txt_list_add_word(&p2p_groups, s + 1, ' '); 4183 return; 4184 } 4185 4186 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) { 4187 s = os_strchr(start, ' '); 4188 if (s == NULL) 4189 return; 4190 cli_txt_list_del_word(&p2p_groups, s + 1, ' '); 4191 return; 4192 } 4193 #endif /* CONFIG_P2P */ 4194 } 4195 4196 4197 static int check_terminating(const char *msg) 4198 { 4199 const char *pos = msg; 4200 4201 if (*pos == '<') { 4202 /* skip priority */ 4203 pos = os_strchr(pos, '>'); 4204 if (pos) 4205 pos++; 4206 else 4207 pos = msg; 4208 } 4209 4210 if (str_starts(pos, WPA_EVENT_TERMINATING) && ctrl_conn) { 4211 edit_clear_line(); 4212 printf("\rConnection to wpa_supplicant lost - trying to " 4213 "reconnect\n"); 4214 edit_redraw(); 4215 wpa_cli_attached = 0; 4216 wpa_cli_close_connection(); 4217 return 1; 4218 } 4219 4220 return 0; 4221 } 4222 4223 4224 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor) 4225 { 4226 if (ctrl_conn == NULL) { 4227 wpa_cli_reconnect(); 4228 return; 4229 } 4230 while (wpa_ctrl_pending(ctrl) > 0) { 4231 char buf[4096]; 4232 size_t len = sizeof(buf) - 1; 4233 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { 4234 buf[len] = '\0'; 4235 if (action_monitor) 4236 wpa_cli_action_process(buf); 4237 else { 4238 cli_event(buf); 4239 if (wpa_cli_show_event(buf)) { 4240 edit_clear_line(); 4241 wpa_cli_msg_cb(buf, 0); 4242 edit_redraw(); 4243 } 4244 4245 if (interactive && check_terminating(buf) > 0) 4246 return; 4247 } 4248 } else { 4249 printf("Could not read pending message.\n"); 4250 break; 4251 } 4252 } 4253 4254 if (wpa_ctrl_pending(ctrl) < 0) { 4255 printf("Connection to wpa_supplicant lost - trying to " 4256 "reconnect\n"); 4257 wpa_cli_reconnect(); 4258 } 4259 } 4260 4261 4262 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx) 4263 { 4264 if (ctrl_conn) { 4265 int res; 4266 char *prefix = ifname_prefix; 4267 4268 ifname_prefix = NULL; 4269 res = _wpa_ctrl_command(ctrl_conn, "PING", 0); 4270 ifname_prefix = prefix; 4271 if (res) { 4272 printf("Connection to wpa_supplicant lost - trying to " 4273 "reconnect\n"); 4274 wpa_cli_close_connection(); 4275 } 4276 } 4277 if (!ctrl_conn) 4278 wpa_cli_reconnect(); 4279 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 4280 } 4281 4282 4283 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx) 4284 { 4285 wpa_cli_recv_pending(mon_conn, 0); 4286 } 4287 4288 4289 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd) 4290 { 4291 char *argv[max_args]; 4292 int argc; 4293 argc = tokenize_cmd(cmd, argv); 4294 if (argc) 4295 wpa_request(ctrl_conn, argc, argv); 4296 } 4297 4298 4299 static void wpa_cli_edit_eof_cb(void *ctx) 4300 { 4301 eloop_terminate(); 4302 } 4303 4304 4305 static int warning_displayed = 0; 4306 static char *hfile = NULL; 4307 static int edit_started = 0; 4308 4309 static void start_edit(void) 4310 { 4311 char *home; 4312 char *ps = NULL; 4313 4314 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE 4315 ps = wpa_ctrl_get_remote_ifname(ctrl_conn); 4316 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ 4317 4318 #ifdef CONFIG_WPA_CLI_HISTORY_DIR 4319 home = CONFIG_WPA_CLI_HISTORY_DIR; 4320 #else /* CONFIG_WPA_CLI_HISTORY_DIR */ 4321 home = getenv("HOME"); 4322 #endif /* CONFIG_WPA_CLI_HISTORY_DIR */ 4323 if (home) { 4324 const char *fname = ".wpa_cli_history"; 4325 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; 4326 hfile = os_malloc(hfile_len); 4327 if (hfile) 4328 os_snprintf(hfile, hfile_len, "%s/%s", home, fname); 4329 } 4330 4331 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, 4332 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) { 4333 eloop_terminate(); 4334 return; 4335 } 4336 4337 edit_started = 1; 4338 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 4339 } 4340 4341 4342 static void update_bssid_list(struct wpa_ctrl *ctrl) 4343 { 4344 char buf[4096]; 4345 size_t len = sizeof(buf); 4346 int ret; 4347 const char *cmd = "BSS RANGE=ALL MASK=0x2"; 4348 char *pos, *end; 4349 4350 if (ctrl == NULL) 4351 return; 4352 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4353 if (ret < 0) 4354 return; 4355 buf[len] = '\0'; 4356 4357 pos = buf; 4358 while (pos) { 4359 pos = os_strstr(pos, "bssid="); 4360 if (pos == NULL) 4361 break; 4362 pos += 6; 4363 end = os_strchr(pos, '\n'); 4364 if (end == NULL) 4365 break; 4366 *end = '\0'; 4367 cli_txt_list_add(&bsses, pos); 4368 pos = end + 1; 4369 } 4370 } 4371 4372 4373 static void update_ifnames(struct wpa_ctrl *ctrl) 4374 { 4375 char buf[4096]; 4376 size_t len = sizeof(buf); 4377 int ret; 4378 const char *cmd = "INTERFACES"; 4379 char *pos, *end; 4380 char txt[200]; 4381 4382 cli_txt_list_flush(&ifnames); 4383 4384 if (ctrl == NULL) 4385 return; 4386 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4387 if (ret < 0) 4388 return; 4389 buf[len] = '\0'; 4390 4391 pos = buf; 4392 while (pos) { 4393 end = os_strchr(pos, '\n'); 4394 if (end == NULL) 4395 break; 4396 *end = '\0'; 4397 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos); 4398 if (!os_snprintf_error(sizeof(txt), ret)) 4399 cli_txt_list_add(&ifnames, txt); 4400 pos = end + 1; 4401 } 4402 } 4403 4404 4405 static void update_creds(struct wpa_ctrl *ctrl) 4406 { 4407 char buf[4096]; 4408 size_t len = sizeof(buf); 4409 int ret; 4410 const char *cmd = "LIST_CREDS"; 4411 char *pos, *end; 4412 int header = 1; 4413 4414 cli_txt_list_flush(&creds); 4415 4416 if (ctrl == NULL) 4417 return; 4418 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4419 if (ret < 0) 4420 return; 4421 buf[len] = '\0'; 4422 4423 pos = buf; 4424 while (pos) { 4425 end = os_strchr(pos, '\n'); 4426 if (end == NULL) 4427 break; 4428 *end = '\0'; 4429 if (!header) 4430 cli_txt_list_add_word(&creds, pos, '\t'); 4431 header = 0; 4432 pos = end + 1; 4433 } 4434 } 4435 4436 4437 static void update_networks(struct wpa_ctrl *ctrl) 4438 { 4439 char buf[4096]; 4440 size_t len = sizeof(buf); 4441 int ret; 4442 const char *cmd = "LIST_NETWORKS"; 4443 char *pos, *end; 4444 int header = 1; 4445 4446 cli_txt_list_flush(&networks); 4447 4448 if (ctrl == NULL) 4449 return; 4450 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4451 if (ret < 0) 4452 return; 4453 buf[len] = '\0'; 4454 4455 pos = buf; 4456 while (pos) { 4457 end = os_strchr(pos, '\n'); 4458 if (end == NULL) 4459 break; 4460 *end = '\0'; 4461 if (!header) 4462 cli_txt_list_add_word(&networks, pos, '\t'); 4463 header = 0; 4464 pos = end + 1; 4465 } 4466 } 4467 4468 4469 static void update_stations(struct wpa_ctrl *ctrl) 4470 { 4471 #ifdef CONFIG_AP 4472 char addr[32], cmd[64]; 4473 4474 if (!ctrl || !interactive) 4475 return; 4476 4477 cli_txt_list_flush(&stations); 4478 4479 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) 4480 return; 4481 do { 4482 if (os_strcmp(addr, "") != 0) 4483 cli_txt_list_add(&stations, addr); 4484 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 4485 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); 4486 #endif /* CONFIG_AP */ 4487 } 4488 4489 4490 static void try_connection(void *eloop_ctx, void *timeout_ctx) 4491 { 4492 if (ctrl_conn) 4493 goto done; 4494 4495 if (ctrl_ifname == NULL) 4496 ctrl_ifname = wpa_cli_get_default_ifname(); 4497 4498 if (wpa_cli_open_connection(ctrl_ifname, 1)) { 4499 if (!warning_displayed) { 4500 printf("Could not connect to wpa_supplicant: " 4501 "%s - re-trying\n", 4502 ctrl_ifname ? ctrl_ifname : "(nil)"); 4503 warning_displayed = 1; 4504 } 4505 eloop_register_timeout(1, 0, try_connection, NULL, NULL); 4506 return; 4507 } 4508 4509 update_bssid_list(ctrl_conn); 4510 update_creds(ctrl_conn); 4511 update_networks(ctrl_conn); 4512 update_stations(ctrl_conn); 4513 4514 if (warning_displayed) 4515 printf("Connection established.\n"); 4516 4517 done: 4518 start_edit(); 4519 } 4520 4521 4522 static void wpa_cli_interactive(void) 4523 { 4524 printf("\nInteractive mode\n\n"); 4525 4526 eloop_register_timeout(0, 0, try_connection, NULL, NULL); 4527 eloop_run(); 4528 eloop_cancel_timeout(try_connection, NULL, NULL); 4529 4530 cli_txt_list_flush(&p2p_peers); 4531 cli_txt_list_flush(&p2p_groups); 4532 cli_txt_list_flush(&bsses); 4533 cli_txt_list_flush(&ifnames); 4534 cli_txt_list_flush(&creds); 4535 cli_txt_list_flush(&networks); 4536 if (edit_started) 4537 edit_deinit(hfile, wpa_cli_edit_filter_history_cb); 4538 os_free(hfile); 4539 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL); 4540 wpa_cli_close_connection(); 4541 } 4542 4543 4544 static void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx) 4545 { 4546 struct wpa_ctrl *ctrl = eloop_ctx; 4547 char buf[256]; 4548 size_t len; 4549 4550 /* verify that connection is still working */ 4551 len = sizeof(buf) - 1; 4552 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, 4553 wpa_cli_action_cb) < 0 || 4554 len < 4 || os_memcmp(buf, "PONG", 4) != 0) { 4555 printf("wpa_supplicant did not reply to PING command - exiting\n"); 4556 eloop_terminate(); 4557 return; 4558 } 4559 eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping, 4560 ctrl, NULL); 4561 } 4562 4563 4564 static void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx) 4565 { 4566 struct wpa_ctrl *ctrl = eloop_ctx; 4567 4568 wpa_cli_recv_pending(ctrl, 1); 4569 } 4570 4571 4572 static void wpa_cli_action(struct wpa_ctrl *ctrl) 4573 { 4574 #ifdef CONFIG_ANSI_C_EXTRA 4575 /* TODO: ANSI C version(?) */ 4576 printf("Action processing not supported in ANSI C build.\n"); 4577 #else /* CONFIG_ANSI_C_EXTRA */ 4578 int fd; 4579 4580 fd = wpa_ctrl_get_fd(ctrl); 4581 eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping, 4582 ctrl, NULL); 4583 eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL); 4584 eloop_run(); 4585 eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL); 4586 eloop_unregister_read_sock(fd); 4587 #endif /* CONFIG_ANSI_C_EXTRA */ 4588 } 4589 4590 4591 static void wpa_cli_cleanup(void) 4592 { 4593 wpa_cli_close_connection(); 4594 if (pid_file) 4595 os_daemonize_terminate(pid_file); 4596 4597 os_program_deinit(); 4598 } 4599 4600 4601 static void wpa_cli_terminate(int sig, void *ctx) 4602 { 4603 eloop_terminate(); 4604 } 4605 4606 4607 static char * wpa_cli_get_default_ifname(void) 4608 { 4609 char *ifname = NULL; 4610 4611 #ifdef ANDROID 4612 char ifprop[PROPERTY_VALUE_MAX]; 4613 if (property_get("wifi.interface", ifprop, NULL) != 0) { 4614 ifname = os_strdup(ifprop); 4615 printf("Using interface '%s'\n", ifname ? ifname : "N/A"); 4616 } 4617 #else /* ANDROID */ 4618 #ifdef CONFIG_CTRL_IFACE_UNIX 4619 struct dirent *dent; 4620 DIR *dir = opendir(ctrl_iface_dir); 4621 if (!dir) { 4622 return NULL; 4623 } 4624 while ((dent = readdir(dir))) { 4625 #ifdef _DIRENT_HAVE_D_TYPE 4626 /* 4627 * Skip the file if it is not a socket. Also accept 4628 * DT_UNKNOWN (0) in case the C library or underlying 4629 * file system does not support d_type. 4630 */ 4631 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) 4632 continue; 4633 #endif /* _DIRENT_HAVE_D_TYPE */ 4634 if (os_strcmp(dent->d_name, ".") == 0 || 4635 os_strcmp(dent->d_name, "..") == 0) 4636 continue; 4637 printf("Selected interface '%s'\n", dent->d_name); 4638 ifname = os_strdup(dent->d_name); 4639 break; 4640 } 4641 closedir(dir); 4642 #endif /* CONFIG_CTRL_IFACE_UNIX */ 4643 4644 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4645 char buf[4096], *pos; 4646 size_t len; 4647 struct wpa_ctrl *ctrl; 4648 int ret; 4649 4650 ctrl = wpa_ctrl_open(NULL); 4651 if (ctrl == NULL) 4652 return NULL; 4653 4654 len = sizeof(buf) - 1; 4655 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); 4656 if (ret >= 0) { 4657 buf[len] = '\0'; 4658 pos = os_strchr(buf, '\n'); 4659 if (pos) 4660 *pos = '\0'; 4661 ifname = os_strdup(buf); 4662 } 4663 wpa_ctrl_close(ctrl); 4664 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4665 #endif /* ANDROID */ 4666 4667 return ifname; 4668 } 4669 4670 4671 int main(int argc, char *argv[]) 4672 { 4673 int c; 4674 int daemonize = 0; 4675 int ret = 0; 4676 4677 if (os_program_init()) 4678 return -1; 4679 4680 for (;;) { 4681 c = getopt(argc, argv, "a:Bg:G:hi:p:P:s:v"); 4682 if (c < 0) 4683 break; 4684 switch (c) { 4685 case 'a': 4686 action_file = optarg; 4687 break; 4688 case 'B': 4689 daemonize = 1; 4690 break; 4691 case 'g': 4692 global = optarg; 4693 break; 4694 case 'G': 4695 ping_interval = atoi(optarg); 4696 break; 4697 case 'h': 4698 usage(); 4699 return 0; 4700 case 'v': 4701 printf("%s\n", wpa_cli_version); 4702 return 0; 4703 case 'i': 4704 os_free(ctrl_ifname); 4705 ctrl_ifname = os_strdup(optarg); 4706 break; 4707 case 'p': 4708 ctrl_iface_dir = optarg; 4709 break; 4710 case 'P': 4711 pid_file = optarg; 4712 break; 4713 case 's': 4714 client_socket_dir = optarg; 4715 break; 4716 default: 4717 usage(); 4718 return -1; 4719 } 4720 } 4721 4722 interactive = (argc == optind) && (action_file == NULL); 4723 4724 if (interactive) 4725 printf("%s\n\n%s\n\n", wpa_cli_version, cli_license); 4726 4727 if (eloop_init()) 4728 return -1; 4729 4730 if (global && wpa_cli_open_global_ctrl() < 0) 4731 return -1; 4732 4733 eloop_register_signal_terminate(wpa_cli_terminate, NULL); 4734 4735 if (ctrl_ifname == NULL) 4736 ctrl_ifname = wpa_cli_get_default_ifname(); 4737 4738 if (interactive) { 4739 wpa_cli_interactive(); 4740 } else { 4741 if (!global && 4742 wpa_cli_open_connection(ctrl_ifname, 0) < 0) { 4743 fprintf(stderr, "Failed to connect to non-global " 4744 "ctrl_ifname: %s error: %s\n", 4745 ctrl_ifname ? ctrl_ifname : "(nil)", 4746 strerror(errno)); 4747 return -1; 4748 } 4749 4750 if (action_file) { 4751 if (wpa_ctrl_attach(ctrl_conn) == 0) { 4752 wpa_cli_attached = 1; 4753 } else { 4754 printf("Warning: Failed to attach to " 4755 "wpa_supplicant.\n"); 4756 return -1; 4757 } 4758 } 4759 4760 if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue()) 4761 return -1; 4762 4763 if (action_file) 4764 wpa_cli_action(ctrl_conn); 4765 else 4766 ret = wpa_request(ctrl_conn, argc - optind, 4767 &argv[optind]); 4768 } 4769 4770 os_free(ctrl_ifname); 4771 eloop_destroy(); 4772 wpa_cli_cleanup(); 4773 4774 return ret; 4775 } 4776 4777 #else /* CONFIG_CTRL_IFACE */ 4778 int main(int argc, char *argv[]) 4779 { 4780 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n"); 4781 return -1; 4782 } 4783 #endif /* CONFIG_CTRL_IFACE */ 4784