Home | History | Annotate | Download | only in common
      1 /*
      2  * IEEE 802.11 Common routines
      3  * Copyright (c) 2002-2015, 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 "includes.h"
     10 
     11 #include "common.h"
     12 #include "defs.h"
     13 #include "wpa_common.h"
     14 #include "qca-vendor.h"
     15 #include "ieee802_11_defs.h"
     16 #include "ieee802_11_common.h"
     17 
     18 
     19 static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
     20 					    struct ieee802_11_elems *elems,
     21 					    int show_errors)
     22 {
     23 	unsigned int oui;
     24 
     25 	/* first 3 bytes in vendor specific information element are the IEEE
     26 	 * OUI of the vendor. The following byte is used a vendor specific
     27 	 * sub-type. */
     28 	if (elen < 4) {
     29 		if (show_errors) {
     30 			wpa_printf(MSG_MSGDUMP, "short vendor specific "
     31 				   "information element ignored (len=%lu)",
     32 				   (unsigned long) elen);
     33 		}
     34 		return -1;
     35 	}
     36 
     37 	oui = WPA_GET_BE24(pos);
     38 	switch (oui) {
     39 	case OUI_MICROSOFT:
     40 		/* Microsoft/Wi-Fi information elements are further typed and
     41 		 * subtyped */
     42 		switch (pos[3]) {
     43 		case 1:
     44 			/* Microsoft OUI (00:50:F2) with OUI Type 1:
     45 			 * real WPA information element */
     46 			elems->wpa_ie = pos;
     47 			elems->wpa_ie_len = elen;
     48 			break;
     49 		case WMM_OUI_TYPE:
     50 			/* WMM information element */
     51 			if (elen < 5) {
     52 				wpa_printf(MSG_MSGDUMP, "short WMM "
     53 					   "information element ignored "
     54 					   "(len=%lu)",
     55 					   (unsigned long) elen);
     56 				return -1;
     57 			}
     58 			switch (pos[4]) {
     59 			case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT:
     60 			case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT:
     61 				/*
     62 				 * Share same pointer since only one of these
     63 				 * is used and they start with same data.
     64 				 * Length field can be used to distinguish the
     65 				 * IEs.
     66 				 */
     67 				elems->wmm = pos;
     68 				elems->wmm_len = elen;
     69 				break;
     70 			case WMM_OUI_SUBTYPE_TSPEC_ELEMENT:
     71 				elems->wmm_tspec = pos;
     72 				elems->wmm_tspec_len = elen;
     73 				break;
     74 			default:
     75 				wpa_printf(MSG_EXCESSIVE, "unknown WMM "
     76 					   "information element ignored "
     77 					   "(subtype=%d len=%lu)",
     78 					   pos[4], (unsigned long) elen);
     79 				return -1;
     80 			}
     81 			break;
     82 		case 4:
     83 			/* Wi-Fi Protected Setup (WPS) IE */
     84 			elems->wps_ie = pos;
     85 			elems->wps_ie_len = elen;
     86 			break;
     87 		default:
     88 			wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft "
     89 				   "information element ignored "
     90 				   "(type=%d len=%lu)",
     91 				   pos[3], (unsigned long) elen);
     92 			return -1;
     93 		}
     94 		break;
     95 
     96 	case OUI_WFA:
     97 		switch (pos[3]) {
     98 		case P2P_OUI_TYPE:
     99 			/* Wi-Fi Alliance - P2P IE */
    100 			elems->p2p = pos;
    101 			elems->p2p_len = elen;
    102 			break;
    103 		case WFD_OUI_TYPE:
    104 			/* Wi-Fi Alliance - WFD IE */
    105 			elems->wfd = pos;
    106 			elems->wfd_len = elen;
    107 			break;
    108 		case HS20_INDICATION_OUI_TYPE:
    109 			/* Hotspot 2.0 */
    110 			elems->hs20 = pos;
    111 			elems->hs20_len = elen;
    112 			break;
    113 		case HS20_OSEN_OUI_TYPE:
    114 			/* Hotspot 2.0 OSEN */
    115 			elems->osen = pos;
    116 			elems->osen_len = elen;
    117 			break;
    118 		case MBO_OUI_TYPE:
    119 			/* MBO-OCE */
    120 			elems->mbo = pos;
    121 			elems->mbo_len = elen;
    122 			break;
    123 		default:
    124 			wpa_printf(MSG_MSGDUMP, "Unknown WFA "
    125 				   "information element ignored "
    126 				   "(type=%d len=%lu)",
    127 				   pos[3], (unsigned long) elen);
    128 			return -1;
    129 		}
    130 		break;
    131 
    132 	case OUI_BROADCOM:
    133 		switch (pos[3]) {
    134 		case VENDOR_HT_CAPAB_OUI_TYPE:
    135 			elems->vendor_ht_cap = pos;
    136 			elems->vendor_ht_cap_len = elen;
    137 			break;
    138 		case VENDOR_VHT_TYPE:
    139 			if (elen > 4 &&
    140 			    (pos[4] == VENDOR_VHT_SUBTYPE ||
    141 			     pos[4] == VENDOR_VHT_SUBTYPE2)) {
    142 				elems->vendor_vht = pos;
    143 				elems->vendor_vht_len = elen;
    144 			} else
    145 				return -1;
    146 			break;
    147 		default:
    148 			wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
    149 				   "information element ignored "
    150 				   "(type=%d len=%lu)",
    151 				   pos[3], (unsigned long) elen);
    152 			return -1;
    153 		}
    154 		break;
    155 
    156 	case OUI_QCA:
    157 		switch (pos[3]) {
    158 		case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
    159 			elems->pref_freq_list = pos;
    160 			elems->pref_freq_list_len = elen;
    161 			break;
    162 		default:
    163 			wpa_printf(MSG_EXCESSIVE,
    164 				   "Unknown QCA information element ignored (type=%d len=%lu)",
    165 				   pos[3], (unsigned long) elen);
    166 			return -1;
    167 		}
    168 		break;
    169 
    170 	default:
    171 		wpa_printf(MSG_EXCESSIVE, "unknown vendor specific "
    172 			   "information element ignored (vendor OUI "
    173 			   "%02x:%02x:%02x len=%lu)",
    174 			   pos[0], pos[1], pos[2], (unsigned long) elen);
    175 		return -1;
    176 	}
    177 
    178 	return 0;
    179 }
    180 
    181 
    182 static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
    183 				      struct ieee802_11_elems *elems,
    184 				      int show_errors)
    185 {
    186 	u8 ext_id;
    187 
    188 	if (elen < 1) {
    189 		if (show_errors) {
    190 			wpa_printf(MSG_MSGDUMP,
    191 				   "short information element (Ext)");
    192 		}
    193 		return -1;
    194 	}
    195 
    196 	ext_id = *pos++;
    197 	elen--;
    198 
    199 	switch (ext_id) {
    200 	case WLAN_EID_EXT_ASSOC_DELAY_INFO:
    201 		if (elen != 1)
    202 			break;
    203 		elems->assoc_delay_info = pos;
    204 		break;
    205 	case WLAN_EID_EXT_FILS_REQ_PARAMS:
    206 		if (elen < 3)
    207 			break;
    208 		elems->fils_req_params = pos;
    209 		elems->fils_req_params_len = elen;
    210 		break;
    211 	case WLAN_EID_EXT_FILS_KEY_CONFIRM:
    212 		elems->fils_key_confirm = pos;
    213 		elems->fils_key_confirm_len = elen;
    214 		break;
    215 	case WLAN_EID_EXT_FILS_SESSION:
    216 		if (elen != FILS_SESSION_LEN)
    217 			break;
    218 		elems->fils_session = pos;
    219 		break;
    220 	case WLAN_EID_EXT_FILS_HLP_CONTAINER:
    221 		if (elen < 2 * ETH_ALEN)
    222 			break;
    223 		elems->fils_hlp = pos;
    224 		elems->fils_hlp_len = elen;
    225 		break;
    226 	case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN:
    227 		if (elen < 1)
    228 			break;
    229 		elems->fils_ip_addr_assign = pos;
    230 		elems->fils_ip_addr_assign_len = elen;
    231 		break;
    232 	case WLAN_EID_EXT_KEY_DELIVERY:
    233 		if (elen < WPA_KEY_RSC_LEN)
    234 			break;
    235 		elems->key_delivery = pos;
    236 		elems->key_delivery_len = elen;
    237 		break;
    238 	case WLAN_EID_EXT_FILS_WRAPPED_DATA:
    239 		elems->fils_wrapped_data = pos;
    240 		elems->fils_wrapped_data_len = elen;
    241 		break;
    242 	case WLAN_EID_EXT_FILS_PUBLIC_KEY:
    243 		if (elen < 1)
    244 			break;
    245 		elems->fils_pk = pos;
    246 		elems->fils_pk_len = elen;
    247 		break;
    248 	case WLAN_EID_EXT_FILS_NONCE:
    249 		if (elen != FILS_NONCE_LEN)
    250 			break;
    251 		elems->fils_nonce = pos;
    252 		break;
    253 	case WLAN_EID_EXT_OWE_DH_PARAM:
    254 		if (elen < 2)
    255 			break;
    256 		elems->owe_dh = pos;
    257 		elems->owe_dh_len = elen;
    258 		break;
    259 	default:
    260 		if (show_errors) {
    261 			wpa_printf(MSG_MSGDUMP,
    262 				   "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
    263 				   ext_id, (unsigned int) elen);
    264 		}
    265 		return -1;
    266 	}
    267 
    268 	return 0;
    269 }
    270 
    271 
    272 /**
    273  * ieee802_11_parse_elems - Parse information elements in management frames
    274  * @start: Pointer to the start of IEs
    275  * @len: Length of IE buffer in octets
    276  * @elems: Data structure for parsed elements
    277  * @show_errors: Whether to show parsing errors in debug log
    278  * Returns: Parsing result
    279  */
    280 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
    281 				struct ieee802_11_elems *elems,
    282 				int show_errors)
    283 {
    284 	size_t left = len;
    285 	const u8 *pos = start;
    286 	int unknown = 0;
    287 
    288 	os_memset(elems, 0, sizeof(*elems));
    289 
    290 	while (left >= 2) {
    291 		u8 id, elen;
    292 
    293 		id = *pos++;
    294 		elen = *pos++;
    295 		left -= 2;
    296 
    297 		if (elen > left) {
    298 			if (show_errors) {
    299 				wpa_printf(MSG_DEBUG, "IEEE 802.11 element "
    300 					   "parse failed (id=%d elen=%d "
    301 					   "left=%lu)",
    302 					   id, elen, (unsigned long) left);
    303 				wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
    304 			}
    305 			return ParseFailed;
    306 		}
    307 
    308 		switch (id) {
    309 		case WLAN_EID_SSID:
    310 			if (elen > SSID_MAX_LEN) {
    311 				wpa_printf(MSG_DEBUG,
    312 					   "Ignored too long SSID element (elen=%u)",
    313 					   elen);
    314 				break;
    315 			}
    316 			elems->ssid = pos;
    317 			elems->ssid_len = elen;
    318 			break;
    319 		case WLAN_EID_SUPP_RATES:
    320 			elems->supp_rates = pos;
    321 			elems->supp_rates_len = elen;
    322 			break;
    323 		case WLAN_EID_DS_PARAMS:
    324 			if (elen < 1)
    325 				break;
    326 			elems->ds_params = pos;
    327 			break;
    328 		case WLAN_EID_CF_PARAMS:
    329 		case WLAN_EID_TIM:
    330 			break;
    331 		case WLAN_EID_CHALLENGE:
    332 			elems->challenge = pos;
    333 			elems->challenge_len = elen;
    334 			break;
    335 		case WLAN_EID_ERP_INFO:
    336 			if (elen < 1)
    337 				break;
    338 			elems->erp_info = pos;
    339 			break;
    340 		case WLAN_EID_EXT_SUPP_RATES:
    341 			elems->ext_supp_rates = pos;
    342 			elems->ext_supp_rates_len = elen;
    343 			break;
    344 		case WLAN_EID_VENDOR_SPECIFIC:
    345 			if (ieee802_11_parse_vendor_specific(pos, elen,
    346 							     elems,
    347 							     show_errors))
    348 				unknown++;
    349 			break;
    350 		case WLAN_EID_RSN:
    351 			elems->rsn_ie = pos;
    352 			elems->rsn_ie_len = elen;
    353 			break;
    354 		case WLAN_EID_PWR_CAPABILITY:
    355 			break;
    356 		case WLAN_EID_SUPPORTED_CHANNELS:
    357 			elems->supp_channels = pos;
    358 			elems->supp_channels_len = elen;
    359 			break;
    360 		case WLAN_EID_MOBILITY_DOMAIN:
    361 			if (elen < sizeof(struct rsn_mdie))
    362 				break;
    363 			elems->mdie = pos;
    364 			elems->mdie_len = elen;
    365 			break;
    366 		case WLAN_EID_FAST_BSS_TRANSITION:
    367 			if (elen < sizeof(struct rsn_ftie))
    368 				break;
    369 			elems->ftie = pos;
    370 			elems->ftie_len = elen;
    371 			break;
    372 		case WLAN_EID_TIMEOUT_INTERVAL:
    373 			if (elen != 5)
    374 				break;
    375 			elems->timeout_int = pos;
    376 			break;
    377 		case WLAN_EID_HT_CAP:
    378 			if (elen < sizeof(struct ieee80211_ht_capabilities))
    379 				break;
    380 			elems->ht_capabilities = pos;
    381 			break;
    382 		case WLAN_EID_HT_OPERATION:
    383 			if (elen < sizeof(struct ieee80211_ht_operation))
    384 				break;
    385 			elems->ht_operation = pos;
    386 			break;
    387 		case WLAN_EID_MESH_CONFIG:
    388 			elems->mesh_config = pos;
    389 			elems->mesh_config_len = elen;
    390 			break;
    391 		case WLAN_EID_MESH_ID:
    392 			elems->mesh_id = pos;
    393 			elems->mesh_id_len = elen;
    394 			break;
    395 		case WLAN_EID_PEER_MGMT:
    396 			elems->peer_mgmt = pos;
    397 			elems->peer_mgmt_len = elen;
    398 			break;
    399 		case WLAN_EID_VHT_CAP:
    400 			if (elen < sizeof(struct ieee80211_vht_capabilities))
    401 				break;
    402 			elems->vht_capabilities = pos;
    403 			break;
    404 		case WLAN_EID_VHT_OPERATION:
    405 			if (elen < sizeof(struct ieee80211_vht_operation))
    406 				break;
    407 			elems->vht_operation = pos;
    408 			break;
    409 		case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
    410 			if (elen != 1)
    411 				break;
    412 			elems->vht_opmode_notif = pos;
    413 			break;
    414 		case WLAN_EID_LINK_ID:
    415 			if (elen < 18)
    416 				break;
    417 			elems->link_id = pos;
    418 			break;
    419 		case WLAN_EID_INTERWORKING:
    420 			elems->interworking = pos;
    421 			elems->interworking_len = elen;
    422 			break;
    423 		case WLAN_EID_QOS_MAP_SET:
    424 			if (elen < 16)
    425 				break;
    426 			elems->qos_map_set = pos;
    427 			elems->qos_map_set_len = elen;
    428 			break;
    429 		case WLAN_EID_EXT_CAPAB:
    430 			elems->ext_capab = pos;
    431 			elems->ext_capab_len = elen;
    432 			break;
    433 		case WLAN_EID_BSS_MAX_IDLE_PERIOD:
    434 			if (elen < 3)
    435 				break;
    436 			elems->bss_max_idle_period = pos;
    437 			break;
    438 		case WLAN_EID_SSID_LIST:
    439 			elems->ssid_list = pos;
    440 			elems->ssid_list_len = elen;
    441 			break;
    442 		case WLAN_EID_AMPE:
    443 			elems->ampe = pos;
    444 			elems->ampe_len = elen;
    445 			break;
    446 		case WLAN_EID_MIC:
    447 			elems->mic = pos;
    448 			elems->mic_len = elen;
    449 			/* after mic everything is encrypted, so stop. */
    450 			left = elen;
    451 			break;
    452 		case WLAN_EID_MULTI_BAND:
    453 			if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
    454 				wpa_printf(MSG_MSGDUMP,
    455 					   "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
    456 					   id, elen);
    457 				break;
    458 			}
    459 
    460 			elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
    461 			elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
    462 			elems->mb_ies.nof_ies++;
    463 			break;
    464 		case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
    465 			elems->supp_op_classes = pos;
    466 			elems->supp_op_classes_len = elen;
    467 			break;
    468 		case WLAN_EID_RRM_ENABLED_CAPABILITIES:
    469 			elems->rrm_enabled = pos;
    470 			elems->rrm_enabled_len = elen;
    471 			break;
    472 		case WLAN_EID_CAG_NUMBER:
    473 			elems->cag_number = pos;
    474 			elems->cag_number_len = elen;
    475 			break;
    476 		case WLAN_EID_AP_CSN:
    477 			if (elen < 1)
    478 				break;
    479 			elems->ap_csn = pos;
    480 			break;
    481 		case WLAN_EID_FILS_INDICATION:
    482 			if (elen < 2)
    483 				break;
    484 			elems->fils_indic = pos;
    485 			elems->fils_indic_len = elen;
    486 			break;
    487 		case WLAN_EID_DILS:
    488 			if (elen < 2)
    489 				break;
    490 			elems->dils = pos;
    491 			elems->dils_len = elen;
    492 			break;
    493 		case WLAN_EID_FRAGMENT:
    494 			/* TODO */
    495 			break;
    496 		case WLAN_EID_EXTENSION:
    497 			if (ieee802_11_parse_extension(pos, elen, elems,
    498 						       show_errors))
    499 				unknown++;
    500 			break;
    501 		default:
    502 			unknown++;
    503 			if (!show_errors)
    504 				break;
    505 			wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
    506 				   "ignored unknown element (id=%d elen=%d)",
    507 				   id, elen);
    508 			break;
    509 		}
    510 
    511 		left -= elen;
    512 		pos += elen;
    513 	}
    514 
    515 	if (left)
    516 		return ParseFailed;
    517 
    518 	return unknown ? ParseUnknown : ParseOK;
    519 }
    520 
    521 
    522 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
    523 {
    524 	int count = 0;
    525 	const u8 *pos, *end;
    526 
    527 	if (ies == NULL)
    528 		return 0;
    529 
    530 	pos = ies;
    531 	end = ies + ies_len;
    532 
    533 	while (end - pos >= 2) {
    534 		if (2 + pos[1] > end - pos)
    535 			break;
    536 		count++;
    537 		pos += 2 + pos[1];
    538 	}
    539 
    540 	return count;
    541 }
    542 
    543 
    544 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
    545 					    u32 oui_type)
    546 {
    547 	struct wpabuf *buf;
    548 	const u8 *end, *pos, *ie;
    549 
    550 	pos = ies;
    551 	end = ies + ies_len;
    552 	ie = NULL;
    553 
    554 	while (end - pos > 1) {
    555 		if (2 + pos[1] > end - pos)
    556 			return NULL;
    557 		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
    558 		    WPA_GET_BE32(&pos[2]) == oui_type) {
    559 			ie = pos;
    560 			break;
    561 		}
    562 		pos += 2 + pos[1];
    563 	}
    564 
    565 	if (ie == NULL)
    566 		return NULL; /* No specified vendor IE found */
    567 
    568 	buf = wpabuf_alloc(ies_len);
    569 	if (buf == NULL)
    570 		return NULL;
    571 
    572 	/*
    573 	 * There may be multiple vendor IEs in the message, so need to
    574 	 * concatenate their data fields.
    575 	 */
    576 	while (end - pos > 1) {
    577 		if (2 + pos[1] > end - pos)
    578 			break;
    579 		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
    580 		    WPA_GET_BE32(&pos[2]) == oui_type)
    581 			wpabuf_put_data(buf, pos + 6, pos[1] - 4);
    582 		pos += 2 + pos[1];
    583 	}
    584 
    585 	return buf;
    586 }
    587 
    588 
    589 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
    590 {
    591 	u16 fc, type, stype;
    592 
    593 	/*
    594 	 * PS-Poll frames are 16 bytes. All other frames are
    595 	 * 24 bytes or longer.
    596 	 */
    597 	if (len < 16)
    598 		return NULL;
    599 
    600 	fc = le_to_host16(hdr->frame_control);
    601 	type = WLAN_FC_GET_TYPE(fc);
    602 	stype = WLAN_FC_GET_STYPE(fc);
    603 
    604 	switch (type) {
    605 	case WLAN_FC_TYPE_DATA:
    606 		if (len < 24)
    607 			return NULL;
    608 		switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
    609 		case WLAN_FC_FROMDS | WLAN_FC_TODS:
    610 		case WLAN_FC_TODS:
    611 			return hdr->addr1;
    612 		case WLAN_FC_FROMDS:
    613 			return hdr->addr2;
    614 		default:
    615 			return NULL;
    616 		}
    617 	case WLAN_FC_TYPE_CTRL:
    618 		if (stype != WLAN_FC_STYPE_PSPOLL)
    619 			return NULL;
    620 		return hdr->addr1;
    621 	case WLAN_FC_TYPE_MGMT:
    622 		return hdr->addr3;
    623 	default:
    624 		return NULL;
    625 	}
    626 }
    627 
    628 
    629 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
    630 			  const char *name, const char *val)
    631 {
    632 	int num, v;
    633 	const char *pos;
    634 	struct hostapd_wmm_ac_params *ac;
    635 
    636 	/* skip 'wme_ac_' or 'wmm_ac_' prefix */
    637 	pos = name + 7;
    638 	if (os_strncmp(pos, "be_", 3) == 0) {
    639 		num = 0;
    640 		pos += 3;
    641 	} else if (os_strncmp(pos, "bk_", 3) == 0) {
    642 		num = 1;
    643 		pos += 3;
    644 	} else if (os_strncmp(pos, "vi_", 3) == 0) {
    645 		num = 2;
    646 		pos += 3;
    647 	} else if (os_strncmp(pos, "vo_", 3) == 0) {
    648 		num = 3;
    649 		pos += 3;
    650 	} else {
    651 		wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
    652 		return -1;
    653 	}
    654 
    655 	ac = &wmm_ac_params[num];
    656 
    657 	if (os_strcmp(pos, "aifs") == 0) {
    658 		v = atoi(val);
    659 		if (v < 1 || v > 255) {
    660 			wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
    661 			return -1;
    662 		}
    663 		ac->aifs = v;
    664 	} else if (os_strcmp(pos, "cwmin") == 0) {
    665 		v = atoi(val);
    666 		if (v < 0 || v > 15) {
    667 			wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
    668 			return -1;
    669 		}
    670 		ac->cwmin = v;
    671 	} else if (os_strcmp(pos, "cwmax") == 0) {
    672 		v = atoi(val);
    673 		if (v < 0 || v > 15) {
    674 			wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
    675 			return -1;
    676 		}
    677 		ac->cwmax = v;
    678 	} else if (os_strcmp(pos, "txop_limit") == 0) {
    679 		v = atoi(val);
    680 		if (v < 0 || v > 0xffff) {
    681 			wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
    682 			return -1;
    683 		}
    684 		ac->txop_limit = v;
    685 	} else if (os_strcmp(pos, "acm") == 0) {
    686 		v = atoi(val);
    687 		if (v < 0 || v > 1) {
    688 			wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
    689 			return -1;
    690 		}
    691 		ac->admission_control_mandatory = v;
    692 	} else {
    693 		wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
    694 		return -1;
    695 	}
    696 
    697 	return 0;
    698 }
    699 
    700 
    701 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
    702 {
    703 	u8 op_class;
    704 
    705 	return ieee80211_freq_to_channel_ext(freq, 0, VHT_CHANWIDTH_USE_HT,
    706 					     &op_class, channel);
    707 }
    708 
    709 
    710 /**
    711  * ieee80211_freq_to_channel_ext - Convert frequency into channel info
    712  * for HT40 and VHT. DFS channels are not covered.
    713  * @freq: Frequency (MHz) to convert
    714  * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
    715  * @vht: VHT channel width (VHT_CHANWIDTH_*)
    716  * @op_class: Buffer for returning operating class
    717  * @channel: Buffer for returning channel number
    718  * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
    719  */
    720 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
    721 						   int sec_channel, int vht,
    722 						   u8 *op_class, u8 *channel)
    723 {
    724 	u8 vht_opclass;
    725 
    726 	/* TODO: more operating classes */
    727 
    728 	if (sec_channel > 1 || sec_channel < -1)
    729 		return NUM_HOSTAPD_MODES;
    730 
    731 	if (freq >= 2412 && freq <= 2472) {
    732 		if ((freq - 2407) % 5)
    733 			return NUM_HOSTAPD_MODES;
    734 
    735 		if (vht)
    736 			return NUM_HOSTAPD_MODES;
    737 
    738 		/* 2.407 GHz, channels 1..13 */
    739 		if (sec_channel == 1)
    740 			*op_class = 83;
    741 		else if (sec_channel == -1)
    742 			*op_class = 84;
    743 		else
    744 			*op_class = 81;
    745 
    746 		*channel = (freq - 2407) / 5;
    747 
    748 		return HOSTAPD_MODE_IEEE80211G;
    749 	}
    750 
    751 	if (freq == 2484) {
    752 		if (sec_channel || vht)
    753 			return NUM_HOSTAPD_MODES;
    754 
    755 		*op_class = 82; /* channel 14 */
    756 		*channel = 14;
    757 
    758 		return HOSTAPD_MODE_IEEE80211B;
    759 	}
    760 
    761 	if (freq >= 4900 && freq < 5000) {
    762 		if ((freq - 4000) % 5)
    763 			return NUM_HOSTAPD_MODES;
    764 		*channel = (freq - 4000) / 5;
    765 		*op_class = 0; /* TODO */
    766 		return HOSTAPD_MODE_IEEE80211A;
    767 	}
    768 
    769 	switch (vht) {
    770 	case VHT_CHANWIDTH_80MHZ:
    771 		vht_opclass = 128;
    772 		break;
    773 	case VHT_CHANWIDTH_160MHZ:
    774 		vht_opclass = 129;
    775 		break;
    776 	case VHT_CHANWIDTH_80P80MHZ:
    777 		vht_opclass = 130;
    778 		break;
    779 	default:
    780 		vht_opclass = 0;
    781 		break;
    782 	}
    783 
    784 	/* 5 GHz, channels 36..48 */
    785 	if (freq >= 5180 && freq <= 5240) {
    786 		if ((freq - 5000) % 5)
    787 			return NUM_HOSTAPD_MODES;
    788 
    789 		if (vht_opclass)
    790 			*op_class = vht_opclass;
    791 		else if (sec_channel == 1)
    792 			*op_class = 116;
    793 		else if (sec_channel == -1)
    794 			*op_class = 117;
    795 		else
    796 			*op_class = 115;
    797 
    798 		*channel = (freq - 5000) / 5;
    799 
    800 		return HOSTAPD_MODE_IEEE80211A;
    801 	}
    802 
    803 	/* 5 GHz, channels 52..64 */
    804 	if (freq >= 5260 && freq <= 5320) {
    805 		if ((freq - 5000) % 5)
    806 			return NUM_HOSTAPD_MODES;
    807 
    808 		if (vht_opclass)
    809 			*op_class = vht_opclass;
    810 		else if (sec_channel == 1)
    811 			*op_class = 119;
    812 		else if (sec_channel == -1)
    813 			*op_class = 120;
    814 		else
    815 			*op_class = 118;
    816 
    817 		*channel = (freq - 5000) / 5;
    818 
    819 		return HOSTAPD_MODE_IEEE80211A;
    820 	}
    821 
    822 	/* 5 GHz, channels 149..169 */
    823 	if (freq >= 5745 && freq <= 5845) {
    824 		if ((freq - 5000) % 5)
    825 			return NUM_HOSTAPD_MODES;
    826 
    827 		if (vht_opclass)
    828 			*op_class = vht_opclass;
    829 		else if (sec_channel == 1)
    830 			*op_class = 126;
    831 		else if (sec_channel == -1)
    832 			*op_class = 127;
    833 		else if (freq <= 5805)
    834 			*op_class = 124;
    835 		else
    836 			*op_class = 125;
    837 
    838 		*channel = (freq - 5000) / 5;
    839 
    840 		return HOSTAPD_MODE_IEEE80211A;
    841 	}
    842 
    843 	/* 5 GHz, channels 100..140 */
    844 	if (freq >= 5000 && freq <= 5700) {
    845 		if ((freq - 5000) % 5)
    846 			return NUM_HOSTAPD_MODES;
    847 
    848 		if (vht_opclass)
    849 			*op_class = vht_opclass;
    850 		else if (sec_channel == 1)
    851 			*op_class = 122;
    852 		else if (sec_channel == -1)
    853 			*op_class = 123;
    854 		else
    855 			*op_class = 121;
    856 
    857 		*channel = (freq - 5000) / 5;
    858 
    859 		return HOSTAPD_MODE_IEEE80211A;
    860 	}
    861 
    862 	if (freq >= 5000 && freq < 5900) {
    863 		if ((freq - 5000) % 5)
    864 			return NUM_HOSTAPD_MODES;
    865 		*channel = (freq - 5000) / 5;
    866 		*op_class = 0; /* TODO */
    867 		return HOSTAPD_MODE_IEEE80211A;
    868 	}
    869 
    870 	/* 56.16 GHz, channel 1..4 */
    871 	if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
    872 		if (sec_channel || vht)
    873 			return NUM_HOSTAPD_MODES;
    874 
    875 		*channel = (freq - 56160) / 2160;
    876 		*op_class = 180;
    877 
    878 		return HOSTAPD_MODE_IEEE80211AD;
    879 	}
    880 
    881 	return NUM_HOSTAPD_MODES;
    882 }
    883 
    884 
    885 static const char *const us_op_class_cc[] = {
    886 	"US", "CA", NULL
    887 };
    888 
    889 static const char *const eu_op_class_cc[] = {
    890 	"AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
    891 	"DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
    892 	"LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
    893 	"RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
    894 };
    895 
    896 static const char *const jp_op_class_cc[] = {
    897 	"JP", NULL
    898 };
    899 
    900 static const char *const cn_op_class_cc[] = {
    901 	"CN", NULL
    902 };
    903 
    904 
    905 static int country_match(const char *const cc[], const char *const country)
    906 {
    907 	int i;
    908 
    909 	if (country == NULL)
    910 		return 0;
    911 	for (i = 0; cc[i]; i++) {
    912 		if (cc[i][0] == country[0] && cc[i][1] == country[1])
    913 			return 1;
    914 	}
    915 
    916 	return 0;
    917 }
    918 
    919 
    920 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
    921 {
    922 	switch (op_class) {
    923 	case 12: /* channels 1..11 */
    924 	case 32: /* channels 1..7; 40 MHz */
    925 	case 33: /* channels 5..11; 40 MHz */
    926 		if (chan < 1 || chan > 11)
    927 			return -1;
    928 		return 2407 + 5 * chan;
    929 	case 1: /* channels 36,40,44,48 */
    930 	case 2: /* channels 52,56,60,64; dfs */
    931 	case 22: /* channels 36,44; 40 MHz */
    932 	case 23: /* channels 52,60; 40 MHz */
    933 	case 27: /* channels 40,48; 40 MHz */
    934 	case 28: /* channels 56,64; 40 MHz */
    935 		if (chan < 36 || chan > 64)
    936 			return -1;
    937 		return 5000 + 5 * chan;
    938 	case 4: /* channels 100-144 */
    939 	case 24: /* channels 100-140; 40 MHz */
    940 		if (chan < 100 || chan > 144)
    941 			return -1;
    942 		return 5000 + 5 * chan;
    943 	case 3: /* channels 149,153,157,161 */
    944 	case 25: /* channels 149,157; 40 MHz */
    945 	case 26: /* channels 149,157; 40 MHz */
    946 	case 30: /* channels 153,161; 40 MHz */
    947 	case 31: /* channels 153,161; 40 MHz */
    948 		if (chan < 149 || chan > 161)
    949 			return -1;
    950 		return 5000 + 5 * chan;
    951 	case 5: /* channels 149,153,157,161,165 */
    952 		if (chan < 149 || chan > 165)
    953 			return -1;
    954 		return 5000 + 5 * chan;
    955 	case 34: /* 60 GHz band, channels 1..3 */
    956 		if (chan < 1 || chan > 3)
    957 			return -1;
    958 		return 56160 + 2160 * chan;
    959 	}
    960 	return -1;
    961 }
    962 
    963 
    964 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
    965 {
    966 	switch (op_class) {
    967 	case 4: /* channels 1..13 */
    968 	case 11: /* channels 1..9; 40 MHz */
    969 	case 12: /* channels 5..13; 40 MHz */
    970 		if (chan < 1 || chan > 13)
    971 			return -1;
    972 		return 2407 + 5 * chan;
    973 	case 1: /* channels 36,40,44,48 */
    974 	case 2: /* channels 52,56,60,64; dfs */
    975 	case 5: /* channels 36,44; 40 MHz */
    976 	case 6: /* channels 52,60; 40 MHz */
    977 	case 8: /* channels 40,48; 40 MHz */
    978 	case 9: /* channels 56,64; 40 MHz */
    979 		if (chan < 36 || chan > 64)
    980 			return -1;
    981 		return 5000 + 5 * chan;
    982 	case 3: /* channels 100-140 */
    983 	case 7: /* channels 100-132; 40 MHz */
    984 	case 10: /* channels 104-136; 40 MHz */
    985 	case 16: /* channels 100-140 */
    986 		if (chan < 100 || chan > 140)
    987 			return -1;
    988 		return 5000 + 5 * chan;
    989 	case 17: /* channels 149,153,157,161,165,169 */
    990 		if (chan < 149 || chan > 169)
    991 			return -1;
    992 		return 5000 + 5 * chan;
    993 	case 18: /* 60 GHz band, channels 1..4 */
    994 		if (chan < 1 || chan > 4)
    995 			return -1;
    996 		return 56160 + 2160 * chan;
    997 	}
    998 	return -1;
    999 }
   1000 
   1001 
   1002 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
   1003 {
   1004 	switch (op_class) {
   1005 	case 30: /* channels 1..13 */
   1006 	case 56: /* channels 1..9; 40 MHz */
   1007 	case 57: /* channels 5..13; 40 MHz */
   1008 		if (chan < 1 || chan > 13)
   1009 			return -1;
   1010 		return 2407 + 5 * chan;
   1011 	case 31: /* channel 14 */
   1012 		if (chan != 14)
   1013 			return -1;
   1014 		return 2414 + 5 * chan;
   1015 	case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
   1016 	case 32: /* channels 52,56,60,64 */
   1017 	case 33: /* channels 52,56,60,64 */
   1018 	case 36: /* channels 36,44; 40 MHz */
   1019 	case 37: /* channels 52,60; 40 MHz */
   1020 	case 38: /* channels 52,60; 40 MHz */
   1021 	case 41: /* channels 40,48; 40 MHz */
   1022 	case 42: /* channels 56,64; 40 MHz */
   1023 	case 43: /* channels 56,64; 40 MHz */
   1024 		if (chan < 34 || chan > 64)
   1025 			return -1;
   1026 		return 5000 + 5 * chan;
   1027 	case 34: /* channels 100-140 */
   1028 	case 35: /* channels 100-140 */
   1029 	case 39: /* channels 100-132; 40 MHz */
   1030 	case 40: /* channels 100-132; 40 MHz */
   1031 	case 44: /* channels 104-136; 40 MHz */
   1032 	case 45: /* channels 104-136; 40 MHz */
   1033 	case 58: /* channels 100-140 */
   1034 		if (chan < 100 || chan > 140)
   1035 			return -1;
   1036 		return 5000 + 5 * chan;
   1037 	case 59: /* 60 GHz band, channels 1..4 */
   1038 		if (chan < 1 || chan > 3)
   1039 			return -1;
   1040 		return 56160 + 2160 * chan;
   1041 	}
   1042 	return -1;
   1043 }
   1044 
   1045 
   1046 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
   1047 {
   1048 	switch (op_class) {
   1049 	case 7: /* channels 1..13 */
   1050 	case 8: /* channels 1..9; 40 MHz */
   1051 	case 9: /* channels 5..13; 40 MHz */
   1052 		if (chan < 1 || chan > 13)
   1053 			return -1;
   1054 		return 2407 + 5 * chan;
   1055 	case 1: /* channels 36,40,44,48 */
   1056 	case 2: /* channels 52,56,60,64; dfs */
   1057 	case 4: /* channels 36,44; 40 MHz */
   1058 	case 5: /* channels 52,60; 40 MHz */
   1059 		if (chan < 36 || chan > 64)
   1060 			return -1;
   1061 		return 5000 + 5 * chan;
   1062 	case 3: /* channels 149,153,157,161,165 */
   1063 	case 6: /* channels 149,157; 40 MHz */
   1064 		if (chan < 149 || chan > 165)
   1065 			return -1;
   1066 		return 5000 + 5 * chan;
   1067 	}
   1068 	return -1;
   1069 }
   1070 
   1071 
   1072 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
   1073 {
   1074 	/* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
   1075 	switch (op_class) {
   1076 	case 81:
   1077 		/* channels 1..13 */
   1078 		if (chan < 1 || chan > 13)
   1079 			return -1;
   1080 		return 2407 + 5 * chan;
   1081 	case 82:
   1082 		/* channel 14 */
   1083 		if (chan != 14)
   1084 			return -1;
   1085 		return 2414 + 5 * chan;
   1086 	case 83: /* channels 1..9; 40 MHz */
   1087 	case 84: /* channels 5..13; 40 MHz */
   1088 		if (chan < 1 || chan > 13)
   1089 			return -1;
   1090 		return 2407 + 5 * chan;
   1091 	case 115: /* channels 36,40,44,48; indoor only */
   1092 	case 116: /* channels 36,44; 40 MHz; indoor only */
   1093 	case 117: /* channels 40,48; 40 MHz; indoor only */
   1094 	case 118: /* channels 52,56,60,64; dfs */
   1095 	case 119: /* channels 52,60; 40 MHz; dfs */
   1096 	case 120: /* channels 56,64; 40 MHz; dfs */
   1097 		if (chan < 36 || chan > 64)
   1098 			return -1;
   1099 		return 5000 + 5 * chan;
   1100 	case 121: /* channels 100-140 */
   1101 	case 122: /* channels 100-142; 40 MHz */
   1102 	case 123: /* channels 104-136; 40 MHz */
   1103 		if (chan < 100 || chan > 140)
   1104 			return -1;
   1105 		return 5000 + 5 * chan;
   1106 	case 124: /* channels 149,153,157,161 */
   1107 	case 126: /* channels 149,157; 40 MHz */
   1108 	case 127: /* channels 153,161; 40 MHz */
   1109 		if (chan < 149 || chan > 161)
   1110 			return -1;
   1111 		return 5000 + 5 * chan;
   1112 	case 125: /* channels 149,153,157,161,165,169 */
   1113 		if (chan < 149 || chan > 169)
   1114 			return -1;
   1115 		return 5000 + 5 * chan;
   1116 	case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
   1117 	case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
   1118 		if (chan < 36 || chan > 161)
   1119 			return -1;
   1120 		return 5000 + 5 * chan;
   1121 	case 129: /* center freqs 50, 114; 160 MHz */
   1122 		if (chan < 36 || chan > 128)
   1123 			return -1;
   1124 		return 5000 + 5 * chan;
   1125 	case 180: /* 60 GHz band, channels 1..4 */
   1126 		if (chan < 1 || chan > 4)
   1127 			return -1;
   1128 		return 56160 + 2160 * chan;
   1129 	}
   1130 	return -1;
   1131 }
   1132 
   1133 /**
   1134  * ieee80211_chan_to_freq - Convert channel info to frequency
   1135  * @country: Country code, if known; otherwise, global operating class is used
   1136  * @op_class: Operating class
   1137  * @chan: Channel number
   1138  * Returns: Frequency in MHz or -1 if the specified channel is unknown
   1139  */
   1140 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
   1141 {
   1142 	int freq;
   1143 
   1144 	if (country_match(us_op_class_cc, country)) {
   1145 		freq = ieee80211_chan_to_freq_us(op_class, chan);
   1146 		if (freq > 0)
   1147 			return freq;
   1148 	}
   1149 
   1150 	if (country_match(eu_op_class_cc, country)) {
   1151 		freq = ieee80211_chan_to_freq_eu(op_class, chan);
   1152 		if (freq > 0)
   1153 			return freq;
   1154 	}
   1155 
   1156 	if (country_match(jp_op_class_cc, country)) {
   1157 		freq = ieee80211_chan_to_freq_jp(op_class, chan);
   1158 		if (freq > 0)
   1159 			return freq;
   1160 	}
   1161 
   1162 	if (country_match(cn_op_class_cc, country)) {
   1163 		freq = ieee80211_chan_to_freq_cn(op_class, chan);
   1164 		if (freq > 0)
   1165 			return freq;
   1166 	}
   1167 
   1168 	return ieee80211_chan_to_freq_global(op_class, chan);
   1169 }
   1170 
   1171 
   1172 int ieee80211_is_dfs(int freq)
   1173 {
   1174 	/* TODO: this could be more accurate to better cover all domains */
   1175 	return (freq >= 5260 && freq <= 5320) || (freq >= 5500 && freq <= 5700);
   1176 }
   1177 
   1178 
   1179 static int is_11b(u8 rate)
   1180 {
   1181 	return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
   1182 }
   1183 
   1184 
   1185 int supp_rates_11b_only(struct ieee802_11_elems *elems)
   1186 {
   1187 	int num_11b = 0, num_others = 0;
   1188 	int i;
   1189 
   1190 	if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
   1191 		return 0;
   1192 
   1193 	for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
   1194 		if (is_11b(elems->supp_rates[i]))
   1195 			num_11b++;
   1196 		else
   1197 			num_others++;
   1198 	}
   1199 
   1200 	for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
   1201 	     i++) {
   1202 		if (is_11b(elems->ext_supp_rates[i]))
   1203 			num_11b++;
   1204 		else
   1205 			num_others++;
   1206 	}
   1207 
   1208 	return num_11b > 0 && num_others == 0;
   1209 }
   1210 
   1211 
   1212 const char * fc2str(u16 fc)
   1213 {
   1214 	u16 stype = WLAN_FC_GET_STYPE(fc);
   1215 #define C2S(x) case x: return #x;
   1216 
   1217 	switch (WLAN_FC_GET_TYPE(fc)) {
   1218 	case WLAN_FC_TYPE_MGMT:
   1219 		switch (stype) {
   1220 		C2S(WLAN_FC_STYPE_ASSOC_REQ)
   1221 		C2S(WLAN_FC_STYPE_ASSOC_RESP)
   1222 		C2S(WLAN_FC_STYPE_REASSOC_REQ)
   1223 		C2S(WLAN_FC_STYPE_REASSOC_RESP)
   1224 		C2S(WLAN_FC_STYPE_PROBE_REQ)
   1225 		C2S(WLAN_FC_STYPE_PROBE_RESP)
   1226 		C2S(WLAN_FC_STYPE_BEACON)
   1227 		C2S(WLAN_FC_STYPE_ATIM)
   1228 		C2S(WLAN_FC_STYPE_DISASSOC)
   1229 		C2S(WLAN_FC_STYPE_AUTH)
   1230 		C2S(WLAN_FC_STYPE_DEAUTH)
   1231 		C2S(WLAN_FC_STYPE_ACTION)
   1232 		}
   1233 		break;
   1234 	case WLAN_FC_TYPE_CTRL:
   1235 		switch (stype) {
   1236 		C2S(WLAN_FC_STYPE_PSPOLL)
   1237 		C2S(WLAN_FC_STYPE_RTS)
   1238 		C2S(WLAN_FC_STYPE_CTS)
   1239 		C2S(WLAN_FC_STYPE_ACK)
   1240 		C2S(WLAN_FC_STYPE_CFEND)
   1241 		C2S(WLAN_FC_STYPE_CFENDACK)
   1242 		}
   1243 		break;
   1244 	case WLAN_FC_TYPE_DATA:
   1245 		switch (stype) {
   1246 		C2S(WLAN_FC_STYPE_DATA)
   1247 		C2S(WLAN_FC_STYPE_DATA_CFACK)
   1248 		C2S(WLAN_FC_STYPE_DATA_CFPOLL)
   1249 		C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
   1250 		C2S(WLAN_FC_STYPE_NULLFUNC)
   1251 		C2S(WLAN_FC_STYPE_CFACK)
   1252 		C2S(WLAN_FC_STYPE_CFPOLL)
   1253 		C2S(WLAN_FC_STYPE_CFACKPOLL)
   1254 		C2S(WLAN_FC_STYPE_QOS_DATA)
   1255 		C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
   1256 		C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
   1257 		C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
   1258 		C2S(WLAN_FC_STYPE_QOS_NULL)
   1259 		C2S(WLAN_FC_STYPE_QOS_CFPOLL)
   1260 		C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
   1261 		}
   1262 		break;
   1263 	}
   1264 	return "WLAN_FC_TYPE_UNKNOWN";
   1265 #undef C2S
   1266 }
   1267 
   1268 
   1269 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
   1270 		       size_t ies_len)
   1271 {
   1272 	os_memset(info, 0, sizeof(*info));
   1273 
   1274 	while (ies_buf && ies_len >= 2 &&
   1275 	       info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) {
   1276 		size_t len = 2 + ies_buf[1];
   1277 
   1278 		if (len > ies_len) {
   1279 			wpa_hexdump(MSG_DEBUG, "Truncated IEs",
   1280 				    ies_buf, ies_len);
   1281 			return -1;
   1282 		}
   1283 
   1284 		if (ies_buf[0] == WLAN_EID_MULTI_BAND) {
   1285 			wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len);
   1286 			info->ies[info->nof_ies].ie = ies_buf + 2;
   1287 			info->ies[info->nof_ies].ie_len = ies_buf[1];
   1288 			info->nof_ies++;
   1289 		}
   1290 
   1291 		ies_len -= len;
   1292 		ies_buf += len;
   1293 	}
   1294 
   1295 	return 0;
   1296 }
   1297 
   1298 
   1299 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
   1300 {
   1301 	struct wpabuf *mb_ies = NULL;
   1302 
   1303 	WPA_ASSERT(info != NULL);
   1304 
   1305 	if (info->nof_ies) {
   1306 		u8 i;
   1307 		size_t mb_ies_size = 0;
   1308 
   1309 		for (i = 0; i < info->nof_ies; i++)
   1310 			mb_ies_size += 2 + info->ies[i].ie_len;
   1311 
   1312 		mb_ies = wpabuf_alloc(mb_ies_size);
   1313 		if (mb_ies) {
   1314 			for (i = 0; i < info->nof_ies; i++) {
   1315 				wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
   1316 				wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
   1317 				wpabuf_put_data(mb_ies,
   1318 						info->ies[i].ie,
   1319 						info->ies[i].ie_len);
   1320 			}
   1321 		}
   1322 	}
   1323 
   1324 	return mb_ies;
   1325 }
   1326 
   1327 
   1328 const struct oper_class_map global_op_class[] = {
   1329 	{ HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
   1330 	{ HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
   1331 
   1332 	/* Do not enable HT40 on 2.4 GHz for P2P use for now */
   1333 	{ HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
   1334 	{ HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
   1335 
   1336 	{ HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
   1337 	{ HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
   1338 	{ HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
   1339 	{ HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
   1340 	{ HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
   1341 	{ HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
   1342 	{ HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
   1343 	{ HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
   1344 	{ HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
   1345 	{ HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
   1346 	{ HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
   1347 	{ HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
   1348 	{ HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
   1349 
   1350 	/*
   1351 	 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
   1352 	 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
   1353 	 * 80 MHz, but currently use the following definition for simplicity
   1354 	 * (these center frequencies are not actual channels, which makes
   1355 	 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
   1356 	 * care of removing invalid channels.
   1357 	 */
   1358 	{ HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
   1359 	{ HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
   1360 	{ HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
   1361 	{ HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
   1362 	{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
   1363 };
   1364 
   1365 
   1366 static enum phy_type ieee80211_phy_type_by_freq(int freq)
   1367 {
   1368 	enum hostapd_hw_mode hw_mode;
   1369 	u8 channel;
   1370 
   1371 	hw_mode = ieee80211_freq_to_chan(freq, &channel);
   1372 
   1373 	switch (hw_mode) {
   1374 	case HOSTAPD_MODE_IEEE80211A:
   1375 		return PHY_TYPE_OFDM;
   1376 	case HOSTAPD_MODE_IEEE80211B:
   1377 		return PHY_TYPE_HRDSSS;
   1378 	case HOSTAPD_MODE_IEEE80211G:
   1379 		return PHY_TYPE_ERP;
   1380 	case HOSTAPD_MODE_IEEE80211AD:
   1381 		return PHY_TYPE_DMG;
   1382 	default:
   1383 		return PHY_TYPE_UNSPECIFIED;
   1384 	};
   1385 }
   1386 
   1387 
   1388 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
   1389 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
   1390 {
   1391 	if (vht)
   1392 		return PHY_TYPE_VHT;
   1393 	if (ht)
   1394 		return PHY_TYPE_HT;
   1395 
   1396 	return ieee80211_phy_type_by_freq(freq);
   1397 }
   1398 
   1399 
   1400 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
   1401 
   1402 
   1403 /**
   1404  * get_ie - Fetch a specified information element from IEs buffer
   1405  * @ies: Information elements buffer
   1406  * @len: Information elements buffer length
   1407  * @eid: Information element identifier (WLAN_EID_*)
   1408  * Returns: Pointer to the information element (id field) or %NULL if not found
   1409  *
   1410  * This function returns the first matching information element in the IEs
   1411  * buffer or %NULL in case the element is not found.
   1412  */
   1413 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
   1414 {
   1415 	const u8 *end;
   1416 
   1417 	if (!ies)
   1418 		return NULL;
   1419 
   1420 	end = ies + len;
   1421 
   1422 	while (end - ies > 1) {
   1423 		if (2 + ies[1] > end - ies)
   1424 			break;
   1425 
   1426 		if (ies[0] == eid)
   1427 			return ies;
   1428 
   1429 		ies += 2 + ies[1];
   1430 	}
   1431 
   1432 	return NULL;
   1433 }
   1434 
   1435 
   1436 /**
   1437  * get_ie_ext - Fetch a specified extended information element from IEs buffer
   1438  * @ies: Information elements buffer
   1439  * @len: Information elements buffer length
   1440  * @ext: Information element extension identifier (WLAN_EID_EXT_*)
   1441  * Returns: Pointer to the information element (id field) or %NULL if not found
   1442  *
   1443  * This function returns the first matching information element in the IEs
   1444  * buffer or %NULL in case the element is not found.
   1445  */
   1446 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
   1447 {
   1448 	const u8 *end;
   1449 
   1450 	if (!ies)
   1451 		return NULL;
   1452 
   1453 	end = ies + len;
   1454 
   1455 	while (end - ies > 1) {
   1456 		if (2 + ies[1] > end - ies)
   1457 			break;
   1458 
   1459 		if (ies[0] == WLAN_EID_EXTENSION && ies[1] >= 1 &&
   1460 		    ies[2] == ext)
   1461 			return ies;
   1462 
   1463 		ies += 2 + ies[1];
   1464 	}
   1465 
   1466 	return NULL;
   1467 }
   1468 
   1469 
   1470 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
   1471 {
   1472 	/*
   1473 	 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
   1474 	 * OUI (3), OUI type (1).
   1475 	 */
   1476 	if (len < 6 + attr_len) {
   1477 		wpa_printf(MSG_DEBUG,
   1478 			   "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
   1479 			   len, attr_len);
   1480 		return 0;
   1481 	}
   1482 
   1483 	*buf++ = WLAN_EID_VENDOR_SPECIFIC;
   1484 	*buf++ = attr_len + 4;
   1485 	WPA_PUT_BE24(buf, OUI_WFA);
   1486 	buf += 3;
   1487 	*buf++ = MBO_OUI_TYPE;
   1488 	os_memcpy(buf, attr, attr_len);
   1489 
   1490 	return 6 + attr_len;
   1491 }
   1492 
   1493 
   1494 static const struct country_op_class us_op_class[] = {
   1495 	{ 1, 115 },
   1496 	{ 2, 118 },
   1497 	{ 3, 124 },
   1498 	{ 4, 121 },
   1499 	{ 5, 125 },
   1500 	{ 12, 81 },
   1501 	{ 22, 116 },
   1502 	{ 23, 119 },
   1503 	{ 24, 122 },
   1504 	{ 25, 126 },
   1505 	{ 26, 126 },
   1506 	{ 27, 117 },
   1507 	{ 28, 120 },
   1508 	{ 29, 123 },
   1509 	{ 30, 127 },
   1510 	{ 31, 127 },
   1511 	{ 32, 83 },
   1512 	{ 33, 84 },
   1513 	{ 34, 180 },
   1514 };
   1515 
   1516 static const struct country_op_class eu_op_class[] = {
   1517 	{ 1, 115 },
   1518 	{ 2, 118 },
   1519 	{ 3, 121 },
   1520 	{ 4, 81 },
   1521 	{ 5, 116 },
   1522 	{ 6, 119 },
   1523 	{ 7, 122 },
   1524 	{ 8, 117 },
   1525 	{ 9, 120 },
   1526 	{ 10, 123 },
   1527 	{ 11, 83 },
   1528 	{ 12, 84 },
   1529 	{ 17, 125 },
   1530 	{ 18, 180 },
   1531 };
   1532 
   1533 static const struct country_op_class jp_op_class[] = {
   1534 	{ 1, 115 },
   1535 	{ 30, 81 },
   1536 	{ 31, 82 },
   1537 	{ 32, 118 },
   1538 	{ 33, 118 },
   1539 	{ 34, 121 },
   1540 	{ 35, 121 },
   1541 	{ 36, 116 },
   1542 	{ 37, 119 },
   1543 	{ 38, 119 },
   1544 	{ 39, 122 },
   1545 	{ 40, 122 },
   1546 	{ 41, 117 },
   1547 	{ 42, 120 },
   1548 	{ 43, 120 },
   1549 	{ 44, 123 },
   1550 	{ 45, 123 },
   1551 	{ 56, 83 },
   1552 	{ 57, 84 },
   1553 	{ 58, 121 },
   1554 	{ 59, 180 },
   1555 };
   1556 
   1557 static const struct country_op_class cn_op_class[] = {
   1558 	{ 1, 115 },
   1559 	{ 2, 118 },
   1560 	{ 3, 125 },
   1561 	{ 4, 116 },
   1562 	{ 5, 119 },
   1563 	{ 6, 126 },
   1564 	{ 7, 81 },
   1565 	{ 8, 83 },
   1566 	{ 9, 84 },
   1567 };
   1568 
   1569 static u8
   1570 global_op_class_from_country_array(u8 op_class, size_t array_size,
   1571 				   const struct country_op_class *country_array)
   1572 {
   1573 	size_t i;
   1574 
   1575 	for (i = 0; i < array_size; i++) {
   1576 		if (country_array[i].country_op_class == op_class)
   1577 			return country_array[i].global_op_class;
   1578 	}
   1579 
   1580 	return 0;
   1581 }
   1582 
   1583 
   1584 u8 country_to_global_op_class(const char *country, u8 op_class)
   1585 {
   1586 	const struct country_op_class *country_array;
   1587 	size_t size;
   1588 	u8 g_op_class;
   1589 
   1590 	if (country_match(us_op_class_cc, country)) {
   1591 		country_array = us_op_class;
   1592 		size = ARRAY_SIZE(us_op_class);
   1593 	} else if (country_match(eu_op_class_cc, country)) {
   1594 		country_array = eu_op_class;
   1595 		size = ARRAY_SIZE(eu_op_class);
   1596 	} else if (country_match(jp_op_class_cc, country)) {
   1597 		country_array = jp_op_class;
   1598 		size = ARRAY_SIZE(jp_op_class);
   1599 	} else if (country_match(cn_op_class_cc, country)) {
   1600 		country_array = cn_op_class;
   1601 		size = ARRAY_SIZE(cn_op_class);
   1602 	} else {
   1603 		/*
   1604 		 * Countries that do not match any of the above countries use
   1605 		 * global operating classes
   1606 		 */
   1607 		return op_class;
   1608 	}
   1609 
   1610 	g_op_class = global_op_class_from_country_array(op_class, size,
   1611 							country_array);
   1612 
   1613 	/*
   1614 	 * If the given operating class did not match any of the country's
   1615 	 * operating classes, assume that global operating class is used.
   1616 	 */
   1617 	return g_op_class ? g_op_class : op_class;
   1618 }
   1619 
   1620 
   1621 const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
   1622 {
   1623 	const struct oper_class_map *op;
   1624 
   1625 	if (country)
   1626 		op_class = country_to_global_op_class(country, op_class);
   1627 
   1628 	op = &global_op_class[0];
   1629 	while (op->op_class && op->op_class != op_class)
   1630 		op++;
   1631 
   1632 	if (!op->op_class)
   1633 		return NULL;
   1634 
   1635 	return op;
   1636 }
   1637 
   1638 
   1639 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
   1640 				    size_t nei_rep_len)
   1641 {
   1642 	u8 *nei_pos = nei_rep;
   1643 	const char *end;
   1644 
   1645 	/*
   1646 	 * BSS Transition Candidate List Entries - Neighbor Report elements
   1647 	 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
   1648 	 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
   1649 	 */
   1650 	while (pos) {
   1651 		u8 *nei_start;
   1652 		long int val;
   1653 		char *endptr, *tmp;
   1654 
   1655 		pos = os_strstr(pos, " neighbor=");
   1656 		if (!pos)
   1657 			break;
   1658 		if (nei_pos + 15 > nei_rep + nei_rep_len) {
   1659 			wpa_printf(MSG_DEBUG,
   1660 				   "Not enough room for additional neighbor");
   1661 			return -1;
   1662 		}
   1663 		pos += 10;
   1664 
   1665 		nei_start = nei_pos;
   1666 		*nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
   1667 		nei_pos++; /* length to be filled in */
   1668 
   1669 		if (hwaddr_aton(pos, nei_pos)) {
   1670 			wpa_printf(MSG_DEBUG, "Invalid BSSID");
   1671 			return -1;
   1672 		}
   1673 		nei_pos += ETH_ALEN;
   1674 		pos += 17;
   1675 		if (*pos != ',') {
   1676 			wpa_printf(MSG_DEBUG, "Missing BSSID Information");
   1677 			return -1;
   1678 		}
   1679 		pos++;
   1680 
   1681 		val = strtol(pos, &endptr, 0);
   1682 		WPA_PUT_LE32(nei_pos, val);
   1683 		nei_pos += 4;
   1684 		if (*endptr != ',') {
   1685 			wpa_printf(MSG_DEBUG, "Missing Operating Class");
   1686 			return -1;
   1687 		}
   1688 		pos = endptr + 1;
   1689 
   1690 		*nei_pos++ = atoi(pos); /* Operating Class */
   1691 		pos = os_strchr(pos, ',');
   1692 		if (pos == NULL) {
   1693 			wpa_printf(MSG_DEBUG, "Missing Channel Number");
   1694 			return -1;
   1695 		}
   1696 		pos++;
   1697 
   1698 		*nei_pos++ = atoi(pos); /* Channel Number */
   1699 		pos = os_strchr(pos, ',');
   1700 		if (pos == NULL) {
   1701 			wpa_printf(MSG_DEBUG, "Missing PHY Type");
   1702 			return -1;
   1703 		}
   1704 		pos++;
   1705 
   1706 		*nei_pos++ = atoi(pos); /* PHY Type */
   1707 		end = os_strchr(pos, ' ');
   1708 		tmp = os_strchr(pos, ',');
   1709 		if (tmp && (!end || tmp < end)) {
   1710 			/* Optional Subelements (hexdump) */
   1711 			size_t len;
   1712 
   1713 			pos = tmp + 1;
   1714 			end = os_strchr(pos, ' ');
   1715 			if (end)
   1716 				len = end - pos;
   1717 			else
   1718 				len = os_strlen(pos);
   1719 			if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
   1720 				wpa_printf(MSG_DEBUG,
   1721 					   "Not enough room for neighbor subelements");
   1722 				return -1;
   1723 			}
   1724 			if (len & 0x01 ||
   1725 			    hexstr2bin(pos, nei_pos, len / 2) < 0) {
   1726 				wpa_printf(MSG_DEBUG,
   1727 					   "Invalid neighbor subelement info");
   1728 				return -1;
   1729 			}
   1730 			nei_pos += len / 2;
   1731 			pos = end;
   1732 		}
   1733 
   1734 		nei_start[1] = nei_pos - nei_start - 2;
   1735 	}
   1736 
   1737 	return nei_pos - nei_rep;
   1738 }
   1739