2 * Copyright (c) 2015 Jan Kolarik
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * @addtogroup libieee80211
36 * Internal IEEE 802.11 header that should not be included.
39 #ifndef LIB_IEEE80211_PRIVATE_H
40 #define LIB_IEEE80211_PRIVATE_H
42 #include <fibril_synch.h>
43 #include <byteorder.h>
44 #include <ddf/driver.h>
45 #include <sys/types.h>
46 #include <ieee80211/ieee80211.h>
47 #include "ieee80211.h"
49 /** Timeout in us for waiting to authentication/association response. */
50 #define AUTH_TIMEOUT 200000
52 /** Timeout in us for waiting to finish 4-way handshake process. */
53 #define HANDSHAKE_TIMEOUT 5000000
55 /** Scanning period. */
56 #define SCAN_PERIOD_USEC 35000000
58 /** Time to wait for beacons on channel. */
59 #define SCAN_CHANNEL_WAIT_USEC 200000
61 /** Max time to keep scan result. */
62 #define MAX_KEEP_SCAN_SPAN_SEC 120
64 /** Security bit in capability info field. */
65 #define CAP_SECURITY 0x10
67 /** Protocol type used in EAPOL frames. */
68 #define ETH_TYPE_PAE 0x888e
70 /** WPA OUI used in vendor specific IE. */
71 #define WPA_OUI 0x0050f201
73 /** GTK OUI used in vendor specific IE. */
74 #define GTK_OUI 0x000fac01
76 /** Max PTK key length. */
77 #define MAX_PTK_LENGTH 64
79 /** Max GTK key length. */
80 #define MAX_GTK_LENGTH 64
82 /** KEK offset inside PTK. */
85 /** TK offset inside PTK. */
88 /** Length of Michael MIC code used in TKIP security suite. */
91 /** Length of data to be encrypted by PRF function.
93 * NONCE + SNONCE (2 * 32) + DEST_MAC + SOURCE_MAC (2 * ETH_ADDR)
96 #define PRF_CRYPT_DATA_LENGTH (2 * 32 + 2 * ETH_ADDR)
98 /** Special room in header reserved for encryption. */
100 IEEE80211_TKIP_HEADER_LENGTH
= 8,
101 IEEE80211_CCMP_HEADER_LENGTH
= 8
102 } ieee80211_encrypt_header_reserve_length_t
;
104 /** IEEE 802.11 PTK key length. */
106 IEEE80211_PTK_CCMP_LENGTH
= 48,
107 IEEE80211_PTK_TKIP_LENGTH
= 64
108 } ieee80211_ptk_length_t
;
110 /** IEEE 802.11 GTK key length. */
112 IEEE80211_GTK_CCMP_LENGTH
= 16,
113 IEEE80211_GTK_TKIP_LENGTH
= 32
114 } ieee80211_gtk_length_t
;
116 /** IEEE 802.11 frame types. */
118 IEEE80211_MGMT_FRAME
= 0x0,
119 IEEE80211_CTRL_FRAME
= 0x4,
120 IEEE80211_DATA_FRAME
= 0x8,
121 IEEE80211_EXT_FRAME
= 0xC
122 } ieee80211_frame_type_t
;
124 /** IEEE 802.11 management frame subtypes. */
126 IEEE80211_MGMT_ASSOC_REQ_FRAME
= 0x00,
127 IEEE80211_MGMT_ASSOC_RESP_FRAME
= 0x10,
128 IEEE80211_MGMT_REASSOC_REQ_FRAME
= 0x20,
129 IEEE80211_MGMT_REASSOC_RESP_FRAME
= 0x30,
130 IEEE80211_MGMT_PROBE_REQ_FRAME
= 0x40,
131 IEEE80211_MGMT_PROBE_RESP_FRAME
= 0x50,
132 IEEE80211_MGMT_BEACON_FRAME
= 0x80,
133 IEEE80211_MGMT_DISASSOC_FRAME
= 0xA0,
134 IEEE80211_MGMT_AUTH_FRAME
= 0xB0,
135 IEEE80211_MGMT_DEAUTH_FRAME
= 0xC0,
136 } ieee80211_frame_mgmt_subtype_t
;
138 /** IEEE 802.11 data frame subtypes. */
140 IEEE80211_DATA_DATA_FRAME
= 0x0000,
141 IEEE80211_DATA_QOS_FRAME
= 0x0080
142 } ieee80211_frame_data_subtype_t
;
144 /** IEEE 802.11 frame control value masks. */
146 IEEE80211_FRAME_CTRL_FRAME_TYPE
= 0x000C,
147 IEEE80211_FRAME_CTRL_FRAME_SUBTYPE
= 0x00F0,
148 IEEE80211_FRAME_CTRL_PROTECTED
= 0x4000
149 } ieee80211_frame_ctrl_mask_t
;
151 /** IEEE 802.11 frame control DS field values. */
153 IEEE80211_FRAME_CTRL_TODS
= 0x0100,
154 IEEE80211_FRAME_CTRL_FROMDS
= 0x0200
155 } ieee80211_frame_ctrl_ds_t
;
157 /** IEEE 802.11 authentication cipher suites values. */
159 IEEE80211_AUTH_CIPHER_TKIP
= 0x02,
160 IEEE80211_AUTH_CIPHER_CCMP
= 0x04
161 } ieee80211_auth_cipher_type_t
;
163 /** IEEE 802.11 AKM suites values. */
165 IEEE80211_AUTH_AKM_8021X
= 0x01,
166 IEEE80211_AUTH_AKM_PSK
= 0x02
167 } ieee80211_auth_akm_type_t
;
170 IEEE80211_EAPOL_START
= 0x1,
171 IEEE80211_EAPOL_KEY
= 0x3
172 } ieee80211_eapol_frame_type_t
;
175 IEEE80211_EAPOL_KEY_KEYINFO_KEYTYPE
= 0x0008,
176 IEEE80211_EAPOL_KEY_KEYINFO_KEYID
= 0x0010,
177 IEEE80211_EAPOL_KEY_KEYINFO_INSTALL
= 0x0040,
178 IEEE80211_EAPOL_KEY_KEYINFO_ACK
= 0x0080,
179 IEEE80211_EAPOL_KEY_KEYINFO_MIC
= 0x0100,
180 IEEE80211_EAPOL_KEY_KEYINFO_SECURE
= 0x0200,
181 IEEE80211_EAPOL_KEY_KEYINFO_ENCDATA
= 0x1000
182 } ieee80211_eapol_key_keyinfo_t
;
184 /** IEEE 802.11 information element types. */
186 IEEE80211_SSID_IE
= 0, /**< Target SSID. */
187 IEEE80211_RATES_IE
= 1, /**< Supported data rates. */
188 IEEE80211_CHANNEL_IE
= 3, /**< Current channel number. */
189 IEEE80211_CHALLENGE_IE
= 16, /**< Challenge text. */
190 IEEE80211_RSN_IE
= 48, /**< RSN. */
191 IEEE80211_EXT_RATES_IE
= 50, /**< Extended data rates. */
192 IEEE80211_VENDOR_IE
= 221 /**< Vendor specific IE. */
193 } ieee80211_ie_type_t
;
195 /** IEEE 802.11 authentication phases. */
197 IEEE80211_AUTH_DISCONNECTED
,
198 IEEE80211_AUTH_AUTHENTICATED
,
199 IEEE80211_AUTH_ASSOCIATED
,
200 IEEE80211_AUTH_CONNECTED
201 } ieee80211_auth_phase_t
;
203 /** Link with scan result info. */
207 ieee80211_scan_result_t scan_result
;
208 uint8_t auth_ie
[256];
210 } ieee80211_scan_result_link_t
;
212 /** List of scan results info. */
215 fibril_mutex_t results_mutex
;
217 } ieee80211_scan_result_list_t
;
222 char password
[IEEE80211_MAX_PASSW_LEN
];
223 uint8_t ptk
[MAX_PTK_LENGTH
];
224 uint8_t gtk
[MAX_GTK_LENGTH
];
225 ieee80211_scan_result_link_t
*res_link
;
226 } ieee80211_bssid_info_t
;
228 /** IEEE 802.11 WiFi device structure. */
229 struct ieee80211_dev
{
230 /** Backing DDF device. */
233 /** Pointer to implemented IEEE 802.11 device operations. */
234 ieee80211_ops_t
*ops
;
236 /** Pointer to implemented IEEE 802.11 interface operations. */
237 ieee80211_iface_t
*iface
;
239 /** Pointer to driver specific data. */
242 /** Current operating frequency. */
243 uint16_t current_freq
;
245 /** Current operating mode. */
246 ieee80211_operating_mode_t current_op_mode
;
248 /** Info about BSSID we are connected to. */
249 ieee80211_bssid_info_t bssid_info
;
252 * Flag indicating that data traffic is encrypted by HW key
253 * that is set up in device.
257 /** BSSIDs we listen to. */
258 nic_address_t bssid_mask
;
260 /** List of APs in neighborhood. */
261 ieee80211_scan_result_list_t ap_list
;
263 /** Current sequence number used in data frames. */
264 uint16_t sequence_number
;
266 /** Current authentication phase. */
267 ieee80211_auth_phase_t current_auth_phase
;
269 /** Flag indicating whether client wants connect to network. */
270 bool pending_conn_req
;
272 /** Scanning guard. */
273 fibril_mutex_t scan_mutex
;
275 /** General purpose guard. */
276 fibril_mutex_t gen_mutex
;
278 /** General purpose condition variable. */
279 fibril_condvar_t gen_cond
;
281 /** Indicates whether device is fully initialized. */
284 /** Indicates whether driver has already started. */
288 /** IEEE 802.3 (ethernet) header. */
290 uint8_t dest_addr
[ETH_ADDR
];
291 uint8_t src_addr
[ETH_ADDR
];
292 uint16_t proto
; /**< Big Endian value! */
293 } __attribute__((packed
)) __attribute__((aligned(2)))
296 /** IEEE 802.11 management header structure. */
298 uint16_t frame_ctrl
; /**< Little Endian value! */
299 uint16_t duration_id
; /**< Little Endian value! */
300 uint8_t dest_addr
[ETH_ADDR
];
301 uint8_t src_addr
[ETH_ADDR
];
302 uint8_t bssid
[ETH_ADDR
];
303 uint16_t seq_ctrl
; /**< Little Endian value! */
304 } __attribute__((packed
)) __attribute__((aligned(2)))
305 ieee80211_mgmt_header_t
;
307 /** IEEE 802.11 data header structure. */
309 uint16_t frame_ctrl
; /**< Little Endian value! */
310 uint16_t duration_id
; /**< Little Endian value! */
311 uint8_t address1
[ETH_ADDR
];
312 uint8_t address2
[ETH_ADDR
];
313 uint8_t address3
[ETH_ADDR
];
314 uint16_t seq_ctrl
; /**< Little Endian value! */
315 } __attribute__((packed
)) __attribute__((aligned(2)))
316 ieee80211_data_header_t
;
318 /** IEEE 802.11 information element header. */
322 } __attribute__((packed
)) __attribute__((aligned(2)))
323 ieee80211_ie_header_t
;
325 /** IEEE 802.11 authentication frame body. */
327 uint16_t auth_alg
; /**< Little Endian value! */
328 uint16_t auth_trans_no
; /**< Little Endian value! */
329 uint16_t status
; /**< Little Endian value! */
330 } __attribute__((packed
)) __attribute__((aligned(2)))
331 ieee80211_auth_body_t
;
333 /** IEEE 802.11 deauthentication frame body. */
335 uint16_t reason
; /**< Little Endian value! */
336 } __attribute__((packed
)) __attribute__((aligned(2)))
337 ieee80211_deauth_body_t
;
339 /** IEEE 802.11 association request frame body. */
341 uint16_t capability
; /**< Little Endian value! */
342 uint16_t listen_interval
; /**< Little Endian value! */
343 } __attribute__((packed
)) __attribute__((aligned(2)))
344 ieee80211_assoc_req_body_t
;
346 /** IEEE 802.11 association response frame body. */
348 uint16_t capability
; /**< Little Endian value! */
349 uint16_t status
; /**< Little Endian value! */
350 uint16_t aid
; /**< Little Endian value! */
351 } __attribute__((packed
)) __attribute__((aligned(2)))
352 ieee80211_assoc_resp_body_t
;
354 /** IEEE 802.11 beacon frame body start. */
356 uint8_t timestamp
[8];
357 uint16_t beacon_interval
; /**< Little Endian value! */
358 uint16_t capability
; /**< Little Endian value! */
359 } __attribute__((packed
)) __attribute__((aligned(2)))
360 ieee80211_beacon_start_t
;
362 /** IEEE 802.11i EAPOL-Key frame format. */
364 uint8_t proto_version
;
366 uint16_t body_length
; /**< Big Endian value! */
367 uint8_t descriptor_type
;
368 uint16_t key_info
; /**< Big Endian value! */
369 uint16_t key_length
; /**< Big Endian value! */
370 uint8_t key_replay_counter
[8];
371 uint8_t key_nonce
[32];
372 uint8_t eapol_key_iv
[16];
376 uint16_t key_data_length
; /**< Big Endian value! */
377 } __attribute__((packed
)) ieee80211_eapol_key_frame_t
;
379 #define ieee80211_scan_result_list_foreach(results, iter) \
380 list_foreach((results).list, link, ieee80211_scan_result_link_t, (iter))
383 ieee80211_scan_result_list_init(ieee80211_scan_result_list_t
*results
)
385 list_initialize(&results
->list
);
386 fibril_mutex_initialize(&results
->results_mutex
);
390 ieee80211_scan_result_list_remove(ieee80211_scan_result_list_t
*results
,
391 ieee80211_scan_result_link_t
*result
)
393 list_remove(&result
->link
);
398 ieee80211_scan_result_list_append(ieee80211_scan_result_list_t
*results
,
399 ieee80211_scan_result_link_t
*result
)
401 list_append(&result
->link
, &results
->list
);
405 extern bool ieee80211_is_fromds_frame(uint16_t);
406 extern bool ieee80211_is_tods_frame(uint16_t);
407 extern void ieee80211_set_connect_request(ieee80211_dev_t
*);
408 extern bool ieee80211_pending_connect_request(ieee80211_dev_t
*);
409 extern ieee80211_auth_phase_t
ieee80211_get_auth_phase(ieee80211_dev_t
*);
410 extern void ieee80211_set_auth_phase(ieee80211_dev_t
*, ieee80211_auth_phase_t
);
411 extern int ieee80211_probe_request(ieee80211_dev_t
*, char *);
412 extern int ieee80211_authenticate(ieee80211_dev_t
*);
413 extern int ieee80211_associate(ieee80211_dev_t
*, char *);
414 extern int ieee80211_deauthenticate(ieee80211_dev_t
*);