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