1 /* 2 * WPA Supplicant / Control interface (shared code for all backends) 3 * Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "utils/includes.h" 10 11 #include "utils/common.h" 12 #include "utils/eloop.h" 13 #include "utils/uuid.h" 14 #include "common/version.h" 15 #include "common/ieee802_11_defs.h" 16 #include "common/ieee802_11_common.h" 17 #include "common/wpa_ctrl.h" 18 #include "eap_peer/eap.h" 19 #include "eapol_supp/eapol_supp_sm.h" 20 #include "rsn_supp/wpa.h" 21 #include "rsn_supp/preauth.h" 22 #include "rsn_supp/pmksa_cache.h" 23 #include "l2_packet/l2_packet.h" 24 #include "wps/wps.h" 25 #include "config.h" 26 #include "wpa_supplicant_i.h" 27 #include "driver_i.h" 28 #include "wps_supplicant.h" 29 #include "ibss_rsn.h" 30 #include "ap.h" 31 #include "p2p_supplicant.h" 32 #include "p2p/p2p.h" 33 #include "hs20_supplicant.h" 34 #include "wifi_display.h" 35 #include "notify.h" 36 #include "bss.h" 37 #include "scan.h" 38 #include "ctrl_iface.h" 39 #include "interworking.h" 40 #include "blacklist.h" 41 #include "autoscan.h" 42 #include "wnm_sta.h" 43 44 static int wpa_supplicant_global_iface_list(struct wpa_global *global, 45 char *buf, int len); 46 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 47 char *buf, int len); 48 49 50 static int pno_start(struct wpa_supplicant *wpa_s) 51 { 52 int ret, interval; 53 size_t i, num_ssid; 54 struct wpa_ssid *ssid; 55 struct wpa_driver_scan_params params; 56 57 if (wpa_s->pno || wpa_s->pno_sched_pending) 58 return 0; 59 60 if ((wpa_s->wpa_state > WPA_SCANNING) && 61 (wpa_s->wpa_state <= WPA_COMPLETED)) { 62 wpa_printf(MSG_ERROR, "PNO: In assoc process"); 63 return -EAGAIN; 64 } 65 66 if (wpa_s->wpa_state == WPA_SCANNING) { 67 wpa_supplicant_cancel_scan(wpa_s); 68 if (wpa_s->sched_scanning) { 69 wpa_printf(MSG_DEBUG, "Schedule PNO on completion of " 70 "ongoing sched scan"); 71 wpa_supplicant_cancel_sched_scan(wpa_s); 72 wpa_s->pno_sched_pending = 1; 73 return 0; 74 } 75 } 76 77 os_memset(¶ms, 0, sizeof(params)); 78 79 num_ssid = 0; 80 ssid = wpa_s->conf->ssid; 81 while (ssid) { 82 if (!wpas_network_disabled(wpa_s, ssid)) 83 num_ssid++; 84 ssid = ssid->next; 85 } 86 if (num_ssid > WPAS_MAX_SCAN_SSIDS) { 87 wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from " 88 "%u", WPAS_MAX_SCAN_SSIDS, (unsigned int) num_ssid); 89 num_ssid = WPAS_MAX_SCAN_SSIDS; 90 } 91 92 if (num_ssid == 0) { 93 wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs"); 94 return -1; 95 } 96 97 params.filter_ssids = os_malloc(sizeof(struct wpa_driver_scan_filter) * 98 num_ssid); 99 if (params.filter_ssids == NULL) 100 return -1; 101 i = 0; 102 ssid = wpa_s->conf->ssid; 103 while (ssid) { 104 if (!wpas_network_disabled(wpa_s, ssid)) { 105 params.ssids[i].ssid = ssid->ssid; 106 params.ssids[i].ssid_len = ssid->ssid_len; 107 params.num_ssids++; 108 os_memcpy(params.filter_ssids[i].ssid, ssid->ssid, 109 ssid->ssid_len); 110 params.filter_ssids[i].ssid_len = ssid->ssid_len; 111 params.num_filter_ssids++; 112 i++; 113 if (i == num_ssid) 114 break; 115 } 116 ssid = ssid->next; 117 } 118 119 if (wpa_s->conf->filter_rssi) 120 params.filter_rssi = wpa_s->conf->filter_rssi; 121 122 interval = wpa_s->conf->sched_scan_interval ? 123 wpa_s->conf->sched_scan_interval : 10; 124 125 ret = wpa_supplicant_start_sched_scan(wpa_s, ¶ms, interval); 126 os_free(params.filter_ssids); 127 if (ret == 0) 128 wpa_s->pno = 1; 129 return ret; 130 } 131 132 133 static int pno_stop(struct wpa_supplicant *wpa_s) 134 { 135 int ret = 0; 136 137 if (wpa_s->pno || wpa_s->sched_scanning) { 138 wpa_s->pno = 0; 139 ret = wpa_supplicant_stop_sched_scan(wpa_s); 140 } 141 142 wpa_s->pno_sched_pending = 0; 143 144 if (wpa_s->wpa_state == WPA_SCANNING) 145 wpa_supplicant_req_scan(wpa_s, 0, 0); 146 147 return ret; 148 } 149 150 151 static int set_bssid_filter(struct wpa_supplicant *wpa_s, char *val) 152 { 153 char *pos; 154 u8 addr[ETH_ALEN], *filter = NULL, *n; 155 size_t count = 0; 156 157 pos = val; 158 while (pos) { 159 if (*pos == '\0') 160 break; 161 if (hwaddr_aton(pos, addr)) { 162 os_free(filter); 163 return -1; 164 } 165 n = os_realloc_array(filter, count + 1, ETH_ALEN); 166 if (n == NULL) { 167 os_free(filter); 168 return -1; 169 } 170 filter = n; 171 os_memcpy(filter + count * ETH_ALEN, addr, ETH_ALEN); 172 count++; 173 174 pos = os_strchr(pos, ' '); 175 if (pos) 176 pos++; 177 } 178 179 wpa_hexdump(MSG_DEBUG, "bssid_filter", filter, count * ETH_ALEN); 180 os_free(wpa_s->bssid_filter); 181 wpa_s->bssid_filter = filter; 182 wpa_s->bssid_filter_count = count; 183 184 return 0; 185 } 186 187 188 static int set_disallow_aps(struct wpa_supplicant *wpa_s, char *val) 189 { 190 char *pos; 191 u8 addr[ETH_ALEN], *bssid = NULL, *n; 192 struct wpa_ssid_value *ssid = NULL, *ns; 193 size_t count = 0, ssid_count = 0; 194 struct wpa_ssid *c; 195 196 /* 197 * disallow_list ::= <ssid_spec> | <bssid_spec> | <disallow_list> | "" 198 * SSID_SPEC ::= ssid <SSID_HEX> 199 * BSSID_SPEC ::= bssid <BSSID_HEX> 200 */ 201 202 pos = val; 203 while (pos) { 204 if (*pos == '\0') 205 break; 206 if (os_strncmp(pos, "bssid ", 6) == 0) { 207 int res; 208 pos += 6; 209 res = hwaddr_aton2(pos, addr); 210 if (res < 0) { 211 os_free(ssid); 212 os_free(bssid); 213 wpa_printf(MSG_DEBUG, "Invalid disallow_aps " 214 "BSSID value '%s'", pos); 215 return -1; 216 } 217 pos += res; 218 n = os_realloc_array(bssid, count + 1, ETH_ALEN); 219 if (n == NULL) { 220 os_free(ssid); 221 os_free(bssid); 222 return -1; 223 } 224 bssid = n; 225 os_memcpy(bssid + count * ETH_ALEN, addr, ETH_ALEN); 226 count++; 227 } else if (os_strncmp(pos, "ssid ", 5) == 0) { 228 char *end; 229 pos += 5; 230 231 end = pos; 232 while (*end) { 233 if (*end == '\0' || *end == ' ') 234 break; 235 end++; 236 } 237 238 ns = os_realloc_array(ssid, ssid_count + 1, 239 sizeof(struct wpa_ssid_value)); 240 if (ns == NULL) { 241 os_free(ssid); 242 os_free(bssid); 243 return -1; 244 } 245 ssid = ns; 246 247 if ((end - pos) & 0x01 || end - pos > 2 * 32 || 248 hexstr2bin(pos, ssid[ssid_count].ssid, 249 (end - pos) / 2) < 0) { 250 os_free(ssid); 251 os_free(bssid); 252 wpa_printf(MSG_DEBUG, "Invalid disallow_aps " 253 "SSID value '%s'", pos); 254 return -1; 255 } 256 ssid[ssid_count].ssid_len = (end - pos) / 2; 257 wpa_hexdump_ascii(MSG_DEBUG, "disallow_aps SSID", 258 ssid[ssid_count].ssid, 259 ssid[ssid_count].ssid_len); 260 ssid_count++; 261 pos = end; 262 } else { 263 wpa_printf(MSG_DEBUG, "Unexpected disallow_aps value " 264 "'%s'", pos); 265 os_free(ssid); 266 os_free(bssid); 267 return -1; 268 } 269 270 pos = os_strchr(pos, ' '); 271 if (pos) 272 pos++; 273 } 274 275 wpa_hexdump(MSG_DEBUG, "disallow_aps_bssid", bssid, count * ETH_ALEN); 276 os_free(wpa_s->disallow_aps_bssid); 277 wpa_s->disallow_aps_bssid = bssid; 278 wpa_s->disallow_aps_bssid_count = count; 279 280 wpa_printf(MSG_DEBUG, "disallow_aps_ssid_count %d", (int) ssid_count); 281 os_free(wpa_s->disallow_aps_ssid); 282 wpa_s->disallow_aps_ssid = ssid; 283 wpa_s->disallow_aps_ssid_count = ssid_count; 284 285 if (!wpa_s->current_ssid || wpa_s->wpa_state < WPA_AUTHENTICATING) 286 return 0; 287 288 c = wpa_s->current_ssid; 289 if (c->mode != WPAS_MODE_INFRA && c->mode != WPAS_MODE_IBSS) 290 return 0; 291 292 if (!disallowed_bssid(wpa_s, wpa_s->bssid) && 293 !disallowed_ssid(wpa_s, c->ssid, c->ssid_len)) 294 return 0; 295 296 wpa_printf(MSG_DEBUG, "Disconnect and try to find another network " 297 "because current AP was marked disallowed"); 298 299 #ifdef CONFIG_SME 300 wpa_s->sme.prev_bssid_set = 0; 301 #endif /* CONFIG_SME */ 302 wpa_s->reassociate = 1; 303 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 304 wpa_supplicant_req_scan(wpa_s, 0, 0); 305 306 return 0; 307 } 308 309 310 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, 311 char *cmd) 312 { 313 char *value; 314 int ret = 0; 315 316 value = os_strchr(cmd, ' '); 317 if (value == NULL) 318 return -1; 319 *value++ = '\0'; 320 321 wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value); 322 if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) { 323 eapol_sm_configure(wpa_s->eapol, 324 atoi(value), -1, -1, -1); 325 } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) { 326 eapol_sm_configure(wpa_s->eapol, 327 -1, atoi(value), -1, -1); 328 } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) { 329 eapol_sm_configure(wpa_s->eapol, 330 -1, -1, atoi(value), -1); 331 } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) { 332 eapol_sm_configure(wpa_s->eapol, 333 -1, -1, -1, atoi(value)); 334 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) { 335 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME, 336 atoi(value))) 337 ret = -1; 338 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") == 339 0) { 340 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD, 341 atoi(value))) 342 ret = -1; 343 } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) { 344 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value))) 345 ret = -1; 346 } else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) { 347 wpa_s->wps_fragment_size = atoi(value); 348 #ifdef CONFIG_WPS_TESTING 349 } else if (os_strcasecmp(cmd, "wps_version_number") == 0) { 350 long int val; 351 val = strtol(value, NULL, 0); 352 if (val < 0 || val > 0xff) { 353 ret = -1; 354 wpa_printf(MSG_DEBUG, "WPS: Invalid " 355 "wps_version_number %ld", val); 356 } else { 357 wps_version_number = val; 358 wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS " 359 "version %u.%u", 360 (wps_version_number & 0xf0) >> 4, 361 wps_version_number & 0x0f); 362 } 363 } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) { 364 wps_testing_dummy_cred = atoi(value); 365 wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d", 366 wps_testing_dummy_cred); 367 } else if (os_strcasecmp(cmd, "wps_corrupt_pkhash") == 0) { 368 wps_corrupt_pkhash = atoi(value); 369 wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d", 370 wps_corrupt_pkhash); 371 #endif /* CONFIG_WPS_TESTING */ 372 } else if (os_strcasecmp(cmd, "ampdu") == 0) { 373 if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0) 374 ret = -1; 375 #ifdef CONFIG_TDLS 376 #ifdef CONFIG_TDLS_TESTING 377 } else if (os_strcasecmp(cmd, "tdls_testing") == 0) { 378 extern unsigned int tdls_testing; 379 tdls_testing = strtol(value, NULL, 0); 380 wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing); 381 #endif /* CONFIG_TDLS_TESTING */ 382 } else if (os_strcasecmp(cmd, "tdls_disabled") == 0) { 383 int disabled = atoi(value); 384 wpa_printf(MSG_DEBUG, "TDLS: tdls_disabled=%d", disabled); 385 if (disabled) { 386 if (wpa_drv_tdls_oper(wpa_s, TDLS_DISABLE, NULL) < 0) 387 ret = -1; 388 } else if (wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL) < 0) 389 ret = -1; 390 wpa_tdls_enable(wpa_s->wpa, !disabled); 391 #endif /* CONFIG_TDLS */ 392 } else if (os_strcasecmp(cmd, "pno") == 0) { 393 if (atoi(value)) 394 ret = pno_start(wpa_s); 395 else 396 ret = pno_stop(wpa_s); 397 } else if (os_strcasecmp(cmd, "radio_disabled") == 0) { 398 int disabled = atoi(value); 399 if (wpa_drv_radio_disable(wpa_s, disabled) < 0) 400 ret = -1; 401 else if (disabled) 402 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); 403 } else if (os_strcasecmp(cmd, "uapsd") == 0) { 404 if (os_strcmp(value, "disable") == 0) 405 wpa_s->set_sta_uapsd = 0; 406 else { 407 int be, bk, vi, vo; 408 char *pos; 409 /* format: BE,BK,VI,VO;max SP Length */ 410 be = atoi(value); 411 pos = os_strchr(value, ','); 412 if (pos == NULL) 413 return -1; 414 pos++; 415 bk = atoi(pos); 416 pos = os_strchr(pos, ','); 417 if (pos == NULL) 418 return -1; 419 pos++; 420 vi = atoi(pos); 421 pos = os_strchr(pos, ','); 422 if (pos == NULL) 423 return -1; 424 pos++; 425 vo = atoi(pos); 426 /* ignore max SP Length for now */ 427 428 wpa_s->set_sta_uapsd = 1; 429 wpa_s->sta_uapsd = 0; 430 if (be) 431 wpa_s->sta_uapsd |= BIT(0); 432 if (bk) 433 wpa_s->sta_uapsd |= BIT(1); 434 if (vi) 435 wpa_s->sta_uapsd |= BIT(2); 436 if (vo) 437 wpa_s->sta_uapsd |= BIT(3); 438 } 439 } else if (os_strcasecmp(cmd, "ps") == 0) { 440 ret = wpa_drv_set_p2p_powersave(wpa_s, atoi(value), -1, -1); 441 #ifdef CONFIG_WIFI_DISPLAY 442 } else if (os_strcasecmp(cmd, "wifi_display") == 0) { 443 wifi_display_enable(wpa_s->global, !!atoi(value)); 444 #endif /* CONFIG_WIFI_DISPLAY */ 445 } else if (os_strcasecmp(cmd, "bssid_filter") == 0) { 446 ret = set_bssid_filter(wpa_s, value); 447 } else if (os_strcasecmp(cmd, "disallow_aps") == 0) { 448 ret = set_disallow_aps(wpa_s, value); 449 } else if (os_strcasecmp(cmd, "no_keep_alive") == 0) { 450 wpa_s->no_keep_alive = !!atoi(value); 451 } else { 452 value[-1] = '='; 453 ret = wpa_config_process_global(wpa_s->conf, cmd, -1); 454 if (ret == 0) 455 wpa_supplicant_update_config(wpa_s); 456 } 457 458 return ret; 459 } 460 461 462 static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s, 463 char *cmd, char *buf, size_t buflen) 464 { 465 int res = -1; 466 467 wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd); 468 469 if (os_strcmp(cmd, "version") == 0) { 470 res = os_snprintf(buf, buflen, "%s", VERSION_STR); 471 } else if (os_strcasecmp(cmd, "country") == 0) { 472 if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) 473 res = os_snprintf(buf, buflen, "%c%c", 474 wpa_s->conf->country[0], 475 wpa_s->conf->country[1]); 476 #ifdef CONFIG_WIFI_DISPLAY 477 } else if (os_strcasecmp(cmd, "wifi_display") == 0) { 478 res = os_snprintf(buf, buflen, "%d", 479 wpa_s->global->wifi_display); 480 if (res < 0 || (unsigned int) res >= buflen) 481 return -1; 482 return res; 483 #endif /* CONFIG_WIFI_DISPLAY */ 484 #ifdef CONFIG_TESTING_GET_GTK 485 } else if (os_strcmp(cmd, "gtk") == 0) { 486 if (wpa_s->last_gtk_len == 0) 487 return -1; 488 res = wpa_snprintf_hex(buf, buflen, wpa_s->last_gtk, 489 wpa_s->last_gtk_len); 490 return res; 491 #endif /* CONFIG_TESTING_GET_GTK */ 492 } 493 494 if (res < 0 || (unsigned int) res >= buflen) 495 return -1; 496 return res; 497 } 498 499 500 #ifdef IEEE8021X_EAPOL 501 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s, 502 char *addr) 503 { 504 u8 bssid[ETH_ALEN]; 505 struct wpa_ssid *ssid = wpa_s->current_ssid; 506 507 if (hwaddr_aton(addr, bssid)) { 508 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address " 509 "'%s'", addr); 510 return -1; 511 } 512 513 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid)); 514 rsn_preauth_deinit(wpa_s->wpa); 515 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL)) 516 return -1; 517 518 return 0; 519 } 520 #endif /* IEEE8021X_EAPOL */ 521 522 523 #ifdef CONFIG_PEERKEY 524 /* MLME-STKSTART.request(peer) */ 525 static int wpa_supplicant_ctrl_iface_stkstart( 526 struct wpa_supplicant *wpa_s, char *addr) 527 { 528 u8 peer[ETH_ALEN]; 529 530 if (hwaddr_aton(addr, peer)) { 531 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid " 532 "address '%s'", addr); 533 return -1; 534 } 535 536 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR, 537 MAC2STR(peer)); 538 539 return wpa_sm_stkstart(wpa_s->wpa, peer); 540 } 541 #endif /* CONFIG_PEERKEY */ 542 543 544 #ifdef CONFIG_TDLS 545 546 static int wpa_supplicant_ctrl_iface_tdls_discover( 547 struct wpa_supplicant *wpa_s, char *addr) 548 { 549 u8 peer[ETH_ALEN]; 550 int ret; 551 552 if (hwaddr_aton(addr, peer)) { 553 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid " 554 "address '%s'", addr); 555 return -1; 556 } 557 558 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR, 559 MAC2STR(peer)); 560 561 if (wpa_tdls_is_external_setup(wpa_s->wpa)) 562 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer); 563 else 564 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer); 565 566 return ret; 567 } 568 569 570 static int wpa_supplicant_ctrl_iface_tdls_setup( 571 struct wpa_supplicant *wpa_s, char *addr) 572 { 573 u8 peer[ETH_ALEN]; 574 int ret; 575 576 if (hwaddr_aton(addr, peer)) { 577 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP: invalid " 578 "address '%s'", addr); 579 return -1; 580 } 581 582 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP " MACSTR, 583 MAC2STR(peer)); 584 585 if ((wpa_s->conf->tdls_external_control) && 586 wpa_tdls_is_external_setup(wpa_s->wpa)) 587 return wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer); 588 589 wpa_tdls_remove(wpa_s->wpa, peer); 590 591 if (wpa_tdls_is_external_setup(wpa_s->wpa)) 592 ret = wpa_tdls_start(wpa_s->wpa, peer); 593 else 594 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer); 595 596 return ret; 597 } 598 599 600 static int wpa_supplicant_ctrl_iface_tdls_teardown( 601 struct wpa_supplicant *wpa_s, char *addr) 602 { 603 u8 peer[ETH_ALEN]; 604 int ret; 605 606 if (hwaddr_aton(addr, peer)) { 607 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid " 608 "address '%s'", addr); 609 return -1; 610 } 611 612 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR, 613 MAC2STR(peer)); 614 615 if ((wpa_s->conf->tdls_external_control) && 616 wpa_tdls_is_external_setup(wpa_s->wpa)) 617 return wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer); 618 619 if (wpa_tdls_is_external_setup(wpa_s->wpa)) 620 ret = wpa_tdls_teardown_link( 621 wpa_s->wpa, peer, 622 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED); 623 else 624 ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer); 625 626 return ret; 627 } 628 629 #endif /* CONFIG_TDLS */ 630 631 632 #ifdef CONFIG_IEEE80211R 633 static int wpa_supplicant_ctrl_iface_ft_ds( 634 struct wpa_supplicant *wpa_s, char *addr) 635 { 636 u8 target_ap[ETH_ALEN]; 637 struct wpa_bss *bss; 638 const u8 *mdie; 639 640 if (hwaddr_aton(addr, target_ap)) { 641 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid " 642 "address '%s'", addr); 643 return -1; 644 } 645 646 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap)); 647 648 bss = wpa_bss_get_bssid(wpa_s, target_ap); 649 if (bss) 650 mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); 651 else 652 mdie = NULL; 653 654 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie); 655 } 656 #endif /* CONFIG_IEEE80211R */ 657 658 659 #ifdef CONFIG_WPS 660 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s, 661 char *cmd) 662 { 663 u8 bssid[ETH_ALEN], *_bssid = bssid; 664 #ifdef CONFIG_P2P 665 u8 p2p_dev_addr[ETH_ALEN]; 666 #endif /* CONFIG_P2P */ 667 #ifdef CONFIG_AP 668 u8 *_p2p_dev_addr = NULL; 669 #endif /* CONFIG_AP */ 670 671 if (cmd == NULL || os_strcmp(cmd, "any") == 0) { 672 _bssid = NULL; 673 #ifdef CONFIG_P2P 674 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) { 675 if (hwaddr_aton(cmd + 13, p2p_dev_addr)) { 676 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid " 677 "P2P Device Address '%s'", 678 cmd + 13); 679 return -1; 680 } 681 _p2p_dev_addr = p2p_dev_addr; 682 #endif /* CONFIG_P2P */ 683 } else if (hwaddr_aton(cmd, bssid)) { 684 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'", 685 cmd); 686 return -1; 687 } 688 689 #ifdef CONFIG_AP 690 if (wpa_s->ap_iface) 691 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr); 692 #endif /* CONFIG_AP */ 693 694 return wpas_wps_start_pbc(wpa_s, _bssid, 0); 695 } 696 697 698 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, 699 char *cmd, char *buf, 700 size_t buflen) 701 { 702 u8 bssid[ETH_ALEN], *_bssid = bssid; 703 char *pin; 704 int ret; 705 706 pin = os_strchr(cmd, ' '); 707 if (pin) 708 *pin++ = '\0'; 709 710 if (os_strcmp(cmd, "any") == 0) 711 _bssid = NULL; 712 else if (os_strcmp(cmd, "get") == 0) { 713 ret = wps_generate_pin(); 714 goto done; 715 } else if (hwaddr_aton(cmd, bssid)) { 716 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'", 717 cmd); 718 return -1; 719 } 720 721 #ifdef CONFIG_AP 722 if (wpa_s->ap_iface) { 723 int timeout = 0; 724 char *pos; 725 726 if (pin) { 727 pos = os_strchr(pin, ' '); 728 if (pos) { 729 *pos++ = '\0'; 730 timeout = atoi(pos); 731 } 732 } 733 734 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin, 735 buf, buflen, timeout); 736 } 737 #endif /* CONFIG_AP */ 738 739 if (pin) { 740 ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0, 741 DEV_PW_DEFAULT); 742 if (ret < 0) 743 return -1; 744 ret = os_snprintf(buf, buflen, "%s", pin); 745 if (ret < 0 || (size_t) ret >= buflen) 746 return -1; 747 return ret; 748 } 749 750 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT); 751 if (ret < 0) 752 return -1; 753 754 done: 755 /* Return the generated PIN */ 756 ret = os_snprintf(buf, buflen, "%08d", ret); 757 if (ret < 0 || (size_t) ret >= buflen) 758 return -1; 759 return ret; 760 } 761 762 763 static int wpa_supplicant_ctrl_iface_wps_check_pin( 764 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 765 { 766 char pin[9]; 767 size_t len; 768 char *pos; 769 int ret; 770 771 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN", 772 (u8 *) cmd, os_strlen(cmd)); 773 for (pos = cmd, len = 0; *pos != '\0'; pos++) { 774 if (*pos < '0' || *pos > '9') 775 continue; 776 pin[len++] = *pos; 777 if (len == 9) { 778 wpa_printf(MSG_DEBUG, "WPS: Too long PIN"); 779 return -1; 780 } 781 } 782 if (len != 4 && len != 8) { 783 wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len); 784 return -1; 785 } 786 pin[len] = '\0'; 787 788 if (len == 8) { 789 unsigned int pin_val; 790 pin_val = atoi(pin); 791 if (!wps_pin_valid(pin_val)) { 792 wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit"); 793 ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n"); 794 if (ret < 0 || (size_t) ret >= buflen) 795 return -1; 796 return ret; 797 } 798 } 799 800 ret = os_snprintf(buf, buflen, "%s", pin); 801 if (ret < 0 || (size_t) ret >= buflen) 802 return -1; 803 804 return ret; 805 } 806 807 808 #ifdef CONFIG_WPS_NFC 809 810 static int wpa_supplicant_ctrl_iface_wps_nfc(struct wpa_supplicant *wpa_s, 811 char *cmd) 812 { 813 u8 bssid[ETH_ALEN], *_bssid = bssid; 814 815 if (cmd == NULL || cmd[0] == '\0') 816 _bssid = NULL; 817 else if (hwaddr_aton(cmd, bssid)) 818 return -1; 819 820 return wpas_wps_start_nfc(wpa_s, NULL, _bssid, NULL, 0, 0, NULL, NULL, 821 0, 0); 822 } 823 824 825 static int wpa_supplicant_ctrl_iface_wps_nfc_config_token( 826 struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len) 827 { 828 int ndef; 829 struct wpabuf *buf; 830 int res; 831 char *pos; 832 833 pos = os_strchr(cmd, ' '); 834 if (pos) 835 *pos++ = '\0'; 836 if (os_strcmp(cmd, "WPS") == 0) 837 ndef = 0; 838 else if (os_strcmp(cmd, "NDEF") == 0) 839 ndef = 1; 840 else 841 return -1; 842 843 buf = wpas_wps_nfc_config_token(wpa_s, ndef, pos); 844 if (buf == NULL) 845 return -1; 846 847 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 848 wpabuf_len(buf)); 849 reply[res++] = '\n'; 850 reply[res] = '\0'; 851 852 wpabuf_free(buf); 853 854 return res; 855 } 856 857 858 static int wpa_supplicant_ctrl_iface_wps_nfc_token( 859 struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len) 860 { 861 int ndef; 862 struct wpabuf *buf; 863 int res; 864 865 if (os_strcmp(cmd, "WPS") == 0) 866 ndef = 0; 867 else if (os_strcmp(cmd, "NDEF") == 0) 868 ndef = 1; 869 else 870 return -1; 871 872 buf = wpas_wps_nfc_token(wpa_s, ndef); 873 if (buf == NULL) 874 return -1; 875 876 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 877 wpabuf_len(buf)); 878 reply[res++] = '\n'; 879 reply[res] = '\0'; 880 881 wpabuf_free(buf); 882 883 return res; 884 } 885 886 887 static int wpa_supplicant_ctrl_iface_wps_nfc_tag_read( 888 struct wpa_supplicant *wpa_s, char *pos) 889 { 890 size_t len; 891 struct wpabuf *buf; 892 int ret; 893 char *freq; 894 int forced_freq = 0; 895 896 freq = strstr(pos, " freq="); 897 if (freq) { 898 *freq = '\0'; 899 freq += 6; 900 forced_freq = atoi(freq); 901 } 902 903 len = os_strlen(pos); 904 if (len & 0x01) 905 return -1; 906 len /= 2; 907 908 buf = wpabuf_alloc(len); 909 if (buf == NULL) 910 return -1; 911 if (hexstr2bin(pos, wpabuf_put(buf, len), len) < 0) { 912 wpabuf_free(buf); 913 return -1; 914 } 915 916 ret = wpas_wps_nfc_tag_read(wpa_s, buf, forced_freq); 917 wpabuf_free(buf); 918 919 return ret; 920 } 921 922 923 static int wpas_ctrl_nfc_get_handover_req_wps(struct wpa_supplicant *wpa_s, 924 char *reply, size_t max_len, 925 int ndef) 926 { 927 struct wpabuf *buf; 928 int res; 929 930 buf = wpas_wps_nfc_handover_req(wpa_s, ndef); 931 if (buf == NULL) 932 return -1; 933 934 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 935 wpabuf_len(buf)); 936 reply[res++] = '\n'; 937 reply[res] = '\0'; 938 939 wpabuf_free(buf); 940 941 return res; 942 } 943 944 945 static int wpas_ctrl_nfc_get_handover_req_p2p(struct wpa_supplicant *wpa_s, 946 char *reply, size_t max_len, 947 int ndef) 948 { 949 struct wpabuf *buf; 950 int res; 951 952 buf = wpas_p2p_nfc_handover_req(wpa_s, ndef); 953 if (buf == NULL) { 954 wpa_printf(MSG_DEBUG, "P2P: Could not generate NFC handover request"); 955 return -1; 956 } 957 958 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 959 wpabuf_len(buf)); 960 reply[res++] = '\n'; 961 reply[res] = '\0'; 962 963 wpabuf_free(buf); 964 965 return res; 966 } 967 968 969 static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s, 970 char *cmd, char *reply, 971 size_t max_len) 972 { 973 char *pos; 974 int ndef; 975 976 pos = os_strchr(cmd, ' '); 977 if (pos == NULL) 978 return -1; 979 *pos++ = '\0'; 980 981 if (os_strcmp(cmd, "WPS") == 0) 982 ndef = 0; 983 else if (os_strcmp(cmd, "NDEF") == 0) 984 ndef = 1; 985 else 986 return -1; 987 988 if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) { 989 if (!ndef) 990 return -1; 991 return wpas_ctrl_nfc_get_handover_req_wps( 992 wpa_s, reply, max_len, ndef); 993 } 994 995 if (os_strcmp(pos, "P2P-CR") == 0) { 996 return wpas_ctrl_nfc_get_handover_req_p2p( 997 wpa_s, reply, max_len, ndef); 998 } 999 1000 return -1; 1001 } 1002 1003 1004 static int wpas_ctrl_nfc_get_handover_sel_wps(struct wpa_supplicant *wpa_s, 1005 char *reply, size_t max_len, 1006 int ndef, int cr, char *uuid) 1007 { 1008 struct wpabuf *buf; 1009 int res; 1010 1011 buf = wpas_wps_nfc_handover_sel(wpa_s, ndef, cr, uuid); 1012 if (buf == NULL) 1013 return -1; 1014 1015 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 1016 wpabuf_len(buf)); 1017 reply[res++] = '\n'; 1018 reply[res] = '\0'; 1019 1020 wpabuf_free(buf); 1021 1022 return res; 1023 } 1024 1025 1026 static int wpas_ctrl_nfc_get_handover_sel_p2p(struct wpa_supplicant *wpa_s, 1027 char *reply, size_t max_len, 1028 int ndef, int tag) 1029 { 1030 struct wpabuf *buf; 1031 int res; 1032 1033 buf = wpas_p2p_nfc_handover_sel(wpa_s, ndef, tag); 1034 if (buf == NULL) 1035 return -1; 1036 1037 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 1038 wpabuf_len(buf)); 1039 reply[res++] = '\n'; 1040 reply[res] = '\0'; 1041 1042 wpabuf_free(buf); 1043 1044 return res; 1045 } 1046 1047 1048 static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s, 1049 char *cmd, char *reply, 1050 size_t max_len) 1051 { 1052 char *pos, *pos2; 1053 int ndef; 1054 1055 pos = os_strchr(cmd, ' '); 1056 if (pos == NULL) 1057 return -1; 1058 *pos++ = '\0'; 1059 1060 if (os_strcmp(cmd, "WPS") == 0) 1061 ndef = 0; 1062 else if (os_strcmp(cmd, "NDEF") == 0) 1063 ndef = 1; 1064 else 1065 return -1; 1066 1067 pos2 = os_strchr(pos, ' '); 1068 if (pos2) 1069 *pos2++ = '\0'; 1070 if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) { 1071 if (!ndef) 1072 return -1; 1073 return wpas_ctrl_nfc_get_handover_sel_wps( 1074 wpa_s, reply, max_len, ndef, 1075 os_strcmp(pos, "WPS-CR") == 0, pos2); 1076 } 1077 1078 if (os_strcmp(pos, "P2P-CR") == 0) { 1079 return wpas_ctrl_nfc_get_handover_sel_p2p( 1080 wpa_s, reply, max_len, ndef, 0); 1081 } 1082 1083 if (os_strcmp(pos, "P2P-CR-TAG") == 0) { 1084 return wpas_ctrl_nfc_get_handover_sel_p2p( 1085 wpa_s, reply, max_len, ndef, 1); 1086 } 1087 1088 return -1; 1089 } 1090 1091 1092 static int wpas_ctrl_nfc_rx_handover_req(struct wpa_supplicant *wpa_s, 1093 char *cmd, char *reply, 1094 size_t max_len) 1095 { 1096 size_t len; 1097 struct wpabuf *buf; 1098 int ret; 1099 1100 len = os_strlen(cmd); 1101 if (len & 0x01) 1102 return -1; 1103 len /= 2; 1104 1105 buf = wpabuf_alloc(len); 1106 if (buf == NULL) 1107 return -1; 1108 if (hexstr2bin(cmd, wpabuf_put(buf, len), len) < 0) { 1109 wpabuf_free(buf); 1110 return -1; 1111 } 1112 1113 ret = wpas_wps_nfc_rx_handover_req(wpa_s, buf); 1114 wpabuf_free(buf); 1115 1116 return ret; 1117 } 1118 1119 1120 static int wpas_ctrl_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s, 1121 char *cmd) 1122 { 1123 size_t len; 1124 struct wpabuf *buf; 1125 int ret; 1126 1127 len = os_strlen(cmd); 1128 if (len & 0x01) 1129 return -1; 1130 len /= 2; 1131 1132 buf = wpabuf_alloc(len); 1133 if (buf == NULL) 1134 return -1; 1135 if (hexstr2bin(cmd, wpabuf_put(buf, len), len) < 0) { 1136 wpabuf_free(buf); 1137 return -1; 1138 } 1139 1140 ret = wpas_wps_nfc_rx_handover_sel(wpa_s, buf); 1141 wpabuf_free(buf); 1142 1143 return ret; 1144 } 1145 1146 1147 static int wpas_ctrl_nfc_report_handover(struct wpa_supplicant *wpa_s, 1148 char *cmd) 1149 { 1150 size_t len; 1151 struct wpabuf *req, *sel; 1152 int ret; 1153 char *pos, *role, *type, *pos2; 1154 char *freq; 1155 int forced_freq = 0; 1156 1157 freq = strstr(cmd, " freq="); 1158 if (freq) { 1159 *freq = '\0'; 1160 freq += 6; 1161 forced_freq = atoi(freq); 1162 } 1163 1164 role = cmd; 1165 pos = os_strchr(role, ' '); 1166 if (pos == NULL) { 1167 wpa_printf(MSG_DEBUG, "NFC: Missing type in handover report"); 1168 return -1; 1169 } 1170 *pos++ = '\0'; 1171 1172 type = pos; 1173 pos = os_strchr(type, ' '); 1174 if (pos == NULL) { 1175 wpa_printf(MSG_DEBUG, "NFC: Missing request message in handover report"); 1176 return -1; 1177 } 1178 *pos++ = '\0'; 1179 1180 pos2 = os_strchr(pos, ' '); 1181 if (pos2 == NULL) { 1182 wpa_printf(MSG_DEBUG, "NFC: Missing select message in handover report"); 1183 return -1; 1184 } 1185 *pos2++ = '\0'; 1186 1187 len = os_strlen(pos); 1188 if (len & 0x01) { 1189 wpa_printf(MSG_DEBUG, "NFC: Invalid request message length in handover report"); 1190 return -1; 1191 } 1192 len /= 2; 1193 1194 req = wpabuf_alloc(len); 1195 if (req == NULL) { 1196 wpa_printf(MSG_DEBUG, "NFC: Failed to allocate memory for request message"); 1197 return -1; 1198 } 1199 if (hexstr2bin(pos, wpabuf_put(req, len), len) < 0) { 1200 wpa_printf(MSG_DEBUG, "NFC: Invalid request message hexdump in handover report"); 1201 wpabuf_free(req); 1202 return -1; 1203 } 1204 1205 len = os_strlen(pos2); 1206 if (len & 0x01) { 1207 wpa_printf(MSG_DEBUG, "NFC: Invalid select message length in handover report"); 1208 wpabuf_free(req); 1209 return -1; 1210 } 1211 len /= 2; 1212 1213 sel = wpabuf_alloc(len); 1214 if (sel == NULL) { 1215 wpa_printf(MSG_DEBUG, "NFC: Failed to allocate memory for select message"); 1216 wpabuf_free(req); 1217 return -1; 1218 } 1219 if (hexstr2bin(pos2, wpabuf_put(sel, len), len) < 0) { 1220 wpa_printf(MSG_DEBUG, "NFC: Invalid select message hexdump in handover report"); 1221 wpabuf_free(req); 1222 wpabuf_free(sel); 1223 return -1; 1224 } 1225 1226 wpa_printf(MSG_DEBUG, "NFC: Connection handover reported - role=%s type=%s req_len=%d sel_len=%d", 1227 role, type, (int) wpabuf_len(req), (int) wpabuf_len(sel)); 1228 1229 if (os_strcmp(role, "INIT") == 0 && os_strcmp(type, "WPS") == 0) { 1230 ret = wpas_wps_nfc_report_handover(wpa_s, req, sel); 1231 } else if (os_strcmp(role, "RESP") == 0 && os_strcmp(type, "WPS") == 0) 1232 { 1233 ret = wpas_ap_wps_nfc_report_handover(wpa_s, req, sel); 1234 if (ret < 0) 1235 ret = wpas_er_wps_nfc_report_handover(wpa_s, req, sel); 1236 } else if (os_strcmp(role, "INIT") == 0 && os_strcmp(type, "P2P") == 0) 1237 { 1238 ret = wpas_p2p_nfc_report_handover(wpa_s, 1, req, sel, 0); 1239 } else if (os_strcmp(role, "RESP") == 0 && os_strcmp(type, "P2P") == 0) 1240 { 1241 ret = wpas_p2p_nfc_report_handover(wpa_s, 0, req, sel, 1242 forced_freq); 1243 } else { 1244 wpa_printf(MSG_DEBUG, "NFC: Unsupported connection handover " 1245 "reported: role=%s type=%s", role, type); 1246 ret = -1; 1247 } 1248 wpabuf_free(req); 1249 wpabuf_free(sel); 1250 1251 if (ret) 1252 wpa_printf(MSG_DEBUG, "NFC: Failed to process reported handover messages"); 1253 1254 return ret; 1255 } 1256 1257 #endif /* CONFIG_WPS_NFC */ 1258 1259 1260 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s, 1261 char *cmd) 1262 { 1263 u8 bssid[ETH_ALEN]; 1264 char *pin; 1265 char *new_ssid; 1266 char *new_auth; 1267 char *new_encr; 1268 char *new_key; 1269 struct wps_new_ap_settings ap; 1270 1271 pin = os_strchr(cmd, ' '); 1272 if (pin == NULL) 1273 return -1; 1274 *pin++ = '\0'; 1275 1276 if (hwaddr_aton(cmd, bssid)) { 1277 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'", 1278 cmd); 1279 return -1; 1280 } 1281 1282 new_ssid = os_strchr(pin, ' '); 1283 if (new_ssid == NULL) 1284 return wpas_wps_start_reg(wpa_s, bssid, pin, NULL); 1285 *new_ssid++ = '\0'; 1286 1287 new_auth = os_strchr(new_ssid, ' '); 1288 if (new_auth == NULL) 1289 return -1; 1290 *new_auth++ = '\0'; 1291 1292 new_encr = os_strchr(new_auth, ' '); 1293 if (new_encr == NULL) 1294 return -1; 1295 *new_encr++ = '\0'; 1296 1297 new_key = os_strchr(new_encr, ' '); 1298 if (new_key == NULL) 1299 return -1; 1300 *new_key++ = '\0'; 1301 1302 os_memset(&ap, 0, sizeof(ap)); 1303 ap.ssid_hex = new_ssid; 1304 ap.auth = new_auth; 1305 ap.encr = new_encr; 1306 ap.key_hex = new_key; 1307 return wpas_wps_start_reg(wpa_s, bssid, pin, &ap); 1308 } 1309 1310 1311 #ifdef CONFIG_AP 1312 static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant *wpa_s, 1313 char *cmd, char *buf, 1314 size_t buflen) 1315 { 1316 int timeout = 300; 1317 char *pos; 1318 const char *pin_txt; 1319 1320 if (!wpa_s->ap_iface) 1321 return -1; 1322 1323 pos = os_strchr(cmd, ' '); 1324 if (pos) 1325 *pos++ = '\0'; 1326 1327 if (os_strcmp(cmd, "disable") == 0) { 1328 wpas_wps_ap_pin_disable(wpa_s); 1329 return os_snprintf(buf, buflen, "OK\n"); 1330 } 1331 1332 if (os_strcmp(cmd, "random") == 0) { 1333 if (pos) 1334 timeout = atoi(pos); 1335 pin_txt = wpas_wps_ap_pin_random(wpa_s, timeout); 1336 if (pin_txt == NULL) 1337 return -1; 1338 return os_snprintf(buf, buflen, "%s", pin_txt); 1339 } 1340 1341 if (os_strcmp(cmd, "get") == 0) { 1342 pin_txt = wpas_wps_ap_pin_get(wpa_s); 1343 if (pin_txt == NULL) 1344 return -1; 1345 return os_snprintf(buf, buflen, "%s", pin_txt); 1346 } 1347 1348 if (os_strcmp(cmd, "set") == 0) { 1349 char *pin; 1350 if (pos == NULL) 1351 return -1; 1352 pin = pos; 1353 pos = os_strchr(pos, ' '); 1354 if (pos) { 1355 *pos++ = '\0'; 1356 timeout = atoi(pos); 1357 } 1358 if (os_strlen(pin) > buflen) 1359 return -1; 1360 if (wpas_wps_ap_pin_set(wpa_s, pin, timeout) < 0) 1361 return -1; 1362 return os_snprintf(buf, buflen, "%s", pin); 1363 } 1364 1365 return -1; 1366 } 1367 #endif /* CONFIG_AP */ 1368 1369 1370 #ifdef CONFIG_WPS_ER 1371 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s, 1372 char *cmd) 1373 { 1374 char *uuid = cmd, *pin, *pos; 1375 u8 addr_buf[ETH_ALEN], *addr = NULL; 1376 pin = os_strchr(uuid, ' '); 1377 if (pin == NULL) 1378 return -1; 1379 *pin++ = '\0'; 1380 pos = os_strchr(pin, ' '); 1381 if (pos) { 1382 *pos++ = '\0'; 1383 if (hwaddr_aton(pos, addr_buf) == 0) 1384 addr = addr_buf; 1385 } 1386 return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin); 1387 } 1388 1389 1390 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s, 1391 char *cmd) 1392 { 1393 char *uuid = cmd, *pin; 1394 pin = os_strchr(uuid, ' '); 1395 if (pin == NULL) 1396 return -1; 1397 *pin++ = '\0'; 1398 return wpas_wps_er_learn(wpa_s, uuid, pin); 1399 } 1400 1401 1402 static int wpa_supplicant_ctrl_iface_wps_er_set_config( 1403 struct wpa_supplicant *wpa_s, char *cmd) 1404 { 1405 char *uuid = cmd, *id; 1406 id = os_strchr(uuid, ' '); 1407 if (id == NULL) 1408 return -1; 1409 *id++ = '\0'; 1410 return wpas_wps_er_set_config(wpa_s, uuid, atoi(id)); 1411 } 1412 1413 1414 static int wpa_supplicant_ctrl_iface_wps_er_config( 1415 struct wpa_supplicant *wpa_s, char *cmd) 1416 { 1417 char *pin; 1418 char *new_ssid; 1419 char *new_auth; 1420 char *new_encr; 1421 char *new_key; 1422 struct wps_new_ap_settings ap; 1423 1424 pin = os_strchr(cmd, ' '); 1425 if (pin == NULL) 1426 return -1; 1427 *pin++ = '\0'; 1428 1429 new_ssid = os_strchr(pin, ' '); 1430 if (new_ssid == NULL) 1431 return -1; 1432 *new_ssid++ = '\0'; 1433 1434 new_auth = os_strchr(new_ssid, ' '); 1435 if (new_auth == NULL) 1436 return -1; 1437 *new_auth++ = '\0'; 1438 1439 new_encr = os_strchr(new_auth, ' '); 1440 if (new_encr == NULL) 1441 return -1; 1442 *new_encr++ = '\0'; 1443 1444 new_key = os_strchr(new_encr, ' '); 1445 if (new_key == NULL) 1446 return -1; 1447 *new_key++ = '\0'; 1448 1449 os_memset(&ap, 0, sizeof(ap)); 1450 ap.ssid_hex = new_ssid; 1451 ap.auth = new_auth; 1452 ap.encr = new_encr; 1453 ap.key_hex = new_key; 1454 return wpas_wps_er_config(wpa_s, cmd, pin, &ap); 1455 } 1456 1457 1458 #ifdef CONFIG_WPS_NFC 1459 static int wpa_supplicant_ctrl_iface_wps_er_nfc_config_token( 1460 struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len) 1461 { 1462 int ndef; 1463 struct wpabuf *buf; 1464 int res; 1465 char *uuid; 1466 1467 uuid = os_strchr(cmd, ' '); 1468 if (uuid == NULL) 1469 return -1; 1470 *uuid++ = '\0'; 1471 1472 if (os_strcmp(cmd, "WPS") == 0) 1473 ndef = 0; 1474 else if (os_strcmp(cmd, "NDEF") == 0) 1475 ndef = 1; 1476 else 1477 return -1; 1478 1479 buf = wpas_wps_er_nfc_config_token(wpa_s, ndef, uuid); 1480 if (buf == NULL) 1481 return -1; 1482 1483 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 1484 wpabuf_len(buf)); 1485 reply[res++] = '\n'; 1486 reply[res] = '\0'; 1487 1488 wpabuf_free(buf); 1489 1490 return res; 1491 } 1492 #endif /* CONFIG_WPS_NFC */ 1493 #endif /* CONFIG_WPS_ER */ 1494 1495 #endif /* CONFIG_WPS */ 1496 1497 1498 #ifdef CONFIG_IBSS_RSN 1499 static int wpa_supplicant_ctrl_iface_ibss_rsn( 1500 struct wpa_supplicant *wpa_s, char *addr) 1501 { 1502 u8 peer[ETH_ALEN]; 1503 1504 if (hwaddr_aton(addr, peer)) { 1505 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid " 1506 "address '%s'", addr); 1507 return -1; 1508 } 1509 1510 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR, 1511 MAC2STR(peer)); 1512 1513 return ibss_rsn_start(wpa_s->ibss_rsn, peer); 1514 } 1515 #endif /* CONFIG_IBSS_RSN */ 1516 1517 1518 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s, 1519 char *rsp) 1520 { 1521 #ifdef IEEE8021X_EAPOL 1522 char *pos, *id_pos; 1523 int id; 1524 struct wpa_ssid *ssid; 1525 1526 pos = os_strchr(rsp, '-'); 1527 if (pos == NULL) 1528 return -1; 1529 *pos++ = '\0'; 1530 id_pos = pos; 1531 pos = os_strchr(pos, ':'); 1532 if (pos == NULL) 1533 return -1; 1534 *pos++ = '\0'; 1535 id = atoi(id_pos); 1536 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id); 1537 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 1538 (u8 *) pos, os_strlen(pos)); 1539 1540 ssid = wpa_config_get_network(wpa_s->conf, id); 1541 if (ssid == NULL) { 1542 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 1543 "to update", id); 1544 return -1; 1545 } 1546 1547 return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid, rsp, 1548 pos); 1549 #else /* IEEE8021X_EAPOL */ 1550 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included"); 1551 return -1; 1552 #endif /* IEEE8021X_EAPOL */ 1553 } 1554 1555 1556 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, 1557 const char *params, 1558 char *buf, size_t buflen) 1559 { 1560 char *pos, *end, tmp[30]; 1561 int res, verbose, wps, ret; 1562 1563 if (os_strcmp(params, "-DRIVER") == 0) 1564 return wpa_drv_status(wpa_s, buf, buflen); 1565 verbose = os_strcmp(params, "-VERBOSE") == 0; 1566 wps = os_strcmp(params, "-WPS") == 0; 1567 pos = buf; 1568 end = buf + buflen; 1569 if (wpa_s->wpa_state >= WPA_ASSOCIATED) { 1570 struct wpa_ssid *ssid = wpa_s->current_ssid; 1571 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n", 1572 MAC2STR(wpa_s->bssid)); 1573 if (ret < 0 || ret >= end - pos) 1574 return pos - buf; 1575 pos += ret; 1576 if (ssid) { 1577 u8 *_ssid = ssid->ssid; 1578 size_t ssid_len = ssid->ssid_len; 1579 u8 ssid_buf[MAX_SSID_LEN]; 1580 if (ssid_len == 0) { 1581 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf); 1582 if (_res < 0) 1583 ssid_len = 0; 1584 else 1585 ssid_len = _res; 1586 _ssid = ssid_buf; 1587 } 1588 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n", 1589 wpa_ssid_txt(_ssid, ssid_len), 1590 ssid->id); 1591 if (ret < 0 || ret >= end - pos) 1592 return pos - buf; 1593 pos += ret; 1594 1595 if (wps && ssid->passphrase && 1596 wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && 1597 (ssid->mode == WPAS_MODE_AP || 1598 ssid->mode == WPAS_MODE_P2P_GO)) { 1599 ret = os_snprintf(pos, end - pos, 1600 "passphrase=%s\n", 1601 ssid->passphrase); 1602 if (ret < 0 || ret >= end - pos) 1603 return pos - buf; 1604 pos += ret; 1605 } 1606 if (ssid->id_str) { 1607 ret = os_snprintf(pos, end - pos, 1608 "id_str=%s\n", 1609 ssid->id_str); 1610 if (ret < 0 || ret >= end - pos) 1611 return pos - buf; 1612 pos += ret; 1613 } 1614 1615 switch (ssid->mode) { 1616 case WPAS_MODE_INFRA: 1617 ret = os_snprintf(pos, end - pos, 1618 "mode=station\n"); 1619 break; 1620 case WPAS_MODE_IBSS: 1621 ret = os_snprintf(pos, end - pos, 1622 "mode=IBSS\n"); 1623 break; 1624 case WPAS_MODE_AP: 1625 ret = os_snprintf(pos, end - pos, 1626 "mode=AP\n"); 1627 break; 1628 case WPAS_MODE_P2P_GO: 1629 ret = os_snprintf(pos, end - pos, 1630 "mode=P2P GO\n"); 1631 break; 1632 case WPAS_MODE_P2P_GROUP_FORMATION: 1633 ret = os_snprintf(pos, end - pos, 1634 "mode=P2P GO - group " 1635 "formation\n"); 1636 break; 1637 default: 1638 ret = 0; 1639 break; 1640 } 1641 if (ret < 0 || ret >= end - pos) 1642 return pos - buf; 1643 pos += ret; 1644 } 1645 1646 #ifdef CONFIG_AP 1647 if (wpa_s->ap_iface) { 1648 pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, 1649 end - pos, 1650 verbose); 1651 } else 1652 #endif /* CONFIG_AP */ 1653 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose); 1654 } 1655 #ifdef CONFIG_SAE 1656 if (wpa_s->wpa_state >= WPA_ASSOCIATED && 1657 #ifdef CONFIG_AP 1658 !wpa_s->ap_iface && 1659 #endif /* CONFIG_AP */ 1660 wpa_s->sme.sae.state == SAE_ACCEPTED) { 1661 ret = os_snprintf(pos, end - pos, "sae_group=%d\n", 1662 wpa_s->sme.sae.group); 1663 if (ret < 0 || ret >= end - pos) 1664 return pos - buf; 1665 pos += ret; 1666 } 1667 #endif /* CONFIG_SAE */ 1668 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n", 1669 wpa_supplicant_state_txt(wpa_s->wpa_state)); 1670 if (ret < 0 || ret >= end - pos) 1671 return pos - buf; 1672 pos += ret; 1673 1674 if (wpa_s->l2 && 1675 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) { 1676 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp); 1677 if (ret < 0 || ret >= end - pos) 1678 return pos - buf; 1679 pos += ret; 1680 } 1681 1682 #ifdef CONFIG_P2P 1683 if (wpa_s->global->p2p) { 1684 ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR 1685 "\n", MAC2STR(wpa_s->global->p2p_dev_addr)); 1686 if (ret < 0 || ret >= end - pos) 1687 return pos - buf; 1688 pos += ret; 1689 } 1690 #endif /* CONFIG_P2P */ 1691 1692 ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n", 1693 MAC2STR(wpa_s->own_addr)); 1694 if (ret < 0 || ret >= end - pos) 1695 return pos - buf; 1696 pos += ret; 1697 1698 #ifdef CONFIG_HS20 1699 if (wpa_s->current_bss && 1700 wpa_bss_get_vendor_ie(wpa_s->current_bss, HS20_IE_VENDOR_TYPE) && 1701 wpa_s->wpa_proto == WPA_PROTO_RSN && 1702 wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) { 1703 ret = os_snprintf(pos, end - pos, "hs20=1\n"); 1704 if (ret < 0 || ret >= end - pos) 1705 return pos - buf; 1706 pos += ret; 1707 } 1708 1709 if (wpa_s->current_ssid) { 1710 struct wpa_cred *cred; 1711 char *type; 1712 1713 for (cred = wpa_s->conf->cred; cred; cred = cred->next) { 1714 size_t i; 1715 1716 if (wpa_s->current_ssid->parent_cred != cred) 1717 continue; 1718 1719 for (i = 0; cred->domain && i < cred->num_domain; i++) { 1720 ret = os_snprintf(pos, end - pos, 1721 "home_sp=%s\n", 1722 cred->domain[i]); 1723 if (ret < 0 || ret >= end - pos) 1724 return pos - buf; 1725 pos += ret; 1726 } 1727 1728 if (wpa_s->current_bss == NULL || 1729 wpa_s->current_bss->anqp == NULL) 1730 res = -1; 1731 else 1732 res = interworking_home_sp_cred( 1733 wpa_s, cred, 1734 wpa_s->current_bss->anqp->domain_name); 1735 if (res > 0) 1736 type = "home"; 1737 else if (res == 0) 1738 type = "roaming"; 1739 else 1740 type = "unknown"; 1741 1742 ret = os_snprintf(pos, end - pos, "sp_type=%s\n", type); 1743 if (ret < 0 || ret >= end - pos) 1744 return pos - buf; 1745 pos += ret; 1746 1747 break; 1748 } 1749 } 1750 #endif /* CONFIG_HS20 */ 1751 1752 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) || 1753 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 1754 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos, 1755 verbose); 1756 if (res >= 0) 1757 pos += res; 1758 } 1759 1760 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose); 1761 if (res >= 0) 1762 pos += res; 1763 1764 #ifdef CONFIG_WPS 1765 { 1766 char uuid_str[100]; 1767 uuid_bin2str(wpa_s->wps->uuid, uuid_str, sizeof(uuid_str)); 1768 ret = os_snprintf(pos, end - pos, "uuid=%s\n", uuid_str); 1769 if (ret < 0 || ret >= end - pos) 1770 return pos - buf; 1771 pos += ret; 1772 } 1773 #endif /* CONFIG_WPS */ 1774 1775 #ifdef ANDROID 1776 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_STATE_CHANGE 1777 "id=%d state=%d BSSID=" MACSTR " SSID=%s", 1778 wpa_s->current_ssid ? wpa_s->current_ssid->id : -1, 1779 wpa_s->wpa_state, 1780 MAC2STR(wpa_s->bssid), 1781 wpa_s->current_ssid && wpa_s->current_ssid->ssid ? 1782 wpa_ssid_txt(wpa_s->current_ssid->ssid, 1783 wpa_s->current_ssid->ssid_len) : ""); 1784 if (wpa_s->wpa_state == WPA_COMPLETED) { 1785 struct wpa_ssid *ssid = wpa_s->current_ssid; 1786 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED 1787 "- connection to " MACSTR 1788 " completed %s [id=%d id_str=%s]", 1789 MAC2STR(wpa_s->bssid), "(auth)", 1790 ssid ? ssid->id : -1, 1791 ssid && ssid->id_str ? ssid->id_str : ""); 1792 } 1793 #endif /* ANDROID */ 1794 1795 return pos - buf; 1796 } 1797 1798 1799 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s, 1800 char *cmd) 1801 { 1802 char *pos; 1803 int id; 1804 struct wpa_ssid *ssid; 1805 u8 bssid[ETH_ALEN]; 1806 1807 /* cmd: "<network id> <BSSID>" */ 1808 pos = os_strchr(cmd, ' '); 1809 if (pos == NULL) 1810 return -1; 1811 *pos++ = '\0'; 1812 id = atoi(cmd); 1813 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos); 1814 if (hwaddr_aton(pos, bssid)) { 1815 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos); 1816 return -1; 1817 } 1818 1819 ssid = wpa_config_get_network(wpa_s->conf, id); 1820 if (ssid == NULL) { 1821 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 1822 "to update", id); 1823 return -1; 1824 } 1825 1826 os_memcpy(ssid->bssid, bssid, ETH_ALEN); 1827 ssid->bssid_set = !is_zero_ether_addr(bssid); 1828 1829 return 0; 1830 } 1831 1832 1833 static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s, 1834 char *cmd, char *buf, 1835 size_t buflen) 1836 { 1837 u8 bssid[ETH_ALEN]; 1838 struct wpa_blacklist *e; 1839 char *pos, *end; 1840 int ret; 1841 1842 /* cmd: "BLACKLIST [<BSSID>]" */ 1843 if (*cmd == '\0') { 1844 pos = buf; 1845 end = buf + buflen; 1846 e = wpa_s->blacklist; 1847 while (e) { 1848 ret = os_snprintf(pos, end - pos, MACSTR "\n", 1849 MAC2STR(e->bssid)); 1850 if (ret < 0 || ret >= end - pos) 1851 return pos - buf; 1852 pos += ret; 1853 e = e->next; 1854 } 1855 return pos - buf; 1856 } 1857 1858 cmd++; 1859 if (os_strncmp(cmd, "clear", 5) == 0) { 1860 wpa_blacklist_clear(wpa_s); 1861 os_memcpy(buf, "OK\n", 3); 1862 return 3; 1863 } 1864 1865 wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd); 1866 if (hwaddr_aton(cmd, bssid)) { 1867 wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd); 1868 return -1; 1869 } 1870 1871 /* 1872 * Add the BSSID twice, so its count will be 2, causing it to be 1873 * skipped when processing scan results. 1874 */ 1875 ret = wpa_blacklist_add(wpa_s, bssid); 1876 if (ret != 0) 1877 return -1; 1878 ret = wpa_blacklist_add(wpa_s, bssid); 1879 if (ret != 0) 1880 return -1; 1881 os_memcpy(buf, "OK\n", 3); 1882 return 3; 1883 } 1884 1885 1886 static const char * debug_level_str(int level) 1887 { 1888 switch (level) { 1889 case MSG_EXCESSIVE: 1890 return "EXCESSIVE"; 1891 case MSG_MSGDUMP: 1892 return "MSGDUMP"; 1893 case MSG_DEBUG: 1894 return "DEBUG"; 1895 case MSG_INFO: 1896 return "INFO"; 1897 case MSG_WARNING: 1898 return "WARNING"; 1899 case MSG_ERROR: 1900 return "ERROR"; 1901 default: 1902 return "?"; 1903 } 1904 } 1905 1906 1907 static int str_to_debug_level(const char *s) 1908 { 1909 if (os_strcasecmp(s, "EXCESSIVE") == 0) 1910 return MSG_EXCESSIVE; 1911 if (os_strcasecmp(s, "MSGDUMP") == 0) 1912 return MSG_MSGDUMP; 1913 if (os_strcasecmp(s, "DEBUG") == 0) 1914 return MSG_DEBUG; 1915 if (os_strcasecmp(s, "INFO") == 0) 1916 return MSG_INFO; 1917 if (os_strcasecmp(s, "WARNING") == 0) 1918 return MSG_WARNING; 1919 if (os_strcasecmp(s, "ERROR") == 0) 1920 return MSG_ERROR; 1921 return -1; 1922 } 1923 1924 1925 static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s, 1926 char *cmd, char *buf, 1927 size_t buflen) 1928 { 1929 char *pos, *end, *stamp; 1930 int ret; 1931 1932 if (cmd == NULL) { 1933 return -1; 1934 } 1935 1936 /* cmd: "LOG_LEVEL [<level>]" */ 1937 if (*cmd == '\0') { 1938 pos = buf; 1939 end = buf + buflen; 1940 ret = os_snprintf(pos, end - pos, "Current level: %s\n" 1941 "Timestamp: %d\n", 1942 debug_level_str(wpa_debug_level), 1943 wpa_debug_timestamp); 1944 if (ret < 0 || ret >= end - pos) 1945 ret = 0; 1946 1947 return ret; 1948 } 1949 1950 while (*cmd == ' ') 1951 cmd++; 1952 1953 stamp = os_strchr(cmd, ' '); 1954 if (stamp) { 1955 *stamp++ = '\0'; 1956 while (*stamp == ' ') { 1957 stamp++; 1958 } 1959 } 1960 1961 if (cmd && os_strlen(cmd)) { 1962 int level = str_to_debug_level(cmd); 1963 if (level < 0) 1964 return -1; 1965 wpa_debug_level = level; 1966 } 1967 1968 if (stamp && os_strlen(stamp)) 1969 wpa_debug_timestamp = atoi(stamp); 1970 1971 os_memcpy(buf, "OK\n", 3); 1972 return 3; 1973 } 1974 1975 1976 static int wpa_supplicant_ctrl_iface_list_networks( 1977 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1978 { 1979 char *pos, *end; 1980 struct wpa_ssid *ssid; 1981 int ret; 1982 1983 pos = buf; 1984 end = buf + buflen; 1985 ret = os_snprintf(pos, end - pos, 1986 "network id / ssid / bssid / flags\n"); 1987 if (ret < 0 || ret >= end - pos) 1988 return pos - buf; 1989 pos += ret; 1990 1991 ssid = wpa_s->conf->ssid; 1992 while (ssid) { 1993 ret = os_snprintf(pos, end - pos, "%d\t%s", 1994 ssid->id, 1995 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 1996 if (ret < 0 || ret >= end - pos) 1997 return pos - buf; 1998 pos += ret; 1999 if (ssid->bssid_set) { 2000 ret = os_snprintf(pos, end - pos, "\t" MACSTR, 2001 MAC2STR(ssid->bssid)); 2002 } else { 2003 ret = os_snprintf(pos, end - pos, "\tany"); 2004 } 2005 if (ret < 0 || ret >= end - pos) 2006 return pos - buf; 2007 pos += ret; 2008 ret = os_snprintf(pos, end - pos, "\t%s%s%s%s", 2009 ssid == wpa_s->current_ssid ? 2010 "[CURRENT]" : "", 2011 ssid->disabled ? "[DISABLED]" : "", 2012 ssid->disabled_until.sec ? 2013 "[TEMP-DISABLED]" : "", 2014 ssid->disabled == 2 ? "[P2P-PERSISTENT]" : 2015 ""); 2016 if (ret < 0 || ret >= end - pos) 2017 return pos - buf; 2018 pos += ret; 2019 ret = os_snprintf(pos, end - pos, "\n"); 2020 if (ret < 0 || ret >= end - pos) 2021 return pos - buf; 2022 pos += ret; 2023 2024 ssid = ssid->next; 2025 } 2026 2027 return pos - buf; 2028 } 2029 2030 2031 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher) 2032 { 2033 int ret; 2034 ret = os_snprintf(pos, end - pos, "-"); 2035 if (ret < 0 || ret >= end - pos) 2036 return pos; 2037 pos += ret; 2038 ret = wpa_write_ciphers(pos, end, cipher, "+"); 2039 if (ret < 0) 2040 return pos; 2041 pos += ret; 2042 return pos; 2043 } 2044 2045 2046 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto, 2047 const u8 *ie, size_t ie_len) 2048 { 2049 struct wpa_ie_data data; 2050 int first, ret; 2051 2052 ret = os_snprintf(pos, end - pos, "[%s-", proto); 2053 if (ret < 0 || ret >= end - pos) 2054 return pos; 2055 pos += ret; 2056 2057 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) { 2058 ret = os_snprintf(pos, end - pos, "?]"); 2059 if (ret < 0 || ret >= end - pos) 2060 return pos; 2061 pos += ret; 2062 return pos; 2063 } 2064 2065 first = 1; 2066 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 2067 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+"); 2068 if (ret < 0 || ret >= end - pos) 2069 return pos; 2070 pos += ret; 2071 first = 0; 2072 } 2073 if (data.key_mgmt & WPA_KEY_MGMT_PSK) { 2074 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+"); 2075 if (ret < 0 || ret >= end - pos) 2076 return pos; 2077 pos += ret; 2078 first = 0; 2079 } 2080 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) { 2081 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+"); 2082 if (ret < 0 || ret >= end - pos) 2083 return pos; 2084 pos += ret; 2085 first = 0; 2086 } 2087 #ifdef CONFIG_IEEE80211R 2088 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { 2089 ret = os_snprintf(pos, end - pos, "%sFT/EAP", 2090 first ? "" : "+"); 2091 if (ret < 0 || ret >= end - pos) 2092 return pos; 2093 pos += ret; 2094 first = 0; 2095 } 2096 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) { 2097 ret = os_snprintf(pos, end - pos, "%sFT/PSK", 2098 first ? "" : "+"); 2099 if (ret < 0 || ret >= end - pos) 2100 return pos; 2101 pos += ret; 2102 first = 0; 2103 } 2104 #endif /* CONFIG_IEEE80211R */ 2105 #ifdef CONFIG_IEEE80211W 2106 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { 2107 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256", 2108 first ? "" : "+"); 2109 if (ret < 0 || ret >= end - pos) 2110 return pos; 2111 pos += ret; 2112 first = 0; 2113 } 2114 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { 2115 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256", 2116 first ? "" : "+"); 2117 if (ret < 0 || ret >= end - pos) 2118 return pos; 2119 pos += ret; 2120 first = 0; 2121 } 2122 #endif /* CONFIG_IEEE80211W */ 2123 2124 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher); 2125 2126 if (data.capabilities & WPA_CAPABILITY_PREAUTH) { 2127 ret = os_snprintf(pos, end - pos, "-preauth"); 2128 if (ret < 0 || ret >= end - pos) 2129 return pos; 2130 pos += ret; 2131 } 2132 2133 ret = os_snprintf(pos, end - pos, "]"); 2134 if (ret < 0 || ret >= end - pos) 2135 return pos; 2136 pos += ret; 2137 2138 return pos; 2139 } 2140 2141 2142 #ifdef CONFIG_WPS 2143 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s, 2144 char *pos, char *end, 2145 struct wpabuf *wps_ie) 2146 { 2147 int ret; 2148 const char *txt; 2149 2150 if (wps_ie == NULL) 2151 return pos; 2152 if (wps_is_selected_pbc_registrar(wps_ie)) 2153 txt = "[WPS-PBC]"; 2154 #ifdef CONFIG_WPS2 2155 else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0)) 2156 txt = "[WPS-AUTH]"; 2157 #endif /* CONFIG_WPS2 */ 2158 else if (wps_is_selected_pin_registrar(wps_ie)) 2159 txt = "[WPS-PIN]"; 2160 else 2161 txt = "[WPS]"; 2162 2163 ret = os_snprintf(pos, end - pos, "%s", txt); 2164 if (ret >= 0 && ret < end - pos) 2165 pos += ret; 2166 wpabuf_free(wps_ie); 2167 return pos; 2168 } 2169 #endif /* CONFIG_WPS */ 2170 2171 2172 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s, 2173 char *pos, char *end, 2174 const struct wpa_bss *bss) 2175 { 2176 #ifdef CONFIG_WPS 2177 struct wpabuf *wps_ie; 2178 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); 2179 return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie); 2180 #else /* CONFIG_WPS */ 2181 return pos; 2182 #endif /* CONFIG_WPS */ 2183 } 2184 2185 2186 /* Format one result on one text line into a buffer. */ 2187 static int wpa_supplicant_ctrl_iface_scan_result( 2188 struct wpa_supplicant *wpa_s, 2189 const struct wpa_bss *bss, char *buf, size_t buflen) 2190 { 2191 char *pos, *end; 2192 int ret; 2193 const u8 *ie, *ie2, *p2p; 2194 2195 p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE); 2196 if (!p2p) 2197 p2p = wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE); 2198 if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN && 2199 os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 2200 0) 2201 return 0; /* Do not show P2P listen discovery results here */ 2202 2203 pos = buf; 2204 end = buf + buflen; 2205 2206 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t", 2207 MAC2STR(bss->bssid), bss->freq, bss->level); 2208 if (ret < 0 || ret >= end - pos) 2209 return -1; 2210 pos += ret; 2211 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 2212 if (ie) 2213 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]); 2214 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); 2215 if (ie2) 2216 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); 2217 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); 2218 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 2219 ret = os_snprintf(pos, end - pos, "[WEP]"); 2220 if (ret < 0 || ret >= end - pos) 2221 return -1; 2222 pos += ret; 2223 } 2224 if (bss->caps & IEEE80211_CAP_IBSS) { 2225 ret = os_snprintf(pos, end - pos, "[IBSS]"); 2226 if (ret < 0 || ret >= end - pos) 2227 return -1; 2228 pos += ret; 2229 } 2230 if (bss->caps & IEEE80211_CAP_ESS) { 2231 ret = os_snprintf(pos, end - pos, "[ESS]"); 2232 if (ret < 0 || ret >= end - pos) 2233 return -1; 2234 pos += ret; 2235 } 2236 if (p2p) { 2237 ret = os_snprintf(pos, end - pos, "[P2P]"); 2238 if (ret < 0 || ret >= end - pos) 2239 return -1; 2240 pos += ret; 2241 } 2242 #ifdef CONFIG_HS20 2243 if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE) && ie2) { 2244 ret = os_snprintf(pos, end - pos, "[HS20]"); 2245 if (ret < 0 || ret >= end - pos) 2246 return -1; 2247 pos += ret; 2248 } 2249 #endif /* CONFIG_HS20 */ 2250 2251 ret = os_snprintf(pos, end - pos, "\t%s", 2252 wpa_ssid_txt(bss->ssid, bss->ssid_len)); 2253 if (ret < 0 || ret >= end - pos) 2254 return -1; 2255 pos += ret; 2256 2257 ret = os_snprintf(pos, end - pos, "\n"); 2258 if (ret < 0 || ret >= end - pos) 2259 return -1; 2260 pos += ret; 2261 2262 return pos - buf; 2263 } 2264 2265 2266 static int wpa_supplicant_ctrl_iface_scan_results( 2267 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 2268 { 2269 char *pos, *end; 2270 struct wpa_bss *bss; 2271 int ret; 2272 2273 pos = buf; 2274 end = buf + buflen; 2275 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / " 2276 "flags / ssid\n"); 2277 if (ret < 0 || ret >= end - pos) 2278 return pos - buf; 2279 pos += ret; 2280 2281 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) { 2282 ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos, 2283 end - pos); 2284 if (ret < 0 || ret >= end - pos) 2285 return pos - buf; 2286 pos += ret; 2287 } 2288 2289 return pos - buf; 2290 } 2291 2292 2293 static int wpa_supplicant_ctrl_iface_select_network( 2294 struct wpa_supplicant *wpa_s, char *cmd) 2295 { 2296 int id; 2297 struct wpa_ssid *ssid; 2298 2299 /* cmd: "<network id>" or "any" */ 2300 if (os_strcmp(cmd, "any") == 0) { 2301 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any"); 2302 ssid = NULL; 2303 } else { 2304 id = atoi(cmd); 2305 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id); 2306 2307 ssid = wpa_config_get_network(wpa_s->conf, id); 2308 if (ssid == NULL) { 2309 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 2310 "network id=%d", id); 2311 return -1; 2312 } 2313 if (ssid->disabled == 2) { 2314 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 2315 "SELECT_NETWORK with persistent P2P group"); 2316 return -1; 2317 } 2318 } 2319 2320 wpa_supplicant_select_network(wpa_s, ssid); 2321 2322 return 0; 2323 } 2324 2325 2326 static int wpa_supplicant_ctrl_iface_enable_network( 2327 struct wpa_supplicant *wpa_s, char *cmd) 2328 { 2329 int id; 2330 struct wpa_ssid *ssid; 2331 2332 /* cmd: "<network id>" or "all" */ 2333 if (os_strcmp(cmd, "all") == 0) { 2334 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all"); 2335 ssid = NULL; 2336 } else { 2337 id = atoi(cmd); 2338 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id); 2339 2340 ssid = wpa_config_get_network(wpa_s->conf, id); 2341 if (ssid == NULL) { 2342 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 2343 "network id=%d", id); 2344 return -1; 2345 } 2346 if (ssid->disabled == 2) { 2347 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 2348 "ENABLE_NETWORK with persistent P2P group"); 2349 return -1; 2350 } 2351 2352 if (os_strstr(cmd, " no-connect")) { 2353 ssid->disabled = 0; 2354 return 0; 2355 } 2356 } 2357 wpa_supplicant_enable_network(wpa_s, ssid); 2358 2359 return 0; 2360 } 2361 2362 2363 static int wpa_supplicant_ctrl_iface_disable_network( 2364 struct wpa_supplicant *wpa_s, char *cmd) 2365 { 2366 int id; 2367 struct wpa_ssid *ssid; 2368 2369 /* cmd: "<network id>" or "all" */ 2370 if (os_strcmp(cmd, "all") == 0) { 2371 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all"); 2372 ssid = NULL; 2373 } else { 2374 id = atoi(cmd); 2375 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id); 2376 2377 ssid = wpa_config_get_network(wpa_s->conf, id); 2378 if (ssid == NULL) { 2379 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 2380 "network id=%d", id); 2381 return -1; 2382 } 2383 if (ssid->disabled == 2) { 2384 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 2385 "DISABLE_NETWORK with persistent P2P " 2386 "group"); 2387 return -1; 2388 } 2389 } 2390 wpa_supplicant_disable_network(wpa_s, ssid); 2391 2392 return 0; 2393 } 2394 2395 2396 static int wpa_supplicant_ctrl_iface_add_network( 2397 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 2398 { 2399 struct wpa_ssid *ssid; 2400 int ret; 2401 2402 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK"); 2403 2404 ssid = wpa_config_add_network(wpa_s->conf); 2405 if (ssid == NULL) 2406 return -1; 2407 2408 wpas_notify_network_added(wpa_s, ssid); 2409 2410 ssid->disabled = 1; 2411 wpa_config_set_network_defaults(ssid); 2412 2413 ret = os_snprintf(buf, buflen, "%d\n", ssid->id); 2414 if (ret < 0 || (size_t) ret >= buflen) 2415 return -1; 2416 return ret; 2417 } 2418 2419 2420 static int wpa_supplicant_ctrl_iface_remove_network( 2421 struct wpa_supplicant *wpa_s, char *cmd) 2422 { 2423 int id; 2424 struct wpa_ssid *ssid; 2425 int was_disabled; 2426 2427 /* cmd: "<network id>" or "all" */ 2428 if (os_strcmp(cmd, "all") == 0) { 2429 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all"); 2430 if (wpa_s->sched_scanning) 2431 wpa_supplicant_cancel_sched_scan(wpa_s); 2432 2433 eapol_sm_invalidate_cached_session(wpa_s->eapol); 2434 if (wpa_s->current_ssid) { 2435 #ifdef CONFIG_SME 2436 wpa_s->sme.prev_bssid_set = 0; 2437 #endif /* CONFIG_SME */ 2438 wpa_sm_set_config(wpa_s->wpa, NULL); 2439 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 2440 wpa_supplicant_deauthenticate( 2441 wpa_s, WLAN_REASON_DEAUTH_LEAVING); 2442 } 2443 ssid = wpa_s->conf->ssid; 2444 while (ssid) { 2445 struct wpa_ssid *remove_ssid = ssid; 2446 id = ssid->id; 2447 ssid = ssid->next; 2448 wpas_notify_network_removed(wpa_s, remove_ssid); 2449 wpa_config_remove_network(wpa_s->conf, id); 2450 } 2451 return 0; 2452 } 2453 2454 id = atoi(cmd); 2455 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id); 2456 2457 ssid = wpa_config_get_network(wpa_s->conf, id); 2458 if (ssid) 2459 wpas_notify_network_removed(wpa_s, ssid); 2460 if (ssid == NULL) { 2461 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 2462 "id=%d", id); 2463 return -1; 2464 } 2465 2466 if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) { 2467 #ifdef CONFIG_SME 2468 wpa_s->sme.prev_bssid_set = 0; 2469 #endif /* CONFIG_SME */ 2470 /* 2471 * Invalidate the EAP session cache if the current or 2472 * previously used network is removed. 2473 */ 2474 eapol_sm_invalidate_cached_session(wpa_s->eapol); 2475 } 2476 2477 if (ssid == wpa_s->current_ssid) { 2478 wpa_sm_set_config(wpa_s->wpa, NULL); 2479 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 2480 2481 wpa_supplicant_deauthenticate(wpa_s, 2482 WLAN_REASON_DEAUTH_LEAVING); 2483 } 2484 2485 was_disabled = ssid->disabled; 2486 2487 if (wpa_config_remove_network(wpa_s->conf, id) < 0) { 2488 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Not able to remove the " 2489 "network id=%d", id); 2490 return -1; 2491 } 2492 2493 if (!was_disabled && wpa_s->sched_scanning) { 2494 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to remove " 2495 "network from filters"); 2496 wpa_supplicant_cancel_sched_scan(wpa_s); 2497 wpa_supplicant_req_scan(wpa_s, 0, 0); 2498 } 2499 2500 return 0; 2501 } 2502 2503 2504 static int wpa_supplicant_ctrl_iface_set_network( 2505 struct wpa_supplicant *wpa_s, char *cmd) 2506 { 2507 int id; 2508 struct wpa_ssid *ssid; 2509 char *name, *value; 2510 2511 /* cmd: "<network id> <variable name> <value>" */ 2512 name = os_strchr(cmd, ' '); 2513 if (name == NULL) 2514 return -1; 2515 *name++ = '\0'; 2516 2517 value = os_strchr(name, ' '); 2518 if (value == NULL) 2519 return -1; 2520 *value++ = '\0'; 2521 2522 id = atoi(cmd); 2523 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'", 2524 id, name); 2525 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 2526 (u8 *) value, os_strlen(value)); 2527 2528 ssid = wpa_config_get_network(wpa_s->conf, id); 2529 if (ssid == NULL) { 2530 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 2531 "id=%d", id); 2532 return -1; 2533 } 2534 2535 if (wpa_config_set(ssid, name, value, 0) < 0) { 2536 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network " 2537 "variable '%s'", name); 2538 return -1; 2539 } 2540 2541 if (os_strcmp(name, "bssid") != 0 && 2542 os_strcmp(name, "priority") != 0) 2543 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); 2544 2545 if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) { 2546 /* 2547 * Invalidate the EAP session cache if anything in the current 2548 * or previously used configuration changes. 2549 */ 2550 eapol_sm_invalidate_cached_session(wpa_s->eapol); 2551 } 2552 2553 if ((os_strcmp(name, "psk") == 0 && 2554 value[0] == '"' && ssid->ssid_len) || 2555 (os_strcmp(name, "ssid") == 0 && ssid->passphrase)) 2556 wpa_config_update_psk(ssid); 2557 else if (os_strcmp(name, "priority") == 0) 2558 wpa_config_update_prio_list(wpa_s->conf); 2559 2560 return 0; 2561 } 2562 2563 2564 static int wpa_supplicant_ctrl_iface_get_network( 2565 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 2566 { 2567 int id; 2568 size_t res; 2569 struct wpa_ssid *ssid; 2570 char *name, *value; 2571 2572 /* cmd: "<network id> <variable name>" */ 2573 name = os_strchr(cmd, ' '); 2574 if (name == NULL || buflen == 0) 2575 return -1; 2576 *name++ = '\0'; 2577 2578 id = atoi(cmd); 2579 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'", 2580 id, name); 2581 2582 ssid = wpa_config_get_network(wpa_s->conf, id); 2583 if (ssid == NULL) { 2584 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 2585 "id=%d", id); 2586 return -1; 2587 } 2588 2589 value = wpa_config_get_no_key(ssid, name); 2590 if (value == NULL) { 2591 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network " 2592 "variable '%s'", name); 2593 return -1; 2594 } 2595 2596 res = os_strlcpy(buf, value, buflen); 2597 if (res >= buflen) { 2598 os_free(value); 2599 return -1; 2600 } 2601 2602 os_free(value); 2603 2604 return res; 2605 } 2606 2607 2608 static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant *wpa_s, 2609 char *buf, size_t buflen) 2610 { 2611 char *pos, *end; 2612 struct wpa_cred *cred; 2613 int ret; 2614 2615 pos = buf; 2616 end = buf + buflen; 2617 ret = os_snprintf(pos, end - pos, 2618 "cred id / realm / username / domain / imsi\n"); 2619 if (ret < 0 || ret >= end - pos) 2620 return pos - buf; 2621 pos += ret; 2622 2623 cred = wpa_s->conf->cred; 2624 while (cred) { 2625 ret = os_snprintf(pos, end - pos, "%d\t%s\t%s\t%s\t%s\n", 2626 cred->id, cred->realm ? cred->realm : "", 2627 cred->username ? cred->username : "", 2628 cred->domain ? cred->domain[0] : "", 2629 cred->imsi ? cred->imsi : ""); 2630 if (ret < 0 || ret >= end - pos) 2631 return pos - buf; 2632 pos += ret; 2633 2634 cred = cred->next; 2635 } 2636 2637 return pos - buf; 2638 } 2639 2640 2641 static int wpa_supplicant_ctrl_iface_add_cred(struct wpa_supplicant *wpa_s, 2642 char *buf, size_t buflen) 2643 { 2644 struct wpa_cred *cred; 2645 int ret; 2646 2647 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_CRED"); 2648 2649 cred = wpa_config_add_cred(wpa_s->conf); 2650 if (cred == NULL) 2651 return -1; 2652 2653 ret = os_snprintf(buf, buflen, "%d\n", cred->id); 2654 if (ret < 0 || (size_t) ret >= buflen) 2655 return -1; 2656 return ret; 2657 } 2658 2659 2660 static int wpas_ctrl_remove_cred(struct wpa_supplicant *wpa_s, 2661 struct wpa_cred *cred) 2662 { 2663 struct wpa_ssid *ssid; 2664 char str[20]; 2665 2666 if (cred == NULL || wpa_config_remove_cred(wpa_s->conf, cred->id) < 0) { 2667 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred"); 2668 return -1; 2669 } 2670 2671 /* Remove any network entry created based on the removed credential */ 2672 ssid = wpa_s->conf->ssid; 2673 while (ssid) { 2674 if (ssid->parent_cred == cred) { 2675 wpa_printf(MSG_DEBUG, "Remove network id %d since it " 2676 "used the removed credential", ssid->id); 2677 os_snprintf(str, sizeof(str), "%d", ssid->id); 2678 ssid = ssid->next; 2679 wpa_supplicant_ctrl_iface_remove_network(wpa_s, str); 2680 } else 2681 ssid = ssid->next; 2682 } 2683 2684 return 0; 2685 } 2686 2687 2688 static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s, 2689 char *cmd) 2690 { 2691 int id; 2692 struct wpa_cred *cred, *prev; 2693 2694 /* cmd: "<cred id>", "all", or "sp_fqdn=<FQDN>" */ 2695 if (os_strcmp(cmd, "all") == 0) { 2696 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED all"); 2697 cred = wpa_s->conf->cred; 2698 while (cred) { 2699 prev = cred; 2700 cred = cred->next; 2701 wpas_ctrl_remove_cred(wpa_s, prev); 2702 } 2703 return 0; 2704 } 2705 2706 if (os_strncmp(cmd, "sp_fqdn=", 8) == 0) { 2707 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED SP FQDN '%s'", 2708 cmd + 8); 2709 cred = wpa_s->conf->cred; 2710 while (cred) { 2711 prev = cred; 2712 cred = cred->next; 2713 if (prev->domain) { 2714 size_t i; 2715 for (i = 0; i < prev->num_domain; i++) { 2716 if (os_strcmp(prev->domain[i], cmd + 8) 2717 != 0) 2718 continue; 2719 wpas_ctrl_remove_cred(wpa_s, prev); 2720 break; 2721 } 2722 } 2723 } 2724 return 0; 2725 } 2726 2727 id = atoi(cmd); 2728 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED id=%d", id); 2729 2730 cred = wpa_config_get_cred(wpa_s->conf, id); 2731 return wpas_ctrl_remove_cred(wpa_s, cred); 2732 } 2733 2734 2735 static int wpa_supplicant_ctrl_iface_set_cred(struct wpa_supplicant *wpa_s, 2736 char *cmd) 2737 { 2738 int id; 2739 struct wpa_cred *cred; 2740 char *name, *value; 2741 2742 /* cmd: "<cred id> <variable name> <value>" */ 2743 name = os_strchr(cmd, ' '); 2744 if (name == NULL) 2745 return -1; 2746 *name++ = '\0'; 2747 2748 value = os_strchr(name, ' '); 2749 if (value == NULL) 2750 return -1; 2751 *value++ = '\0'; 2752 2753 id = atoi(cmd); 2754 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_CRED id=%d name='%s'", 2755 id, name); 2756 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 2757 (u8 *) value, os_strlen(value)); 2758 2759 cred = wpa_config_get_cred(wpa_s->conf, id); 2760 if (cred == NULL) { 2761 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred id=%d", 2762 id); 2763 return -1; 2764 } 2765 2766 if (wpa_config_set_cred(cred, name, value, 0) < 0) { 2767 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set cred " 2768 "variable '%s'", name); 2769 return -1; 2770 } 2771 2772 return 0; 2773 } 2774 2775 2776 #ifndef CONFIG_NO_CONFIG_WRITE 2777 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s) 2778 { 2779 int ret; 2780 2781 if (!wpa_s->conf->update_config) { 2782 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed " 2783 "to update configuration (update_config=0)"); 2784 return -1; 2785 } 2786 2787 ret = wpa_config_write(wpa_s->confname, wpa_s->conf); 2788 if (ret) { 2789 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to " 2790 "update configuration"); 2791 } else { 2792 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration" 2793 " updated"); 2794 } 2795 2796 return ret; 2797 } 2798 #endif /* CONFIG_NO_CONFIG_WRITE */ 2799 2800 2801 struct cipher_info { 2802 unsigned int capa; 2803 const char *name; 2804 int group_only; 2805 }; 2806 2807 static const struct cipher_info ciphers[] = { 2808 { WPA_DRIVER_CAPA_ENC_CCMP_256, "CCMP-256", 0 }, 2809 { WPA_DRIVER_CAPA_ENC_GCMP_256, "GCMP-256", 0 }, 2810 { WPA_DRIVER_CAPA_ENC_CCMP, "CCMP", 0 }, 2811 { WPA_DRIVER_CAPA_ENC_GCMP, "GCMP", 0 }, 2812 { WPA_DRIVER_CAPA_ENC_TKIP, "TKIP", 0 }, 2813 { WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE, "NONE", 0 }, 2814 { WPA_DRIVER_CAPA_ENC_WEP104, "WEP104", 1 }, 2815 { WPA_DRIVER_CAPA_ENC_WEP40, "WEP40", 1 } 2816 }; 2817 2818 2819 static int ctrl_iface_get_capability_pairwise(int res, char *strict, 2820 struct wpa_driver_capa *capa, 2821 char *buf, size_t buflen) 2822 { 2823 int ret, first = 1; 2824 char *pos, *end; 2825 size_t len; 2826 unsigned int i; 2827 2828 pos = buf; 2829 end = pos + buflen; 2830 2831 if (res < 0) { 2832 if (strict) 2833 return 0; 2834 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen); 2835 if (len >= buflen) 2836 return -1; 2837 return len; 2838 } 2839 2840 for (i = 0; i < ARRAY_SIZE(ciphers); i++) { 2841 if (!ciphers[i].group_only && capa->enc & ciphers[i].capa) { 2842 ret = os_snprintf(pos, end - pos, "%s%s", 2843 first ? "" : " ", ciphers[i].name); 2844 if (ret < 0 || ret >= end - pos) 2845 return pos - buf; 2846 pos += ret; 2847 first = 0; 2848 } 2849 } 2850 2851 return pos - buf; 2852 } 2853 2854 2855 static int ctrl_iface_get_capability_group(int res, char *strict, 2856 struct wpa_driver_capa *capa, 2857 char *buf, size_t buflen) 2858 { 2859 int ret, first = 1; 2860 char *pos, *end; 2861 size_t len; 2862 unsigned int i; 2863 2864 pos = buf; 2865 end = pos + buflen; 2866 2867 if (res < 0) { 2868 if (strict) 2869 return 0; 2870 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen); 2871 if (len >= buflen) 2872 return -1; 2873 return len; 2874 } 2875 2876 for (i = 0; i < ARRAY_SIZE(ciphers); i++) { 2877 if (capa->enc & ciphers[i].capa) { 2878 ret = os_snprintf(pos, end - pos, "%s%s", 2879 first ? "" : " ", ciphers[i].name); 2880 if (ret < 0 || ret >= end - pos) 2881 return pos - buf; 2882 pos += ret; 2883 first = 0; 2884 } 2885 } 2886 2887 return pos - buf; 2888 } 2889 2890 2891 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict, 2892 struct wpa_driver_capa *capa, 2893 char *buf, size_t buflen) 2894 { 2895 int ret; 2896 char *pos, *end; 2897 size_t len; 2898 2899 pos = buf; 2900 end = pos + buflen; 2901 2902 if (res < 0) { 2903 if (strict) 2904 return 0; 2905 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE " 2906 "NONE", buflen); 2907 if (len >= buflen) 2908 return -1; 2909 return len; 2910 } 2911 2912 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X"); 2913 if (ret < 0 || ret >= end - pos) 2914 return pos - buf; 2915 pos += ret; 2916 2917 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 2918 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { 2919 ret = os_snprintf(pos, end - pos, " WPA-EAP"); 2920 if (ret < 0 || ret >= end - pos) 2921 return pos - buf; 2922 pos += ret; 2923 } 2924 2925 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 2926 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 2927 ret = os_snprintf(pos, end - pos, " WPA-PSK"); 2928 if (ret < 0 || ret >= end - pos) 2929 return pos - buf; 2930 pos += ret; 2931 } 2932 2933 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 2934 ret = os_snprintf(pos, end - pos, " WPA-NONE"); 2935 if (ret < 0 || ret >= end - pos) 2936 return pos - buf; 2937 pos += ret; 2938 } 2939 2940 return pos - buf; 2941 } 2942 2943 2944 static int ctrl_iface_get_capability_proto(int res, char *strict, 2945 struct wpa_driver_capa *capa, 2946 char *buf, size_t buflen) 2947 { 2948 int ret, first = 1; 2949 char *pos, *end; 2950 size_t len; 2951 2952 pos = buf; 2953 end = pos + buflen; 2954 2955 if (res < 0) { 2956 if (strict) 2957 return 0; 2958 len = os_strlcpy(buf, "RSN WPA", buflen); 2959 if (len >= buflen) 2960 return -1; 2961 return len; 2962 } 2963 2964 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 2965 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 2966 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " "); 2967 if (ret < 0 || ret >= end - pos) 2968 return pos - buf; 2969 pos += ret; 2970 first = 0; 2971 } 2972 2973 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 2974 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { 2975 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " "); 2976 if (ret < 0 || ret >= end - pos) 2977 return pos - buf; 2978 pos += ret; 2979 first = 0; 2980 } 2981 2982 return pos - buf; 2983 } 2984 2985 2986 static int ctrl_iface_get_capability_auth_alg(int res, char *strict, 2987 struct wpa_driver_capa *capa, 2988 char *buf, size_t buflen) 2989 { 2990 int ret, first = 1; 2991 char *pos, *end; 2992 size_t len; 2993 2994 pos = buf; 2995 end = pos + buflen; 2996 2997 if (res < 0) { 2998 if (strict) 2999 return 0; 3000 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen); 3001 if (len >= buflen) 3002 return -1; 3003 return len; 3004 } 3005 3006 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) { 3007 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " "); 3008 if (ret < 0 || ret >= end - pos) 3009 return pos - buf; 3010 pos += ret; 3011 first = 0; 3012 } 3013 3014 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) { 3015 ret = os_snprintf(pos, end - pos, "%sSHARED", 3016 first ? "" : " "); 3017 if (ret < 0 || ret >= end - pos) 3018 return pos - buf; 3019 pos += ret; 3020 first = 0; 3021 } 3022 3023 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) { 3024 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " "); 3025 if (ret < 0 || ret >= end - pos) 3026 return pos - buf; 3027 pos += ret; 3028 first = 0; 3029 } 3030 3031 return pos - buf; 3032 } 3033 3034 3035 static int ctrl_iface_get_capability_modes(int res, char *strict, 3036 struct wpa_driver_capa *capa, 3037 char *buf, size_t buflen) 3038 { 3039 int ret, first = 1; 3040 char *pos, *end; 3041 size_t len; 3042 3043 pos = buf; 3044 end = pos + buflen; 3045 3046 if (res < 0) { 3047 if (strict) 3048 return 0; 3049 len = os_strlcpy(buf, "IBSS AP", buflen); 3050 if (len >= buflen) 3051 return -1; 3052 return len; 3053 } 3054 3055 if (capa->flags & WPA_DRIVER_FLAGS_IBSS) { 3056 ret = os_snprintf(pos, end - pos, "%sIBSS", first ? "" : " "); 3057 if (ret < 0 || ret >= end - pos) 3058 return pos - buf; 3059 pos += ret; 3060 first = 0; 3061 } 3062 3063 if (capa->flags & WPA_DRIVER_FLAGS_AP) { 3064 ret = os_snprintf(pos, end - pos, "%sAP", first ? "" : " "); 3065 if (ret < 0 || ret >= end - pos) 3066 return pos - buf; 3067 pos += ret; 3068 first = 0; 3069 } 3070 3071 return pos - buf; 3072 } 3073 3074 3075 static int ctrl_iface_get_capability_channels(struct wpa_supplicant *wpa_s, 3076 char *buf, size_t buflen) 3077 { 3078 struct hostapd_channel_data *chnl; 3079 int ret, i, j; 3080 char *pos, *end, *hmode; 3081 3082 pos = buf; 3083 end = pos + buflen; 3084 3085 for (j = 0; j < wpa_s->hw.num_modes; j++) { 3086 switch (wpa_s->hw.modes[j].mode) { 3087 case HOSTAPD_MODE_IEEE80211B: 3088 hmode = "B"; 3089 break; 3090 case HOSTAPD_MODE_IEEE80211G: 3091 hmode = "G"; 3092 break; 3093 case HOSTAPD_MODE_IEEE80211A: 3094 hmode = "A"; 3095 break; 3096 case HOSTAPD_MODE_IEEE80211AD: 3097 hmode = "AD"; 3098 break; 3099 default: 3100 continue; 3101 } 3102 ret = os_snprintf(pos, end - pos, "Mode[%s] Channels:", hmode); 3103 if (ret < 0 || ret >= end - pos) 3104 return pos - buf; 3105 pos += ret; 3106 chnl = wpa_s->hw.modes[j].channels; 3107 for (i = 0; i < wpa_s->hw.modes[j].num_channels; i++) { 3108 if (chnl[i].flag & HOSTAPD_CHAN_DISABLED) 3109 continue; 3110 ret = os_snprintf(pos, end - pos, " %d", chnl[i].chan); 3111 if (ret < 0 || ret >= end - pos) 3112 return pos - buf; 3113 pos += ret; 3114 } 3115 ret = os_snprintf(pos, end - pos, "\n"); 3116 if (ret < 0 || ret >= end - pos) 3117 return pos - buf; 3118 pos += ret; 3119 } 3120 3121 return pos - buf; 3122 } 3123 3124 3125 static int ctrl_iface_get_capability_freq(struct wpa_supplicant *wpa_s, 3126 char *buf, size_t buflen) 3127 { 3128 struct hostapd_channel_data *chnl; 3129 int ret, i, j; 3130 char *pos, *end, *hmode; 3131 3132 pos = buf; 3133 end = pos + buflen; 3134 3135 for (j = 0; j < wpa_s->hw.num_modes; j++) { 3136 switch (wpa_s->hw.modes[j].mode) { 3137 case HOSTAPD_MODE_IEEE80211B: 3138 hmode = "B"; 3139 break; 3140 case HOSTAPD_MODE_IEEE80211G: 3141 hmode = "G"; 3142 break; 3143 case HOSTAPD_MODE_IEEE80211A: 3144 hmode = "A"; 3145 break; 3146 case HOSTAPD_MODE_IEEE80211AD: 3147 hmode = "AD"; 3148 break; 3149 default: 3150 continue; 3151 } 3152 ret = os_snprintf(pos, end - pos, "Mode[%s] Channels:\n", 3153 hmode); 3154 if (ret < 0 || ret >= end - pos) 3155 return pos - buf; 3156 pos += ret; 3157 chnl = wpa_s->hw.modes[j].channels; 3158 for (i = 0; i < wpa_s->hw.modes[j].num_channels; i++) { 3159 if (chnl[i].flag & HOSTAPD_CHAN_DISABLED) 3160 continue; 3161 ret = os_snprintf(pos, end - pos, " %d = %d MHz%s\n", 3162 chnl[i].chan, chnl[i].freq, 3163 chnl[i].flag & HOSTAPD_CHAN_NO_IBSS ? 3164 " (NO_IBSS)" : ""); 3165 if (ret < 0 || ret >= end - pos) 3166 return pos - buf; 3167 pos += ret; 3168 } 3169 ret = os_snprintf(pos, end - pos, "\n"); 3170 if (ret < 0 || ret >= end - pos) 3171 return pos - buf; 3172 pos += ret; 3173 } 3174 3175 return pos - buf; 3176 } 3177 3178 3179 static int wpa_supplicant_ctrl_iface_get_capability( 3180 struct wpa_supplicant *wpa_s, const char *_field, char *buf, 3181 size_t buflen) 3182 { 3183 struct wpa_driver_capa capa; 3184 int res; 3185 char *strict; 3186 char field[30]; 3187 size_t len; 3188 3189 /* Determine whether or not strict checking was requested */ 3190 len = os_strlcpy(field, _field, sizeof(field)); 3191 if (len >= sizeof(field)) 3192 return -1; 3193 strict = os_strchr(field, ' '); 3194 if (strict != NULL) { 3195 *strict++ = '\0'; 3196 if (os_strcmp(strict, "strict") != 0) 3197 return -1; 3198 } 3199 3200 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s", 3201 field, strict ? strict : ""); 3202 3203 if (os_strcmp(field, "eap") == 0) { 3204 return eap_get_names(buf, buflen); 3205 } 3206 3207 res = wpa_drv_get_capa(wpa_s, &capa); 3208 3209 if (os_strcmp(field, "pairwise") == 0) 3210 return ctrl_iface_get_capability_pairwise(res, strict, &capa, 3211 buf, buflen); 3212 3213 if (os_strcmp(field, "group") == 0) 3214 return ctrl_iface_get_capability_group(res, strict, &capa, 3215 buf, buflen); 3216 3217 if (os_strcmp(field, "key_mgmt") == 0) 3218 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa, 3219 buf, buflen); 3220 3221 if (os_strcmp(field, "proto") == 0) 3222 return ctrl_iface_get_capability_proto(res, strict, &capa, 3223 buf, buflen); 3224 3225 if (os_strcmp(field, "auth_alg") == 0) 3226 return ctrl_iface_get_capability_auth_alg(res, strict, &capa, 3227 buf, buflen); 3228 3229 if (os_strcmp(field, "modes") == 0) 3230 return ctrl_iface_get_capability_modes(res, strict, &capa, 3231 buf, buflen); 3232 3233 if (os_strcmp(field, "channels") == 0) 3234 return ctrl_iface_get_capability_channels(wpa_s, buf, buflen); 3235 3236 if (os_strcmp(field, "freq") == 0) 3237 return ctrl_iface_get_capability_freq(wpa_s, buf, buflen); 3238 3239 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'", 3240 field); 3241 3242 return -1; 3243 } 3244 3245 3246 #ifdef CONFIG_INTERWORKING 3247 static char * anqp_add_hex(char *pos, char *end, const char *title, 3248 struct wpabuf *data) 3249 { 3250 char *start = pos; 3251 size_t i; 3252 int ret; 3253 const u8 *d; 3254 3255 if (data == NULL) 3256 return start; 3257 3258 ret = os_snprintf(pos, end - pos, "%s=", title); 3259 if (ret < 0 || ret >= end - pos) 3260 return start; 3261 pos += ret; 3262 3263 d = wpabuf_head_u8(data); 3264 for (i = 0; i < wpabuf_len(data); i++) { 3265 ret = os_snprintf(pos, end - pos, "%02x", *d++); 3266 if (ret < 0 || ret >= end - pos) 3267 return start; 3268 pos += ret; 3269 } 3270 3271 ret = os_snprintf(pos, end - pos, "\n"); 3272 if (ret < 0 || ret >= end - pos) 3273 return start; 3274 pos += ret; 3275 3276 return pos; 3277 } 3278 #endif /* CONFIG_INTERWORKING */ 3279 3280 3281 static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, 3282 unsigned long mask, char *buf, size_t buflen) 3283 { 3284 size_t i; 3285 int ret; 3286 char *pos, *end; 3287 const u8 *ie, *ie2; 3288 3289 pos = buf; 3290 end = buf + buflen; 3291 3292 if (mask & WPA_BSS_MASK_ID) { 3293 ret = os_snprintf(pos, end - pos, "id=%u\n", bss->id); 3294 if (ret < 0 || ret >= end - pos) 3295 return 0; 3296 pos += ret; 3297 } 3298 3299 if (mask & WPA_BSS_MASK_BSSID) { 3300 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n", 3301 MAC2STR(bss->bssid)); 3302 if (ret < 0 || ret >= end - pos) 3303 return 0; 3304 pos += ret; 3305 } 3306 3307 if (mask & WPA_BSS_MASK_FREQ) { 3308 ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq); 3309 if (ret < 0 || ret >= end - pos) 3310 return 0; 3311 pos += ret; 3312 } 3313 3314 if (mask & WPA_BSS_MASK_BEACON_INT) { 3315 ret = os_snprintf(pos, end - pos, "beacon_int=%d\n", 3316 bss->beacon_int); 3317 if (ret < 0 || ret >= end - pos) 3318 return 0; 3319 pos += ret; 3320 } 3321 3322 if (mask & WPA_BSS_MASK_CAPABILITIES) { 3323 ret = os_snprintf(pos, end - pos, "capabilities=0x%04x\n", 3324 bss->caps); 3325 if (ret < 0 || ret >= end - pos) 3326 return 0; 3327 pos += ret; 3328 } 3329 3330 if (mask & WPA_BSS_MASK_QUAL) { 3331 ret = os_snprintf(pos, end - pos, "qual=%d\n", bss->qual); 3332 if (ret < 0 || ret >= end - pos) 3333 return 0; 3334 pos += ret; 3335 } 3336 3337 if (mask & WPA_BSS_MASK_NOISE) { 3338 ret = os_snprintf(pos, end - pos, "noise=%d\n", bss->noise); 3339 if (ret < 0 || ret >= end - pos) 3340 return 0; 3341 pos += ret; 3342 } 3343 3344 if (mask & WPA_BSS_MASK_LEVEL) { 3345 ret = os_snprintf(pos, end - pos, "level=%d\n", bss->level); 3346 if (ret < 0 || ret >= end - pos) 3347 return 0; 3348 pos += ret; 3349 } 3350 3351 if (mask & WPA_BSS_MASK_TSF) { 3352 ret = os_snprintf(pos, end - pos, "tsf=%016llu\n", 3353 (unsigned long long) bss->tsf); 3354 if (ret < 0 || ret >= end - pos) 3355 return 0; 3356 pos += ret; 3357 } 3358 3359 if (mask & WPA_BSS_MASK_AGE) { 3360 struct os_reltime now; 3361 3362 os_get_reltime(&now); 3363 ret = os_snprintf(pos, end - pos, "age=%d\n", 3364 (int) (now.sec - bss->last_update.sec)); 3365 if (ret < 0 || ret >= end - pos) 3366 return 0; 3367 pos += ret; 3368 } 3369 3370 if (mask & WPA_BSS_MASK_IE) { 3371 ret = os_snprintf(pos, end - pos, "ie="); 3372 if (ret < 0 || ret >= end - pos) 3373 return 0; 3374 pos += ret; 3375 3376 ie = (const u8 *) (bss + 1); 3377 for (i = 0; i < bss->ie_len; i++) { 3378 ret = os_snprintf(pos, end - pos, "%02x", *ie++); 3379 if (ret < 0 || ret >= end - pos) 3380 return 0; 3381 pos += ret; 3382 } 3383 3384 ret = os_snprintf(pos, end - pos, "\n"); 3385 if (ret < 0 || ret >= end - pos) 3386 return 0; 3387 pos += ret; 3388 } 3389 3390 if (mask & WPA_BSS_MASK_FLAGS) { 3391 ret = os_snprintf(pos, end - pos, "flags="); 3392 if (ret < 0 || ret >= end - pos) 3393 return 0; 3394 pos += ret; 3395 3396 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 3397 if (ie) 3398 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 3399 2 + ie[1]); 3400 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); 3401 if (ie2) 3402 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 3403 2 + ie2[1]); 3404 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); 3405 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 3406 ret = os_snprintf(pos, end - pos, "[WEP]"); 3407 if (ret < 0 || ret >= end - pos) 3408 return 0; 3409 pos += ret; 3410 } 3411 if (bss->caps & IEEE80211_CAP_IBSS) { 3412 ret = os_snprintf(pos, end - pos, "[IBSS]"); 3413 if (ret < 0 || ret >= end - pos) 3414 return 0; 3415 pos += ret; 3416 } 3417 if (bss->caps & IEEE80211_CAP_ESS) { 3418 ret = os_snprintf(pos, end - pos, "[ESS]"); 3419 if (ret < 0 || ret >= end - pos) 3420 return 0; 3421 pos += ret; 3422 } 3423 if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) || 3424 wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) { 3425 ret = os_snprintf(pos, end - pos, "[P2P]"); 3426 if (ret < 0 || ret >= end - pos) 3427 return 0; 3428 pos += ret; 3429 } 3430 #ifdef CONFIG_HS20 3431 if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE)) { 3432 ret = os_snprintf(pos, end - pos, "[HS20]"); 3433 if (ret < 0 || ret >= end - pos) 3434 return 0; 3435 pos += ret; 3436 } 3437 #endif /* CONFIG_HS20 */ 3438 3439 ret = os_snprintf(pos, end - pos, "\n"); 3440 if (ret < 0 || ret >= end - pos) 3441 return 0; 3442 pos += ret; 3443 } 3444 3445 if (mask & WPA_BSS_MASK_SSID) { 3446 ret = os_snprintf(pos, end - pos, "ssid=%s\n", 3447 wpa_ssid_txt(bss->ssid, bss->ssid_len)); 3448 if (ret < 0 || ret >= end - pos) 3449 return 0; 3450 pos += ret; 3451 } 3452 3453 #ifdef CONFIG_WPS 3454 if (mask & WPA_BSS_MASK_WPS_SCAN) { 3455 ie = (const u8 *) (bss + 1); 3456 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end); 3457 if (ret < 0 || ret >= end - pos) 3458 return 0; 3459 pos += ret; 3460 } 3461 #endif /* CONFIG_WPS */ 3462 3463 #ifdef CONFIG_P2P 3464 if (mask & WPA_BSS_MASK_P2P_SCAN) { 3465 ie = (const u8 *) (bss + 1); 3466 ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end); 3467 if (ret < 0 || ret >= end - pos) 3468 return 0; 3469 pos += ret; 3470 } 3471 #endif /* CONFIG_P2P */ 3472 3473 #ifdef CONFIG_WIFI_DISPLAY 3474 if (mask & WPA_BSS_MASK_WIFI_DISPLAY) { 3475 struct wpabuf *wfd; 3476 ie = (const u8 *) (bss + 1); 3477 wfd = ieee802_11_vendor_ie_concat(ie, bss->ie_len, 3478 WFD_IE_VENDOR_TYPE); 3479 if (wfd) { 3480 ret = os_snprintf(pos, end - pos, "wfd_subelems="); 3481 if (ret < 0 || ret >= end - pos) 3482 return 0; 3483 pos += ret; 3484 3485 pos += wpa_snprintf_hex(pos, end - pos, 3486 wpabuf_head(wfd), 3487 wpabuf_len(wfd)); 3488 wpabuf_free(wfd); 3489 3490 ret = os_snprintf(pos, end - pos, "\n"); 3491 if (ret < 0 || ret >= end - pos) 3492 return 0; 3493 pos += ret; 3494 } 3495 } 3496 #endif /* CONFIG_WIFI_DISPLAY */ 3497 3498 #ifdef CONFIG_INTERWORKING 3499 if ((mask & WPA_BSS_MASK_INTERNETW) && bss->anqp) { 3500 struct wpa_bss_anqp *anqp = bss->anqp; 3501 pos = anqp_add_hex(pos, end, "anqp_venue_name", 3502 anqp->venue_name); 3503 pos = anqp_add_hex(pos, end, "anqp_network_auth_type", 3504 anqp->network_auth_type); 3505 pos = anqp_add_hex(pos, end, "anqp_roaming_consortium", 3506 anqp->roaming_consortium); 3507 pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability", 3508 anqp->ip_addr_type_availability); 3509 pos = anqp_add_hex(pos, end, "anqp_nai_realm", 3510 anqp->nai_realm); 3511 pos = anqp_add_hex(pos, end, "anqp_3gpp", anqp->anqp_3gpp); 3512 pos = anqp_add_hex(pos, end, "anqp_domain_name", 3513 anqp->domain_name); 3514 #ifdef CONFIG_HS20 3515 pos = anqp_add_hex(pos, end, "hs20_operator_friendly_name", 3516 anqp->hs20_operator_friendly_name); 3517 pos = anqp_add_hex(pos, end, "hs20_wan_metrics", 3518 anqp->hs20_wan_metrics); 3519 pos = anqp_add_hex(pos, end, "hs20_connection_capability", 3520 anqp->hs20_connection_capability); 3521 #endif /* CONFIG_HS20 */ 3522 } 3523 #endif /* CONFIG_INTERWORKING */ 3524 3525 if (mask & WPA_BSS_MASK_DELIM) { 3526 ret = os_snprintf(pos, end - pos, "====\n"); 3527 if (ret < 0 || ret >= end - pos) 3528 return 0; 3529 pos += ret; 3530 } 3531 3532 return pos - buf; 3533 } 3534 3535 3536 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, 3537 const char *cmd, char *buf, 3538 size_t buflen) 3539 { 3540 u8 bssid[ETH_ALEN]; 3541 size_t i; 3542 struct wpa_bss *bss; 3543 struct wpa_bss *bsslast = NULL; 3544 struct dl_list *next; 3545 int ret = 0; 3546 int len; 3547 char *ctmp; 3548 unsigned long mask = WPA_BSS_MASK_ALL; 3549 3550 if (os_strncmp(cmd, "RANGE=", 6) == 0) { 3551 if (os_strncmp(cmd + 6, "ALL", 3) == 0) { 3552 bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss, 3553 list_id); 3554 bsslast = dl_list_last(&wpa_s->bss_id, struct wpa_bss, 3555 list_id); 3556 } else { /* N1-N2 */ 3557 unsigned int id1, id2; 3558 3559 if ((ctmp = os_strchr(cmd + 6, '-')) == NULL) { 3560 wpa_printf(MSG_INFO, "Wrong BSS range " 3561 "format"); 3562 return 0; 3563 } 3564 3565 if (*(cmd + 6) == '-') 3566 id1 = 0; 3567 else 3568 id1 = atoi(cmd + 6); 3569 ctmp++; 3570 if (*ctmp >= '0' && *ctmp <= '9') 3571 id2 = atoi(ctmp); 3572 else 3573 id2 = (unsigned int) -1; 3574 bss = wpa_bss_get_id_range(wpa_s, id1, id2); 3575 if (id2 == (unsigned int) -1) 3576 bsslast = dl_list_last(&wpa_s->bss_id, 3577 struct wpa_bss, 3578 list_id); 3579 else { 3580 bsslast = wpa_bss_get_id(wpa_s, id2); 3581 if (bsslast == NULL && bss && id2 > id1) { 3582 struct wpa_bss *tmp = bss; 3583 for (;;) { 3584 next = tmp->list_id.next; 3585 if (next == &wpa_s->bss_id) 3586 break; 3587 tmp = dl_list_entry( 3588 next, struct wpa_bss, 3589 list_id); 3590 if (tmp->id > id2) 3591 break; 3592 bsslast = tmp; 3593 } 3594 } 3595 } 3596 } 3597 } else if (os_strncmp(cmd, "FIRST", 5) == 0) 3598 bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss, list_id); 3599 else if (os_strncmp(cmd, "LAST", 4) == 0) 3600 bss = dl_list_last(&wpa_s->bss_id, struct wpa_bss, list_id); 3601 else if (os_strncmp(cmd, "ID-", 3) == 0) { 3602 i = atoi(cmd + 3); 3603 bss = wpa_bss_get_id(wpa_s, i); 3604 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { 3605 i = atoi(cmd + 5); 3606 bss = wpa_bss_get_id(wpa_s, i); 3607 if (bss) { 3608 next = bss->list_id.next; 3609 if (next == &wpa_s->bss_id) 3610 bss = NULL; 3611 else 3612 bss = dl_list_entry(next, struct wpa_bss, 3613 list_id); 3614 } 3615 #ifdef CONFIG_P2P 3616 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) { 3617 if (hwaddr_aton(cmd + 13, bssid) == 0) 3618 bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid); 3619 else 3620 bss = NULL; 3621 #endif /* CONFIG_P2P */ 3622 } else if (hwaddr_aton(cmd, bssid) == 0) 3623 bss = wpa_bss_get_bssid(wpa_s, bssid); 3624 else { 3625 struct wpa_bss *tmp; 3626 i = atoi(cmd); 3627 bss = NULL; 3628 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id) 3629 { 3630 if (i-- == 0) { 3631 bss = tmp; 3632 break; 3633 } 3634 } 3635 } 3636 3637 if ((ctmp = os_strstr(cmd, "MASK=")) != NULL) { 3638 mask = strtoul(ctmp + 5, NULL, 0x10); 3639 if (mask == 0) 3640 mask = WPA_BSS_MASK_ALL; 3641 } 3642 3643 if (bss == NULL) 3644 return 0; 3645 3646 if (bsslast == NULL) 3647 bsslast = bss; 3648 do { 3649 len = print_bss_info(wpa_s, bss, mask, buf, buflen); 3650 ret += len; 3651 buf += len; 3652 buflen -= len; 3653 if (bss == bsslast) { 3654 if ((mask & WPA_BSS_MASK_DELIM) && len && 3655 (bss == dl_list_last(&wpa_s->bss_id, 3656 struct wpa_bss, list_id))) 3657 os_snprintf(buf - 5, 5, "####\n"); 3658 break; 3659 } 3660 next = bss->list_id.next; 3661 if (next == &wpa_s->bss_id) 3662 break; 3663 bss = dl_list_entry(next, struct wpa_bss, list_id); 3664 } while (bss && len); 3665 3666 return ret; 3667 } 3668 3669 3670 static int wpa_supplicant_ctrl_iface_ap_scan( 3671 struct wpa_supplicant *wpa_s, char *cmd) 3672 { 3673 int ap_scan = atoi(cmd); 3674 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan); 3675 } 3676 3677 3678 static int wpa_supplicant_ctrl_iface_scan_interval( 3679 struct wpa_supplicant *wpa_s, char *cmd) 3680 { 3681 int scan_int = atoi(cmd); 3682 return wpa_supplicant_set_scan_interval(wpa_s, scan_int); 3683 } 3684 3685 3686 static int wpa_supplicant_ctrl_iface_bss_expire_age( 3687 struct wpa_supplicant *wpa_s, char *cmd) 3688 { 3689 int expire_age = atoi(cmd); 3690 return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age); 3691 } 3692 3693 3694 static int wpa_supplicant_ctrl_iface_bss_expire_count( 3695 struct wpa_supplicant *wpa_s, char *cmd) 3696 { 3697 int expire_count = atoi(cmd); 3698 return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count); 3699 } 3700 3701 3702 static int wpa_supplicant_ctrl_iface_bss_flush( 3703 struct wpa_supplicant *wpa_s, char *cmd) 3704 { 3705 int flush_age = atoi(cmd); 3706 3707 if (flush_age == 0) 3708 wpa_bss_flush(wpa_s); 3709 else 3710 wpa_bss_flush_by_age(wpa_s, flush_age); 3711 return 0; 3712 } 3713 3714 3715 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s) 3716 { 3717 wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication"); 3718 /* MLME-DELETEKEYS.request */ 3719 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0); 3720 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0); 3721 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0); 3722 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0); 3723 #ifdef CONFIG_IEEE80211W 3724 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0); 3725 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0); 3726 #endif /* CONFIG_IEEE80211W */ 3727 3728 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL, 3729 0); 3730 /* MLME-SETPROTECTION.request(None) */ 3731 wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid, 3732 MLME_SETPROTECTION_PROTECT_TYPE_NONE, 3733 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE); 3734 wpa_sm_drop_sa(wpa_s->wpa); 3735 } 3736 3737 3738 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s, 3739 char *addr) 3740 { 3741 #ifdef CONFIG_NO_SCAN_PROCESSING 3742 return -1; 3743 #else /* CONFIG_NO_SCAN_PROCESSING */ 3744 u8 bssid[ETH_ALEN]; 3745 struct wpa_bss *bss; 3746 struct wpa_ssid *ssid = wpa_s->current_ssid; 3747 3748 if (hwaddr_aton(addr, bssid)) { 3749 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid " 3750 "address '%s'", addr); 3751 return -1; 3752 } 3753 3754 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid)); 3755 3756 if (!ssid) { 3757 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network " 3758 "configuration known for the target AP"); 3759 return -1; 3760 } 3761 3762 bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len); 3763 if (!bss) { 3764 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found " 3765 "from BSS table"); 3766 return -1; 3767 } 3768 3769 /* 3770 * TODO: Find best network configuration block from configuration to 3771 * allow roaming to other networks 3772 */ 3773 3774 wpa_s->reassociate = 1; 3775 wpa_supplicant_connect(wpa_s, bss, ssid); 3776 3777 return 0; 3778 #endif /* CONFIG_NO_SCAN_PROCESSING */ 3779 } 3780 3781 3782 #ifdef CONFIG_P2P 3783 static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd) 3784 { 3785 unsigned int timeout = atoi(cmd); 3786 enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL; 3787 u8 dev_id[ETH_ALEN], *_dev_id = NULL; 3788 u8 dev_type[WPS_DEV_TYPE_LEN], *_dev_type = NULL; 3789 char *pos; 3790 unsigned int search_delay; 3791 3792 if (os_strstr(cmd, "type=social")) 3793 type = P2P_FIND_ONLY_SOCIAL; 3794 else if (os_strstr(cmd, "type=progressive")) 3795 type = P2P_FIND_PROGRESSIVE; 3796 3797 pos = os_strstr(cmd, "dev_id="); 3798 if (pos) { 3799 pos += 7; 3800 if (hwaddr_aton(pos, dev_id)) 3801 return -1; 3802 _dev_id = dev_id; 3803 } 3804 3805 pos = os_strstr(cmd, "dev_type="); 3806 if (pos) { 3807 pos += 9; 3808 if (wps_dev_type_str2bin(pos, dev_type) < 0) 3809 return -1; 3810 _dev_type = dev_type; 3811 } 3812 3813 pos = os_strstr(cmd, "delay="); 3814 if (pos) { 3815 pos += 6; 3816 search_delay = atoi(pos); 3817 } else 3818 search_delay = wpas_p2p_search_delay(wpa_s); 3819 3820 return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL, _dev_type, 3821 _dev_id, search_delay); 3822 } 3823 3824 3825 static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, 3826 char *buf, size_t buflen) 3827 { 3828 u8 addr[ETH_ALEN]; 3829 char *pos, *pos2; 3830 char *pin = NULL; 3831 enum p2p_wps_method wps_method; 3832 int new_pin; 3833 int ret; 3834 int persistent_group, persistent_id = -1; 3835 int join; 3836 int auth; 3837 int automatic; 3838 int go_intent = -1; 3839 int freq = 0; 3840 int pd; 3841 int ht40, vht; 3842 3843 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad] 3844 * [persistent|persistent=<network id>] 3845 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc] 3846 * [ht40] [vht] */ 3847 3848 if (hwaddr_aton(cmd, addr)) 3849 return -1; 3850 3851 pos = cmd + 17; 3852 if (*pos != ' ') 3853 return -1; 3854 pos++; 3855 3856 persistent_group = os_strstr(pos, " persistent") != NULL; 3857 pos2 = os_strstr(pos, " persistent="); 3858 if (pos2) { 3859 struct wpa_ssid *ssid; 3860 persistent_id = atoi(pos2 + 12); 3861 ssid = wpa_config_get_network(wpa_s->conf, persistent_id); 3862 if (ssid == NULL || ssid->disabled != 2 || 3863 ssid->mode != WPAS_MODE_P2P_GO) { 3864 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 3865 "SSID id=%d for persistent P2P group (GO)", 3866 persistent_id); 3867 return -1; 3868 } 3869 } 3870 join = os_strstr(pos, " join") != NULL; 3871 auth = os_strstr(pos, " auth") != NULL; 3872 automatic = os_strstr(pos, " auto") != NULL; 3873 pd = os_strstr(pos, " provdisc") != NULL; 3874 vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht; 3875 ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 || 3876 vht; 3877 3878 pos2 = os_strstr(pos, " go_intent="); 3879 if (pos2) { 3880 pos2 += 11; 3881 go_intent = atoi(pos2); 3882 if (go_intent < 0 || go_intent > 15) 3883 return -1; 3884 } 3885 3886 pos2 = os_strstr(pos, " freq="); 3887 if (pos2) { 3888 pos2 += 6; 3889 freq = atoi(pos2); 3890 if (freq <= 0) 3891 return -1; 3892 } 3893 3894 if (os_strncmp(pos, "pin", 3) == 0) { 3895 /* Request random PIN (to be displayed) and enable the PIN */ 3896 wps_method = WPS_PIN_DISPLAY; 3897 } else if (os_strncmp(pos, "pbc", 3) == 0) { 3898 wps_method = WPS_PBC; 3899 } else { 3900 pin = pos; 3901 pos = os_strchr(pin, ' '); 3902 wps_method = WPS_PIN_KEYPAD; 3903 if (pos) { 3904 *pos++ = '\0'; 3905 if (os_strncmp(pos, "display", 7) == 0) 3906 wps_method = WPS_PIN_DISPLAY; 3907 } 3908 if (!wps_pin_str_valid(pin)) { 3909 os_memcpy(buf, "FAIL-INVALID-PIN\n", 17); 3910 return 17; 3911 } 3912 } 3913 3914 new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method, 3915 persistent_group, automatic, join, 3916 auth, go_intent, freq, persistent_id, pd, 3917 ht40, vht); 3918 if (new_pin == -2) { 3919 os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25); 3920 return 25; 3921 } 3922 if (new_pin == -3) { 3923 os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25); 3924 return 25; 3925 } 3926 if (new_pin < 0) 3927 return -1; 3928 if (wps_method == WPS_PIN_DISPLAY && pin == NULL) { 3929 ret = os_snprintf(buf, buflen, "%08d", new_pin); 3930 if (ret < 0 || (size_t) ret >= buflen) 3931 return -1; 3932 return ret; 3933 } 3934 3935 os_memcpy(buf, "OK\n", 3); 3936 return 3; 3937 } 3938 3939 3940 static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd) 3941 { 3942 unsigned int timeout = atoi(cmd); 3943 return wpas_p2p_listen(wpa_s, timeout); 3944 } 3945 3946 3947 static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd) 3948 { 3949 u8 addr[ETH_ALEN]; 3950 char *pos; 3951 enum wpas_p2p_prov_disc_use use = WPAS_P2P_PD_FOR_GO_NEG; 3952 3953 /* <addr> <config method> [join|auto] */ 3954 3955 if (hwaddr_aton(cmd, addr)) 3956 return -1; 3957 3958 pos = cmd + 17; 3959 if (*pos != ' ') 3960 return -1; 3961 pos++; 3962 3963 if (os_strstr(pos, " join") != NULL) 3964 use = WPAS_P2P_PD_FOR_JOIN; 3965 else if (os_strstr(pos, " auto") != NULL) 3966 use = WPAS_P2P_PD_AUTO; 3967 3968 return wpas_p2p_prov_disc(wpa_s, addr, pos, use); 3969 } 3970 3971 3972 static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf, 3973 size_t buflen) 3974 { 3975 struct wpa_ssid *ssid = wpa_s->current_ssid; 3976 3977 if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 3978 ssid->passphrase == NULL) 3979 return -1; 3980 3981 os_strlcpy(buf, ssid->passphrase, buflen); 3982 return os_strlen(buf); 3983 } 3984 3985 3986 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd, 3987 char *buf, size_t buflen) 3988 { 3989 u64 ref; 3990 int res; 3991 u8 dst_buf[ETH_ALEN], *dst; 3992 struct wpabuf *tlvs; 3993 char *pos; 3994 size_t len; 3995 3996 if (hwaddr_aton(cmd, dst_buf)) 3997 return -1; 3998 dst = dst_buf; 3999 if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 && 4000 dst[3] == 0 && dst[4] == 0 && dst[5] == 0) 4001 dst = NULL; 4002 pos = cmd + 17; 4003 if (*pos != ' ') 4004 return -1; 4005 pos++; 4006 4007 if (os_strncmp(pos, "upnp ", 5) == 0) { 4008 u8 version; 4009 pos += 5; 4010 if (hexstr2bin(pos, &version, 1) < 0) 4011 return -1; 4012 pos += 2; 4013 if (*pos != ' ') 4014 return -1; 4015 pos++; 4016 ref = wpas_p2p_sd_request_upnp(wpa_s, dst, version, pos); 4017 #ifdef CONFIG_WIFI_DISPLAY 4018 } else if (os_strncmp(pos, "wifi-display ", 13) == 0) { 4019 ref = wpas_p2p_sd_request_wifi_display(wpa_s, dst, pos + 13); 4020 #endif /* CONFIG_WIFI_DISPLAY */ 4021 } else { 4022 len = os_strlen(pos); 4023 if (len & 1) 4024 return -1; 4025 len /= 2; 4026 tlvs = wpabuf_alloc(len); 4027 if (tlvs == NULL) 4028 return -1; 4029 if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) { 4030 wpabuf_free(tlvs); 4031 return -1; 4032 } 4033 4034 ref = wpas_p2p_sd_request(wpa_s, dst, tlvs); 4035 wpabuf_free(tlvs); 4036 } 4037 if (ref == 0) 4038 return -1; 4039 res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref); 4040 if (res < 0 || (unsigned) res >= buflen) 4041 return -1; 4042 return res; 4043 } 4044 4045 4046 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s, 4047 char *cmd) 4048 { 4049 long long unsigned val; 4050 u64 req; 4051 if (sscanf(cmd, "%llx", &val) != 1) 4052 return -1; 4053 req = val; 4054 return wpas_p2p_sd_cancel_request(wpa_s, req); 4055 } 4056 4057 4058 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd) 4059 { 4060 int freq; 4061 u8 dst[ETH_ALEN]; 4062 u8 dialog_token; 4063 struct wpabuf *resp_tlvs; 4064 char *pos, *pos2; 4065 size_t len; 4066 4067 pos = os_strchr(cmd, ' '); 4068 if (pos == NULL) 4069 return -1; 4070 *pos++ = '\0'; 4071 freq = atoi(cmd); 4072 if (freq == 0) 4073 return -1; 4074 4075 if (hwaddr_aton(pos, dst)) 4076 return -1; 4077 pos += 17; 4078 if (*pos != ' ') 4079 return -1; 4080 pos++; 4081 4082 pos2 = os_strchr(pos, ' '); 4083 if (pos2 == NULL) 4084 return -1; 4085 *pos2++ = '\0'; 4086 dialog_token = atoi(pos); 4087 4088 len = os_strlen(pos2); 4089 if (len & 1) 4090 return -1; 4091 len /= 2; 4092 resp_tlvs = wpabuf_alloc(len); 4093 if (resp_tlvs == NULL) 4094 return -1; 4095 if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) { 4096 wpabuf_free(resp_tlvs); 4097 return -1; 4098 } 4099 4100 wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs); 4101 wpabuf_free(resp_tlvs); 4102 return 0; 4103 } 4104 4105 4106 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s, 4107 char *cmd) 4108 { 4109 if (os_strcmp(cmd, "0") && os_strcmp(cmd, "1")) 4110 return -1; 4111 wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd); 4112 return 0; 4113 } 4114 4115 4116 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s, 4117 char *cmd) 4118 { 4119 char *pos; 4120 size_t len; 4121 struct wpabuf *query, *resp; 4122 4123 pos = os_strchr(cmd, ' '); 4124 if (pos == NULL) 4125 return -1; 4126 *pos++ = '\0'; 4127 4128 len = os_strlen(cmd); 4129 if (len & 1) 4130 return -1; 4131 len /= 2; 4132 query = wpabuf_alloc(len); 4133 if (query == NULL) 4134 return -1; 4135 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) { 4136 wpabuf_free(query); 4137 return -1; 4138 } 4139 4140 len = os_strlen(pos); 4141 if (len & 1) { 4142 wpabuf_free(query); 4143 return -1; 4144 } 4145 len /= 2; 4146 resp = wpabuf_alloc(len); 4147 if (resp == NULL) { 4148 wpabuf_free(query); 4149 return -1; 4150 } 4151 if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) { 4152 wpabuf_free(query); 4153 wpabuf_free(resp); 4154 return -1; 4155 } 4156 4157 if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) { 4158 wpabuf_free(query); 4159 wpabuf_free(resp); 4160 return -1; 4161 } 4162 return 0; 4163 } 4164 4165 4166 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd) 4167 { 4168 char *pos; 4169 u8 version; 4170 4171 pos = os_strchr(cmd, ' '); 4172 if (pos == NULL) 4173 return -1; 4174 *pos++ = '\0'; 4175 4176 if (hexstr2bin(cmd, &version, 1) < 0) 4177 return -1; 4178 4179 return wpas_p2p_service_add_upnp(wpa_s, version, pos); 4180 } 4181 4182 4183 static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd) 4184 { 4185 char *pos; 4186 4187 pos = os_strchr(cmd, ' '); 4188 if (pos == NULL) 4189 return -1; 4190 *pos++ = '\0'; 4191 4192 if (os_strcmp(cmd, "bonjour") == 0) 4193 return p2p_ctrl_service_add_bonjour(wpa_s, pos); 4194 if (os_strcmp(cmd, "upnp") == 0) 4195 return p2p_ctrl_service_add_upnp(wpa_s, pos); 4196 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd); 4197 return -1; 4198 } 4199 4200 4201 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s, 4202 char *cmd) 4203 { 4204 size_t len; 4205 struct wpabuf *query; 4206 int ret; 4207 4208 len = os_strlen(cmd); 4209 if (len & 1) 4210 return -1; 4211 len /= 2; 4212 query = wpabuf_alloc(len); 4213 if (query == NULL) 4214 return -1; 4215 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) { 4216 wpabuf_free(query); 4217 return -1; 4218 } 4219 4220 ret = wpas_p2p_service_del_bonjour(wpa_s, query); 4221 wpabuf_free(query); 4222 return ret; 4223 } 4224 4225 4226 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd) 4227 { 4228 char *pos; 4229 u8 version; 4230 4231 pos = os_strchr(cmd, ' '); 4232 if (pos == NULL) 4233 return -1; 4234 *pos++ = '\0'; 4235 4236 if (hexstr2bin(cmd, &version, 1) < 0) 4237 return -1; 4238 4239 return wpas_p2p_service_del_upnp(wpa_s, version, pos); 4240 } 4241 4242 4243 static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd) 4244 { 4245 char *pos; 4246 4247 pos = os_strchr(cmd, ' '); 4248 if (pos == NULL) 4249 return -1; 4250 *pos++ = '\0'; 4251 4252 if (os_strcmp(cmd, "bonjour") == 0) 4253 return p2p_ctrl_service_del_bonjour(wpa_s, pos); 4254 if (os_strcmp(cmd, "upnp") == 0) 4255 return p2p_ctrl_service_del_upnp(wpa_s, pos); 4256 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd); 4257 return -1; 4258 } 4259 4260 4261 static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd) 4262 { 4263 u8 addr[ETH_ALEN]; 4264 4265 /* <addr> */ 4266 4267 if (hwaddr_aton(cmd, addr)) 4268 return -1; 4269 4270 return wpas_p2p_reject(wpa_s, addr); 4271 } 4272 4273 4274 static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) 4275 { 4276 char *pos; 4277 int id; 4278 struct wpa_ssid *ssid; 4279 u8 *_peer = NULL, peer[ETH_ALEN]; 4280 int freq = 0, pref_freq = 0; 4281 int ht40, vht; 4282 4283 id = atoi(cmd); 4284 pos = os_strstr(cmd, " peer="); 4285 if (pos) { 4286 pos += 6; 4287 if (hwaddr_aton(pos, peer)) 4288 return -1; 4289 _peer = peer; 4290 } 4291 ssid = wpa_config_get_network(wpa_s->conf, id); 4292 if (ssid == NULL || ssid->disabled != 2) { 4293 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 4294 "for persistent P2P group", 4295 id); 4296 return -1; 4297 } 4298 4299 pos = os_strstr(cmd, " freq="); 4300 if (pos) { 4301 pos += 6; 4302 freq = atoi(pos); 4303 if (freq <= 0) 4304 return -1; 4305 } 4306 4307 pos = os_strstr(cmd, " pref="); 4308 if (pos) { 4309 pos += 6; 4310 pref_freq = atoi(pos); 4311 if (pref_freq <= 0) 4312 return -1; 4313 } 4314 4315 vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht; 4316 ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 || 4317 vht; 4318 4319 return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40, vht, 4320 pref_freq); 4321 } 4322 4323 4324 static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd) 4325 { 4326 char *pos; 4327 u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL; 4328 4329 pos = os_strstr(cmd, " peer="); 4330 if (!pos) 4331 return -1; 4332 4333 *pos = '\0'; 4334 pos += 6; 4335 if (hwaddr_aton(pos, peer)) { 4336 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos); 4337 return -1; 4338 } 4339 4340 pos = os_strstr(pos, " go_dev_addr="); 4341 if (pos) { 4342 pos += 13; 4343 if (hwaddr_aton(pos, go_dev_addr)) { 4344 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", 4345 pos); 4346 return -1; 4347 } 4348 go_dev = go_dev_addr; 4349 } 4350 4351 return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev); 4352 } 4353 4354 4355 static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd) 4356 { 4357 if (os_strncmp(cmd, "persistent=", 11) == 0) 4358 return p2p_ctrl_invite_persistent(wpa_s, cmd + 11); 4359 if (os_strncmp(cmd, "group=", 6) == 0) 4360 return p2p_ctrl_invite_group(wpa_s, cmd + 6); 4361 4362 return -1; 4363 } 4364 4365 4366 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s, 4367 char *cmd, int freq, int ht40, 4368 int vht) 4369 { 4370 int id; 4371 struct wpa_ssid *ssid; 4372 4373 id = atoi(cmd); 4374 ssid = wpa_config_get_network(wpa_s->conf, id); 4375 if (ssid == NULL || ssid->disabled != 2) { 4376 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 4377 "for persistent P2P group", 4378 id); 4379 return -1; 4380 } 4381 4382 return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, ht40, vht, 4383 NULL, 0); 4384 } 4385 4386 4387 static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) 4388 { 4389 int freq = 0, ht40, vht; 4390 char *pos; 4391 4392 pos = os_strstr(cmd, "freq="); 4393 if (pos) 4394 freq = atoi(pos + 5); 4395 4396 vht = (os_strstr(cmd, "vht") != NULL) || wpa_s->conf->p2p_go_vht; 4397 ht40 = (os_strstr(cmd, "ht40") != NULL) || wpa_s->conf->p2p_go_ht40 || 4398 vht; 4399 4400 if (os_strncmp(cmd, "persistent=", 11) == 0) 4401 return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq, 4402 ht40, vht); 4403 if (os_strcmp(cmd, "persistent") == 0 || 4404 os_strncmp(cmd, "persistent ", 11) == 0) 4405 return wpas_p2p_group_add(wpa_s, 1, freq, ht40, vht); 4406 if (os_strncmp(cmd, "freq=", 5) == 0) 4407 return wpas_p2p_group_add(wpa_s, 0, freq, ht40, vht); 4408 if (ht40) 4409 return wpas_p2p_group_add(wpa_s, 0, freq, ht40, vht); 4410 4411 wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'", 4412 cmd); 4413 return -1; 4414 } 4415 4416 4417 static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd, 4418 char *buf, size_t buflen) 4419 { 4420 u8 addr[ETH_ALEN], *addr_ptr; 4421 int next, res; 4422 const struct p2p_peer_info *info; 4423 char *pos, *end; 4424 char devtype[WPS_DEV_TYPE_BUFSIZE]; 4425 struct wpa_ssid *ssid; 4426 size_t i; 4427 4428 if (!wpa_s->global->p2p) 4429 return -1; 4430 4431 if (os_strcmp(cmd, "FIRST") == 0) { 4432 addr_ptr = NULL; 4433 next = 0; 4434 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { 4435 if (hwaddr_aton(cmd + 5, addr) < 0) 4436 return -1; 4437 addr_ptr = addr; 4438 next = 1; 4439 } else { 4440 if (hwaddr_aton(cmd, addr) < 0) 4441 return -1; 4442 addr_ptr = addr; 4443 next = 0; 4444 } 4445 4446 info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next); 4447 if (info == NULL) 4448 return -1; 4449 4450 pos = buf; 4451 end = buf + buflen; 4452 4453 res = os_snprintf(pos, end - pos, MACSTR "\n" 4454 "pri_dev_type=%s\n" 4455 "device_name=%s\n" 4456 "manufacturer=%s\n" 4457 "model_name=%s\n" 4458 "model_number=%s\n" 4459 "serial_number=%s\n" 4460 "config_methods=0x%x\n" 4461 "dev_capab=0x%x\n" 4462 "group_capab=0x%x\n" 4463 "level=%d\n", 4464 MAC2STR(info->p2p_device_addr), 4465 wps_dev_type_bin2str(info->pri_dev_type, 4466 devtype, sizeof(devtype)), 4467 info->device_name, 4468 info->manufacturer, 4469 info->model_name, 4470 info->model_number, 4471 info->serial_number, 4472 info->config_methods, 4473 info->dev_capab, 4474 info->group_capab, 4475 info->level); 4476 if (res < 0 || res >= end - pos) 4477 return pos - buf; 4478 pos += res; 4479 4480 for (i = 0; i < info->wps_sec_dev_type_list_len / WPS_DEV_TYPE_LEN; i++) 4481 { 4482 const u8 *t; 4483 t = &info->wps_sec_dev_type_list[i * WPS_DEV_TYPE_LEN]; 4484 res = os_snprintf(pos, end - pos, "sec_dev_type=%s\n", 4485 wps_dev_type_bin2str(t, devtype, 4486 sizeof(devtype))); 4487 if (res < 0 || res >= end - pos) 4488 return pos - buf; 4489 pos += res; 4490 } 4491 4492 ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr, NULL, 0); 4493 if (ssid) { 4494 res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id); 4495 if (res < 0 || res >= end - pos) 4496 return pos - buf; 4497 pos += res; 4498 } 4499 4500 res = p2p_get_peer_info_txt(info, pos, end - pos); 4501 if (res < 0) 4502 return pos - buf; 4503 pos += res; 4504 4505 return pos - buf; 4506 } 4507 4508 4509 static int p2p_ctrl_disallow_freq(struct wpa_supplicant *wpa_s, 4510 const char *param) 4511 { 4512 unsigned int i; 4513 4514 if (wpa_s->global->p2p == NULL) 4515 return -1; 4516 4517 if (freq_range_list_parse(&wpa_s->global->p2p_disallow_freq, param) < 0) 4518 return -1; 4519 4520 for (i = 0; i < wpa_s->global->p2p_disallow_freq.num; i++) { 4521 struct wpa_freq_range *freq; 4522 freq = &wpa_s->global->p2p_disallow_freq.range[i]; 4523 wpa_printf(MSG_DEBUG, "P2P: Disallowed frequency range %u-%u", 4524 freq->min, freq->max); 4525 } 4526 4527 wpas_p2p_update_channel_list(wpa_s); 4528 return 0; 4529 } 4530 4531 4532 static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd) 4533 { 4534 char *param; 4535 4536 if (wpa_s->global->p2p == NULL) 4537 return -1; 4538 4539 param = os_strchr(cmd, ' '); 4540 if (param == NULL) 4541 return -1; 4542 *param++ = '\0'; 4543 4544 if (os_strcmp(cmd, "discoverability") == 0) { 4545 p2p_set_client_discoverability(wpa_s->global->p2p, 4546 atoi(param)); 4547 return 0; 4548 } 4549 4550 if (os_strcmp(cmd, "managed") == 0) { 4551 p2p_set_managed_oper(wpa_s->global->p2p, atoi(param)); 4552 return 0; 4553 } 4554 4555 if (os_strcmp(cmd, "listen_channel") == 0) { 4556 return p2p_set_listen_channel(wpa_s->global->p2p, 81, 4557 atoi(param)); 4558 } 4559 4560 if (os_strcmp(cmd, "ssid_postfix") == 0) { 4561 return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param, 4562 os_strlen(param)); 4563 } 4564 4565 if (os_strcmp(cmd, "noa") == 0) { 4566 char *pos; 4567 int count, start, duration; 4568 /* GO NoA parameters: count,start_offset(ms),duration(ms) */ 4569 count = atoi(param); 4570 pos = os_strchr(param, ','); 4571 if (pos == NULL) 4572 return -1; 4573 pos++; 4574 start = atoi(pos); 4575 pos = os_strchr(pos, ','); 4576 if (pos == NULL) 4577 return -1; 4578 pos++; 4579 duration = atoi(pos); 4580 if (count < 0 || count > 255 || start < 0 || duration < 0) 4581 return -1; 4582 if (count == 0 && duration > 0) 4583 return -1; 4584 wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d " 4585 "start=%d duration=%d", count, start, duration); 4586 return wpas_p2p_set_noa(wpa_s, count, start, duration); 4587 } 4588 4589 if (os_strcmp(cmd, "ps") == 0) 4590 return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1); 4591 4592 if (os_strcmp(cmd, "oppps") == 0) 4593 return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1); 4594 4595 if (os_strcmp(cmd, "ctwindow") == 0) 4596 return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param)); 4597 4598 if (os_strcmp(cmd, "disabled") == 0) { 4599 wpa_s->global->p2p_disabled = atoi(param); 4600 wpa_printf(MSG_DEBUG, "P2P functionality %s", 4601 wpa_s->global->p2p_disabled ? 4602 "disabled" : "enabled"); 4603 if (wpa_s->global->p2p_disabled) { 4604 wpas_p2p_stop_find(wpa_s); 4605 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 4606 p2p_flush(wpa_s->global->p2p); 4607 } 4608 return 0; 4609 } 4610 4611 if (os_strcmp(cmd, "conc_pref") == 0) { 4612 if (os_strcmp(param, "sta") == 0) 4613 wpa_s->global->conc_pref = WPA_CONC_PREF_STA; 4614 else if (os_strcmp(param, "p2p") == 0) 4615 wpa_s->global->conc_pref = WPA_CONC_PREF_P2P; 4616 else { 4617 wpa_printf(MSG_INFO, "Invalid conc_pref value"); 4618 return -1; 4619 } 4620 wpa_printf(MSG_DEBUG, "Single channel concurrency preference: " 4621 "%s", param); 4622 return 0; 4623 } 4624 4625 if (os_strcmp(cmd, "force_long_sd") == 0) { 4626 wpa_s->force_long_sd = atoi(param); 4627 return 0; 4628 } 4629 4630 if (os_strcmp(cmd, "peer_filter") == 0) { 4631 u8 addr[ETH_ALEN]; 4632 if (hwaddr_aton(param, addr)) 4633 return -1; 4634 p2p_set_peer_filter(wpa_s->global->p2p, addr); 4635 return 0; 4636 } 4637 4638 if (os_strcmp(cmd, "cross_connect") == 0) 4639 return wpas_p2p_set_cross_connect(wpa_s, atoi(param)); 4640 4641 if (os_strcmp(cmd, "go_apsd") == 0) { 4642 if (os_strcmp(param, "disable") == 0) 4643 wpa_s->set_ap_uapsd = 0; 4644 else { 4645 wpa_s->set_ap_uapsd = 1; 4646 wpa_s->ap_uapsd = atoi(param); 4647 } 4648 return 0; 4649 } 4650 4651 if (os_strcmp(cmd, "client_apsd") == 0) { 4652 if (os_strcmp(param, "disable") == 0) 4653 wpa_s->set_sta_uapsd = 0; 4654 else { 4655 int be, bk, vi, vo; 4656 char *pos; 4657 /* format: BE,BK,VI,VO;max SP Length */ 4658 be = atoi(param); 4659 pos = os_strchr(param, ','); 4660 if (pos == NULL) 4661 return -1; 4662 pos++; 4663 bk = atoi(pos); 4664 pos = os_strchr(pos, ','); 4665 if (pos == NULL) 4666 return -1; 4667 pos++; 4668 vi = atoi(pos); 4669 pos = os_strchr(pos, ','); 4670 if (pos == NULL) 4671 return -1; 4672 pos++; 4673 vo = atoi(pos); 4674 /* ignore max SP Length for now */ 4675 4676 wpa_s->set_sta_uapsd = 1; 4677 wpa_s->sta_uapsd = 0; 4678 if (be) 4679 wpa_s->sta_uapsd |= BIT(0); 4680 if (bk) 4681 wpa_s->sta_uapsd |= BIT(1); 4682 if (vi) 4683 wpa_s->sta_uapsd |= BIT(2); 4684 if (vo) 4685 wpa_s->sta_uapsd |= BIT(3); 4686 } 4687 return 0; 4688 } 4689 4690 if (os_strcmp(cmd, "disallow_freq") == 0) 4691 return p2p_ctrl_disallow_freq(wpa_s, param); 4692 4693 if (os_strcmp(cmd, "disc_int") == 0) { 4694 int min_disc_int, max_disc_int, max_disc_tu; 4695 char *pos; 4696 4697 pos = param; 4698 4699 min_disc_int = atoi(pos); 4700 pos = os_strchr(pos, ' '); 4701 if (pos == NULL) 4702 return -1; 4703 *pos++ = '\0'; 4704 4705 max_disc_int = atoi(pos); 4706 pos = os_strchr(pos, ' '); 4707 if (pos == NULL) 4708 return -1; 4709 *pos++ = '\0'; 4710 4711 max_disc_tu = atoi(pos); 4712 4713 return p2p_set_disc_int(wpa_s->global->p2p, min_disc_int, 4714 max_disc_int, max_disc_tu); 4715 } 4716 4717 if (os_strcmp(cmd, "per_sta_psk") == 0) { 4718 wpa_s->global->p2p_per_sta_psk = !!atoi(param); 4719 return 0; 4720 } 4721 4722 #ifdef CONFIG_WPS_NFC 4723 if (os_strcmp(cmd, "nfc_tag") == 0) 4724 return wpas_p2p_nfc_tag_enabled(wpa_s, !!atoi(param)); 4725 #endif /* CONFIG_WPS_NFC */ 4726 4727 if (os_strcmp(cmd, "disable_ip_addr_req") == 0) { 4728 wpa_s->p2p_disable_ip_addr_req = !!atoi(param); 4729 return 0; 4730 } 4731 4732 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'", 4733 cmd); 4734 4735 return -1; 4736 } 4737 4738 4739 static void p2p_ctrl_flush(struct wpa_supplicant *wpa_s) 4740 { 4741 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 4742 wpa_s->force_long_sd = 0; 4743 if (wpa_s->global->p2p) 4744 p2p_flush(wpa_s->global->p2p); 4745 } 4746 4747 4748 static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd) 4749 { 4750 char *pos, *pos2; 4751 unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0; 4752 4753 if (cmd[0]) { 4754 pos = os_strchr(cmd, ' '); 4755 if (pos == NULL) 4756 return -1; 4757 *pos++ = '\0'; 4758 dur1 = atoi(cmd); 4759 4760 pos2 = os_strchr(pos, ' '); 4761 if (pos2) 4762 *pos2++ = '\0'; 4763 int1 = atoi(pos); 4764 } else 4765 pos2 = NULL; 4766 4767 if (pos2) { 4768 pos = os_strchr(pos2, ' '); 4769 if (pos == NULL) 4770 return -1; 4771 *pos++ = '\0'; 4772 dur2 = atoi(pos2); 4773 int2 = atoi(pos); 4774 } 4775 4776 return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2); 4777 } 4778 4779 4780 static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd) 4781 { 4782 char *pos; 4783 unsigned int period = 0, interval = 0; 4784 4785 if (cmd[0]) { 4786 pos = os_strchr(cmd, ' '); 4787 if (pos == NULL) 4788 return -1; 4789 *pos++ = '\0'; 4790 period = atoi(cmd); 4791 interval = atoi(pos); 4792 } 4793 4794 return wpas_p2p_ext_listen(wpa_s, period, interval); 4795 } 4796 4797 4798 static int p2p_ctrl_remove_client(struct wpa_supplicant *wpa_s, const char *cmd) 4799 { 4800 const char *pos; 4801 u8 peer[ETH_ALEN]; 4802 int iface_addr = 0; 4803 4804 pos = cmd; 4805 if (os_strncmp(pos, "iface=", 6) == 0) { 4806 iface_addr = 1; 4807 pos += 6; 4808 } 4809 if (hwaddr_aton(pos, peer)) 4810 return -1; 4811 4812 wpas_p2p_remove_client(wpa_s, peer, iface_addr); 4813 return 0; 4814 } 4815 4816 #endif /* CONFIG_P2P */ 4817 4818 4819 static int * freq_range_to_channel_list(struct wpa_supplicant *wpa_s, char *val) 4820 { 4821 struct wpa_freq_range_list ranges; 4822 int *freqs = NULL; 4823 struct hostapd_hw_modes *mode; 4824 u16 i; 4825 4826 if (wpa_s->hw.modes == NULL) 4827 return NULL; 4828 4829 os_memset(&ranges, 0, sizeof(ranges)); 4830 if (freq_range_list_parse(&ranges, val) < 0) 4831 return NULL; 4832 4833 for (i = 0; i < wpa_s->hw.num_modes; i++) { 4834 int j; 4835 4836 mode = &wpa_s->hw.modes[i]; 4837 for (j = 0; j < mode->num_channels; j++) { 4838 unsigned int freq; 4839 4840 if (mode->channels[j].flag & HOSTAPD_CHAN_DISABLED) 4841 continue; 4842 4843 freq = mode->channels[j].freq; 4844 if (!freq_range_list_includes(&ranges, freq)) 4845 continue; 4846 4847 int_array_add_unique(&freqs, freq); 4848 } 4849 } 4850 4851 os_free(ranges.range); 4852 return freqs; 4853 } 4854 4855 4856 #ifdef CONFIG_INTERWORKING 4857 4858 static int ctrl_interworking_select(struct wpa_supplicant *wpa_s, char *param) 4859 { 4860 int auto_sel = 0; 4861 int *freqs = NULL; 4862 4863 if (param) { 4864 char *pos; 4865 4866 auto_sel = os_strstr(param, "auto") != NULL; 4867 4868 pos = os_strstr(param, "freq="); 4869 if (pos) { 4870 freqs = freq_range_to_channel_list(wpa_s, pos + 5); 4871 if (freqs == NULL) 4872 return -1; 4873 } 4874 4875 } 4876 4877 return interworking_select(wpa_s, auto_sel, freqs); 4878 } 4879 4880 4881 static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst) 4882 { 4883 u8 bssid[ETH_ALEN]; 4884 struct wpa_bss *bss; 4885 4886 if (hwaddr_aton(dst, bssid)) { 4887 wpa_printf(MSG_DEBUG, "Invalid BSSID '%s'", dst); 4888 return -1; 4889 } 4890 4891 bss = wpa_bss_get_bssid(wpa_s, bssid); 4892 if (bss == NULL) { 4893 wpa_printf(MSG_DEBUG, "Could not find BSS " MACSTR, 4894 MAC2STR(bssid)); 4895 return -1; 4896 } 4897 4898 return interworking_connect(wpa_s, bss); 4899 } 4900 4901 4902 static int get_anqp(struct wpa_supplicant *wpa_s, char *dst) 4903 { 4904 u8 dst_addr[ETH_ALEN]; 4905 int used; 4906 char *pos; 4907 #define MAX_ANQP_INFO_ID 100 4908 u16 id[MAX_ANQP_INFO_ID]; 4909 size_t num_id = 0; 4910 4911 used = hwaddr_aton2(dst, dst_addr); 4912 if (used < 0) 4913 return -1; 4914 pos = dst + used; 4915 while (num_id < MAX_ANQP_INFO_ID) { 4916 id[num_id] = atoi(pos); 4917 if (id[num_id]) 4918 num_id++; 4919 pos = os_strchr(pos + 1, ','); 4920 if (pos == NULL) 4921 break; 4922 pos++; 4923 } 4924 4925 if (num_id == 0) 4926 return -1; 4927 4928 return anqp_send_req(wpa_s, dst_addr, id, num_id); 4929 } 4930 4931 4932 static int gas_request(struct wpa_supplicant *wpa_s, char *cmd) 4933 { 4934 u8 dst_addr[ETH_ALEN]; 4935 struct wpabuf *advproto, *query = NULL; 4936 int used, ret = -1; 4937 char *pos, *end; 4938 size_t len; 4939 4940 used = hwaddr_aton2(cmd, dst_addr); 4941 if (used < 0) 4942 return -1; 4943 4944 pos = cmd + used; 4945 while (*pos == ' ') 4946 pos++; 4947 4948 /* Advertisement Protocol ID */ 4949 end = os_strchr(pos, ' '); 4950 if (end) 4951 len = end - pos; 4952 else 4953 len = os_strlen(pos); 4954 if (len & 0x01) 4955 return -1; 4956 len /= 2; 4957 if (len == 0) 4958 return -1; 4959 advproto = wpabuf_alloc(len); 4960 if (advproto == NULL) 4961 return -1; 4962 if (hexstr2bin(pos, wpabuf_put(advproto, len), len) < 0) 4963 goto fail; 4964 4965 if (end) { 4966 /* Optional Query Request */ 4967 pos = end + 1; 4968 while (*pos == ' ') 4969 pos++; 4970 4971 len = os_strlen(pos); 4972 if (len) { 4973 if (len & 0x01) 4974 goto fail; 4975 len /= 2; 4976 if (len == 0) 4977 goto fail; 4978 query = wpabuf_alloc(len); 4979 if (query == NULL) 4980 goto fail; 4981 if (hexstr2bin(pos, wpabuf_put(query, len), len) < 0) 4982 goto fail; 4983 } 4984 } 4985 4986 ret = gas_send_request(wpa_s, dst_addr, advproto, query); 4987 4988 fail: 4989 wpabuf_free(advproto); 4990 wpabuf_free(query); 4991 4992 return ret; 4993 } 4994 4995 4996 static int gas_response_get(struct wpa_supplicant *wpa_s, char *cmd, char *buf, 4997 size_t buflen) 4998 { 4999 u8 addr[ETH_ALEN]; 5000 int dialog_token; 5001 int used; 5002 char *pos; 5003 size_t resp_len, start, requested_len; 5004 struct wpabuf *resp; 5005 int ret; 5006 5007 used = hwaddr_aton2(cmd, addr); 5008 if (used < 0) 5009 return -1; 5010 5011 pos = cmd + used; 5012 while (*pos == ' ') 5013 pos++; 5014 dialog_token = atoi(pos); 5015 5016 if (wpa_s->last_gas_resp && 5017 os_memcmp(addr, wpa_s->last_gas_addr, ETH_ALEN) == 0 && 5018 dialog_token == wpa_s->last_gas_dialog_token) 5019 resp = wpa_s->last_gas_resp; 5020 else if (wpa_s->prev_gas_resp && 5021 os_memcmp(addr, wpa_s->prev_gas_addr, ETH_ALEN) == 0 && 5022 dialog_token == wpa_s->prev_gas_dialog_token) 5023 resp = wpa_s->prev_gas_resp; 5024 else 5025 return -1; 5026 5027 resp_len = wpabuf_len(resp); 5028 start = 0; 5029 requested_len = resp_len; 5030 5031 pos = os_strchr(pos, ' '); 5032 if (pos) { 5033 start = atoi(pos); 5034 if (start > resp_len) 5035 return os_snprintf(buf, buflen, "FAIL-Invalid range"); 5036 pos = os_strchr(pos, ','); 5037 if (pos == NULL) 5038 return -1; 5039 pos++; 5040 requested_len = atoi(pos); 5041 if (start + requested_len > resp_len) 5042 return os_snprintf(buf, buflen, "FAIL-Invalid range"); 5043 } 5044 5045 if (requested_len * 2 + 1 > buflen) 5046 return os_snprintf(buf, buflen, "FAIL-Too long response"); 5047 5048 ret = wpa_snprintf_hex(buf, buflen, wpabuf_head_u8(resp) + start, 5049 requested_len); 5050 5051 if (start + requested_len == resp_len) { 5052 /* 5053 * Free memory by dropping the response after it has been 5054 * fetched. 5055 */ 5056 if (resp == wpa_s->prev_gas_resp) { 5057 wpabuf_free(wpa_s->prev_gas_resp); 5058 wpa_s->prev_gas_resp = NULL; 5059 } else { 5060 wpabuf_free(wpa_s->last_gas_resp); 5061 wpa_s->last_gas_resp = NULL; 5062 } 5063 } 5064 5065 return ret; 5066 } 5067 #endif /* CONFIG_INTERWORKING */ 5068 5069 5070 #ifdef CONFIG_HS20 5071 5072 static int get_hs20_anqp(struct wpa_supplicant *wpa_s, char *dst) 5073 { 5074 u8 dst_addr[ETH_ALEN]; 5075 int used; 5076 char *pos; 5077 u32 subtypes = 0; 5078 5079 used = hwaddr_aton2(dst, dst_addr); 5080 if (used < 0) 5081 return -1; 5082 pos = dst + used; 5083 for (;;) { 5084 int num = atoi(pos); 5085 if (num <= 0 || num > 31) 5086 return -1; 5087 subtypes |= BIT(num); 5088 pos = os_strchr(pos + 1, ','); 5089 if (pos == NULL) 5090 break; 5091 pos++; 5092 } 5093 5094 if (subtypes == 0) 5095 return -1; 5096 5097 return hs20_anqp_send_req(wpa_s, dst_addr, subtypes, NULL, 0); 5098 } 5099 5100 5101 static int hs20_nai_home_realm_list(struct wpa_supplicant *wpa_s, 5102 const u8 *addr, const char *realm) 5103 { 5104 u8 *buf; 5105 size_t rlen, len; 5106 int ret; 5107 5108 rlen = os_strlen(realm); 5109 len = 3 + rlen; 5110 buf = os_malloc(len); 5111 if (buf == NULL) 5112 return -1; 5113 buf[0] = 1; /* NAI Home Realm Count */ 5114 buf[1] = 0; /* Formatted in accordance with RFC 4282 */ 5115 buf[2] = rlen; 5116 os_memcpy(buf + 3, realm, rlen); 5117 5118 ret = hs20_anqp_send_req(wpa_s, addr, 5119 BIT(HS20_STYPE_NAI_HOME_REALM_QUERY), 5120 buf, len); 5121 5122 os_free(buf); 5123 5124 return ret; 5125 } 5126 5127 5128 static int hs20_get_nai_home_realm_list(struct wpa_supplicant *wpa_s, 5129 char *dst) 5130 { 5131 struct wpa_cred *cred = wpa_s->conf->cred; 5132 u8 dst_addr[ETH_ALEN]; 5133 int used; 5134 u8 *buf; 5135 size_t len; 5136 int ret; 5137 5138 used = hwaddr_aton2(dst, dst_addr); 5139 if (used < 0) 5140 return -1; 5141 5142 while (dst[used] == ' ') 5143 used++; 5144 if (os_strncmp(dst + used, "realm=", 6) == 0) 5145 return hs20_nai_home_realm_list(wpa_s, dst_addr, 5146 dst + used + 6); 5147 5148 len = os_strlen(dst + used); 5149 5150 if (len == 0 && cred && cred->realm) 5151 return hs20_nai_home_realm_list(wpa_s, dst_addr, cred->realm); 5152 5153 if (len % 1) 5154 return -1; 5155 len /= 2; 5156 buf = os_malloc(len); 5157 if (buf == NULL) 5158 return -1; 5159 if (hexstr2bin(dst + used, buf, len) < 0) { 5160 os_free(buf); 5161 return -1; 5162 } 5163 5164 ret = hs20_anqp_send_req(wpa_s, dst_addr, 5165 BIT(HS20_STYPE_NAI_HOME_REALM_QUERY), 5166 buf, len); 5167 os_free(buf); 5168 5169 return ret; 5170 } 5171 5172 #endif /* CONFIG_HS20 */ 5173 5174 5175 static int wpa_supplicant_ctrl_iface_sta_autoconnect( 5176 struct wpa_supplicant *wpa_s, char *cmd) 5177 { 5178 wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0; 5179 return 0; 5180 } 5181 5182 5183 #ifdef CONFIG_AUTOSCAN 5184 5185 static int wpa_supplicant_ctrl_iface_autoscan(struct wpa_supplicant *wpa_s, 5186 char *cmd) 5187 { 5188 enum wpa_states state = wpa_s->wpa_state; 5189 char *new_params = NULL; 5190 5191 if (os_strlen(cmd) > 0) { 5192 new_params = os_strdup(cmd); 5193 if (new_params == NULL) 5194 return -1; 5195 } 5196 5197 os_free(wpa_s->conf->autoscan); 5198 wpa_s->conf->autoscan = new_params; 5199 5200 if (wpa_s->conf->autoscan == NULL) 5201 autoscan_deinit(wpa_s); 5202 else if (state == WPA_DISCONNECTED || state == WPA_INACTIVE) 5203 autoscan_init(wpa_s, 1); 5204 else if (state == WPA_SCANNING) 5205 wpa_supplicant_reinit_autoscan(wpa_s); 5206 5207 return 0; 5208 } 5209 5210 #endif /* CONFIG_AUTOSCAN */ 5211 5212 5213 #ifdef CONFIG_WNM 5214 5215 static int wpas_ctrl_iface_wnm_sleep(struct wpa_supplicant *wpa_s, char *cmd) 5216 { 5217 int enter; 5218 int intval = 0; 5219 char *pos; 5220 int ret; 5221 struct wpabuf *tfs_req = NULL; 5222 5223 if (os_strncmp(cmd, "enter", 5) == 0) 5224 enter = 1; 5225 else if (os_strncmp(cmd, "exit", 4) == 0) 5226 enter = 0; 5227 else 5228 return -1; 5229 5230 pos = os_strstr(cmd, " interval="); 5231 if (pos) 5232 intval = atoi(pos + 10); 5233 5234 pos = os_strstr(cmd, " tfs_req="); 5235 if (pos) { 5236 char *end; 5237 size_t len; 5238 pos += 9; 5239 end = os_strchr(pos, ' '); 5240 if (end) 5241 len = end - pos; 5242 else 5243 len = os_strlen(pos); 5244 if (len & 1) 5245 return -1; 5246 len /= 2; 5247 tfs_req = wpabuf_alloc(len); 5248 if (tfs_req == NULL) 5249 return -1; 5250 if (hexstr2bin(pos, wpabuf_put(tfs_req, len), len) < 0) { 5251 wpabuf_free(tfs_req); 5252 return -1; 5253 } 5254 } 5255 5256 ret = ieee802_11_send_wnmsleep_req(wpa_s, enter ? WNM_SLEEP_MODE_ENTER : 5257 WNM_SLEEP_MODE_EXIT, intval, 5258 tfs_req); 5259 wpabuf_free(tfs_req); 5260 5261 return ret; 5262 } 5263 5264 5265 static int wpas_ctrl_iface_wnm_bss_query(struct wpa_supplicant *wpa_s, char *cmd) 5266 { 5267 int query_reason; 5268 5269 query_reason = atoi(cmd); 5270 5271 wpa_printf(MSG_DEBUG, "CTRL_IFACE: WNM_BSS_QUERY query_reason=%d", 5272 query_reason); 5273 5274 return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason); 5275 } 5276 5277 #endif /* CONFIG_WNM */ 5278 5279 5280 /* Get string representation of channel width */ 5281 static const char * channel_width_name(enum chan_width width) 5282 { 5283 switch (width) { 5284 case CHAN_WIDTH_20_NOHT: 5285 return "20 MHz (no HT)"; 5286 case CHAN_WIDTH_20: 5287 return "20 MHz"; 5288 case CHAN_WIDTH_40: 5289 return "40 MHz"; 5290 case CHAN_WIDTH_80: 5291 return "80 MHz"; 5292 case CHAN_WIDTH_80P80: 5293 return "80+80 MHz"; 5294 case CHAN_WIDTH_160: 5295 return "160 MHz"; 5296 default: 5297 return "unknown"; 5298 } 5299 } 5300 5301 5302 static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf, 5303 size_t buflen) 5304 { 5305 struct wpa_signal_info si; 5306 int ret; 5307 char *pos, *end; 5308 5309 ret = wpa_drv_signal_poll(wpa_s, &si); 5310 if (ret) 5311 return -1; 5312 5313 pos = buf; 5314 end = buf + buflen; 5315 5316 ret = os_snprintf(pos, end - pos, "RSSI=%d\nLINKSPEED=%d\n" 5317 "NOISE=%d\nFREQUENCY=%u\n", 5318 si.current_signal, si.current_txrate / 1000, 5319 si.current_noise, si.frequency); 5320 if (ret < 0 || ret > end - pos) 5321 return -1; 5322 pos += ret; 5323 5324 if (si.chanwidth != CHAN_WIDTH_UNKNOWN) { 5325 ret = os_snprintf(pos, end - pos, "WIDTH=%s\n", 5326 channel_width_name(si.chanwidth)); 5327 if (ret < 0 || ret > end - pos) 5328 return -1; 5329 pos += ret; 5330 } 5331 5332 if (si.center_frq1 > 0 && si.center_frq2 > 0) { 5333 ret = os_snprintf(pos, end - pos, 5334 "CENTER_FRQ1=%d\nCENTER_FRQ2=%d\n", 5335 si.center_frq1, si.center_frq2); 5336 if (ret < 0 || ret > end - pos) 5337 return -1; 5338 pos += ret; 5339 } 5340 5341 if (si.avg_signal) { 5342 ret = os_snprintf(pos, end - pos, 5343 "AVG_RSSI=%d\n", si.avg_signal); 5344 if (ret < 0 || ret >= end - pos) 5345 return -1; 5346 pos += ret; 5347 } 5348 5349 return pos - buf; 5350 } 5351 5352 5353 static int wpa_supplicant_pktcnt_poll(struct wpa_supplicant *wpa_s, char *buf, 5354 size_t buflen) 5355 { 5356 struct hostap_sta_driver_data sta; 5357 int ret; 5358 5359 ret = wpa_drv_pktcnt_poll(wpa_s, &sta); 5360 if (ret) 5361 return -1; 5362 5363 ret = os_snprintf(buf, buflen, "TXGOOD=%lu\nTXBAD=%lu\nRXGOOD=%lu\n", 5364 sta.tx_packets, sta.tx_retry_failed, sta.rx_packets); 5365 if (ret < 0 || (size_t) ret > buflen) 5366 return -1; 5367 return ret; 5368 } 5369 5370 5371 #ifdef ANDROID 5372 static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd, 5373 char *buf, size_t buflen) 5374 { 5375 int ret; 5376 5377 ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen); 5378 if (ret == 0) { 5379 if (os_strncasecmp(cmd, "COUNTRY", 7) == 0) { 5380 struct p2p_data *p2p = wpa_s->global->p2p; 5381 if (p2p) { 5382 char country[3]; 5383 country[0] = cmd[8]; 5384 country[1] = cmd[9]; 5385 country[2] = 0x04; 5386 p2p_set_country(p2p, country); 5387 } 5388 } 5389 ret = os_snprintf(buf, buflen, "%s\n", "OK"); 5390 } 5391 return ret; 5392 } 5393 #endif /* ANDROID */ 5394 5395 5396 static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) 5397 { 5398 wpa_dbg(wpa_s, MSG_DEBUG, "Flush all wpa_supplicant state"); 5399 5400 #ifdef CONFIG_P2P 5401 wpas_p2p_stop_find(wpa_s); 5402 p2p_ctrl_flush(wpa_s); 5403 wpas_p2p_group_remove(wpa_s, "*"); 5404 wpas_p2p_service_flush(wpa_s); 5405 wpa_s->global->p2p_disabled = 0; 5406 wpa_s->global->p2p_per_sta_psk = 0; 5407 wpa_s->conf->num_sec_device_types = 0; 5408 wpa_s->p2p_disable_ip_addr_req = 0; 5409 #endif /* CONFIG_P2P */ 5410 5411 #ifdef CONFIG_WPS_TESTING 5412 wps_version_number = 0x20; 5413 wps_testing_dummy_cred = 0; 5414 wps_corrupt_pkhash = 0; 5415 #endif /* CONFIG_WPS_TESTING */ 5416 #ifdef CONFIG_WPS 5417 wpa_s->wps_fragment_size = 0; 5418 wpas_wps_cancel(wpa_s); 5419 #endif /* CONFIG_WPS */ 5420 wpa_s->after_wps = 0; 5421 wpa_s->known_wps_freq = 0; 5422 5423 #ifdef CONFIG_TDLS 5424 #ifdef CONFIG_TDLS_TESTING 5425 extern unsigned int tdls_testing; 5426 tdls_testing = 0; 5427 #endif /* CONFIG_TDLS_TESTING */ 5428 wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL); 5429 wpa_tdls_enable(wpa_s->wpa, 1); 5430 #endif /* CONFIG_TDLS */ 5431 5432 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL); 5433 wpa_supplicant_stop_countermeasures(wpa_s, NULL); 5434 5435 wpa_s->no_keep_alive = 0; 5436 5437 os_free(wpa_s->disallow_aps_bssid); 5438 wpa_s->disallow_aps_bssid = NULL; 5439 wpa_s->disallow_aps_bssid_count = 0; 5440 os_free(wpa_s->disallow_aps_ssid); 5441 wpa_s->disallow_aps_ssid = NULL; 5442 wpa_s->disallow_aps_ssid_count = 0; 5443 5444 wpa_s->set_sta_uapsd = 0; 5445 wpa_s->sta_uapsd = 0; 5446 5447 wpa_drv_radio_disable(wpa_s, 0); 5448 5449 wpa_bss_flush(wpa_s); 5450 wpa_blacklist_clear(wpa_s); 5451 wpa_s->extra_blacklist_count = 0; 5452 wpa_supplicant_ctrl_iface_remove_network(wpa_s, "all"); 5453 wpa_supplicant_ctrl_iface_remove_cred(wpa_s, "all"); 5454 wpa_config_flush_blobs(wpa_s->conf); 5455 wpa_s->conf->auto_interworking = 0; 5456 wpa_s->conf->okc = 0; 5457 wpa_s->conf->pmf = 0; 5458 5459 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME, 43200); 5460 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD, 70); 5461 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, 60); 5462 eapol_sm_notify_logoff(wpa_s->eapol, FALSE); 5463 5464 radio_remove_unstarted_work(wpa_s, NULL); 5465 } 5466 5467 5468 static int wpas_ctrl_radio_work_show(struct wpa_supplicant *wpa_s, 5469 char *buf, size_t buflen) 5470 { 5471 struct wpa_radio_work *work; 5472 char *pos, *end; 5473 struct os_reltime now, diff; 5474 5475 pos = buf; 5476 end = buf + buflen; 5477 5478 os_get_reltime(&now); 5479 5480 dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list) 5481 { 5482 int ret; 5483 5484 os_reltime_sub(&now, &work->time, &diff); 5485 ret = os_snprintf(pos, end - pos, "%s@%s:%u:%u:%ld.%06ld\n", 5486 work->type, work->wpa_s->ifname, work->freq, 5487 work->started, diff.sec, diff.usec); 5488 if (ret < 0 || ret >= end - pos) 5489 break; 5490 pos += ret; 5491 } 5492 5493 return pos - buf; 5494 } 5495 5496 5497 static void wpas_ctrl_radio_work_timeout(void *eloop_ctx, void *timeout_ctx) 5498 { 5499 struct wpa_radio_work *work = eloop_ctx; 5500 struct wpa_external_work *ework = work->ctx; 5501 5502 wpa_dbg(work->wpa_s, MSG_DEBUG, 5503 "Timing out external radio work %u (%s)", 5504 ework->id, work->type); 5505 wpa_msg(work->wpa_s, MSG_INFO, EXT_RADIO_WORK_TIMEOUT "%u", ework->id); 5506 os_free(ework); 5507 radio_work_done(work); 5508 } 5509 5510 5511 static void wpas_ctrl_radio_work_cb(struct wpa_radio_work *work, int deinit) 5512 { 5513 struct wpa_external_work *ework = work->ctx; 5514 5515 if (deinit) { 5516 os_free(ework); 5517 return; 5518 } 5519 5520 wpa_dbg(work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)", 5521 ework->id, ework->type); 5522 wpa_msg(work->wpa_s, MSG_INFO, EXT_RADIO_WORK_START "%u", ework->id); 5523 if (!ework->timeout) 5524 ework->timeout = 10; 5525 eloop_register_timeout(ework->timeout, 0, wpas_ctrl_radio_work_timeout, 5526 work, NULL); 5527 } 5528 5529 5530 static int wpas_ctrl_radio_work_add(struct wpa_supplicant *wpa_s, char *cmd, 5531 char *buf, size_t buflen) 5532 { 5533 struct wpa_external_work *ework; 5534 char *pos, *pos2; 5535 size_t type_len; 5536 int ret; 5537 unsigned int freq = 0; 5538 5539 /* format: <name> [freq=<MHz>] [timeout=<seconds>] */ 5540 5541 ework = os_zalloc(sizeof(*ework)); 5542 if (ework == NULL) 5543 return -1; 5544 5545 pos = os_strchr(cmd, ' '); 5546 if (pos) { 5547 type_len = pos - cmd; 5548 pos++; 5549 5550 pos2 = os_strstr(pos, "freq="); 5551 if (pos2) 5552 freq = atoi(pos2 + 5); 5553 5554 pos2 = os_strstr(pos, "timeout="); 5555 if (pos2) 5556 ework->timeout = atoi(pos2 + 8); 5557 } else { 5558 type_len = os_strlen(cmd); 5559 } 5560 if (4 + type_len >= sizeof(ework->type)) 5561 type_len = sizeof(ework->type) - 4 - 1; 5562 os_strlcpy(ework->type, "ext:", sizeof(ework->type)); 5563 os_memcpy(ework->type + 4, cmd, type_len); 5564 ework->type[4 + type_len] = '\0'; 5565 5566 wpa_s->ext_work_id++; 5567 if (wpa_s->ext_work_id == 0) 5568 wpa_s->ext_work_id++; 5569 ework->id = wpa_s->ext_work_id; 5570 5571 if (radio_add_work(wpa_s, freq, ework->type, 0, wpas_ctrl_radio_work_cb, 5572 ework) < 0) { 5573 os_free(ework); 5574 return -1; 5575 } 5576 5577 ret = os_snprintf(buf, buflen, "%u", ework->id); 5578 if (ret < 0 || (size_t) ret >= buflen) 5579 return -1; 5580 return ret; 5581 } 5582 5583 5584 static int wpas_ctrl_radio_work_done(struct wpa_supplicant *wpa_s, char *cmd) 5585 { 5586 struct wpa_radio_work *work; 5587 unsigned int id = atoi(cmd); 5588 5589 dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list) 5590 { 5591 struct wpa_external_work *ework; 5592 5593 if (os_strncmp(work->type, "ext:", 4) != 0) 5594 continue; 5595 ework = work->ctx; 5596 if (id && ework->id != id) 5597 continue; 5598 wpa_dbg(wpa_s, MSG_DEBUG, 5599 "Completed external radio work %u (%s)", 5600 ework->id, ework->type); 5601 eloop_cancel_timeout(wpas_ctrl_radio_work_timeout, work, NULL); 5602 os_free(ework); 5603 radio_work_done(work); 5604 return 3; /* "OK\n" */ 5605 } 5606 5607 return -1; 5608 } 5609 5610 5611 static int wpas_ctrl_radio_work(struct wpa_supplicant *wpa_s, char *cmd, 5612 char *buf, size_t buflen) 5613 { 5614 if (os_strcmp(cmd, "show") == 0) 5615 return wpas_ctrl_radio_work_show(wpa_s, buf, buflen); 5616 if (os_strncmp(cmd, "add ", 4) == 0) 5617 return wpas_ctrl_radio_work_add(wpa_s, cmd + 4, buf, buflen); 5618 if (os_strncmp(cmd, "done ", 5) == 0) 5619 return wpas_ctrl_radio_work_done(wpa_s, cmd + 4); 5620 return -1; 5621 } 5622 5623 5624 void wpas_ctrl_radio_work_flush(struct wpa_supplicant *wpa_s) 5625 { 5626 struct wpa_radio_work *work, *tmp; 5627 5628 if (!wpa_s || !wpa_s->radio) 5629 return; 5630 5631 dl_list_for_each_safe(work, tmp, &wpa_s->radio->work, 5632 struct wpa_radio_work, list) { 5633 struct wpa_external_work *ework; 5634 5635 if (os_strncmp(work->type, "ext:", 4) != 0) 5636 continue; 5637 ework = work->ctx; 5638 wpa_dbg(wpa_s, MSG_DEBUG, 5639 "Flushing %sexternal radio work %u (%s)", 5640 work->started ? " started" : "", ework->id, 5641 ework->type); 5642 if (work->started) 5643 eloop_cancel_timeout(wpas_ctrl_radio_work_timeout, 5644 work, NULL); 5645 os_free(ework); 5646 radio_work_done(work); 5647 } 5648 } 5649 5650 5651 static void wpas_ctrl_eapol_response(void *eloop_ctx, void *timeout_ctx) 5652 { 5653 struct wpa_supplicant *wpa_s = eloop_ctx; 5654 eapol_sm_notify_ctrl_response(wpa_s->eapol); 5655 } 5656 5657 5658 static int set_scan_freqs(struct wpa_supplicant *wpa_s, char *val) 5659 { 5660 int *freqs = NULL; 5661 5662 freqs = freq_range_to_channel_list(wpa_s, val); 5663 if (freqs == NULL) 5664 return -1; 5665 5666 os_free(wpa_s->manual_scan_freqs); 5667 wpa_s->manual_scan_freqs = freqs; 5668 5669 return 0; 5670 } 5671 5672 5673 static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params, 5674 char *reply, int reply_size, int *reply_len) 5675 { 5676 char *pos; 5677 5678 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 5679 *reply_len = -1; 5680 return; 5681 } 5682 5683 wpa_s->manual_scan_passive = 0; 5684 wpa_s->manual_scan_use_id = 0; 5685 wpa_s->manual_scan_only_new = 0; 5686 5687 if (params) { 5688 if (os_strncasecmp(params, "TYPE=ONLY", 9) == 0) 5689 wpa_s->scan_res_handler = scan_only_handler; 5690 5691 pos = os_strstr(params, "freq="); 5692 if (pos && set_scan_freqs(wpa_s, pos + 5) < 0) { 5693 *reply_len = -1; 5694 return; 5695 } 5696 5697 pos = os_strstr(params, "passive="); 5698 if (pos) 5699 wpa_s->manual_scan_passive = !!atoi(pos + 8); 5700 5701 pos = os_strstr(params, "use_id="); 5702 if (pos) 5703 wpa_s->manual_scan_use_id = atoi(pos + 7); 5704 5705 pos = os_strstr(params, "only_new=1"); 5706 if (pos) 5707 wpa_s->manual_scan_only_new = 1; 5708 } else { 5709 os_free(wpa_s->manual_scan_freqs); 5710 wpa_s->manual_scan_freqs = NULL; 5711 if (wpa_s->scan_res_handler == scan_only_handler) 5712 wpa_s->scan_res_handler = NULL; 5713 } 5714 5715 if (!wpa_s->sched_scanning && !wpa_s->scanning && 5716 ((wpa_s->wpa_state <= WPA_SCANNING) || 5717 (wpa_s->wpa_state == WPA_COMPLETED))) { 5718 wpa_s->normal_scans = 0; 5719 wpa_s->scan_req = MANUAL_SCAN_REQ; 5720 wpa_s->after_wps = 0; 5721 wpa_s->known_wps_freq = 0; 5722 wpa_supplicant_req_scan(wpa_s, 0, 0); 5723 if (wpa_s->manual_scan_use_id) { 5724 wpa_s->manual_scan_id++; 5725 wpa_dbg(wpa_s, MSG_DEBUG, "Assigned scan id %u", 5726 wpa_s->manual_scan_id); 5727 *reply_len = os_snprintf(reply, reply_size, "%u\n", 5728 wpa_s->manual_scan_id); 5729 } 5730 } else if (wpa_s->sched_scanning) { 5731 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to allow requested full scan to proceed"); 5732 wpa_supplicant_cancel_sched_scan(wpa_s); 5733 wpa_s->scan_req = MANUAL_SCAN_REQ; 5734 wpa_supplicant_req_scan(wpa_s, 0, 0); 5735 if (wpa_s->manual_scan_use_id) { 5736 wpa_s->manual_scan_id++; 5737 *reply_len = os_snprintf(reply, reply_size, "%u\n", 5738 wpa_s->manual_scan_id); 5739 wpa_dbg(wpa_s, MSG_DEBUG, "Assigned scan id %u", 5740 wpa_s->manual_scan_id); 5741 } 5742 } else { 5743 wpa_printf(MSG_DEBUG, "Ongoing scan action - reject new request"); 5744 *reply_len = os_snprintf(reply, reply_size, "FAIL-BUSY\n"); 5745 } 5746 } 5747 5748 5749 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, 5750 char *buf, size_t *resp_len) 5751 { 5752 char *reply; 5753 const int reply_size = 4096; 5754 int reply_len; 5755 5756 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 || 5757 os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 5758 if (wpa_debug_show_keys) 5759 wpa_dbg(wpa_s, MSG_DEBUG, 5760 "Control interface command '%s'", buf); 5761 else 5762 wpa_dbg(wpa_s, MSG_DEBUG, 5763 "Control interface command '%s [REMOVED]'", 5764 os_strncmp(buf, WPA_CTRL_RSP, 5765 os_strlen(WPA_CTRL_RSP)) == 0 ? 5766 WPA_CTRL_RSP : "SET_NETWORK"); 5767 } else if (os_strncmp(buf, "WPS_NFC_TAG_READ", 16) == 0 || 5768 os_strncmp(buf, "NFC_REPORT_HANDOVER", 19) == 0 || 5769 os_strncmp(buf, "NFC_RX_HANDOVER_SEL", 19) == 0) { 5770 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface", 5771 (const u8 *) buf, os_strlen(buf)); 5772 } else { 5773 int level = MSG_DEBUG; 5774 if (os_strcmp(buf, "PING") == 0) 5775 level = MSG_EXCESSIVE; 5776 wpa_dbg(wpa_s, level, "Control interface command '%s'", buf); 5777 } 5778 5779 reply = os_malloc(reply_size); 5780 if (reply == NULL) { 5781 *resp_len = 1; 5782 return NULL; 5783 } 5784 5785 os_memcpy(reply, "OK\n", 3); 5786 reply_len = 3; 5787 5788 if (os_strcmp(buf, "PING") == 0) { 5789 os_memcpy(reply, "PONG\n", 5); 5790 reply_len = 5; 5791 } else if (os_strcmp(buf, "IFNAME") == 0) { 5792 reply_len = os_strlen(wpa_s->ifname); 5793 os_memcpy(reply, wpa_s->ifname, reply_len); 5794 } else if (os_strncmp(buf, "RELOG", 5) == 0) { 5795 if (wpa_debug_reopen_file() < 0) 5796 reply_len = -1; 5797 } else if (os_strncmp(buf, "NOTE ", 5) == 0) { 5798 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); 5799 } else if (os_strcmp(buf, "MIB") == 0) { 5800 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); 5801 if (reply_len >= 0) { 5802 int res; 5803 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len, 5804 reply_size - reply_len); 5805 if (res < 0) 5806 reply_len = -1; 5807 else 5808 reply_len += res; 5809 } 5810 } else if (os_strncmp(buf, "STATUS", 6) == 0) { 5811 reply_len = wpa_supplicant_ctrl_iface_status( 5812 wpa_s, buf + 6, reply, reply_size); 5813 } else if (os_strcmp(buf, "PMKSA") == 0) { 5814 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply, 5815 reply_size); 5816 } else if (os_strncmp(buf, "SET ", 4) == 0) { 5817 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) 5818 reply_len = -1; 5819 } else if (os_strncmp(buf, "GET ", 4) == 0) { 5820 reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4, 5821 reply, reply_size); 5822 } else if (os_strcmp(buf, "LOGON") == 0) { 5823 eapol_sm_notify_logoff(wpa_s->eapol, FALSE); 5824 } else if (os_strcmp(buf, "LOGOFF") == 0) { 5825 eapol_sm_notify_logoff(wpa_s->eapol, TRUE); 5826 } else if (os_strcmp(buf, "REASSOCIATE") == 0) { 5827 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 5828 reply_len = -1; 5829 else 5830 wpas_request_connection(wpa_s); 5831 } else if (os_strcmp(buf, "RECONNECT") == 0) { 5832 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 5833 reply_len = -1; 5834 else if (wpa_s->disconnected) 5835 wpas_request_connection(wpa_s); 5836 #ifdef IEEE8021X_EAPOL 5837 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) { 5838 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8)) 5839 reply_len = -1; 5840 #endif /* IEEE8021X_EAPOL */ 5841 #ifdef CONFIG_PEERKEY 5842 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) { 5843 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9)) 5844 reply_len = -1; 5845 #endif /* CONFIG_PEERKEY */ 5846 #ifdef CONFIG_IEEE80211R 5847 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) { 5848 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6)) 5849 reply_len = -1; 5850 #endif /* CONFIG_IEEE80211R */ 5851 #ifdef CONFIG_WPS 5852 } else if (os_strcmp(buf, "WPS_PBC") == 0) { 5853 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL); 5854 if (res == -2) { 5855 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 5856 reply_len = 17; 5857 } else if (res) 5858 reply_len = -1; 5859 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) { 5860 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8); 5861 if (res == -2) { 5862 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 5863 reply_len = 17; 5864 } else if (res) 5865 reply_len = -1; 5866 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) { 5867 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8, 5868 reply, 5869 reply_size); 5870 } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) { 5871 reply_len = wpa_supplicant_ctrl_iface_wps_check_pin( 5872 wpa_s, buf + 14, reply, reply_size); 5873 } else if (os_strcmp(buf, "WPS_CANCEL") == 0) { 5874 if (wpas_wps_cancel(wpa_s)) 5875 reply_len = -1; 5876 #ifdef CONFIG_WPS_NFC 5877 } else if (os_strcmp(buf, "WPS_NFC") == 0) { 5878 if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, NULL)) 5879 reply_len = -1; 5880 } else if (os_strncmp(buf, "WPS_NFC ", 8) == 0) { 5881 if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, buf + 8)) 5882 reply_len = -1; 5883 } else if (os_strncmp(buf, "WPS_NFC_CONFIG_TOKEN ", 21) == 0) { 5884 reply_len = wpa_supplicant_ctrl_iface_wps_nfc_config_token( 5885 wpa_s, buf + 21, reply, reply_size); 5886 } else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) { 5887 reply_len = wpa_supplicant_ctrl_iface_wps_nfc_token( 5888 wpa_s, buf + 14, reply, reply_size); 5889 } else if (os_strncmp(buf, "WPS_NFC_TAG_READ ", 17) == 0) { 5890 if (wpa_supplicant_ctrl_iface_wps_nfc_tag_read(wpa_s, 5891 buf + 17)) 5892 reply_len = -1; 5893 } else if (os_strncmp(buf, "NFC_GET_HANDOVER_REQ ", 21) == 0) { 5894 reply_len = wpas_ctrl_nfc_get_handover_req( 5895 wpa_s, buf + 21, reply, reply_size); 5896 } else if (os_strncmp(buf, "NFC_GET_HANDOVER_SEL ", 21) == 0) { 5897 reply_len = wpas_ctrl_nfc_get_handover_sel( 5898 wpa_s, buf + 21, reply, reply_size); 5899 } else if (os_strncmp(buf, "NFC_RX_HANDOVER_REQ ", 20) == 0) { 5900 reply_len = wpas_ctrl_nfc_rx_handover_req( 5901 wpa_s, buf + 20, reply, reply_size); 5902 } else if (os_strncmp(buf, "NFC_RX_HANDOVER_SEL ", 20) == 0) { 5903 if (wpas_ctrl_nfc_rx_handover_sel(wpa_s, buf + 20)) 5904 reply_len = -1; 5905 } else if (os_strncmp(buf, "NFC_REPORT_HANDOVER ", 20) == 0) { 5906 if (wpas_ctrl_nfc_report_handover(wpa_s, buf + 20)) 5907 reply_len = -1; 5908 #endif /* CONFIG_WPS_NFC */ 5909 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) { 5910 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8)) 5911 reply_len = -1; 5912 #ifdef CONFIG_AP 5913 } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) { 5914 reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin( 5915 wpa_s, buf + 11, reply, reply_size); 5916 #endif /* CONFIG_AP */ 5917 #ifdef CONFIG_WPS_ER 5918 } else if (os_strcmp(buf, "WPS_ER_START") == 0) { 5919 if (wpas_wps_er_start(wpa_s, NULL)) 5920 reply_len = -1; 5921 } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) { 5922 if (wpas_wps_er_start(wpa_s, buf + 13)) 5923 reply_len = -1; 5924 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) { 5925 if (wpas_wps_er_stop(wpa_s)) 5926 reply_len = -1; 5927 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) { 5928 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11)) 5929 reply_len = -1; 5930 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) { 5931 int ret = wpas_wps_er_pbc(wpa_s, buf + 11); 5932 if (ret == -2) { 5933 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 5934 reply_len = 17; 5935 } else if (ret == -3) { 5936 os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18); 5937 reply_len = 18; 5938 } else if (ret == -4) { 5939 os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20); 5940 reply_len = 20; 5941 } else if (ret) 5942 reply_len = -1; 5943 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) { 5944 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13)) 5945 reply_len = -1; 5946 } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) { 5947 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s, 5948 buf + 18)) 5949 reply_len = -1; 5950 } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) { 5951 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14)) 5952 reply_len = -1; 5953 #ifdef CONFIG_WPS_NFC 5954 } else if (os_strncmp(buf, "WPS_ER_NFC_CONFIG_TOKEN ", 24) == 0) { 5955 reply_len = wpa_supplicant_ctrl_iface_wps_er_nfc_config_token( 5956 wpa_s, buf + 24, reply, reply_size); 5957 #endif /* CONFIG_WPS_NFC */ 5958 #endif /* CONFIG_WPS_ER */ 5959 #endif /* CONFIG_WPS */ 5960 #ifdef CONFIG_IBSS_RSN 5961 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) { 5962 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9)) 5963 reply_len = -1; 5964 #endif /* CONFIG_IBSS_RSN */ 5965 #ifdef CONFIG_P2P 5966 } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) { 5967 if (p2p_ctrl_find(wpa_s, buf + 9)) 5968 reply_len = -1; 5969 } else if (os_strcmp(buf, "P2P_FIND") == 0) { 5970 if (p2p_ctrl_find(wpa_s, "")) 5971 reply_len = -1; 5972 } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) { 5973 wpas_p2p_stop_find(wpa_s); 5974 } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) { 5975 reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply, 5976 reply_size); 5977 } else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) { 5978 if (p2p_ctrl_listen(wpa_s, buf + 11)) 5979 reply_len = -1; 5980 } else if (os_strcmp(buf, "P2P_LISTEN") == 0) { 5981 if (p2p_ctrl_listen(wpa_s, "")) 5982 reply_len = -1; 5983 } else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) { 5984 if (wpas_p2p_group_remove(wpa_s, buf + 17)) 5985 reply_len = -1; 5986 } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) { 5987 if (wpas_p2p_group_add(wpa_s, 0, 0, 0, 0)) 5988 reply_len = -1; 5989 } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) { 5990 if (p2p_ctrl_group_add(wpa_s, buf + 14)) 5991 reply_len = -1; 5992 } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) { 5993 if (p2p_ctrl_prov_disc(wpa_s, buf + 14)) 5994 reply_len = -1; 5995 } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) { 5996 reply_len = p2p_get_passphrase(wpa_s, reply, reply_size); 5997 } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) { 5998 reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply, 5999 reply_size); 6000 } else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) { 6001 if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0) 6002 reply_len = -1; 6003 } else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) { 6004 if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0) 6005 reply_len = -1; 6006 } else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) { 6007 wpas_p2p_sd_service_update(wpa_s); 6008 } else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) { 6009 if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0) 6010 reply_len = -1; 6011 } else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) { 6012 wpas_p2p_service_flush(wpa_s); 6013 } else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) { 6014 if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0) 6015 reply_len = -1; 6016 } else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) { 6017 if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0) 6018 reply_len = -1; 6019 } else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) { 6020 if (p2p_ctrl_reject(wpa_s, buf + 11) < 0) 6021 reply_len = -1; 6022 } else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) { 6023 if (p2p_ctrl_invite(wpa_s, buf + 11) < 0) 6024 reply_len = -1; 6025 } else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) { 6026 reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply, 6027 reply_size); 6028 } else if (os_strncmp(buf, "P2P_SET ", 8) == 0) { 6029 if (p2p_ctrl_set(wpa_s, buf + 8) < 0) 6030 reply_len = -1; 6031 } else if (os_strcmp(buf, "P2P_FLUSH") == 0) { 6032 p2p_ctrl_flush(wpa_s); 6033 } else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) { 6034 if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0) 6035 reply_len = -1; 6036 } else if (os_strcmp(buf, "P2P_CANCEL") == 0) { 6037 if (wpas_p2p_cancel(wpa_s)) 6038 reply_len = -1; 6039 } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) { 6040 if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0) 6041 reply_len = -1; 6042 } else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) { 6043 if (p2p_ctrl_presence_req(wpa_s, "") < 0) 6044 reply_len = -1; 6045 } else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) { 6046 if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0) 6047 reply_len = -1; 6048 } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) { 6049 if (p2p_ctrl_ext_listen(wpa_s, "") < 0) 6050 reply_len = -1; 6051 } else if (os_strncmp(buf, "P2P_REMOVE_CLIENT ", 18) == 0) { 6052 if (p2p_ctrl_remove_client(wpa_s, buf + 18) < 0) 6053 reply_len = -1; 6054 #endif /* CONFIG_P2P */ 6055 #ifdef CONFIG_WIFI_DISPLAY 6056 } else if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0) { 6057 if (wifi_display_subelem_set(wpa_s->global, buf + 16) < 0) 6058 reply_len = -1; 6059 } else if (os_strncmp(buf, "WFD_SUBELEM_GET ", 16) == 0) { 6060 reply_len = wifi_display_subelem_get(wpa_s->global, buf + 16, 6061 reply, reply_size); 6062 #endif /* CONFIG_WIFI_DISPLAY */ 6063 #ifdef CONFIG_INTERWORKING 6064 } else if (os_strcmp(buf, "FETCH_ANQP") == 0) { 6065 if (interworking_fetch_anqp(wpa_s) < 0) 6066 reply_len = -1; 6067 } else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) { 6068 interworking_stop_fetch_anqp(wpa_s); 6069 } else if (os_strcmp(buf, "INTERWORKING_SELECT") == 0) { 6070 if (ctrl_interworking_select(wpa_s, NULL) < 0) 6071 reply_len = -1; 6072 } else if (os_strncmp(buf, "INTERWORKING_SELECT ", 20) == 0) { 6073 if (ctrl_interworking_select(wpa_s, buf + 20) < 0) 6074 reply_len = -1; 6075 } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) { 6076 if (ctrl_interworking_connect(wpa_s, buf + 21) < 0) 6077 reply_len = -1; 6078 } else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) { 6079 if (get_anqp(wpa_s, buf + 9) < 0) 6080 reply_len = -1; 6081 } else if (os_strncmp(buf, "GAS_REQUEST ", 12) == 0) { 6082 if (gas_request(wpa_s, buf + 12) < 0) 6083 reply_len = -1; 6084 } else if (os_strncmp(buf, "GAS_RESPONSE_GET ", 17) == 0) { 6085 reply_len = gas_response_get(wpa_s, buf + 17, reply, 6086 reply_size); 6087 #endif /* CONFIG_INTERWORKING */ 6088 #ifdef CONFIG_HS20 6089 } else if (os_strncmp(buf, "HS20_ANQP_GET ", 14) == 0) { 6090 if (get_hs20_anqp(wpa_s, buf + 14) < 0) 6091 reply_len = -1; 6092 } else if (os_strncmp(buf, "HS20_GET_NAI_HOME_REALM_LIST ", 29) == 0) { 6093 if (hs20_get_nai_home_realm_list(wpa_s, buf + 29) < 0) 6094 reply_len = -1; 6095 #endif /* CONFIG_HS20 */ 6096 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0) 6097 { 6098 if (wpa_supplicant_ctrl_iface_ctrl_rsp( 6099 wpa_s, buf + os_strlen(WPA_CTRL_RSP))) 6100 reply_len = -1; 6101 else { 6102 /* 6103 * Notify response from timeout to allow the control 6104 * interface response to be sent first. 6105 */ 6106 eloop_register_timeout(0, 0, wpas_ctrl_eapol_response, 6107 wpa_s, NULL); 6108 } 6109 } else if (os_strcmp(buf, "RECONFIGURE") == 0) { 6110 if (wpa_supplicant_reload_configuration(wpa_s)) 6111 reply_len = -1; 6112 } else if (os_strcmp(buf, "TERMINATE") == 0) { 6113 wpa_supplicant_terminate_proc(wpa_s->global); 6114 } else if (os_strncmp(buf, "BSSID ", 6) == 0) { 6115 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) 6116 reply_len = -1; 6117 } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) { 6118 reply_len = wpa_supplicant_ctrl_iface_blacklist( 6119 wpa_s, buf + 9, reply, reply_size); 6120 } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) { 6121 reply_len = wpa_supplicant_ctrl_iface_log_level( 6122 wpa_s, buf + 9, reply, reply_size); 6123 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) { 6124 reply_len = wpa_supplicant_ctrl_iface_list_networks( 6125 wpa_s, reply, reply_size); 6126 } else if (os_strcmp(buf, "DISCONNECT") == 0) { 6127 #ifdef CONFIG_SME 6128 wpa_s->sme.prev_bssid_set = 0; 6129 #endif /* CONFIG_SME */ 6130 wpa_s->reassociate = 0; 6131 wpa_s->disconnected = 1; 6132 wpa_supplicant_cancel_sched_scan(wpa_s); 6133 wpa_supplicant_cancel_scan(wpa_s); 6134 wpa_supplicant_deauthenticate(wpa_s, 6135 WLAN_REASON_DEAUTH_LEAVING); 6136 } else if (os_strcmp(buf, "SCAN") == 0) { 6137 wpas_ctrl_scan(wpa_s, NULL, reply, reply_size, &reply_len); 6138 } else if (os_strncmp(buf, "SCAN ", 5) == 0) { 6139 wpas_ctrl_scan(wpa_s, buf + 5, reply, reply_size, &reply_len); 6140 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) { 6141 reply_len = wpa_supplicant_ctrl_iface_scan_results( 6142 wpa_s, reply, reply_size); 6143 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) { 6144 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15)) 6145 reply_len = -1; 6146 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) { 6147 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15)) 6148 reply_len = -1; 6149 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) { 6150 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16)) 6151 reply_len = -1; 6152 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) { 6153 reply_len = wpa_supplicant_ctrl_iface_add_network( 6154 wpa_s, reply, reply_size); 6155 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) { 6156 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15)) 6157 reply_len = -1; 6158 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 6159 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12)) 6160 reply_len = -1; 6161 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) { 6162 reply_len = wpa_supplicant_ctrl_iface_get_network( 6163 wpa_s, buf + 12, reply, reply_size); 6164 } else if (os_strcmp(buf, "LIST_CREDS") == 0) { 6165 reply_len = wpa_supplicant_ctrl_iface_list_creds( 6166 wpa_s, reply, reply_size); 6167 } else if (os_strcmp(buf, "ADD_CRED") == 0) { 6168 reply_len = wpa_supplicant_ctrl_iface_add_cred( 6169 wpa_s, reply, reply_size); 6170 } else if (os_strncmp(buf, "REMOVE_CRED ", 12) == 0) { 6171 if (wpa_supplicant_ctrl_iface_remove_cred(wpa_s, buf + 12)) 6172 reply_len = -1; 6173 } else if (os_strncmp(buf, "SET_CRED ", 9) == 0) { 6174 if (wpa_supplicant_ctrl_iface_set_cred(wpa_s, buf + 9)) 6175 reply_len = -1; 6176 #ifndef CONFIG_NO_CONFIG_WRITE 6177 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) { 6178 if (wpa_supplicant_ctrl_iface_save_config(wpa_s)) 6179 reply_len = -1; 6180 #endif /* CONFIG_NO_CONFIG_WRITE */ 6181 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) { 6182 reply_len = wpa_supplicant_ctrl_iface_get_capability( 6183 wpa_s, buf + 15, reply, reply_size); 6184 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) { 6185 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8)) 6186 reply_len = -1; 6187 } else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) { 6188 if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s, buf + 14)) 6189 reply_len = -1; 6190 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 6191 reply_len = wpa_supplicant_global_iface_list( 6192 wpa_s->global, reply, reply_size); 6193 } else if (os_strcmp(buf, "INTERFACES") == 0) { 6194 reply_len = wpa_supplicant_global_iface_interfaces( 6195 wpa_s->global, reply, reply_size); 6196 } else if (os_strncmp(buf, "BSS ", 4) == 0) { 6197 reply_len = wpa_supplicant_ctrl_iface_bss( 6198 wpa_s, buf + 4, reply, reply_size); 6199 #ifdef CONFIG_AP 6200 } else if (os_strcmp(buf, "STA-FIRST") == 0) { 6201 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); 6202 } else if (os_strncmp(buf, "STA ", 4) == 0) { 6203 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply, 6204 reply_size); 6205 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { 6206 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, 6207 reply_size); 6208 } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) { 6209 if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15)) 6210 reply_len = -1; 6211 } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) { 6212 if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13)) 6213 reply_len = -1; 6214 } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) { 6215 if (ap_ctrl_iface_chanswitch(wpa_s, buf + 12)) 6216 reply_len = -1; 6217 #endif /* CONFIG_AP */ 6218 } else if (os_strcmp(buf, "SUSPEND") == 0) { 6219 wpas_notify_suspend(wpa_s->global); 6220 } else if (os_strcmp(buf, "RESUME") == 0) { 6221 wpas_notify_resume(wpa_s->global); 6222 } else if (os_strcmp(buf, "DROP_SA") == 0) { 6223 wpa_supplicant_ctrl_iface_drop_sa(wpa_s); 6224 } else if (os_strncmp(buf, "ROAM ", 5) == 0) { 6225 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5)) 6226 reply_len = -1; 6227 } else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) { 6228 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16)) 6229 reply_len = -1; 6230 } else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) { 6231 if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15)) 6232 reply_len = -1; 6233 } else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) { 6234 if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s, 6235 buf + 17)) 6236 reply_len = -1; 6237 } else if (os_strncmp(buf, "BSS_FLUSH ", 10) == 0) { 6238 if (wpa_supplicant_ctrl_iface_bss_flush(wpa_s, buf + 10)) 6239 reply_len = -1; 6240 #ifdef CONFIG_TDLS 6241 } else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) { 6242 if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14)) 6243 reply_len = -1; 6244 } else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) { 6245 if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11)) 6246 reply_len = -1; 6247 } else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) { 6248 if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14)) 6249 reply_len = -1; 6250 #endif /* CONFIG_TDLS */ 6251 } else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) { 6252 reply_len = wpa_supplicant_signal_poll(wpa_s, reply, 6253 reply_size); 6254 } else if (os_strncmp(buf, "PKTCNT_POLL", 11) == 0) { 6255 reply_len = wpa_supplicant_pktcnt_poll(wpa_s, reply, 6256 reply_size); 6257 #ifdef CONFIG_AUTOSCAN 6258 } else if (os_strncmp(buf, "AUTOSCAN ", 9) == 0) { 6259 if (wpa_supplicant_ctrl_iface_autoscan(wpa_s, buf + 9)) 6260 reply_len = -1; 6261 #endif /* CONFIG_AUTOSCAN */ 6262 #ifdef ANDROID 6263 } else if (os_strncmp(buf, "DRIVER ", 7) == 0) { 6264 reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply, 6265 reply_size); 6266 #endif /* ANDROID */ 6267 } else if (os_strcmp(buf, "REAUTHENTICATE") == 0) { 6268 pmksa_cache_clear_current(wpa_s->wpa); 6269 eapol_sm_request_reauth(wpa_s->eapol); 6270 #ifdef CONFIG_WNM 6271 } else if (os_strncmp(buf, "WNM_SLEEP ", 10) == 0) { 6272 if (wpas_ctrl_iface_wnm_sleep(wpa_s, buf + 10)) 6273 reply_len = -1; 6274 } else if (os_strncmp(buf, "WNM_BSS_QUERY ", 10) == 0) { 6275 if (wpas_ctrl_iface_wnm_bss_query(wpa_s, buf + 10)) 6276 reply_len = -1; 6277 #endif /* CONFIG_WNM */ 6278 } else if (os_strcmp(buf, "FLUSH") == 0) { 6279 wpa_supplicant_ctrl_iface_flush(wpa_s); 6280 } else if (os_strncmp(buf, "RADIO_WORK ", 11) == 0) { 6281 reply_len = wpas_ctrl_radio_work(wpa_s, buf + 11, reply, 6282 reply_size); 6283 } else { 6284 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 6285 reply_len = 16; 6286 } 6287 6288 if (reply_len < 0) { 6289 os_memcpy(reply, "FAIL\n", 5); 6290 reply_len = 5; 6291 } 6292 6293 *resp_len = reply_len; 6294 return reply; 6295 } 6296 6297 6298 static int wpa_supplicant_global_iface_add(struct wpa_global *global, 6299 char *cmd) 6300 { 6301 struct wpa_interface iface; 6302 char *pos; 6303 6304 /* 6305 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param> 6306 * TAB<bridge_ifname> 6307 */ 6308 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd); 6309 6310 os_memset(&iface, 0, sizeof(iface)); 6311 6312 do { 6313 iface.ifname = pos = cmd; 6314 pos = os_strchr(pos, '\t'); 6315 if (pos) 6316 *pos++ = '\0'; 6317 if (iface.ifname[0] == '\0') 6318 return -1; 6319 if (pos == NULL) 6320 break; 6321 6322 iface.confname = pos; 6323 pos = os_strchr(pos, '\t'); 6324 if (pos) 6325 *pos++ = '\0'; 6326 if (iface.confname[0] == '\0') 6327 iface.confname = NULL; 6328 if (pos == NULL) 6329 break; 6330 6331 iface.driver = pos; 6332 pos = os_strchr(pos, '\t'); 6333 if (pos) 6334 *pos++ = '\0'; 6335 if (iface.driver[0] == '\0') 6336 iface.driver = NULL; 6337 if (pos == NULL) 6338 break; 6339 6340 iface.ctrl_interface = pos; 6341 pos = os_strchr(pos, '\t'); 6342 if (pos) 6343 *pos++ = '\0'; 6344 if (iface.ctrl_interface[0] == '\0') 6345 iface.ctrl_interface = NULL; 6346 if (pos == NULL) 6347 break; 6348 6349 iface.driver_param = pos; 6350 pos = os_strchr(pos, '\t'); 6351 if (pos) 6352 *pos++ = '\0'; 6353 if (iface.driver_param[0] == '\0') 6354 iface.driver_param = NULL; 6355 if (pos == NULL) 6356 break; 6357 6358 iface.bridge_ifname = pos; 6359 pos = os_strchr(pos, '\t'); 6360 if (pos) 6361 *pos++ = '\0'; 6362 if (iface.bridge_ifname[0] == '\0') 6363 iface.bridge_ifname = NULL; 6364 if (pos == NULL) 6365 break; 6366 } while (0); 6367 6368 if (wpa_supplicant_get_iface(global, iface.ifname)) 6369 return -1; 6370 6371 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1; 6372 } 6373 6374 6375 static int wpa_supplicant_global_iface_remove(struct wpa_global *global, 6376 char *cmd) 6377 { 6378 struct wpa_supplicant *wpa_s; 6379 6380 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd); 6381 6382 wpa_s = wpa_supplicant_get_iface(global, cmd); 6383 if (wpa_s == NULL) 6384 return -1; 6385 return wpa_supplicant_remove_iface(global, wpa_s, 0); 6386 } 6387 6388 6389 static void wpa_free_iface_info(struct wpa_interface_info *iface) 6390 { 6391 struct wpa_interface_info *prev; 6392 6393 while (iface) { 6394 prev = iface; 6395 iface = iface->next; 6396 6397 os_free(prev->ifname); 6398 os_free(prev->desc); 6399 os_free(prev); 6400 } 6401 } 6402 6403 6404 static int wpa_supplicant_global_iface_list(struct wpa_global *global, 6405 char *buf, int len) 6406 { 6407 int i, res; 6408 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp; 6409 char *pos, *end; 6410 6411 for (i = 0; wpa_drivers[i]; i++) { 6412 struct wpa_driver_ops *drv = wpa_drivers[i]; 6413 if (drv->get_interfaces == NULL) 6414 continue; 6415 tmp = drv->get_interfaces(global->drv_priv[i]); 6416 if (tmp == NULL) 6417 continue; 6418 6419 if (last == NULL) 6420 iface = last = tmp; 6421 else 6422 last->next = tmp; 6423 while (last->next) 6424 last = last->next; 6425 } 6426 6427 pos = buf; 6428 end = buf + len; 6429 for (tmp = iface; tmp; tmp = tmp->next) { 6430 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n", 6431 tmp->drv_name, tmp->ifname, 6432 tmp->desc ? tmp->desc : ""); 6433 if (res < 0 || res >= end - pos) { 6434 *pos = '\0'; 6435 break; 6436 } 6437 pos += res; 6438 } 6439 6440 wpa_free_iface_info(iface); 6441 6442 return pos - buf; 6443 } 6444 6445 6446 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 6447 char *buf, int len) 6448 { 6449 int res; 6450 char *pos, *end; 6451 struct wpa_supplicant *wpa_s; 6452 6453 wpa_s = global->ifaces; 6454 pos = buf; 6455 end = buf + len; 6456 6457 while (wpa_s) { 6458 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname); 6459 if (res < 0 || res >= end - pos) { 6460 *pos = '\0'; 6461 break; 6462 } 6463 pos += res; 6464 wpa_s = wpa_s->next; 6465 } 6466 return pos - buf; 6467 } 6468 6469 6470 static char * wpas_global_ctrl_iface_ifname(struct wpa_global *global, 6471 const char *ifname, 6472 char *cmd, size_t *resp_len) 6473 { 6474 struct wpa_supplicant *wpa_s; 6475 6476 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 6477 if (os_strcmp(ifname, wpa_s->ifname) == 0) 6478 break; 6479 } 6480 6481 if (wpa_s == NULL) { 6482 char *resp = os_strdup("FAIL-NO-IFNAME-MATCH\n"); 6483 if (resp) 6484 *resp_len = os_strlen(resp); 6485 else 6486 *resp_len = 1; 6487 return resp; 6488 } 6489 6490 return wpa_supplicant_ctrl_iface_process(wpa_s, cmd, resp_len); 6491 } 6492 6493 6494 static char * wpas_global_ctrl_iface_redir_p2p(struct wpa_global *global, 6495 char *buf, size_t *resp_len) 6496 { 6497 #ifdef CONFIG_P2P 6498 static const char * cmd[] = { 6499 "LIST_NETWORKS", 6500 "SAVE_CONFIG", 6501 "P2P_FIND", 6502 "P2P_STOP_FIND", 6503 "P2P_LISTEN", 6504 "P2P_GROUP_ADD", 6505 "P2P_GET_PASSPHRASE", 6506 "P2P_SERVICE_UPDATE", 6507 "P2P_SERVICE_FLUSH", 6508 "P2P_FLUSH", 6509 "P2P_CANCEL", 6510 "P2P_PRESENCE_REQ", 6511 "P2P_EXT_LISTEN", 6512 NULL 6513 }; 6514 static const char * prefix[] = { 6515 #ifdef ANDROID 6516 "DRIVER ", 6517 #endif /* ANDROID */ 6518 "GET_NETWORK ", 6519 "REMOVE_NETWORK ", 6520 "SET ", 6521 "P2P_FIND ", 6522 "P2P_CONNECT ", 6523 "P2P_LISTEN ", 6524 "P2P_GROUP_REMOVE ", 6525 "P2P_GROUP_ADD ", 6526 "P2P_PROV_DISC ", 6527 "P2P_SERV_DISC_REQ ", 6528 "P2P_SERV_DISC_CANCEL_REQ ", 6529 "P2P_SERV_DISC_RESP ", 6530 "P2P_SERV_DISC_EXTERNAL ", 6531 "P2P_SERVICE_ADD ", 6532 "P2P_SERVICE_DEL ", 6533 "P2P_REJECT ", 6534 "P2P_INVITE ", 6535 "P2P_PEER ", 6536 "P2P_SET ", 6537 "P2P_UNAUTHORIZE ", 6538 "P2P_PRESENCE_REQ ", 6539 "P2P_EXT_LISTEN ", 6540 "P2P_REMOVE_CLIENT ", 6541 NULL 6542 }; 6543 int found = 0; 6544 int i; 6545 6546 if (global->p2p_init_wpa_s == NULL) 6547 return NULL; 6548 6549 for (i = 0; !found && cmd[i]; i++) { 6550 if (os_strcmp(buf, cmd[i]) == 0) 6551 found = 1; 6552 } 6553 6554 for (i = 0; !found && prefix[i]; i++) { 6555 if (os_strncmp(buf, prefix[i], os_strlen(prefix[i])) == 0) 6556 found = 1; 6557 } 6558 6559 if (found) 6560 return wpa_supplicant_ctrl_iface_process(global->p2p_init_wpa_s, 6561 buf, resp_len); 6562 #endif /* CONFIG_P2P */ 6563 return NULL; 6564 } 6565 6566 6567 static char * wpas_global_ctrl_iface_redir_wfd(struct wpa_global *global, 6568 char *buf, size_t *resp_len) 6569 { 6570 #ifdef CONFIG_WIFI_DISPLAY 6571 if (global->p2p_init_wpa_s == NULL) 6572 return NULL; 6573 if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0 || 6574 os_strncmp(buf, "WFD_SUBELEM_GET ", 16) == 0) 6575 return wpa_supplicant_ctrl_iface_process(global->p2p_init_wpa_s, 6576 buf, resp_len); 6577 #endif /* CONFIG_WIFI_DISPLAY */ 6578 return NULL; 6579 } 6580 6581 6582 static char * wpas_global_ctrl_iface_redir(struct wpa_global *global, 6583 char *buf, size_t *resp_len) 6584 { 6585 char *ret; 6586 6587 ret = wpas_global_ctrl_iface_redir_p2p(global, buf, resp_len); 6588 if (ret) 6589 return ret; 6590 6591 ret = wpas_global_ctrl_iface_redir_wfd(global, buf, resp_len); 6592 if (ret) 6593 return ret; 6594 6595 return NULL; 6596 } 6597 6598 6599 static int wpas_global_ctrl_iface_set(struct wpa_global *global, char *cmd) 6600 { 6601 char *value; 6602 6603 value = os_strchr(cmd, ' '); 6604 if (value == NULL) 6605 return -1; 6606 *value++ = '\0'; 6607 6608 wpa_printf(MSG_DEBUG, "GLOBAL_CTRL_IFACE SET '%s'='%s'", cmd, value); 6609 6610 #ifdef CONFIG_WIFI_DISPLAY 6611 if (os_strcasecmp(cmd, "wifi_display") == 0) { 6612 wifi_display_enable(global, !!atoi(value)); 6613 return 0; 6614 } 6615 #endif /* CONFIG_WIFI_DISPLAY */ 6616 6617 return -1; 6618 } 6619 6620 6621 #ifndef CONFIG_NO_CONFIG_WRITE 6622 static int wpas_global_ctrl_iface_save_config(struct wpa_global *global) 6623 { 6624 int ret = 0; 6625 struct wpa_supplicant *wpa_s; 6626 6627 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 6628 if (!wpa_s->conf->update_config) { 6629 wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed to update configuration (update_config=0)"); 6630 continue; 6631 } 6632 6633 if (wpa_config_write(wpa_s->confname, wpa_s->conf)) { 6634 wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to update configuration"); 6635 ret = 1; 6636 } else { 6637 wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration updated"); 6638 } 6639 } 6640 6641 return ret; 6642 } 6643 #endif /* CONFIG_NO_CONFIG_WRITE */ 6644 6645 6646 static int wpas_global_ctrl_iface_status(struct wpa_global *global, 6647 char *buf, size_t buflen) 6648 { 6649 char *pos, *end; 6650 int ret; 6651 struct wpa_supplicant *wpa_s; 6652 6653 pos = buf; 6654 end = buf + buflen; 6655 6656 #ifdef CONFIG_P2P 6657 if (global->p2p && !global->p2p_disabled) { 6658 ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR 6659 "\n" 6660 "p2p_state=%s\n", 6661 MAC2STR(global->p2p_dev_addr), 6662 p2p_get_state_txt(global->p2p)); 6663 if (ret < 0 || ret >= end - pos) 6664 return pos - buf; 6665 pos += ret; 6666 } else if (global->p2p) { 6667 ret = os_snprintf(pos, end - pos, "p2p_state=DISABLED\n"); 6668 if (ret < 0 || ret >= end - pos) 6669 return pos - buf; 6670 pos += ret; 6671 } 6672 #endif /* CONFIG_P2P */ 6673 6674 #ifdef CONFIG_WIFI_DISPLAY 6675 ret = os_snprintf(pos, end - pos, "wifi_display=%d\n", 6676 !!global->wifi_display); 6677 if (ret < 0 || ret >= end - pos) 6678 return pos - buf; 6679 pos += ret; 6680 #endif /* CONFIG_WIFI_DISPLAY */ 6681 6682 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 6683 ret = os_snprintf(pos, end - pos, "ifname=%s\n" 6684 "address=" MACSTR "\n", 6685 wpa_s->ifname, MAC2STR(wpa_s->own_addr)); 6686 if (ret < 0 || ret >= end - pos) 6687 return pos - buf; 6688 pos += ret; 6689 } 6690 6691 return pos - buf; 6692 } 6693 6694 6695 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global, 6696 char *buf, size_t *resp_len) 6697 { 6698 char *reply; 6699 const int reply_size = 2048; 6700 int reply_len; 6701 int level = MSG_DEBUG; 6702 6703 if (os_strncmp(buf, "IFNAME=", 7) == 0) { 6704 char *pos = os_strchr(buf + 7, ' '); 6705 if (pos) { 6706 *pos++ = '\0'; 6707 return wpas_global_ctrl_iface_ifname(global, 6708 buf + 7, pos, 6709 resp_len); 6710 } 6711 } 6712 6713 reply = wpas_global_ctrl_iface_redir(global, buf, resp_len); 6714 if (reply) 6715 return reply; 6716 6717 if (os_strcmp(buf, "PING") == 0) 6718 level = MSG_EXCESSIVE; 6719 wpa_hexdump_ascii(level, "RX global ctrl_iface", 6720 (const u8 *) buf, os_strlen(buf)); 6721 6722 reply = os_malloc(reply_size); 6723 if (reply == NULL) { 6724 *resp_len = 1; 6725 return NULL; 6726 } 6727 6728 os_memcpy(reply, "OK\n", 3); 6729 reply_len = 3; 6730 6731 if (os_strcmp(buf, "PING") == 0) { 6732 os_memcpy(reply, "PONG\n", 5); 6733 reply_len = 5; 6734 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) { 6735 if (wpa_supplicant_global_iface_add(global, buf + 14)) 6736 reply_len = -1; 6737 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) { 6738 if (wpa_supplicant_global_iface_remove(global, buf + 17)) 6739 reply_len = -1; 6740 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 6741 reply_len = wpa_supplicant_global_iface_list( 6742 global, reply, reply_size); 6743 } else if (os_strcmp(buf, "INTERFACES") == 0) { 6744 reply_len = wpa_supplicant_global_iface_interfaces( 6745 global, reply, reply_size); 6746 } else if (os_strcmp(buf, "TERMINATE") == 0) { 6747 wpa_supplicant_terminate_proc(global); 6748 } else if (os_strcmp(buf, "SUSPEND") == 0) { 6749 wpas_notify_suspend(global); 6750 } else if (os_strcmp(buf, "RESUME") == 0) { 6751 wpas_notify_resume(global); 6752 } else if (os_strncmp(buf, "SET ", 4) == 0) { 6753 if (wpas_global_ctrl_iface_set(global, buf + 4)) 6754 reply_len = -1; 6755 #ifndef CONFIG_NO_CONFIG_WRITE 6756 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) { 6757 if (wpas_global_ctrl_iface_save_config(global)) 6758 reply_len = -1; 6759 #endif /* CONFIG_NO_CONFIG_WRITE */ 6760 } else if (os_strcmp(buf, "STATUS") == 0) { 6761 reply_len = wpas_global_ctrl_iface_status(global, reply, 6762 reply_size); 6763 } else { 6764 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 6765 reply_len = 16; 6766 } 6767 6768 if (reply_len < 0) { 6769 os_memcpy(reply, "FAIL\n", 5); 6770 reply_len = 5; 6771 } 6772 6773 *resp_len = reply_len; 6774 return reply; 6775 } 6776