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