1 /* 2 * BSS list 3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "utils/includes.h" 10 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" 16 #include "wlantest.h" 17 18 bss_find(struct wlantest * wt,const u8 * bssid)19 struct wlantest_bss * bss_find(struct wlantest *wt, const u8 *bssid) 20 { 21 struct wlantest_bss *bss; 22 23 dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) { 24 if (ether_addr_equal(bss->bssid, bssid)) 25 return bss; 26 } 27 28 return NULL; 29 } 30 31 bss_find_mld(struct wlantest * wt,const u8 * mld_mac_addr,int link_id)32 struct wlantest_bss * bss_find_mld(struct wlantest *wt, const u8 *mld_mac_addr, 33 int link_id) 34 { 35 struct wlantest_bss *bss; 36 37 dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) { 38 if (ether_addr_equal(bss->mld_mac_addr, mld_mac_addr) && 39 (link_id < 0 || 40 (bss->link_id_set && bss->link_id == link_id))) 41 return bss; 42 } 43 44 return NULL; 45 } 46 47 bss_get(struct wlantest * wt,const u8 * bssid)48 struct wlantest_bss * bss_get(struct wlantest *wt, const u8 *bssid) 49 { 50 struct wlantest_bss *bss; 51 52 if (bssid[0] & 0x01) 53 return NULL; /* Skip group addressed frames */ 54 55 bss = bss_find(wt, bssid); 56 if (bss) 57 return bss; 58 59 bss = os_zalloc(sizeof(*bss)); 60 if (bss == NULL) 61 return NULL; 62 dl_list_init(&bss->sta); 63 dl_list_init(&bss->pmk); 64 dl_list_init(&bss->tdls); 65 os_memcpy(bss->bssid, bssid, ETH_ALEN); 66 dl_list_add(&wt->bss, &bss->list); 67 wpa_printf(MSG_DEBUG, "Discovered new BSS - " MACSTR, 68 MAC2STR(bss->bssid)); 69 return bss; 70 } 71 72 pmk_deinit(struct wlantest_pmk * pmk)73 void pmk_deinit(struct wlantest_pmk *pmk) 74 { 75 dl_list_del(&pmk->list); 76 os_free(pmk); 77 } 78 79 tdls_deinit(struct wlantest_tdls * tdls)80 void tdls_deinit(struct wlantest_tdls *tdls) 81 { 82 dl_list_del(&tdls->list); 83 os_free(tdls); 84 } 85 86 bss_deinit(struct wlantest_bss * bss)87 void bss_deinit(struct wlantest_bss *bss) 88 { 89 struct wlantest_sta *sta, *n; 90 struct wlantest_pmk *pmk, *np; 91 struct wlantest_tdls *tdls, *nt; 92 dl_list_for_each_safe(sta, n, &bss->sta, struct wlantest_sta, list) 93 sta_deinit(sta); 94 dl_list_for_each_safe(pmk, np, &bss->pmk, struct wlantest_pmk, list) 95 pmk_deinit(pmk); 96 dl_list_for_each_safe(tdls, nt, &bss->tdls, struct wlantest_tdls, list) 97 tdls_deinit(tdls); 98 dl_list_del(&bss->list); 99 os_free(bss); 100 } 101 102 bss_add_pmk_from_passphrase(struct wlantest_bss * bss,const char * passphrase)103 int bss_add_pmk_from_passphrase(struct wlantest_bss *bss, 104 const char *passphrase) 105 { 106 struct wlantest_pmk *pmk; 107 108 pmk = os_zalloc(sizeof(*pmk)); 109 if (pmk == NULL) 110 return -1; 111 if (pbkdf2_sha1(passphrase, bss->ssid, bss->ssid_len, 4096, 112 pmk->pmk, PMK_LEN) < 0) { 113 os_free(pmk); 114 return -1; 115 } 116 117 wpa_printf(MSG_INFO, "Add possible PMK for BSSID " MACSTR 118 " based on passphrase '%s'", 119 MAC2STR(bss->bssid), passphrase); 120 wpa_hexdump(MSG_DEBUG, "Possible PMK", pmk->pmk, PMK_LEN); 121 pmk->pmk_len = PMK_LEN; 122 dl_list_add(&bss->pmk, &pmk->list); 123 124 return 0; 125 } 126 127 bss_add_pmk(struct wlantest * wt,struct wlantest_bss * bss)128 static void bss_add_pmk(struct wlantest *wt, struct wlantest_bss *bss) 129 { 130 struct wlantest_passphrase *p; 131 132 dl_list_for_each(p, &wt->passphrase, struct wlantest_passphrase, list) 133 { 134 if (!is_zero_ether_addr(p->bssid) && 135 !ether_addr_equal(p->bssid, bss->bssid)) 136 continue; 137 if (p->ssid_len && 138 (p->ssid_len != bss->ssid_len || 139 os_memcmp(p->ssid, bss->ssid, p->ssid_len) != 0)) 140 continue; 141 142 if (bss_add_pmk_from_passphrase(bss, p->passphrase) < 0) 143 break; 144 } 145 } 146 147 bss_update(struct wlantest * wt,struct wlantest_bss * bss,struct ieee802_11_elems * elems,int beacon)148 void bss_update(struct wlantest *wt, struct wlantest_bss *bss, 149 struct ieee802_11_elems *elems, int beacon) 150 { 151 struct wpa_ie_data data; 152 int update = 0; 153 154 if (bss->capab_info != bss->prev_capab_info) 155 update = 1; 156 157 if (beacon && (!elems->ssid || elems->ssid_len > 32)) { 158 wpa_printf(MSG_INFO, 159 "Invalid or missing SSID in a %s frame for " MACSTR, 160 beacon == 1 ? "Beacon" : "Probe Response", 161 MAC2STR(bss->bssid)); 162 bss->parse_error_reported = 1; 163 return; 164 } 165 166 if (beacon && 167 (bss->ssid_len != elems->ssid_len || 168 os_memcmp(bss->ssid, elems->ssid, bss->ssid_len) != 0)) { 169 wpa_printf(MSG_DEBUG, "Store SSID '%s' for BSSID " MACSTR, 170 wpa_ssid_txt(elems->ssid, elems->ssid_len), 171 MAC2STR(bss->bssid)); 172 os_memcpy(bss->ssid, elems->ssid, elems->ssid_len); 173 bss->ssid_len = elems->ssid_len; 174 bss_add_pmk(wt, bss); 175 } 176 177 /* S1G does not include RSNE in beacon, so only clear it from 178 * Probe Response frames. Note this assumes short beacons were dropped 179 * due to missing SSID above. 180 */ 181 if (!elems->rsn_ie && (!elems->s1g_capab || beacon != 1)) { 182 if (bss->rsnie[0]) { 183 add_note(wt, MSG_INFO, "BSS " MACSTR 184 " - RSN IE removed", MAC2STR(bss->bssid)); 185 bss->rsnie[0] = 0; 186 update = 1; 187 } 188 } else if (elems->rsn_ie) { 189 if (bss->rsnie[0] == 0 || 190 os_memcmp(bss->rsnie, elems->rsn_ie - 2, 191 elems->rsn_ie_len + 2) != 0) { 192 wpa_printf(MSG_INFO, "BSS " MACSTR " - RSN IE " 193 "stored", MAC2STR(bss->bssid)); 194 wpa_hexdump(MSG_DEBUG, "RSN IE", elems->rsn_ie - 2, 195 elems->rsn_ie_len + 2); 196 update = 1; 197 } 198 os_memcpy(bss->rsnie, elems->rsn_ie - 2, 199 elems->rsn_ie_len + 2); 200 } 201 202 if (elems->wpa_ie == NULL) { 203 if (bss->wpaie[0]) { 204 add_note(wt, MSG_INFO, "BSS " MACSTR 205 " - WPA IE removed", MAC2STR(bss->bssid)); 206 bss->wpaie[0] = 0; 207 update = 1; 208 } 209 } else { 210 if (bss->wpaie[0] == 0 || 211 os_memcmp(bss->wpaie, elems->wpa_ie - 2, 212 elems->wpa_ie_len + 2) != 0) { 213 wpa_printf(MSG_INFO, "BSS " MACSTR " - WPA IE " 214 "stored", MAC2STR(bss->bssid)); 215 wpa_hexdump(MSG_DEBUG, "WPA IE", elems->wpa_ie - 2, 216 elems->wpa_ie_len + 2); 217 update = 1; 218 } 219 os_memcpy(bss->wpaie, elems->wpa_ie - 2, 220 elems->wpa_ie_len + 2); 221 } 222 223 if (elems->mdie) 224 os_memcpy(bss->mdid, elems->mdie, 2); 225 226 bss->mesh = elems->mesh_id != NULL; 227 228 if (is_zero_ether_addr(bss->mld_mac_addr) && 229 elems->basic_mle && elems->basic_mle_len >= 2 + 1 + ETH_ALEN && 230 elems->basic_mle[2] >= 1 + ETH_ALEN) { 231 os_memcpy(bss->mld_mac_addr, &elems->basic_mle[2 + 1], 232 ETH_ALEN); 233 wpa_printf(MSG_DEBUG, 234 "Learned AP MLD MAC Address from Beacon/Probe Response frame: " 235 MACSTR " (BSSID " MACSTR ")", 236 MAC2STR(bss->mld_mac_addr), MAC2STR(bss->bssid)); 237 } 238 239 if (!bss->link_id_set && 240 elems->basic_mle && elems->basic_mle_len >= 2 + 1 + ETH_ALEN + 1 && 241 elems->basic_mle[2] >= 1 + ETH_ALEN + 1 && 242 (WPA_GET_LE16(elems->basic_mle) & 243 BASIC_MULTI_LINK_CTRL_PRES_LINK_ID)) { 244 bss->link_id = elems->basic_mle[2 + 1 + ETH_ALEN] & 0x0f; 245 wpa_printf(MSG_DEBUG, 246 "Learned AP MLD Link ID %u for this affiliated link", 247 bss->link_id); 248 bss->link_id_set = true; 249 } 250 251 if (!update) 252 return; 253 254 if (beacon == 1) 255 bss->beacon_seen = 1; 256 else if (beacon == 2) 257 bss->proberesp_seen = 1; 258 bss->ies_set = 1; 259 bss->prev_capab_info = bss->capab_info; 260 bss->proto = 0; 261 bss->pairwise_cipher = 0; 262 bss->group_cipher = 0; 263 bss->key_mgmt = 0; 264 bss->rsn_capab = 0; 265 bss->mgmt_group_cipher = 0; 266 267 if (bss->wpaie[0]) { 268 if (wpa_parse_wpa_ie_wpa(bss->wpaie, 2 + bss->wpaie[1], &data) 269 < 0) { 270 add_note(wt, MSG_INFO, "Failed to parse WPA IE from " 271 MACSTR, MAC2STR(bss->bssid)); 272 } else { 273 bss->proto |= data.proto; 274 bss->pairwise_cipher |= data.pairwise_cipher; 275 bss->group_cipher |= data.group_cipher; 276 bss->key_mgmt |= data.key_mgmt; 277 bss->rsn_capab = data.capabilities; 278 bss->mgmt_group_cipher |= data.mgmt_group_cipher; 279 } 280 } 281 282 if (bss->rsnie[0]) { 283 if (wpa_parse_wpa_ie_rsn(bss->rsnie, 2 + bss->rsnie[1], &data) 284 < 0) { 285 add_note(wt, MSG_INFO, "Failed to parse RSN IE from " 286 MACSTR, MAC2STR(bss->bssid)); 287 } else { 288 bss->proto |= data.proto; 289 bss->pairwise_cipher |= data.pairwise_cipher; 290 bss->group_cipher |= data.group_cipher; 291 bss->key_mgmt |= data.key_mgmt; 292 bss->rsn_capab = data.capabilities; 293 bss->mgmt_group_cipher |= data.mgmt_group_cipher; 294 } 295 } 296 297 if (!(bss->proto & WPA_PROTO_RSN) || 298 !(bss->rsn_capab & WPA_CAPABILITY_MFPC)) 299 bss->mgmt_group_cipher = 0; 300 301 if (!bss->wpaie[0] && !bss->rsnie[0] && 302 (bss->capab_info & WLAN_CAPABILITY_PRIVACY)) 303 bss->group_cipher = WPA_CIPHER_WEP40; 304 305 wpa_printf(MSG_INFO, "BSS " MACSTR 306 " proto=%s%s%s" 307 "pairwise=%s%s%s%s%s%s%s" 308 "group=%s%s%s%s%s%s%s%s%s" 309 "mgmt_group_cipher=%s%s%s%s%s" 310 "key_mgmt=%s%s%s%s%s%s%s%s%s%s%s%s%s%s" 311 "rsn_capab=%s%s%s%s%s%s%s%s%s%s", 312 MAC2STR(bss->bssid), 313 bss->proto == 0 ? "OPEN " : "", 314 bss->proto & WPA_PROTO_WPA ? "WPA " : "", 315 bss->proto & WPA_PROTO_RSN ? "WPA2 " : "", 316 bss->pairwise_cipher == 0 ? "N/A " : "", 317 bss->pairwise_cipher & WPA_CIPHER_NONE ? "NONE " : "", 318 bss->pairwise_cipher & WPA_CIPHER_TKIP ? "TKIP " : "", 319 bss->pairwise_cipher & WPA_CIPHER_CCMP ? "CCMP " : "", 320 bss->pairwise_cipher & WPA_CIPHER_CCMP_256 ? "CCMP-256 " : 321 "", 322 bss->pairwise_cipher & WPA_CIPHER_GCMP ? "GCMP " : "", 323 bss->pairwise_cipher & WPA_CIPHER_GCMP_256 ? "GCMP-256 " : 324 "", 325 bss->group_cipher == 0 ? "N/A " : "", 326 bss->group_cipher & WPA_CIPHER_NONE ? "NONE " : "", 327 bss->group_cipher & WPA_CIPHER_WEP40 ? "WEP40 " : "", 328 bss->group_cipher & WPA_CIPHER_WEP104 ? "WEP104 " : "", 329 bss->group_cipher & WPA_CIPHER_TKIP ? "TKIP " : "", 330 bss->group_cipher & WPA_CIPHER_CCMP ? "CCMP " : "", 331 bss->group_cipher & WPA_CIPHER_CCMP_256 ? "CCMP-256 " : "", 332 bss->group_cipher & WPA_CIPHER_GCMP ? "GCMP " : "", 333 bss->group_cipher & WPA_CIPHER_GCMP_256 ? "GCMP-256 " : "", 334 bss->mgmt_group_cipher == 0 ? "N/A " : "", 335 bss->mgmt_group_cipher & WPA_CIPHER_AES_128_CMAC ? 336 "BIP " : "", 337 bss->mgmt_group_cipher & WPA_CIPHER_BIP_GMAC_128 ? 338 "BIP-GMAC-128 " : "", 339 bss->mgmt_group_cipher & WPA_CIPHER_BIP_GMAC_256 ? 340 "BIP-GMAC-256 " : "", 341 bss->mgmt_group_cipher & WPA_CIPHER_BIP_CMAC_256 ? 342 "BIP-CMAC-256 " : "", 343 bss->key_mgmt == 0 ? "N/A " : "", 344 bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X ? "EAP " : "", 345 bss->key_mgmt & WPA_KEY_MGMT_PSK ? "PSK " : "", 346 bss->key_mgmt & WPA_KEY_MGMT_WPA_NONE ? "WPA-NONE " : "", 347 bss->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X ? "FT-EAP " : "", 348 bss->key_mgmt & WPA_KEY_MGMT_FT_PSK ? "FT-PSK " : "", 349 bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256 ? 350 "EAP-SHA256 " : "", 351 bss->key_mgmt & WPA_KEY_MGMT_PSK_SHA256 ? 352 "PSK-SHA256 " : "", 353 bss->key_mgmt & WPA_KEY_MGMT_OWE ? "OWE " : "", 354 bss->key_mgmt & WPA_KEY_MGMT_PASN ? "PASN " : "", 355 bss->key_mgmt & WPA_KEY_MGMT_DPP ? "DPP " : "", 356 bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B ? 357 "EAP-SUITE-B " : "", 358 bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 ? 359 "EAP-SUITE-B-192 " : "", 360 bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA384 ? 361 "EAP-SHA384 " : "", 362 bss->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "", 363 bss->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ? 364 "NO_PAIRWISE " : "", 365 bss->rsn_capab & WPA_CAPABILITY_MFPR ? "MFPR " : "", 366 bss->rsn_capab & WPA_CAPABILITY_MFPC ? "MFPC " : "", 367 bss->rsn_capab & WPA_CAPABILITY_PEERKEY_ENABLED ? 368 "PEERKEY " : "", 369 bss->rsn_capab & WPA_CAPABILITY_SPP_A_MSDU_CAPABLE ? 370 "SPP-A-MSDU-CAPAB " : "", 371 bss->rsn_capab & WPA_CAPABILITY_SPP_A_MSDU_REQUIRED ? 372 "SPP-A-MSDU-REQUIRED " : "", 373 bss->rsn_capab & WPA_CAPABILITY_PBAC ? "PBAC " : "", 374 bss->rsn_capab & WPA_CAPABILITY_OCVC ? "OCVC " : "", 375 bss->rsn_capab & WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST ? 376 "ExtKeyID " : ""); 377 } 378 379 bss_flush(struct wlantest * wt)380 void bss_flush(struct wlantest *wt) 381 { 382 struct wlantest_bss *bss, *n; 383 dl_list_for_each_safe(bss, n, &wt->bss, struct wlantest_bss, list) 384 bss_deinit(bss); 385 } 386