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