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