xref: /freebsd/contrib/wpa/src/common/ieee802_11_common.h (revision a90b9d0159070121c221b966469c3e36d912bf82)
139beb93cSSam Leffler /*
239beb93cSSam Leffler  * IEEE 802.11 Common routines
34bc52338SCy Schubert  * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
439beb93cSSam Leffler  *
5f05cddf9SRui Paulo  * This software may be distributed under the terms of the BSD license.
6f05cddf9SRui Paulo  * See README for more details.
739beb93cSSam Leffler  */
839beb93cSSam Leffler 
939beb93cSSam Leffler #ifndef IEEE802_11_COMMON_H
1039beb93cSSam Leffler #define IEEE802_11_COMMON_H
1139beb93cSSam Leffler 
12780fb4a2SCy Schubert #include "defs.h"
134bc52338SCy Schubert #include "ieee802_11_defs.h"
144bc52338SCy Schubert 
154bc52338SCy Schubert struct element {
164bc52338SCy Schubert 	u8 id;
174bc52338SCy Schubert 	u8 datalen;
184bc52338SCy Schubert 	u8 data[];
194bc52338SCy Schubert } STRUCT_PACKED;
20780fb4a2SCy Schubert 
2185732ac8SCy Schubert struct hostapd_hw_modes;
2285732ac8SCy Schubert 
23325151a3SRui Paulo #define MAX_NOF_MB_IES_SUPPORTED 5
24325151a3SRui Paulo 
25325151a3SRui Paulo struct mb_ies_info {
26325151a3SRui Paulo 	struct {
27325151a3SRui Paulo 		const u8 *ie;
28325151a3SRui Paulo 		u8 ie_len;
29325151a3SRui Paulo 	} ies[MAX_NOF_MB_IES_SUPPORTED];
30325151a3SRui Paulo 	u8 nof_ies;
31325151a3SRui Paulo };
32325151a3SRui Paulo 
33*a90b9d01SCy Schubert struct multi_ap_params {
34*a90b9d01SCy Schubert 	u8 capability;
35*a90b9d01SCy Schubert 	u8 profile;
36*a90b9d01SCy Schubert 	u16 vlanid;
37c1d255d3SCy Schubert };
38c1d255d3SCy Schubert 
3939beb93cSSam Leffler /* Parsed Information Elements */
4039beb93cSSam Leffler struct ieee802_11_elems {
41e28a4053SRui Paulo 	const u8 *ssid;
42e28a4053SRui Paulo 	const u8 *supp_rates;
43e28a4053SRui Paulo 	const u8 *ds_params;
44e28a4053SRui Paulo 	const u8 *challenge;
45e28a4053SRui Paulo 	const u8 *erp_info;
46e28a4053SRui Paulo 	const u8 *ext_supp_rates;
47e28a4053SRui Paulo 	const u8 *wpa_ie;
48e28a4053SRui Paulo 	const u8 *rsn_ie;
49c1d255d3SCy Schubert 	const u8 *rsnxe;
50e28a4053SRui Paulo 	const u8 *wmm; /* WMM Information or Parameter Element */
51e28a4053SRui Paulo 	const u8 *wmm_tspec;
52e28a4053SRui Paulo 	const u8 *wps_ie;
53e28a4053SRui Paulo 	const u8 *supp_channels;
54e28a4053SRui Paulo 	const u8 *mdie;
55e28a4053SRui Paulo 	const u8 *ftie;
56e28a4053SRui Paulo 	const u8 *timeout_int;
57e28a4053SRui Paulo 	const u8 *ht_capabilities;
58e28a4053SRui Paulo 	const u8 *ht_operation;
595b9c547cSRui Paulo 	const u8 *mesh_config;
605b9c547cSRui Paulo 	const u8 *mesh_id;
615b9c547cSRui Paulo 	const u8 *peer_mgmt;
62f05cddf9SRui Paulo 	const u8 *vht_capabilities;
63f05cddf9SRui Paulo 	const u8 *vht_operation;
64*a90b9d01SCy Schubert 	const u8 *opmode_notif;
65e28a4053SRui Paulo 	const u8 *vendor_ht_cap;
665b9c547cSRui Paulo 	const u8 *vendor_vht;
67f05cddf9SRui Paulo 	const u8 *p2p;
68f05cddf9SRui Paulo 	const u8 *wfd;
69f05cddf9SRui Paulo 	const u8 *link_id;
70f05cddf9SRui Paulo 	const u8 *interworking;
715b9c547cSRui Paulo 	const u8 *qos_map_set;
72f05cddf9SRui Paulo 	const u8 *hs20;
73f05cddf9SRui Paulo 	const u8 *ext_capab;
74f05cddf9SRui Paulo 	const u8 *bss_max_idle_period;
75f05cddf9SRui Paulo 	const u8 *ssid_list;
765b9c547cSRui Paulo 	const u8 *osen;
77780fb4a2SCy Schubert 	const u8 *mbo;
785b9c547cSRui Paulo 	const u8 *ampe;
795b9c547cSRui Paulo 	const u8 *mic;
80325151a3SRui Paulo 	const u8 *pref_freq_list;
81780fb4a2SCy Schubert 	const u8 *supp_op_classes;
82780fb4a2SCy Schubert 	const u8 *rrm_enabled;
8385732ac8SCy Schubert 	const u8 *cag_number;
8485732ac8SCy Schubert 	const u8 *ap_csn;
8585732ac8SCy Schubert 	const u8 *fils_indic;
8685732ac8SCy Schubert 	const u8 *dils;
8785732ac8SCy Schubert 	const u8 *assoc_delay_info;
8885732ac8SCy Schubert 	const u8 *fils_req_params;
8985732ac8SCy Schubert 	const u8 *fils_key_confirm;
9085732ac8SCy Schubert 	const u8 *fils_session;
9185732ac8SCy Schubert 	const u8 *fils_hlp;
9285732ac8SCy Schubert 	const u8 *fils_ip_addr_assign;
9385732ac8SCy Schubert 	const u8 *key_delivery;
94c1d255d3SCy Schubert 	const u8 *wrapped_data;
9585732ac8SCy Schubert 	const u8 *fils_pk;
9685732ac8SCy Schubert 	const u8 *fils_nonce;
9785732ac8SCy Schubert 	const u8 *owe_dh;
9885732ac8SCy Schubert 	const u8 *power_capab;
9985732ac8SCy Schubert 	const u8 *roaming_cons_sel;
10085732ac8SCy Schubert 	const u8 *password_id;
1014bc52338SCy Schubert 	const u8 *oci;
1024bc52338SCy Schubert 	const u8 *multi_ap;
1034bc52338SCy Schubert 	const u8 *he_capabilities;
104206b73d0SCy Schubert 	const u8 *he_operation;
105c1d255d3SCy Schubert 	const u8 *short_ssid_list;
106c1d255d3SCy Schubert 	const u8 *he_6ghz_band_cap;
107c1d255d3SCy Schubert 	const u8 *sae_pk;
108c1d255d3SCy Schubert 	const u8 *s1g_capab;
109c1d255d3SCy Schubert 	const u8 *pasn_params;
110*a90b9d01SCy Schubert 	const u8 *eht_capabilities;
111*a90b9d01SCy Schubert 	const u8 *eht_operation;
112*a90b9d01SCy Schubert 	const u8 *basic_mle;
113*a90b9d01SCy Schubert 	const u8 *probe_req_mle;
114*a90b9d01SCy Schubert 	const u8 *reconf_mle;
115*a90b9d01SCy Schubert 	const u8 *tdls_mle;
116*a90b9d01SCy Schubert 	const u8 *prior_access_mle;
117*a90b9d01SCy Schubert 	const u8 *mbssid_known_bss;
118*a90b9d01SCy Schubert 	const u8 *mbssid;
119e28a4053SRui Paulo 
12039beb93cSSam Leffler 	u8 ssid_len;
12139beb93cSSam Leffler 	u8 supp_rates_len;
12239beb93cSSam Leffler 	u8 challenge_len;
12339beb93cSSam Leffler 	u8 ext_supp_rates_len;
12439beb93cSSam Leffler 	u8 wpa_ie_len;
12539beb93cSSam Leffler 	u8 rsn_ie_len;
126c1d255d3SCy Schubert 	u8 rsnxe_len;
1273157ba21SRui Paulo 	u8 wmm_len; /* 7 = WMM Information; 24 = WMM Parameter */
1283157ba21SRui Paulo 	u8 wmm_tspec_len;
12939beb93cSSam Leffler 	u8 wps_ie_len;
13039beb93cSSam Leffler 	u8 supp_channels_len;
13139beb93cSSam Leffler 	u8 mdie_len;
13239beb93cSSam Leffler 	u8 ftie_len;
1335b9c547cSRui Paulo 	u8 mesh_config_len;
1345b9c547cSRui Paulo 	u8 mesh_id_len;
1355b9c547cSRui Paulo 	u8 peer_mgmt_len;
13639beb93cSSam Leffler 	u8 vendor_ht_cap_len;
1375b9c547cSRui Paulo 	u8 vendor_vht_len;
138f05cddf9SRui Paulo 	u8 p2p_len;
139f05cddf9SRui Paulo 	u8 wfd_len;
140f05cddf9SRui Paulo 	u8 interworking_len;
1415b9c547cSRui Paulo 	u8 qos_map_set_len;
142f05cddf9SRui Paulo 	u8 hs20_len;
143f05cddf9SRui Paulo 	u8 ext_capab_len;
144f05cddf9SRui Paulo 	u8 ssid_list_len;
1455b9c547cSRui Paulo 	u8 osen_len;
146780fb4a2SCy Schubert 	u8 mbo_len;
1475b9c547cSRui Paulo 	u8 ampe_len;
1485b9c547cSRui Paulo 	u8 mic_len;
149325151a3SRui Paulo 	u8 pref_freq_list_len;
150780fb4a2SCy Schubert 	u8 supp_op_classes_len;
151780fb4a2SCy Schubert 	u8 rrm_enabled_len;
15285732ac8SCy Schubert 	u8 cag_number_len;
15385732ac8SCy Schubert 	u8 fils_indic_len;
15485732ac8SCy Schubert 	u8 dils_len;
15585732ac8SCy Schubert 	u8 fils_req_params_len;
15685732ac8SCy Schubert 	u8 fils_key_confirm_len;
157*a90b9d01SCy Schubert 	size_t fils_hlp_len;
15885732ac8SCy Schubert 	u8 fils_ip_addr_assign_len;
15985732ac8SCy Schubert 	u8 key_delivery_len;
160*a90b9d01SCy Schubert 	size_t wrapped_data_len;
16185732ac8SCy Schubert 	u8 fils_pk_len;
16285732ac8SCy Schubert 	u8 owe_dh_len;
16385732ac8SCy Schubert 	u8 power_capab_len;
16485732ac8SCy Schubert 	u8 roaming_cons_sel_len;
16585732ac8SCy Schubert 	u8 password_id_len;
1664bc52338SCy Schubert 	u8 oci_len;
1674bc52338SCy Schubert 	u8 multi_ap_len;
1684bc52338SCy Schubert 	u8 he_capabilities_len;
169206b73d0SCy Schubert 	u8 he_operation_len;
170c1d255d3SCy Schubert 	u8 short_ssid_list_len;
171c1d255d3SCy Schubert 	u8 sae_pk_len;
172c1d255d3SCy Schubert 	u8 pasn_params_len;
173*a90b9d01SCy Schubert 	u8 eht_capabilities_len;
174*a90b9d01SCy Schubert 	u8 eht_operation_len;
175*a90b9d01SCy Schubert 	size_t basic_mle_len;
176*a90b9d01SCy Schubert 	size_t probe_req_mle_len;
177*a90b9d01SCy Schubert 	size_t reconf_mle_len;
178*a90b9d01SCy Schubert 	size_t tdls_mle_len;
179*a90b9d01SCy Schubert 	size_t prior_access_mle_len;
180*a90b9d01SCy Schubert 	u8 mbssid_known_bss_len;
181*a90b9d01SCy Schubert 	u8 mbssid_len;
182780fb4a2SCy Schubert 
183325151a3SRui Paulo 	struct mb_ies_info mb_ies;
184*a90b9d01SCy Schubert 
185*a90b9d01SCy Schubert 	size_t fte_defrag_len;
186*a90b9d01SCy Schubert 
187*a90b9d01SCy Schubert 	/*
188*a90b9d01SCy Schubert 	 * The number of fragment elements to be skipped after a known
189*a90b9d01SCy Schubert 	 * fragmented element.
190*a90b9d01SCy Schubert 	 */
191*a90b9d01SCy Schubert 	unsigned int num_frag_elems;
19239beb93cSSam Leffler };
19339beb93cSSam Leffler 
19439beb93cSSam Leffler typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
19539beb93cSSam Leffler 
196e28a4053SRui Paulo ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
19739beb93cSSam Leffler 				struct ieee802_11_elems *elems,
19839beb93cSSam Leffler 				int show_errors);
199*a90b9d01SCy Schubert void ieee802_11_elems_clear_ids(struct ieee802_11_elems *elems,
200*a90b9d01SCy Schubert 				const u8 *ids, size_t num);
201*a90b9d01SCy Schubert void ieee802_11_elems_clear_ext_ids(struct ieee802_11_elems *elems,
202*a90b9d01SCy Schubert 				    const u8 *ids, size_t num);
203*a90b9d01SCy Schubert ParseRes ieee802_11_parse_link_assoc_req(const u8 *start, size_t len,
204*a90b9d01SCy Schubert 					 struct ieee802_11_elems *elems,
205*a90b9d01SCy Schubert 					 struct wpabuf *mlbuf,
206*a90b9d01SCy Schubert 					 u8 link_id, bool show_errors);
207e28a4053SRui Paulo int ieee802_11_ie_count(const u8 *ies, size_t ies_len);
208e28a4053SRui Paulo struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
209e28a4053SRui Paulo 					    u32 oui_type);
210f05cddf9SRui Paulo struct ieee80211_hdr;
211f05cddf9SRui Paulo const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len);
212f05cddf9SRui Paulo 
213f05cddf9SRui Paulo struct hostapd_wmm_ac_params {
214f05cddf9SRui Paulo 	int cwmin;
215f05cddf9SRui Paulo 	int cwmax;
216f05cddf9SRui Paulo 	int aifs;
217f05cddf9SRui Paulo 	int txop_limit; /* in units of 32us */
218f05cddf9SRui Paulo 	int admission_control_mandatory;
219f05cddf9SRui Paulo };
220f05cddf9SRui Paulo 
221f05cddf9SRui Paulo int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
222f05cddf9SRui Paulo 			  const char *name, const char *val);
223c1d255d3SCy Schubert 
224c1d255d3SCy Schubert struct hostapd_tx_queue_params {
225c1d255d3SCy Schubert 	int aifs;
226c1d255d3SCy Schubert 	int cwmin;
227c1d255d3SCy Schubert 	int cwmax;
228c1d255d3SCy Schubert 	int burst; /* maximum burst time in 0.1 ms, i.e., 10 = 1 ms */
229c1d255d3SCy Schubert };
230c1d255d3SCy Schubert 
231c1d255d3SCy Schubert #define NUM_TX_QUEUES 4
232c1d255d3SCy Schubert 
233c1d255d3SCy Schubert int hostapd_config_tx_queue(struct hostapd_tx_queue_params queue[],
234c1d255d3SCy Schubert 			    const char *name, const char *val);
2355b9c547cSRui Paulo enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel);
2365b9c547cSRui Paulo int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan);
237*a90b9d01SCy Schubert enum hostapd_hw_mode
238*a90b9d01SCy Schubert ieee80211_freq_to_channel_ext(unsigned int freq, int sec_channel,
239*a90b9d01SCy Schubert 			      enum oper_chan_width chanwidth,
240325151a3SRui Paulo 			      u8 *op_class, u8 *channel);
2414bc52338SCy Schubert int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
2424bc52338SCy Schubert 				  int sec_channel, u8 *op_class, u8 *channel);
24385732ac8SCy Schubert int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
24485732ac8SCy Schubert 		     u16 num_modes);
2454b72b91aSCy Schubert int is_dfs_global_op_class(u8 op_class);
246*a90b9d01SCy Schubert bool is_80plus_op_class(u8 op_class);
247780fb4a2SCy Schubert enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht);
24839beb93cSSam Leffler 
2495b9c547cSRui Paulo int supp_rates_11b_only(struct ieee802_11_elems *elems);
250325151a3SRui Paulo int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
251325151a3SRui Paulo 		       size_t ies_len);
252325151a3SRui Paulo struct wpabuf * mb_ies_by_info(struct mb_ies_info *info);
2535b9c547cSRui Paulo 
2545b9c547cSRui Paulo const char * fc2str(u16 fc);
255206b73d0SCy Schubert const char * reason2str(u16 reason);
256206b73d0SCy Schubert const char * status2str(u16 status);
257780fb4a2SCy Schubert 
258780fb4a2SCy Schubert struct oper_class_map {
259780fb4a2SCy Schubert 	enum hostapd_hw_mode mode;
260780fb4a2SCy Schubert 	u8 op_class;
261780fb4a2SCy Schubert 	u8 min_chan;
262780fb4a2SCy Schubert 	u8 max_chan;
263780fb4a2SCy Schubert 	u8 inc;
264c1d255d3SCy Schubert 	enum { BW20, BW40PLUS, BW40MINUS, BW40, BW80, BW2160, BW160, BW80P80,
265*a90b9d01SCy Schubert 	       BW320, BW4320, BW6480, BW8640} bw;
266780fb4a2SCy Schubert 	enum { P2P_SUPP, NO_P2P_SUPP } p2p;
267780fb4a2SCy Schubert };
268780fb4a2SCy Schubert 
269780fb4a2SCy Schubert extern const struct oper_class_map global_op_class[];
270780fb4a2SCy Schubert extern size_t global_op_class_size;
271780fb4a2SCy Schubert 
272780fb4a2SCy Schubert const u8 * get_ie(const u8 *ies, size_t len, u8 eid);
27385732ac8SCy Schubert const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext);
2744bc52338SCy Schubert const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type);
275780fb4a2SCy Schubert 
276780fb4a2SCy Schubert size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
277780fb4a2SCy Schubert 
278*a90b9d01SCy Schubert u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len,
279*a90b9d01SCy Schubert 		      struct multi_ap_params *multi_ap);
280*a90b9d01SCy Schubert size_t add_multi_ap_ie(u8 *buf, size_t len,
281*a90b9d01SCy Schubert 		       const struct multi_ap_params *multi_ap);
2824bc52338SCy Schubert 
28385732ac8SCy Schubert struct country_op_class {
28485732ac8SCy Schubert 	u8 country_op_class;
28585732ac8SCy Schubert 	u8 global_op_class;
28685732ac8SCy Schubert };
28785732ac8SCy Schubert 
28885732ac8SCy Schubert u8 country_to_global_op_class(const char *country, u8 op_class);
28985732ac8SCy Schubert 
29085732ac8SCy Schubert const struct oper_class_map * get_oper_class(const char *country, u8 op_class);
2914bc52338SCy Schubert int oper_class_bw_to_int(const struct oper_class_map *map);
292c1d255d3SCy Schubert int center_idx_to_bw_6ghz(u8 idx);
293c1d255d3SCy Schubert bool is_6ghz_freq(int freq);
294c1d255d3SCy Schubert bool is_6ghz_op_class(u8 op_class);
295c1d255d3SCy Schubert bool is_6ghz_psc_frequency(int freq);
2964b72b91aSCy Schubert int get_6ghz_sec_channel(int channel);
29785732ac8SCy Schubert 
298*a90b9d01SCy Schubert bool is_same_band(int freq1, int freq2);
299*a90b9d01SCy Schubert #define IS_2P4GHZ(n) (n >= 2412 && n <= 2484)
300*a90b9d01SCy Schubert #define IS_5GHZ(n) (n > 4000 && n < 5895)
301*a90b9d01SCy Schubert 
30285732ac8SCy Schubert int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
30385732ac8SCy Schubert 				    size_t nei_rep_len);
30485732ac8SCy Schubert 
3054bc52338SCy Schubert int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
306c1d255d3SCy Schubert bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
307c1d255d3SCy Schubert 			       unsigned int capab);
308c1d255d3SCy Schubert bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab);
309c1d255d3SCy Schubert int op_class_to_bandwidth(u8 op_class);
310*a90b9d01SCy Schubert enum oper_chan_width op_class_to_ch_width(u8 op_class);
311*a90b9d01SCy Schubert int chwidth_freq2_to_ch_width(int chwidth, int freq2);
3124bc52338SCy Schubert 
3134bc52338SCy Schubert /* element iteration helpers */
3144bc52338SCy Schubert #define for_each_element(_elem, _data, _datalen)			\
3154bc52338SCy Schubert 	for (_elem = (const struct element *) (_data);			\
3164bc52338SCy Schubert 	     (const u8 *) (_data) + (_datalen) - (const u8 *) _elem >=	\
3174bc52338SCy Schubert 		(int) sizeof(*_elem) &&					\
3184bc52338SCy Schubert 	     (const u8 *) (_data) + (_datalen) - (const u8 *) _elem >=	\
3194bc52338SCy Schubert 		(int) sizeof(*_elem) + _elem->datalen;			\
3204bc52338SCy Schubert 	     _elem = (const struct element *) (_elem->data + _elem->datalen))
3214bc52338SCy Schubert 
3224bc52338SCy Schubert #define for_each_element_id(element, _id, data, datalen)		\
3234bc52338SCy Schubert 	for_each_element(element, data, datalen)			\
3244bc52338SCy Schubert 		if (element->id == (_id))
3254bc52338SCy Schubert 
3264bc52338SCy Schubert #define for_each_element_extid(element, extid, _data, _datalen)		\
3274bc52338SCy Schubert 	for_each_element(element, _data, _datalen)			\
3284bc52338SCy Schubert 		if (element->id == WLAN_EID_EXTENSION &&		\
3294bc52338SCy Schubert 		    element->datalen > 0 &&				\
3304bc52338SCy Schubert 		    element->data[0] == (extid))
3314bc52338SCy Schubert 
3324bc52338SCy Schubert #define for_each_subelement(sub, element)				\
3334bc52338SCy Schubert 	for_each_element(sub, (element)->data, (element)->datalen)
3344bc52338SCy Schubert 
3354bc52338SCy Schubert #define for_each_subelement_id(sub, id, element)			\
3364bc52338SCy Schubert 	for_each_element_id(sub, id, (element)->data, (element)->datalen)
3374bc52338SCy Schubert 
3384bc52338SCy Schubert #define for_each_subelement_extid(sub, extid, element)			\
3394bc52338SCy Schubert 	for_each_element_extid(sub, extid, (element)->data, (element)->datalen)
3404bc52338SCy Schubert 
3414bc52338SCy Schubert /**
3424bc52338SCy Schubert  * for_each_element_completed - Determine if element parsing consumed all data
3434bc52338SCy Schubert  * @element: Element pointer after for_each_element() or friends
3444bc52338SCy Schubert  * @data: Same data pointer as passed to for_each_element() or friends
3454bc52338SCy Schubert  * @datalen: Same data length as passed to for_each_element() or friends
3464bc52338SCy Schubert  *
3474bc52338SCy Schubert  * This function returns 1 if all the data was parsed or considered
3484bc52338SCy Schubert  * while walking the elements. Only use this if your for_each_element()
3494bc52338SCy Schubert  * loop cannot be broken out of, otherwise it always returns 0.
3504bc52338SCy Schubert  *
3514bc52338SCy Schubert  * If some data was malformed, this returns %false since the last parsed
3524bc52338SCy Schubert  * element will not fill the whole remaining data.
3534bc52338SCy Schubert  */
for_each_element_completed(const struct element * element,const void * data,size_t datalen)3544bc52338SCy Schubert static inline int for_each_element_completed(const struct element *element,
3554bc52338SCy Schubert 					     const void *data, size_t datalen)
3564bc52338SCy Schubert {
3574bc52338SCy Schubert 	return (const u8 *) element == (const u8 *) data + datalen;
3584bc52338SCy Schubert }
3594bc52338SCy Schubert 
360c1d255d3SCy Schubert struct ieee80211_edmg_config;
361c1d255d3SCy Schubert 
362c1d255d3SCy Schubert void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
363c1d255d3SCy Schubert 			      int primary_channel,
364c1d255d3SCy Schubert 			      struct ieee80211_edmg_config *edmg);
365c1d255d3SCy Schubert 
366c1d255d3SCy Schubert int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,
367c1d255d3SCy Schubert 			    struct ieee80211_edmg_config requested);
368c1d255d3SCy Schubert 
369*a90b9d01SCy Schubert struct wpabuf * ieee802_11_defrag(const u8 *data, size_t len, bool ext_elem);
370*a90b9d01SCy Schubert const u8 * get_ml_ie(const u8 *ies, size_t len, u8 type);
371*a90b9d01SCy Schubert const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len);
372c1d255d3SCy Schubert 
37339beb93cSSam Leffler #endif /* IEEE802_11_COMMON_H */
374