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