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