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