1/*
2 * IEEE 802.11 Common routines
3 * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9#include "includes.h"
10
11#include "common.h"
12#include "defs.h"
13#include "wpa_common.h"
14#include "drivers/driver.h"
15#include "qca-vendor.h"
16#include "ieee802_11_defs.h"
17#include "ieee802_11_common.h"
18
19
20static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
21					    struct ieee802_11_elems *elems,
22					    int show_errors)
23{
24	unsigned int oui;
25
26	/* first 3 bytes in vendor specific information element are the IEEE
27	 * OUI of the vendor. The following byte is used a vendor specific
28	 * sub-type. */
29	if (elen < 4) {
30		if (show_errors) {
31			wpa_printf(MSG_MSGDUMP, "short vendor specific "
32				   "information element ignored (len=%lu)",
33				   (unsigned long) elen);
34		}
35		return -1;
36	}
37
38	oui = WPA_GET_BE24(pos);
39	switch (oui) {
40	case OUI_MICROSOFT:
41		/* Microsoft/Wi-Fi information elements are further typed and
42		 * subtyped */
43		switch (pos[3]) {
44		case 1:
45			/* Microsoft OUI (00:50:F2) with OUI Type 1:
46			 * real WPA information element */
47			elems->wpa_ie = pos;
48			elems->wpa_ie_len = elen;
49			break;
50		case WMM_OUI_TYPE:
51			/* WMM information element */
52			if (elen < 5) {
53				wpa_printf(MSG_MSGDUMP, "short WMM "
54					   "information element ignored "
55					   "(len=%lu)",
56					   (unsigned long) elen);
57				return -1;
58			}
59			switch (pos[4]) {
60			case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT:
61			case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT:
62				/*
63				 * Share same pointer since only one of these
64				 * is used and they start with same data.
65				 * Length field can be used to distinguish the
66				 * IEs.
67				 */
68				elems->wmm = pos;
69				elems->wmm_len = elen;
70				break;
71			case WMM_OUI_SUBTYPE_TSPEC_ELEMENT:
72				elems->wmm_tspec = pos;
73				elems->wmm_tspec_len = elen;
74				break;
75			default:
76				wpa_printf(MSG_EXCESSIVE, "unknown WMM "
77					   "information element ignored "
78					   "(subtype=%d len=%lu)",
79					   pos[4], (unsigned long) elen);
80				return -1;
81			}
82			break;
83		case 4:
84			/* Wi-Fi Protected Setup (WPS) IE */
85			elems->wps_ie = pos;
86			elems->wps_ie_len = elen;
87			break;
88		default:
89			wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft "
90				   "information element ignored "
91				   "(type=%d len=%lu)",
92				   pos[3], (unsigned long) elen);
93			return -1;
94		}
95		break;
96
97	case OUI_WFA:
98		switch (pos[3]) {
99		case P2P_OUI_TYPE:
100			/* Wi-Fi Alliance - P2P IE */
101			elems->p2p = pos;
102			elems->p2p_len = elen;
103			break;
104		case WFD_OUI_TYPE:
105			/* Wi-Fi Alliance - WFD IE */
106			elems->wfd = pos;
107			elems->wfd_len = elen;
108			break;
109		case HS20_INDICATION_OUI_TYPE:
110			/* Hotspot 2.0 */
111			elems->hs20 = pos;
112			elems->hs20_len = elen;
113			break;
114		case HS20_OSEN_OUI_TYPE:
115			/* Hotspot 2.0 OSEN */
116			elems->osen = pos;
117			elems->osen_len = elen;
118			break;
119		case MBO_OUI_TYPE:
120			/* MBO-OCE */
121			elems->mbo = pos;
122			elems->mbo_len = elen;
123			break;
124		case HS20_ROAMING_CONS_SEL_OUI_TYPE:
125			/* Hotspot 2.0 Roaming Consortium Selection */
126			elems->roaming_cons_sel = pos;
127			elems->roaming_cons_sel_len = elen;
128			break;
129		case MULTI_AP_OUI_TYPE:
130			elems->multi_ap = pos;
131			elems->multi_ap_len = elen;
132			break;
133		default:
134			wpa_printf(MSG_MSGDUMP, "Unknown WFA "
135				   "information element ignored "
136				   "(type=%d len=%lu)",
137				   pos[3], (unsigned long) elen);
138			return -1;
139		}
140		break;
141
142	case OUI_BROADCOM:
143		switch (pos[3]) {
144		case VENDOR_HT_CAPAB_OUI_TYPE:
145			elems->vendor_ht_cap = pos;
146			elems->vendor_ht_cap_len = elen;
147			break;
148		case VENDOR_VHT_TYPE:
149			if (elen > 4 &&
150			    (pos[4] == VENDOR_VHT_SUBTYPE ||
151			     pos[4] == VENDOR_VHT_SUBTYPE2)) {
152				elems->vendor_vht = pos;
153				elems->vendor_vht_len = elen;
154			} else
155				return -1;
156			break;
157		default:
158			wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
159				   "information element ignored "
160				   "(type=%d len=%lu)",
161				   pos[3], (unsigned long) elen);
162			return -1;
163		}
164		break;
165
166	case OUI_QCA:
167		switch (pos[3]) {
168		case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
169			elems->pref_freq_list = pos;
170			elems->pref_freq_list_len = elen;
171			break;
172		default:
173			wpa_printf(MSG_EXCESSIVE,
174				   "Unknown QCA information element ignored (type=%d len=%lu)",
175				   pos[3], (unsigned long) elen);
176			return -1;
177		}
178		break;
179
180	default:
181		wpa_printf(MSG_EXCESSIVE, "unknown vendor specific "
182			   "information element ignored (vendor OUI "
183			   "%02x:%02x:%02x len=%lu)",
184			   pos[0], pos[1], pos[2], (unsigned long) elen);
185		return -1;
186	}
187
188	return 0;
189}
190
191
192static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
193				      struct ieee802_11_elems *elems,
194				      int show_errors)
195{
196	u8 ext_id;
197
198	if (elen < 1) {
199		if (show_errors) {
200			wpa_printf(MSG_MSGDUMP,
201				   "short information element (Ext)");
202		}
203		return -1;
204	}
205
206	ext_id = *pos++;
207	elen--;
208
209	switch (ext_id) {
210	case WLAN_EID_EXT_ASSOC_DELAY_INFO:
211		if (elen != 1)
212			break;
213		elems->assoc_delay_info = pos;
214		break;
215	case WLAN_EID_EXT_FILS_REQ_PARAMS:
216		if (elen < 3)
217			break;
218		elems->fils_req_params = pos;
219		elems->fils_req_params_len = elen;
220		break;
221	case WLAN_EID_EXT_FILS_KEY_CONFIRM:
222		elems->fils_key_confirm = pos;
223		elems->fils_key_confirm_len = elen;
224		break;
225	case WLAN_EID_EXT_FILS_SESSION:
226		if (elen != FILS_SESSION_LEN)
227			break;
228		elems->fils_session = pos;
229		break;
230	case WLAN_EID_EXT_FILS_HLP_CONTAINER:
231		if (elen < 2 * ETH_ALEN)
232			break;
233		elems->fils_hlp = pos;
234		elems->fils_hlp_len = elen;
235		break;
236	case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN:
237		if (elen < 1)
238			break;
239		elems->fils_ip_addr_assign = pos;
240		elems->fils_ip_addr_assign_len = elen;
241		break;
242	case WLAN_EID_EXT_KEY_DELIVERY:
243		if (elen < WPA_KEY_RSC_LEN)
244			break;
245		elems->key_delivery = pos;
246		elems->key_delivery_len = elen;
247		break;
248	case WLAN_EID_EXT_FILS_WRAPPED_DATA:
249		elems->fils_wrapped_data = pos;
250		elems->fils_wrapped_data_len = elen;
251		break;
252	case WLAN_EID_EXT_FILS_PUBLIC_KEY:
253		if (elen < 1)
254			break;
255		elems->fils_pk = pos;
256		elems->fils_pk_len = elen;
257		break;
258	case WLAN_EID_EXT_FILS_NONCE:
259		if (elen != FILS_NONCE_LEN)
260			break;
261		elems->fils_nonce = pos;
262		break;
263	case WLAN_EID_EXT_OWE_DH_PARAM:
264		if (elen < 2)
265			break;
266		elems->owe_dh = pos;
267		elems->owe_dh_len = elen;
268		break;
269	case WLAN_EID_EXT_PASSWORD_IDENTIFIER:
270		elems->password_id = pos;
271		elems->password_id_len = elen;
272		break;
273	case WLAN_EID_EXT_HE_CAPABILITIES:
274		elems->he_capabilities = pos;
275		elems->he_capabilities_len = elen;
276		break;
277	case WLAN_EID_EXT_HE_OPERATION:
278		elems->he_operation = pos;
279		elems->he_operation_len = elen;
280		break;
281	case WLAN_EID_EXT_OCV_OCI:
282		elems->oci = pos;
283		elems->oci_len = elen;
284		break;
285	default:
286		if (show_errors) {
287			wpa_printf(MSG_MSGDUMP,
288				   "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
289				   ext_id, (unsigned int) elen);
290		}
291		return -1;
292	}
293
294	return 0;
295}
296
297
298/**
299 * ieee802_11_parse_elems - Parse information elements in management frames
300 * @start: Pointer to the start of IEs
301 * @len: Length of IE buffer in octets
302 * @elems: Data structure for parsed elements
303 * @show_errors: Whether to show parsing errors in debug log
304 * Returns: Parsing result
305 */
306ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
307				struct ieee802_11_elems *elems,
308				int show_errors)
309{
310	const struct element *elem;
311	int unknown = 0;
312
313	os_memset(elems, 0, sizeof(*elems));
314
315	if (!start)
316		return ParseOK;
317
318	for_each_element(elem, start, len) {
319		u8 id = elem->id, elen = elem->datalen;
320		const u8 *pos = elem->data;
321
322		switch (id) {
323		case WLAN_EID_SSID:
324			if (elen > SSID_MAX_LEN) {
325				wpa_printf(MSG_DEBUG,
326					   "Ignored too long SSID element (elen=%u)",
327					   elen);
328				break;
329			}
330			elems->ssid = pos;
331			elems->ssid_len = elen;
332			break;
333		case WLAN_EID_SUPP_RATES:
334			elems->supp_rates = pos;
335			elems->supp_rates_len = elen;
336			break;
337		case WLAN_EID_DS_PARAMS:
338			if (elen < 1)
339				break;
340			elems->ds_params = pos;
341			break;
342		case WLAN_EID_CF_PARAMS:
343		case WLAN_EID_TIM:
344			break;
345		case WLAN_EID_CHALLENGE:
346			elems->challenge = pos;
347			elems->challenge_len = elen;
348			break;
349		case WLAN_EID_ERP_INFO:
350			if (elen < 1)
351				break;
352			elems->erp_info = pos;
353			break;
354		case WLAN_EID_EXT_SUPP_RATES:
355			elems->ext_supp_rates = pos;
356			elems->ext_supp_rates_len = elen;
357			break;
358		case WLAN_EID_VENDOR_SPECIFIC:
359			if (ieee802_11_parse_vendor_specific(pos, elen,
360							     elems,
361							     show_errors))
362				unknown++;
363			break;
364		case WLAN_EID_RSN:
365			elems->rsn_ie = pos;
366			elems->rsn_ie_len = elen;
367			break;
368		case WLAN_EID_PWR_CAPABILITY:
369			if (elen < 2)
370				break;
371			elems->power_capab = pos;
372			elems->power_capab_len = elen;
373			break;
374		case WLAN_EID_SUPPORTED_CHANNELS:
375			elems->supp_channels = pos;
376			elems->supp_channels_len = elen;
377			break;
378		case WLAN_EID_MOBILITY_DOMAIN:
379			if (elen < sizeof(struct rsn_mdie))
380				break;
381			elems->mdie = pos;
382			elems->mdie_len = elen;
383			break;
384		case WLAN_EID_FAST_BSS_TRANSITION:
385			if (elen < sizeof(struct rsn_ftie))
386				break;
387			elems->ftie = pos;
388			elems->ftie_len = elen;
389			break;
390		case WLAN_EID_TIMEOUT_INTERVAL:
391			if (elen != 5)
392				break;
393			elems->timeout_int = pos;
394			break;
395		case WLAN_EID_HT_CAP:
396			if (elen < sizeof(struct ieee80211_ht_capabilities))
397				break;
398			elems->ht_capabilities = pos;
399			break;
400		case WLAN_EID_HT_OPERATION:
401			if (elen < sizeof(struct ieee80211_ht_operation))
402				break;
403			elems->ht_operation = pos;
404			break;
405		case WLAN_EID_MESH_CONFIG:
406			elems->mesh_config = pos;
407			elems->mesh_config_len = elen;
408			break;
409		case WLAN_EID_MESH_ID:
410			elems->mesh_id = pos;
411			elems->mesh_id_len = elen;
412			break;
413		case WLAN_EID_PEER_MGMT:
414			elems->peer_mgmt = pos;
415			elems->peer_mgmt_len = elen;
416			break;
417		case WLAN_EID_VHT_CAP:
418			if (elen < sizeof(struct ieee80211_vht_capabilities))
419				break;
420			elems->vht_capabilities = pos;
421			break;
422		case WLAN_EID_VHT_OPERATION:
423			if (elen < sizeof(struct ieee80211_vht_operation))
424				break;
425			elems->vht_operation = pos;
426			break;
427		case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
428			if (elen != 1)
429				break;
430			elems->vht_opmode_notif = pos;
431			break;
432		case WLAN_EID_LINK_ID:
433			if (elen < 18)
434				break;
435			elems->link_id = pos;
436			break;
437		case WLAN_EID_INTERWORKING:
438			elems->interworking = pos;
439			elems->interworking_len = elen;
440			break;
441		case WLAN_EID_QOS_MAP_SET:
442			if (elen < 16)
443				break;
444			elems->qos_map_set = pos;
445			elems->qos_map_set_len = elen;
446			break;
447		case WLAN_EID_EXT_CAPAB:
448			elems->ext_capab = pos;
449			elems->ext_capab_len = elen;
450			break;
451		case WLAN_EID_BSS_MAX_IDLE_PERIOD:
452			if (elen < 3)
453				break;
454			elems->bss_max_idle_period = pos;
455			break;
456		case WLAN_EID_SSID_LIST:
457			elems->ssid_list = pos;
458			elems->ssid_list_len = elen;
459			break;
460		case WLAN_EID_AMPE:
461			elems->ampe = pos;
462			elems->ampe_len = elen;
463			break;
464		case WLAN_EID_MIC:
465			elems->mic = pos;
466			elems->mic_len = elen;
467			/* after mic everything is encrypted, so stop. */
468			goto done;
469		case WLAN_EID_MULTI_BAND:
470			if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
471				wpa_printf(MSG_MSGDUMP,
472					   "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
473					   id, elen);
474				break;
475			}
476
477			elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
478			elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
479			elems->mb_ies.nof_ies++;
480			break;
481		case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
482			elems->supp_op_classes = pos;
483			elems->supp_op_classes_len = elen;
484			break;
485		case WLAN_EID_RRM_ENABLED_CAPABILITIES:
486			elems->rrm_enabled = pos;
487			elems->rrm_enabled_len = elen;
488			break;
489		case WLAN_EID_CAG_NUMBER:
490			elems->cag_number = pos;
491			elems->cag_number_len = elen;
492			break;
493		case WLAN_EID_AP_CSN:
494			if (elen < 1)
495				break;
496			elems->ap_csn = pos;
497			break;
498		case WLAN_EID_FILS_INDICATION:
499			if (elen < 2)
500				break;
501			elems->fils_indic = pos;
502			elems->fils_indic_len = elen;
503			break;
504		case WLAN_EID_DILS:
505			if (elen < 2)
506				break;
507			elems->dils = pos;
508			elems->dils_len = elen;
509			break;
510		case WLAN_EID_FRAGMENT:
511			/* TODO */
512			break;
513		case WLAN_EID_EXTENSION:
514			if (ieee802_11_parse_extension(pos, elen, elems,
515						       show_errors))
516				unknown++;
517			break;
518		default:
519			unknown++;
520			if (!show_errors)
521				break;
522			wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
523				   "ignored unknown element (id=%d elen=%d)",
524				   id, elen);
525			break;
526		}
527	}
528
529	if (!for_each_element_completed(elem, start, len)) {
530		if (show_errors) {
531			wpa_printf(MSG_DEBUG,
532				   "IEEE 802.11 element parse failed @%d",
533				   (int) (start + len - (const u8 *) elem));
534			wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
535		}
536		return ParseFailed;
537	}
538
539done:
540	return unknown ? ParseUnknown : ParseOK;
541}
542
543
544int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
545{
546	const struct element *elem;
547	int count = 0;
548
549	if (ies == NULL)
550		return 0;
551
552	for_each_element(elem, ies, ies_len)
553		count++;
554
555	return count;
556}
557
558
559struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
560					    u32 oui_type)
561{
562	struct wpabuf *buf;
563	const struct element *elem, *found = NULL;
564
565	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
566		if (elem->datalen >= 4 &&
567		    WPA_GET_BE32(elem->data) == oui_type) {
568			found = elem;
569			break;
570		}
571	}
572
573	if (!found)
574		return NULL; /* No specified vendor IE found */
575
576	buf = wpabuf_alloc(ies_len);
577	if (buf == NULL)
578		return NULL;
579
580	/*
581	 * There may be multiple vendor IEs in the message, so need to
582	 * concatenate their data fields.
583	 */
584	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
585		if (elem->datalen >= 4 && WPA_GET_BE32(elem->data) == oui_type)
586			wpabuf_put_data(buf, elem->data + 4, elem->datalen - 4);
587	}
588
589	return buf;
590}
591
592
593const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
594{
595	u16 fc, type, stype;
596
597	/*
598	 * PS-Poll frames are 16 bytes. All other frames are
599	 * 24 bytes or longer.
600	 */
601	if (len < 16)
602		return NULL;
603
604	fc = le_to_host16(hdr->frame_control);
605	type = WLAN_FC_GET_TYPE(fc);
606	stype = WLAN_FC_GET_STYPE(fc);
607
608	switch (type) {
609	case WLAN_FC_TYPE_DATA:
610		if (len < 24)
611			return NULL;
612		switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
613		case WLAN_FC_FROMDS | WLAN_FC_TODS:
614		case WLAN_FC_TODS:
615			return hdr->addr1;
616		case WLAN_FC_FROMDS:
617			return hdr->addr2;
618		default:
619			return NULL;
620		}
621	case WLAN_FC_TYPE_CTRL:
622		if (stype != WLAN_FC_STYPE_PSPOLL)
623			return NULL;
624		return hdr->addr1;
625	case WLAN_FC_TYPE_MGMT:
626		return hdr->addr3;
627	default:
628		return NULL;
629	}
630}
631
632
633int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
634			  const char *name, const char *val)
635{
636	int num, v;
637	const char *pos;
638	struct hostapd_wmm_ac_params *ac;
639
640	/* skip 'wme_ac_' or 'wmm_ac_' prefix */
641	pos = name + 7;
642	if (os_strncmp(pos, "be_", 3) == 0) {
643		num = 0;
644		pos += 3;
645	} else if (os_strncmp(pos, "bk_", 3) == 0) {
646		num = 1;
647		pos += 3;
648	} else if (os_strncmp(pos, "vi_", 3) == 0) {
649		num = 2;
650		pos += 3;
651	} else if (os_strncmp(pos, "vo_", 3) == 0) {
652		num = 3;
653		pos += 3;
654	} else {
655		wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
656		return -1;
657	}
658
659	ac = &wmm_ac_params[num];
660
661	if (os_strcmp(pos, "aifs") == 0) {
662		v = atoi(val);
663		if (v < 1 || v > 255) {
664			wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
665			return -1;
666		}
667		ac->aifs = v;
668	} else if (os_strcmp(pos, "cwmin") == 0) {
669		v = atoi(val);
670		if (v < 0 || v > 15) {
671			wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
672			return -1;
673		}
674		ac->cwmin = v;
675	} else if (os_strcmp(pos, "cwmax") == 0) {
676		v = atoi(val);
677		if (v < 0 || v > 15) {
678			wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
679			return -1;
680		}
681		ac->cwmax = v;
682	} else if (os_strcmp(pos, "txop_limit") == 0) {
683		v = atoi(val);
684		if (v < 0 || v > 0xffff) {
685			wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
686			return -1;
687		}
688		ac->txop_limit = v;
689	} else if (os_strcmp(pos, "acm") == 0) {
690		v = atoi(val);
691		if (v < 0 || v > 1) {
692			wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
693			return -1;
694		}
695		ac->admission_control_mandatory = v;
696	} else {
697		wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
698		return -1;
699	}
700
701	return 0;
702}
703
704
705enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
706{
707	u8 op_class;
708
709	return ieee80211_freq_to_channel_ext(freq, 0, CHANWIDTH_USE_HT,
710					     &op_class, channel);
711}
712
713
714/**
715 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
716 * for HT40 and VHT. DFS channels are not covered.
717 * @freq: Frequency (MHz) to convert
718 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
719 * @vht: VHT channel width (CHANWIDTH_*)
720 * @op_class: Buffer for returning operating class
721 * @channel: Buffer for returning channel number
722 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
723 */
724enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
725						   int sec_channel, int vht,
726						   u8 *op_class, u8 *channel)
727{
728	u8 vht_opclass;
729
730	/* TODO: more operating classes */
731
732	if (sec_channel > 1 || sec_channel < -1)
733		return NUM_HOSTAPD_MODES;
734
735	if (freq >= 2412 && freq <= 2472) {
736		if ((freq - 2407) % 5)
737			return NUM_HOSTAPD_MODES;
738
739		if (vht)
740			return NUM_HOSTAPD_MODES;
741
742		/* 2.407 GHz, channels 1..13 */
743		if (sec_channel == 1)
744			*op_class = 83;
745		else if (sec_channel == -1)
746			*op_class = 84;
747		else
748			*op_class = 81;
749
750		*channel = (freq - 2407) / 5;
751
752		return HOSTAPD_MODE_IEEE80211G;
753	}
754
755	if (freq == 2484) {
756		if (sec_channel || vht)
757			return NUM_HOSTAPD_MODES;
758
759		*op_class = 82; /* channel 14 */
760		*channel = 14;
761
762		return HOSTAPD_MODE_IEEE80211B;
763	}
764
765	if (freq >= 4900 && freq < 5000) {
766		if ((freq - 4000) % 5)
767			return NUM_HOSTAPD_MODES;
768		*channel = (freq - 4000) / 5;
769		*op_class = 0; /* TODO */
770		return HOSTAPD_MODE_IEEE80211A;
771	}
772
773	switch (vht) {
774	case CHANWIDTH_80MHZ:
775		vht_opclass = 128;
776		break;
777	case CHANWIDTH_160MHZ:
778		vht_opclass = 129;
779		break;
780	case CHANWIDTH_80P80MHZ:
781		vht_opclass = 130;
782		break;
783	default:
784		vht_opclass = 0;
785		break;
786	}
787
788	/* 5 GHz, channels 36..48 */
789	if (freq >= 5180 && freq <= 5240) {
790		if ((freq - 5000) % 5)
791			return NUM_HOSTAPD_MODES;
792
793		if (vht_opclass)
794			*op_class = vht_opclass;
795		else if (sec_channel == 1)
796			*op_class = 116;
797		else if (sec_channel == -1)
798			*op_class = 117;
799		else
800			*op_class = 115;
801
802		*channel = (freq - 5000) / 5;
803
804		return HOSTAPD_MODE_IEEE80211A;
805	}
806
807	/* 5 GHz, channels 52..64 */
808	if (freq >= 5260 && freq <= 5320) {
809		if ((freq - 5000) % 5)
810			return NUM_HOSTAPD_MODES;
811
812		if (vht_opclass)
813			*op_class = vht_opclass;
814		else if (sec_channel == 1)
815			*op_class = 119;
816		else if (sec_channel == -1)
817			*op_class = 120;
818		else
819			*op_class = 118;
820
821		*channel = (freq - 5000) / 5;
822
823		return HOSTAPD_MODE_IEEE80211A;
824	}
825
826	/* 5 GHz, channels 149..169 */
827	if (freq >= 5745 && freq <= 5845) {
828		if ((freq - 5000) % 5)
829			return NUM_HOSTAPD_MODES;
830
831		if (vht_opclass)
832			*op_class = vht_opclass;
833		else if (sec_channel == 1)
834			*op_class = 126;
835		else if (sec_channel == -1)
836			*op_class = 127;
837		else if (freq <= 5805)
838			*op_class = 124;
839		else
840			*op_class = 125;
841
842		*channel = (freq - 5000) / 5;
843
844		return HOSTAPD_MODE_IEEE80211A;
845	}
846
847	/* 5 GHz, channels 100..140 */
848	if (freq >= 5000 && freq <= 5700) {
849		if ((freq - 5000) % 5)
850			return NUM_HOSTAPD_MODES;
851
852		if (vht_opclass)
853			*op_class = vht_opclass;
854		else if (sec_channel == 1)
855			*op_class = 122;
856		else if (sec_channel == -1)
857			*op_class = 123;
858		else
859			*op_class = 121;
860
861		*channel = (freq - 5000) / 5;
862
863		return HOSTAPD_MODE_IEEE80211A;
864	}
865
866	if (freq >= 5000 && freq < 5900) {
867		if ((freq - 5000) % 5)
868			return NUM_HOSTAPD_MODES;
869		*channel = (freq - 5000) / 5;
870		*op_class = 0; /* TODO */
871		return HOSTAPD_MODE_IEEE80211A;
872	}
873
874	/* 56.16 GHz, channel 1..4 */
875	if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
876		if (sec_channel || vht)
877			return NUM_HOSTAPD_MODES;
878
879		*channel = (freq - 56160) / 2160;
880		*op_class = 180;
881
882		return HOSTAPD_MODE_IEEE80211AD;
883	}
884
885	return NUM_HOSTAPD_MODES;
886}
887
888
889int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
890				  int sec_channel, u8 *op_class, u8 *channel)
891{
892	int vht = CHAN_WIDTH_UNKNOWN;
893
894	switch (chanwidth) {
895	case CHAN_WIDTH_UNKNOWN:
896	case CHAN_WIDTH_20_NOHT:
897	case CHAN_WIDTH_20:
898	case CHAN_WIDTH_40:
899		vht = CHANWIDTH_USE_HT;
900		break;
901	case CHAN_WIDTH_80:
902		vht = CHANWIDTH_80MHZ;
903		break;
904	case CHAN_WIDTH_80P80:
905		vht = CHANWIDTH_80P80MHZ;
906		break;
907	case CHAN_WIDTH_160:
908		vht = CHANWIDTH_160MHZ;
909		break;
910	}
911
912	if (ieee80211_freq_to_channel_ext(freq, sec_channel, vht, op_class,
913					  channel) == NUM_HOSTAPD_MODES) {
914		wpa_printf(MSG_WARNING,
915			   "Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)",
916			   freq, chanwidth, sec_channel);
917		return -1;
918	}
919
920	return 0;
921}
922
923
924static const char *const us_op_class_cc[] = {
925	"US", "CA", NULL
926};
927
928static const char *const eu_op_class_cc[] = {
929	"AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
930	"DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
931	"LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
932	"RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
933};
934
935static const char *const jp_op_class_cc[] = {
936	"JP", NULL
937};
938
939static const char *const cn_op_class_cc[] = {
940	"CN", NULL
941};
942
943
944static int country_match(const char *const cc[], const char *const country)
945{
946	int i;
947
948	if (country == NULL)
949		return 0;
950	for (i = 0; cc[i]; i++) {
951		if (cc[i][0] == country[0] && cc[i][1] == country[1])
952			return 1;
953	}
954
955	return 0;
956}
957
958
959static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
960{
961	switch (op_class) {
962	case 12: /* channels 1..11 */
963	case 32: /* channels 1..7; 40 MHz */
964	case 33: /* channels 5..11; 40 MHz */
965		if (chan < 1 || chan > 11)
966			return -1;
967		return 2407 + 5 * chan;
968	case 1: /* channels 36,40,44,48 */
969	case 2: /* channels 52,56,60,64; dfs */
970	case 22: /* channels 36,44; 40 MHz */
971	case 23: /* channels 52,60; 40 MHz */
972	case 27: /* channels 40,48; 40 MHz */
973	case 28: /* channels 56,64; 40 MHz */
974		if (chan < 36 || chan > 64)
975			return -1;
976		return 5000 + 5 * chan;
977	case 4: /* channels 100-144 */
978	case 24: /* channels 100-140; 40 MHz */
979		if (chan < 100 || chan > 144)
980			return -1;
981		return 5000 + 5 * chan;
982	case 3: /* channels 149,153,157,161 */
983	case 25: /* channels 149,157; 40 MHz */
984	case 26: /* channels 149,157; 40 MHz */
985	case 30: /* channels 153,161; 40 MHz */
986	case 31: /* channels 153,161; 40 MHz */
987		if (chan < 149 || chan > 161)
988			return -1;
989		return 5000 + 5 * chan;
990	case 5: /* channels 149,153,157,161,165 */
991		if (chan < 149 || chan > 165)
992			return -1;
993		return 5000 + 5 * chan;
994	case 34: /* 60 GHz band, channels 1..3 */
995		if (chan < 1 || chan > 3)
996			return -1;
997		return 56160 + 2160 * chan;
998	}
999	return -1;
1000}
1001
1002
1003static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
1004{
1005	switch (op_class) {
1006	case 4: /* channels 1..13 */
1007	case 11: /* channels 1..9; 40 MHz */
1008	case 12: /* channels 5..13; 40 MHz */
1009		if (chan < 1 || chan > 13)
1010			return -1;
1011		return 2407 + 5 * chan;
1012	case 1: /* channels 36,40,44,48 */
1013	case 2: /* channels 52,56,60,64; dfs */
1014	case 5: /* channels 36,44; 40 MHz */
1015	case 6: /* channels 52,60; 40 MHz */
1016	case 8: /* channels 40,48; 40 MHz */
1017	case 9: /* channels 56,64; 40 MHz */
1018		if (chan < 36 || chan > 64)
1019			return -1;
1020		return 5000 + 5 * chan;
1021	case 3: /* channels 100-140 */
1022	case 7: /* channels 100-132; 40 MHz */
1023	case 10: /* channels 104-136; 40 MHz */
1024	case 16: /* channels 100-140 */
1025		if (chan < 100 || chan > 140)
1026			return -1;
1027		return 5000 + 5 * chan;
1028	case 17: /* channels 149,153,157,161,165,169 */
1029		if (chan < 149 || chan > 169)
1030			return -1;
1031		return 5000 + 5 * chan;
1032	case 18: /* 60 GHz band, channels 1..4 */
1033		if (chan < 1 || chan > 4)
1034			return -1;
1035		return 56160 + 2160 * chan;
1036	}
1037	return -1;
1038}
1039
1040
1041static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
1042{
1043	switch (op_class) {
1044	case 30: /* channels 1..13 */
1045	case 56: /* channels 1..9; 40 MHz */
1046	case 57: /* channels 5..13; 40 MHz */
1047		if (chan < 1 || chan > 13)
1048			return -1;
1049		return 2407 + 5 * chan;
1050	case 31: /* channel 14 */
1051		if (chan != 14)
1052			return -1;
1053		return 2414 + 5 * chan;
1054	case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
1055	case 32: /* channels 52,56,60,64 */
1056	case 33: /* channels 52,56,60,64 */
1057	case 36: /* channels 36,44; 40 MHz */
1058	case 37: /* channels 52,60; 40 MHz */
1059	case 38: /* channels 52,60; 40 MHz */
1060	case 41: /* channels 40,48; 40 MHz */
1061	case 42: /* channels 56,64; 40 MHz */
1062	case 43: /* channels 56,64; 40 MHz */
1063		if (chan < 34 || chan > 64)
1064			return -1;
1065		return 5000 + 5 * chan;
1066	case 34: /* channels 100-140 */
1067	case 35: /* channels 100-140 */
1068	case 39: /* channels 100-132; 40 MHz */
1069	case 40: /* channels 100-132; 40 MHz */
1070	case 44: /* channels 104-136; 40 MHz */
1071	case 45: /* channels 104-136; 40 MHz */
1072	case 58: /* channels 100-140 */
1073		if (chan < 100 || chan > 140)
1074			return -1;
1075		return 5000 + 5 * chan;
1076	case 59: /* 60 GHz band, channels 1..4 */
1077		if (chan < 1 || chan > 3)
1078			return -1;
1079		return 56160 + 2160 * chan;
1080	}
1081	return -1;
1082}
1083
1084
1085static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
1086{
1087	switch (op_class) {
1088	case 7: /* channels 1..13 */
1089	case 8: /* channels 1..9; 40 MHz */
1090	case 9: /* channels 5..13; 40 MHz */
1091		if (chan < 1 || chan > 13)
1092			return -1;
1093		return 2407 + 5 * chan;
1094	case 1: /* channels 36,40,44,48 */
1095	case 2: /* channels 52,56,60,64; dfs */
1096	case 4: /* channels 36,44; 40 MHz */
1097	case 5: /* channels 52,60; 40 MHz */
1098		if (chan < 36 || chan > 64)
1099			return -1;
1100		return 5000 + 5 * chan;
1101	case 3: /* channels 149,153,157,161,165 */
1102	case 6: /* channels 149,157; 40 MHz */
1103		if (chan < 149 || chan > 165)
1104			return -1;
1105		return 5000 + 5 * chan;
1106	}
1107	return -1;
1108}
1109
1110
1111static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
1112{
1113	/* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
1114	switch (op_class) {
1115	case 81:
1116		/* channels 1..13 */
1117		if (chan < 1 || chan > 13)
1118			return -1;
1119		return 2407 + 5 * chan;
1120	case 82:
1121		/* channel 14 */
1122		if (chan != 14)
1123			return -1;
1124		return 2414 + 5 * chan;
1125	case 83: /* channels 1..9; 40 MHz */
1126	case 84: /* channels 5..13; 40 MHz */
1127		if (chan < 1 || chan > 13)
1128			return -1;
1129		return 2407 + 5 * chan;
1130	case 115: /* channels 36,40,44,48; indoor only */
1131	case 116: /* channels 36,44; 40 MHz; indoor only */
1132	case 117: /* channels 40,48; 40 MHz; indoor only */
1133	case 118: /* channels 52,56,60,64; dfs */
1134	case 119: /* channels 52,60; 40 MHz; dfs */
1135	case 120: /* channels 56,64; 40 MHz; dfs */
1136		if (chan < 36 || chan > 64)
1137			return -1;
1138		return 5000 + 5 * chan;
1139	case 121: /* channels 100-140 */
1140	case 122: /* channels 100-142; 40 MHz */
1141	case 123: /* channels 104-136; 40 MHz */
1142		if (chan < 100 || chan > 140)
1143			return -1;
1144		return 5000 + 5 * chan;
1145	case 124: /* channels 149,153,157,161 */
1146	case 126: /* channels 149,157; 40 MHz */
1147	case 127: /* channels 153,161; 40 MHz */
1148		if (chan < 149 || chan > 161)
1149			return -1;
1150		return 5000 + 5 * chan;
1151	case 125: /* channels 149,153,157,161,165,169 */
1152		if (chan < 149 || chan > 169)
1153			return -1;
1154		return 5000 + 5 * chan;
1155	case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1156	case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1157		if (chan < 36 || chan > 161)
1158			return -1;
1159		return 5000 + 5 * chan;
1160	case 129: /* center freqs 50, 114; 160 MHz */
1161		if (chan < 36 || chan > 128)
1162			return -1;
1163		return 5000 + 5 * chan;
1164	case 180: /* 60 GHz band, channels 1..4 */
1165		if (chan < 1 || chan > 4)
1166			return -1;
1167		return 56160 + 2160 * chan;
1168	}
1169	return -1;
1170}
1171
1172/**
1173 * ieee80211_chan_to_freq - Convert channel info to frequency
1174 * @country: Country code, if known; otherwise, global operating class is used
1175 * @op_class: Operating class
1176 * @chan: Channel number
1177 * Returns: Frequency in MHz or -1 if the specified channel is unknown
1178 */
1179int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
1180{
1181	int freq;
1182
1183	if (country_match(us_op_class_cc, country)) {
1184		freq = ieee80211_chan_to_freq_us(op_class, chan);
1185		if (freq > 0)
1186			return freq;
1187	}
1188
1189	if (country_match(eu_op_class_cc, country)) {
1190		freq = ieee80211_chan_to_freq_eu(op_class, chan);
1191		if (freq > 0)
1192			return freq;
1193	}
1194
1195	if (country_match(jp_op_class_cc, country)) {
1196		freq = ieee80211_chan_to_freq_jp(op_class, chan);
1197		if (freq > 0)
1198			return freq;
1199	}
1200
1201	if (country_match(cn_op_class_cc, country)) {
1202		freq = ieee80211_chan_to_freq_cn(op_class, chan);
1203		if (freq > 0)
1204			return freq;
1205	}
1206
1207	return ieee80211_chan_to_freq_global(op_class, chan);
1208}
1209
1210
1211int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
1212		     u16 num_modes)
1213{
1214	int i, j;
1215
1216	if (!modes || !num_modes)
1217		return (freq >= 5260 && freq <= 5320) ||
1218			(freq >= 5500 && freq <= 5700);
1219
1220	for (i = 0; i < num_modes; i++) {
1221		for (j = 0; j < modes[i].num_channels; j++) {
1222			if (modes[i].channels[j].freq == freq &&
1223			    (modes[i].channels[j].flag & HOSTAPD_CHAN_RADAR))
1224				return 1;
1225		}
1226	}
1227
1228	return 0;
1229}
1230
1231
1232static int is_11b(u8 rate)
1233{
1234	return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1235}
1236
1237
1238int supp_rates_11b_only(struct ieee802_11_elems *elems)
1239{
1240	int num_11b = 0, num_others = 0;
1241	int i;
1242
1243	if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1244		return 0;
1245
1246	for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1247		if (is_11b(elems->supp_rates[i]))
1248			num_11b++;
1249		else
1250			num_others++;
1251	}
1252
1253	for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1254	     i++) {
1255		if (is_11b(elems->ext_supp_rates[i]))
1256			num_11b++;
1257		else
1258			num_others++;
1259	}
1260
1261	return num_11b > 0 && num_others == 0;
1262}
1263
1264
1265const char * fc2str(u16 fc)
1266{
1267	u16 stype = WLAN_FC_GET_STYPE(fc);
1268#define C2S(x) case x: return #x;
1269
1270	switch (WLAN_FC_GET_TYPE(fc)) {
1271	case WLAN_FC_TYPE_MGMT:
1272		switch (stype) {
1273		C2S(WLAN_FC_STYPE_ASSOC_REQ)
1274		C2S(WLAN_FC_STYPE_ASSOC_RESP)
1275		C2S(WLAN_FC_STYPE_REASSOC_REQ)
1276		C2S(WLAN_FC_STYPE_REASSOC_RESP)
1277		C2S(WLAN_FC_STYPE_PROBE_REQ)
1278		C2S(WLAN_FC_STYPE_PROBE_RESP)
1279		C2S(WLAN_FC_STYPE_BEACON)
1280		C2S(WLAN_FC_STYPE_ATIM)
1281		C2S(WLAN_FC_STYPE_DISASSOC)
1282		C2S(WLAN_FC_STYPE_AUTH)
1283		C2S(WLAN_FC_STYPE_DEAUTH)
1284		C2S(WLAN_FC_STYPE_ACTION)
1285		}
1286		break;
1287	case WLAN_FC_TYPE_CTRL:
1288		switch (stype) {
1289		C2S(WLAN_FC_STYPE_PSPOLL)
1290		C2S(WLAN_FC_STYPE_RTS)
1291		C2S(WLAN_FC_STYPE_CTS)
1292		C2S(WLAN_FC_STYPE_ACK)
1293		C2S(WLAN_FC_STYPE_CFEND)
1294		C2S(WLAN_FC_STYPE_CFENDACK)
1295		}
1296		break;
1297	case WLAN_FC_TYPE_DATA:
1298		switch (stype) {
1299		C2S(WLAN_FC_STYPE_DATA)
1300		C2S(WLAN_FC_STYPE_DATA_CFACK)
1301		C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1302		C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1303		C2S(WLAN_FC_STYPE_NULLFUNC)
1304		C2S(WLAN_FC_STYPE_CFACK)
1305		C2S(WLAN_FC_STYPE_CFPOLL)
1306		C2S(WLAN_FC_STYPE_CFACKPOLL)
1307		C2S(WLAN_FC_STYPE_QOS_DATA)
1308		C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1309		C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1310		C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1311		C2S(WLAN_FC_STYPE_QOS_NULL)
1312		C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1313		C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1314		}
1315		break;
1316	}
1317	return "WLAN_FC_TYPE_UNKNOWN";
1318#undef C2S
1319}
1320
1321
1322const char * reason2str(u16 reason)
1323{
1324#define R2S(r) case WLAN_REASON_ ## r: return #r;
1325	switch (reason) {
1326	R2S(UNSPECIFIED)
1327	R2S(PREV_AUTH_NOT_VALID)
1328	R2S(DEAUTH_LEAVING)
1329	R2S(DISASSOC_DUE_TO_INACTIVITY)
1330	R2S(DISASSOC_AP_BUSY)
1331	R2S(CLASS2_FRAME_FROM_NONAUTH_STA)
1332	R2S(CLASS3_FRAME_FROM_NONASSOC_STA)
1333	R2S(DISASSOC_STA_HAS_LEFT)
1334	R2S(STA_REQ_ASSOC_WITHOUT_AUTH)
1335	R2S(PWR_CAPABILITY_NOT_VALID)
1336	R2S(SUPPORTED_CHANNEL_NOT_VALID)
1337	R2S(BSS_TRANSITION_DISASSOC)
1338	R2S(INVALID_IE)
1339	R2S(MICHAEL_MIC_FAILURE)
1340	R2S(4WAY_HANDSHAKE_TIMEOUT)
1341	R2S(GROUP_KEY_UPDATE_TIMEOUT)
1342	R2S(IE_IN_4WAY_DIFFERS)
1343	R2S(GROUP_CIPHER_NOT_VALID)
1344	R2S(PAIRWISE_CIPHER_NOT_VALID)
1345	R2S(AKMP_NOT_VALID)
1346	R2S(UNSUPPORTED_RSN_IE_VERSION)
1347	R2S(INVALID_RSN_IE_CAPAB)
1348	R2S(IEEE_802_1X_AUTH_FAILED)
1349	R2S(CIPHER_SUITE_REJECTED)
1350	R2S(TDLS_TEARDOWN_UNREACHABLE)
1351	R2S(TDLS_TEARDOWN_UNSPECIFIED)
1352	R2S(SSP_REQUESTED_DISASSOC)
1353	R2S(NO_SSP_ROAMING_AGREEMENT)
1354	R2S(BAD_CIPHER_OR_AKM)
1355	R2S(NOT_AUTHORIZED_THIS_LOCATION)
1356	R2S(SERVICE_CHANGE_PRECLUDES_TS)
1357	R2S(UNSPECIFIED_QOS_REASON)
1358	R2S(NOT_ENOUGH_BANDWIDTH)
1359	R2S(DISASSOC_LOW_ACK)
1360	R2S(EXCEEDED_TXOP)
1361	R2S(STA_LEAVING)
1362	R2S(END_TS_BA_DLS)
1363	R2S(UNKNOWN_TS_BA)
1364	R2S(TIMEOUT)
1365	R2S(PEERKEY_MISMATCH)
1366	R2S(AUTHORIZED_ACCESS_LIMIT_REACHED)
1367	R2S(EXTERNAL_SERVICE_REQUIREMENTS)
1368	R2S(INVALID_FT_ACTION_FRAME_COUNT)
1369	R2S(INVALID_PMKID)
1370	R2S(INVALID_MDE)
1371	R2S(INVALID_FTE)
1372	R2S(MESH_PEERING_CANCELLED)
1373	R2S(MESH_MAX_PEERS)
1374	R2S(MESH_CONFIG_POLICY_VIOLATION)
1375	R2S(MESH_CLOSE_RCVD)
1376	R2S(MESH_MAX_RETRIES)
1377	R2S(MESH_CONFIRM_TIMEOUT)
1378	R2S(MESH_INVALID_GTK)
1379	R2S(MESH_INCONSISTENT_PARAMS)
1380	R2S(MESH_INVALID_SECURITY_CAP)
1381	R2S(MESH_PATH_ERROR_NO_PROXY_INFO)
1382	R2S(MESH_PATH_ERROR_NO_FORWARDING_INFO)
1383	R2S(MESH_PATH_ERROR_DEST_UNREACHABLE)
1384	R2S(MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS)
1385	R2S(MESH_CHANNEL_SWITCH_REGULATORY_REQ)
1386	R2S(MESH_CHANNEL_SWITCH_UNSPECIFIED)
1387	}
1388	return "UNKNOWN";
1389#undef R2S
1390}
1391
1392
1393const char * status2str(u16 status)
1394{
1395#define S2S(s) case WLAN_STATUS_ ## s: return #s;
1396	switch (status) {
1397	S2S(SUCCESS)
1398	S2S(UNSPECIFIED_FAILURE)
1399	S2S(TDLS_WAKEUP_ALTERNATE)
1400	S2S(TDLS_WAKEUP_REJECT)
1401	S2S(SECURITY_DISABLED)
1402	S2S(UNACCEPTABLE_LIFETIME)
1403	S2S(NOT_IN_SAME_BSS)
1404	S2S(CAPS_UNSUPPORTED)
1405	S2S(REASSOC_NO_ASSOC)
1406	S2S(ASSOC_DENIED_UNSPEC)
1407	S2S(NOT_SUPPORTED_AUTH_ALG)
1408	S2S(UNKNOWN_AUTH_TRANSACTION)
1409	S2S(CHALLENGE_FAIL)
1410	S2S(AUTH_TIMEOUT)
1411	S2S(AP_UNABLE_TO_HANDLE_NEW_STA)
1412	S2S(ASSOC_DENIED_RATES)
1413	S2S(ASSOC_DENIED_NOSHORT)
1414	S2S(SPEC_MGMT_REQUIRED)
1415	S2S(PWR_CAPABILITY_NOT_VALID)
1416	S2S(SUPPORTED_CHANNEL_NOT_VALID)
1417	S2S(ASSOC_DENIED_NO_SHORT_SLOT_TIME)
1418	S2S(ASSOC_DENIED_NO_HT)
1419	S2S(R0KH_UNREACHABLE)
1420	S2S(ASSOC_DENIED_NO_PCO)
1421	S2S(ASSOC_REJECTED_TEMPORARILY)
1422	S2S(ROBUST_MGMT_FRAME_POLICY_VIOLATION)
1423	S2S(UNSPECIFIED_QOS_FAILURE)
1424	S2S(DENIED_INSUFFICIENT_BANDWIDTH)
1425	S2S(DENIED_POOR_CHANNEL_CONDITIONS)
1426	S2S(DENIED_QOS_NOT_SUPPORTED)
1427	S2S(REQUEST_DECLINED)
1428	S2S(INVALID_PARAMETERS)
1429	S2S(REJECTED_WITH_SUGGESTED_CHANGES)
1430	S2S(INVALID_IE)
1431	S2S(GROUP_CIPHER_NOT_VALID)
1432	S2S(PAIRWISE_CIPHER_NOT_VALID)
1433	S2S(AKMP_NOT_VALID)
1434	S2S(UNSUPPORTED_RSN_IE_VERSION)
1435	S2S(INVALID_RSN_IE_CAPAB)
1436	S2S(CIPHER_REJECTED_PER_POLICY)
1437	S2S(TS_NOT_CREATED)
1438	S2S(DIRECT_LINK_NOT_ALLOWED)
1439	S2S(DEST_STA_NOT_PRESENT)
1440	S2S(DEST_STA_NOT_QOS_STA)
1441	S2S(ASSOC_DENIED_LISTEN_INT_TOO_LARGE)
1442	S2S(INVALID_FT_ACTION_FRAME_COUNT)
1443	S2S(INVALID_PMKID)
1444	S2S(INVALID_MDIE)
1445	S2S(INVALID_FTIE)
1446	S2S(REQUESTED_TCLAS_NOT_SUPPORTED)
1447	S2S(INSUFFICIENT_TCLAS_PROCESSING_RESOURCES)
1448	S2S(TRY_ANOTHER_BSS)
1449	S2S(GAS_ADV_PROTO_NOT_SUPPORTED)
1450	S2S(NO_OUTSTANDING_GAS_REQ)
1451	S2S(GAS_RESP_NOT_RECEIVED)
1452	S2S(STA_TIMED_OUT_WAITING_FOR_GAS_RESP)
1453	S2S(GAS_RESP_LARGER_THAN_LIMIT)
1454	S2S(REQ_REFUSED_HOME)
1455	S2S(ADV_SRV_UNREACHABLE)
1456	S2S(REQ_REFUSED_SSPN)
1457	S2S(REQ_REFUSED_UNAUTH_ACCESS)
1458	S2S(INVALID_RSNIE)
1459	S2S(U_APSD_COEX_NOT_SUPPORTED)
1460	S2S(U_APSD_COEX_MODE_NOT_SUPPORTED)
1461	S2S(BAD_INTERVAL_WITH_U_APSD_COEX)
1462	S2S(ANTI_CLOGGING_TOKEN_REQ)
1463	S2S(FINITE_CYCLIC_GROUP_NOT_SUPPORTED)
1464	S2S(CANNOT_FIND_ALT_TBTT)
1465	S2S(TRANSMISSION_FAILURE)
1466	S2S(REQ_TCLAS_NOT_SUPPORTED)
1467	S2S(TCLAS_RESOURCES_EXCHAUSTED)
1468	S2S(REJECTED_WITH_SUGGESTED_BSS_TRANSITION)
1469	S2S(REJECT_WITH_SCHEDULE)
1470	S2S(REJECT_NO_WAKEUP_SPECIFIED)
1471	S2S(SUCCESS_POWER_SAVE_MODE)
1472	S2S(PENDING_ADMITTING_FST_SESSION)
1473	S2S(PERFORMING_FST_NOW)
1474	S2S(PENDING_GAP_IN_BA_WINDOW)
1475	S2S(REJECT_U_PID_SETTING)
1476	S2S(REFUSED_EXTERNAL_REASON)
1477	S2S(REFUSED_AP_OUT_OF_MEMORY)
1478	S2S(REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED)
1479	S2S(QUERY_RESP_OUTSTANDING)
1480	S2S(REJECT_DSE_BAND)
1481	S2S(TCLAS_PROCESSING_TERMINATED)
1482	S2S(TS_SCHEDULE_CONFLICT)
1483	S2S(DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL)
1484	S2S(MCCAOP_RESERVATION_CONFLICT)
1485	S2S(MAF_LIMIT_EXCEEDED)
1486	S2S(MCCA_TRACK_LIMIT_EXCEEDED)
1487	S2S(DENIED_DUE_TO_SPECTRUM_MANAGEMENT)
1488	S2S(ASSOC_DENIED_NO_VHT)
1489	S2S(ENABLEMENT_DENIED)
1490	S2S(RESTRICTION_FROM_AUTHORIZED_GDB)
1491	S2S(AUTHORIZATION_DEENABLED)
1492	S2S(FILS_AUTHENTICATION_FAILURE)
1493	S2S(UNKNOWN_AUTHENTICATION_SERVER)
1494	S2S(UNKNOWN_PASSWORD_IDENTIFIER)
1495	}
1496	return "UNKNOWN";
1497#undef S2S
1498}
1499
1500
1501int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1502		       size_t ies_len)
1503{
1504	const struct element *elem;
1505
1506	os_memset(info, 0, sizeof(*info));
1507
1508	if (!ies_buf)
1509		return 0;
1510
1511	for_each_element_id(elem, WLAN_EID_MULTI_BAND, ies_buf, ies_len) {
1512		if (info->nof_ies >= MAX_NOF_MB_IES_SUPPORTED)
1513			return 0;
1514
1515		wpa_printf(MSG_DEBUG, "MB IE of %u bytes found",
1516			   elem->datalen + 2);
1517		info->ies[info->nof_ies].ie = elem->data;
1518		info->ies[info->nof_ies].ie_len = elem->datalen;
1519		info->nof_ies++;
1520	}
1521
1522	if (!for_each_element_completed(elem, ies_buf, ies_len)) {
1523		wpa_hexdump(MSG_DEBUG, "Truncated IEs", ies_buf, ies_len);
1524		return -1;
1525	}
1526
1527	return 0;
1528}
1529
1530
1531struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1532{
1533	struct wpabuf *mb_ies = NULL;
1534
1535	WPA_ASSERT(info != NULL);
1536
1537	if (info->nof_ies) {
1538		u8 i;
1539		size_t mb_ies_size = 0;
1540
1541		for (i = 0; i < info->nof_ies; i++)
1542			mb_ies_size += 2 + info->ies[i].ie_len;
1543
1544		mb_ies = wpabuf_alloc(mb_ies_size);
1545		if (mb_ies) {
1546			for (i = 0; i < info->nof_ies; i++) {
1547				wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1548				wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1549				wpabuf_put_data(mb_ies,
1550						info->ies[i].ie,
1551						info->ies[i].ie_len);
1552			}
1553		}
1554	}
1555
1556	return mb_ies;
1557}
1558
1559
1560const struct oper_class_map global_op_class[] = {
1561	{ HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1562	{ HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1563
1564	/* Do not enable HT40 on 2.4 GHz for P2P use for now */
1565	{ HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1566	{ HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1567
1568	{ HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1569	{ HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1570	{ HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1571	{ HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1572	{ HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1573	{ HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1574	{ HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1575	{ HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1576	{ HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1577	{ HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1578	{ HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
1579	{ HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
1580	{ HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
1581
1582	/*
1583	 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
1584	 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
1585	 * 80 MHz, but currently use the following definition for simplicity
1586	 * (these center frequencies are not actual channels, which makes
1587	 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
1588	 * care of removing invalid channels.
1589	 */
1590	{ HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
1591	{ HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
1592	{ HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
1593	{ HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
1594	{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
1595};
1596
1597
1598static enum phy_type ieee80211_phy_type_by_freq(int freq)
1599{
1600	enum hostapd_hw_mode hw_mode;
1601	u8 channel;
1602
1603	hw_mode = ieee80211_freq_to_chan(freq, &channel);
1604
1605	switch (hw_mode) {
1606	case HOSTAPD_MODE_IEEE80211A:
1607		return PHY_TYPE_OFDM;
1608	case HOSTAPD_MODE_IEEE80211B:
1609		return PHY_TYPE_HRDSSS;
1610	case HOSTAPD_MODE_IEEE80211G:
1611		return PHY_TYPE_ERP;
1612	case HOSTAPD_MODE_IEEE80211AD:
1613		return PHY_TYPE_DMG;
1614	default:
1615		return PHY_TYPE_UNSPECIFIED;
1616	};
1617}
1618
1619
1620/* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
1621enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
1622{
1623	if (vht)
1624		return PHY_TYPE_VHT;
1625	if (ht)
1626		return PHY_TYPE_HT;
1627
1628	return ieee80211_phy_type_by_freq(freq);
1629}
1630
1631
1632size_t global_op_class_size = ARRAY_SIZE(global_op_class);
1633
1634
1635/**
1636 * get_ie - Fetch a specified information element from IEs buffer
1637 * @ies: Information elements buffer
1638 * @len: Information elements buffer length
1639 * @eid: Information element identifier (WLAN_EID_*)
1640 * Returns: Pointer to the information element (id field) or %NULL if not found
1641 *
1642 * This function returns the first matching information element in the IEs
1643 * buffer or %NULL in case the element is not found.
1644 */
1645const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
1646{
1647	const struct element *elem;
1648
1649	if (!ies)
1650		return NULL;
1651
1652	for_each_element_id(elem, eid, ies, len)
1653		return &elem->id;
1654
1655	return NULL;
1656}
1657
1658
1659/**
1660 * get_ie_ext - Fetch a specified extended information element from IEs buffer
1661 * @ies: Information elements buffer
1662 * @len: Information elements buffer length
1663 * @ext: Information element extension identifier (WLAN_EID_EXT_*)
1664 * Returns: Pointer to the information element (id field) or %NULL if not found
1665 *
1666 * This function returns the first matching information element in the IEs
1667 * buffer or %NULL in case the element is not found.
1668 */
1669const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
1670{
1671	const struct element *elem;
1672
1673	if (!ies)
1674		return NULL;
1675
1676	for_each_element_extid(elem, ext, ies, len)
1677		return &elem->id;
1678
1679	return NULL;
1680}
1681
1682
1683const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type)
1684{
1685	const struct element *elem;
1686
1687	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, len) {
1688		if (elem->datalen >= 4 &&
1689		    vendor_type == WPA_GET_BE32(elem->data))
1690			return &elem->id;
1691	}
1692
1693	return NULL;
1694}
1695
1696
1697size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
1698{
1699	/*
1700	 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
1701	 * OUI (3), OUI type (1).
1702	 */
1703	if (len < 6 + attr_len) {
1704		wpa_printf(MSG_DEBUG,
1705			   "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
1706			   len, attr_len);
1707		return 0;
1708	}
1709
1710	*buf++ = WLAN_EID_VENDOR_SPECIFIC;
1711	*buf++ = attr_len + 4;
1712	WPA_PUT_BE24(buf, OUI_WFA);
1713	buf += 3;
1714	*buf++ = MBO_OUI_TYPE;
1715	os_memcpy(buf, attr, attr_len);
1716
1717	return 6 + attr_len;
1718}
1719
1720
1721size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
1722{
1723	u8 *pos = buf;
1724
1725	if (len < 9)
1726		return 0;
1727
1728	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
1729	*pos++ = 7; /* len */
1730	WPA_PUT_BE24(pos, OUI_WFA);
1731	pos += 3;
1732	*pos++ = MULTI_AP_OUI_TYPE;
1733	*pos++ = MULTI_AP_SUB_ELEM_TYPE;
1734	*pos++ = 1; /* len */
1735	*pos++ = value;
1736
1737	return pos - buf;
1738}
1739
1740
1741static const struct country_op_class us_op_class[] = {
1742	{ 1, 115 },
1743	{ 2, 118 },
1744	{ 3, 124 },
1745	{ 4, 121 },
1746	{ 5, 125 },
1747	{ 12, 81 },
1748	{ 22, 116 },
1749	{ 23, 119 },
1750	{ 24, 122 },
1751	{ 25, 126 },
1752	{ 26, 126 },
1753	{ 27, 117 },
1754	{ 28, 120 },
1755	{ 29, 123 },
1756	{ 30, 127 },
1757	{ 31, 127 },
1758	{ 32, 83 },
1759	{ 33, 84 },
1760	{ 34, 180 },
1761};
1762
1763static const struct country_op_class eu_op_class[] = {
1764	{ 1, 115 },
1765	{ 2, 118 },
1766	{ 3, 121 },
1767	{ 4, 81 },
1768	{ 5, 116 },
1769	{ 6, 119 },
1770	{ 7, 122 },
1771	{ 8, 117 },
1772	{ 9, 120 },
1773	{ 10, 123 },
1774	{ 11, 83 },
1775	{ 12, 84 },
1776	{ 17, 125 },
1777	{ 18, 180 },
1778};
1779
1780static const struct country_op_class jp_op_class[] = {
1781	{ 1, 115 },
1782	{ 30, 81 },
1783	{ 31, 82 },
1784	{ 32, 118 },
1785	{ 33, 118 },
1786	{ 34, 121 },
1787	{ 35, 121 },
1788	{ 36, 116 },
1789	{ 37, 119 },
1790	{ 38, 119 },
1791	{ 39, 122 },
1792	{ 40, 122 },
1793	{ 41, 117 },
1794	{ 42, 120 },
1795	{ 43, 120 },
1796	{ 44, 123 },
1797	{ 45, 123 },
1798	{ 56, 83 },
1799	{ 57, 84 },
1800	{ 58, 121 },
1801	{ 59, 180 },
1802};
1803
1804static const struct country_op_class cn_op_class[] = {
1805	{ 1, 115 },
1806	{ 2, 118 },
1807	{ 3, 125 },
1808	{ 4, 116 },
1809	{ 5, 119 },
1810	{ 6, 126 },
1811	{ 7, 81 },
1812	{ 8, 83 },
1813	{ 9, 84 },
1814};
1815
1816static u8
1817global_op_class_from_country_array(u8 op_class, size_t array_size,
1818				   const struct country_op_class *country_array)
1819{
1820	size_t i;
1821
1822	for (i = 0; i < array_size; i++) {
1823		if (country_array[i].country_op_class == op_class)
1824			return country_array[i].global_op_class;
1825	}
1826
1827	return 0;
1828}
1829
1830
1831u8 country_to_global_op_class(const char *country, u8 op_class)
1832{
1833	const struct country_op_class *country_array;
1834	size_t size;
1835	u8 g_op_class;
1836
1837	if (country_match(us_op_class_cc, country)) {
1838		country_array = us_op_class;
1839		size = ARRAY_SIZE(us_op_class);
1840	} else if (country_match(eu_op_class_cc, country)) {
1841		country_array = eu_op_class;
1842		size = ARRAY_SIZE(eu_op_class);
1843	} else if (country_match(jp_op_class_cc, country)) {
1844		country_array = jp_op_class;
1845		size = ARRAY_SIZE(jp_op_class);
1846	} else if (country_match(cn_op_class_cc, country)) {
1847		country_array = cn_op_class;
1848		size = ARRAY_SIZE(cn_op_class);
1849	} else {
1850		/*
1851		 * Countries that do not match any of the above countries use
1852		 * global operating classes
1853		 */
1854		return op_class;
1855	}
1856
1857	g_op_class = global_op_class_from_country_array(op_class, size,
1858							country_array);
1859
1860	/*
1861	 * If the given operating class did not match any of the country's
1862	 * operating classes, assume that global operating class is used.
1863	 */
1864	return g_op_class ? g_op_class : op_class;
1865}
1866
1867
1868const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
1869{
1870	const struct oper_class_map *op;
1871
1872	if (country)
1873		op_class = country_to_global_op_class(country, op_class);
1874
1875	op = &global_op_class[0];
1876	while (op->op_class && op->op_class != op_class)
1877		op++;
1878
1879	if (!op->op_class)
1880		return NULL;
1881
1882	return op;
1883}
1884
1885
1886int oper_class_bw_to_int(const struct oper_class_map *map)
1887{
1888	switch (map->bw) {
1889	case BW20:
1890		return 20;
1891	case BW40PLUS:
1892	case BW40MINUS:
1893		return 40;
1894	case BW80:
1895		return 80;
1896	case BW80P80:
1897	case BW160:
1898		return 160;
1899	case BW2160:
1900		return 2160;
1901	default:
1902		return 0;
1903	}
1904}
1905
1906
1907int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
1908				    size_t nei_rep_len)
1909{
1910	u8 *nei_pos = nei_rep;
1911	const char *end;
1912
1913	/*
1914	 * BSS Transition Candidate List Entries - Neighbor Report elements
1915	 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
1916	 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
1917	 */
1918	while (pos) {
1919		u8 *nei_start;
1920		long int val;
1921		char *endptr, *tmp;
1922
1923		pos = os_strstr(pos, " neighbor=");
1924		if (!pos)
1925			break;
1926		if (nei_pos + 15 > nei_rep + nei_rep_len) {
1927			wpa_printf(MSG_DEBUG,
1928				   "Not enough room for additional neighbor");
1929			return -1;
1930		}
1931		pos += 10;
1932
1933		nei_start = nei_pos;
1934		*nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
1935		nei_pos++; /* length to be filled in */
1936
1937		if (hwaddr_aton(pos, nei_pos)) {
1938			wpa_printf(MSG_DEBUG, "Invalid BSSID");
1939			return -1;
1940		}
1941		nei_pos += ETH_ALEN;
1942		pos += 17;
1943		if (*pos != ',') {
1944			wpa_printf(MSG_DEBUG, "Missing BSSID Information");
1945			return -1;
1946		}
1947		pos++;
1948
1949		val = strtol(pos, &endptr, 0);
1950		WPA_PUT_LE32(nei_pos, val);
1951		nei_pos += 4;
1952		if (*endptr != ',') {
1953			wpa_printf(MSG_DEBUG, "Missing Operating Class");
1954			return -1;
1955		}
1956		pos = endptr + 1;
1957
1958		*nei_pos++ = atoi(pos); /* Operating Class */
1959		pos = os_strchr(pos, ',');
1960		if (pos == NULL) {
1961			wpa_printf(MSG_DEBUG, "Missing Channel Number");
1962			return -1;
1963		}
1964		pos++;
1965
1966		*nei_pos++ = atoi(pos); /* Channel Number */
1967		pos = os_strchr(pos, ',');
1968		if (pos == NULL) {
1969			wpa_printf(MSG_DEBUG, "Missing PHY Type");
1970			return -1;
1971		}
1972		pos++;
1973
1974		*nei_pos++ = atoi(pos); /* PHY Type */
1975		end = os_strchr(pos, ' ');
1976		tmp = os_strchr(pos, ',');
1977		if (tmp && (!end || tmp < end)) {
1978			/* Optional Subelements (hexdump) */
1979			size_t len;
1980
1981			pos = tmp + 1;
1982			end = os_strchr(pos, ' ');
1983			if (end)
1984				len = end - pos;
1985			else
1986				len = os_strlen(pos);
1987			if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
1988				wpa_printf(MSG_DEBUG,
1989					   "Not enough room for neighbor subelements");
1990				return -1;
1991			}
1992			if (len & 0x01 ||
1993			    hexstr2bin(pos, nei_pos, len / 2) < 0) {
1994				wpa_printf(MSG_DEBUG,
1995					   "Invalid neighbor subelement info");
1996				return -1;
1997			}
1998			nei_pos += len / 2;
1999			pos = end;
2000		}
2001
2002		nei_start[1] = nei_pos - nei_start - 2;
2003	}
2004
2005	return nei_pos - nei_rep;
2006}
2007
2008
2009int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
2010{
2011	if (!ie || ie[1] <= capab / 8)
2012		return 0;
2013	return !!(ie[2 + capab / 8] & BIT(capab % 8));
2014}
2015