xref: /freebsd/contrib/wpa/src/common/ieee802_11_common.c (revision fab66680b3df4792fb0d3d13b2c9cdd88538d3d2)
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_OCV_OCI:
278 		elems->oci = pos;
279 		elems->oci_len = elen;
280 		break;
281 	default:
282 		if (show_errors) {
283 			wpa_printf(MSG_MSGDUMP,
284 				   "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
285 				   ext_id, (unsigned int) elen);
286 		}
287 		return -1;
288 	}
289 
290 	return 0;
291 }
292 
293 
294 /**
295  * ieee802_11_parse_elems - Parse information elements in management frames
296  * @start: Pointer to the start of IEs
297  * @len: Length of IE buffer in octets
298  * @elems: Data structure for parsed elements
299  * @show_errors: Whether to show parsing errors in debug log
300  * Returns: Parsing result
301  */
302 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
303 				struct ieee802_11_elems *elems,
304 				int show_errors)
305 {
306 	const struct element *elem;
307 	int unknown = 0;
308 
309 	os_memset(elems, 0, sizeof(*elems));
310 
311 	if (!start)
312 		return ParseOK;
313 
314 	for_each_element(elem, start, len) {
315 		u8 id = elem->id, elen = elem->datalen;
316 		const u8 *pos = elem->data;
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 			goto done;
465 		case WLAN_EID_MULTI_BAND:
466 			if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
467 				wpa_printf(MSG_MSGDUMP,
468 					   "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
469 					   id, elen);
470 				break;
471 			}
472 
473 			elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
474 			elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
475 			elems->mb_ies.nof_ies++;
476 			break;
477 		case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
478 			elems->supp_op_classes = pos;
479 			elems->supp_op_classes_len = elen;
480 			break;
481 		case WLAN_EID_RRM_ENABLED_CAPABILITIES:
482 			elems->rrm_enabled = pos;
483 			elems->rrm_enabled_len = elen;
484 			break;
485 		case WLAN_EID_CAG_NUMBER:
486 			elems->cag_number = pos;
487 			elems->cag_number_len = elen;
488 			break;
489 		case WLAN_EID_AP_CSN:
490 			if (elen < 1)
491 				break;
492 			elems->ap_csn = pos;
493 			break;
494 		case WLAN_EID_FILS_INDICATION:
495 			if (elen < 2)
496 				break;
497 			elems->fils_indic = pos;
498 			elems->fils_indic_len = elen;
499 			break;
500 		case WLAN_EID_DILS:
501 			if (elen < 2)
502 				break;
503 			elems->dils = pos;
504 			elems->dils_len = elen;
505 			break;
506 		case WLAN_EID_FRAGMENT:
507 			/* TODO */
508 			break;
509 		case WLAN_EID_EXTENSION:
510 			if (ieee802_11_parse_extension(pos, elen, elems,
511 						       show_errors))
512 				unknown++;
513 			break;
514 		default:
515 			unknown++;
516 			if (!show_errors)
517 				break;
518 			wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
519 				   "ignored unknown element (id=%d elen=%d)",
520 				   id, elen);
521 			break;
522 		}
523 	}
524 
525 	if (!for_each_element_completed(elem, start, len)) {
526 		if (show_errors) {
527 			wpa_printf(MSG_DEBUG,
528 				   "IEEE 802.11 element parse failed @%d",
529 				   (int) (start + len - (const u8 *) elem));
530 			wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
531 		}
532 		return ParseFailed;
533 	}
534 
535 done:
536 	return unknown ? ParseUnknown : ParseOK;
537 }
538 
539 
540 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
541 {
542 	const struct element *elem;
543 	int count = 0;
544 
545 	if (ies == NULL)
546 		return 0;
547 
548 	for_each_element(elem, ies, ies_len)
549 		count++;
550 
551 	return count;
552 }
553 
554 
555 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
556 					    u32 oui_type)
557 {
558 	struct wpabuf *buf;
559 	const struct element *elem, *found = NULL;
560 
561 	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
562 		if (elem->datalen >= 4 &&
563 		    WPA_GET_BE32(elem->data) == oui_type) {
564 			found = elem;
565 			break;
566 		}
567 	}
568 
569 	if (!found)
570 		return NULL; /* No specified vendor IE found */
571 
572 	buf = wpabuf_alloc(ies_len);
573 	if (buf == NULL)
574 		return NULL;
575 
576 	/*
577 	 * There may be multiple vendor IEs in the message, so need to
578 	 * concatenate their data fields.
579 	 */
580 	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
581 		if (elem->datalen >= 4 && WPA_GET_BE32(elem->data) == oui_type)
582 			wpabuf_put_data(buf, elem->data + 4, elem->datalen - 4);
583 	}
584 
585 	return buf;
586 }
587 
588 
589 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
590 {
591 	u16 fc, type, stype;
592 
593 	/*
594 	 * PS-Poll frames are 16 bytes. All other frames are
595 	 * 24 bytes or longer.
596 	 */
597 	if (len < 16)
598 		return NULL;
599 
600 	fc = le_to_host16(hdr->frame_control);
601 	type = WLAN_FC_GET_TYPE(fc);
602 	stype = WLAN_FC_GET_STYPE(fc);
603 
604 	switch (type) {
605 	case WLAN_FC_TYPE_DATA:
606 		if (len < 24)
607 			return NULL;
608 		switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
609 		case WLAN_FC_FROMDS | WLAN_FC_TODS:
610 		case WLAN_FC_TODS:
611 			return hdr->addr1;
612 		case WLAN_FC_FROMDS:
613 			return hdr->addr2;
614 		default:
615 			return NULL;
616 		}
617 	case WLAN_FC_TYPE_CTRL:
618 		if (stype != WLAN_FC_STYPE_PSPOLL)
619 			return NULL;
620 		return hdr->addr1;
621 	case WLAN_FC_TYPE_MGMT:
622 		return hdr->addr3;
623 	default:
624 		return NULL;
625 	}
626 }
627 
628 
629 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
630 			  const char *name, const char *val)
631 {
632 	int num, v;
633 	const char *pos;
634 	struct hostapd_wmm_ac_params *ac;
635 
636 	/* skip 'wme_ac_' or 'wmm_ac_' prefix */
637 	pos = name + 7;
638 	if (os_strncmp(pos, "be_", 3) == 0) {
639 		num = 0;
640 		pos += 3;
641 	} else if (os_strncmp(pos, "bk_", 3) == 0) {
642 		num = 1;
643 		pos += 3;
644 	} else if (os_strncmp(pos, "vi_", 3) == 0) {
645 		num = 2;
646 		pos += 3;
647 	} else if (os_strncmp(pos, "vo_", 3) == 0) {
648 		num = 3;
649 		pos += 3;
650 	} else {
651 		wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
652 		return -1;
653 	}
654 
655 	ac = &wmm_ac_params[num];
656 
657 	if (os_strcmp(pos, "aifs") == 0) {
658 		v = atoi(val);
659 		if (v < 1 || v > 255) {
660 			wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
661 			return -1;
662 		}
663 		ac->aifs = v;
664 	} else if (os_strcmp(pos, "cwmin") == 0) {
665 		v = atoi(val);
666 		if (v < 0 || v > 15) {
667 			wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
668 			return -1;
669 		}
670 		ac->cwmin = v;
671 	} else if (os_strcmp(pos, "cwmax") == 0) {
672 		v = atoi(val);
673 		if (v < 0 || v > 15) {
674 			wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
675 			return -1;
676 		}
677 		ac->cwmax = v;
678 	} else if (os_strcmp(pos, "txop_limit") == 0) {
679 		v = atoi(val);
680 		if (v < 0 || v > 0xffff) {
681 			wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
682 			return -1;
683 		}
684 		ac->txop_limit = v;
685 	} else if (os_strcmp(pos, "acm") == 0) {
686 		v = atoi(val);
687 		if (v < 0 || v > 1) {
688 			wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
689 			return -1;
690 		}
691 		ac->admission_control_mandatory = v;
692 	} else {
693 		wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
694 		return -1;
695 	}
696 
697 	return 0;
698 }
699 
700 
701 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
702 {
703 	u8 op_class;
704 
705 	return ieee80211_freq_to_channel_ext(freq, 0, VHT_CHANWIDTH_USE_HT,
706 					     &op_class, channel);
707 }
708 
709 
710 /**
711  * ieee80211_freq_to_channel_ext - Convert frequency into channel info
712  * for HT40 and VHT. DFS channels are not covered.
713  * @freq: Frequency (MHz) to convert
714  * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
715  * @vht: VHT channel width (VHT_CHANWIDTH_*)
716  * @op_class: Buffer for returning operating class
717  * @channel: Buffer for returning channel number
718  * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
719  */
720 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
721 						   int sec_channel, int vht,
722 						   u8 *op_class, u8 *channel)
723 {
724 	u8 vht_opclass;
725 
726 	/* TODO: more operating classes */
727 
728 	if (sec_channel > 1 || sec_channel < -1)
729 		return NUM_HOSTAPD_MODES;
730 
731 	if (freq >= 2412 && freq <= 2472) {
732 		if ((freq - 2407) % 5)
733 			return NUM_HOSTAPD_MODES;
734 
735 		if (vht)
736 			return NUM_HOSTAPD_MODES;
737 
738 		/* 2.407 GHz, channels 1..13 */
739 		if (sec_channel == 1)
740 			*op_class = 83;
741 		else if (sec_channel == -1)
742 			*op_class = 84;
743 		else
744 			*op_class = 81;
745 
746 		*channel = (freq - 2407) / 5;
747 
748 		return HOSTAPD_MODE_IEEE80211G;
749 	}
750 
751 	if (freq == 2484) {
752 		if (sec_channel || vht)
753 			return NUM_HOSTAPD_MODES;
754 
755 		*op_class = 82; /* channel 14 */
756 		*channel = 14;
757 
758 		return HOSTAPD_MODE_IEEE80211B;
759 	}
760 
761 	if (freq >= 4900 && freq < 5000) {
762 		if ((freq - 4000) % 5)
763 			return NUM_HOSTAPD_MODES;
764 		*channel = (freq - 4000) / 5;
765 		*op_class = 0; /* TODO */
766 		return HOSTAPD_MODE_IEEE80211A;
767 	}
768 
769 	switch (vht) {
770 	case VHT_CHANWIDTH_80MHZ:
771 		vht_opclass = 128;
772 		break;
773 	case VHT_CHANWIDTH_160MHZ:
774 		vht_opclass = 129;
775 		break;
776 	case VHT_CHANWIDTH_80P80MHZ:
777 		vht_opclass = 130;
778 		break;
779 	default:
780 		vht_opclass = 0;
781 		break;
782 	}
783 
784 	/* 5 GHz, channels 36..48 */
785 	if (freq >= 5180 && freq <= 5240) {
786 		if ((freq - 5000) % 5)
787 			return NUM_HOSTAPD_MODES;
788 
789 		if (vht_opclass)
790 			*op_class = vht_opclass;
791 		else if (sec_channel == 1)
792 			*op_class = 116;
793 		else if (sec_channel == -1)
794 			*op_class = 117;
795 		else
796 			*op_class = 115;
797 
798 		*channel = (freq - 5000) / 5;
799 
800 		return HOSTAPD_MODE_IEEE80211A;
801 	}
802 
803 	/* 5 GHz, channels 52..64 */
804 	if (freq >= 5260 && freq <= 5320) {
805 		if ((freq - 5000) % 5)
806 			return NUM_HOSTAPD_MODES;
807 
808 		if (vht_opclass)
809 			*op_class = vht_opclass;
810 		else if (sec_channel == 1)
811 			*op_class = 119;
812 		else if (sec_channel == -1)
813 			*op_class = 120;
814 		else
815 			*op_class = 118;
816 
817 		*channel = (freq - 5000) / 5;
818 
819 		return HOSTAPD_MODE_IEEE80211A;
820 	}
821 
822 	/* 5 GHz, channels 149..169 */
823 	if (freq >= 5745 && freq <= 5845) {
824 		if ((freq - 5000) % 5)
825 			return NUM_HOSTAPD_MODES;
826 
827 		if (vht_opclass)
828 			*op_class = vht_opclass;
829 		else if (sec_channel == 1)
830 			*op_class = 126;
831 		else if (sec_channel == -1)
832 			*op_class = 127;
833 		else if (freq <= 5805)
834 			*op_class = 124;
835 		else
836 			*op_class = 125;
837 
838 		*channel = (freq - 5000) / 5;
839 
840 		return HOSTAPD_MODE_IEEE80211A;
841 	}
842 
843 	/* 5 GHz, channels 100..140 */
844 	if (freq >= 5000 && freq <= 5700) {
845 		if ((freq - 5000) % 5)
846 			return NUM_HOSTAPD_MODES;
847 
848 		if (vht_opclass)
849 			*op_class = vht_opclass;
850 		else if (sec_channel == 1)
851 			*op_class = 122;
852 		else if (sec_channel == -1)
853 			*op_class = 123;
854 		else
855 			*op_class = 121;
856 
857 		*channel = (freq - 5000) / 5;
858 
859 		return HOSTAPD_MODE_IEEE80211A;
860 	}
861 
862 	if (freq >= 5000 && freq < 5900) {
863 		if ((freq - 5000) % 5)
864 			return NUM_HOSTAPD_MODES;
865 		*channel = (freq - 5000) / 5;
866 		*op_class = 0; /* TODO */
867 		return HOSTAPD_MODE_IEEE80211A;
868 	}
869 
870 	/* 56.16 GHz, channel 1..4 */
871 	if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
872 		if (sec_channel || vht)
873 			return NUM_HOSTAPD_MODES;
874 
875 		*channel = (freq - 56160) / 2160;
876 		*op_class = 180;
877 
878 		return HOSTAPD_MODE_IEEE80211AD;
879 	}
880 
881 	return NUM_HOSTAPD_MODES;
882 }
883 
884 
885 int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
886 				  int sec_channel, u8 *op_class, u8 *channel)
887 {
888 	int vht = CHAN_WIDTH_UNKNOWN;
889 
890 	switch (chanwidth) {
891 	case CHAN_WIDTH_UNKNOWN:
892 	case CHAN_WIDTH_20_NOHT:
893 	case CHAN_WIDTH_20:
894 	case CHAN_WIDTH_40:
895 		vht = VHT_CHANWIDTH_USE_HT;
896 		break;
897 	case CHAN_WIDTH_80:
898 		vht = VHT_CHANWIDTH_80MHZ;
899 		break;
900 	case CHAN_WIDTH_80P80:
901 		vht = VHT_CHANWIDTH_80P80MHZ;
902 		break;
903 	case CHAN_WIDTH_160:
904 		vht = VHT_CHANWIDTH_160MHZ;
905 		break;
906 	}
907 
908 	if (ieee80211_freq_to_channel_ext(freq, sec_channel, vht, op_class,
909 					  channel) == NUM_HOSTAPD_MODES) {
910 		wpa_printf(MSG_WARNING,
911 			   "Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)",
912 			   freq, chanwidth, sec_channel);
913 		return -1;
914 	}
915 
916 	return 0;
917 }
918 
919 
920 static const char *const us_op_class_cc[] = {
921 	"US", "CA", NULL
922 };
923 
924 static const char *const eu_op_class_cc[] = {
925 	"AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
926 	"DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
927 	"LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
928 	"RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
929 };
930 
931 static const char *const jp_op_class_cc[] = {
932 	"JP", NULL
933 };
934 
935 static const char *const cn_op_class_cc[] = {
936 	"CN", NULL
937 };
938 
939 
940 static int country_match(const char *const cc[], const char *const country)
941 {
942 	int i;
943 
944 	if (country == NULL)
945 		return 0;
946 	for (i = 0; cc[i]; i++) {
947 		if (cc[i][0] == country[0] && cc[i][1] == country[1])
948 			return 1;
949 	}
950 
951 	return 0;
952 }
953 
954 
955 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
956 {
957 	switch (op_class) {
958 	case 12: /* channels 1..11 */
959 	case 32: /* channels 1..7; 40 MHz */
960 	case 33: /* channels 5..11; 40 MHz */
961 		if (chan < 1 || chan > 11)
962 			return -1;
963 		return 2407 + 5 * chan;
964 	case 1: /* channels 36,40,44,48 */
965 	case 2: /* channels 52,56,60,64; dfs */
966 	case 22: /* channels 36,44; 40 MHz */
967 	case 23: /* channels 52,60; 40 MHz */
968 	case 27: /* channels 40,48; 40 MHz */
969 	case 28: /* channels 56,64; 40 MHz */
970 		if (chan < 36 || chan > 64)
971 			return -1;
972 		return 5000 + 5 * chan;
973 	case 4: /* channels 100-144 */
974 	case 24: /* channels 100-140; 40 MHz */
975 		if (chan < 100 || chan > 144)
976 			return -1;
977 		return 5000 + 5 * chan;
978 	case 3: /* channels 149,153,157,161 */
979 	case 25: /* channels 149,157; 40 MHz */
980 	case 26: /* channels 149,157; 40 MHz */
981 	case 30: /* channels 153,161; 40 MHz */
982 	case 31: /* channels 153,161; 40 MHz */
983 		if (chan < 149 || chan > 161)
984 			return -1;
985 		return 5000 + 5 * chan;
986 	case 5: /* channels 149,153,157,161,165 */
987 		if (chan < 149 || chan > 165)
988 			return -1;
989 		return 5000 + 5 * chan;
990 	case 34: /* 60 GHz band, channels 1..3 */
991 		if (chan < 1 || chan > 3)
992 			return -1;
993 		return 56160 + 2160 * chan;
994 	}
995 	return -1;
996 }
997 
998 
999 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
1000 {
1001 	switch (op_class) {
1002 	case 4: /* channels 1..13 */
1003 	case 11: /* channels 1..9; 40 MHz */
1004 	case 12: /* channels 5..13; 40 MHz */
1005 		if (chan < 1 || chan > 13)
1006 			return -1;
1007 		return 2407 + 5 * chan;
1008 	case 1: /* channels 36,40,44,48 */
1009 	case 2: /* channels 52,56,60,64; dfs */
1010 	case 5: /* channels 36,44; 40 MHz */
1011 	case 6: /* channels 52,60; 40 MHz */
1012 	case 8: /* channels 40,48; 40 MHz */
1013 	case 9: /* channels 56,64; 40 MHz */
1014 		if (chan < 36 || chan > 64)
1015 			return -1;
1016 		return 5000 + 5 * chan;
1017 	case 3: /* channels 100-140 */
1018 	case 7: /* channels 100-132; 40 MHz */
1019 	case 10: /* channels 104-136; 40 MHz */
1020 	case 16: /* channels 100-140 */
1021 		if (chan < 100 || chan > 140)
1022 			return -1;
1023 		return 5000 + 5 * chan;
1024 	case 17: /* channels 149,153,157,161,165,169 */
1025 		if (chan < 149 || chan > 169)
1026 			return -1;
1027 		return 5000 + 5 * chan;
1028 	case 18: /* 60 GHz band, channels 1..4 */
1029 		if (chan < 1 || chan > 4)
1030 			return -1;
1031 		return 56160 + 2160 * chan;
1032 	}
1033 	return -1;
1034 }
1035 
1036 
1037 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
1038 {
1039 	switch (op_class) {
1040 	case 30: /* channels 1..13 */
1041 	case 56: /* channels 1..9; 40 MHz */
1042 	case 57: /* channels 5..13; 40 MHz */
1043 		if (chan < 1 || chan > 13)
1044 			return -1;
1045 		return 2407 + 5 * chan;
1046 	case 31: /* channel 14 */
1047 		if (chan != 14)
1048 			return -1;
1049 		return 2414 + 5 * chan;
1050 	case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
1051 	case 32: /* channels 52,56,60,64 */
1052 	case 33: /* channels 52,56,60,64 */
1053 	case 36: /* channels 36,44; 40 MHz */
1054 	case 37: /* channels 52,60; 40 MHz */
1055 	case 38: /* channels 52,60; 40 MHz */
1056 	case 41: /* channels 40,48; 40 MHz */
1057 	case 42: /* channels 56,64; 40 MHz */
1058 	case 43: /* channels 56,64; 40 MHz */
1059 		if (chan < 34 || chan > 64)
1060 			return -1;
1061 		return 5000 + 5 * chan;
1062 	case 34: /* channels 100-140 */
1063 	case 35: /* channels 100-140 */
1064 	case 39: /* channels 100-132; 40 MHz */
1065 	case 40: /* channels 100-132; 40 MHz */
1066 	case 44: /* channels 104-136; 40 MHz */
1067 	case 45: /* channels 104-136; 40 MHz */
1068 	case 58: /* channels 100-140 */
1069 		if (chan < 100 || chan > 140)
1070 			return -1;
1071 		return 5000 + 5 * chan;
1072 	case 59: /* 60 GHz band, channels 1..4 */
1073 		if (chan < 1 || chan > 3)
1074 			return -1;
1075 		return 56160 + 2160 * chan;
1076 	}
1077 	return -1;
1078 }
1079 
1080 
1081 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
1082 {
1083 	switch (op_class) {
1084 	case 7: /* channels 1..13 */
1085 	case 8: /* channels 1..9; 40 MHz */
1086 	case 9: /* channels 5..13; 40 MHz */
1087 		if (chan < 1 || chan > 13)
1088 			return -1;
1089 		return 2407 + 5 * chan;
1090 	case 1: /* channels 36,40,44,48 */
1091 	case 2: /* channels 52,56,60,64; dfs */
1092 	case 4: /* channels 36,44; 40 MHz */
1093 	case 5: /* channels 52,60; 40 MHz */
1094 		if (chan < 36 || chan > 64)
1095 			return -1;
1096 		return 5000 + 5 * chan;
1097 	case 3: /* channels 149,153,157,161,165 */
1098 	case 6: /* channels 149,157; 40 MHz */
1099 		if (chan < 149 || chan > 165)
1100 			return -1;
1101 		return 5000 + 5 * chan;
1102 	}
1103 	return -1;
1104 }
1105 
1106 
1107 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
1108 {
1109 	/* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
1110 	switch (op_class) {
1111 	case 81:
1112 		/* channels 1..13 */
1113 		if (chan < 1 || chan > 13)
1114 			return -1;
1115 		return 2407 + 5 * chan;
1116 	case 82:
1117 		/* channel 14 */
1118 		if (chan != 14)
1119 			return -1;
1120 		return 2414 + 5 * chan;
1121 	case 83: /* channels 1..9; 40 MHz */
1122 	case 84: /* channels 5..13; 40 MHz */
1123 		if (chan < 1 || chan > 13)
1124 			return -1;
1125 		return 2407 + 5 * chan;
1126 	case 115: /* channels 36,40,44,48; indoor only */
1127 	case 116: /* channels 36,44; 40 MHz; indoor only */
1128 	case 117: /* channels 40,48; 40 MHz; indoor only */
1129 	case 118: /* channels 52,56,60,64; dfs */
1130 	case 119: /* channels 52,60; 40 MHz; dfs */
1131 	case 120: /* channels 56,64; 40 MHz; dfs */
1132 		if (chan < 36 || chan > 64)
1133 			return -1;
1134 		return 5000 + 5 * chan;
1135 	case 121: /* channels 100-140 */
1136 	case 122: /* channels 100-142; 40 MHz */
1137 	case 123: /* channels 104-136; 40 MHz */
1138 		if (chan < 100 || chan > 140)
1139 			return -1;
1140 		return 5000 + 5 * chan;
1141 	case 124: /* channels 149,153,157,161 */
1142 	case 126: /* channels 149,157; 40 MHz */
1143 	case 127: /* channels 153,161; 40 MHz */
1144 		if (chan < 149 || chan > 161)
1145 			return -1;
1146 		return 5000 + 5 * chan;
1147 	case 125: /* channels 149,153,157,161,165,169 */
1148 		if (chan < 149 || chan > 169)
1149 			return -1;
1150 		return 5000 + 5 * chan;
1151 	case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1152 	case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1153 		if (chan < 36 || chan > 161)
1154 			return -1;
1155 		return 5000 + 5 * chan;
1156 	case 129: /* center freqs 50, 114; 160 MHz */
1157 		if (chan < 36 || chan > 128)
1158 			return -1;
1159 		return 5000 + 5 * chan;
1160 	case 180: /* 60 GHz band, channels 1..4 */
1161 		if (chan < 1 || chan > 4)
1162 			return -1;
1163 		return 56160 + 2160 * chan;
1164 	}
1165 	return -1;
1166 }
1167 
1168 /**
1169  * ieee80211_chan_to_freq - Convert channel info to frequency
1170  * @country: Country code, if known; otherwise, global operating class is used
1171  * @op_class: Operating class
1172  * @chan: Channel number
1173  * Returns: Frequency in MHz or -1 if the specified channel is unknown
1174  */
1175 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
1176 {
1177 	int freq;
1178 
1179 	if (country_match(us_op_class_cc, country)) {
1180 		freq = ieee80211_chan_to_freq_us(op_class, chan);
1181 		if (freq > 0)
1182 			return freq;
1183 	}
1184 
1185 	if (country_match(eu_op_class_cc, country)) {
1186 		freq = ieee80211_chan_to_freq_eu(op_class, chan);
1187 		if (freq > 0)
1188 			return freq;
1189 	}
1190 
1191 	if (country_match(jp_op_class_cc, country)) {
1192 		freq = ieee80211_chan_to_freq_jp(op_class, chan);
1193 		if (freq > 0)
1194 			return freq;
1195 	}
1196 
1197 	if (country_match(cn_op_class_cc, country)) {
1198 		freq = ieee80211_chan_to_freq_cn(op_class, chan);
1199 		if (freq > 0)
1200 			return freq;
1201 	}
1202 
1203 	return ieee80211_chan_to_freq_global(op_class, chan);
1204 }
1205 
1206 
1207 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
1208 		     u16 num_modes)
1209 {
1210 	int i, j;
1211 
1212 	if (!modes || !num_modes)
1213 		return (freq >= 5260 && freq <= 5320) ||
1214 			(freq >= 5500 && freq <= 5700);
1215 
1216 	for (i = 0; i < num_modes; i++) {
1217 		for (j = 0; j < modes[i].num_channels; j++) {
1218 			if (modes[i].channels[j].freq == freq &&
1219 			    (modes[i].channels[j].flag & HOSTAPD_CHAN_RADAR))
1220 				return 1;
1221 		}
1222 	}
1223 
1224 	return 0;
1225 }
1226 
1227 
1228 static int is_11b(u8 rate)
1229 {
1230 	return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1231 }
1232 
1233 
1234 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1235 {
1236 	int num_11b = 0, num_others = 0;
1237 	int i;
1238 
1239 	if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1240 		return 0;
1241 
1242 	for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1243 		if (is_11b(elems->supp_rates[i]))
1244 			num_11b++;
1245 		else
1246 			num_others++;
1247 	}
1248 
1249 	for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1250 	     i++) {
1251 		if (is_11b(elems->ext_supp_rates[i]))
1252 			num_11b++;
1253 		else
1254 			num_others++;
1255 	}
1256 
1257 	return num_11b > 0 && num_others == 0;
1258 }
1259 
1260 
1261 const char * fc2str(u16 fc)
1262 {
1263 	u16 stype = WLAN_FC_GET_STYPE(fc);
1264 #define C2S(x) case x: return #x;
1265 
1266 	switch (WLAN_FC_GET_TYPE(fc)) {
1267 	case WLAN_FC_TYPE_MGMT:
1268 		switch (stype) {
1269 		C2S(WLAN_FC_STYPE_ASSOC_REQ)
1270 		C2S(WLAN_FC_STYPE_ASSOC_RESP)
1271 		C2S(WLAN_FC_STYPE_REASSOC_REQ)
1272 		C2S(WLAN_FC_STYPE_REASSOC_RESP)
1273 		C2S(WLAN_FC_STYPE_PROBE_REQ)
1274 		C2S(WLAN_FC_STYPE_PROBE_RESP)
1275 		C2S(WLAN_FC_STYPE_BEACON)
1276 		C2S(WLAN_FC_STYPE_ATIM)
1277 		C2S(WLAN_FC_STYPE_DISASSOC)
1278 		C2S(WLAN_FC_STYPE_AUTH)
1279 		C2S(WLAN_FC_STYPE_DEAUTH)
1280 		C2S(WLAN_FC_STYPE_ACTION)
1281 		}
1282 		break;
1283 	case WLAN_FC_TYPE_CTRL:
1284 		switch (stype) {
1285 		C2S(WLAN_FC_STYPE_PSPOLL)
1286 		C2S(WLAN_FC_STYPE_RTS)
1287 		C2S(WLAN_FC_STYPE_CTS)
1288 		C2S(WLAN_FC_STYPE_ACK)
1289 		C2S(WLAN_FC_STYPE_CFEND)
1290 		C2S(WLAN_FC_STYPE_CFENDACK)
1291 		}
1292 		break;
1293 	case WLAN_FC_TYPE_DATA:
1294 		switch (stype) {
1295 		C2S(WLAN_FC_STYPE_DATA)
1296 		C2S(WLAN_FC_STYPE_DATA_CFACK)
1297 		C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1298 		C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1299 		C2S(WLAN_FC_STYPE_NULLFUNC)
1300 		C2S(WLAN_FC_STYPE_CFACK)
1301 		C2S(WLAN_FC_STYPE_CFPOLL)
1302 		C2S(WLAN_FC_STYPE_CFACKPOLL)
1303 		C2S(WLAN_FC_STYPE_QOS_DATA)
1304 		C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1305 		C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1306 		C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1307 		C2S(WLAN_FC_STYPE_QOS_NULL)
1308 		C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1309 		C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1310 		}
1311 		break;
1312 	}
1313 	return "WLAN_FC_TYPE_UNKNOWN";
1314 #undef C2S
1315 }
1316 
1317 
1318 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1319 		       size_t ies_len)
1320 {
1321 	const struct element *elem;
1322 
1323 	os_memset(info, 0, sizeof(*info));
1324 
1325 	if (!ies_buf)
1326 		return 0;
1327 
1328 	for_each_element_id(elem, WLAN_EID_MULTI_BAND, ies_buf, ies_len) {
1329 		if (info->nof_ies >= MAX_NOF_MB_IES_SUPPORTED)
1330 			return 0;
1331 
1332 		wpa_printf(MSG_DEBUG, "MB IE of %u bytes found",
1333 			   elem->datalen + 2);
1334 		info->ies[info->nof_ies].ie = elem->data;
1335 		info->ies[info->nof_ies].ie_len = elem->datalen;
1336 		info->nof_ies++;
1337 	}
1338 
1339 	if (!for_each_element_completed(elem, ies_buf, ies_len)) {
1340 		wpa_hexdump(MSG_DEBUG, "Truncated IEs", ies_buf, ies_len);
1341 		return -1;
1342 	}
1343 
1344 	return 0;
1345 }
1346 
1347 
1348 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1349 {
1350 	struct wpabuf *mb_ies = NULL;
1351 
1352 	WPA_ASSERT(info != NULL);
1353 
1354 	if (info->nof_ies) {
1355 		u8 i;
1356 		size_t mb_ies_size = 0;
1357 
1358 		for (i = 0; i < info->nof_ies; i++)
1359 			mb_ies_size += 2 + info->ies[i].ie_len;
1360 
1361 		mb_ies = wpabuf_alloc(mb_ies_size);
1362 		if (mb_ies) {
1363 			for (i = 0; i < info->nof_ies; i++) {
1364 				wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1365 				wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1366 				wpabuf_put_data(mb_ies,
1367 						info->ies[i].ie,
1368 						info->ies[i].ie_len);
1369 			}
1370 		}
1371 	}
1372 
1373 	return mb_ies;
1374 }
1375 
1376 
1377 const struct oper_class_map global_op_class[] = {
1378 	{ HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1379 	{ HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1380 
1381 	/* Do not enable HT40 on 2.4 GHz for P2P use for now */
1382 	{ HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1383 	{ HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1384 
1385 	{ HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1386 	{ HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1387 	{ HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1388 	{ HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1389 	{ HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1390 	{ HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1391 	{ HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1392 	{ HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1393 	{ HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1394 	{ HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1395 	{ HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
1396 	{ HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
1397 	{ HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
1398 
1399 	/*
1400 	 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
1401 	 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
1402 	 * 80 MHz, but currently use the following definition for simplicity
1403 	 * (these center frequencies are not actual channels, which makes
1404 	 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
1405 	 * care of removing invalid channels.
1406 	 */
1407 	{ HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
1408 	{ HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
1409 	{ HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
1410 	{ HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
1411 	{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
1412 };
1413 
1414 
1415 static enum phy_type ieee80211_phy_type_by_freq(int freq)
1416 {
1417 	enum hostapd_hw_mode hw_mode;
1418 	u8 channel;
1419 
1420 	hw_mode = ieee80211_freq_to_chan(freq, &channel);
1421 
1422 	switch (hw_mode) {
1423 	case HOSTAPD_MODE_IEEE80211A:
1424 		return PHY_TYPE_OFDM;
1425 	case HOSTAPD_MODE_IEEE80211B:
1426 		return PHY_TYPE_HRDSSS;
1427 	case HOSTAPD_MODE_IEEE80211G:
1428 		return PHY_TYPE_ERP;
1429 	case HOSTAPD_MODE_IEEE80211AD:
1430 		return PHY_TYPE_DMG;
1431 	default:
1432 		return PHY_TYPE_UNSPECIFIED;
1433 	};
1434 }
1435 
1436 
1437 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
1438 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
1439 {
1440 	if (vht)
1441 		return PHY_TYPE_VHT;
1442 	if (ht)
1443 		return PHY_TYPE_HT;
1444 
1445 	return ieee80211_phy_type_by_freq(freq);
1446 }
1447 
1448 
1449 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
1450 
1451 
1452 /**
1453  * get_ie - Fetch a specified information element from IEs buffer
1454  * @ies: Information elements buffer
1455  * @len: Information elements buffer length
1456  * @eid: Information element identifier (WLAN_EID_*)
1457  * Returns: Pointer to the information element (id field) or %NULL if not found
1458  *
1459  * This function returns the first matching information element in the IEs
1460  * buffer or %NULL in case the element is not found.
1461  */
1462 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
1463 {
1464 	const struct element *elem;
1465 
1466 	if (!ies)
1467 		return NULL;
1468 
1469 	for_each_element_id(elem, eid, ies, len)
1470 		return &elem->id;
1471 
1472 	return NULL;
1473 }
1474 
1475 
1476 /**
1477  * get_ie_ext - Fetch a specified extended information element from IEs buffer
1478  * @ies: Information elements buffer
1479  * @len: Information elements buffer length
1480  * @ext: Information element extension identifier (WLAN_EID_EXT_*)
1481  * Returns: Pointer to the information element (id field) or %NULL if not found
1482  *
1483  * This function returns the first matching information element in the IEs
1484  * buffer or %NULL in case the element is not found.
1485  */
1486 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
1487 {
1488 	const struct element *elem;
1489 
1490 	if (!ies)
1491 		return NULL;
1492 
1493 	for_each_element_extid(elem, ext, ies, len)
1494 		return &elem->id;
1495 
1496 	return NULL;
1497 }
1498 
1499 
1500 const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type)
1501 {
1502 	const struct element *elem;
1503 
1504 	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, len) {
1505 		if (elem->datalen >= 4 &&
1506 		    vendor_type == WPA_GET_BE32(elem->data))
1507 			return &elem->id;
1508 	}
1509 
1510 	return NULL;
1511 }
1512 
1513 
1514 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
1515 {
1516 	/*
1517 	 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
1518 	 * OUI (3), OUI type (1).
1519 	 */
1520 	if (len < 6 + attr_len) {
1521 		wpa_printf(MSG_DEBUG,
1522 			   "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
1523 			   len, attr_len);
1524 		return 0;
1525 	}
1526 
1527 	*buf++ = WLAN_EID_VENDOR_SPECIFIC;
1528 	*buf++ = attr_len + 4;
1529 	WPA_PUT_BE24(buf, OUI_WFA);
1530 	buf += 3;
1531 	*buf++ = MBO_OUI_TYPE;
1532 	os_memcpy(buf, attr, attr_len);
1533 
1534 	return 6 + attr_len;
1535 }
1536 
1537 
1538 size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
1539 {
1540 	u8 *pos = buf;
1541 
1542 	if (len < 9)
1543 		return 0;
1544 
1545 	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
1546 	*pos++ = 7; /* len */
1547 	WPA_PUT_BE24(pos, OUI_WFA);
1548 	pos += 3;
1549 	*pos++ = MULTI_AP_OUI_TYPE;
1550 	*pos++ = MULTI_AP_SUB_ELEM_TYPE;
1551 	*pos++ = 1; /* len */
1552 	*pos++ = value;
1553 
1554 	return pos - buf;
1555 }
1556 
1557 
1558 static const struct country_op_class us_op_class[] = {
1559 	{ 1, 115 },
1560 	{ 2, 118 },
1561 	{ 3, 124 },
1562 	{ 4, 121 },
1563 	{ 5, 125 },
1564 	{ 12, 81 },
1565 	{ 22, 116 },
1566 	{ 23, 119 },
1567 	{ 24, 122 },
1568 	{ 25, 126 },
1569 	{ 26, 126 },
1570 	{ 27, 117 },
1571 	{ 28, 120 },
1572 	{ 29, 123 },
1573 	{ 30, 127 },
1574 	{ 31, 127 },
1575 	{ 32, 83 },
1576 	{ 33, 84 },
1577 	{ 34, 180 },
1578 };
1579 
1580 static const struct country_op_class eu_op_class[] = {
1581 	{ 1, 115 },
1582 	{ 2, 118 },
1583 	{ 3, 121 },
1584 	{ 4, 81 },
1585 	{ 5, 116 },
1586 	{ 6, 119 },
1587 	{ 7, 122 },
1588 	{ 8, 117 },
1589 	{ 9, 120 },
1590 	{ 10, 123 },
1591 	{ 11, 83 },
1592 	{ 12, 84 },
1593 	{ 17, 125 },
1594 	{ 18, 180 },
1595 };
1596 
1597 static const struct country_op_class jp_op_class[] = {
1598 	{ 1, 115 },
1599 	{ 30, 81 },
1600 	{ 31, 82 },
1601 	{ 32, 118 },
1602 	{ 33, 118 },
1603 	{ 34, 121 },
1604 	{ 35, 121 },
1605 	{ 36, 116 },
1606 	{ 37, 119 },
1607 	{ 38, 119 },
1608 	{ 39, 122 },
1609 	{ 40, 122 },
1610 	{ 41, 117 },
1611 	{ 42, 120 },
1612 	{ 43, 120 },
1613 	{ 44, 123 },
1614 	{ 45, 123 },
1615 	{ 56, 83 },
1616 	{ 57, 84 },
1617 	{ 58, 121 },
1618 	{ 59, 180 },
1619 };
1620 
1621 static const struct country_op_class cn_op_class[] = {
1622 	{ 1, 115 },
1623 	{ 2, 118 },
1624 	{ 3, 125 },
1625 	{ 4, 116 },
1626 	{ 5, 119 },
1627 	{ 6, 126 },
1628 	{ 7, 81 },
1629 	{ 8, 83 },
1630 	{ 9, 84 },
1631 };
1632 
1633 static u8
1634 global_op_class_from_country_array(u8 op_class, size_t array_size,
1635 				   const struct country_op_class *country_array)
1636 {
1637 	size_t i;
1638 
1639 	for (i = 0; i < array_size; i++) {
1640 		if (country_array[i].country_op_class == op_class)
1641 			return country_array[i].global_op_class;
1642 	}
1643 
1644 	return 0;
1645 }
1646 
1647 
1648 u8 country_to_global_op_class(const char *country, u8 op_class)
1649 {
1650 	const struct country_op_class *country_array;
1651 	size_t size;
1652 	u8 g_op_class;
1653 
1654 	if (country_match(us_op_class_cc, country)) {
1655 		country_array = us_op_class;
1656 		size = ARRAY_SIZE(us_op_class);
1657 	} else if (country_match(eu_op_class_cc, country)) {
1658 		country_array = eu_op_class;
1659 		size = ARRAY_SIZE(eu_op_class);
1660 	} else if (country_match(jp_op_class_cc, country)) {
1661 		country_array = jp_op_class;
1662 		size = ARRAY_SIZE(jp_op_class);
1663 	} else if (country_match(cn_op_class_cc, country)) {
1664 		country_array = cn_op_class;
1665 		size = ARRAY_SIZE(cn_op_class);
1666 	} else {
1667 		/*
1668 		 * Countries that do not match any of the above countries use
1669 		 * global operating classes
1670 		 */
1671 		return op_class;
1672 	}
1673 
1674 	g_op_class = global_op_class_from_country_array(op_class, size,
1675 							country_array);
1676 
1677 	/*
1678 	 * If the given operating class did not match any of the country's
1679 	 * operating classes, assume that global operating class is used.
1680 	 */
1681 	return g_op_class ? g_op_class : op_class;
1682 }
1683 
1684 
1685 const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
1686 {
1687 	const struct oper_class_map *op;
1688 
1689 	if (country)
1690 		op_class = country_to_global_op_class(country, op_class);
1691 
1692 	op = &global_op_class[0];
1693 	while (op->op_class && op->op_class != op_class)
1694 		op++;
1695 
1696 	if (!op->op_class)
1697 		return NULL;
1698 
1699 	return op;
1700 }
1701 
1702 
1703 int oper_class_bw_to_int(const struct oper_class_map *map)
1704 {
1705 	switch (map->bw) {
1706 	case BW20:
1707 		return 20;
1708 	case BW40PLUS:
1709 	case BW40MINUS:
1710 		return 40;
1711 	case BW80:
1712 		return 80;
1713 	case BW80P80:
1714 	case BW160:
1715 		return 160;
1716 	case BW2160:
1717 		return 2160;
1718 	default:
1719 		return 0;
1720 	}
1721 }
1722 
1723 
1724 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
1725 				    size_t nei_rep_len)
1726 {
1727 	u8 *nei_pos = nei_rep;
1728 	const char *end;
1729 
1730 	/*
1731 	 * BSS Transition Candidate List Entries - Neighbor Report elements
1732 	 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
1733 	 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
1734 	 */
1735 	while (pos) {
1736 		u8 *nei_start;
1737 		long int val;
1738 		char *endptr, *tmp;
1739 
1740 		pos = os_strstr(pos, " neighbor=");
1741 		if (!pos)
1742 			break;
1743 		if (nei_pos + 15 > nei_rep + nei_rep_len) {
1744 			wpa_printf(MSG_DEBUG,
1745 				   "Not enough room for additional neighbor");
1746 			return -1;
1747 		}
1748 		pos += 10;
1749 
1750 		nei_start = nei_pos;
1751 		*nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
1752 		nei_pos++; /* length to be filled in */
1753 
1754 		if (hwaddr_aton(pos, nei_pos)) {
1755 			wpa_printf(MSG_DEBUG, "Invalid BSSID");
1756 			return -1;
1757 		}
1758 		nei_pos += ETH_ALEN;
1759 		pos += 17;
1760 		if (*pos != ',') {
1761 			wpa_printf(MSG_DEBUG, "Missing BSSID Information");
1762 			return -1;
1763 		}
1764 		pos++;
1765 
1766 		val = strtol(pos, &endptr, 0);
1767 		WPA_PUT_LE32(nei_pos, val);
1768 		nei_pos += 4;
1769 		if (*endptr != ',') {
1770 			wpa_printf(MSG_DEBUG, "Missing Operating Class");
1771 			return -1;
1772 		}
1773 		pos = endptr + 1;
1774 
1775 		*nei_pos++ = atoi(pos); /* Operating Class */
1776 		pos = os_strchr(pos, ',');
1777 		if (pos == NULL) {
1778 			wpa_printf(MSG_DEBUG, "Missing Channel Number");
1779 			return -1;
1780 		}
1781 		pos++;
1782 
1783 		*nei_pos++ = atoi(pos); /* Channel Number */
1784 		pos = os_strchr(pos, ',');
1785 		if (pos == NULL) {
1786 			wpa_printf(MSG_DEBUG, "Missing PHY Type");
1787 			return -1;
1788 		}
1789 		pos++;
1790 
1791 		*nei_pos++ = atoi(pos); /* PHY Type */
1792 		end = os_strchr(pos, ' ');
1793 		tmp = os_strchr(pos, ',');
1794 		if (tmp && (!end || tmp < end)) {
1795 			/* Optional Subelements (hexdump) */
1796 			size_t len;
1797 
1798 			pos = tmp + 1;
1799 			end = os_strchr(pos, ' ');
1800 			if (end)
1801 				len = end - pos;
1802 			else
1803 				len = os_strlen(pos);
1804 			if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
1805 				wpa_printf(MSG_DEBUG,
1806 					   "Not enough room for neighbor subelements");
1807 				return -1;
1808 			}
1809 			if (len & 0x01 ||
1810 			    hexstr2bin(pos, nei_pos, len / 2) < 0) {
1811 				wpa_printf(MSG_DEBUG,
1812 					   "Invalid neighbor subelement info");
1813 				return -1;
1814 			}
1815 			nei_pos += len / 2;
1816 			pos = end;
1817 		}
1818 
1819 		nei_start[1] = nei_pos - nei_start - 2;
1820 	}
1821 
1822 	return nei_pos - nei_rep;
1823 }
1824 
1825 
1826 int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
1827 {
1828 	if (!ie || ie[1] <= capab / 8)
1829 		return 0;
1830 	return !!(ie[2 + capab / 8] & BIT(capab % 8));
1831 }
1832