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
);
158 if (elems
->rsn_ie
== NULL
) {
160 add_note(wt
, MSG_INFO
, "BSS " MACSTR
161 " - RSN IE removed", MAC2STR(bss
->bssid
));
166 if (bss
->rsnie
[0] == 0 ||
167 os_memcmp(bss
->rsnie
, elems
->rsn_ie
- 2,
168 elems
->rsn_ie_len
+ 2) != 0) {
169 wpa_printf(MSG_INFO
, "BSS " MACSTR
" - RSN IE "
170 "stored", MAC2STR(bss
->bssid
));
171 wpa_hexdump(MSG_DEBUG
, "RSN IE", elems
->rsn_ie
- 2,
172 elems
->rsn_ie_len
+ 2);
175 os_memcpy(bss
->rsnie
, elems
->rsn_ie
- 2,
176 elems
->rsn_ie_len
+ 2);
179 if (elems
->wpa_ie
== NULL
) {
181 add_note(wt
, MSG_INFO
, "BSS " MACSTR
182 " - WPA IE removed", MAC2STR(bss
->bssid
));
187 if (bss
->wpaie
[0] == 0 ||
188 os_memcmp(bss
->wpaie
, elems
->wpa_ie
- 2,
189 elems
->wpa_ie_len
+ 2) != 0) {
190 wpa_printf(MSG_INFO
, "BSS " MACSTR
" - WPA IE "
191 "stored", MAC2STR(bss
->bssid
));
192 wpa_hexdump(MSG_DEBUG
, "WPA IE", elems
->wpa_ie
- 2,
193 elems
->wpa_ie_len
+ 2);
196 os_memcpy(bss
->wpaie
, elems
->wpa_ie
- 2,
197 elems
->wpa_ie_len
+ 2);
203 bss
->prev_capab_info
= bss
->capab_info
;
205 bss
->pairwise_cipher
= 0;
206 bss
->group_cipher
= 0;
209 bss
->mgmt_group_cipher
= 0;
212 if (wpa_parse_wpa_ie_wpa(bss
->wpaie
, 2 + bss
->wpaie
[1], &data
)
214 add_note(wt
, MSG_INFO
, "Failed to parse WPA IE from "
215 MACSTR
, MAC2STR(bss
->bssid
));
217 bss
->proto
|= data
.proto
;
218 bss
->pairwise_cipher
|= data
.pairwise_cipher
;
219 bss
->group_cipher
|= data
.group_cipher
;
220 bss
->key_mgmt
|= data
.key_mgmt
;
221 bss
->rsn_capab
= data
.capabilities
;
222 bss
->mgmt_group_cipher
|= data
.mgmt_group_cipher
;
227 if (wpa_parse_wpa_ie_rsn(bss
->rsnie
, 2 + bss
->rsnie
[1], &data
)
229 add_note(wt
, MSG_INFO
, "Failed to parse RSN IE from "
230 MACSTR
, MAC2STR(bss
->bssid
));
232 bss
->proto
|= data
.proto
;
233 bss
->pairwise_cipher
|= data
.pairwise_cipher
;
234 bss
->group_cipher
|= data
.group_cipher
;
235 bss
->key_mgmt
|= data
.key_mgmt
;
236 bss
->rsn_capab
= data
.capabilities
;
237 bss
->mgmt_group_cipher
|= data
.mgmt_group_cipher
;
241 if (!(bss
->proto
& WPA_PROTO_RSN
) ||
242 !(bss
->rsn_capab
& WPA_CAPABILITY_MFPC
))
243 bss
->mgmt_group_cipher
= 0;
245 if (!bss
->wpaie
[0] && !bss
->rsnie
[0] &&
246 (bss
->capab_info
& WLAN_CAPABILITY_PRIVACY
))
247 bss
->group_cipher
= WPA_CIPHER_WEP40
;
249 wpa_printf(MSG_INFO
, "BSS " MACSTR
253 "mgmt_group_cipher=%s"
254 "key_mgmt=%s%s%s%s%s%s%s%s"
255 "rsn_capab=%s%s%s%s%s",
257 bss
->proto
== 0 ? "OPEN " : "",
258 bss
->proto
& WPA_PROTO_WPA
? "WPA " : "",
259 bss
->proto
& WPA_PROTO_RSN
? "WPA2 " : "",
260 bss
->pairwise_cipher
== 0 ? "N/A " : "",
261 bss
->pairwise_cipher
& WPA_CIPHER_NONE
? "NONE " : "",
262 bss
->pairwise_cipher
& WPA_CIPHER_TKIP
? "TKIP " : "",
263 bss
->pairwise_cipher
& WPA_CIPHER_CCMP
? "CCMP " : "",
264 bss
->group_cipher
== 0 ? "N/A " : "",
265 bss
->group_cipher
& WPA_CIPHER_NONE
? "NONE " : "",
266 bss
->group_cipher
& WPA_CIPHER_WEP40
? "WEP40 " : "",
267 bss
->group_cipher
& WPA_CIPHER_WEP104
? "WEP104 " : "",
268 bss
->group_cipher
& WPA_CIPHER_TKIP
? "TKIP " : "",
269 bss
->group_cipher
& WPA_CIPHER_CCMP
? "CCMP " : "",
270 bss
->mgmt_group_cipher
& WPA_CIPHER_AES_128_CMAC
? "BIP " :
272 bss
->key_mgmt
== 0 ? "N/A " : "",
273 bss
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X
? "EAP " : "",
274 bss
->key_mgmt
& WPA_KEY_MGMT_PSK
? "PSK " : "",
275 bss
->key_mgmt
& WPA_KEY_MGMT_WPA_NONE
? "WPA-NONE " : "",
276 bss
->key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
? "FT-EAP " : "",
277 bss
->key_mgmt
& WPA_KEY_MGMT_FT_PSK
? "FT-PSK " : "",
278 bss
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
?
280 bss
->key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
?
282 bss
->rsn_capab
& WPA_CAPABILITY_PREAUTH
? "PREAUTH " : "",
283 bss
->rsn_capab
& WPA_CAPABILITY_NO_PAIRWISE
?
285 bss
->rsn_capab
& WPA_CAPABILITY_MFPR
? "MFPR " : "",
286 bss
->rsn_capab
& WPA_CAPABILITY_MFPC
? "MFPC " : "",
287 bss
->rsn_capab
& WPA_CAPABILITY_PEERKEY_ENABLED
?
292 void bss_flush(struct wlantest
*wt
)
294 struct wlantest_bss
*bss
, *n
;
295 dl_list_for_each_safe(bss
, n
, &wt
->bss
, struct wlantest_bss
, list
)