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