139beb93cSSam Leffler /* 239beb93cSSam Leffler * wpa_supplicant - Temporary BSSID blacklist 339beb93cSSam Leffler * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 439beb93cSSam Leffler * 5*f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6*f05cddf9SRui Paulo * See README for more details. 739beb93cSSam Leffler */ 839beb93cSSam Leffler 939beb93cSSam Leffler #include "includes.h" 1039beb93cSSam Leffler 1139beb93cSSam Leffler #include "common.h" 1239beb93cSSam Leffler #include "wpa_supplicant_i.h" 1339beb93cSSam Leffler #include "blacklist.h" 1439beb93cSSam Leffler 1539beb93cSSam Leffler /** 1639beb93cSSam Leffler * wpa_blacklist_get - Get the blacklist entry for a BSSID 1739beb93cSSam Leffler * @wpa_s: Pointer to wpa_supplicant data 1839beb93cSSam Leffler * @bssid: BSSID 1939beb93cSSam Leffler * Returns: Matching blacklist entry for the BSSID or %NULL if not found 2039beb93cSSam Leffler */ 2139beb93cSSam Leffler struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s, 2239beb93cSSam Leffler const u8 *bssid) 2339beb93cSSam Leffler { 2439beb93cSSam Leffler struct wpa_blacklist *e; 2539beb93cSSam Leffler 26*f05cddf9SRui Paulo if (wpa_s == NULL || bssid == NULL) 27*f05cddf9SRui Paulo return NULL; 28*f05cddf9SRui Paulo 2939beb93cSSam Leffler e = wpa_s->blacklist; 3039beb93cSSam Leffler while (e) { 3139beb93cSSam Leffler if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) 3239beb93cSSam Leffler return e; 3339beb93cSSam Leffler e = e->next; 3439beb93cSSam Leffler } 3539beb93cSSam Leffler 3639beb93cSSam Leffler return NULL; 3739beb93cSSam Leffler } 3839beb93cSSam Leffler 3939beb93cSSam Leffler 4039beb93cSSam Leffler /** 4139beb93cSSam Leffler * wpa_blacklist_add - Add an BSSID to the blacklist 4239beb93cSSam Leffler * @wpa_s: Pointer to wpa_supplicant data 4339beb93cSSam Leffler * @bssid: BSSID to be added to the blacklist 44*f05cddf9SRui Paulo * Returns: Current blacklist count on success, -1 on failure 4539beb93cSSam Leffler * 4639beb93cSSam Leffler * This function adds the specified BSSID to the blacklist or increases the 4739beb93cSSam Leffler * blacklist count if the BSSID was already listed. It should be called when 4839beb93cSSam Leffler * an association attempt fails either due to the selected BSS rejecting 4939beb93cSSam Leffler * association or due to timeout. 5039beb93cSSam Leffler * 5139beb93cSSam Leffler * This blacklist is used to force %wpa_supplicant to go through all available 5239beb93cSSam Leffler * BSSes before retrying to associate with an BSS that rejected or timed out 5339beb93cSSam Leffler * association. It does not prevent the listed BSS from being used; it only 5439beb93cSSam Leffler * changes the order in which they are tried. 5539beb93cSSam Leffler */ 5639beb93cSSam Leffler int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid) 5739beb93cSSam Leffler { 5839beb93cSSam Leffler struct wpa_blacklist *e; 5939beb93cSSam Leffler 60*f05cddf9SRui Paulo if (wpa_s == NULL || bssid == NULL) 61*f05cddf9SRui Paulo return -1; 62*f05cddf9SRui Paulo 6339beb93cSSam Leffler e = wpa_blacklist_get(wpa_s, bssid); 6439beb93cSSam Leffler if (e) { 6539beb93cSSam Leffler e->count++; 6639beb93cSSam Leffler wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count " 6739beb93cSSam Leffler "incremented to %d", 6839beb93cSSam Leffler MAC2STR(bssid), e->count); 69*f05cddf9SRui Paulo return e->count; 7039beb93cSSam Leffler } 7139beb93cSSam Leffler 7239beb93cSSam Leffler e = os_zalloc(sizeof(*e)); 7339beb93cSSam Leffler if (e == NULL) 7439beb93cSSam Leffler return -1; 7539beb93cSSam Leffler os_memcpy(e->bssid, bssid, ETH_ALEN); 7639beb93cSSam Leffler e->count = 1; 7739beb93cSSam Leffler e->next = wpa_s->blacklist; 7839beb93cSSam Leffler wpa_s->blacklist = e; 7939beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist", 8039beb93cSSam Leffler MAC2STR(bssid)); 8139beb93cSSam Leffler 82*f05cddf9SRui Paulo return e->count; 8339beb93cSSam Leffler } 8439beb93cSSam Leffler 8539beb93cSSam Leffler 8639beb93cSSam Leffler /** 8739beb93cSSam Leffler * wpa_blacklist_del - Remove an BSSID from the blacklist 8839beb93cSSam Leffler * @wpa_s: Pointer to wpa_supplicant data 8939beb93cSSam Leffler * @bssid: BSSID to be removed from the blacklist 9039beb93cSSam Leffler * Returns: 0 on success, -1 on failure 9139beb93cSSam Leffler */ 9239beb93cSSam Leffler int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid) 9339beb93cSSam Leffler { 9439beb93cSSam Leffler struct wpa_blacklist *e, *prev = NULL; 9539beb93cSSam Leffler 96*f05cddf9SRui Paulo if (wpa_s == NULL || bssid == NULL) 97*f05cddf9SRui Paulo return -1; 98*f05cddf9SRui Paulo 9939beb93cSSam Leffler e = wpa_s->blacklist; 10039beb93cSSam Leffler while (e) { 10139beb93cSSam Leffler if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) { 10239beb93cSSam Leffler if (prev == NULL) { 10339beb93cSSam Leffler wpa_s->blacklist = e->next; 10439beb93cSSam Leffler } else { 10539beb93cSSam Leffler prev->next = e->next; 10639beb93cSSam Leffler } 10739beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from " 10839beb93cSSam Leffler "blacklist", MAC2STR(bssid)); 10939beb93cSSam Leffler os_free(e); 11039beb93cSSam Leffler return 0; 11139beb93cSSam Leffler } 11239beb93cSSam Leffler prev = e; 11339beb93cSSam Leffler e = e->next; 11439beb93cSSam Leffler } 11539beb93cSSam Leffler return -1; 11639beb93cSSam Leffler } 11739beb93cSSam Leffler 11839beb93cSSam Leffler 11939beb93cSSam Leffler /** 12039beb93cSSam Leffler * wpa_blacklist_clear - Clear the blacklist of all entries 12139beb93cSSam Leffler * @wpa_s: Pointer to wpa_supplicant data 12239beb93cSSam Leffler */ 12339beb93cSSam Leffler void wpa_blacklist_clear(struct wpa_supplicant *wpa_s) 12439beb93cSSam Leffler { 12539beb93cSSam Leffler struct wpa_blacklist *e, *prev; 126*f05cddf9SRui Paulo int max_count = 0; 12739beb93cSSam Leffler 12839beb93cSSam Leffler e = wpa_s->blacklist; 12939beb93cSSam Leffler wpa_s->blacklist = NULL; 13039beb93cSSam Leffler while (e) { 131*f05cddf9SRui Paulo if (e->count > max_count) 132*f05cddf9SRui Paulo max_count = e->count; 13339beb93cSSam Leffler prev = e; 13439beb93cSSam Leffler e = e->next; 13539beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from " 13639beb93cSSam Leffler "blacklist (clear)", MAC2STR(prev->bssid)); 13739beb93cSSam Leffler os_free(prev); 13839beb93cSSam Leffler } 139*f05cddf9SRui Paulo 140*f05cddf9SRui Paulo wpa_s->extra_blacklist_count += max_count; 14139beb93cSSam Leffler } 142