ieee802_11_common.c revision 289549
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		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 */
185ParseRes 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
390int 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
412struct 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
457const 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
497int 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
569enum 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 */
587enum 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
707static const char *const us_op_class_cc[] = {
708	"US", "CA", NULL
709};
710
711static 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
718static const char *const jp_op_class_cc[] = {
719	"JP", NULL
720};
721
722static const char *const cn_op_class_cc[] = {
723	"CN", NULL
724};
725
726
727static 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
742static 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
786static 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
824static 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
868static 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
894static 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 */
962int 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
994int 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
1001static int is_11b(u8 rate)
1002{
1003	return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1004}
1005
1006
1007int 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
1034const 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
1091int 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
1121struct 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