bss.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. /*
  2. * BSS table
  3. * Copyright (c) 2009-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. #include "utils/includes.h"
  9. #include "utils/common.h"
  10. #include "utils/eloop.h"
  11. #include "common/ieee802_11_defs.h"
  12. #include "drivers/driver.h"
  13. #include "wpa_supplicant_i.h"
  14. #include "config.h"
  15. #include "notify.h"
  16. #include "scan.h"
  17. #include "bss.h"
  18. /**
  19. * WPA_BSS_EXPIRATION_PERIOD - Period of expiration run in seconds
  20. */
  21. #define WPA_BSS_EXPIRATION_PERIOD 10
  22. #define WPA_BSS_FREQ_CHANGED_FLAG BIT(0)
  23. #define WPA_BSS_SIGNAL_CHANGED_FLAG BIT(1)
  24. #define WPA_BSS_PRIVACY_CHANGED_FLAG BIT(2)
  25. #define WPA_BSS_MODE_CHANGED_FLAG BIT(3)
  26. #define WPA_BSS_WPAIE_CHANGED_FLAG BIT(4)
  27. #define WPA_BSS_RSNIE_CHANGED_FLAG BIT(5)
  28. #define WPA_BSS_WPS_CHANGED_FLAG BIT(6)
  29. #define WPA_BSS_RATES_CHANGED_FLAG BIT(7)
  30. #define WPA_BSS_IES_CHANGED_FLAG BIT(8)
  31. struct wpa_bss_anqp * wpa_bss_anqp_alloc(void)
  32. {
  33. struct wpa_bss_anqp *anqp;
  34. anqp = os_zalloc(sizeof(*anqp));
  35. if (anqp == NULL)
  36. return NULL;
  37. anqp->users = 1;
  38. return anqp;
  39. }
  40. static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp)
  41. {
  42. if (anqp == NULL)
  43. return;
  44. anqp->users--;
  45. if (anqp->users > 0) {
  46. /* Another BSS entry holds a pointer to this ANQP info */
  47. return;
  48. }
  49. #ifdef CONFIG_INTERWORKING
  50. wpabuf_free(anqp->venue_name);
  51. wpabuf_free(anqp->network_auth_type);
  52. wpabuf_free(anqp->roaming_consortium);
  53. wpabuf_free(anqp->ip_addr_type_availability);
  54. wpabuf_free(anqp->nai_realm);
  55. wpabuf_free(anqp->anqp_3gpp);
  56. wpabuf_free(anqp->domain_name);
  57. #endif /* CONFIG_INTERWORKING */
  58. #ifdef CONFIG_HS20
  59. wpabuf_free(anqp->hs20_operator_friendly_name);
  60. wpabuf_free(anqp->hs20_wan_metrics);
  61. wpabuf_free(anqp->hs20_connection_capability);
  62. wpabuf_free(anqp->hs20_operating_class);
  63. #endif /* CONFIG_HS20 */
  64. os_free(anqp);
  65. }
  66. static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
  67. const char *reason)
  68. {
  69. if (wpa_s->last_scan_res) {
  70. unsigned int i;
  71. for (i = 0; i < wpa_s->last_scan_res_used; i++) {
  72. if (wpa_s->last_scan_res[i] == bss) {
  73. os_memmove(&wpa_s->last_scan_res[i],
  74. &wpa_s->last_scan_res[i + 1],
  75. (wpa_s->last_scan_res_used - i - 1)
  76. * sizeof(struct wpa_bss *));
  77. wpa_s->last_scan_res_used--;
  78. break;
  79. }
  80. }
  81. }
  82. dl_list_del(&bss->list);
  83. dl_list_del(&bss->list_id);
  84. wpa_s->num_bss--;
  85. wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Remove id %u BSSID " MACSTR
  86. " SSID '%s' due to %s", bss->id, MAC2STR(bss->bssid),
  87. wpa_ssid_txt(bss->ssid, bss->ssid_len), reason);
  88. wpas_notify_bss_removed(wpa_s, bss->bssid, bss->id);
  89. wpa_bss_anqp_free(bss->anqp);
  90. os_free(bss);
  91. }
  92. struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid,
  93. const u8 *ssid, size_t ssid_len)
  94. {
  95. struct wpa_bss *bss;
  96. if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
  97. return NULL;
  98. dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
  99. if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
  100. bss->ssid_len == ssid_len &&
  101. os_memcmp(bss->ssid, ssid, ssid_len) == 0)
  102. return bss;
  103. }
  104. return NULL;
  105. }
  106. static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src)
  107. {
  108. os_time_t usec;
  109. dst->flags = src->flags;
  110. os_memcpy(dst->bssid, src->bssid, ETH_ALEN);
  111. dst->freq = src->freq;
  112. dst->beacon_int = src->beacon_int;
  113. dst->caps = src->caps;
  114. dst->qual = src->qual;
  115. dst->noise = src->noise;
  116. dst->level = src->level;
  117. dst->tsf = src->tsf;
  118. os_get_time(&dst->last_update);
  119. dst->last_update.sec -= src->age / 1000;
  120. usec = (src->age % 1000) * 1000;
  121. if (dst->last_update.usec < usec) {
  122. dst->last_update.sec--;
  123. dst->last_update.usec += 1000000;
  124. }
  125. dst->last_update.usec -= usec;
  126. }
  127. static int wpa_bss_known(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
  128. {
  129. struct wpa_ssid *ssid;
  130. for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
  131. if (ssid->ssid == NULL || ssid->ssid_len == 0)
  132. continue;
  133. if (ssid->ssid_len == bss->ssid_len &&
  134. os_memcmp(ssid->ssid, bss->ssid, ssid->ssid_len) == 0)
  135. return 1;
  136. }
  137. return 0;
  138. }
  139. static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
  140. {
  141. return bss == wpa_s->current_bss ||
  142. os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) == 0 ||
  143. os_memcmp(bss->bssid, wpa_s->pending_bssid, ETH_ALEN) == 0;
  144. }
  145. static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s)
  146. {
  147. struct wpa_bss *bss;
  148. dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
  149. if (!wpa_bss_known(wpa_s, bss)) {
  150. wpa_bss_remove(wpa_s, bss, __func__);
  151. return 0;
  152. }
  153. }
  154. return -1;
  155. }
  156. static int wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s)
  157. {
  158. struct wpa_bss *bss;
  159. /*
  160. * Remove the oldest entry that does not match with any configured
  161. * network.
  162. */
  163. if (wpa_bss_remove_oldest_unknown(wpa_s) == 0)
  164. return 0;
  165. /*
  166. * Remove the oldest entry that isn't currently in use.
  167. */
  168. dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
  169. if (!wpa_bss_in_use(wpa_s, bss)) {
  170. wpa_bss_remove(wpa_s, bss, __func__);
  171. return 0;
  172. }
  173. }
  174. return -1;
  175. }
  176. static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s,
  177. const u8 *ssid, size_t ssid_len,
  178. struct wpa_scan_res *res)
  179. {
  180. struct wpa_bss *bss;
  181. bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len);
  182. if (bss == NULL)
  183. return NULL;
  184. bss->id = wpa_s->bss_next_id++;
  185. bss->last_update_idx = wpa_s->bss_update_idx;
  186. wpa_bss_copy_res(bss, res);
  187. os_memcpy(bss->ssid, ssid, ssid_len);
  188. bss->ssid_len = ssid_len;
  189. bss->ie_len = res->ie_len;
  190. bss->beacon_ie_len = res->beacon_ie_len;
  191. os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len);
  192. dl_list_add_tail(&wpa_s->bss, &bss->list);
  193. dl_list_add_tail(&wpa_s->bss_id, &bss->list_id);
  194. wpa_s->num_bss++;
  195. wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Add new id %u BSSID " MACSTR
  196. " SSID '%s'",
  197. bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len));
  198. wpas_notify_bss_added(wpa_s, bss->bssid, bss->id);
  199. if (wpa_s->num_bss > wpa_s->conf->bss_max_count &&
  200. wpa_bss_remove_oldest(wpa_s) != 0) {
  201. wpa_printf(MSG_ERROR, "Increasing the MAX BSS count to %d "
  202. "because all BSSes are in use. We should normally "
  203. "not get here!", (int) wpa_s->num_bss);
  204. wpa_s->conf->bss_max_count = wpa_s->num_bss;
  205. }
  206. return bss;
  207. }
  208. static int are_ies_equal(const struct wpa_bss *old,
  209. const struct wpa_scan_res *new, u32 ie)
  210. {
  211. const u8 *old_ie, *new_ie;
  212. struct wpabuf *old_ie_buff = NULL;
  213. struct wpabuf *new_ie_buff = NULL;
  214. int new_ie_len, old_ie_len, ret, is_multi;
  215. switch (ie) {
  216. case WPA_IE_VENDOR_TYPE:
  217. old_ie = wpa_bss_get_vendor_ie(old, ie);
  218. new_ie = wpa_scan_get_vendor_ie(new, ie);
  219. is_multi = 0;
  220. break;
  221. case WPS_IE_VENDOR_TYPE:
  222. old_ie_buff = wpa_bss_get_vendor_ie_multi(old, ie);
  223. new_ie_buff = wpa_scan_get_vendor_ie_multi(new, ie);
  224. is_multi = 1;
  225. break;
  226. case WLAN_EID_RSN:
  227. case WLAN_EID_SUPP_RATES:
  228. case WLAN_EID_EXT_SUPP_RATES:
  229. old_ie = wpa_bss_get_ie(old, ie);
  230. new_ie = wpa_scan_get_ie(new, ie);
  231. is_multi = 0;
  232. break;
  233. default:
  234. wpa_printf(MSG_DEBUG, "bss: %s: cannot compare IEs", __func__);
  235. return 0;
  236. }
  237. if (is_multi) {
  238. /* in case of multiple IEs stored in buffer */
  239. old_ie = old_ie_buff ? wpabuf_head_u8(old_ie_buff) : NULL;
  240. new_ie = new_ie_buff ? wpabuf_head_u8(new_ie_buff) : NULL;
  241. old_ie_len = old_ie_buff ? wpabuf_len(old_ie_buff) : 0;
  242. new_ie_len = new_ie_buff ? wpabuf_len(new_ie_buff) : 0;
  243. } else {
  244. /* in case of single IE */
  245. old_ie_len = old_ie ? old_ie[1] + 2 : 0;
  246. new_ie_len = new_ie ? new_ie[1] + 2 : 0;
  247. }
  248. if (!old_ie || !new_ie)
  249. ret = !old_ie && !new_ie;
  250. else
  251. ret = (old_ie_len == new_ie_len &&
  252. os_memcmp(old_ie, new_ie, old_ie_len) == 0);
  253. wpabuf_free(old_ie_buff);
  254. wpabuf_free(new_ie_buff);
  255. return ret;
  256. }
  257. static u32 wpa_bss_compare_res(const struct wpa_bss *old,
  258. const struct wpa_scan_res *new)
  259. {
  260. u32 changes = 0;
  261. int caps_diff = old->caps ^ new->caps;
  262. if (old->freq != new->freq)
  263. changes |= WPA_BSS_FREQ_CHANGED_FLAG;
  264. if (old->level != new->level)
  265. changes |= WPA_BSS_SIGNAL_CHANGED_FLAG;
  266. if (caps_diff & IEEE80211_CAP_PRIVACY)
  267. changes |= WPA_BSS_PRIVACY_CHANGED_FLAG;
  268. if (caps_diff & IEEE80211_CAP_IBSS)
  269. changes |= WPA_BSS_MODE_CHANGED_FLAG;
  270. if (old->ie_len == new->ie_len &&
  271. os_memcmp(old + 1, new + 1, old->ie_len) == 0)
  272. return changes;
  273. changes |= WPA_BSS_IES_CHANGED_FLAG;
  274. if (!are_ies_equal(old, new, WPA_IE_VENDOR_TYPE))
  275. changes |= WPA_BSS_WPAIE_CHANGED_FLAG;
  276. if (!are_ies_equal(old, new, WLAN_EID_RSN))
  277. changes |= WPA_BSS_RSNIE_CHANGED_FLAG;
  278. if (!are_ies_equal(old, new, WPS_IE_VENDOR_TYPE))
  279. changes |= WPA_BSS_WPS_CHANGED_FLAG;
  280. if (!are_ies_equal(old, new, WLAN_EID_SUPP_RATES) ||
  281. !are_ies_equal(old, new, WLAN_EID_EXT_SUPP_RATES))
  282. changes |= WPA_BSS_RATES_CHANGED_FLAG;
  283. return changes;
  284. }
  285. static void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
  286. const struct wpa_bss *bss)
  287. {
  288. if (changes & WPA_BSS_FREQ_CHANGED_FLAG)
  289. wpas_notify_bss_freq_changed(wpa_s, bss->id);
  290. if (changes & WPA_BSS_SIGNAL_CHANGED_FLAG)
  291. wpas_notify_bss_signal_changed(wpa_s, bss->id);
  292. if (changes & WPA_BSS_PRIVACY_CHANGED_FLAG)
  293. wpas_notify_bss_privacy_changed(wpa_s, bss->id);
  294. if (changes & WPA_BSS_MODE_CHANGED_FLAG)
  295. wpas_notify_bss_mode_changed(wpa_s, bss->id);
  296. if (changes & WPA_BSS_WPAIE_CHANGED_FLAG)
  297. wpas_notify_bss_wpaie_changed(wpa_s, bss->id);
  298. if (changes & WPA_BSS_RSNIE_CHANGED_FLAG)
  299. wpas_notify_bss_rsnie_changed(wpa_s, bss->id);
  300. if (changes & WPA_BSS_WPS_CHANGED_FLAG)
  301. wpas_notify_bss_wps_changed(wpa_s, bss->id);
  302. if (changes & WPA_BSS_IES_CHANGED_FLAG)
  303. wpas_notify_bss_ies_changed(wpa_s, bss->id);
  304. if (changes & WPA_BSS_RATES_CHANGED_FLAG)
  305. wpas_notify_bss_rates_changed(wpa_s, bss->id);
  306. }
  307. static void wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
  308. struct wpa_scan_res *res)
  309. {
  310. u32 changes;
  311. changes = wpa_bss_compare_res(bss, res);
  312. bss->scan_miss_count = 0;
  313. bss->last_update_idx = wpa_s->bss_update_idx;
  314. wpa_bss_copy_res(bss, res);
  315. /* Move the entry to the end of the list */
  316. dl_list_del(&bss->list);
  317. if (bss->ie_len + bss->beacon_ie_len >=
  318. res->ie_len + res->beacon_ie_len) {
  319. os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len);
  320. bss->ie_len = res->ie_len;
  321. bss->beacon_ie_len = res->beacon_ie_len;
  322. } else {
  323. struct wpa_bss *nbss;
  324. struct dl_list *prev = bss->list_id.prev;
  325. dl_list_del(&bss->list_id);
  326. nbss = os_realloc(bss, sizeof(*bss) + res->ie_len +
  327. res->beacon_ie_len);
  328. if (nbss) {
  329. if (wpa_s->current_bss == bss)
  330. wpa_s->current_bss = nbss;
  331. bss = nbss;
  332. os_memcpy(bss + 1, res + 1,
  333. res->ie_len + res->beacon_ie_len);
  334. bss->ie_len = res->ie_len;
  335. bss->beacon_ie_len = res->beacon_ie_len;
  336. }
  337. dl_list_add(prev, &bss->list_id);
  338. }
  339. dl_list_add_tail(&wpa_s->bss, &bss->list);
  340. notify_bss_changes(wpa_s, changes, bss);
  341. }
  342. void wpa_bss_update_start(struct wpa_supplicant *wpa_s)
  343. {
  344. wpa_s->bss_update_idx++;
  345. wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Start scan result update %u",
  346. wpa_s->bss_update_idx);
  347. wpa_s->last_scan_res_used = 0;
  348. }
  349. void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
  350. struct wpa_scan_res *res)
  351. {
  352. const u8 *ssid, *p2p;
  353. struct wpa_bss *bss;
  354. ssid = wpa_scan_get_ie(res, WLAN_EID_SSID);
  355. if (ssid == NULL) {
  356. wpa_dbg(wpa_s, MSG_DEBUG, "BSS: No SSID IE included for "
  357. MACSTR, MAC2STR(res->bssid));
  358. return;
  359. }
  360. if (ssid[1] > 32) {
  361. wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Too long SSID IE included for "
  362. MACSTR, MAC2STR(res->bssid));
  363. return;
  364. }
  365. p2p = wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE);
  366. #ifdef CONFIG_P2P
  367. if (p2p == NULL &&
  368. wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
  369. /*
  370. * If it's a P2P specific interface, then don't update
  371. * the scan result without a P2P IE.
  372. */
  373. wpa_printf(MSG_DEBUG, "BSS: No P2P IE - skipping BSS " MACSTR
  374. " update for P2P interface", MAC2STR(res->bssid));
  375. return;
  376. }
  377. #endif /* CONFIG_P2P */
  378. if (p2p && ssid[1] == P2P_WILDCARD_SSID_LEN &&
  379. os_memcmp(ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 0)
  380. return; /* Skip P2P listen discovery results here */
  381. /* TODO: add option for ignoring BSSes we are not interested in
  382. * (to save memory) */
  383. bss = wpa_bss_get(wpa_s, res->bssid, ssid + 2, ssid[1]);
  384. if (bss == NULL)
  385. bss = wpa_bss_add(wpa_s, ssid + 2, ssid[1], res);
  386. else
  387. wpa_bss_update(wpa_s, bss, res);
  388. if (bss == NULL)
  389. return;
  390. if (wpa_s->last_scan_res_used >= wpa_s->last_scan_res_size) {
  391. struct wpa_bss **n;
  392. unsigned int siz;
  393. if (wpa_s->last_scan_res_size == 0)
  394. siz = 32;
  395. else
  396. siz = wpa_s->last_scan_res_size * 2;
  397. n = os_realloc_array(wpa_s->last_scan_res, siz,
  398. sizeof(struct wpa_bss *));
  399. if (n == NULL)
  400. return;
  401. wpa_s->last_scan_res = n;
  402. wpa_s->last_scan_res_size = siz;
  403. }
  404. wpa_s->last_scan_res[wpa_s->last_scan_res_used++] = bss;
  405. }
  406. static int wpa_bss_included_in_scan(const struct wpa_bss *bss,
  407. const struct scan_info *info)
  408. {
  409. int found;
  410. size_t i;
  411. if (info == NULL)
  412. return 1;
  413. if (info->num_freqs) {
  414. found = 0;
  415. for (i = 0; i < info->num_freqs; i++) {
  416. if (bss->freq == info->freqs[i]) {
  417. found = 1;
  418. break;
  419. }
  420. }
  421. if (!found)
  422. return 0;
  423. }
  424. if (info->num_ssids) {
  425. found = 0;
  426. for (i = 0; i < info->num_ssids; i++) {
  427. const struct wpa_driver_scan_ssid *s = &info->ssids[i];
  428. if ((s->ssid == NULL || s->ssid_len == 0) ||
  429. (s->ssid_len == bss->ssid_len &&
  430. os_memcmp(s->ssid, bss->ssid, bss->ssid_len) ==
  431. 0)) {
  432. found = 1;
  433. break;
  434. }
  435. }
  436. if (!found)
  437. return 0;
  438. }
  439. return 1;
  440. }
  441. void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
  442. int new_scan)
  443. {
  444. struct wpa_bss *bss, *n;
  445. wpa_s->last_scan_full = 0;
  446. os_get_time(&wpa_s->last_scan);
  447. if (!new_scan)
  448. return; /* do not expire entries without new scan */
  449. if (info && !info->aborted && !info->freqs) {
  450. size_t i;
  451. if (info->num_ssids == 0) {
  452. wpa_s->last_scan_full = 1;
  453. } else {
  454. for (i = 0; i < info->num_ssids; i++) {
  455. if (info->ssids[i].ssid == NULL ||
  456. info->ssids[i].ssid_len == 0) {
  457. wpa_s->last_scan_full = 1;
  458. break;
  459. }
  460. }
  461. }
  462. }
  463. dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
  464. if (wpa_bss_in_use(wpa_s, bss))
  465. continue;
  466. if (!wpa_bss_included_in_scan(bss, info))
  467. continue; /* expire only BSSes that were scanned */
  468. if (bss->last_update_idx < wpa_s->bss_update_idx)
  469. bss->scan_miss_count++;
  470. if (bss->scan_miss_count >=
  471. wpa_s->conf->bss_expiration_scan_count) {
  472. wpa_bss_remove(wpa_s, bss, "no match in scan");
  473. }
  474. }
  475. wpa_printf(MSG_DEBUG, "BSS: last_scan_res_used=%u/%u "
  476. "last_scan_full=%d",
  477. wpa_s->last_scan_res_used, wpa_s->last_scan_res_size,
  478. wpa_s->last_scan_full);
  479. }
  480. void wpa_bss_flush_by_age(struct wpa_supplicant *wpa_s, int age)
  481. {
  482. struct wpa_bss *bss, *n;
  483. struct os_time t;
  484. if (dl_list_empty(&wpa_s->bss))
  485. return;
  486. os_get_time(&t);
  487. t.sec -= age;
  488. dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
  489. if (wpa_bss_in_use(wpa_s, bss))
  490. continue;
  491. if (os_time_before(&bss->last_update, &t)) {
  492. wpa_bss_remove(wpa_s, bss, __func__);
  493. } else
  494. break;
  495. }
  496. }
  497. static void wpa_bss_timeout(void *eloop_ctx, void *timeout_ctx)
  498. {
  499. struct wpa_supplicant *wpa_s = eloop_ctx;
  500. wpa_bss_flush_by_age(wpa_s, wpa_s->conf->bss_expiration_age);
  501. eloop_register_timeout(WPA_BSS_EXPIRATION_PERIOD, 0,
  502. wpa_bss_timeout, wpa_s, NULL);
  503. }
  504. int wpa_bss_init(struct wpa_supplicant *wpa_s)
  505. {
  506. dl_list_init(&wpa_s->bss);
  507. dl_list_init(&wpa_s->bss_id);
  508. eloop_register_timeout(WPA_BSS_EXPIRATION_PERIOD, 0,
  509. wpa_bss_timeout, wpa_s, NULL);
  510. return 0;
  511. }
  512. void wpa_bss_flush(struct wpa_supplicant *wpa_s)
  513. {
  514. struct wpa_bss *bss, *n;
  515. if (wpa_s->bss.next == NULL)
  516. return; /* BSS table not yet initialized */
  517. dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
  518. if (wpa_bss_in_use(wpa_s, bss))
  519. continue;
  520. wpa_bss_remove(wpa_s, bss, __func__);
  521. }
  522. }
  523. void wpa_bss_deinit(struct wpa_supplicant *wpa_s)
  524. {
  525. eloop_cancel_timeout(wpa_bss_timeout, wpa_s, NULL);
  526. wpa_bss_flush(wpa_s);
  527. }
  528. struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s,
  529. const u8 *bssid)
  530. {
  531. struct wpa_bss *bss;
  532. if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
  533. return NULL;
  534. dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
  535. if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
  536. return bss;
  537. }
  538. return NULL;
  539. }
  540. #ifdef CONFIG_P2P
  541. struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s,
  542. const u8 *dev_addr)
  543. {
  544. struct wpa_bss *bss;
  545. dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
  546. u8 addr[ETH_ALEN];
  547. if (p2p_parse_dev_addr((const u8 *) (bss + 1), bss->ie_len,
  548. addr) == 0 &&
  549. os_memcmp(addr, dev_addr, ETH_ALEN) == 0)
  550. return bss;
  551. }
  552. return NULL;
  553. }
  554. #endif /* CONFIG_P2P */
  555. struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
  556. {
  557. struct wpa_bss *bss;
  558. dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
  559. if (bss->id == id)
  560. return bss;
  561. }
  562. return NULL;
  563. }
  564. const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie)
  565. {
  566. const u8 *end, *pos;
  567. pos = (const u8 *) (bss + 1);
  568. end = pos + bss->ie_len;
  569. while (pos + 1 < end) {
  570. if (pos + 2 + pos[1] > end)
  571. break;
  572. if (pos[0] == ie)
  573. return pos;
  574. pos += 2 + pos[1];
  575. }
  576. return NULL;
  577. }
  578. const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type)
  579. {
  580. const u8 *end, *pos;
  581. pos = (const u8 *) (bss + 1);
  582. end = pos + bss->ie_len;
  583. while (pos + 1 < end) {
  584. if (pos + 2 + pos[1] > end)
  585. break;
  586. if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
  587. vendor_type == WPA_GET_BE32(&pos[2]))
  588. return pos;
  589. pos += 2 + pos[1];
  590. }
  591. return NULL;
  592. }
  593. struct wpabuf * wpa_bss_get_vendor_ie_multi(const struct wpa_bss *bss,
  594. u32 vendor_type)
  595. {
  596. struct wpabuf *buf;
  597. const u8 *end, *pos;
  598. buf = wpabuf_alloc(bss->ie_len);
  599. if (buf == NULL)
  600. return NULL;
  601. pos = (const u8 *) (bss + 1);
  602. end = pos + bss->ie_len;
  603. while (pos + 1 < end) {
  604. if (pos + 2 + pos[1] > end)
  605. break;
  606. if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
  607. vendor_type == WPA_GET_BE32(&pos[2]))
  608. wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
  609. pos += 2 + pos[1];
  610. }
  611. if (wpabuf_len(buf) == 0) {
  612. wpabuf_free(buf);
  613. buf = NULL;
  614. }
  615. return buf;
  616. }
  617. struct wpabuf * wpa_bss_get_vendor_ie_multi_beacon(const struct wpa_bss *bss,
  618. u32 vendor_type)
  619. {
  620. struct wpabuf *buf;
  621. const u8 *end, *pos;
  622. buf = wpabuf_alloc(bss->beacon_ie_len);
  623. if (buf == NULL)
  624. return NULL;
  625. pos = (const u8 *) (bss + 1);
  626. pos += bss->ie_len;
  627. end = pos + bss->beacon_ie_len;
  628. while (pos + 1 < end) {
  629. if (pos + 2 + pos[1] > end)
  630. break;
  631. if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
  632. vendor_type == WPA_GET_BE32(&pos[2]))
  633. wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
  634. pos += 2 + pos[1];
  635. }
  636. if (wpabuf_len(buf) == 0) {
  637. wpabuf_free(buf);
  638. buf = NULL;
  639. }
  640. return buf;
  641. }
  642. int wpa_bss_get_max_rate(const struct wpa_bss *bss)
  643. {
  644. int rate = 0;
  645. const u8 *ie;
  646. int i;
  647. ie = wpa_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
  648. for (i = 0; ie && i < ie[1]; i++) {
  649. if ((ie[i + 2] & 0x7f) > rate)
  650. rate = ie[i + 2] & 0x7f;
  651. }
  652. ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
  653. for (i = 0; ie && i < ie[1]; i++) {
  654. if ((ie[i + 2] & 0x7f) > rate)
  655. rate = ie[i + 2] & 0x7f;
  656. }
  657. return rate;
  658. }
  659. int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates)
  660. {
  661. const u8 *ie, *ie2;
  662. int i, j;
  663. unsigned int len;
  664. u8 *r;
  665. ie = wpa_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
  666. ie2 = wpa_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
  667. len = (ie ? ie[1] : 0) + (ie2 ? ie2[1] : 0);
  668. r = os_malloc(len);
  669. if (!r)
  670. return -1;
  671. for (i = 0; ie && i < ie[1]; i++)
  672. r[i] = ie[i + 2] & 0x7f;
  673. for (j = 0; ie2 && j < ie2[1]; j++)
  674. r[i + j] = ie2[j + 2] & 0x7f;
  675. *rates = r;
  676. return len;
  677. }