1189251Ssam/* 2189251Ssam * wpa_supplicant - Temporary BSSID blacklist 3189251Ssam * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 4189251Ssam * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7189251Ssam */ 8189251Ssam 9189251Ssam#include "includes.h" 10189251Ssam 11189251Ssam#include "common.h" 12189251Ssam#include "wpa_supplicant_i.h" 13189251Ssam#include "blacklist.h" 14189251Ssam 15189251Ssam/** 16189251Ssam * wpa_blacklist_get - Get the blacklist entry for a BSSID 17189251Ssam * @wpa_s: Pointer to wpa_supplicant data 18189251Ssam * @bssid: BSSID 19189251Ssam * Returns: Matching blacklist entry for the BSSID or %NULL if not found 20189251Ssam */ 21189251Ssamstruct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s, 22189251Ssam const u8 *bssid) 23189251Ssam{ 24189251Ssam struct wpa_blacklist *e; 25189251Ssam 26252726Srpaulo if (wpa_s == NULL || bssid == NULL) 27252726Srpaulo return NULL; 28252726Srpaulo 29189251Ssam e = wpa_s->blacklist; 30189251Ssam while (e) { 31189251Ssam if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) 32189251Ssam return e; 33189251Ssam e = e->next; 34189251Ssam } 35189251Ssam 36189251Ssam return NULL; 37189251Ssam} 38189251Ssam 39189251Ssam 40189251Ssam/** 41189251Ssam * wpa_blacklist_add - Add an BSSID to the blacklist 42189251Ssam * @wpa_s: Pointer to wpa_supplicant data 43189251Ssam * @bssid: BSSID to be added to the blacklist 44252726Srpaulo * Returns: Current blacklist count on success, -1 on failure 45189251Ssam * 46189251Ssam * This function adds the specified BSSID to the blacklist or increases the 47189251Ssam * blacklist count if the BSSID was already listed. It should be called when 48189251Ssam * an association attempt fails either due to the selected BSS rejecting 49189251Ssam * association or due to timeout. 50189251Ssam * 51189251Ssam * This blacklist is used to force %wpa_supplicant to go through all available 52189251Ssam * BSSes before retrying to associate with an BSS that rejected or timed out 53189251Ssam * association. It does not prevent the listed BSS from being used; it only 54189251Ssam * changes the order in which they are tried. 55189251Ssam */ 56189251Ssamint wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid) 57189251Ssam{ 58189251Ssam struct wpa_blacklist *e; 59189251Ssam 60252726Srpaulo if (wpa_s == NULL || bssid == NULL) 61252726Srpaulo return -1; 62252726Srpaulo 63189251Ssam e = wpa_blacklist_get(wpa_s, bssid); 64189251Ssam if (e) { 65189251Ssam e->count++; 66189251Ssam wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count " 67189251Ssam "incremented to %d", 68189251Ssam MAC2STR(bssid), e->count); 69252726Srpaulo return e->count; 70189251Ssam } 71189251Ssam 72189251Ssam e = os_zalloc(sizeof(*e)); 73189251Ssam if (e == NULL) 74189251Ssam return -1; 75189251Ssam os_memcpy(e->bssid, bssid, ETH_ALEN); 76189251Ssam e->count = 1; 77189251Ssam e->next = wpa_s->blacklist; 78189251Ssam wpa_s->blacklist = e; 79189251Ssam wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist", 80189251Ssam MAC2STR(bssid)); 81189251Ssam 82252726Srpaulo return e->count; 83189251Ssam} 84189251Ssam 85189251Ssam 86189251Ssam/** 87189251Ssam * wpa_blacklist_del - Remove an BSSID from the blacklist 88189251Ssam * @wpa_s: Pointer to wpa_supplicant data 89189251Ssam * @bssid: BSSID to be removed from the blacklist 90189251Ssam * Returns: 0 on success, -1 on failure 91189251Ssam */ 92189251Ssamint wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid) 93189251Ssam{ 94189251Ssam struct wpa_blacklist *e, *prev = NULL; 95189251Ssam 96252726Srpaulo if (wpa_s == NULL || bssid == NULL) 97252726Srpaulo return -1; 98252726Srpaulo 99189251Ssam e = wpa_s->blacklist; 100189251Ssam while (e) { 101189251Ssam if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) { 102189251Ssam if (prev == NULL) { 103189251Ssam wpa_s->blacklist = e->next; 104189251Ssam } else { 105189251Ssam prev->next = e->next; 106189251Ssam } 107189251Ssam wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from " 108189251Ssam "blacklist", MAC2STR(bssid)); 109189251Ssam os_free(e); 110189251Ssam return 0; 111189251Ssam } 112189251Ssam prev = e; 113189251Ssam e = e->next; 114189251Ssam } 115189251Ssam return -1; 116189251Ssam} 117189251Ssam 118189251Ssam 119189251Ssam/** 120189251Ssam * wpa_blacklist_clear - Clear the blacklist of all entries 121189251Ssam * @wpa_s: Pointer to wpa_supplicant data 122189251Ssam */ 123189251Ssamvoid wpa_blacklist_clear(struct wpa_supplicant *wpa_s) 124189251Ssam{ 125189251Ssam struct wpa_blacklist *e, *prev; 126252726Srpaulo int max_count = 0; 127189251Ssam 128189251Ssam e = wpa_s->blacklist; 129189251Ssam wpa_s->blacklist = NULL; 130189251Ssam while (e) { 131252726Srpaulo if (e->count > max_count) 132252726Srpaulo max_count = e->count; 133189251Ssam prev = e; 134189251Ssam e = e->next; 135189251Ssam wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from " 136189251Ssam "blacklist (clear)", MAC2STR(prev->bssid)); 137189251Ssam os_free(prev); 138189251Ssam } 139252726Srpaulo 140252726Srpaulo wpa_s->extra_blacklist_count += max_count; 141189251Ssam} 142