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