xref: /freebsd/contrib/wpa/src/common/ieee802_11_common.h (revision 71e72c9e91c4b8007a4292e09669e8b549c29e97)
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 #ifndef IEEE802_11_COMMON_H
10 #define IEEE802_11_COMMON_H
11 
12 #include "defs.h"
13 #include "ieee802_11_defs.h"
14 
15 struct element {
16 	u8 id;
17 	u8 datalen;
18 	u8 data[];
19 } STRUCT_PACKED;
20 
21 struct hostapd_hw_modes;
22 
23 #define MAX_NOF_MB_IES_SUPPORTED 5
24 
25 struct mb_ies_info {
26 	struct {
27 		const u8 *ie;
28 		u8 ie_len;
29 	} ies[MAX_NOF_MB_IES_SUPPORTED];
30 	u8 nof_ies;
31 };
32 
33 struct multi_ap_params {
34 	u8 capability;
35 	u8 profile;
36 	u16 vlanid;
37 };
38 
39 /* Parsed Information Elements */
40 struct ieee802_11_elems {
41 	/* Control of parsing operations */
42 	bool show_errors;
43 	bool stop_at_mic; /* Whether to stop parsing after MIC element */
44 
45 	/* Parsed data */
46 	const u8 *ssid;
47 	const u8 *supp_rates;
48 	const u8 *ds_params;
49 	const u8 *challenge;
50 	const u8 *erp_info;
51 	const u8 *ext_supp_rates;
52 	const u8 *wpa_ie;
53 	const u8 *rsn_ie;
54 	const u8 *rsnxe;
55 	const u8 *wmm; /* WMM Information or Parameter Element */
56 	const u8 *wmm_tspec;
57 	const u8 *wps_ie;
58 	const u8 *supp_channels;
59 	const u8 *mdie;
60 	const u8 *ftie;
61 	const u8 *timeout_int;
62 	const u8 *ht_capabilities;
63 	const u8 *ht_operation;
64 	const u8 *mesh_config;
65 	const u8 *mesh_id;
66 	const u8 *peer_mgmt;
67 	const u8 *vht_capabilities;
68 	const u8 *vht_operation;
69 	const u8 *opmode_notif;
70 	const u8 *vendor_ht_cap;
71 	const u8 *vendor_vht;
72 	const u8 *p2p;
73 	const u8 *p2p2_ie;
74 	const u8 *pasn_encrypted_data;
75 	const u8 *wfd;
76 	const u8 *link_id;
77 	const u8 *interworking;
78 	const u8 *qos_map_set;
79 	const u8 *hs20;
80 	const u8 *ext_capab;
81 	const u8 *bss_max_idle_period;
82 	const u8 *ssid_list;
83 	const u8 *mbo;
84 	const u8 *ampe;
85 	const u8 *mic;
86 	const u8 *pref_freq_list;
87 	const u8 *supp_op_classes;
88 	const u8 *rrm_enabled;
89 	const u8 *cag_number;
90 	const u8 *ap_csn;
91 	const u8 *fils_indic;
92 	const u8 *dils;
93 	const u8 *assoc_delay_info;
94 	const u8 *fils_req_params;
95 	const u8 *fils_key_confirm;
96 	const u8 *fils_session;
97 	const u8 *fils_hlp;
98 	const u8 *fils_ip_addr_assign;
99 	const u8 *key_delivery;
100 	const u8 *wrapped_data;
101 	const u8 *fils_pk;
102 	const u8 *nonce;
103 	const u8 *owe_dh;
104 	const u8 *power_capab;
105 	const u8 *roaming_cons_sel;
106 	const u8 *password_id;
107 	const u8 *oci;
108 	const u8 *multi_ap;
109 	const u8 *he_capabilities;
110 	const u8 *he_operation;
111 	const u8 *short_ssid_list;
112 	const u8 *he_6ghz_band_cap;
113 	const u8 *sae_pk;
114 	const u8 *s1g_capab;
115 	const u8 *pasn_params;
116 	const u8 *eht_capabilities;
117 	const u8 *eht_operation;
118 	const u8 *basic_mle;
119 	const u8 *probe_req_mle;
120 	const u8 *reconf_mle;
121 	const u8 *tdls_mle;
122 	const u8 *prior_access_mle;
123 	const u8 *mbssid_known_bss;
124 	const u8 *mbssid;
125 	const u8 *rsne_override;
126 	const u8 *rsne_override_2;
127 	const u8 *rsnxe_override;
128 	const u8 *rsn_selection;
129 	const u8 *wfa_capab;
130 	const u8 *proximity_ranging;
131 	const u8 *akm_suite_selector;
132 	const u8 *supported_groups;
133 	const u8 *nan_ie;
134 
135 	u8 ssid_len;
136 	u8 supp_rates_len;
137 	u8 challenge_len;
138 	u8 ext_supp_rates_len;
139 	u8 wpa_ie_len;
140 	u8 rsn_ie_len;
141 	u8 rsnxe_len;
142 	u8 wmm_len; /* 7 = WMM Information; 24 = WMM Parameter */
143 	u8 wmm_tspec_len;
144 	u8 wps_ie_len;
145 	u8 supp_channels_len;
146 	u8 mdie_len;
147 	u8 ftie_len;
148 	u8 mesh_config_len;
149 	u8 mesh_id_len;
150 	u8 peer_mgmt_len;
151 	u8 vendor_ht_cap_len;
152 	u8 vendor_vht_len;
153 	u8 p2p_len;
154 	u8 p2p2_ie_len;
155 	u8 pasn_encrypted_data_len;
156 	u8 wfd_len;
157 	u8 interworking_len;
158 	u8 qos_map_set_len;
159 	u8 hs20_len;
160 	u8 ext_capab_len;
161 	u8 ssid_list_len;
162 	u8 mbo_len;
163 	u8 ampe_len;
164 	u8 mic_len;
165 	u8 pref_freq_list_len;
166 	u8 supp_op_classes_len;
167 	u8 rrm_enabled_len;
168 	u8 cag_number_len;
169 	u8 fils_indic_len;
170 	u8 dils_len;
171 	u8 fils_req_params_len;
172 	u8 fils_key_confirm_len;
173 	size_t fils_hlp_len;
174 	u8 fils_ip_addr_assign_len;
175 	size_t key_delivery_len;
176 	size_t wrapped_data_len;
177 	u8 fils_pk_len;
178 	u8 nonce_len;
179 	u8 owe_dh_len;
180 	u8 power_capab_len;
181 	u8 roaming_cons_sel_len;
182 	u8 password_id_len;
183 	u8 oci_len;
184 	u8 multi_ap_len;
185 	u8 he_capabilities_len;
186 	u8 he_operation_len;
187 	u8 short_ssid_list_len;
188 	u8 sae_pk_len;
189 	u8 pasn_params_len;
190 	u8 eht_capabilities_len;
191 	u8 eht_operation_len;
192 	size_t basic_mle_len;
193 	size_t probe_req_mle_len;
194 	size_t reconf_mle_len;
195 	size_t tdls_mle_len;
196 	size_t prior_access_mle_len;
197 	u8 mbssid_known_bss_len;
198 	u8 mbssid_len;
199 	size_t rsne_override_len;
200 	size_t rsne_override_2_len;
201 	size_t rsnxe_override_len;
202 	size_t rsn_selection_len;
203 	u8 wfa_capab_len;
204 	size_t proximity_ranging_len;
205 	u8 akm_suite_selector_len;
206 	u8 supported_groups_len;
207 	size_t nan_len;
208 
209 	struct mb_ies_info mb_ies;
210 
211 	size_t fte_defrag_len;
212 
213 	/*
214 	 * The number of fragment elements to be skipped after a known
215 	 * fragmented element.
216 	 */
217 	unsigned int num_frag_elems;
218 };
219 
220 typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
221 
222 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
223 				struct ieee802_11_elems *elems,
224 				int show_errors);
225 ParseRes ieee802_11_parse_elems_ctrl(const u8 *start, size_t len,
226 				     struct ieee802_11_elems *elems);
227 void ieee802_11_elems_clear_ids(struct ieee802_11_elems *elems,
228 				const u8 *ids, size_t num);
229 void ieee802_11_elems_clear_ext_ids(struct ieee802_11_elems *elems,
230 				    const u8 *ids, size_t num);
231 ParseRes ieee802_11_parse_link_assoc_req(struct ieee802_11_elems *elems,
232 					 struct wpabuf *mlbuf,
233 					 u8 link_id, bool show_errors);
234 ParseRes ieee802_11_parse_link_assoc_resp(struct ieee802_11_elems *elems,
235 					  struct wpabuf *mlbuf,
236 					  u8 link_id, bool show_errors);
237 int ieee802_11_ie_count(const u8 *ies, size_t ies_len);
238 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
239 					    u32 oui_type);
240 struct ieee80211_hdr;
241 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len);
242 
243 struct hostapd_wmm_ac_params {
244 	int cwmin;
245 	int cwmax;
246 	int aifs;
247 	int txop_limit; /* in units of 32us */
248 	int admission_control_mandatory;
249 };
250 
251 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
252 			  const char *name, const char *val);
253 
254 struct hostapd_tx_queue_params {
255 	int aifs;
256 	int cwmin;
257 	int cwmax;
258 	int burst; /* maximum burst time in 0.1 ms, i.e., 10 = 1 ms */
259 };
260 
261 #define NUM_TX_QUEUES 4
262 
263 int hostapd_config_tx_queue(struct hostapd_tx_queue_params queue[],
264 			    const char *name, const char *val);
265 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel);
266 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan);
267 enum hostapd_hw_mode
268 ieee80211_freq_to_channel_ext(unsigned int freq, int sec_channel,
269 			      enum oper_chan_width chanwidth,
270 			      u8 *op_class, u8 *channel);
271 int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
272 				  int sec_channel, u8 *op_class, u8 *channel);
273 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
274 		     u16 num_modes);
275 int is_dfs_global_op_class(u8 op_class);
276 bool is_80plus_op_class(u8 op_class);
277 enum phy_type ieee80211_get_phy_type(int freq, bool ht, bool vht, bool he);
278 
279 int supp_rates_11b_only(struct ieee802_11_elems *elems);
280 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
281 		       size_t ies_len);
282 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info);
283 
284 const char * fc2str(u16 fc);
285 const char * reason2str(u16 reason);
286 const char * status2str(u16 status);
287 
288 struct oper_class_map {
289 	enum hostapd_hw_mode mode;
290 	u8 op_class;
291 	u8 min_chan;
292 	u8 max_chan;
293 	u8 inc;
294 	enum { BW20, BW40PLUS, BW40MINUS, BW40, BW80, BW2160, BW160, BW80P80,
295 	       BW320, BW4320, BW6480, BW8640} bw;
296 	enum { P2P_SUPP, NO_P2P_SUPP } p2p;
297 };
298 
299 extern const struct oper_class_map global_op_class[];
300 extern size_t global_op_class_size;
301 
302 const u8 * get_ie(const u8 *ies, size_t len, u8 eid);
303 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext);
304 const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type);
305 
306 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
307 
308 u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len,
309 		      struct multi_ap_params *multi_ap);
310 size_t add_multi_ap_ie(u8 *buf, size_t len,
311 		       const struct multi_ap_params *multi_ap);
312 
313 struct country_op_class {
314 	u8 country_op_class;
315 	u8 global_op_class;
316 };
317 
318 u8 country_to_global_op_class(const char *country, u8 op_class);
319 
320 const struct oper_class_map * get_oper_class(const char *country, u8 op_class);
321 int oper_class_bw_to_int(const struct oper_class_map *map);
322 bool is_24ghz_freq(int freq);
323 bool is_5ghz_freq(int freq);
324 int center_idx_to_bw_6ghz(u8 idx);
325 bool is_6ghz_freq(int freq);
326 bool is_6ghz_op_class(u8 op_class);
327 bool is_6ghz_psc_frequency(int freq);
328 int get_6ghz_sec_channel(int channel);
329 
330 bool is_same_band(int freq1, int freq2);
331 #define IS_2P4GHZ(n) (n >= 2412 && n <= 2484)
332 #define IS_5GHZ(n) (n > 4000 && n < 5895)
333 
334 u8 op_class_idx_to_chan(const struct oper_class_map *op, u8 idx);
335 int op_class_chan_to_idx(const struct oper_class_map *op, u8 chan);
336 int ieee80211_get_center_freq(int ctrl_freq, u32 bw);
337 
338 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
339 				    size_t nei_rep_len);
340 
341 int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
342 bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
343 			       unsigned int capab);
344 bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab);
345 int op_class_to_bandwidth(u8 op_class);
346 enum oper_chan_width op_class_to_ch_width(u8 op_class);
347 int chwidth_freq2_to_ch_width(int chwidth, int freq2);
348 enum oper_chan_width chan_width_to_oper_chwidth(enum chan_width chan_width);
349 
350 /* element iteration helpers */
351 #define for_each_element(_elem, _data, _datalen)			\
352 	for (_elem = (const struct element *) (_data);			\
353 	     (const u8 *) (_data) + (_datalen) - (const u8 *) _elem >=	\
354 		(int) sizeof(*_elem) &&					\
355 	     (const u8 *) (_data) + (_datalen) - (const u8 *) _elem >=	\
356 		(int) sizeof(*_elem) + _elem->datalen;			\
357 	     _elem = (const struct element *) (_elem->data + _elem->datalen))
358 
359 #define for_each_element_id(element, _id, data, datalen)		\
360 	for_each_element(element, data, datalen)			\
361 		if (element->id == (_id))
362 
363 #define for_each_element_extid(element, extid, _data, _datalen)		\
364 	for_each_element(element, _data, _datalen)			\
365 		if (element->id == WLAN_EID_EXTENSION &&		\
366 		    element->datalen > 0 &&				\
367 		    element->data[0] == (extid))
368 
369 #define for_each_subelement(sub, element)				\
370 	for_each_element(sub, (element)->data, (element)->datalen)
371 
372 #define for_each_subelement_id(sub, id, element)			\
373 	for_each_element_id(sub, id, (element)->data, (element)->datalen)
374 
375 #define for_each_subelement_extid(sub, extid, element)			\
376 	for_each_element_extid(sub, extid, (element)->data, (element)->datalen)
377 
378 /**
379  * for_each_element_completed - Determine if element parsing consumed all data
380  * @element: Element pointer after for_each_element() or friends
381  * @data: Same data pointer as passed to for_each_element() or friends
382  * @datalen: Same data length as passed to for_each_element() or friends
383  *
384  * This function returns 1 if all the data was parsed or considered
385  * while walking the elements. Only use this if your for_each_element()
386  * loop cannot be broken out of, otherwise it always returns 0.
387  *
388  * If some data was malformed, this returns %false since the last parsed
389  * element will not fill the whole remaining data.
390  */
for_each_element_completed(const struct element * element,const void * data,size_t datalen)391 static inline int for_each_element_completed(const struct element *element,
392 					     const void *data, size_t datalen)
393 {
394 	return (const u8 *) element == (const u8 *) data + datalen;
395 }
396 
397 struct ieee80211_edmg_config;
398 
399 void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
400 			      int primary_channel,
401 			      struct ieee80211_edmg_config *edmg);
402 
403 int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,
404 			    struct ieee80211_edmg_config requested);
405 
406 struct wpabuf * ieee802_11_defrag(const u8 *data, size_t len, bool ext_elem);
407 ssize_t ieee802_11_defrag_mle_subelem(struct wpabuf *mlbuf,
408 				      const u8 *parent_subelem,
409 				      size_t *defrag_len);
410 const u8 * get_ml_ie(const u8 *ies, size_t len, u8 type);
411 const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len);
412 const u8 * get_basic_mle_eml_capa(const u8 *buf, size_t len);
413 int get_basic_mle_link_id(const u8 *buf, size_t len);
414 
415 unsigned int get_max_nss_capability(struct ieee802_11_elems *elems,
416 				    bool parse_for_rx, enum chan_width bw);
417 
418 struct supported_chan_width {
419 	bool is_40_supported;
420 	bool is_160_supported;
421 	bool is_80p80_supported;
422 	bool is_320_supported;
423 };
424 
425 struct supported_chan_width
426 get_supported_channel_width(struct ieee802_11_elems *elems, int freq);
427 
428 enum chan_width get_operation_channel_width(struct ieee802_11_elems *elems);
429 
430 enum chan_width get_sta_operation_chan_width(
431 	enum chan_width ap_operation_chan_width,
432 	struct supported_chan_width sta_supported_width);
433 
434 #endif /* IEEE802_11_COMMON_H */
435