xref: /dflybsd-src/contrib/wpa_supplicant/src/common/ieee802_11_common.h (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
16d49e1aeSJan Lentfer /*
26d49e1aeSJan Lentfer  * IEEE 802.11 Common routines
3*a1157835SDaniel Fojt  * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
46d49e1aeSJan Lentfer  *
53ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino  * See README for more details.
76d49e1aeSJan Lentfer  */
86d49e1aeSJan Lentfer 
96d49e1aeSJan Lentfer #ifndef IEEE802_11_COMMON_H
106d49e1aeSJan Lentfer #define IEEE802_11_COMMON_H
116d49e1aeSJan Lentfer 
12*a1157835SDaniel Fojt #include "defs.h"
13*a1157835SDaniel Fojt #include "ieee802_11_defs.h"
14*a1157835SDaniel Fojt 
15*a1157835SDaniel Fojt struct element {
16*a1157835SDaniel Fojt 	u8 id;
17*a1157835SDaniel Fojt 	u8 datalen;
18*a1157835SDaniel Fojt 	u8 data[];
19*a1157835SDaniel Fojt } STRUCT_PACKED;
20*a1157835SDaniel Fojt 
21*a1157835SDaniel Fojt struct hostapd_hw_modes;
22*a1157835SDaniel Fojt 
23*a1157835SDaniel Fojt #define MAX_NOF_MB_IES_SUPPORTED 5
24*a1157835SDaniel Fojt 
25*a1157835SDaniel Fojt struct mb_ies_info {
26*a1157835SDaniel Fojt 	struct {
27*a1157835SDaniel Fojt 		const u8 *ie;
28*a1157835SDaniel Fojt 		u8 ie_len;
29*a1157835SDaniel Fojt 	} ies[MAX_NOF_MB_IES_SUPPORTED];
30*a1157835SDaniel Fojt 	u8 nof_ies;
31*a1157835SDaniel Fojt };
32*a1157835SDaniel Fojt 
336d49e1aeSJan Lentfer /* Parsed Information Elements */
346d49e1aeSJan Lentfer struct ieee802_11_elems {
353ff40c12SJohn Marino 	const u8 *ssid;
363ff40c12SJohn Marino 	const u8 *supp_rates;
373ff40c12SJohn Marino 	const u8 *ds_params;
383ff40c12SJohn Marino 	const u8 *challenge;
393ff40c12SJohn Marino 	const u8 *erp_info;
403ff40c12SJohn Marino 	const u8 *ext_supp_rates;
413ff40c12SJohn Marino 	const u8 *wpa_ie;
423ff40c12SJohn Marino 	const u8 *rsn_ie;
433ff40c12SJohn Marino 	const u8 *wmm; /* WMM Information or Parameter Element */
443ff40c12SJohn Marino 	const u8 *wmm_tspec;
453ff40c12SJohn Marino 	const u8 *wps_ie;
463ff40c12SJohn Marino 	const u8 *supp_channels;
473ff40c12SJohn Marino 	const u8 *mdie;
483ff40c12SJohn Marino 	const u8 *ftie;
493ff40c12SJohn Marino 	const u8 *timeout_int;
503ff40c12SJohn Marino 	const u8 *ht_capabilities;
513ff40c12SJohn Marino 	const u8 *ht_operation;
52*a1157835SDaniel Fojt 	const u8 *mesh_config;
53*a1157835SDaniel Fojt 	const u8 *mesh_id;
54*a1157835SDaniel Fojt 	const u8 *peer_mgmt;
553ff40c12SJohn Marino 	const u8 *vht_capabilities;
563ff40c12SJohn Marino 	const u8 *vht_operation;
57*a1157835SDaniel Fojt 	const u8 *vht_opmode_notif;
583ff40c12SJohn Marino 	const u8 *vendor_ht_cap;
59*a1157835SDaniel Fojt 	const u8 *vendor_vht;
603ff40c12SJohn Marino 	const u8 *p2p;
613ff40c12SJohn Marino 	const u8 *wfd;
623ff40c12SJohn Marino 	const u8 *link_id;
633ff40c12SJohn Marino 	const u8 *interworking;
643ff40c12SJohn Marino 	const u8 *qos_map_set;
653ff40c12SJohn Marino 	const u8 *hs20;
663ff40c12SJohn Marino 	const u8 *ext_capab;
673ff40c12SJohn Marino 	const u8 *bss_max_idle_period;
683ff40c12SJohn Marino 	const u8 *ssid_list;
69*a1157835SDaniel Fojt 	const u8 *osen;
70*a1157835SDaniel Fojt 	const u8 *mbo;
71*a1157835SDaniel Fojt 	const u8 *ampe;
72*a1157835SDaniel Fojt 	const u8 *mic;
73*a1157835SDaniel Fojt 	const u8 *pref_freq_list;
74*a1157835SDaniel Fojt 	const u8 *supp_op_classes;
75*a1157835SDaniel Fojt 	const u8 *rrm_enabled;
76*a1157835SDaniel Fojt 	const u8 *cag_number;
77*a1157835SDaniel Fojt 	const u8 *ap_csn;
78*a1157835SDaniel Fojt 	const u8 *fils_indic;
79*a1157835SDaniel Fojt 	const u8 *dils;
80*a1157835SDaniel Fojt 	const u8 *assoc_delay_info;
81*a1157835SDaniel Fojt 	const u8 *fils_req_params;
82*a1157835SDaniel Fojt 	const u8 *fils_key_confirm;
83*a1157835SDaniel Fojt 	const u8 *fils_session;
84*a1157835SDaniel Fojt 	const u8 *fils_hlp;
85*a1157835SDaniel Fojt 	const u8 *fils_ip_addr_assign;
86*a1157835SDaniel Fojt 	const u8 *key_delivery;
87*a1157835SDaniel Fojt 	const u8 *fils_wrapped_data;
88*a1157835SDaniel Fojt 	const u8 *fils_pk;
89*a1157835SDaniel Fojt 	const u8 *fils_nonce;
90*a1157835SDaniel Fojt 	const u8 *owe_dh;
91*a1157835SDaniel Fojt 	const u8 *power_capab;
92*a1157835SDaniel Fojt 	const u8 *roaming_cons_sel;
93*a1157835SDaniel Fojt 	const u8 *password_id;
94*a1157835SDaniel Fojt 	const u8 *oci;
95*a1157835SDaniel Fojt 	const u8 *multi_ap;
96*a1157835SDaniel Fojt 	const u8 *he_capabilities;
97*a1157835SDaniel Fojt 	const u8 *he_operation;
983ff40c12SJohn Marino 
996d49e1aeSJan Lentfer 	u8 ssid_len;
1006d49e1aeSJan Lentfer 	u8 supp_rates_len;
1016d49e1aeSJan Lentfer 	u8 challenge_len;
1026d49e1aeSJan Lentfer 	u8 ext_supp_rates_len;
1036d49e1aeSJan Lentfer 	u8 wpa_ie_len;
1046d49e1aeSJan Lentfer 	u8 rsn_ie_len;
1056d49e1aeSJan Lentfer 	u8 wmm_len; /* 7 = WMM Information; 24 = WMM Parameter */
1066d49e1aeSJan Lentfer 	u8 wmm_tspec_len;
1076d49e1aeSJan Lentfer 	u8 wps_ie_len;
1086d49e1aeSJan Lentfer 	u8 supp_channels_len;
1096d49e1aeSJan Lentfer 	u8 mdie_len;
1106d49e1aeSJan Lentfer 	u8 ftie_len;
111*a1157835SDaniel Fojt 	u8 mesh_config_len;
112*a1157835SDaniel Fojt 	u8 mesh_id_len;
113*a1157835SDaniel Fojt 	u8 peer_mgmt_len;
1146d49e1aeSJan Lentfer 	u8 vendor_ht_cap_len;
115*a1157835SDaniel Fojt 	u8 vendor_vht_len;
1163ff40c12SJohn Marino 	u8 p2p_len;
1173ff40c12SJohn Marino 	u8 wfd_len;
1183ff40c12SJohn Marino 	u8 interworking_len;
1193ff40c12SJohn Marino 	u8 qos_map_set_len;
1203ff40c12SJohn Marino 	u8 hs20_len;
1213ff40c12SJohn Marino 	u8 ext_capab_len;
1223ff40c12SJohn Marino 	u8 ssid_list_len;
123*a1157835SDaniel Fojt 	u8 osen_len;
124*a1157835SDaniel Fojt 	u8 mbo_len;
125*a1157835SDaniel Fojt 	u8 ampe_len;
126*a1157835SDaniel Fojt 	u8 mic_len;
127*a1157835SDaniel Fojt 	u8 pref_freq_list_len;
128*a1157835SDaniel Fojt 	u8 supp_op_classes_len;
129*a1157835SDaniel Fojt 	u8 rrm_enabled_len;
130*a1157835SDaniel Fojt 	u8 cag_number_len;
131*a1157835SDaniel Fojt 	u8 fils_indic_len;
132*a1157835SDaniel Fojt 	u8 dils_len;
133*a1157835SDaniel Fojt 	u8 fils_req_params_len;
134*a1157835SDaniel Fojt 	u8 fils_key_confirm_len;
135*a1157835SDaniel Fojt 	u8 fils_hlp_len;
136*a1157835SDaniel Fojt 	u8 fils_ip_addr_assign_len;
137*a1157835SDaniel Fojt 	u8 key_delivery_len;
138*a1157835SDaniel Fojt 	u8 fils_wrapped_data_len;
139*a1157835SDaniel Fojt 	u8 fils_pk_len;
140*a1157835SDaniel Fojt 	u8 owe_dh_len;
141*a1157835SDaniel Fojt 	u8 power_capab_len;
142*a1157835SDaniel Fojt 	u8 roaming_cons_sel_len;
143*a1157835SDaniel Fojt 	u8 password_id_len;
144*a1157835SDaniel Fojt 	u8 oci_len;
145*a1157835SDaniel Fojt 	u8 multi_ap_len;
146*a1157835SDaniel Fojt 	u8 he_capabilities_len;
147*a1157835SDaniel Fojt 	u8 he_operation_len;
148*a1157835SDaniel Fojt 
149*a1157835SDaniel Fojt 	struct mb_ies_info mb_ies;
1506d49e1aeSJan Lentfer };
1516d49e1aeSJan Lentfer 
1526d49e1aeSJan Lentfer typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
1536d49e1aeSJan Lentfer 
1543ff40c12SJohn Marino ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
1556d49e1aeSJan Lentfer 				struct ieee802_11_elems *elems,
1566d49e1aeSJan Lentfer 				int show_errors);
1573ff40c12SJohn Marino int ieee802_11_ie_count(const u8 *ies, size_t ies_len);
1583ff40c12SJohn Marino struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
1593ff40c12SJohn Marino 					    u32 oui_type);
1603ff40c12SJohn Marino struct ieee80211_hdr;
1613ff40c12SJohn Marino const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len);
1623ff40c12SJohn Marino 
1633ff40c12SJohn Marino struct hostapd_wmm_ac_params {
1643ff40c12SJohn Marino 	int cwmin;
1653ff40c12SJohn Marino 	int cwmax;
1663ff40c12SJohn Marino 	int aifs;
1673ff40c12SJohn Marino 	int txop_limit; /* in units of 32us */
1683ff40c12SJohn Marino 	int admission_control_mandatory;
1693ff40c12SJohn Marino };
1703ff40c12SJohn Marino 
1713ff40c12SJohn Marino int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
1723ff40c12SJohn Marino 			  const char *name, const char *val);
1733ff40c12SJohn Marino enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel);
174*a1157835SDaniel Fojt int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan);
175*a1157835SDaniel Fojt enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
176*a1157835SDaniel Fojt 						   int sec_channel, int vht,
177*a1157835SDaniel Fojt 						   u8 *op_class, u8 *channel);
178*a1157835SDaniel Fojt int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
179*a1157835SDaniel Fojt 				  int sec_channel, u8 *op_class, u8 *channel);
180*a1157835SDaniel Fojt int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
181*a1157835SDaniel Fojt 		     u16 num_modes);
182*a1157835SDaniel Fojt enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht);
1833ff40c12SJohn Marino 
1843ff40c12SJohn Marino int supp_rates_11b_only(struct ieee802_11_elems *elems);
185*a1157835SDaniel Fojt int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
186*a1157835SDaniel Fojt 		       size_t ies_len);
187*a1157835SDaniel Fojt struct wpabuf * mb_ies_by_info(struct mb_ies_info *info);
188*a1157835SDaniel Fojt 
189*a1157835SDaniel Fojt const char * fc2str(u16 fc);
190*a1157835SDaniel Fojt const char * reason2str(u16 reason);
191*a1157835SDaniel Fojt const char * status2str(u16 status);
192*a1157835SDaniel Fojt 
193*a1157835SDaniel Fojt struct oper_class_map {
194*a1157835SDaniel Fojt 	enum hostapd_hw_mode mode;
195*a1157835SDaniel Fojt 	u8 op_class;
196*a1157835SDaniel Fojt 	u8 min_chan;
197*a1157835SDaniel Fojt 	u8 max_chan;
198*a1157835SDaniel Fojt 	u8 inc;
199*a1157835SDaniel Fojt 	enum { BW20, BW40PLUS, BW40MINUS, BW80, BW2160, BW160, BW80P80 } bw;
200*a1157835SDaniel Fojt 	enum { P2P_SUPP, NO_P2P_SUPP } p2p;
201*a1157835SDaniel Fojt };
202*a1157835SDaniel Fojt 
203*a1157835SDaniel Fojt extern const struct oper_class_map global_op_class[];
204*a1157835SDaniel Fojt extern size_t global_op_class_size;
205*a1157835SDaniel Fojt 
206*a1157835SDaniel Fojt const u8 * get_ie(const u8 *ies, size_t len, u8 eid);
207*a1157835SDaniel Fojt const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext);
208*a1157835SDaniel Fojt const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type);
209*a1157835SDaniel Fojt 
210*a1157835SDaniel Fojt size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
211*a1157835SDaniel Fojt 
212*a1157835SDaniel Fojt size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value);
213*a1157835SDaniel Fojt 
214*a1157835SDaniel Fojt struct country_op_class {
215*a1157835SDaniel Fojt 	u8 country_op_class;
216*a1157835SDaniel Fojt 	u8 global_op_class;
217*a1157835SDaniel Fojt };
218*a1157835SDaniel Fojt 
219*a1157835SDaniel Fojt u8 country_to_global_op_class(const char *country, u8 op_class);
220*a1157835SDaniel Fojt 
221*a1157835SDaniel Fojt const struct oper_class_map * get_oper_class(const char *country, u8 op_class);
222*a1157835SDaniel Fojt int oper_class_bw_to_int(const struct oper_class_map *map);
223*a1157835SDaniel Fojt 
224*a1157835SDaniel Fojt int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
225*a1157835SDaniel Fojt 				    size_t nei_rep_len);
226*a1157835SDaniel Fojt 
227*a1157835SDaniel Fojt int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
228*a1157835SDaniel Fojt 
229*a1157835SDaniel Fojt /* element iteration helpers */
230*a1157835SDaniel Fojt #define for_each_element(_elem, _data, _datalen)			\
231*a1157835SDaniel Fojt 	for (_elem = (const struct element *) (_data);			\
232*a1157835SDaniel Fojt 	     (const u8 *) (_data) + (_datalen) - (const u8 *) _elem >=	\
233*a1157835SDaniel Fojt 		(int) sizeof(*_elem) &&					\
234*a1157835SDaniel Fojt 	     (const u8 *) (_data) + (_datalen) - (const u8 *) _elem >=	\
235*a1157835SDaniel Fojt 		(int) sizeof(*_elem) + _elem->datalen;			\
236*a1157835SDaniel Fojt 	     _elem = (const struct element *) (_elem->data + _elem->datalen))
237*a1157835SDaniel Fojt 
238*a1157835SDaniel Fojt #define for_each_element_id(element, _id, data, datalen)		\
239*a1157835SDaniel Fojt 	for_each_element(element, data, datalen)			\
240*a1157835SDaniel Fojt 		if (element->id == (_id))
241*a1157835SDaniel Fojt 
242*a1157835SDaniel Fojt #define for_each_element_extid(element, extid, _data, _datalen)		\
243*a1157835SDaniel Fojt 	for_each_element(element, _data, _datalen)			\
244*a1157835SDaniel Fojt 		if (element->id == WLAN_EID_EXTENSION &&		\
245*a1157835SDaniel Fojt 		    element->datalen > 0 &&				\
246*a1157835SDaniel Fojt 		    element->data[0] == (extid))
247*a1157835SDaniel Fojt 
248*a1157835SDaniel Fojt #define for_each_subelement(sub, element)				\
249*a1157835SDaniel Fojt 	for_each_element(sub, (element)->data, (element)->datalen)
250*a1157835SDaniel Fojt 
251*a1157835SDaniel Fojt #define for_each_subelement_id(sub, id, element)			\
252*a1157835SDaniel Fojt 	for_each_element_id(sub, id, (element)->data, (element)->datalen)
253*a1157835SDaniel Fojt 
254*a1157835SDaniel Fojt #define for_each_subelement_extid(sub, extid, element)			\
255*a1157835SDaniel Fojt 	for_each_element_extid(sub, extid, (element)->data, (element)->datalen)
256*a1157835SDaniel Fojt 
257*a1157835SDaniel Fojt /**
258*a1157835SDaniel Fojt  * for_each_element_completed - Determine if element parsing consumed all data
259*a1157835SDaniel Fojt  * @element: Element pointer after for_each_element() or friends
260*a1157835SDaniel Fojt  * @data: Same data pointer as passed to for_each_element() or friends
261*a1157835SDaniel Fojt  * @datalen: Same data length as passed to for_each_element() or friends
262*a1157835SDaniel Fojt  *
263*a1157835SDaniel Fojt  * This function returns 1 if all the data was parsed or considered
264*a1157835SDaniel Fojt  * while walking the elements. Only use this if your for_each_element()
265*a1157835SDaniel Fojt  * loop cannot be broken out of, otherwise it always returns 0.
266*a1157835SDaniel Fojt  *
267*a1157835SDaniel Fojt  * If some data was malformed, this returns %false since the last parsed
268*a1157835SDaniel Fojt  * element will not fill the whole remaining data.
269*a1157835SDaniel Fojt  */
for_each_element_completed(const struct element * element,const void * data,size_t datalen)270*a1157835SDaniel Fojt static inline int for_each_element_completed(const struct element *element,
271*a1157835SDaniel Fojt 					     const void *data, size_t datalen)
272*a1157835SDaniel Fojt {
273*a1157835SDaniel Fojt 	return (const u8 *) element == (const u8 *) data + datalen;
274*a1157835SDaniel Fojt }
2756d49e1aeSJan Lentfer 
2766d49e1aeSJan Lentfer #endif /* IEEE802_11_COMMON_H */
277