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