3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "common/defs.h"
13 #include "common/ieee802_11_defs.h"
14 #include "common/ieee802_11_common.h"
15 #include "crypto/sha1.h"
19 struct wlantest_bss
* bss_find(struct wlantest
*wt
, const u8
*bssid
)
21 struct wlantest_bss
*bss
;
23 dl_list_for_each(bss
, &wt
->bss
, struct wlantest_bss
, list
) {
24 if (os_memcmp(bss
->bssid
, bssid
, ETH_ALEN
) == 0)
32 struct wlantest_bss
* bss_get(struct wlantest
*wt
, const u8
*bssid
)
34 struct wlantest_bss
*bss
;
37 return NULL
; /* Skip group addressed frames */
39 bss
= bss_find(wt
, bssid
);
43 bss
= os_zalloc(sizeof(*bss
));
46 dl_list_init(&bss
->sta
);
47 dl_list_init(&bss
->pmk
);
48 dl_list_init(&bss
->tdls
);
49 os_memcpy(bss
->bssid
, bssid
, ETH_ALEN
);
50 dl_list_add(&wt
->bss
, &bss
->list
);
51 wpa_printf(MSG_DEBUG
, "Discovered new BSS - " MACSTR
,
57 void pmk_deinit(struct wlantest_pmk
*pmk
)
59 dl_list_del(&pmk
->list
);
64 void tdls_deinit(struct wlantest_tdls
*tdls
)
66 dl_list_del(&tdls
->list
);
71 void bss_deinit(struct wlantest_bss
*bss
)
73 struct wlantest_sta
*sta
, *n
;
74 struct wlantest_pmk
*pmk
, *np
;
75 struct wlantest_tdls
*tdls
, *nt
;
76 dl_list_for_each_safe(sta
, n
, &bss
->sta
, struct wlantest_sta
, list
)
78 dl_list_for_each_safe(pmk
, np
, &bss
->pmk
, struct wlantest_pmk
, list
)
80 dl_list_for_each_safe(tdls
, nt
, &bss
->tdls
, struct wlantest_tdls
, list
)
82 dl_list_del(&bss
->list
);
87 int bss_add_pmk_from_passphrase(struct wlantest_bss
*bss
,
88 const char *passphrase
)
90 struct wlantest_pmk
*pmk
;
92 pmk
= os_zalloc(sizeof(*pmk
));
95 if (pbkdf2_sha1(passphrase
, bss
->ssid
, bss
->ssid_len
, 4096,
96 pmk
->pmk
, sizeof(pmk
->pmk
)) < 0) {
101 wpa_printf(MSG_INFO
, "Add possible PMK for BSSID " MACSTR
102 " based on passphrase '%s'",
103 MAC2STR(bss
->bssid
), passphrase
);
104 wpa_hexdump(MSG_DEBUG
, "Possible PMK", pmk
->pmk
, sizeof(pmk
->pmk
));
105 dl_list_add(&bss
->pmk
, &pmk
->list
);
111 static void bss_add_pmk(struct wlantest
*wt
, struct wlantest_bss
*bss
)
113 struct wlantest_passphrase
*p
;
115 dl_list_for_each(p
, &wt
->passphrase
, struct wlantest_passphrase
, list
)
117 if (!is_zero_ether_addr(p
->bssid
) &&
118 os_memcmp(p
->bssid
, bss
->bssid
, ETH_ALEN
) != 0)
121 (p
->ssid_len
!= bss
->ssid_len
||
122 os_memcmp(p
->ssid
, bss
->ssid
, p
->ssid_len
) != 0))
125 if (bss_add_pmk_from_passphrase(bss
, p
->passphrase
) < 0)
131 void bss_update(struct wlantest
*wt
, struct wlantest_bss
*bss
,
132 struct ieee802_11_elems
*elems
)
134 struct wpa_ie_data data
;
137 if (bss
->capab_info
!= bss
->prev_capab_info
)
140 if (elems
->ssid
== NULL
|| elems
->ssid_len
> 32) {
141 wpa_printf(MSG_INFO
, "Invalid or missing SSID in a Beacon "
142 "frame for " MACSTR
, MAC2STR(bss
->bssid
));
143 bss
->parse_error_reported
= 1;
147 if (bss
->ssid_len
!= elems
->ssid_len
||
148 os_memcmp(bss
->ssid
, elems
->ssid
, bss
->ssid_len
) != 0) {
149 wpa_printf(MSG_DEBUG
, "Store SSID '%s' for BSSID " MACSTR
,
150 wpa_ssid_txt(elems
->ssid
, elems
->ssid_len
),
151 MAC2STR(bss
->bssid
));
152 os_memcpy(bss
->ssid
, elems
->ssid
, elems
->ssid_len
);
153 bss
->ssid_len
= elems
->ssid_len
;
154 bss_add_pmk(wt
, bss
);
157 if (elems
->osen
== NULL
) {
158 if (bss
->osenie
[0]) {
159 add_note(wt
, MSG_INFO
, "BSS " MACSTR
160 " - OSEN IE removed", MAC2STR(bss
->bssid
));
165 if (bss
->osenie
[0] == 0 ||
166 os_memcmp(bss
->osenie
, elems
->osen
- 2,
167 elems
->osen_len
+ 2) != 0) {
168 wpa_printf(MSG_INFO
, "BSS " MACSTR
" - OSEN IE "
169 "stored", MAC2STR(bss
->bssid
));
170 wpa_hexdump(MSG_DEBUG
, "OSEN IE", elems
->osen
- 2,
171 elems
->osen_len
+ 2);
174 os_memcpy(bss
->osenie
, elems
->osen
- 2,
175 elems
->osen_len
+ 2);
178 if (elems
->rsn_ie
== NULL
) {
180 add_note(wt
, MSG_INFO
, "BSS " MACSTR
181 " - RSN IE removed", MAC2STR(bss
->bssid
));
186 if (bss
->rsnie
[0] == 0 ||
187 os_memcmp(bss
->rsnie
, elems
->rsn_ie
- 2,
188 elems
->rsn_ie_len
+ 2) != 0) {
189 wpa_printf(MSG_INFO
, "BSS " MACSTR
" - RSN IE "
190 "stored", MAC2STR(bss
->bssid
));
191 wpa_hexdump(MSG_DEBUG
, "RSN IE", elems
->rsn_ie
- 2,
192 elems
->rsn_ie_len
+ 2);
195 os_memcpy(bss
->rsnie
, elems
->rsn_ie
- 2,
196 elems
->rsn_ie_len
+ 2);
199 if (elems
->wpa_ie
== NULL
) {
201 add_note(wt
, MSG_INFO
, "BSS " MACSTR
202 " - WPA IE removed", MAC2STR(bss
->bssid
));
207 if (bss
->wpaie
[0] == 0 ||
208 os_memcmp(bss
->wpaie
, elems
->wpa_ie
- 2,
209 elems
->wpa_ie_len
+ 2) != 0) {
210 wpa_printf(MSG_INFO
, "BSS " MACSTR
" - WPA IE "
211 "stored", MAC2STR(bss
->bssid
));
212 wpa_hexdump(MSG_DEBUG
, "WPA IE", elems
->wpa_ie
- 2,
213 elems
->wpa_ie_len
+ 2);
216 os_memcpy(bss
->wpaie
, elems
->wpa_ie
- 2,
217 elems
->wpa_ie_len
+ 2);
221 os_memcpy(bss
->mdid
, elems
->mdie
, 2);
226 bss
->prev_capab_info
= bss
->capab_info
;
228 bss
->pairwise_cipher
= 0;
229 bss
->group_cipher
= 0;
232 bss
->mgmt_group_cipher
= 0;
235 if (wpa_parse_wpa_ie_wpa(bss
->wpaie
, 2 + bss
->wpaie
[1], &data
)
237 add_note(wt
, MSG_INFO
, "Failed to parse WPA IE from "
238 MACSTR
, MAC2STR(bss
->bssid
));
240 bss
->proto
|= data
.proto
;
241 bss
->pairwise_cipher
|= data
.pairwise_cipher
;
242 bss
->group_cipher
|= data
.group_cipher
;
243 bss
->key_mgmt
|= data
.key_mgmt
;
244 bss
->rsn_capab
= data
.capabilities
;
245 bss
->mgmt_group_cipher
|= data
.mgmt_group_cipher
;
250 if (wpa_parse_wpa_ie_rsn(bss
->rsnie
, 2 + bss
->rsnie
[1], &data
)
252 add_note(wt
, MSG_INFO
, "Failed to parse RSN IE from "
253 MACSTR
, MAC2STR(bss
->bssid
));
255 bss
->proto
|= data
.proto
;
256 bss
->pairwise_cipher
|= data
.pairwise_cipher
;
257 bss
->group_cipher
|= data
.group_cipher
;
258 bss
->key_mgmt
|= data
.key_mgmt
;
259 bss
->rsn_capab
= data
.capabilities
;
260 bss
->mgmt_group_cipher
|= data
.mgmt_group_cipher
;
264 if (bss
->osenie
[0]) {
265 bss
->proto
|= WPA_PROTO_OSEN
;
266 bss
->pairwise_cipher
|= WPA_CIPHER_CCMP
;
267 bss
->group_cipher
|= WPA_CIPHER_CCMP
;
268 bss
->key_mgmt
|= WPA_KEY_MGMT_OSEN
;
271 if (!(bss
->proto
& WPA_PROTO_RSN
) ||
272 !(bss
->rsn_capab
& WPA_CAPABILITY_MFPC
))
273 bss
->mgmt_group_cipher
= 0;
275 if (!bss
->wpaie
[0] && !bss
->rsnie
[0] && !bss
->osenie
[0] &&
276 (bss
->capab_info
& WLAN_CAPABILITY_PRIVACY
))
277 bss
->group_cipher
= WPA_CIPHER_WEP40
;
279 wpa_printf(MSG_INFO
, "BSS " MACSTR
281 "pairwise=%s%s%s%s%s%s%s"
282 "group=%s%s%s%s%s%s%s%s%s"
283 "mgmt_group_cipher=%s%s%s%s%s"
284 "key_mgmt=%s%s%s%s%s%s%s%s%s"
285 "rsn_capab=%s%s%s%s%s",
287 bss
->proto
== 0 ? "OPEN " : "",
288 bss
->proto
& WPA_PROTO_WPA
? "WPA " : "",
289 bss
->proto
& WPA_PROTO_RSN
? "WPA2 " : "",
290 bss
->proto
& WPA_PROTO_OSEN
? "OSEN " : "",
291 bss
->pairwise_cipher
== 0 ? "N/A " : "",
292 bss
->pairwise_cipher
& WPA_CIPHER_NONE
? "NONE " : "",
293 bss
->pairwise_cipher
& WPA_CIPHER_TKIP
? "TKIP " : "",
294 bss
->pairwise_cipher
& WPA_CIPHER_CCMP
? "CCMP " : "",
295 bss
->pairwise_cipher
& WPA_CIPHER_CCMP_256
? "CCMP-256 " :
297 bss
->pairwise_cipher
& WPA_CIPHER_GCMP
? "GCMP " : "",
298 bss
->pairwise_cipher
& WPA_CIPHER_GCMP_256
? "GCMP-256 " :
300 bss
->group_cipher
== 0 ? "N/A " : "",
301 bss
->group_cipher
& WPA_CIPHER_NONE
? "NONE " : "",
302 bss
->group_cipher
& WPA_CIPHER_WEP40
? "WEP40 " : "",
303 bss
->group_cipher
& WPA_CIPHER_WEP104
? "WEP104 " : "",
304 bss
->group_cipher
& WPA_CIPHER_TKIP
? "TKIP " : "",
305 bss
->group_cipher
& WPA_CIPHER_CCMP
? "CCMP " : "",
306 bss
->group_cipher
& WPA_CIPHER_CCMP_256
? "CCMP-256 " : "",
307 bss
->group_cipher
& WPA_CIPHER_GCMP
? "GCMP " : "",
308 bss
->group_cipher
& WPA_CIPHER_GCMP_256
? "GCMP-256 " : "",
309 bss
->mgmt_group_cipher
== 0 ? "N/A " : "",
310 bss
->mgmt_group_cipher
& WPA_CIPHER_AES_128_CMAC
?
312 bss
->mgmt_group_cipher
& WPA_CIPHER_BIP_GMAC_128
?
313 "BIP-GMAC-128 " : "",
314 bss
->mgmt_group_cipher
& WPA_CIPHER_BIP_GMAC_256
?
315 "BIP-GMAC-256 " : "",
316 bss
->mgmt_group_cipher
& WPA_CIPHER_BIP_CMAC_256
?
317 "BIP-CMAC-256 " : "",
318 bss
->key_mgmt
== 0 ? "N/A " : "",
319 bss
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X
? "EAP " : "",
320 bss
->key_mgmt
& WPA_KEY_MGMT_PSK
? "PSK " : "",
321 bss
->key_mgmt
& WPA_KEY_MGMT_WPA_NONE
? "WPA-NONE " : "",
322 bss
->key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
? "FT-EAP " : "",
323 bss
->key_mgmt
& WPA_KEY_MGMT_FT_PSK
? "FT-PSK " : "",
324 bss
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
?
326 bss
->key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
?
328 bss
->key_mgmt
& WPA_KEY_MGMT_OSEN
? "OSEN " : "",
329 bss
->rsn_capab
& WPA_CAPABILITY_PREAUTH
? "PREAUTH " : "",
330 bss
->rsn_capab
& WPA_CAPABILITY_NO_PAIRWISE
?
332 bss
->rsn_capab
& WPA_CAPABILITY_MFPR
? "MFPR " : "",
333 bss
->rsn_capab
& WPA_CAPABILITY_MFPC
? "MFPC " : "",
334 bss
->rsn_capab
& WPA_CAPABILITY_PEERKEY_ENABLED
?
339 void bss_flush(struct wlantest
*wt
)
341 struct wlantest_bss
*bss
, *n
;
342 dl_list_for_each_safe(bss
, n
, &wt
->bss
, struct wlantest_bss
, list
)