xref: /freebsd/contrib/wpa/src/common/ieee802_11_common.c (revision 193d9e768ba63fcfb187cfd17f461f7d41345048)
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 
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 		default:
119 			wpa_printf(MSG_MSGDUMP, "Unknown WFA "
120 				   "information element ignored "
121 				   "(type=%d len=%lu)",
122 				   pos[3], (unsigned long) elen);
123 			return -1;
124 		}
125 		break;
126 
127 	case OUI_BROADCOM:
128 		switch (pos[3]) {
129 		case VENDOR_HT_CAPAB_OUI_TYPE:
130 			elems->vendor_ht_cap = pos;
131 			elems->vendor_ht_cap_len = elen;
132 			break;
133 		case VENDOR_VHT_TYPE:
134 			if (elen > 4 &&
135 			    (pos[4] == VENDOR_VHT_SUBTYPE ||
136 			     pos[4] == VENDOR_VHT_SUBTYPE2)) {
137 				elems->vendor_vht = pos;
138 				elems->vendor_vht_len = elen;
139 			} else
140 				return -1;
141 			break;
142 		default:
143 			wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
144 				   "information element ignored "
145 				   "(type=%d len=%lu)",
146 				   pos[3], (unsigned long) elen);
147 			return -1;
148 		}
149 		break;
150 
151 	case OUI_QCA:
152 		switch (pos[3]) {
153 		case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
154 			elems->pref_freq_list = pos;
155 			elems->pref_freq_list_len = elen;
156 			break;
157 		default:
158 			wpa_printf(MSG_EXCESSIVE,
159 				   "Unknown QCA information element ignored (type=%d len=%lu)",
160 				   pos[3], (unsigned long) elen);
161 			return -1;
162 		}
163 		break;
164 
165 	default:
166 		wpa_printf(MSG_EXCESSIVE, "unknown vendor specific "
167 			   "information element ignored (vendor OUI "
168 			   "%02x:%02x:%02x len=%lu)",
169 			   pos[0], pos[1], pos[2], (unsigned long) elen);
170 		return -1;
171 	}
172 
173 	return 0;
174 }
175 
176 
177 /**
178  * ieee802_11_parse_elems - Parse information elements in management frames
179  * @start: Pointer to the start of IEs
180  * @len: Length of IE buffer in octets
181  * @elems: Data structure for parsed elements
182  * @show_errors: Whether to show parsing errors in debug log
183  * Returns: Parsing result
184  */
185 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
186 				struct ieee802_11_elems *elems,
187 				int show_errors)
188 {
189 	size_t left = len;
190 	const u8 *pos = start;
191 	int unknown = 0;
192 
193 	os_memset(elems, 0, sizeof(*elems));
194 
195 	while (left >= 2) {
196 		u8 id, elen;
197 
198 		id = *pos++;
199 		elen = *pos++;
200 		left -= 2;
201 
202 		if (elen > left) {
203 			if (show_errors) {
204 				wpa_printf(MSG_DEBUG, "IEEE 802.11 element "
205 					   "parse failed (id=%d elen=%d "
206 					   "left=%lu)",
207 					   id, elen, (unsigned long) left);
208 				wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
209 			}
210 			return ParseFailed;
211 		}
212 
213 		switch (id) {
214 		case WLAN_EID_SSID:
215 			if (elen > SSID_MAX_LEN) {
216 				wpa_printf(MSG_DEBUG,
217 					   "Ignored too long SSID element (elen=%u)",
218 					   elen);
219 				break;
220 			}
221 			elems->ssid = pos;
222 			elems->ssid_len = elen;
223 			break;
224 		case WLAN_EID_SUPP_RATES:
225 			elems->supp_rates = pos;
226 			elems->supp_rates_len = elen;
227 			break;
228 		case WLAN_EID_DS_PARAMS:
229 			if (elen < 1)
230 				break;
231 			elems->ds_params = pos;
232 			break;
233 		case WLAN_EID_CF_PARAMS:
234 		case WLAN_EID_TIM:
235 			break;
236 		case WLAN_EID_CHALLENGE:
237 			elems->challenge = pos;
238 			elems->challenge_len = elen;
239 			break;
240 		case WLAN_EID_ERP_INFO:
241 			if (elen < 1)
242 				break;
243 			elems->erp_info = pos;
244 			break;
245 		case WLAN_EID_EXT_SUPP_RATES:
246 			elems->ext_supp_rates = pos;
247 			elems->ext_supp_rates_len = elen;
248 			break;
249 		case WLAN_EID_VENDOR_SPECIFIC:
250 			if (ieee802_11_parse_vendor_specific(pos, elen,
251 							     elems,
252 							     show_errors))
253 				unknown++;
254 			break;
255 		case WLAN_EID_RSN:
256 			elems->rsn_ie = pos;
257 			elems->rsn_ie_len = elen;
258 			break;
259 		case WLAN_EID_PWR_CAPABILITY:
260 			break;
261 		case WLAN_EID_SUPPORTED_CHANNELS:
262 			elems->supp_channels = pos;
263 			elems->supp_channels_len = elen;
264 			break;
265 		case WLAN_EID_MOBILITY_DOMAIN:
266 			if (elen < sizeof(struct rsn_mdie))
267 				break;
268 			elems->mdie = pos;
269 			elems->mdie_len = elen;
270 			break;
271 		case WLAN_EID_FAST_BSS_TRANSITION:
272 			if (elen < sizeof(struct rsn_ftie))
273 				break;
274 			elems->ftie = pos;
275 			elems->ftie_len = elen;
276 			break;
277 		case WLAN_EID_TIMEOUT_INTERVAL:
278 			if (elen != 5)
279 				break;
280 			elems->timeout_int = pos;
281 			break;
282 		case WLAN_EID_HT_CAP:
283 			if (elen < sizeof(struct ieee80211_ht_capabilities))
284 				break;
285 			elems->ht_capabilities = pos;
286 			break;
287 		case WLAN_EID_HT_OPERATION:
288 			if (elen < sizeof(struct ieee80211_ht_operation))
289 				break;
290 			elems->ht_operation = pos;
291 			break;
292 		case WLAN_EID_MESH_CONFIG:
293 			elems->mesh_config = pos;
294 			elems->mesh_config_len = elen;
295 			break;
296 		case WLAN_EID_MESH_ID:
297 			elems->mesh_id = pos;
298 			elems->mesh_id_len = elen;
299 			break;
300 		case WLAN_EID_PEER_MGMT:
301 			elems->peer_mgmt = pos;
302 			elems->peer_mgmt_len = elen;
303 			break;
304 		case WLAN_EID_VHT_CAP:
305 			if (elen < sizeof(struct ieee80211_vht_capabilities))
306 				break;
307 			elems->vht_capabilities = pos;
308 			break;
309 		case WLAN_EID_VHT_OPERATION:
310 			if (elen < sizeof(struct ieee80211_vht_operation))
311 				break;
312 			elems->vht_operation = pos;
313 			break;
314 		case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
315 			if (elen != 1)
316 				break;
317 			elems->vht_opmode_notif = pos;
318 			break;
319 		case WLAN_EID_LINK_ID:
320 			if (elen < 18)
321 				break;
322 			elems->link_id = pos;
323 			break;
324 		case WLAN_EID_INTERWORKING:
325 			elems->interworking = pos;
326 			elems->interworking_len = elen;
327 			break;
328 		case WLAN_EID_QOS_MAP_SET:
329 			if (elen < 16)
330 				break;
331 			elems->qos_map_set = pos;
332 			elems->qos_map_set_len = elen;
333 			break;
334 		case WLAN_EID_EXT_CAPAB:
335 			elems->ext_capab = pos;
336 			elems->ext_capab_len = elen;
337 			break;
338 		case WLAN_EID_BSS_MAX_IDLE_PERIOD:
339 			if (elen < 3)
340 				break;
341 			elems->bss_max_idle_period = pos;
342 			break;
343 		case WLAN_EID_SSID_LIST:
344 			elems->ssid_list = pos;
345 			elems->ssid_list_len = elen;
346 			break;
347 		case WLAN_EID_AMPE:
348 			elems->ampe = pos;
349 			elems->ampe_len = elen;
350 			break;
351 		case WLAN_EID_MIC:
352 			elems->mic = pos;
353 			elems->mic_len = elen;
354 			/* after mic everything is encrypted, so stop. */
355 			left = elen;
356 			break;
357 		case WLAN_EID_MULTI_BAND:
358 			if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
359 				wpa_printf(MSG_MSGDUMP,
360 					   "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
361 					   id, elen);
362 				break;
363 			}
364 
365 			elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
366 			elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
367 			elems->mb_ies.nof_ies++;
368 			break;
369 		default:
370 			unknown++;
371 			if (!show_errors)
372 				break;
373 			wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
374 				   "ignored unknown element (id=%d elen=%d)",
375 				   id, elen);
376 			break;
377 		}
378 
379 		left -= elen;
380 		pos += elen;
381 	}
382 
383 	if (left)
384 		return ParseFailed;
385 
386 	return unknown ? ParseUnknown : ParseOK;
387 }
388 
389 
390 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
391 {
392 	int count = 0;
393 	const u8 *pos, *end;
394 
395 	if (ies == NULL)
396 		return 0;
397 
398 	pos = ies;
399 	end = ies + ies_len;
400 
401 	while (pos + 2 <= end) {
402 		if (pos + 2 + pos[1] > end)
403 			break;
404 		count++;
405 		pos += 2 + pos[1];
406 	}
407 
408 	return count;
409 }
410 
411 
412 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
413 					    u32 oui_type)
414 {
415 	struct wpabuf *buf;
416 	const u8 *end, *pos, *ie;
417 
418 	pos = ies;
419 	end = ies + ies_len;
420 	ie = NULL;
421 
422 	while (pos + 1 < end) {
423 		if (pos + 2 + pos[1] > end)
424 			return NULL;
425 		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
426 		    WPA_GET_BE32(&pos[2]) == oui_type) {
427 			ie = pos;
428 			break;
429 		}
430 		pos += 2 + pos[1];
431 	}
432 
433 	if (ie == NULL)
434 		return NULL; /* No specified vendor IE found */
435 
436 	buf = wpabuf_alloc(ies_len);
437 	if (buf == NULL)
438 		return NULL;
439 
440 	/*
441 	 * There may be multiple vendor IEs in the message, so need to
442 	 * concatenate their data fields.
443 	 */
444 	while (pos + 1 < end) {
445 		if (pos + 2 + pos[1] > end)
446 			break;
447 		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
448 		    WPA_GET_BE32(&pos[2]) == oui_type)
449 			wpabuf_put_data(buf, pos + 6, pos[1] - 4);
450 		pos += 2 + pos[1];
451 	}
452 
453 	return buf;
454 }
455 
456 
457 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
458 {
459 	u16 fc, type, stype;
460 
461 	/*
462 	 * PS-Poll frames are 16 bytes. All other frames are
463 	 * 24 bytes or longer.
464 	 */
465 	if (len < 16)
466 		return NULL;
467 
468 	fc = le_to_host16(hdr->frame_control);
469 	type = WLAN_FC_GET_TYPE(fc);
470 	stype = WLAN_FC_GET_STYPE(fc);
471 
472 	switch (type) {
473 	case WLAN_FC_TYPE_DATA:
474 		if (len < 24)
475 			return NULL;
476 		switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
477 		case WLAN_FC_FROMDS | WLAN_FC_TODS:
478 		case WLAN_FC_TODS:
479 			return hdr->addr1;
480 		case WLAN_FC_FROMDS:
481 			return hdr->addr2;
482 		default:
483 			return NULL;
484 		}
485 	case WLAN_FC_TYPE_CTRL:
486 		if (stype != WLAN_FC_STYPE_PSPOLL)
487 			return NULL;
488 		return hdr->addr1;
489 	case WLAN_FC_TYPE_MGMT:
490 		return hdr->addr3;
491 	default:
492 		return NULL;
493 	}
494 }
495 
496 
497 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
498 			  const char *name, const char *val)
499 {
500 	int num, v;
501 	const char *pos;
502 	struct hostapd_wmm_ac_params *ac;
503 
504 	/* skip 'wme_ac_' or 'wmm_ac_' prefix */
505 	pos = name + 7;
506 	if (os_strncmp(pos, "be_", 3) == 0) {
507 		num = 0;
508 		pos += 3;
509 	} else if (os_strncmp(pos, "bk_", 3) == 0) {
510 		num = 1;
511 		pos += 3;
512 	} else if (os_strncmp(pos, "vi_", 3) == 0) {
513 		num = 2;
514 		pos += 3;
515 	} else if (os_strncmp(pos, "vo_", 3) == 0) {
516 		num = 3;
517 		pos += 3;
518 	} else {
519 		wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
520 		return -1;
521 	}
522 
523 	ac = &wmm_ac_params[num];
524 
525 	if (os_strcmp(pos, "aifs") == 0) {
526 		v = atoi(val);
527 		if (v < 1 || v > 255) {
528 			wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
529 			return -1;
530 		}
531 		ac->aifs = v;
532 	} else if (os_strcmp(pos, "cwmin") == 0) {
533 		v = atoi(val);
534 		if (v < 0 || v > 15) {
535 			wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
536 			return -1;
537 		}
538 		ac->cwmin = v;
539 	} else if (os_strcmp(pos, "cwmax") == 0) {
540 		v = atoi(val);
541 		if (v < 0 || v > 15) {
542 			wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
543 			return -1;
544 		}
545 		ac->cwmax = v;
546 	} else if (os_strcmp(pos, "txop_limit") == 0) {
547 		v = atoi(val);
548 		if (v < 0 || v > 0xffff) {
549 			wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
550 			return -1;
551 		}
552 		ac->txop_limit = v;
553 	} else if (os_strcmp(pos, "acm") == 0) {
554 		v = atoi(val);
555 		if (v < 0 || v > 1) {
556 			wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
557 			return -1;
558 		}
559 		ac->admission_control_mandatory = v;
560 	} else {
561 		wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
562 		return -1;
563 	}
564 
565 	return 0;
566 }
567 
568 
569 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
570 {
571 	u8 op_class;
572 
573 	return ieee80211_freq_to_channel_ext(freq, 0, 0, &op_class, channel);
574 }
575 
576 
577 /**
578  * ieee80211_freq_to_channel_ext - Convert frequency into channel info
579  * for HT40 and VHT. DFS channels are not covered.
580  * @freq: Frequency (MHz) to convert
581  * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
582  * @vht: 0 - non-VHT, 1 - 80 MHz
583  * @op_class: Buffer for returning operating class
584  * @channel: Buffer for returning channel number
585  * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
586  */
587 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
588 						   int sec_channel, int vht,
589 						   u8 *op_class, u8 *channel)
590 {
591 	/* TODO: more operating classes */
592 
593 	if (sec_channel > 1 || sec_channel < -1)
594 		return NUM_HOSTAPD_MODES;
595 
596 	if (freq >= 2412 && freq <= 2472) {
597 		if ((freq - 2407) % 5)
598 			return NUM_HOSTAPD_MODES;
599 
600 		if (vht)
601 			return NUM_HOSTAPD_MODES;
602 
603 		/* 2.407 GHz, channels 1..13 */
604 		if (sec_channel == 1)
605 			*op_class = 83;
606 		else if (sec_channel == -1)
607 			*op_class = 84;
608 		else
609 			*op_class = 81;
610 
611 		*channel = (freq - 2407) / 5;
612 
613 		return HOSTAPD_MODE_IEEE80211G;
614 	}
615 
616 	if (freq == 2484) {
617 		if (sec_channel || vht)
618 			return NUM_HOSTAPD_MODES;
619 
620 		*op_class = 82; /* channel 14 */
621 		*channel = 14;
622 
623 		return HOSTAPD_MODE_IEEE80211B;
624 	}
625 
626 	if (freq >= 4900 && freq < 5000) {
627 		if ((freq - 4000) % 5)
628 			return NUM_HOSTAPD_MODES;
629 		*channel = (freq - 4000) / 5;
630 		*op_class = 0; /* TODO */
631 		return HOSTAPD_MODE_IEEE80211A;
632 	}
633 
634 	/* 5 GHz, channels 36..48 */
635 	if (freq >= 5180 && freq <= 5240) {
636 		if ((freq - 5000) % 5)
637 			return NUM_HOSTAPD_MODES;
638 
639 		if (sec_channel == 1)
640 			*op_class = 116;
641 		else if (sec_channel == -1)
642 			*op_class = 117;
643 		else if (vht)
644 			*op_class = 128;
645 		else
646 			*op_class = 115;
647 
648 		*channel = (freq - 5000) / 5;
649 
650 		return HOSTAPD_MODE_IEEE80211A;
651 	}
652 
653 	/* 5 GHz, channels 149..161 */
654 	if (freq >= 5745 && freq <= 5805) {
655 		if ((freq - 5000) % 5)
656 			return NUM_HOSTAPD_MODES;
657 
658 		if (sec_channel == 1)
659 			*op_class = 126;
660 		else if (sec_channel == -1)
661 			*op_class = 127;
662 		else if (vht)
663 			*op_class = 128;
664 		else
665 			*op_class = 124;
666 
667 		*channel = (freq - 5000) / 5;
668 
669 		return HOSTAPD_MODE_IEEE80211A;
670 	}
671 
672 	/* 5 GHz, channels 149..169 */
673 	if (freq >= 5745 && freq <= 5845) {
674 		if ((freq - 5000) % 5)
675 			return NUM_HOSTAPD_MODES;
676 
677 		*op_class = 125;
678 
679 		*channel = (freq - 5000) / 5;
680 
681 		return HOSTAPD_MODE_IEEE80211A;
682 	}
683 
684 	if (freq >= 5000 && freq < 5900) {
685 		if ((freq - 5000) % 5)
686 			return NUM_HOSTAPD_MODES;
687 		*channel = (freq - 5000) / 5;
688 		*op_class = 0; /* TODO */
689 		return HOSTAPD_MODE_IEEE80211A;
690 	}
691 
692 	/* 56.16 GHz, channel 1..4 */
693 	if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
694 		if (sec_channel || vht)
695 			return NUM_HOSTAPD_MODES;
696 
697 		*channel = (freq - 56160) / 2160;
698 		*op_class = 180;
699 
700 		return HOSTAPD_MODE_IEEE80211AD;
701 	}
702 
703 	return NUM_HOSTAPD_MODES;
704 }
705 
706 
707 static const char *const us_op_class_cc[] = {
708 	"US", "CA", NULL
709 };
710 
711 static const char *const eu_op_class_cc[] = {
712 	"AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
713 	"DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
714 	"LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
715 	"RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
716 };
717 
718 static const char *const jp_op_class_cc[] = {
719 	"JP", NULL
720 };
721 
722 static const char *const cn_op_class_cc[] = {
723 	"CN", NULL
724 };
725 
726 
727 static int country_match(const char *const cc[], const char *const country)
728 {
729 	int i;
730 
731 	if (country == NULL)
732 		return 0;
733 	for (i = 0; cc[i]; i++) {
734 		if (cc[i][0] == country[0] && cc[i][1] == country[1])
735 			return 1;
736 	}
737 
738 	return 0;
739 }
740 
741 
742 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
743 {
744 	switch (op_class) {
745 	case 12: /* channels 1..11 */
746 	case 32: /* channels 1..7; 40 MHz */
747 	case 33: /* channels 5..11; 40 MHz */
748 		if (chan < 1 || chan > 11)
749 			return -1;
750 		return 2407 + 5 * chan;
751 	case 1: /* channels 36,40,44,48 */
752 	case 2: /* channels 52,56,60,64; dfs */
753 	case 22: /* channels 36,44; 40 MHz */
754 	case 23: /* channels 52,60; 40 MHz */
755 	case 27: /* channels 40,48; 40 MHz */
756 	case 28: /* channels 56,64; 40 MHz */
757 		if (chan < 36 || chan > 64)
758 			return -1;
759 		return 5000 + 5 * chan;
760 	case 4: /* channels 100-144 */
761 	case 24: /* channels 100-140; 40 MHz */
762 		if (chan < 100 || chan > 144)
763 			return -1;
764 		return 5000 + 5 * chan;
765 	case 3: /* channels 149,153,157,161 */
766 	case 25: /* channels 149,157; 40 MHz */
767 	case 26: /* channels 149,157; 40 MHz */
768 	case 30: /* channels 153,161; 40 MHz */
769 	case 31: /* channels 153,161; 40 MHz */
770 		if (chan < 149 || chan > 161)
771 			return -1;
772 		return 5000 + 5 * chan;
773 	case 5: /* channels 149,153,157,161,165 */
774 		if (chan < 149 || chan > 165)
775 			return -1;
776 		return 5000 + 5 * chan;
777 	case 34: /* 60 GHz band, channels 1..3 */
778 		if (chan < 1 || chan > 3)
779 			return -1;
780 		return 56160 + 2160 * chan;
781 	}
782 	return -1;
783 }
784 
785 
786 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
787 {
788 	switch (op_class) {
789 	case 4: /* channels 1..13 */
790 	case 11: /* channels 1..9; 40 MHz */
791 	case 12: /* channels 5..13; 40 MHz */
792 		if (chan < 1 || chan > 13)
793 			return -1;
794 		return 2407 + 5 * chan;
795 	case 1: /* channels 36,40,44,48 */
796 	case 2: /* channels 52,56,60,64; dfs */
797 	case 5: /* channels 36,44; 40 MHz */
798 	case 6: /* channels 52,60; 40 MHz */
799 	case 8: /* channels 40,48; 40 MHz */
800 	case 9: /* channels 56,64; 40 MHz */
801 		if (chan < 36 || chan > 64)
802 			return -1;
803 		return 5000 + 5 * chan;
804 	case 3: /* channels 100-140 */
805 	case 7: /* channels 100-132; 40 MHz */
806 	case 10: /* channels 104-136; 40 MHz */
807 	case 16: /* channels 100-140 */
808 		if (chan < 100 || chan > 140)
809 			return -1;
810 		return 5000 + 5 * chan;
811 	case 17: /* channels 149,153,157,161,165,169 */
812 		if (chan < 149 || chan > 169)
813 			return -1;
814 		return 5000 + 5 * chan;
815 	case 18: /* 60 GHz band, channels 1..4 */
816 		if (chan < 1 || chan > 4)
817 			return -1;
818 		return 56160 + 2160 * chan;
819 	}
820 	return -1;
821 }
822 
823 
824 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
825 {
826 	switch (op_class) {
827 	case 30: /* channels 1..13 */
828 	case 56: /* channels 1..9; 40 MHz */
829 	case 57: /* channels 5..13; 40 MHz */
830 		if (chan < 1 || chan > 13)
831 			return -1;
832 		return 2407 + 5 * chan;
833 	case 31: /* channel 14 */
834 		if (chan != 14)
835 			return -1;
836 		return 2414 + 5 * chan;
837 	case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
838 	case 32: /* channels 52,56,60,64 */
839 	case 33: /* channels 52,56,60,64 */
840 	case 36: /* channels 36,44; 40 MHz */
841 	case 37: /* channels 52,60; 40 MHz */
842 	case 38: /* channels 52,60; 40 MHz */
843 	case 41: /* channels 40,48; 40 MHz */
844 	case 42: /* channels 56,64; 40 MHz */
845 	case 43: /* channels 56,64; 40 MHz */
846 		if (chan < 34 || chan > 64)
847 			return -1;
848 		return 5000 + 5 * chan;
849 	case 34: /* channels 100-140 */
850 	case 35: /* channels 100-140 */
851 	case 39: /* channels 100-132; 40 MHz */
852 	case 40: /* channels 100-132; 40 MHz */
853 	case 44: /* channels 104-136; 40 MHz */
854 	case 45: /* channels 104-136; 40 MHz */
855 	case 58: /* channels 100-140 */
856 		if (chan < 100 || chan > 140)
857 			return -1;
858 		return 5000 + 5 * chan;
859 	case 59: /* 60 GHz band, channels 1..4 */
860 		if (chan < 1 || chan > 3)
861 			return -1;
862 		return 56160 + 2160 * chan;
863 	}
864 	return -1;
865 }
866 
867 
868 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
869 {
870 	switch (op_class) {
871 	case 7: /* channels 1..13 */
872 	case 8: /* channels 1..9; 40 MHz */
873 	case 9: /* channels 5..13; 40 MHz */
874 		if (chan < 1 || chan > 13)
875 			return -1;
876 		return 2407 + 5 * chan;
877 	case 1: /* channels 36,40,44,48 */
878 	case 2: /* channels 52,56,60,64; dfs */
879 	case 4: /* channels 36,44; 40 MHz */
880 	case 5: /* channels 52,60; 40 MHz */
881 		if (chan < 36 || chan > 64)
882 			return -1;
883 		return 5000 + 5 * chan;
884 	case 3: /* channels 149,153,157,161,165 */
885 	case 6: /* channels 149,157; 40 MHz */
886 		if (chan < 149 || chan > 165)
887 			return -1;
888 		return 5000 + 5 * chan;
889 	}
890 	return -1;
891 }
892 
893 
894 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
895 {
896 	/* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
897 	switch (op_class) {
898 	case 81:
899 		/* channels 1..13 */
900 		if (chan < 1 || chan > 13)
901 			return -1;
902 		return 2407 + 5 * chan;
903 	case 82:
904 		/* channel 14 */
905 		if (chan != 14)
906 			return -1;
907 		return 2414 + 5 * chan;
908 	case 83: /* channels 1..9; 40 MHz */
909 	case 84: /* channels 5..13; 40 MHz */
910 		if (chan < 1 || chan > 13)
911 			return -1;
912 		return 2407 + 5 * chan;
913 	case 115: /* channels 36,40,44,48; indoor only */
914 	case 116: /* channels 36,44; 40 MHz; indoor only */
915 	case 117: /* channels 40,48; 40 MHz; indoor only */
916 	case 118: /* channels 52,56,60,64; dfs */
917 	case 119: /* channels 52,60; 40 MHz; dfs */
918 	case 120: /* channels 56,64; 40 MHz; dfs */
919 		if (chan < 36 || chan > 64)
920 			return -1;
921 		return 5000 + 5 * chan;
922 	case 121: /* channels 100-140 */
923 	case 122: /* channels 100-142; 40 MHz */
924 	case 123: /* channels 104-136; 40 MHz */
925 		if (chan < 100 || chan > 140)
926 			return -1;
927 		return 5000 + 5 * chan;
928 	case 124: /* channels 149,153,157,161 */
929 	case 126: /* channels 149,157; 40 MHz */
930 	case 127: /* channels 153,161; 40 MHz */
931 		if (chan < 149 || chan > 161)
932 			return -1;
933 		return 5000 + 5 * chan;
934 	case 125: /* channels 149,153,157,161,165,169 */
935 		if (chan < 149 || chan > 169)
936 			return -1;
937 		return 5000 + 5 * chan;
938 	case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
939 	case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
940 		if (chan < 36 || chan > 161)
941 			return -1;
942 		return 5000 + 5 * chan;
943 	case 129: /* center freqs 50, 114; 160 MHz */
944 		if (chan < 50 || chan > 114)
945 			return -1;
946 		return 5000 + 5 * chan;
947 	case 180: /* 60 GHz band, channels 1..4 */
948 		if (chan < 1 || chan > 4)
949 			return -1;
950 		return 56160 + 2160 * chan;
951 	}
952 	return -1;
953 }
954 
955 /**
956  * ieee80211_chan_to_freq - Convert channel info to frequency
957  * @country: Country code, if known; otherwise, global operating class is used
958  * @op_class: Operating class
959  * @chan: Channel number
960  * Returns: Frequency in MHz or -1 if the specified channel is unknown
961  */
962 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
963 {
964 	int freq;
965 
966 	if (country_match(us_op_class_cc, country)) {
967 		freq = ieee80211_chan_to_freq_us(op_class, chan);
968 		if (freq > 0)
969 			return freq;
970 	}
971 
972 	if (country_match(eu_op_class_cc, country)) {
973 		freq = ieee80211_chan_to_freq_eu(op_class, chan);
974 		if (freq > 0)
975 			return freq;
976 	}
977 
978 	if (country_match(jp_op_class_cc, country)) {
979 		freq = ieee80211_chan_to_freq_jp(op_class, chan);
980 		if (freq > 0)
981 			return freq;
982 	}
983 
984 	if (country_match(cn_op_class_cc, country)) {
985 		freq = ieee80211_chan_to_freq_cn(op_class, chan);
986 		if (freq > 0)
987 			return freq;
988 	}
989 
990 	return ieee80211_chan_to_freq_global(op_class, chan);
991 }
992 
993 
994 int ieee80211_is_dfs(int freq)
995 {
996 	/* TODO: this could be more accurate to better cover all domains */
997 	return (freq >= 5260 && freq <= 5320) || (freq >= 5500 && freq <= 5700);
998 }
999 
1000 
1001 static int is_11b(u8 rate)
1002 {
1003 	return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1004 }
1005 
1006 
1007 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1008 {
1009 	int num_11b = 0, num_others = 0;
1010 	int i;
1011 
1012 	if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1013 		return 0;
1014 
1015 	for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1016 		if (is_11b(elems->supp_rates[i]))
1017 			num_11b++;
1018 		else
1019 			num_others++;
1020 	}
1021 
1022 	for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1023 	     i++) {
1024 		if (is_11b(elems->ext_supp_rates[i]))
1025 			num_11b++;
1026 		else
1027 			num_others++;
1028 	}
1029 
1030 	return num_11b > 0 && num_others == 0;
1031 }
1032 
1033 
1034 const char * fc2str(u16 fc)
1035 {
1036 	u16 stype = WLAN_FC_GET_STYPE(fc);
1037 #define C2S(x) case x: return #x;
1038 
1039 	switch (WLAN_FC_GET_TYPE(fc)) {
1040 	case WLAN_FC_TYPE_MGMT:
1041 		switch (stype) {
1042 		C2S(WLAN_FC_STYPE_ASSOC_REQ)
1043 		C2S(WLAN_FC_STYPE_ASSOC_RESP)
1044 		C2S(WLAN_FC_STYPE_REASSOC_REQ)
1045 		C2S(WLAN_FC_STYPE_REASSOC_RESP)
1046 		C2S(WLAN_FC_STYPE_PROBE_REQ)
1047 		C2S(WLAN_FC_STYPE_PROBE_RESP)
1048 		C2S(WLAN_FC_STYPE_BEACON)
1049 		C2S(WLAN_FC_STYPE_ATIM)
1050 		C2S(WLAN_FC_STYPE_DISASSOC)
1051 		C2S(WLAN_FC_STYPE_AUTH)
1052 		C2S(WLAN_FC_STYPE_DEAUTH)
1053 		C2S(WLAN_FC_STYPE_ACTION)
1054 		}
1055 		break;
1056 	case WLAN_FC_TYPE_CTRL:
1057 		switch (stype) {
1058 		C2S(WLAN_FC_STYPE_PSPOLL)
1059 		C2S(WLAN_FC_STYPE_RTS)
1060 		C2S(WLAN_FC_STYPE_CTS)
1061 		C2S(WLAN_FC_STYPE_ACK)
1062 		C2S(WLAN_FC_STYPE_CFEND)
1063 		C2S(WLAN_FC_STYPE_CFENDACK)
1064 		}
1065 		break;
1066 	case WLAN_FC_TYPE_DATA:
1067 		switch (stype) {
1068 		C2S(WLAN_FC_STYPE_DATA)
1069 		C2S(WLAN_FC_STYPE_DATA_CFACK)
1070 		C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1071 		C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1072 		C2S(WLAN_FC_STYPE_NULLFUNC)
1073 		C2S(WLAN_FC_STYPE_CFACK)
1074 		C2S(WLAN_FC_STYPE_CFPOLL)
1075 		C2S(WLAN_FC_STYPE_CFACKPOLL)
1076 		C2S(WLAN_FC_STYPE_QOS_DATA)
1077 		C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1078 		C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1079 		C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1080 		C2S(WLAN_FC_STYPE_QOS_NULL)
1081 		C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1082 		C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1083 		}
1084 		break;
1085 	}
1086 	return "WLAN_FC_TYPE_UNKNOWN";
1087 #undef C2S
1088 }
1089 
1090 
1091 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1092 		       size_t ies_len)
1093 {
1094 	os_memset(info, 0, sizeof(*info));
1095 
1096 	while (ies_buf && ies_len >= 2 &&
1097 	       info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) {
1098 		size_t len = 2 + ies_buf[1];
1099 
1100 		if (len > ies_len) {
1101 			wpa_hexdump(MSG_DEBUG, "Truncated IEs",
1102 				    ies_buf, ies_len);
1103 			return -1;
1104 		}
1105 
1106 		if (ies_buf[0] == WLAN_EID_MULTI_BAND) {
1107 			wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len);
1108 			info->ies[info->nof_ies].ie = ies_buf + 2;
1109 			info->ies[info->nof_ies].ie_len = ies_buf[1];
1110 			info->nof_ies++;
1111 		}
1112 
1113 		ies_len -= len;
1114 		ies_buf += len;
1115 	}
1116 
1117 	return 0;
1118 }
1119 
1120 
1121 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1122 {
1123 	struct wpabuf *mb_ies = NULL;
1124 
1125 	WPA_ASSERT(info != NULL);
1126 
1127 	if (info->nof_ies) {
1128 		u8 i;
1129 		size_t mb_ies_size = 0;
1130 
1131 		for (i = 0; i < info->nof_ies; i++)
1132 			mb_ies_size += 2 + info->ies[i].ie_len;
1133 
1134 		mb_ies = wpabuf_alloc(mb_ies_size);
1135 		if (mb_ies) {
1136 			for (i = 0; i < info->nof_ies; i++) {
1137 				wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1138 				wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1139 				wpabuf_put_data(mb_ies,
1140 						info->ies[i].ie,
1141 						info->ies[i].ie_len);
1142 			}
1143 		}
1144 	}
1145 
1146 	return mb_ies;
1147 }
1148