1 /* 2 * WPA Supplicant / Control interface (shared code for all backends) 3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "utils/includes.h" 16 17 #include "utils/common.h" 18 #include "utils/eloop.h" 19 #include "common/version.h" 20 #include "common/ieee802_11_defs.h" 21 #include "common/wpa_ctrl.h" 22 #include "eap_peer/eap.h" 23 #include "eapol_supp/eapol_supp_sm.h" 24 #include "rsn_supp/wpa.h" 25 #include "rsn_supp/preauth.h" 26 #include "rsn_supp/pmksa_cache.h" 27 #include "l2_packet/l2_packet.h" 28 #include "wps/wps.h" 29 #include "config.h" 30 #include "wpa_supplicant_i.h" 31 #include "driver_i.h" 32 #include "wps_supplicant.h" 33 #include "ibss_rsn.h" 34 #include "ap.h" 35 #include "p2p_supplicant.h" 36 #include "p2p/p2p.h" 37 #include "notify.h" 38 #include "bss.h" 39 #include "scan.h" 40 #include "ctrl_iface.h" 41 #include "interworking.h" 42 #include "blacklist.h" 43 #include "wpas_glue.h" 44 45 extern struct wpa_driver_ops *wpa_drivers[]; 46 47 static int wpa_supplicant_global_iface_list(struct wpa_global *global, 48 char *buf, int len); 49 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 50 char *buf, int len); 51 52 53 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, 54 char *cmd) 55 { 56 char *value; 57 int ret = 0; 58 59 value = os_strchr(cmd, ' '); 60 if (value == NULL) 61 return -1; 62 *value++ = '\0'; 63 64 wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value); 65 if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) { 66 eapol_sm_configure(wpa_s->eapol, 67 atoi(value), -1, -1, -1); 68 } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) { 69 eapol_sm_configure(wpa_s->eapol, 70 -1, atoi(value), -1, -1); 71 } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) { 72 eapol_sm_configure(wpa_s->eapol, 73 -1, -1, atoi(value), -1); 74 } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) { 75 eapol_sm_configure(wpa_s->eapol, 76 -1, -1, -1, atoi(value)); 77 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) { 78 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME, 79 atoi(value))) 80 ret = -1; 81 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") == 82 0) { 83 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD, 84 atoi(value))) 85 ret = -1; 86 } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) { 87 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value))) 88 ret = -1; 89 } else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) { 90 wpa_s->wps_fragment_size = atoi(value); 91 #ifdef CONFIG_WPS_TESTING 92 } else if (os_strcasecmp(cmd, "wps_version_number") == 0) { 93 long int val; 94 val = strtol(value, NULL, 0); 95 if (val < 0 || val > 0xff) { 96 ret = -1; 97 wpa_printf(MSG_DEBUG, "WPS: Invalid " 98 "wps_version_number %ld", val); 99 } else { 100 wps_version_number = val; 101 wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS " 102 "version %u.%u", 103 (wps_version_number & 0xf0) >> 4, 104 wps_version_number & 0x0f); 105 } 106 } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) { 107 wps_testing_dummy_cred = atoi(value); 108 wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d", 109 wps_testing_dummy_cred); 110 #endif /* CONFIG_WPS_TESTING */ 111 } else if (os_strcasecmp(cmd, "ampdu") == 0) { 112 if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0) 113 ret = -1; 114 #ifdef CONFIG_TDLS_TESTING 115 } else if (os_strcasecmp(cmd, "tdls_testing") == 0) { 116 extern unsigned int tdls_testing; 117 tdls_testing = strtol(value, NULL, 0); 118 wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing); 119 #endif /* CONFIG_TDLS_TESTING */ 120 #ifdef CONFIG_TDLS 121 } else if (os_strcasecmp(cmd, "tdls_disabled") == 0) { 122 int disabled = atoi(value); 123 wpa_printf(MSG_DEBUG, "TDLS: tdls_disabled=%d", disabled); 124 if (disabled) { 125 if (wpa_drv_tdls_oper(wpa_s, TDLS_DISABLE, NULL) < 0) 126 ret = -1; 127 } else if (wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL) < 0) 128 ret = -1; 129 wpa_tdls_enable(wpa_s->wpa, !disabled); 130 #endif /* CONFIG_TDLS */ 131 } else { 132 value[-1] = '='; 133 ret = wpa_config_process_global(wpa_s->conf, cmd, -1); 134 if (ret == 0) 135 wpa_supplicant_update_config(wpa_s); 136 } 137 138 return ret; 139 } 140 141 142 static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s, 143 char *cmd, char *buf, size_t buflen) 144 { 145 int res; 146 147 wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd); 148 149 if (os_strcmp(cmd, "version") == 0) { 150 res = os_snprintf(buf, buflen, "%s", VERSION_STR); 151 if (res < 0 || (unsigned int) res >= buflen) 152 return -1; 153 return res; 154 } 155 156 return -1; 157 } 158 159 160 #ifdef IEEE8021X_EAPOL 161 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s, 162 char *addr) 163 { 164 u8 bssid[ETH_ALEN]; 165 struct wpa_ssid *ssid = wpa_s->current_ssid; 166 167 if (hwaddr_aton(addr, bssid)) { 168 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address " 169 "'%s'", addr); 170 return -1; 171 } 172 173 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid)); 174 rsn_preauth_deinit(wpa_s->wpa); 175 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL)) 176 return -1; 177 178 return 0; 179 } 180 #endif /* IEEE8021X_EAPOL */ 181 182 183 #ifdef CONFIG_PEERKEY 184 /* MLME-STKSTART.request(peer) */ 185 static int wpa_supplicant_ctrl_iface_stkstart( 186 struct wpa_supplicant *wpa_s, char *addr) 187 { 188 u8 peer[ETH_ALEN]; 189 190 if (hwaddr_aton(addr, peer)) { 191 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid " 192 "address '%s'", addr); 193 return -1; 194 } 195 196 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR, 197 MAC2STR(peer)); 198 199 return wpa_sm_stkstart(wpa_s->wpa, peer); 200 } 201 #endif /* CONFIG_PEERKEY */ 202 203 204 #ifdef CONFIG_TDLS 205 206 static int wpa_supplicant_ctrl_iface_tdls_discover( 207 struct wpa_supplicant *wpa_s, char *addr) 208 { 209 u8 peer[ETH_ALEN]; 210 int ret; 211 212 if (hwaddr_aton(addr, peer)) { 213 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid " 214 "address '%s'", addr); 215 return -1; 216 } 217 218 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR, 219 MAC2STR(peer)); 220 221 if (wpa_tdls_is_external_setup(wpa_s->wpa)) 222 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer); 223 else 224 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer); 225 226 return ret; 227 } 228 229 230 static int wpa_supplicant_ctrl_iface_tdls_setup( 231 struct wpa_supplicant *wpa_s, char *addr) 232 { 233 u8 peer[ETH_ALEN]; 234 int ret; 235 236 if (hwaddr_aton(addr, peer)) { 237 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP: invalid " 238 "address '%s'", addr); 239 return -1; 240 } 241 242 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP " MACSTR, 243 MAC2STR(peer)); 244 245 ret = wpa_tdls_reneg(wpa_s->wpa, peer); 246 if (ret) { 247 if (wpa_tdls_is_external_setup(wpa_s->wpa)) 248 ret = wpa_tdls_start(wpa_s->wpa, peer); 249 else 250 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer); 251 } 252 253 return ret; 254 } 255 256 257 static int wpa_supplicant_ctrl_iface_tdls_teardown( 258 struct wpa_supplicant *wpa_s, char *addr) 259 { 260 u8 peer[ETH_ALEN]; 261 262 if (hwaddr_aton(addr, peer)) { 263 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid " 264 "address '%s'", addr); 265 return -1; 266 } 267 268 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR, 269 MAC2STR(peer)); 270 271 return wpa_tdls_teardown_link(wpa_s->wpa, peer, 272 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED); 273 } 274 275 #endif /* CONFIG_TDLS */ 276 277 278 #ifdef CONFIG_IEEE80211R 279 static int wpa_supplicant_ctrl_iface_ft_ds( 280 struct wpa_supplicant *wpa_s, char *addr) 281 { 282 u8 target_ap[ETH_ALEN]; 283 struct wpa_bss *bss; 284 const u8 *mdie; 285 286 if (hwaddr_aton(addr, target_ap)) { 287 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid " 288 "address '%s'", addr); 289 return -1; 290 } 291 292 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap)); 293 294 bss = wpa_bss_get_bssid(wpa_s, target_ap); 295 if (bss) 296 mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); 297 else 298 mdie = NULL; 299 300 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie); 301 } 302 #endif /* CONFIG_IEEE80211R */ 303 304 305 #ifdef CONFIG_WPS 306 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s, 307 char *cmd) 308 { 309 u8 bssid[ETH_ALEN], *_bssid = bssid; 310 #ifdef CONFIG_P2P 311 u8 p2p_dev_addr[ETH_ALEN]; 312 #endif /* CONFIG_P2P */ 313 #ifdef CONFIG_AP 314 u8 *_p2p_dev_addr = NULL; 315 #endif /* CONFIG_AP */ 316 317 if (cmd == NULL || os_strcmp(cmd, "any") == 0) { 318 _bssid = NULL; 319 #ifdef CONFIG_P2P 320 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) { 321 if (hwaddr_aton(cmd + 13, p2p_dev_addr)) { 322 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid " 323 "P2P Device Address '%s'", 324 cmd + 13); 325 return -1; 326 } 327 _p2p_dev_addr = p2p_dev_addr; 328 #endif /* CONFIG_P2P */ 329 } else if (hwaddr_aton(cmd, bssid)) { 330 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'", 331 cmd); 332 return -1; 333 } 334 335 #ifdef CONFIG_AP 336 if (wpa_s->ap_iface) 337 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr); 338 #endif /* CONFIG_AP */ 339 340 return wpas_wps_start_pbc(wpa_s, _bssid, 0); 341 } 342 343 344 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, 345 char *cmd, char *buf, 346 size_t buflen) 347 { 348 u8 bssid[ETH_ALEN], *_bssid = bssid; 349 char *pin; 350 int ret; 351 352 pin = os_strchr(cmd, ' '); 353 if (pin) 354 *pin++ = '\0'; 355 356 if (os_strcmp(cmd, "any") == 0) 357 _bssid = NULL; 358 else if (os_strcmp(cmd, "get") == 0) { 359 ret = wps_generate_pin(); 360 goto done; 361 } else if (hwaddr_aton(cmd, bssid)) { 362 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'", 363 cmd); 364 return -1; 365 } 366 367 #ifdef CONFIG_AP 368 if (wpa_s->ap_iface) 369 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin, 370 buf, buflen); 371 #endif /* CONFIG_AP */ 372 373 if (pin) { 374 ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0, 375 DEV_PW_DEFAULT); 376 if (ret < 0) 377 return -1; 378 ret = os_snprintf(buf, buflen, "%s", pin); 379 if (ret < 0 || (size_t) ret >= buflen) 380 return -1; 381 return ret; 382 } 383 384 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT); 385 if (ret < 0) 386 return -1; 387 388 done: 389 /* Return the generated PIN */ 390 ret = os_snprintf(buf, buflen, "%08d", ret); 391 if (ret < 0 || (size_t) ret >= buflen) 392 return -1; 393 return ret; 394 } 395 396 397 static int wpa_supplicant_ctrl_iface_wps_check_pin( 398 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 399 { 400 char pin[9]; 401 size_t len; 402 char *pos; 403 int ret; 404 405 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN", 406 (u8 *) cmd, os_strlen(cmd)); 407 for (pos = cmd, len = 0; *pos != '\0'; pos++) { 408 if (*pos < '0' || *pos > '9') 409 continue; 410 pin[len++] = *pos; 411 if (len == 9) { 412 wpa_printf(MSG_DEBUG, "WPS: Too long PIN"); 413 return -1; 414 } 415 } 416 if (len != 4 && len != 8) { 417 wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len); 418 return -1; 419 } 420 pin[len] = '\0'; 421 422 if (len == 8) { 423 unsigned int pin_val; 424 pin_val = atoi(pin); 425 if (!wps_pin_valid(pin_val)) { 426 wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit"); 427 ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n"); 428 if (ret < 0 || (size_t) ret >= buflen) 429 return -1; 430 return ret; 431 } 432 } 433 434 ret = os_snprintf(buf, buflen, "%s", pin); 435 if (ret < 0 || (size_t) ret >= buflen) 436 return -1; 437 438 return ret; 439 } 440 441 442 #ifdef CONFIG_WPS_OOB 443 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s, 444 char *cmd) 445 { 446 char *path, *method, *name; 447 448 path = os_strchr(cmd, ' '); 449 if (path == NULL) 450 return -1; 451 *path++ = '\0'; 452 453 method = os_strchr(path, ' '); 454 if (method == NULL) 455 return -1; 456 *method++ = '\0'; 457 458 name = os_strchr(method, ' '); 459 if (name != NULL) 460 *name++ = '\0'; 461 462 return wpas_wps_start_oob(wpa_s, cmd, path, method, name); 463 } 464 #endif /* CONFIG_WPS_OOB */ 465 466 467 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s, 468 char *cmd) 469 { 470 u8 bssid[ETH_ALEN]; 471 char *pin; 472 char *new_ssid; 473 char *new_auth; 474 char *new_encr; 475 char *new_key; 476 struct wps_new_ap_settings ap; 477 478 pin = os_strchr(cmd, ' '); 479 if (pin == NULL) 480 return -1; 481 *pin++ = '\0'; 482 483 if (hwaddr_aton(cmd, bssid)) { 484 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'", 485 cmd); 486 return -1; 487 } 488 489 new_ssid = os_strchr(pin, ' '); 490 if (new_ssid == NULL) 491 return wpas_wps_start_reg(wpa_s, bssid, pin, NULL); 492 *new_ssid++ = '\0'; 493 494 new_auth = os_strchr(new_ssid, ' '); 495 if (new_auth == NULL) 496 return -1; 497 *new_auth++ = '\0'; 498 499 new_encr = os_strchr(new_auth, ' '); 500 if (new_encr == NULL) 501 return -1; 502 *new_encr++ = '\0'; 503 504 new_key = os_strchr(new_encr, ' '); 505 if (new_key == NULL) 506 return -1; 507 *new_key++ = '\0'; 508 509 os_memset(&ap, 0, sizeof(ap)); 510 ap.ssid_hex = new_ssid; 511 ap.auth = new_auth; 512 ap.encr = new_encr; 513 ap.key_hex = new_key; 514 return wpas_wps_start_reg(wpa_s, bssid, pin, &ap); 515 } 516 517 518 #ifdef CONFIG_AP 519 static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant *wpa_s, 520 char *cmd, char *buf, 521 size_t buflen) 522 { 523 int timeout = 300; 524 char *pos; 525 const char *pin_txt; 526 527 if (!wpa_s->ap_iface) 528 return -1; 529 530 pos = os_strchr(cmd, ' '); 531 if (pos) 532 *pos++ = '\0'; 533 534 if (os_strcmp(cmd, "disable") == 0) { 535 wpas_wps_ap_pin_disable(wpa_s); 536 return os_snprintf(buf, buflen, "OK\n"); 537 } 538 539 if (os_strcmp(cmd, "random") == 0) { 540 if (pos) 541 timeout = atoi(pos); 542 pin_txt = wpas_wps_ap_pin_random(wpa_s, timeout); 543 if (pin_txt == NULL) 544 return -1; 545 return os_snprintf(buf, buflen, "%s", pin_txt); 546 } 547 548 if (os_strcmp(cmd, "get") == 0) { 549 pin_txt = wpas_wps_ap_pin_get(wpa_s); 550 if (pin_txt == NULL) 551 return -1; 552 return os_snprintf(buf, buflen, "%s", pin_txt); 553 } 554 555 if (os_strcmp(cmd, "set") == 0) { 556 char *pin; 557 if (pos == NULL) 558 return -1; 559 pin = pos; 560 pos = os_strchr(pos, ' '); 561 if (pos) { 562 *pos++ = '\0'; 563 timeout = atoi(pos); 564 } 565 if (os_strlen(pin) > buflen) 566 return -1; 567 if (wpas_wps_ap_pin_set(wpa_s, pin, timeout) < 0) 568 return -1; 569 return os_snprintf(buf, buflen, "%s", pin); 570 } 571 572 return -1; 573 } 574 #endif /* CONFIG_AP */ 575 576 577 #ifdef CONFIG_WPS_ER 578 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s, 579 char *cmd) 580 { 581 char *uuid = cmd, *pin, *pos; 582 u8 addr_buf[ETH_ALEN], *addr = NULL; 583 pin = os_strchr(uuid, ' '); 584 if (pin == NULL) 585 return -1; 586 *pin++ = '\0'; 587 pos = os_strchr(pin, ' '); 588 if (pos) { 589 *pos++ = '\0'; 590 if (hwaddr_aton(pos, addr_buf) == 0) 591 addr = addr_buf; 592 } 593 return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin); 594 } 595 596 597 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s, 598 char *cmd) 599 { 600 char *uuid = cmd, *pin; 601 pin = os_strchr(uuid, ' '); 602 if (pin == NULL) 603 return -1; 604 *pin++ = '\0'; 605 return wpas_wps_er_learn(wpa_s, uuid, pin); 606 } 607 608 609 static int wpa_supplicant_ctrl_iface_wps_er_set_config( 610 struct wpa_supplicant *wpa_s, char *cmd) 611 { 612 char *uuid = cmd, *id; 613 id = os_strchr(uuid, ' '); 614 if (id == NULL) 615 return -1; 616 *id++ = '\0'; 617 return wpas_wps_er_set_config(wpa_s, uuid, atoi(id)); 618 } 619 620 621 static int wpa_supplicant_ctrl_iface_wps_er_config( 622 struct wpa_supplicant *wpa_s, char *cmd) 623 { 624 char *pin; 625 char *new_ssid; 626 char *new_auth; 627 char *new_encr; 628 char *new_key; 629 struct wps_new_ap_settings ap; 630 631 pin = os_strchr(cmd, ' '); 632 if (pin == NULL) 633 return -1; 634 *pin++ = '\0'; 635 636 new_ssid = os_strchr(pin, ' '); 637 if (new_ssid == NULL) 638 return -1; 639 *new_ssid++ = '\0'; 640 641 new_auth = os_strchr(new_ssid, ' '); 642 if (new_auth == NULL) 643 return -1; 644 *new_auth++ = '\0'; 645 646 new_encr = os_strchr(new_auth, ' '); 647 if (new_encr == NULL) 648 return -1; 649 *new_encr++ = '\0'; 650 651 new_key = os_strchr(new_encr, ' '); 652 if (new_key == NULL) 653 return -1; 654 *new_key++ = '\0'; 655 656 os_memset(&ap, 0, sizeof(ap)); 657 ap.ssid_hex = new_ssid; 658 ap.auth = new_auth; 659 ap.encr = new_encr; 660 ap.key_hex = new_key; 661 return wpas_wps_er_config(wpa_s, cmd, pin, &ap); 662 } 663 #endif /* CONFIG_WPS_ER */ 664 665 #endif /* CONFIG_WPS */ 666 667 668 #ifdef CONFIG_IBSS_RSN 669 static int wpa_supplicant_ctrl_iface_ibss_rsn( 670 struct wpa_supplicant *wpa_s, char *addr) 671 { 672 u8 peer[ETH_ALEN]; 673 674 if (hwaddr_aton(addr, peer)) { 675 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid " 676 "address '%s'", addr); 677 return -1; 678 } 679 680 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR, 681 MAC2STR(peer)); 682 683 return ibss_rsn_start(wpa_s->ibss_rsn, peer); 684 } 685 #endif /* CONFIG_IBSS_RSN */ 686 687 688 int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s, 689 struct wpa_ssid *ssid, 690 const char *field, 691 const char *value) 692 { 693 #ifdef IEEE8021X_EAPOL 694 struct eap_peer_config *eap = &ssid->eap; 695 696 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field); 697 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value", 698 (const u8 *) value, os_strlen(value)); 699 700 switch (wpa_supplicant_ctrl_req_from_string(field)) { 701 case WPA_CTRL_REQ_EAP_IDENTITY: 702 os_free(eap->identity); 703 eap->identity = (u8 *) os_strdup(value); 704 eap->identity_len = os_strlen(value); 705 eap->pending_req_identity = 0; 706 if (ssid == wpa_s->current_ssid) 707 wpa_s->reassociate = 1; 708 break; 709 case WPA_CTRL_REQ_EAP_PASSWORD: 710 os_free(eap->password); 711 eap->password = (u8 *) os_strdup(value); 712 eap->password_len = os_strlen(value); 713 eap->pending_req_password = 0; 714 if (ssid == wpa_s->current_ssid) 715 wpa_s->reassociate = 1; 716 break; 717 case WPA_CTRL_REQ_EAP_NEW_PASSWORD: 718 os_free(eap->new_password); 719 eap->new_password = (u8 *) os_strdup(value); 720 eap->new_password_len = os_strlen(value); 721 eap->pending_req_new_password = 0; 722 if (ssid == wpa_s->current_ssid) 723 wpa_s->reassociate = 1; 724 break; 725 case WPA_CTRL_REQ_EAP_PIN: 726 os_free(eap->pin); 727 eap->pin = os_strdup(value); 728 eap->pending_req_pin = 0; 729 if (ssid == wpa_s->current_ssid) 730 wpa_s->reassociate = 1; 731 break; 732 case WPA_CTRL_REQ_EAP_OTP: 733 os_free(eap->otp); 734 eap->otp = (u8 *) os_strdup(value); 735 eap->otp_len = os_strlen(value); 736 os_free(eap->pending_req_otp); 737 eap->pending_req_otp = NULL; 738 eap->pending_req_otp_len = 0; 739 break; 740 case WPA_CTRL_REQ_EAP_PASSPHRASE: 741 os_free(eap->private_key_passwd); 742 eap->private_key_passwd = (u8 *) os_strdup(value); 743 eap->pending_req_passphrase = 0; 744 if (ssid == wpa_s->current_ssid) 745 wpa_s->reassociate = 1; 746 break; 747 default: 748 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field); 749 return -1; 750 } 751 752 return 0; 753 #else /* IEEE8021X_EAPOL */ 754 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included"); 755 return -1; 756 #endif /* IEEE8021X_EAPOL */ 757 } 758 759 760 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s, 761 char *rsp) 762 { 763 #ifdef IEEE8021X_EAPOL 764 char *pos, *id_pos; 765 int id; 766 struct wpa_ssid *ssid; 767 768 pos = os_strchr(rsp, '-'); 769 if (pos == NULL) 770 return -1; 771 *pos++ = '\0'; 772 id_pos = pos; 773 pos = os_strchr(pos, ':'); 774 if (pos == NULL) 775 return -1; 776 *pos++ = '\0'; 777 id = atoi(id_pos); 778 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id); 779 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 780 (u8 *) pos, os_strlen(pos)); 781 782 ssid = wpa_config_get_network(wpa_s->conf, id); 783 if (ssid == NULL) { 784 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 785 "to update", id); 786 return -1; 787 } 788 789 return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid, rsp, 790 pos); 791 #else /* IEEE8021X_EAPOL */ 792 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included"); 793 return -1; 794 #endif /* IEEE8021X_EAPOL */ 795 } 796 797 798 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, 799 const char *params, 800 char *buf, size_t buflen) 801 { 802 char *pos, *end, tmp[30]; 803 int res, verbose, ret; 804 805 verbose = os_strcmp(params, "-VERBOSE") == 0; 806 pos = buf; 807 end = buf + buflen; 808 if (wpa_s->wpa_state >= WPA_ASSOCIATED) { 809 struct wpa_ssid *ssid = wpa_s->current_ssid; 810 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n", 811 MAC2STR(wpa_s->bssid)); 812 if (ret < 0 || ret >= end - pos) 813 return pos - buf; 814 pos += ret; 815 if (ssid) { 816 u8 *_ssid = ssid->ssid; 817 size_t ssid_len = ssid->ssid_len; 818 u8 ssid_buf[MAX_SSID_LEN]; 819 if (ssid_len == 0) { 820 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf); 821 if (_res < 0) 822 ssid_len = 0; 823 else 824 ssid_len = _res; 825 _ssid = ssid_buf; 826 } 827 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n", 828 wpa_ssid_txt(_ssid, ssid_len), 829 ssid->id); 830 if (ret < 0 || ret >= end - pos) 831 return pos - buf; 832 pos += ret; 833 834 if (ssid->id_str) { 835 ret = os_snprintf(pos, end - pos, 836 "id_str=%s\n", 837 ssid->id_str); 838 if (ret < 0 || ret >= end - pos) 839 return pos - buf; 840 pos += ret; 841 } 842 843 switch (ssid->mode) { 844 case WPAS_MODE_INFRA: 845 ret = os_snprintf(pos, end - pos, 846 "mode=station\n"); 847 break; 848 case WPAS_MODE_IBSS: 849 ret = os_snprintf(pos, end - pos, 850 "mode=IBSS\n"); 851 break; 852 case WPAS_MODE_AP: 853 ret = os_snprintf(pos, end - pos, 854 "mode=AP\n"); 855 break; 856 case WPAS_MODE_P2P_GO: 857 ret = os_snprintf(pos, end - pos, 858 "mode=P2P GO\n"); 859 break; 860 case WPAS_MODE_P2P_GROUP_FORMATION: 861 ret = os_snprintf(pos, end - pos, 862 "mode=P2P GO - group " 863 "formation\n"); 864 break; 865 default: 866 ret = 0; 867 break; 868 } 869 if (ret < 0 || ret >= end - pos) 870 return pos - buf; 871 pos += ret; 872 } 873 874 #ifdef CONFIG_AP 875 if (wpa_s->ap_iface) { 876 pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, 877 end - pos, 878 verbose); 879 } else 880 #endif /* CONFIG_AP */ 881 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose); 882 } 883 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n", 884 wpa_supplicant_state_txt(wpa_s->wpa_state)); 885 if (ret < 0 || ret >= end - pos) 886 return pos - buf; 887 pos += ret; 888 889 if (wpa_s->l2 && 890 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) { 891 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp); 892 if (ret < 0 || ret >= end - pos) 893 return pos - buf; 894 pos += ret; 895 } 896 897 #ifdef CONFIG_P2P 898 if (wpa_s->global->p2p) { 899 ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR 900 "\n", MAC2STR(wpa_s->global->p2p_dev_addr)); 901 if (ret < 0 || ret >= end - pos) 902 return pos - buf; 903 pos += ret; 904 } 905 #endif /* CONFIG_P2P */ 906 907 ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n", 908 MAC2STR(wpa_s->own_addr)); 909 if (ret < 0 || ret >= end - pos) 910 return pos - buf; 911 pos += ret; 912 913 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) || 914 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 915 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos, 916 verbose); 917 if (res >= 0) 918 pos += res; 919 } 920 921 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose); 922 if (res >= 0) 923 pos += res; 924 925 return pos - buf; 926 } 927 928 929 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s, 930 char *cmd) 931 { 932 char *pos; 933 int id; 934 struct wpa_ssid *ssid; 935 u8 bssid[ETH_ALEN]; 936 937 /* cmd: "<network id> <BSSID>" */ 938 pos = os_strchr(cmd, ' '); 939 if (pos == NULL) 940 return -1; 941 *pos++ = '\0'; 942 id = atoi(cmd); 943 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos); 944 if (hwaddr_aton(pos, bssid)) { 945 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos); 946 return -1; 947 } 948 949 ssid = wpa_config_get_network(wpa_s->conf, id); 950 if (ssid == NULL) { 951 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 952 "to update", id); 953 return -1; 954 } 955 956 os_memcpy(ssid->bssid, bssid, ETH_ALEN); 957 ssid->bssid_set = !is_zero_ether_addr(bssid); 958 959 return 0; 960 } 961 962 963 static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s, 964 char *cmd, char *buf, 965 size_t buflen) 966 { 967 u8 bssid[ETH_ALEN]; 968 struct wpa_blacklist *e; 969 char *pos, *end; 970 int ret; 971 972 /* cmd: "BLACKLIST [<BSSID>]" */ 973 if (*cmd == '\0') { 974 pos = buf; 975 end = buf + buflen; 976 e = wpa_s->blacklist; 977 while (e) { 978 ret = os_snprintf(pos, end - pos, MACSTR "\n", 979 MAC2STR(e->bssid)); 980 if (ret < 0 || ret >= end - pos) 981 return pos - buf; 982 pos += ret; 983 e = e->next; 984 } 985 return pos - buf; 986 } 987 988 cmd++; 989 if (os_strncmp(cmd, "clear", 5) == 0) { 990 wpa_blacklist_clear(wpa_s); 991 os_memcpy(buf, "OK\n", 3); 992 return 3; 993 } 994 995 wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd); 996 if (hwaddr_aton(cmd, bssid)) { 997 wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd); 998 return -1; 999 } 1000 1001 /* 1002 * Add the BSSID twice, so its count will be 2, causing it to be 1003 * skipped when processing scan results. 1004 */ 1005 ret = wpa_blacklist_add(wpa_s, bssid); 1006 if (ret != 0) 1007 return -1; 1008 ret = wpa_blacklist_add(wpa_s, bssid); 1009 if (ret != 0) 1010 return -1; 1011 os_memcpy(buf, "OK\n", 3); 1012 return 3; 1013 } 1014 1015 1016 extern int wpa_debug_level; 1017 extern int wpa_debug_timestamp; 1018 1019 static const char * debug_level_str(int level) 1020 { 1021 switch (level) { 1022 case MSG_EXCESSIVE: 1023 return "EXCESSIVE"; 1024 case MSG_MSGDUMP: 1025 return "MSGDUMP"; 1026 case MSG_DEBUG: 1027 return "DEBUG"; 1028 case MSG_INFO: 1029 return "INFO"; 1030 case MSG_WARNING: 1031 return "WARNING"; 1032 case MSG_ERROR: 1033 return "ERROR"; 1034 default: 1035 return "?"; 1036 } 1037 } 1038 1039 1040 static int str_to_debug_level(const char *s) 1041 { 1042 if (os_strcasecmp(s, "EXCESSIVE") == 0) 1043 return MSG_EXCESSIVE; 1044 if (os_strcasecmp(s, "MSGDUMP") == 0) 1045 return MSG_MSGDUMP; 1046 if (os_strcasecmp(s, "DEBUG") == 0) 1047 return MSG_DEBUG; 1048 if (os_strcasecmp(s, "INFO") == 0) 1049 return MSG_INFO; 1050 if (os_strcasecmp(s, "WARNING") == 0) 1051 return MSG_WARNING; 1052 if (os_strcasecmp(s, "ERROR") == 0) 1053 return MSG_ERROR; 1054 return -1; 1055 } 1056 1057 1058 static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s, 1059 char *cmd, char *buf, 1060 size_t buflen) 1061 { 1062 char *pos, *end, *stamp; 1063 int ret; 1064 1065 if (cmd == NULL) { 1066 return -1; 1067 } 1068 1069 /* cmd: "LOG_LEVEL [<level>]" */ 1070 if (*cmd == '\0') { 1071 pos = buf; 1072 end = buf + buflen; 1073 ret = os_snprintf(pos, end - pos, "Current level: %s\n" 1074 "Timestamp: %d\n", 1075 debug_level_str(wpa_debug_level), 1076 wpa_debug_timestamp); 1077 if (ret < 0 || ret >= end - pos) 1078 ret = 0; 1079 1080 return ret; 1081 } 1082 1083 while (*cmd == ' ') 1084 cmd++; 1085 1086 stamp = os_strchr(cmd, ' '); 1087 if (stamp) { 1088 *stamp++ = '\0'; 1089 while (*stamp == ' ') { 1090 stamp++; 1091 } 1092 } 1093 1094 if (cmd && os_strlen(cmd)) { 1095 int level = str_to_debug_level(cmd); 1096 if (level < 0) 1097 return -1; 1098 wpa_debug_level = level; 1099 } 1100 1101 if (stamp && os_strlen(stamp)) 1102 wpa_debug_timestamp = atoi(stamp); 1103 1104 os_memcpy(buf, "OK\n", 3); 1105 return 3; 1106 } 1107 1108 1109 static int wpa_supplicant_ctrl_iface_list_networks( 1110 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1111 { 1112 char *pos, *end; 1113 struct wpa_ssid *ssid; 1114 int ret; 1115 1116 pos = buf; 1117 end = buf + buflen; 1118 ret = os_snprintf(pos, end - pos, 1119 "network id / ssid / bssid / flags\n"); 1120 if (ret < 0 || ret >= end - pos) 1121 return pos - buf; 1122 pos += ret; 1123 1124 ssid = wpa_s->conf->ssid; 1125 while (ssid) { 1126 ret = os_snprintf(pos, end - pos, "%d\t%s", 1127 ssid->id, 1128 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 1129 if (ret < 0 || ret >= end - pos) 1130 return pos - buf; 1131 pos += ret; 1132 if (ssid->bssid_set) { 1133 ret = os_snprintf(pos, end - pos, "\t" MACSTR, 1134 MAC2STR(ssid->bssid)); 1135 } else { 1136 ret = os_snprintf(pos, end - pos, "\tany"); 1137 } 1138 if (ret < 0 || ret >= end - pos) 1139 return pos - buf; 1140 pos += ret; 1141 ret = os_snprintf(pos, end - pos, "\t%s%s%s", 1142 ssid == wpa_s->current_ssid ? 1143 "[CURRENT]" : "", 1144 ssid->disabled ? "[DISABLED]" : "", 1145 ssid->disabled == 2 ? "[P2P-PERSISTENT]" : 1146 ""); 1147 if (ret < 0 || ret >= end - pos) 1148 return pos - buf; 1149 pos += ret; 1150 ret = os_snprintf(pos, end - pos, "\n"); 1151 if (ret < 0 || ret >= end - pos) 1152 return pos - buf; 1153 pos += ret; 1154 1155 ssid = ssid->next; 1156 } 1157 1158 return pos - buf; 1159 } 1160 1161 1162 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher) 1163 { 1164 int first = 1, ret; 1165 ret = os_snprintf(pos, end - pos, "-"); 1166 if (ret < 0 || ret >= end - pos) 1167 return pos; 1168 pos += ret; 1169 if (cipher & WPA_CIPHER_NONE) { 1170 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+"); 1171 if (ret < 0 || ret >= end - pos) 1172 return pos; 1173 pos += ret; 1174 first = 0; 1175 } 1176 if (cipher & WPA_CIPHER_WEP40) { 1177 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+"); 1178 if (ret < 0 || ret >= end - pos) 1179 return pos; 1180 pos += ret; 1181 first = 0; 1182 } 1183 if (cipher & WPA_CIPHER_WEP104) { 1184 ret = os_snprintf(pos, end - pos, "%sWEP104", 1185 first ? "" : "+"); 1186 if (ret < 0 || ret >= end - pos) 1187 return pos; 1188 pos += ret; 1189 first = 0; 1190 } 1191 if (cipher & WPA_CIPHER_TKIP) { 1192 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+"); 1193 if (ret < 0 || ret >= end - pos) 1194 return pos; 1195 pos += ret; 1196 first = 0; 1197 } 1198 if (cipher & WPA_CIPHER_CCMP) { 1199 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+"); 1200 if (ret < 0 || ret >= end - pos) 1201 return pos; 1202 pos += ret; 1203 first = 0; 1204 } 1205 return pos; 1206 } 1207 1208 1209 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto, 1210 const u8 *ie, size_t ie_len) 1211 { 1212 struct wpa_ie_data data; 1213 int first, ret; 1214 1215 ret = os_snprintf(pos, end - pos, "[%s-", proto); 1216 if (ret < 0 || ret >= end - pos) 1217 return pos; 1218 pos += ret; 1219 1220 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) { 1221 ret = os_snprintf(pos, end - pos, "?]"); 1222 if (ret < 0 || ret >= end - pos) 1223 return pos; 1224 pos += ret; 1225 return pos; 1226 } 1227 1228 first = 1; 1229 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 1230 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+"); 1231 if (ret < 0 || ret >= end - pos) 1232 return pos; 1233 pos += ret; 1234 first = 0; 1235 } 1236 if (data.key_mgmt & WPA_KEY_MGMT_PSK) { 1237 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+"); 1238 if (ret < 0 || ret >= end - pos) 1239 return pos; 1240 pos += ret; 1241 first = 0; 1242 } 1243 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) { 1244 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+"); 1245 if (ret < 0 || ret >= end - pos) 1246 return pos; 1247 pos += ret; 1248 first = 0; 1249 } 1250 #ifdef CONFIG_IEEE80211R 1251 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { 1252 ret = os_snprintf(pos, end - pos, "%sFT/EAP", 1253 first ? "" : "+"); 1254 if (ret < 0 || ret >= end - pos) 1255 return pos; 1256 pos += ret; 1257 first = 0; 1258 } 1259 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) { 1260 ret = os_snprintf(pos, end - pos, "%sFT/PSK", 1261 first ? "" : "+"); 1262 if (ret < 0 || ret >= end - pos) 1263 return pos; 1264 pos += ret; 1265 first = 0; 1266 } 1267 #endif /* CONFIG_IEEE80211R */ 1268 #ifdef CONFIG_IEEE80211W 1269 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { 1270 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256", 1271 first ? "" : "+"); 1272 if (ret < 0 || ret >= end - pos) 1273 return pos; 1274 pos += ret; 1275 first = 0; 1276 } 1277 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { 1278 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256", 1279 first ? "" : "+"); 1280 if (ret < 0 || ret >= end - pos) 1281 return pos; 1282 pos += ret; 1283 first = 0; 1284 } 1285 #endif /* CONFIG_IEEE80211W */ 1286 1287 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher); 1288 1289 if (data.capabilities & WPA_CAPABILITY_PREAUTH) { 1290 ret = os_snprintf(pos, end - pos, "-preauth"); 1291 if (ret < 0 || ret >= end - pos) 1292 return pos; 1293 pos += ret; 1294 } 1295 1296 ret = os_snprintf(pos, end - pos, "]"); 1297 if (ret < 0 || ret >= end - pos) 1298 return pos; 1299 pos += ret; 1300 1301 return pos; 1302 } 1303 1304 1305 #ifdef CONFIG_WPS 1306 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s, 1307 char *pos, char *end, 1308 struct wpabuf *wps_ie) 1309 { 1310 int ret; 1311 const char *txt; 1312 1313 if (wps_ie == NULL) 1314 return pos; 1315 if (wps_is_selected_pbc_registrar(wps_ie)) 1316 txt = "[WPS-PBC]"; 1317 #ifdef CONFIG_WPS2 1318 else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0)) 1319 txt = "[WPS-AUTH]"; 1320 #endif /* CONFIG_WPS2 */ 1321 else if (wps_is_selected_pin_registrar(wps_ie)) 1322 txt = "[WPS-PIN]"; 1323 else 1324 txt = "[WPS]"; 1325 1326 ret = os_snprintf(pos, end - pos, "%s", txt); 1327 if (ret >= 0 && ret < end - pos) 1328 pos += ret; 1329 wpabuf_free(wps_ie); 1330 return pos; 1331 } 1332 #endif /* CONFIG_WPS */ 1333 1334 1335 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s, 1336 char *pos, char *end, 1337 const struct wpa_bss *bss) 1338 { 1339 #ifdef CONFIG_WPS 1340 struct wpabuf *wps_ie; 1341 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); 1342 return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie); 1343 #else /* CONFIG_WPS */ 1344 return pos; 1345 #endif /* CONFIG_WPS */ 1346 } 1347 1348 1349 /* Format one result on one text line into a buffer. */ 1350 static int wpa_supplicant_ctrl_iface_scan_result( 1351 struct wpa_supplicant *wpa_s, 1352 const struct wpa_bss *bss, char *buf, size_t buflen) 1353 { 1354 char *pos, *end; 1355 int ret; 1356 const u8 *ie, *ie2, *p2p; 1357 1358 p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE); 1359 if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN && 1360 os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 1361 0) 1362 return 0; /* Do not show P2P listen discovery results here */ 1363 1364 pos = buf; 1365 end = buf + buflen; 1366 1367 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t", 1368 MAC2STR(bss->bssid), bss->freq, bss->level); 1369 if (ret < 0 || ret >= end - pos) 1370 return -1; 1371 pos += ret; 1372 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 1373 if (ie) 1374 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]); 1375 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); 1376 if (ie2) 1377 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); 1378 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); 1379 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 1380 ret = os_snprintf(pos, end - pos, "[WEP]"); 1381 if (ret < 0 || ret >= end - pos) 1382 return -1; 1383 pos += ret; 1384 } 1385 if (bss->caps & IEEE80211_CAP_IBSS) { 1386 ret = os_snprintf(pos, end - pos, "[IBSS]"); 1387 if (ret < 0 || ret >= end - pos) 1388 return -1; 1389 pos += ret; 1390 } 1391 if (bss->caps & IEEE80211_CAP_ESS) { 1392 ret = os_snprintf(pos, end - pos, "[ESS]"); 1393 if (ret < 0 || ret >= end - pos) 1394 return -1; 1395 pos += ret; 1396 } 1397 if (p2p) { 1398 ret = os_snprintf(pos, end - pos, "[P2P]"); 1399 if (ret < 0 || ret >= end - pos) 1400 return -1; 1401 pos += ret; 1402 } 1403 1404 ret = os_snprintf(pos, end - pos, "\t%s", 1405 wpa_ssid_txt(bss->ssid, bss->ssid_len)); 1406 if (ret < 0 || ret >= end - pos) 1407 return -1; 1408 pos += ret; 1409 1410 ret = os_snprintf(pos, end - pos, "\n"); 1411 if (ret < 0 || ret >= end - pos) 1412 return -1; 1413 pos += ret; 1414 1415 return pos - buf; 1416 } 1417 1418 1419 static int wpa_supplicant_ctrl_iface_scan_results( 1420 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1421 { 1422 char *pos, *end; 1423 struct wpa_bss *bss; 1424 int ret; 1425 1426 pos = buf; 1427 end = buf + buflen; 1428 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / " 1429 "flags / ssid\n"); 1430 if (ret < 0 || ret >= end - pos) 1431 return pos - buf; 1432 pos += ret; 1433 1434 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) { 1435 ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos, 1436 end - pos); 1437 if (ret < 0 || ret >= end - pos) 1438 return pos - buf; 1439 pos += ret; 1440 } 1441 1442 return pos - buf; 1443 } 1444 1445 1446 static int wpa_supplicant_ctrl_iface_select_network( 1447 struct wpa_supplicant *wpa_s, char *cmd) 1448 { 1449 int id; 1450 struct wpa_ssid *ssid; 1451 1452 /* cmd: "<network id>" or "any" */ 1453 if (os_strcmp(cmd, "any") == 0) { 1454 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any"); 1455 ssid = NULL; 1456 } else { 1457 id = atoi(cmd); 1458 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id); 1459 1460 ssid = wpa_config_get_network(wpa_s->conf, id); 1461 if (ssid == NULL) { 1462 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 1463 "network id=%d", id); 1464 return -1; 1465 } 1466 if (ssid->disabled == 2) { 1467 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 1468 "SELECT_NETWORK with persistent P2P group"); 1469 return -1; 1470 } 1471 } 1472 1473 wpa_supplicant_select_network(wpa_s, ssid); 1474 1475 return 0; 1476 } 1477 1478 1479 static int wpa_supplicant_ctrl_iface_enable_network( 1480 struct wpa_supplicant *wpa_s, char *cmd) 1481 { 1482 int id; 1483 struct wpa_ssid *ssid; 1484 1485 /* cmd: "<network id>" or "all" */ 1486 if (os_strcmp(cmd, "all") == 0) { 1487 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all"); 1488 ssid = NULL; 1489 } else { 1490 id = atoi(cmd); 1491 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id); 1492 1493 ssid = wpa_config_get_network(wpa_s->conf, id); 1494 if (ssid == NULL) { 1495 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 1496 "network id=%d", id); 1497 return -1; 1498 } 1499 if (ssid->disabled == 2) { 1500 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 1501 "ENABLE_NETWORK with persistent P2P group"); 1502 return -1; 1503 } 1504 } 1505 wpa_supplicant_enable_network(wpa_s, ssid); 1506 1507 return 0; 1508 } 1509 1510 1511 static int wpa_supplicant_ctrl_iface_disable_network( 1512 struct wpa_supplicant *wpa_s, char *cmd) 1513 { 1514 int id; 1515 struct wpa_ssid *ssid; 1516 1517 /* cmd: "<network id>" or "all" */ 1518 if (os_strcmp(cmd, "all") == 0) { 1519 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all"); 1520 ssid = NULL; 1521 } else { 1522 id = atoi(cmd); 1523 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id); 1524 1525 ssid = wpa_config_get_network(wpa_s->conf, id); 1526 if (ssid == NULL) { 1527 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 1528 "network id=%d", id); 1529 return -1; 1530 } 1531 if (ssid->disabled == 2) { 1532 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 1533 "DISABLE_NETWORK with persistent P2P " 1534 "group"); 1535 return -1; 1536 } 1537 } 1538 wpa_supplicant_disable_network(wpa_s, ssid); 1539 1540 return 0; 1541 } 1542 1543 1544 static int wpa_supplicant_ctrl_iface_add_network( 1545 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1546 { 1547 struct wpa_ssid *ssid; 1548 int ret; 1549 1550 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK"); 1551 1552 ssid = wpa_config_add_network(wpa_s->conf); 1553 if (ssid == NULL) 1554 return -1; 1555 1556 wpas_notify_network_added(wpa_s, ssid); 1557 1558 ssid->disabled = 1; 1559 wpa_config_set_network_defaults(ssid); 1560 1561 ret = os_snprintf(buf, buflen, "%d\n", ssid->id); 1562 if (ret < 0 || (size_t) ret >= buflen) 1563 return -1; 1564 return ret; 1565 } 1566 1567 1568 static int wpa_supplicant_ctrl_iface_remove_network( 1569 struct wpa_supplicant *wpa_s, char *cmd) 1570 { 1571 int id; 1572 struct wpa_ssid *ssid; 1573 1574 /* cmd: "<network id>" or "all" */ 1575 if (os_strcmp(cmd, "all") == 0) { 1576 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all"); 1577 ssid = wpa_s->conf->ssid; 1578 while (ssid) { 1579 struct wpa_ssid *remove_ssid = ssid; 1580 id = ssid->id; 1581 ssid = ssid->next; 1582 wpas_notify_network_removed(wpa_s, remove_ssid); 1583 wpa_config_remove_network(wpa_s->conf, id); 1584 } 1585 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1586 if (wpa_s->current_ssid) { 1587 #ifdef CONFIG_SME 1588 wpa_s->sme.prev_bssid_set = 0; 1589 #endif /* CONFIG_SME */ 1590 wpa_sm_set_config(wpa_s->wpa, NULL); 1591 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 1592 wpa_supplicant_disassociate(wpa_s, 1593 WLAN_REASON_DEAUTH_LEAVING); 1594 } 1595 return 0; 1596 } 1597 1598 id = atoi(cmd); 1599 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id); 1600 1601 ssid = wpa_config_get_network(wpa_s->conf, id); 1602 if (ssid) 1603 wpas_notify_network_removed(wpa_s, ssid); 1604 if (ssid == NULL || 1605 wpa_config_remove_network(wpa_s->conf, id) < 0) { 1606 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1607 "id=%d", id); 1608 return -1; 1609 } 1610 1611 if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) { 1612 #ifdef CONFIG_SME 1613 wpa_s->sme.prev_bssid_set = 0; 1614 #endif /* CONFIG_SME */ 1615 /* 1616 * Invalidate the EAP session cache if the current or 1617 * previously used network is removed. 1618 */ 1619 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1620 } 1621 1622 if (ssid == wpa_s->current_ssid) { 1623 wpa_sm_set_config(wpa_s->wpa, NULL); 1624 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 1625 1626 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 1627 } 1628 1629 return 0; 1630 } 1631 1632 1633 static int wpa_supplicant_ctrl_iface_set_network( 1634 struct wpa_supplicant *wpa_s, char *cmd) 1635 { 1636 int id; 1637 struct wpa_ssid *ssid; 1638 char *name, *value; 1639 1640 /* cmd: "<network id> <variable name> <value>" */ 1641 name = os_strchr(cmd, ' '); 1642 if (name == NULL) 1643 return -1; 1644 *name++ = '\0'; 1645 1646 value = os_strchr(name, ' '); 1647 if (value == NULL) 1648 return -1; 1649 *value++ = '\0'; 1650 1651 id = atoi(cmd); 1652 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'", 1653 id, name); 1654 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 1655 (u8 *) value, os_strlen(value)); 1656 1657 ssid = wpa_config_get_network(wpa_s->conf, id); 1658 if (ssid == NULL) { 1659 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1660 "id=%d", id); 1661 return -1; 1662 } 1663 1664 if (wpa_config_set(ssid, name, value, 0) < 0) { 1665 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network " 1666 "variable '%s'", name); 1667 return -1; 1668 } 1669 1670 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); 1671 1672 if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) { 1673 /* 1674 * Invalidate the EAP session cache if anything in the current 1675 * or previously used configuration changes. 1676 */ 1677 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1678 } 1679 1680 if ((os_strcmp(name, "psk") == 0 && 1681 value[0] == '"' && ssid->ssid_len) || 1682 (os_strcmp(name, "ssid") == 0 && ssid->passphrase)) 1683 wpa_config_update_psk(ssid); 1684 else if (os_strcmp(name, "priority") == 0) 1685 wpa_config_update_prio_list(wpa_s->conf); 1686 1687 return 0; 1688 } 1689 1690 1691 static int wpa_supplicant_ctrl_iface_get_network( 1692 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 1693 { 1694 int id; 1695 size_t res; 1696 struct wpa_ssid *ssid; 1697 char *name, *value; 1698 1699 /* cmd: "<network id> <variable name>" */ 1700 name = os_strchr(cmd, ' '); 1701 if (name == NULL || buflen == 0) 1702 return -1; 1703 *name++ = '\0'; 1704 1705 id = atoi(cmd); 1706 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'", 1707 id, name); 1708 1709 ssid = wpa_config_get_network(wpa_s->conf, id); 1710 if (ssid == NULL) { 1711 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1712 "id=%d", id); 1713 return -1; 1714 } 1715 1716 value = wpa_config_get_no_key(ssid, name); 1717 if (value == NULL) { 1718 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network " 1719 "variable '%s'", name); 1720 return -1; 1721 } 1722 1723 res = os_strlcpy(buf, value, buflen); 1724 if (res >= buflen) { 1725 os_free(value); 1726 return -1; 1727 } 1728 1729 os_free(value); 1730 1731 return res; 1732 } 1733 1734 1735 #ifndef CONFIG_NO_CONFIG_WRITE 1736 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s) 1737 { 1738 int ret; 1739 1740 if (!wpa_s->conf->update_config) { 1741 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed " 1742 "to update configuration (update_config=0)"); 1743 return -1; 1744 } 1745 1746 ret = wpa_config_write(wpa_s->confname, wpa_s->conf); 1747 if (ret) { 1748 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to " 1749 "update configuration"); 1750 } else { 1751 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration" 1752 " updated"); 1753 } 1754 1755 return ret; 1756 } 1757 #endif /* CONFIG_NO_CONFIG_WRITE */ 1758 1759 1760 static int ctrl_iface_get_capability_pairwise(int res, char *strict, 1761 struct wpa_driver_capa *capa, 1762 char *buf, size_t buflen) 1763 { 1764 int ret, first = 1; 1765 char *pos, *end; 1766 size_t len; 1767 1768 pos = buf; 1769 end = pos + buflen; 1770 1771 if (res < 0) { 1772 if (strict) 1773 return 0; 1774 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen); 1775 if (len >= buflen) 1776 return -1; 1777 return len; 1778 } 1779 1780 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) { 1781 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " "); 1782 if (ret < 0 || ret >= end - pos) 1783 return pos - buf; 1784 pos += ret; 1785 first = 0; 1786 } 1787 1788 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) { 1789 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " "); 1790 if (ret < 0 || ret >= end - pos) 1791 return pos - buf; 1792 pos += ret; 1793 first = 0; 1794 } 1795 1796 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 1797 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " "); 1798 if (ret < 0 || ret >= end - pos) 1799 return pos - buf; 1800 pos += ret; 1801 first = 0; 1802 } 1803 1804 return pos - buf; 1805 } 1806 1807 1808 static int ctrl_iface_get_capability_group(int res, char *strict, 1809 struct wpa_driver_capa *capa, 1810 char *buf, size_t buflen) 1811 { 1812 int ret, first = 1; 1813 char *pos, *end; 1814 size_t len; 1815 1816 pos = buf; 1817 end = pos + buflen; 1818 1819 if (res < 0) { 1820 if (strict) 1821 return 0; 1822 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen); 1823 if (len >= buflen) 1824 return -1; 1825 return len; 1826 } 1827 1828 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) { 1829 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " "); 1830 if (ret < 0 || ret >= end - pos) 1831 return pos - buf; 1832 pos += ret; 1833 first = 0; 1834 } 1835 1836 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) { 1837 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " "); 1838 if (ret < 0 || ret >= end - pos) 1839 return pos - buf; 1840 pos += ret; 1841 first = 0; 1842 } 1843 1844 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) { 1845 ret = os_snprintf(pos, end - pos, "%sWEP104", 1846 first ? "" : " "); 1847 if (ret < 0 || ret >= end - pos) 1848 return pos - buf; 1849 pos += ret; 1850 first = 0; 1851 } 1852 1853 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) { 1854 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " "); 1855 if (ret < 0 || ret >= end - pos) 1856 return pos - buf; 1857 pos += ret; 1858 first = 0; 1859 } 1860 1861 return pos - buf; 1862 } 1863 1864 1865 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict, 1866 struct wpa_driver_capa *capa, 1867 char *buf, size_t buflen) 1868 { 1869 int ret; 1870 char *pos, *end; 1871 size_t len; 1872 1873 pos = buf; 1874 end = pos + buflen; 1875 1876 if (res < 0) { 1877 if (strict) 1878 return 0; 1879 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE " 1880 "NONE", buflen); 1881 if (len >= buflen) 1882 return -1; 1883 return len; 1884 } 1885 1886 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X"); 1887 if (ret < 0 || ret >= end - pos) 1888 return pos - buf; 1889 pos += ret; 1890 1891 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 1892 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { 1893 ret = os_snprintf(pos, end - pos, " WPA-EAP"); 1894 if (ret < 0 || ret >= end - pos) 1895 return pos - buf; 1896 pos += ret; 1897 } 1898 1899 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 1900 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 1901 ret = os_snprintf(pos, end - pos, " WPA-PSK"); 1902 if (ret < 0 || ret >= end - pos) 1903 return pos - buf; 1904 pos += ret; 1905 } 1906 1907 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 1908 ret = os_snprintf(pos, end - pos, " WPA-NONE"); 1909 if (ret < 0 || ret >= end - pos) 1910 return pos - buf; 1911 pos += ret; 1912 } 1913 1914 return pos - buf; 1915 } 1916 1917 1918 static int ctrl_iface_get_capability_proto(int res, char *strict, 1919 struct wpa_driver_capa *capa, 1920 char *buf, size_t buflen) 1921 { 1922 int ret, first = 1; 1923 char *pos, *end; 1924 size_t len; 1925 1926 pos = buf; 1927 end = pos + buflen; 1928 1929 if (res < 0) { 1930 if (strict) 1931 return 0; 1932 len = os_strlcpy(buf, "RSN WPA", buflen); 1933 if (len >= buflen) 1934 return -1; 1935 return len; 1936 } 1937 1938 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 1939 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 1940 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " "); 1941 if (ret < 0 || ret >= end - pos) 1942 return pos - buf; 1943 pos += ret; 1944 first = 0; 1945 } 1946 1947 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 1948 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { 1949 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " "); 1950 if (ret < 0 || ret >= end - pos) 1951 return pos - buf; 1952 pos += ret; 1953 first = 0; 1954 } 1955 1956 return pos - buf; 1957 } 1958 1959 1960 static int ctrl_iface_get_capability_auth_alg(int res, char *strict, 1961 struct wpa_driver_capa *capa, 1962 char *buf, size_t buflen) 1963 { 1964 int ret, first = 1; 1965 char *pos, *end; 1966 size_t len; 1967 1968 pos = buf; 1969 end = pos + buflen; 1970 1971 if (res < 0) { 1972 if (strict) 1973 return 0; 1974 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen); 1975 if (len >= buflen) 1976 return -1; 1977 return len; 1978 } 1979 1980 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) { 1981 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " "); 1982 if (ret < 0 || ret >= end - pos) 1983 return pos - buf; 1984 pos += ret; 1985 first = 0; 1986 } 1987 1988 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) { 1989 ret = os_snprintf(pos, end - pos, "%sSHARED", 1990 first ? "" : " "); 1991 if (ret < 0 || ret >= end - pos) 1992 return pos - buf; 1993 pos += ret; 1994 first = 0; 1995 } 1996 1997 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) { 1998 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " "); 1999 if (ret < 0 || ret >= end - pos) 2000 return pos - buf; 2001 pos += ret; 2002 first = 0; 2003 } 2004 2005 return pos - buf; 2006 } 2007 2008 2009 static int wpa_supplicant_ctrl_iface_get_capability( 2010 struct wpa_supplicant *wpa_s, const char *_field, char *buf, 2011 size_t buflen) 2012 { 2013 struct wpa_driver_capa capa; 2014 int res; 2015 char *strict; 2016 char field[30]; 2017 size_t len; 2018 2019 /* Determine whether or not strict checking was requested */ 2020 len = os_strlcpy(field, _field, sizeof(field)); 2021 if (len >= sizeof(field)) 2022 return -1; 2023 strict = os_strchr(field, ' '); 2024 if (strict != NULL) { 2025 *strict++ = '\0'; 2026 if (os_strcmp(strict, "strict") != 0) 2027 return -1; 2028 } 2029 2030 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s", 2031 field, strict ? strict : ""); 2032 2033 if (os_strcmp(field, "eap") == 0) { 2034 return eap_get_names(buf, buflen); 2035 } 2036 2037 res = wpa_drv_get_capa(wpa_s, &capa); 2038 2039 if (os_strcmp(field, "pairwise") == 0) 2040 return ctrl_iface_get_capability_pairwise(res, strict, &capa, 2041 buf, buflen); 2042 2043 if (os_strcmp(field, "group") == 0) 2044 return ctrl_iface_get_capability_group(res, strict, &capa, 2045 buf, buflen); 2046 2047 if (os_strcmp(field, "key_mgmt") == 0) 2048 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa, 2049 buf, buflen); 2050 2051 if (os_strcmp(field, "proto") == 0) 2052 return ctrl_iface_get_capability_proto(res, strict, &capa, 2053 buf, buflen); 2054 2055 if (os_strcmp(field, "auth_alg") == 0) 2056 return ctrl_iface_get_capability_auth_alg(res, strict, &capa, 2057 buf, buflen); 2058 2059 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'", 2060 field); 2061 2062 return -1; 2063 } 2064 2065 2066 #ifdef CONFIG_INTERWORKING 2067 static char * anqp_add_hex(char *pos, char *end, const char *title, 2068 struct wpabuf *data) 2069 { 2070 char *start = pos; 2071 size_t i; 2072 int ret; 2073 const u8 *d; 2074 2075 if (data == NULL) 2076 return start; 2077 2078 ret = os_snprintf(pos, end - pos, "%s=", title); 2079 if (ret < 0 || ret >= end - pos) 2080 return start; 2081 pos += ret; 2082 2083 d = wpabuf_head_u8(data); 2084 for (i = 0; i < wpabuf_len(data); i++) { 2085 ret = os_snprintf(pos, end - pos, "%02x", *d++); 2086 if (ret < 0 || ret >= end - pos) 2087 return start; 2088 pos += ret; 2089 } 2090 2091 ret = os_snprintf(pos, end - pos, "\n"); 2092 if (ret < 0 || ret >= end - pos) 2093 return start; 2094 pos += ret; 2095 2096 return pos; 2097 } 2098 #endif /* CONFIG_INTERWORKING */ 2099 2100 2101 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, 2102 const char *cmd, char *buf, 2103 size_t buflen) 2104 { 2105 u8 bssid[ETH_ALEN]; 2106 size_t i; 2107 struct wpa_bss *bss; 2108 int ret; 2109 char *pos, *end; 2110 const u8 *ie, *ie2; 2111 2112 if (os_strcmp(cmd, "FIRST") == 0) 2113 bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list); 2114 else if (os_strncmp(cmd, "ID-", 3) == 0) { 2115 i = atoi(cmd + 3); 2116 bss = wpa_bss_get_id(wpa_s, i); 2117 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { 2118 i = atoi(cmd + 5); 2119 bss = wpa_bss_get_id(wpa_s, i); 2120 if (bss) { 2121 struct dl_list *next = bss->list_id.next; 2122 if (next == &wpa_s->bss_id) 2123 bss = NULL; 2124 else 2125 bss = dl_list_entry(next, struct wpa_bss, 2126 list_id); 2127 } 2128 #ifdef CONFIG_P2P 2129 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) { 2130 if (hwaddr_aton(cmd + 13, bssid) == 0) 2131 bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid); 2132 else 2133 bss = NULL; 2134 #endif /* CONFIG_P2P */ 2135 } else if (hwaddr_aton(cmd, bssid) == 0) 2136 bss = wpa_bss_get_bssid(wpa_s, bssid); 2137 else { 2138 struct wpa_bss *tmp; 2139 i = atoi(cmd); 2140 bss = NULL; 2141 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id) 2142 { 2143 if (i-- == 0) { 2144 bss = tmp; 2145 break; 2146 } 2147 } 2148 } 2149 2150 if (bss == NULL) 2151 return 0; 2152 2153 pos = buf; 2154 end = buf + buflen; 2155 ret = os_snprintf(pos, end - pos, 2156 "id=%u\n" 2157 "bssid=" MACSTR "\n" 2158 "freq=%d\n" 2159 "beacon_int=%d\n" 2160 "capabilities=0x%04x\n" 2161 "qual=%d\n" 2162 "noise=%d\n" 2163 "level=%d\n" 2164 "tsf=%016llu\n" 2165 "ie=", 2166 bss->id, 2167 MAC2STR(bss->bssid), bss->freq, bss->beacon_int, 2168 bss->caps, bss->qual, bss->noise, bss->level, 2169 (unsigned long long) bss->tsf); 2170 if (ret < 0 || ret >= end - pos) 2171 return pos - buf; 2172 pos += ret; 2173 2174 ie = (const u8 *) (bss + 1); 2175 for (i = 0; i < bss->ie_len; i++) { 2176 ret = os_snprintf(pos, end - pos, "%02x", *ie++); 2177 if (ret < 0 || ret >= end - pos) 2178 return pos - buf; 2179 pos += ret; 2180 } 2181 2182 ret = os_snprintf(pos, end - pos, "\n"); 2183 if (ret < 0 || ret >= end - pos) 2184 return pos - buf; 2185 pos += ret; 2186 2187 ret = os_snprintf(pos, end - pos, "flags="); 2188 if (ret < 0 || ret >= end - pos) 2189 return pos - buf; 2190 pos += ret; 2191 2192 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 2193 if (ie) 2194 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]); 2195 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); 2196 if (ie2) 2197 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); 2198 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); 2199 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 2200 ret = os_snprintf(pos, end - pos, "[WEP]"); 2201 if (ret < 0 || ret >= end - pos) 2202 return pos - buf; 2203 pos += ret; 2204 } 2205 if (bss->caps & IEEE80211_CAP_IBSS) { 2206 ret = os_snprintf(pos, end - pos, "[IBSS]"); 2207 if (ret < 0 || ret >= end - pos) 2208 return pos - buf; 2209 pos += ret; 2210 } 2211 if (bss->caps & IEEE80211_CAP_ESS) { 2212 ret = os_snprintf(pos, end - pos, "[ESS]"); 2213 if (ret < 0 || ret >= end - pos) 2214 return pos - buf; 2215 pos += ret; 2216 } 2217 if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) { 2218 ret = os_snprintf(pos, end - pos, "[P2P]"); 2219 if (ret < 0 || ret >= end - pos) 2220 return pos - buf; 2221 pos += ret; 2222 } 2223 2224 ret = os_snprintf(pos, end - pos, "\n"); 2225 if (ret < 0 || ret >= end - pos) 2226 return pos - buf; 2227 pos += ret; 2228 2229 ret = os_snprintf(pos, end - pos, "ssid=%s\n", 2230 wpa_ssid_txt(bss->ssid, bss->ssid_len)); 2231 if (ret < 0 || ret >= end - pos) 2232 return pos - buf; 2233 pos += ret; 2234 2235 #ifdef CONFIG_WPS 2236 ie = (const u8 *) (bss + 1); 2237 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end); 2238 if (ret < 0 || ret >= end - pos) 2239 return pos - buf; 2240 pos += ret; 2241 #endif /* CONFIG_WPS */ 2242 2243 #ifdef CONFIG_P2P 2244 ie = (const u8 *) (bss + 1); 2245 ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end); 2246 if (ret < 0 || ret >= end - pos) 2247 return pos - buf; 2248 pos += ret; 2249 #endif /* CONFIG_P2P */ 2250 2251 #ifdef CONFIG_INTERWORKING 2252 pos = anqp_add_hex(pos, end, "anqp_venue_name", bss->anqp_venue_name); 2253 pos = anqp_add_hex(pos, end, "anqp_network_auth_type", 2254 bss->anqp_network_auth_type); 2255 pos = anqp_add_hex(pos, end, "anqp_roaming_consortium", 2256 bss->anqp_roaming_consortium); 2257 pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability", 2258 bss->anqp_ip_addr_type_availability); 2259 pos = anqp_add_hex(pos, end, "anqp_nai_realm", bss->anqp_nai_realm); 2260 pos = anqp_add_hex(pos, end, "anqp_3gpp", bss->anqp_3gpp); 2261 pos = anqp_add_hex(pos, end, "anqp_domain_name", 2262 bss->anqp_domain_name); 2263 #endif /* CONFIG_INTERWORKING */ 2264 2265 return pos - buf; 2266 } 2267 2268 2269 static int wpa_supplicant_ctrl_iface_ap_scan( 2270 struct wpa_supplicant *wpa_s, char *cmd) 2271 { 2272 int ap_scan = atoi(cmd); 2273 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan); 2274 } 2275 2276 2277 static int wpa_supplicant_ctrl_iface_scan_interval( 2278 struct wpa_supplicant *wpa_s, char *cmd) 2279 { 2280 int scan_int = atoi(cmd); 2281 if (scan_int < 0) 2282 return -1; 2283 wpa_s->scan_interval = scan_int; 2284 return 0; 2285 } 2286 2287 2288 static int wpa_supplicant_ctrl_iface_bss_expire_age( 2289 struct wpa_supplicant *wpa_s, char *cmd) 2290 { 2291 int expire_age = atoi(cmd); 2292 return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age); 2293 } 2294 2295 2296 static int wpa_supplicant_ctrl_iface_bss_expire_count( 2297 struct wpa_supplicant *wpa_s, char *cmd) 2298 { 2299 int expire_count = atoi(cmd); 2300 return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count); 2301 } 2302 2303 2304 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s) 2305 { 2306 wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication"); 2307 /* MLME-DELETEKEYS.request */ 2308 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0); 2309 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0); 2310 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0); 2311 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0); 2312 #ifdef CONFIG_IEEE80211W 2313 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0); 2314 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0); 2315 #endif /* CONFIG_IEEE80211W */ 2316 2317 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL, 2318 0); 2319 /* MLME-SETPROTECTION.request(None) */ 2320 wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid, 2321 MLME_SETPROTECTION_PROTECT_TYPE_NONE, 2322 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE); 2323 wpa_sm_drop_sa(wpa_s->wpa); 2324 } 2325 2326 2327 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s, 2328 char *addr) 2329 { 2330 #ifdef CONFIG_NO_SCAN_PROCESSING 2331 return -1; 2332 #else /* CONFIG_NO_SCAN_PROCESSING */ 2333 u8 bssid[ETH_ALEN]; 2334 struct wpa_bss *bss; 2335 struct wpa_ssid *ssid = wpa_s->current_ssid; 2336 2337 if (hwaddr_aton(addr, bssid)) { 2338 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid " 2339 "address '%s'", addr); 2340 return -1; 2341 } 2342 2343 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid)); 2344 2345 bss = wpa_bss_get_bssid(wpa_s, bssid); 2346 if (!bss) { 2347 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found " 2348 "from BSS table"); 2349 return -1; 2350 } 2351 2352 /* 2353 * TODO: Find best network configuration block from configuration to 2354 * allow roaming to other networks 2355 */ 2356 2357 if (!ssid) { 2358 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network " 2359 "configuration known for the target AP"); 2360 return -1; 2361 } 2362 2363 wpa_s->reassociate = 1; 2364 wpa_supplicant_connect(wpa_s, bss, ssid); 2365 2366 return 0; 2367 #endif /* CONFIG_NO_SCAN_PROCESSING */ 2368 } 2369 2370 2371 #ifdef CONFIG_P2P 2372 static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd) 2373 { 2374 unsigned int timeout = atoi(cmd); 2375 enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL; 2376 u8 dev_id[ETH_ALEN], *_dev_id = NULL; 2377 char *pos; 2378 2379 if (os_strstr(cmd, "type=social")) 2380 type = P2P_FIND_ONLY_SOCIAL; 2381 else if (os_strstr(cmd, "type=progressive")) 2382 type = P2P_FIND_PROGRESSIVE; 2383 2384 pos = os_strstr(cmd, "dev_id="); 2385 if (pos) { 2386 pos += 7; 2387 if (hwaddr_aton(pos, dev_id)) 2388 return -1; 2389 _dev_id = dev_id; 2390 } 2391 2392 return wpas_p2p_find(wpa_s, timeout, type, 0, NULL, _dev_id); 2393 } 2394 2395 2396 static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, 2397 char *buf, size_t buflen) 2398 { 2399 u8 addr[ETH_ALEN]; 2400 char *pos, *pos2; 2401 char *pin = NULL; 2402 enum p2p_wps_method wps_method; 2403 int new_pin; 2404 int ret; 2405 int persistent_group; 2406 int join; 2407 int auth; 2408 int go_intent = -1; 2409 int freq = 0; 2410 2411 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad] [persistent] 2412 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] */ 2413 2414 if (hwaddr_aton(cmd, addr)) 2415 return -1; 2416 2417 pos = cmd + 17; 2418 if (*pos != ' ') 2419 return -1; 2420 pos++; 2421 2422 persistent_group = os_strstr(pos, " persistent") != NULL; 2423 join = os_strstr(pos, " join") != NULL; 2424 auth = os_strstr(pos, " auth") != NULL; 2425 2426 pos2 = os_strstr(pos, " go_intent="); 2427 if (pos2) { 2428 pos2 += 11; 2429 go_intent = atoi(pos2); 2430 if (go_intent < 0 || go_intent > 15) 2431 return -1; 2432 } 2433 2434 pos2 = os_strstr(pos, " freq="); 2435 if (pos2) { 2436 pos2 += 6; 2437 freq = atoi(pos2); 2438 if (freq <= 0) 2439 return -1; 2440 } 2441 2442 if (os_strncmp(pos, "pin", 3) == 0) { 2443 /* Request random PIN (to be displayed) and enable the PIN */ 2444 wps_method = WPS_PIN_DISPLAY; 2445 } else if (os_strncmp(pos, "pbc", 3) == 0) { 2446 wps_method = WPS_PBC; 2447 } else { 2448 pin = pos; 2449 pos = os_strchr(pin, ' '); 2450 wps_method = WPS_PIN_KEYPAD; 2451 if (pos) { 2452 *pos++ = '\0'; 2453 if (os_strncmp(pos, "display", 7) == 0) 2454 wps_method = WPS_PIN_DISPLAY; 2455 } 2456 } 2457 2458 new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method, 2459 persistent_group, join, auth, go_intent, 2460 freq); 2461 if (new_pin == -2) { 2462 os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25); 2463 return 25; 2464 } 2465 if (new_pin == -3) { 2466 os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25); 2467 return 25; 2468 } 2469 if (new_pin < 0) 2470 return -1; 2471 if (wps_method == WPS_PIN_DISPLAY && pin == NULL) { 2472 ret = os_snprintf(buf, buflen, "%08d", new_pin); 2473 if (ret < 0 || (size_t) ret >= buflen) 2474 return -1; 2475 return ret; 2476 } 2477 2478 os_memcpy(buf, "OK\n", 3); 2479 return 3; 2480 } 2481 2482 2483 static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd) 2484 { 2485 unsigned int timeout = atoi(cmd); 2486 return wpas_p2p_listen(wpa_s, timeout); 2487 } 2488 2489 2490 static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd) 2491 { 2492 u8 addr[ETH_ALEN]; 2493 char *pos; 2494 2495 /* <addr> <config method> [join] */ 2496 2497 if (hwaddr_aton(cmd, addr)) 2498 return -1; 2499 2500 pos = cmd + 17; 2501 if (*pos != ' ') 2502 return -1; 2503 pos++; 2504 2505 return wpas_p2p_prov_disc(wpa_s, addr, pos, 2506 os_strstr(pos, "join") != NULL); 2507 } 2508 2509 2510 static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf, 2511 size_t buflen) 2512 { 2513 struct wpa_ssid *ssid = wpa_s->current_ssid; 2514 2515 if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 2516 ssid->passphrase == NULL) 2517 return -1; 2518 2519 os_strlcpy(buf, ssid->passphrase, buflen); 2520 return os_strlen(buf); 2521 } 2522 2523 2524 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd, 2525 char *buf, size_t buflen) 2526 { 2527 u64 ref; 2528 int res; 2529 u8 dst_buf[ETH_ALEN], *dst; 2530 struct wpabuf *tlvs; 2531 char *pos; 2532 size_t len; 2533 2534 if (hwaddr_aton(cmd, dst_buf)) 2535 return -1; 2536 dst = dst_buf; 2537 if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 && 2538 dst[3] == 0 && dst[4] == 0 && dst[5] == 0) 2539 dst = NULL; 2540 pos = cmd + 17; 2541 if (*pos != ' ') 2542 return -1; 2543 pos++; 2544 2545 if (os_strncmp(pos, "upnp ", 5) == 0) { 2546 u8 version; 2547 pos += 5; 2548 if (hexstr2bin(pos, &version, 1) < 0) 2549 return -1; 2550 pos += 2; 2551 if (*pos != ' ') 2552 return -1; 2553 pos++; 2554 ref = (unsigned long) wpas_p2p_sd_request_upnp(wpa_s, dst, 2555 version, pos); 2556 } else { 2557 len = os_strlen(pos); 2558 if (len & 1) 2559 return -1; 2560 len /= 2; 2561 tlvs = wpabuf_alloc(len); 2562 if (tlvs == NULL) 2563 return -1; 2564 if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) { 2565 wpabuf_free(tlvs); 2566 return -1; 2567 } 2568 2569 ref = (unsigned long) wpas_p2p_sd_request(wpa_s, dst, tlvs); 2570 wpabuf_free(tlvs); 2571 } 2572 res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref); 2573 if (res < 0 || (unsigned) res >= buflen) 2574 return -1; 2575 return res; 2576 } 2577 2578 2579 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s, 2580 char *cmd) 2581 { 2582 long long unsigned val; 2583 u64 req; 2584 if (sscanf(cmd, "%llx", &val) != 1) 2585 return -1; 2586 req = val; 2587 return wpas_p2p_sd_cancel_request(wpa_s, (void *) (unsigned long) req); 2588 } 2589 2590 2591 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd) 2592 { 2593 int freq; 2594 u8 dst[ETH_ALEN]; 2595 u8 dialog_token; 2596 struct wpabuf *resp_tlvs; 2597 char *pos, *pos2; 2598 size_t len; 2599 2600 pos = os_strchr(cmd, ' '); 2601 if (pos == NULL) 2602 return -1; 2603 *pos++ = '\0'; 2604 freq = atoi(cmd); 2605 if (freq == 0) 2606 return -1; 2607 2608 if (hwaddr_aton(pos, dst)) 2609 return -1; 2610 pos += 17; 2611 if (*pos != ' ') 2612 return -1; 2613 pos++; 2614 2615 pos2 = os_strchr(pos, ' '); 2616 if (pos2 == NULL) 2617 return -1; 2618 *pos2++ = '\0'; 2619 dialog_token = atoi(pos); 2620 2621 len = os_strlen(pos2); 2622 if (len & 1) 2623 return -1; 2624 len /= 2; 2625 resp_tlvs = wpabuf_alloc(len); 2626 if (resp_tlvs == NULL) 2627 return -1; 2628 if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) { 2629 wpabuf_free(resp_tlvs); 2630 return -1; 2631 } 2632 2633 wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs); 2634 wpabuf_free(resp_tlvs); 2635 return 0; 2636 } 2637 2638 2639 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s, 2640 char *cmd) 2641 { 2642 if (os_strcmp(cmd, "0") && os_strcmp(cmd, "1")) 2643 return -1; 2644 wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd); 2645 return 0; 2646 } 2647 2648 2649 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s, 2650 char *cmd) 2651 { 2652 char *pos; 2653 size_t len; 2654 struct wpabuf *query, *resp; 2655 2656 pos = os_strchr(cmd, ' '); 2657 if (pos == NULL) 2658 return -1; 2659 *pos++ = '\0'; 2660 2661 len = os_strlen(cmd); 2662 if (len & 1) 2663 return -1; 2664 len /= 2; 2665 query = wpabuf_alloc(len); 2666 if (query == NULL) 2667 return -1; 2668 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) { 2669 wpabuf_free(query); 2670 return -1; 2671 } 2672 2673 len = os_strlen(pos); 2674 if (len & 1) { 2675 wpabuf_free(query); 2676 return -1; 2677 } 2678 len /= 2; 2679 resp = wpabuf_alloc(len); 2680 if (resp == NULL) { 2681 wpabuf_free(query); 2682 return -1; 2683 } 2684 if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) { 2685 wpabuf_free(query); 2686 wpabuf_free(resp); 2687 return -1; 2688 } 2689 2690 if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) { 2691 wpabuf_free(query); 2692 wpabuf_free(resp); 2693 return -1; 2694 } 2695 return 0; 2696 } 2697 2698 2699 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd) 2700 { 2701 char *pos; 2702 u8 version; 2703 2704 pos = os_strchr(cmd, ' '); 2705 if (pos == NULL) 2706 return -1; 2707 *pos++ = '\0'; 2708 2709 if (hexstr2bin(cmd, &version, 1) < 0) 2710 return -1; 2711 2712 return wpas_p2p_service_add_upnp(wpa_s, version, pos); 2713 } 2714 2715 2716 static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd) 2717 { 2718 char *pos; 2719 2720 pos = os_strchr(cmd, ' '); 2721 if (pos == NULL) 2722 return -1; 2723 *pos++ = '\0'; 2724 2725 if (os_strcmp(cmd, "bonjour") == 0) 2726 return p2p_ctrl_service_add_bonjour(wpa_s, pos); 2727 if (os_strcmp(cmd, "upnp") == 0) 2728 return p2p_ctrl_service_add_upnp(wpa_s, pos); 2729 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd); 2730 return -1; 2731 } 2732 2733 2734 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s, 2735 char *cmd) 2736 { 2737 size_t len; 2738 struct wpabuf *query; 2739 int ret; 2740 2741 len = os_strlen(cmd); 2742 if (len & 1) 2743 return -1; 2744 len /= 2; 2745 query = wpabuf_alloc(len); 2746 if (query == NULL) 2747 return -1; 2748 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) { 2749 wpabuf_free(query); 2750 return -1; 2751 } 2752 2753 ret = wpas_p2p_service_del_bonjour(wpa_s, query); 2754 wpabuf_free(query); 2755 return ret; 2756 } 2757 2758 2759 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd) 2760 { 2761 char *pos; 2762 u8 version; 2763 2764 pos = os_strchr(cmd, ' '); 2765 if (pos == NULL) 2766 return -1; 2767 *pos++ = '\0'; 2768 2769 if (hexstr2bin(cmd, &version, 1) < 0) 2770 return -1; 2771 2772 return wpas_p2p_service_del_upnp(wpa_s, version, pos); 2773 } 2774 2775 2776 static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd) 2777 { 2778 char *pos; 2779 2780 pos = os_strchr(cmd, ' '); 2781 if (pos == NULL) 2782 return -1; 2783 *pos++ = '\0'; 2784 2785 if (os_strcmp(cmd, "bonjour") == 0) 2786 return p2p_ctrl_service_del_bonjour(wpa_s, pos); 2787 if (os_strcmp(cmd, "upnp") == 0) 2788 return p2p_ctrl_service_del_upnp(wpa_s, pos); 2789 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd); 2790 return -1; 2791 } 2792 2793 2794 static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd) 2795 { 2796 u8 addr[ETH_ALEN]; 2797 2798 /* <addr> */ 2799 2800 if (hwaddr_aton(cmd, addr)) 2801 return -1; 2802 2803 return wpas_p2p_reject(wpa_s, addr); 2804 } 2805 2806 2807 static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) 2808 { 2809 char *pos; 2810 int id; 2811 struct wpa_ssid *ssid; 2812 u8 peer[ETH_ALEN]; 2813 2814 id = atoi(cmd); 2815 pos = os_strstr(cmd, " peer="); 2816 if (pos) { 2817 pos += 6; 2818 if (hwaddr_aton(pos, peer)) 2819 return -1; 2820 } 2821 ssid = wpa_config_get_network(wpa_s->conf, id); 2822 if (ssid == NULL || ssid->disabled != 2) { 2823 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 2824 "for persistent P2P group", 2825 id); 2826 return -1; 2827 } 2828 2829 return wpas_p2p_invite(wpa_s, pos ? peer : NULL, ssid, NULL); 2830 } 2831 2832 2833 static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd) 2834 { 2835 char *pos; 2836 u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL; 2837 2838 pos = os_strstr(cmd, " peer="); 2839 if (!pos) 2840 return -1; 2841 2842 *pos = '\0'; 2843 pos += 6; 2844 if (hwaddr_aton(pos, peer)) { 2845 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos); 2846 return -1; 2847 } 2848 2849 pos = os_strstr(pos, " go_dev_addr="); 2850 if (pos) { 2851 pos += 13; 2852 if (hwaddr_aton(pos, go_dev_addr)) { 2853 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", 2854 pos); 2855 return -1; 2856 } 2857 go_dev = go_dev_addr; 2858 } 2859 2860 return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev); 2861 } 2862 2863 2864 static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd) 2865 { 2866 if (os_strncmp(cmd, "persistent=", 11) == 0) 2867 return p2p_ctrl_invite_persistent(wpa_s, cmd + 11); 2868 if (os_strncmp(cmd, "group=", 6) == 0) 2869 return p2p_ctrl_invite_group(wpa_s, cmd + 6); 2870 2871 return -1; 2872 } 2873 2874 2875 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s, 2876 char *cmd, int freq) 2877 { 2878 int id; 2879 struct wpa_ssid *ssid; 2880 2881 id = atoi(cmd); 2882 ssid = wpa_config_get_network(wpa_s->conf, id); 2883 if (ssid == NULL || ssid->disabled != 2) { 2884 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 2885 "for persistent P2P group", 2886 id); 2887 return -1; 2888 } 2889 2890 return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq); 2891 } 2892 2893 2894 static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) 2895 { 2896 int freq = 0; 2897 char *pos; 2898 2899 pos = os_strstr(cmd, "freq="); 2900 if (pos) 2901 freq = atoi(pos + 5); 2902 2903 if (os_strncmp(cmd, "persistent=", 11) == 0) 2904 return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq); 2905 if (os_strcmp(cmd, "persistent") == 0 || 2906 os_strncmp(cmd, "persistent ", 11) == 0) 2907 return wpas_p2p_group_add(wpa_s, 1, freq); 2908 if (os_strncmp(cmd, "freq=", 5) == 0) 2909 return wpas_p2p_group_add(wpa_s, 0, freq); 2910 2911 wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'", 2912 cmd); 2913 return -1; 2914 } 2915 2916 2917 static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd, 2918 char *buf, size_t buflen) 2919 { 2920 u8 addr[ETH_ALEN], *addr_ptr; 2921 int next, res; 2922 const struct p2p_peer_info *info; 2923 char *pos, *end; 2924 char devtype[WPS_DEV_TYPE_BUFSIZE]; 2925 struct wpa_ssid *ssid; 2926 2927 if (!wpa_s->global->p2p) 2928 return -1; 2929 2930 if (os_strcmp(cmd, "FIRST") == 0) { 2931 addr_ptr = NULL; 2932 next = 0; 2933 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { 2934 if (hwaddr_aton(cmd + 5, addr) < 0) 2935 return -1; 2936 addr_ptr = addr; 2937 next = 1; 2938 } else { 2939 if (hwaddr_aton(cmd, addr) < 0) 2940 return -1; 2941 addr_ptr = addr; 2942 next = 0; 2943 } 2944 2945 info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next); 2946 if (info == NULL) 2947 return -1; 2948 2949 pos = buf; 2950 end = buf + buflen; 2951 2952 res = os_snprintf(pos, end - pos, MACSTR "\n" 2953 "pri_dev_type=%s\n" 2954 "device_name=%s\n" 2955 "manufacturer=%s\n" 2956 "model_name=%s\n" 2957 "model_number=%s\n" 2958 "serial_number=%s\n" 2959 "config_methods=0x%x\n" 2960 "dev_capab=0x%x\n" 2961 "group_capab=0x%x\n" 2962 "level=%d\n", 2963 MAC2STR(info->p2p_device_addr), 2964 wps_dev_type_bin2str(info->pri_dev_type, 2965 devtype, sizeof(devtype)), 2966 info->device_name, 2967 info->manufacturer, 2968 info->model_name, 2969 info->model_number, 2970 info->serial_number, 2971 info->config_methods, 2972 info->dev_capab, 2973 info->group_capab, 2974 info->level); 2975 if (res < 0 || res >= end - pos) 2976 return pos - buf; 2977 pos += res; 2978 2979 ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr, NULL, 0); 2980 if (ssid) { 2981 res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id); 2982 if (res < 0 || res >= end - pos) 2983 return pos - buf; 2984 pos += res; 2985 } 2986 2987 res = p2p_get_peer_info_txt(info, pos, end - pos); 2988 if (res < 0) 2989 return pos - buf; 2990 pos += res; 2991 2992 return pos - buf; 2993 } 2994 2995 2996 static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd) 2997 { 2998 char *param; 2999 3000 if (wpa_s->global->p2p == NULL) 3001 return -1; 3002 3003 param = os_strchr(cmd, ' '); 3004 if (param == NULL) 3005 return -1; 3006 *param++ = '\0'; 3007 3008 if (os_strcmp(cmd, "discoverability") == 0) { 3009 p2p_set_client_discoverability(wpa_s->global->p2p, 3010 atoi(param)); 3011 return 0; 3012 } 3013 3014 if (os_strcmp(cmd, "managed") == 0) { 3015 p2p_set_managed_oper(wpa_s->global->p2p, atoi(param)); 3016 return 0; 3017 } 3018 3019 if (os_strcmp(cmd, "listen_channel") == 0) { 3020 return p2p_set_listen_channel(wpa_s->global->p2p, 81, 3021 atoi(param)); 3022 } 3023 3024 if (os_strcmp(cmd, "ssid_postfix") == 0) { 3025 return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param, 3026 os_strlen(param)); 3027 } 3028 3029 if (os_strcmp(cmd, "noa") == 0) { 3030 char *pos; 3031 int count, start, duration; 3032 /* GO NoA parameters: count,start_offset(ms),duration(ms) */ 3033 count = atoi(param); 3034 pos = os_strchr(param, ','); 3035 if (pos == NULL) 3036 return -1; 3037 pos++; 3038 start = atoi(pos); 3039 pos = os_strchr(pos, ','); 3040 if (pos == NULL) 3041 return -1; 3042 pos++; 3043 duration = atoi(pos); 3044 if (count < 0 || count > 255 || start < 0 || duration < 0) 3045 return -1; 3046 if (count == 0 && duration > 0) 3047 return -1; 3048 wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d " 3049 "start=%d duration=%d", count, start, duration); 3050 return wpas_p2p_set_noa(wpa_s, count, start, duration); 3051 } 3052 3053 if (os_strcmp(cmd, "ps") == 0) 3054 return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1); 3055 3056 if (os_strcmp(cmd, "oppps") == 0) 3057 return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1); 3058 3059 if (os_strcmp(cmd, "ctwindow") == 0) 3060 return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param)); 3061 3062 if (os_strcmp(cmd, "disabled") == 0) { 3063 wpa_s->global->p2p_disabled = atoi(param); 3064 wpa_printf(MSG_DEBUG, "P2P functionality %s", 3065 wpa_s->global->p2p_disabled ? 3066 "disabled" : "enabled"); 3067 if (wpa_s->global->p2p_disabled) { 3068 wpas_p2p_stop_find(wpa_s); 3069 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 3070 p2p_flush(wpa_s->global->p2p); 3071 } 3072 return 0; 3073 } 3074 3075 if (os_strcmp(cmd, "force_long_sd") == 0) { 3076 wpa_s->force_long_sd = atoi(param); 3077 return 0; 3078 } 3079 3080 if (os_strcmp(cmd, "peer_filter") == 0) { 3081 u8 addr[ETH_ALEN]; 3082 if (hwaddr_aton(param, addr)) 3083 return -1; 3084 p2p_set_peer_filter(wpa_s->global->p2p, addr); 3085 return 0; 3086 } 3087 3088 if (os_strcmp(cmd, "cross_connect") == 0) 3089 return wpas_p2p_set_cross_connect(wpa_s, atoi(param)); 3090 3091 if (os_strcmp(cmd, "go_apsd") == 0) { 3092 if (os_strcmp(param, "disable") == 0) 3093 wpa_s->set_ap_uapsd = 0; 3094 else { 3095 wpa_s->set_ap_uapsd = 1; 3096 wpa_s->ap_uapsd = atoi(param); 3097 } 3098 return 0; 3099 } 3100 3101 if (os_strcmp(cmd, "client_apsd") == 0) { 3102 if (os_strcmp(param, "disable") == 0) 3103 wpa_s->set_sta_uapsd = 0; 3104 else { 3105 int be, bk, vi, vo; 3106 char *pos; 3107 /* format: BE,BK,VI,VO;max SP Length */ 3108 be = atoi(param); 3109 pos = os_strchr(param, ','); 3110 if (pos == NULL) 3111 return -1; 3112 pos++; 3113 bk = atoi(pos); 3114 pos = os_strchr(pos, ','); 3115 if (pos == NULL) 3116 return -1; 3117 pos++; 3118 vi = atoi(pos); 3119 pos = os_strchr(pos, ','); 3120 if (pos == NULL) 3121 return -1; 3122 pos++; 3123 vo = atoi(pos); 3124 /* ignore max SP Length for now */ 3125 3126 wpa_s->set_sta_uapsd = 1; 3127 wpa_s->sta_uapsd = 0; 3128 if (be) 3129 wpa_s->sta_uapsd |= BIT(0); 3130 if (bk) 3131 wpa_s->sta_uapsd |= BIT(1); 3132 if (vi) 3133 wpa_s->sta_uapsd |= BIT(2); 3134 if (vo) 3135 wpa_s->sta_uapsd |= BIT(3); 3136 } 3137 return 0; 3138 } 3139 3140 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'", 3141 cmd); 3142 3143 return -1; 3144 } 3145 3146 3147 static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd) 3148 { 3149 char *pos, *pos2; 3150 unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0; 3151 3152 if (cmd[0]) { 3153 pos = os_strchr(cmd, ' '); 3154 if (pos == NULL) 3155 return -1; 3156 *pos++ = '\0'; 3157 dur1 = atoi(cmd); 3158 3159 pos2 = os_strchr(pos, ' '); 3160 if (pos2) 3161 *pos2++ = '\0'; 3162 int1 = atoi(pos); 3163 } else 3164 pos2 = NULL; 3165 3166 if (pos2) { 3167 pos = os_strchr(pos2, ' '); 3168 if (pos == NULL) 3169 return -1; 3170 *pos++ = '\0'; 3171 dur2 = atoi(pos2); 3172 int2 = atoi(pos); 3173 } 3174 3175 return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2); 3176 } 3177 3178 3179 static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd) 3180 { 3181 char *pos; 3182 unsigned int period = 0, interval = 0; 3183 3184 if (cmd[0]) { 3185 pos = os_strchr(cmd, ' '); 3186 if (pos == NULL) 3187 return -1; 3188 *pos++ = '\0'; 3189 period = atoi(cmd); 3190 interval = atoi(pos); 3191 } 3192 3193 return wpas_p2p_ext_listen(wpa_s, period, interval); 3194 } 3195 3196 #endif /* CONFIG_P2P */ 3197 3198 3199 #ifdef CONFIG_INTERWORKING 3200 static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst) 3201 { 3202 u8 bssid[ETH_ALEN]; 3203 struct wpa_bss *bss; 3204 3205 if (hwaddr_aton(dst, bssid)) { 3206 wpa_printf(MSG_DEBUG, "Invalid BSSID '%s'", dst); 3207 return -1; 3208 } 3209 3210 bss = wpa_bss_get_bssid(wpa_s, bssid); 3211 if (bss == NULL) { 3212 wpa_printf(MSG_DEBUG, "Could not find BSS " MACSTR, 3213 MAC2STR(bssid)); 3214 return -1; 3215 } 3216 3217 return interworking_connect(wpa_s, bss); 3218 } 3219 3220 3221 static int get_anqp(struct wpa_supplicant *wpa_s, char *dst) 3222 { 3223 u8 dst_addr[ETH_ALEN]; 3224 int used; 3225 char *pos; 3226 #define MAX_ANQP_INFO_ID 100 3227 u16 id[MAX_ANQP_INFO_ID]; 3228 size_t num_id = 0; 3229 3230 used = hwaddr_aton2(dst, dst_addr); 3231 if (used < 0) 3232 return -1; 3233 pos = dst + used; 3234 while (num_id < MAX_ANQP_INFO_ID) { 3235 id[num_id] = atoi(pos); 3236 if (id[num_id]) 3237 num_id++; 3238 pos = os_strchr(pos + 1, ','); 3239 if (pos == NULL) 3240 break; 3241 pos++; 3242 } 3243 3244 if (num_id == 0) 3245 return -1; 3246 3247 return anqp_send_req(wpa_s, dst_addr, id, num_id); 3248 } 3249 #endif /* CONFIG_INTERWORKING */ 3250 3251 3252 static int wpa_supplicant_ctrl_iface_sta_autoconnect( 3253 struct wpa_supplicant *wpa_s, char *cmd) 3254 { 3255 wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0; 3256 return 0; 3257 } 3258 3259 3260 static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf, 3261 size_t buflen) 3262 { 3263 struct wpa_signal_info si; 3264 int ret; 3265 3266 ret = wpa_drv_signal_poll(wpa_s, &si); 3267 if (ret) 3268 return -1; 3269 3270 ret = os_snprintf(buf, buflen, "RSSI=%d\nLINKSPEED=%d\n" 3271 "NOISE=%d\nFREQUENCY=%u\n", 3272 si.current_signal, si.current_txrate / 1000, 3273 si.current_noise, si.frequency); 3274 if (ret < 0 || (unsigned int) ret > buflen) 3275 return -1; 3276 return ret; 3277 } 3278 3279 3280 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, 3281 char *buf, size_t *resp_len) 3282 { 3283 char *reply; 3284 const int reply_size = 4096; 3285 int ctrl_rsp = 0; 3286 int reply_len; 3287 3288 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 || 3289 os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 3290 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface", 3291 (const u8 *) buf, os_strlen(buf)); 3292 } else { 3293 int level = MSG_DEBUG; 3294 if (os_strcmp(buf, "PING") == 0) 3295 level = MSG_EXCESSIVE; 3296 wpa_hexdump_ascii(level, "RX ctrl_iface", 3297 (const u8 *) buf, os_strlen(buf)); 3298 } 3299 3300 reply = os_malloc(reply_size); 3301 if (reply == NULL) { 3302 *resp_len = 1; 3303 return NULL; 3304 } 3305 3306 os_memcpy(reply, "OK\n", 3); 3307 reply_len = 3; 3308 3309 if (os_strcmp(buf, "PING") == 0) { 3310 os_memcpy(reply, "PONG\n", 5); 3311 reply_len = 5; 3312 } else if (os_strncmp(buf, "RELOG", 5) == 0) { 3313 if (wpa_debug_reopen_file() < 0) 3314 reply_len = -1; 3315 } else if (os_strncmp(buf, "NOTE ", 5) == 0) { 3316 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); 3317 } else if (os_strcmp(buf, "MIB") == 0) { 3318 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); 3319 if (reply_len >= 0) { 3320 int res; 3321 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len, 3322 reply_size - reply_len); 3323 if (res < 0) 3324 reply_len = -1; 3325 else 3326 reply_len += res; 3327 } 3328 } else if (os_strncmp(buf, "STATUS", 6) == 0) { 3329 reply_len = wpa_supplicant_ctrl_iface_status( 3330 wpa_s, buf + 6, reply, reply_size); 3331 } else if (os_strcmp(buf, "PMKSA") == 0) { 3332 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply, 3333 reply_size); 3334 } else if (os_strncmp(buf, "SET ", 4) == 0) { 3335 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) 3336 reply_len = -1; 3337 } else if (os_strncmp(buf, "GET ", 4) == 0) { 3338 reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4, 3339 reply, reply_size); 3340 } else if (os_strcmp(buf, "LOGON") == 0) { 3341 eapol_sm_notify_logoff(wpa_s->eapol, FALSE); 3342 } else if (os_strcmp(buf, "LOGOFF") == 0) { 3343 eapol_sm_notify_logoff(wpa_s->eapol, TRUE); 3344 } else if (os_strcmp(buf, "REASSOCIATE") == 0) { 3345 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 3346 reply_len = -1; 3347 else { 3348 wpa_s->disconnected = 0; 3349 wpa_s->reassociate = 1; 3350 wpa_supplicant_req_scan(wpa_s, 0, 0); 3351 } 3352 } else if (os_strcmp(buf, "RECONNECT") == 0) { 3353 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 3354 reply_len = -1; 3355 else if (wpa_s->disconnected) { 3356 wpa_s->disconnected = 0; 3357 wpa_s->reassociate = 1; 3358 wpa_supplicant_req_scan(wpa_s, 0, 0); 3359 } 3360 #ifdef IEEE8021X_EAPOL 3361 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) { 3362 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8)) 3363 reply_len = -1; 3364 #endif /* IEEE8021X_EAPOL */ 3365 #ifdef CONFIG_PEERKEY 3366 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) { 3367 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9)) 3368 reply_len = -1; 3369 #endif /* CONFIG_PEERKEY */ 3370 #ifdef CONFIG_IEEE80211R 3371 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) { 3372 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6)) 3373 reply_len = -1; 3374 #endif /* CONFIG_IEEE80211R */ 3375 #ifdef CONFIG_WPS 3376 } else if (os_strcmp(buf, "WPS_PBC") == 0) { 3377 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL); 3378 if (res == -2) { 3379 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 3380 reply_len = 17; 3381 } else if (res) 3382 reply_len = -1; 3383 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) { 3384 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8); 3385 if (res == -2) { 3386 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 3387 reply_len = 17; 3388 } else if (res) 3389 reply_len = -1; 3390 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) { 3391 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8, 3392 reply, 3393 reply_size); 3394 } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) { 3395 reply_len = wpa_supplicant_ctrl_iface_wps_check_pin( 3396 wpa_s, buf + 14, reply, reply_size); 3397 } else if (os_strcmp(buf, "WPS_CANCEL") == 0) { 3398 if (wpas_wps_cancel(wpa_s)) 3399 reply_len = -1; 3400 #ifdef CONFIG_WPS_OOB 3401 } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) { 3402 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8)) 3403 reply_len = -1; 3404 #endif /* CONFIG_WPS_OOB */ 3405 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) { 3406 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8)) 3407 reply_len = -1; 3408 #ifdef CONFIG_AP 3409 } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) { 3410 reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin( 3411 wpa_s, buf + 11, reply, reply_size); 3412 #endif /* CONFIG_AP */ 3413 #ifdef CONFIG_WPS_ER 3414 } else if (os_strcmp(buf, "WPS_ER_START") == 0) { 3415 if (wpas_wps_er_start(wpa_s, NULL)) 3416 reply_len = -1; 3417 } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) { 3418 if (wpas_wps_er_start(wpa_s, buf + 13)) 3419 reply_len = -1; 3420 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) { 3421 if (wpas_wps_er_stop(wpa_s)) 3422 reply_len = -1; 3423 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) { 3424 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11)) 3425 reply_len = -1; 3426 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) { 3427 int ret = wpas_wps_er_pbc(wpa_s, buf + 11); 3428 if (ret == -2) { 3429 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 3430 reply_len = 17; 3431 } else if (ret == -3) { 3432 os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18); 3433 reply_len = 18; 3434 } else if (ret == -4) { 3435 os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20); 3436 reply_len = 20; 3437 } else if (ret) 3438 reply_len = -1; 3439 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) { 3440 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13)) 3441 reply_len = -1; 3442 } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) { 3443 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s, 3444 buf + 18)) 3445 reply_len = -1; 3446 } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) { 3447 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14)) 3448 reply_len = -1; 3449 #endif /* CONFIG_WPS_ER */ 3450 #endif /* CONFIG_WPS */ 3451 #ifdef CONFIG_IBSS_RSN 3452 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) { 3453 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9)) 3454 reply_len = -1; 3455 #endif /* CONFIG_IBSS_RSN */ 3456 #ifdef CONFIG_P2P 3457 } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) { 3458 if (p2p_ctrl_find(wpa_s, buf + 9)) 3459 reply_len = -1; 3460 } else if (os_strcmp(buf, "P2P_FIND") == 0) { 3461 if (p2p_ctrl_find(wpa_s, "")) 3462 reply_len = -1; 3463 } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) { 3464 wpas_p2p_stop_find(wpa_s); 3465 } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) { 3466 reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply, 3467 reply_size); 3468 } else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) { 3469 if (p2p_ctrl_listen(wpa_s, buf + 11)) 3470 reply_len = -1; 3471 } else if (os_strcmp(buf, "P2P_LISTEN") == 0) { 3472 if (p2p_ctrl_listen(wpa_s, "")) 3473 reply_len = -1; 3474 } else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) { 3475 if (wpas_p2p_group_remove(wpa_s, buf + 17)) 3476 reply_len = -1; 3477 } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) { 3478 if (wpas_p2p_group_add(wpa_s, 0, 0)) 3479 reply_len = -1; 3480 } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) { 3481 if (p2p_ctrl_group_add(wpa_s, buf + 14)) 3482 reply_len = -1; 3483 } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) { 3484 if (p2p_ctrl_prov_disc(wpa_s, buf + 14)) 3485 reply_len = -1; 3486 } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) { 3487 reply_len = p2p_get_passphrase(wpa_s, reply, reply_size); 3488 } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) { 3489 reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply, 3490 reply_size); 3491 } else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) { 3492 if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0) 3493 reply_len = -1; 3494 } else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) { 3495 if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0) 3496 reply_len = -1; 3497 } else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) { 3498 wpas_p2p_sd_service_update(wpa_s); 3499 } else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) { 3500 if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0) 3501 reply_len = -1; 3502 } else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) { 3503 wpas_p2p_service_flush(wpa_s); 3504 } else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) { 3505 if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0) 3506 reply_len = -1; 3507 } else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) { 3508 if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0) 3509 reply_len = -1; 3510 } else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) { 3511 if (p2p_ctrl_reject(wpa_s, buf + 11) < 0) 3512 reply_len = -1; 3513 } else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) { 3514 if (p2p_ctrl_invite(wpa_s, buf + 11) < 0) 3515 reply_len = -1; 3516 } else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) { 3517 reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply, 3518 reply_size); 3519 } else if (os_strncmp(buf, "P2P_SET ", 8) == 0) { 3520 if (p2p_ctrl_set(wpa_s, buf + 8) < 0) 3521 reply_len = -1; 3522 } else if (os_strcmp(buf, "P2P_FLUSH") == 0) { 3523 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 3524 wpa_s->force_long_sd = 0; 3525 if (wpa_s->global->p2p) 3526 p2p_flush(wpa_s->global->p2p); 3527 } else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) { 3528 if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0) 3529 reply_len = -1; 3530 } else if (os_strcmp(buf, "P2P_CANCEL") == 0) { 3531 if (wpas_p2p_cancel(wpa_s)) 3532 reply_len = -1; 3533 } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) { 3534 if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0) 3535 reply_len = -1; 3536 } else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) { 3537 if (p2p_ctrl_presence_req(wpa_s, "") < 0) 3538 reply_len = -1; 3539 } else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) { 3540 if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0) 3541 reply_len = -1; 3542 } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) { 3543 if (p2p_ctrl_ext_listen(wpa_s, "") < 0) 3544 reply_len = -1; 3545 #endif /* CONFIG_P2P */ 3546 #ifdef CONFIG_INTERWORKING 3547 } else if (os_strcmp(buf, "FETCH_ANQP") == 0) { 3548 if (interworking_fetch_anqp(wpa_s) < 0) 3549 reply_len = -1; 3550 } else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) { 3551 interworking_stop_fetch_anqp(wpa_s); 3552 } else if (os_strncmp(buf, "INTERWORKING_SELECT", 19) == 0) { 3553 if (interworking_select(wpa_s, os_strstr(buf + 19, "auto") != 3554 NULL) < 0) 3555 reply_len = -1; 3556 } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) { 3557 if (ctrl_interworking_connect(wpa_s, buf + 21) < 0) 3558 reply_len = -1; 3559 } else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) { 3560 if (get_anqp(wpa_s, buf + 9) < 0) 3561 reply_len = -1; 3562 #endif /* CONFIG_INTERWORKING */ 3563 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0) 3564 { 3565 if (wpa_supplicant_ctrl_iface_ctrl_rsp( 3566 wpa_s, buf + os_strlen(WPA_CTRL_RSP))) 3567 reply_len = -1; 3568 else 3569 ctrl_rsp = 1; 3570 } else if (os_strcmp(buf, "RECONFIGURE") == 0) { 3571 if (wpa_supplicant_reload_configuration(wpa_s)) 3572 reply_len = -1; 3573 } else if (os_strcmp(buf, "TERMINATE") == 0) { 3574 wpa_supplicant_terminate_proc(wpa_s->global); 3575 } else if (os_strncmp(buf, "BSSID ", 6) == 0) { 3576 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) 3577 reply_len = -1; 3578 } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) { 3579 reply_len = wpa_supplicant_ctrl_iface_blacklist( 3580 wpa_s, buf + 9, reply, reply_size); 3581 } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) { 3582 reply_len = wpa_supplicant_ctrl_iface_log_level( 3583 wpa_s, buf + 9, reply, reply_size); 3584 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) { 3585 reply_len = wpa_supplicant_ctrl_iface_list_networks( 3586 wpa_s, reply, reply_size); 3587 } else if (os_strcmp(buf, "DISCONNECT") == 0) { 3588 #ifdef CONFIG_SME 3589 wpa_s->sme.prev_bssid_set = 0; 3590 #endif /* CONFIG_SME */ 3591 wpa_s->reassociate = 0; 3592 wpa_s->disconnected = 1; 3593 wpa_supplicant_deauthenticate(wpa_s, 3594 WLAN_REASON_DEAUTH_LEAVING); 3595 } else if (os_strcmp(buf, "SCAN") == 0) { 3596 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 3597 reply_len = -1; 3598 else { 3599 if (!wpa_s->scanning && 3600 ((wpa_s->wpa_state <= WPA_SCANNING) || 3601 (wpa_s->wpa_state == WPA_COMPLETED))) { 3602 wpa_s->scan_req = 2; 3603 wpa_supplicant_req_scan(wpa_s, 0, 0); 3604 } else { 3605 wpa_printf(MSG_DEBUG, "Ongoing scan action - " 3606 "reject new request"); 3607 reply_len = os_snprintf(reply, reply_size, 3608 "FAIL-BUSY\n"); 3609 } 3610 } 3611 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) { 3612 reply_len = wpa_supplicant_ctrl_iface_scan_results( 3613 wpa_s, reply, reply_size); 3614 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) { 3615 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15)) 3616 reply_len = -1; 3617 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) { 3618 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15)) 3619 reply_len = -1; 3620 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) { 3621 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16)) 3622 reply_len = -1; 3623 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) { 3624 reply_len = wpa_supplicant_ctrl_iface_add_network( 3625 wpa_s, reply, reply_size); 3626 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) { 3627 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15)) 3628 reply_len = -1; 3629 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 3630 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12)) 3631 reply_len = -1; 3632 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) { 3633 reply_len = wpa_supplicant_ctrl_iface_get_network( 3634 wpa_s, buf + 12, reply, reply_size); 3635 #ifndef CONFIG_NO_CONFIG_WRITE 3636 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) { 3637 if (wpa_supplicant_ctrl_iface_save_config(wpa_s)) 3638 reply_len = -1; 3639 #endif /* CONFIG_NO_CONFIG_WRITE */ 3640 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) { 3641 reply_len = wpa_supplicant_ctrl_iface_get_capability( 3642 wpa_s, buf + 15, reply, reply_size); 3643 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) { 3644 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8)) 3645 reply_len = -1; 3646 } else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) { 3647 if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s, buf + 14)) 3648 reply_len = -1; 3649 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 3650 reply_len = wpa_supplicant_global_iface_list( 3651 wpa_s->global, reply, reply_size); 3652 } else if (os_strcmp(buf, "INTERFACES") == 0) { 3653 reply_len = wpa_supplicant_global_iface_interfaces( 3654 wpa_s->global, reply, reply_size); 3655 } else if (os_strncmp(buf, "BSS ", 4) == 0) { 3656 reply_len = wpa_supplicant_ctrl_iface_bss( 3657 wpa_s, buf + 4, reply, reply_size); 3658 #ifdef CONFIG_AP 3659 } else if (os_strcmp(buf, "STA-FIRST") == 0) { 3660 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); 3661 } else if (os_strncmp(buf, "STA ", 4) == 0) { 3662 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply, 3663 reply_size); 3664 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { 3665 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, 3666 reply_size); 3667 #endif /* CONFIG_AP */ 3668 } else if (os_strcmp(buf, "SUSPEND") == 0) { 3669 wpas_notify_suspend(wpa_s->global); 3670 } else if (os_strcmp(buf, "RESUME") == 0) { 3671 wpas_notify_resume(wpa_s->global); 3672 } else if (os_strcmp(buf, "DROP_SA") == 0) { 3673 wpa_supplicant_ctrl_iface_drop_sa(wpa_s); 3674 } else if (os_strncmp(buf, "ROAM ", 5) == 0) { 3675 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5)) 3676 reply_len = -1; 3677 } else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) { 3678 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16)) 3679 reply_len = -1; 3680 } else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) { 3681 if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15)) 3682 reply_len = -1; 3683 } else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) { 3684 if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s, 3685 buf + 17)) 3686 reply_len = -1; 3687 #ifdef CONFIG_TDLS 3688 } else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) { 3689 if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14)) 3690 reply_len = -1; 3691 } else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) { 3692 if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11)) 3693 reply_len = -1; 3694 } else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) { 3695 if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14)) 3696 reply_len = -1; 3697 #endif /* CONFIG_TDLS */ 3698 } else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) { 3699 reply_len = wpa_supplicant_signal_poll(wpa_s, reply, 3700 reply_size); 3701 } else { 3702 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 3703 reply_len = 16; 3704 } 3705 3706 if (reply_len < 0) { 3707 os_memcpy(reply, "FAIL\n", 5); 3708 reply_len = 5; 3709 } 3710 3711 if (ctrl_rsp) 3712 eapol_sm_notify_ctrl_response(wpa_s->eapol); 3713 3714 *resp_len = reply_len; 3715 return reply; 3716 } 3717 3718 3719 static int wpa_supplicant_global_iface_add(struct wpa_global *global, 3720 char *cmd) 3721 { 3722 struct wpa_interface iface; 3723 char *pos; 3724 3725 /* 3726 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param> 3727 * TAB<bridge_ifname> 3728 */ 3729 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd); 3730 3731 os_memset(&iface, 0, sizeof(iface)); 3732 3733 do { 3734 iface.ifname = pos = cmd; 3735 pos = os_strchr(pos, '\t'); 3736 if (pos) 3737 *pos++ = '\0'; 3738 if (iface.ifname[0] == '\0') 3739 return -1; 3740 if (pos == NULL) 3741 break; 3742 3743 iface.confname = pos; 3744 pos = os_strchr(pos, '\t'); 3745 if (pos) 3746 *pos++ = '\0'; 3747 if (iface.confname[0] == '\0') 3748 iface.confname = NULL; 3749 if (pos == NULL) 3750 break; 3751 3752 iface.driver = pos; 3753 pos = os_strchr(pos, '\t'); 3754 if (pos) 3755 *pos++ = '\0'; 3756 if (iface.driver[0] == '\0') 3757 iface.driver = NULL; 3758 if (pos == NULL) 3759 break; 3760 3761 iface.ctrl_interface = pos; 3762 pos = os_strchr(pos, '\t'); 3763 if (pos) 3764 *pos++ = '\0'; 3765 if (iface.ctrl_interface[0] == '\0') 3766 iface.ctrl_interface = NULL; 3767 if (pos == NULL) 3768 break; 3769 3770 iface.driver_param = pos; 3771 pos = os_strchr(pos, '\t'); 3772 if (pos) 3773 *pos++ = '\0'; 3774 if (iface.driver_param[0] == '\0') 3775 iface.driver_param = NULL; 3776 if (pos == NULL) 3777 break; 3778 3779 iface.bridge_ifname = pos; 3780 pos = os_strchr(pos, '\t'); 3781 if (pos) 3782 *pos++ = '\0'; 3783 if (iface.bridge_ifname[0] == '\0') 3784 iface.bridge_ifname = NULL; 3785 if (pos == NULL) 3786 break; 3787 } while (0); 3788 3789 if (wpa_supplicant_get_iface(global, iface.ifname)) 3790 return -1; 3791 3792 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1; 3793 } 3794 3795 3796 static int wpa_supplicant_global_iface_remove(struct wpa_global *global, 3797 char *cmd) 3798 { 3799 struct wpa_supplicant *wpa_s; 3800 3801 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd); 3802 3803 wpa_s = wpa_supplicant_get_iface(global, cmd); 3804 if (wpa_s == NULL) 3805 return -1; 3806 return wpa_supplicant_remove_iface(global, wpa_s); 3807 } 3808 3809 3810 static void wpa_free_iface_info(struct wpa_interface_info *iface) 3811 { 3812 struct wpa_interface_info *prev; 3813 3814 while (iface) { 3815 prev = iface; 3816 iface = iface->next; 3817 3818 os_free(prev->ifname); 3819 os_free(prev->desc); 3820 os_free(prev); 3821 } 3822 } 3823 3824 3825 static int wpa_supplicant_global_iface_list(struct wpa_global *global, 3826 char *buf, int len) 3827 { 3828 int i, res; 3829 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp; 3830 char *pos, *end; 3831 3832 for (i = 0; wpa_drivers[i]; i++) { 3833 struct wpa_driver_ops *drv = wpa_drivers[i]; 3834 if (drv->get_interfaces == NULL) 3835 continue; 3836 tmp = drv->get_interfaces(global->drv_priv[i]); 3837 if (tmp == NULL) 3838 continue; 3839 3840 if (last == NULL) 3841 iface = last = tmp; 3842 else 3843 last->next = tmp; 3844 while (last->next) 3845 last = last->next; 3846 } 3847 3848 pos = buf; 3849 end = buf + len; 3850 for (tmp = iface; tmp; tmp = tmp->next) { 3851 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n", 3852 tmp->drv_name, tmp->ifname, 3853 tmp->desc ? tmp->desc : ""); 3854 if (res < 0 || res >= end - pos) { 3855 *pos = '\0'; 3856 break; 3857 } 3858 pos += res; 3859 } 3860 3861 wpa_free_iface_info(iface); 3862 3863 return pos - buf; 3864 } 3865 3866 3867 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 3868 char *buf, int len) 3869 { 3870 int res; 3871 char *pos, *end; 3872 struct wpa_supplicant *wpa_s; 3873 3874 wpa_s = global->ifaces; 3875 pos = buf; 3876 end = buf + len; 3877 3878 while (wpa_s) { 3879 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname); 3880 if (res < 0 || res >= end - pos) { 3881 *pos = '\0'; 3882 break; 3883 } 3884 pos += res; 3885 wpa_s = wpa_s->next; 3886 } 3887 return pos - buf; 3888 } 3889 3890 3891 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global, 3892 char *buf, size_t *resp_len) 3893 { 3894 char *reply; 3895 const int reply_size = 2048; 3896 int reply_len; 3897 int level = MSG_DEBUG; 3898 3899 if (os_strcmp(buf, "PING") == 0) 3900 level = MSG_EXCESSIVE; 3901 wpa_hexdump_ascii(level, "RX global ctrl_iface", 3902 (const u8 *) buf, os_strlen(buf)); 3903 3904 reply = os_malloc(reply_size); 3905 if (reply == NULL) { 3906 *resp_len = 1; 3907 return NULL; 3908 } 3909 3910 os_memcpy(reply, "OK\n", 3); 3911 reply_len = 3; 3912 3913 if (os_strcmp(buf, "PING") == 0) { 3914 os_memcpy(reply, "PONG\n", 5); 3915 reply_len = 5; 3916 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) { 3917 if (wpa_supplicant_global_iface_add(global, buf + 14)) 3918 reply_len = -1; 3919 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) { 3920 if (wpa_supplicant_global_iface_remove(global, buf + 17)) 3921 reply_len = -1; 3922 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 3923 reply_len = wpa_supplicant_global_iface_list( 3924 global, reply, reply_size); 3925 } else if (os_strcmp(buf, "INTERFACES") == 0) { 3926 reply_len = wpa_supplicant_global_iface_interfaces( 3927 global, reply, reply_size); 3928 } else if (os_strcmp(buf, "TERMINATE") == 0) { 3929 wpa_supplicant_terminate_proc(global); 3930 } else if (os_strcmp(buf, "SUSPEND") == 0) { 3931 wpas_notify_suspend(global); 3932 } else if (os_strcmp(buf, "RESUME") == 0) { 3933 wpas_notify_resume(global); 3934 } else { 3935 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 3936 reply_len = 16; 3937 } 3938 3939 if (reply_len < 0) { 3940 os_memcpy(reply, "FAIL\n", 5); 3941 reply_len = 5; 3942 } 3943 3944 *resp_len = reply_len; 3945 return reply; 3946 } 3947