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