]>
Commit | Line | Data |
---|---|---|
6fc6879b | 1 | /* |
c5b26e33 | 2 | * Internal WPA/RSN supplicant state machine definitions |
a3e18dbb | 3 | * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi> |
6fc6879b | 4 | * |
0f3d578e JM |
5 | * This software may be distributed under the terms of the BSD license. |
6 | * See README for more details. | |
6fc6879b JM |
7 | */ |
8 | ||
9 | #ifndef WPA_I_H | |
10 | #define WPA_I_H | |
11 | ||
c5b26e33 JM |
12 | #include "utils/list.h" |
13 | ||
281ff0aa | 14 | struct wpa_tdls_peer; |
6fc6879b JM |
15 | struct wpa_eapol_key; |
16 | ||
17 | /** | |
18 | * struct wpa_sm - Internal WPA state machine data | |
19 | */ | |
20 | struct wpa_sm { | |
207976f0 | 21 | u8 pmk[PMK_LEN_MAX]; |
6fc6879b JM |
22 | size_t pmk_len; |
23 | struct wpa_ptk ptk, tptk; | |
24 | int ptk_set, tptk_set; | |
761396e4 | 25 | unsigned int msg_3_of_4_ok:1; |
6fc6879b JM |
26 | u8 snonce[WPA_NONCE_LEN]; |
27 | u8 anonce[WPA_NONCE_LEN]; /* ANonce from the last 1/4 msg */ | |
28 | int renew_snonce; | |
29 | u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; | |
30 | int rx_replay_counter_set; | |
31 | u8 request_counter[WPA_REPLAY_COUNTER_LEN]; | |
cb5132bb | 32 | struct wpa_gtk gtk; |
87e2db16 | 33 | struct wpa_gtk gtk_wnm_sleep; |
cb5132bb | 34 | struct wpa_igtk igtk; |
87e2db16 | 35 | struct wpa_igtk igtk_wnm_sleep; |
6fc6879b JM |
36 | |
37 | struct eapol_sm *eapol; /* EAPOL state machine from upper level code */ | |
38 | ||
39 | struct rsn_pmksa_cache *pmksa; /* PMKSA cache */ | |
40 | struct rsn_pmksa_cache_entry *cur_pmksa; /* current PMKSA entry */ | |
c5b26e33 | 41 | struct dl_list pmksa_candidates; |
6fc6879b JM |
42 | |
43 | struct l2_packet_data *l2_preauth; | |
44 | struct l2_packet_data *l2_preauth_br; | |
281ff0aa | 45 | struct l2_packet_data *l2_tdls; |
6fc6879b JM |
46 | u8 preauth_bssid[ETH_ALEN]; /* current RSN pre-auth peer or |
47 | * 00:00:00:00:00:00 if no pre-auth is | |
48 | * in progress */ | |
49 | struct eapol_sm *preauth_eapol; | |
50 | ||
51 | struct wpa_sm_ctx *ctx; | |
52 | ||
53 | void *scard_ctx; /* context for smartcard callbacks */ | |
54 | int fast_reauth; /* whether EAP fast re-authentication is enabled */ | |
55 | ||
56 | void *network_ctx; | |
6fc6879b JM |
57 | int allowed_pairwise_cipher; /* bitfield of WPA_CIPHER_* */ |
58 | int proactive_key_caching; | |
59 | int eap_workaround; | |
60 | void *eap_conf_ctx; | |
61 | u8 ssid[32]; | |
62 | size_t ssid_len; | |
581a8cde | 63 | int wpa_ptk_rekey; |
25ef8529 | 64 | int p2p; |
73ed03f3 | 65 | int wpa_rsc_relaxation; |
8b138d28 | 66 | int owe_ptk_workaround; |
ecbf59e6 | 67 | int beacon_prot; |
6fc6879b JM |
68 | |
69 | u8 own_addr[ETH_ALEN]; | |
70 | const char *ifname; | |
71 | const char *bridge_ifname; | |
72 | u8 bssid[ETH_ALEN]; | |
73 | ||
74 | unsigned int dot11RSNAConfigPMKLifetime; | |
75 | unsigned int dot11RSNAConfigPMKReauthThreshold; | |
76 | unsigned int dot11RSNAConfigSATimeout; | |
77 | ||
78 | unsigned int dot11RSNA4WayHandshakeFailures; | |
79 | ||
80 | /* Selected configuration (based on Beacon/ProbeResp WPA IE) */ | |
81 | unsigned int proto; | |
82 | unsigned int pairwise_cipher; | |
83 | unsigned int group_cipher; | |
84 | unsigned int key_mgmt; | |
85 | unsigned int mgmt_group_cipher; | |
86 | ||
87 | int rsn_enabled; /* Whether RSN is enabled in configuration */ | |
e820cf95 | 88 | int mfp; /* 0 = disabled, 1 = optional, 2 = mandatory */ |
55c12f5d | 89 | int ocv; /* Operating Channel Validation */ |
6d6c8877 | 90 | int sae_pwe; /* SAE PWE generation options */ |
6fc6879b JM |
91 | |
92 | u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */ | |
93 | size_t assoc_wpa_ie_len; | |
6d6c8877 JM |
94 | u8 *assoc_rsnxe; /* Own RSNXE from (Re)AssocReq */ |
95 | size_t assoc_rsnxe_len; | |
146889e3 JM |
96 | u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe; |
97 | size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len; | |
6fc6879b | 98 | |
281ff0aa GP |
99 | #ifdef CONFIG_TDLS |
100 | struct wpa_tdls_peer *tdls; | |
52c9e6f3 | 101 | int tdls_prohibited; |
d9d3b78c | 102 | int tdls_chan_switch_prohibited; |
b8f64582 | 103 | int tdls_disabled; |
c58ab8f2 AN |
104 | |
105 | /* The driver supports TDLS */ | |
106 | int tdls_supported; | |
107 | ||
108 | /* | |
109 | * The driver requires explicit discovery/setup/teardown frames sent | |
110 | * to it via tdls_mgmt. | |
111 | */ | |
112 | int tdls_external_setup; | |
4daa5729 AN |
113 | |
114 | /* The driver supports TDLS channel switching */ | |
115 | int tdls_chan_switch; | |
281ff0aa | 116 | #endif /* CONFIG_TDLS */ |
6fc6879b JM |
117 | |
118 | #ifdef CONFIG_IEEE80211R | |
a3e18dbb JM |
119 | u8 xxkey[PMK_LEN_MAX]; /* PSK or the second 256 bits of MSK, or the |
120 | * first 384 bits of MSK */ | |
6fc6879b | 121 | size_t xxkey_len; |
a3e18dbb JM |
122 | u8 pmk_r0[PMK_LEN_MAX]; |
123 | size_t pmk_r0_len; | |
6fc6879b | 124 | u8 pmk_r0_name[WPA_PMK_NAME_LEN]; |
a3e18dbb JM |
125 | u8 pmk_r1[PMK_LEN_MAX]; |
126 | size_t pmk_r1_len; | |
6fc6879b JM |
127 | u8 pmk_r1_name[WPA_PMK_NAME_LEN]; |
128 | u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN]; | |
129 | u8 r0kh_id[FT_R0KH_ID_MAX_LEN]; | |
130 | size_t r0kh_id_len; | |
131 | u8 r1kh_id[FT_R1KH_ID_LEN]; | |
0a1a82db JM |
132 | unsigned int ft_completed:1; |
133 | unsigned int ft_reassoc_completed:1; | |
134 | unsigned int ft_protocol:1; | |
6fc6879b JM |
135 | int over_the_ds_in_progress; |
136 | u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */ | |
86f7b62a | 137 | int set_ptk_after_assoc; |
f4ec630d | 138 | u8 mdie_ft_capab; /* FT Capability and Policy from target AP MDIE */ |
55046414 JM |
139 | u8 *assoc_resp_ies; /* MDIE and FTIE from (Re)Association Response */ |
140 | size_t assoc_resp_ies_len; | |
6fc6879b | 141 | #endif /* CONFIG_IEEE80211R */ |
25ef8529 JM |
142 | |
143 | #ifdef CONFIG_P2P | |
144 | u8 p2p_ip_addr[3 * 4]; | |
145 | #endif /* CONFIG_P2P */ | |
651c6a84 JM |
146 | |
147 | #ifdef CONFIG_TESTING_OPTIONS | |
148 | struct wpabuf *test_assoc_ie; | |
149 | #endif /* CONFIG_TESTING_OPTIONS */ | |
f00b9b88 JM |
150 | |
151 | #ifdef CONFIG_FILS | |
152 | u8 fils_nonce[FILS_NONCE_LEN]; | |
153 | u8 fils_session[FILS_SESSION_LEN]; | |
a6609937 JM |
154 | u8 fils_anonce[FILS_NONCE_LEN]; |
155 | u8 fils_key_auth_ap[FILS_MAX_KEY_AUTH_LEN]; | |
156 | u8 fils_key_auth_sta[FILS_MAX_KEY_AUTH_LEN]; | |
157 | size_t fils_key_auth_len; | |
706df429 | 158 | unsigned int fils_completed:1; |
fcd3d6ce | 159 | unsigned int fils_erp_pmkid_set:1; |
869af307 | 160 | unsigned int fils_cache_id_set:1; |
fcd3d6ce | 161 | u8 fils_erp_pmkid[PMKID_LEN]; |
869af307 | 162 | u8 fils_cache_id[FILS_CACHE_ID_LEN]; |
76e20f4f JM |
163 | struct crypto_ecdh *fils_ecdh; |
164 | int fils_dh_group; | |
165 | size_t fils_dh_elem_len; | |
7d440a3b JM |
166 | struct wpabuf *fils_ft_ies; |
167 | u8 fils_ft[FILS_FT_MAX_LEN]; | |
168 | size_t fils_ft_len; | |
f00b9b88 | 169 | #endif /* CONFIG_FILS */ |
0a614799 JM |
170 | |
171 | #ifdef CONFIG_OWE | |
172 | struct crypto_ecdh *owe_ecdh; | |
ec9f4837 | 173 | u16 owe_group; |
0a614799 | 174 | #endif /* CONFIG_OWE */ |
10ec6a5f JM |
175 | |
176 | #ifdef CONFIG_DPP2 | |
177 | struct wpabuf *dpp_z; | |
178 | #endif /* CONFIG_DPP2 */ | |
6fc6879b JM |
179 | }; |
180 | ||
181 | ||
71934751 | 182 | static inline void wpa_sm_set_state(struct wpa_sm *sm, enum wpa_states state) |
6fc6879b JM |
183 | { |
184 | WPA_ASSERT(sm->ctx->set_state); | |
185 | sm->ctx->set_state(sm->ctx->ctx, state); | |
186 | } | |
187 | ||
71934751 | 188 | static inline enum wpa_states wpa_sm_get_state(struct wpa_sm *sm) |
6fc6879b JM |
189 | { |
190 | WPA_ASSERT(sm->ctx->get_state); | |
191 | return sm->ctx->get_state(sm->ctx->ctx); | |
192 | } | |
193 | ||
4be17ffb | 194 | static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, u16 reason_code) |
6fc6879b JM |
195 | { |
196 | WPA_ASSERT(sm->ctx->deauthenticate); | |
197 | sm->ctx->deauthenticate(sm->ctx->ctx, reason_code); | |
198 | } | |
199 | ||
71934751 | 200 | static inline int wpa_sm_set_key(struct wpa_sm *sm, enum wpa_alg alg, |
6fc6879b JM |
201 | const u8 *addr, int key_idx, int set_tx, |
202 | const u8 *seq, size_t seq_len, | |
a919a260 AW |
203 | const u8 *key, size_t key_len, |
204 | enum key_flag key_flag) | |
6fc6879b JM |
205 | { |
206 | WPA_ASSERT(sm->ctx->set_key); | |
207 | return sm->ctx->set_key(sm->ctx->ctx, alg, addr, key_idx, set_tx, | |
a919a260 | 208 | seq, seq_len, key, key_len, key_flag); |
6fc6879b JM |
209 | } |
210 | ||
211 | static inline void * wpa_sm_get_network_ctx(struct wpa_sm *sm) | |
212 | { | |
213 | WPA_ASSERT(sm->ctx->get_network_ctx); | |
214 | return sm->ctx->get_network_ctx(sm->ctx->ctx); | |
215 | } | |
216 | ||
217 | static inline int wpa_sm_get_bssid(struct wpa_sm *sm, u8 *bssid) | |
218 | { | |
219 | WPA_ASSERT(sm->ctx->get_bssid); | |
220 | return sm->ctx->get_bssid(sm->ctx->ctx, bssid); | |
221 | } | |
222 | ||
223 | static inline int wpa_sm_ether_send(struct wpa_sm *sm, const u8 *dest, | |
224 | u16 proto, const u8 *buf, size_t len) | |
225 | { | |
226 | WPA_ASSERT(sm->ctx->ether_send); | |
227 | return sm->ctx->ether_send(sm->ctx->ctx, dest, proto, buf, len); | |
228 | } | |
229 | ||
230 | static inline int wpa_sm_get_beacon_ie(struct wpa_sm *sm) | |
231 | { | |
232 | WPA_ASSERT(sm->ctx->get_beacon_ie); | |
233 | return sm->ctx->get_beacon_ie(sm->ctx->ctx); | |
234 | } | |
235 | ||
236 | static inline void wpa_sm_cancel_auth_timeout(struct wpa_sm *sm) | |
237 | { | |
238 | WPA_ASSERT(sm->ctx->cancel_auth_timeout); | |
239 | sm->ctx->cancel_auth_timeout(sm->ctx->ctx); | |
240 | } | |
241 | ||
242 | static inline u8 * wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type, | |
243 | const void *data, u16 data_len, | |
244 | size_t *msg_len, void **data_pos) | |
245 | { | |
246 | WPA_ASSERT(sm->ctx->alloc_eapol); | |
247 | return sm->ctx->alloc_eapol(sm->ctx->ctx, type, data, data_len, | |
248 | msg_len, data_pos); | |
249 | } | |
250 | ||
c5793127 | 251 | static inline int wpa_sm_add_pmkid(struct wpa_sm *sm, void *network_ctx, |
42e69bda VK |
252 | const u8 *bssid, const u8 *pmkid, |
253 | const u8 *cache_id, const u8 *pmk, | |
254 | size_t pmk_len) | |
6fc6879b JM |
255 | { |
256 | WPA_ASSERT(sm->ctx->add_pmkid); | |
42e69bda VK |
257 | return sm->ctx->add_pmkid(sm->ctx->ctx, network_ctx, bssid, pmkid, |
258 | cache_id, pmk, pmk_len); | |
6fc6879b JM |
259 | } |
260 | ||
c5793127 | 261 | static inline int wpa_sm_remove_pmkid(struct wpa_sm *sm, void *network_ctx, |
42e69bda VK |
262 | const u8 *bssid, const u8 *pmkid, |
263 | const u8 *cache_id) | |
6fc6879b JM |
264 | { |
265 | WPA_ASSERT(sm->ctx->remove_pmkid); | |
42e69bda VK |
266 | return sm->ctx->remove_pmkid(sm->ctx->ctx, network_ctx, bssid, pmkid, |
267 | cache_id); | |
6fc6879b JM |
268 | } |
269 | ||
270 | static inline int wpa_sm_mlme_setprotection(struct wpa_sm *sm, const u8 *addr, | |
271 | int protect_type, int key_type) | |
272 | { | |
273 | WPA_ASSERT(sm->ctx->mlme_setprotection); | |
274 | return sm->ctx->mlme_setprotection(sm->ctx->ctx, addr, protect_type, | |
275 | key_type); | |
276 | } | |
277 | ||
278 | static inline int wpa_sm_update_ft_ies(struct wpa_sm *sm, const u8 *md, | |
279 | const u8 *ies, size_t ies_len) | |
280 | { | |
281 | if (sm->ctx->update_ft_ies) | |
282 | return sm->ctx->update_ft_ies(sm->ctx->ctx, md, ies, ies_len); | |
283 | return -1; | |
284 | } | |
285 | ||
286 | static inline int wpa_sm_send_ft_action(struct wpa_sm *sm, u8 action, | |
287 | const u8 *target_ap, | |
288 | const u8 *ies, size_t ies_len) | |
289 | { | |
290 | if (sm->ctx->send_ft_action) | |
291 | return sm->ctx->send_ft_action(sm->ctx->ctx, action, target_ap, | |
292 | ies, ies_len); | |
293 | return -1; | |
294 | } | |
295 | ||
2a7e7f4e JM |
296 | static inline int wpa_sm_mark_authenticated(struct wpa_sm *sm, |
297 | const u8 *target_ap) | |
298 | { | |
299 | if (sm->ctx->mark_authenticated) | |
300 | return sm->ctx->mark_authenticated(sm->ctx->ctx, target_ap); | |
301 | return -1; | |
302 | } | |
303 | ||
b14a210c JB |
304 | static inline void wpa_sm_set_rekey_offload(struct wpa_sm *sm) |
305 | { | |
306 | if (!sm->ctx->set_rekey_offload) | |
307 | return; | |
98cd3d1c JM |
308 | sm->ctx->set_rekey_offload(sm->ctx->ctx, sm->ptk.kek, sm->ptk.kek_len, |
309 | sm->ptk.kck, sm->ptk.kck_len, | |
310 | sm->rx_replay_counter); | |
b14a210c JB |
311 | } |
312 | ||
281ff0aa | 313 | #ifdef CONFIG_TDLS |
c58ab8f2 AN |
314 | static inline int wpa_sm_tdls_get_capa(struct wpa_sm *sm, |
315 | int *tdls_supported, | |
4daa5729 AN |
316 | int *tdls_ext_setup, |
317 | int *tdls_chan_switch) | |
c58ab8f2 AN |
318 | { |
319 | if (sm->ctx->tdls_get_capa) | |
320 | return sm->ctx->tdls_get_capa(sm->ctx->ctx, tdls_supported, | |
4daa5729 | 321 | tdls_ext_setup, tdls_chan_switch); |
c58ab8f2 AN |
322 | return -1; |
323 | } | |
324 | ||
281ff0aa GP |
325 | static inline int wpa_sm_send_tdls_mgmt(struct wpa_sm *sm, const u8 *dst, |
326 | u8 action_code, u8 dialog_token, | |
96ecea5e | 327 | u16 status_code, u32 peer_capab, |
984dadc2 AN |
328 | int initiator, const u8 *buf, |
329 | size_t len) | |
281ff0aa GP |
330 | { |
331 | if (sm->ctx->send_tdls_mgmt) | |
332 | return sm->ctx->send_tdls_mgmt(sm->ctx->ctx, dst, action_code, | |
333 | dialog_token, status_code, | |
984dadc2 AN |
334 | peer_capab, initiator, buf, |
335 | len); | |
281ff0aa GP |
336 | return -1; |
337 | } | |
338 | ||
339 | static inline int wpa_sm_tdls_oper(struct wpa_sm *sm, int oper, | |
340 | const u8 *peer) | |
341 | { | |
342 | if (sm->ctx->tdls_oper) | |
343 | return sm->ctx->tdls_oper(sm->ctx->ctx, oper, peer); | |
344 | return -1; | |
345 | } | |
45b722f1 AN |
346 | |
347 | static inline int | |
348 | wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, | |
78533699 | 349 | u16 aid, u16 capability, const u8 *supp_rates, |
ff4178d5 SD |
350 | size_t supp_rates_len, |
351 | const struct ieee80211_ht_capabilities *ht_capab, | |
f8361e3d | 352 | const struct ieee80211_vht_capabilities *vht_capab, |
08d7665c AN |
353 | u8 qosinfo, int wmm, const u8 *ext_capab, |
354 | size_t ext_capab_len, const u8 *supp_channels, | |
355 | size_t supp_channels_len, const u8 *supp_oper_classes, | |
3ed97271 | 356 | size_t supp_oper_classes_len) |
45b722f1 AN |
357 | { |
358 | if (sm->ctx->tdls_peer_addset) | |
359 | return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add, | |
78533699 | 360 | aid, capability, supp_rates, |
ff4178d5 | 361 | supp_rates_len, ht_capab, |
08d7665c | 362 | vht_capab, qosinfo, wmm, |
3ed97271 SD |
363 | ext_capab, ext_capab_len, |
364 | supp_channels, | |
365 | supp_channels_len, | |
366 | supp_oper_classes, | |
367 | supp_oper_classes_len); | |
45b722f1 AN |
368 | return -1; |
369 | } | |
6b90deae AN |
370 | |
371 | static inline int | |
372 | wpa_sm_tdls_enable_channel_switch(struct wpa_sm *sm, const u8 *addr, | |
373 | u8 oper_class, | |
374 | const struct hostapd_freq_params *freq_params) | |
375 | { | |
376 | if (sm->ctx->tdls_enable_channel_switch) | |
377 | return sm->ctx->tdls_enable_channel_switch(sm->ctx->ctx, addr, | |
378 | oper_class, | |
379 | freq_params); | |
380 | return -1; | |
381 | } | |
382 | ||
383 | static inline int | |
384 | wpa_sm_tdls_disable_channel_switch(struct wpa_sm *sm, const u8 *addr) | |
385 | { | |
386 | if (sm->ctx->tdls_disable_channel_switch) | |
387 | return sm->ctx->tdls_disable_channel_switch(sm->ctx->ctx, addr); | |
388 | return -1; | |
389 | } | |
281ff0aa | 390 | #endif /* CONFIG_TDLS */ |
6fc6879b | 391 | |
b41f2684 CL |
392 | static inline int wpa_sm_key_mgmt_set_pmk(struct wpa_sm *sm, |
393 | const u8 *pmk, size_t pmk_len) | |
394 | { | |
b41f2684 CL |
395 | if (!sm->ctx->key_mgmt_set_pmk) |
396 | return -1; | |
397 | return sm->ctx->key_mgmt_set_pmk(sm->ctx->ctx, pmk, pmk_len); | |
398 | } | |
399 | ||
124ddfa1 JM |
400 | static inline void wpa_sm_fils_hlp_rx(struct wpa_sm *sm, |
401 | const u8 *dst, const u8 *src, | |
402 | const u8 *pkt, size_t pkt_len) | |
403 | { | |
404 | if (sm->ctx->fils_hlp_rx) | |
405 | sm->ctx->fils_hlp_rx(sm->ctx->ctx, dst, src, pkt, pkt_len); | |
406 | } | |
407 | ||
4b62b52e MV |
408 | static inline int wpa_sm_channel_info(struct wpa_sm *sm, |
409 | struct wpa_channel_info *ci) | |
410 | { | |
411 | if (!sm->ctx->channel_info) | |
412 | return -1; | |
413 | return sm->ctx->channel_info(sm->ctx->ctx, ci); | |
414 | } | |
415 | ||
124ddfa1 | 416 | |
1049af7e | 417 | int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk, |
c93b7e18 AA |
418 | int ver, const u8 *dest, u16 proto, |
419 | u8 *msg, size_t msg_len, u8 *key_mic); | |
6fc6879b JM |
420 | int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, |
421 | const struct wpa_eapol_key *key, | |
422 | int ver, const u8 *nonce, | |
423 | const u8 *wpa_ie, size_t wpa_ie_len, | |
424 | struct wpa_ptk *ptk); | |
425 | int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst, | |
426 | const struct wpa_eapol_key *key, | |
427 | u16 ver, u16 key_info, | |
6fc6879b JM |
428 | struct wpa_ptk *ptk); |
429 | ||
430 | int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, | |
98cd3d1c | 431 | const struct wpa_eapol_key *key, struct wpa_ptk *ptk); |
6fc6879b | 432 | |
40cf22e6 JM |
433 | void wpa_tdls_assoc(struct wpa_sm *sm); |
434 | void wpa_tdls_disassoc(struct wpa_sm *sm); | |
435 | ||
6fc6879b | 436 | #endif /* WPA_I_H */ |