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