static int wpas_blacklist_module_tests(void) { struct wpa_supplicant wpa_s; int ret = -1; os_memset(&wpa_s, 0, sizeof(wpa_s)); wpa_blacklist_clear(&wpa_s); if (wpa_blacklist_get(NULL, NULL) != NULL || wpa_blacklist_get(NULL, (u8 *) "123456") != NULL || wpa_blacklist_get(&wpa_s, NULL) != NULL || wpa_blacklist_get(&wpa_s, (u8 *) "123456") != NULL) goto fail; if (wpa_blacklist_add(NULL, NULL) == 0 || wpa_blacklist_add(NULL, (u8 *) "123456") == 0 || wpa_blacklist_add(&wpa_s, NULL) == 0) goto fail; if (wpa_blacklist_del(NULL, NULL) == 0 || wpa_blacklist_del(NULL, (u8 *) "123456") == 0 || wpa_blacklist_del(&wpa_s, NULL) == 0 || wpa_blacklist_del(&wpa_s, (u8 *) "123456") == 0) goto fail; if (wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "222222") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "333333") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "444444") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "333333") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "xxxxxx") == 0 || wpa_blacklist_get(&wpa_s, (u8 *) "xxxxxx") != NULL || wpa_blacklist_get(&wpa_s, (u8 *) "111111") == NULL || wpa_blacklist_get(&wpa_s, (u8 *) "222222") == NULL || wpa_blacklist_get(&wpa_s, (u8 *) "444444") == NULL || wpa_blacklist_del(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "222222") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "444444") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "222222") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "333333") < 0) goto fail; ret = 0; fail: wpa_blacklist_clear(&wpa_s); if (ret) wpa_printf(MSG_ERROR, "blacklist module test failure"); return ret; }
static struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res, struct wpa_ssid **selected_ssid) { struct wpa_bss *selected = NULL; int prio; while (selected == NULL) { for (prio = 0; prio < wpa_s->conf->num_prio; prio++) { selected = wpa_supplicant_select_bss( wpa_s, scan_res, wpa_s->conf->pssid[prio], selected_ssid); if (selected) break; } if (selected == NULL && wpa_s->blacklist) { wpa_printf(MSG_DEBUG, "No APs found - clear blacklist " "and try again"); wpa_blacklist_clear(wpa_s); wpa_s->blacklist_cleared++; } else if (selected == NULL) break; } return selected; }
static int wpa_supplicant_ctrl_iface_blacklist( struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) { struct wpa_ssid *ssid; u8 bssid[ETH_ALEN]; struct wpa_blacklist *e; char *pos, *end; int ret; /* cmd: "BLACKLIST [<BSSID>]" */ if (*cmd == '\0') { pos = buf; end = buf + buflen; e = wpa_s->blacklist; while (e) { ret = os_snprintf(pos, end-pos, "%02x:%02x:%02x:%02x:%02x:%02x\n", e->bssid[0], e->bssid[1], e->bssid[2], e->bssid[3], e->bssid[4], e->bssid[5]); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; e = e->next; } return pos - buf; } wpa_printf(MSG_DEBUG, "CTRL_IFACE: bssid='%s'", cmd); ++cmd; if (os_strncmp(cmd, "clear", 5) == 0) { wpa_blacklist_clear(wpa_s); return 0; } if (hwaddr_aton(cmd, bssid)) { wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", cmd); return -1; } /* * Add the BSSID twice, so its count will be 2, causing it to be * skipped when processing scan results. */ ret = wpa_blacklist_add(wpa_s, bssid); if (ret != 0) return ret; return wpa_blacklist_add(wpa_s, bssid); }
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s) { int prio, timeout; struct wpa_scan_res *selected = NULL; struct wpa_ssid *ssid = NULL; wpa_supplicant_notify_scanning(wpa_s, 0); if (wpa_supplicant_get_scan_results(wpa_s) < 0) { if (wpa_s->conf->ap_scan == 2) return; wpa_printf(MSG_DEBUG, "Failed to get scan results - try " "scanning again"); timeout = 1; goto req_scan; } /* * Don't post the results if this was the initial cached * and there were no results. */ if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1 && wpa_s->scan_res->num == 0) { wpa_msg(wpa_s, MSG_DEBUG, "Cached scan results are " "empty - not posting"); } else { wpa_printf(MSG_DEBUG, "New scan results available"); wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS); wpa_supplicant_dbus_notify_scan_results(wpa_s); wpas_wps_notify_scan_results(wpa_s); } if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s))) return; if (wpa_s->disconnected) { wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); return; } while (selected == NULL) { for (prio = 0; prio < wpa_s->conf->num_prio; prio++) { selected = wpa_supplicant_select_bss( wpa_s, wpa_s->conf->pssid[prio], &ssid); if (selected) break; } if (selected == NULL && wpa_s->blacklist) { wpa_printf(MSG_DEBUG, "No APs found - clear blacklist " "and try again"); wpa_blacklist_clear(wpa_s); wpa_s->blacklist_cleared++; } else if (selected == NULL) { break; } } if (selected) { if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) { wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP "PBC session overlap"); timeout = 10; goto req_scan; } /* Do not trigger new association unless the BSSID has changed * or if reassociation is requested. If we are in process of * associating with the selected BSSID, do not trigger new * attempt. */ if (wpa_s->reassociate || (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 && (wpa_s->wpa_state != WPA_ASSOCIATING || os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) != 0))) { if (wpa_supplicant_scard_init(wpa_s, ssid)) { wpa_supplicant_req_scan(wpa_s, 10, 0); return; } wpa_supplicant_associate(wpa_s, selected, ssid); } else { wpa_printf(MSG_DEBUG, "Already associated with the " "selected AP."); } rsn_preauth_scan_results(wpa_s->wpa, wpa_s->scan_res); } else { wpa_printf(MSG_DEBUG, "No suitable AP found."); timeout = 5; goto req_scan; } return; req_scan: if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) { /* * Quick recovery if the initial scan results were not * complete when fetched before the first scan request. */ wpa_s->scan_res_tried++; timeout = 0; } else if (!wpa_supplicant_enabled_networks(wpa_s->conf)) { /* * No networks are enabled; short-circuit request so * we don't wait timeout seconds before transitioning * to INACTIVE state. */ wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); return; } wpa_supplicant_req_scan(wpa_s, timeout, 0); }
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s) { int num, prio, timeout; struct wpa_scan_result *selected = NULL; struct wpa_ssid *ssid = NULL; struct wpa_scan_result *results; if (wpa_supplicant_get_scan_results(wpa_s) < 0) { if (wpa_s->conf->ap_scan == 2) return; wpa_printf(MSG_DEBUG, "Failed to get scan results - try " "scanning again"); timeout = 1; goto req_scan; } wpa_supplicant_dbus_notify_scan_results(wpa_s); if (wpa_s->conf->ap_scan == 2) return; results = wpa_s->scan_results; num = wpa_s->num_scan_results; while (selected == NULL) { for (prio = 0; prio < wpa_s->conf->num_prio; prio++) { selected = wpa_supplicant_select_bss( wpa_s, wpa_s->conf->pssid[prio], results, num, &ssid); if (selected) break; } if (selected == NULL && wpa_s->blacklist) { wpa_printf(MSG_DEBUG, "No APs found - clear blacklist " "and try again"); wpa_blacklist_clear(wpa_s); } else if (selected == NULL) { break; } } if (selected) { /* Do not trigger new association unless the BSSID has changed * or if reassociation is requested. If we are in process of * associating with the selected BSSID, do not trigger new * attempt. */ if (wpa_s->reassociate || (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 && (wpa_s->wpa_state != WPA_ASSOCIATING || os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) != 0))) { if (wpa_supplicant_scard_init(wpa_s, ssid)) { wpa_supplicant_req_scan(wpa_s, 10, 0); return; } wpa_supplicant_associate(wpa_s, selected, ssid); } else { wpa_printf(MSG_DEBUG, "Already associated with the " "selected AP."); } rsn_preauth_scan_results(wpa_s->wpa, results, num); } else { wpa_printf(MSG_DEBUG, "No suitable AP found."); timeout = 5; goto req_scan; } return; req_scan: if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) { /* * Quick recovery if the initial scan results were not * complete when fetched before the first scan request. */ wpa_s->scan_res_tried++; timeout = 0; } wpa_supplicant_req_scan(wpa_s, timeout, 0); }