1/* 2 * wpa_supplicant - Temporary BSSID blacklist 3 * Copyright (c) 2003-2007, 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 "includes.h" 10 11#include "common.h" 12#include "wpa_supplicant_i.h" 13#include "blacklist.h" 14 15/** 16 * wpa_blacklist_get - Get the blacklist entry for a BSSID 17 * @wpa_s: Pointer to wpa_supplicant data 18 * @bssid: BSSID 19 * Returns: Matching blacklist entry for the BSSID or %NULL if not found 20 */ 21struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s, 22 const u8 *bssid) 23{ 24 struct wpa_blacklist *e; 25 26 if (wpa_s == NULL || bssid == NULL) 27 return NULL; 28 29 e = wpa_s->blacklist; 30 while (e) { 31 if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) 32 return e; 33 e = e->next; 34 } 35 36 return NULL; 37} 38 39 40/** 41 * wpa_blacklist_add - Add an BSSID to the blacklist 42 * @wpa_s: Pointer to wpa_supplicant data 43 * @bssid: BSSID to be added to the blacklist 44 * Returns: Current blacklist count on success, -1 on failure 45 * 46 * This function adds the specified BSSID to the blacklist or increases the 47 * blacklist count if the BSSID was already listed. It should be called when 48 * an association attempt fails either due to the selected BSS rejecting 49 * association or due to timeout. 50 * 51 * This blacklist is used to force %wpa_supplicant to go through all available 52 * BSSes before retrying to associate with an BSS that rejected or timed out 53 * association. It does not prevent the listed BSS from being used; it only 54 * changes the order in which they are tried. 55 */ 56int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid) 57{ 58 struct wpa_blacklist *e; 59 60 if (wpa_s == NULL || bssid == NULL) 61 return -1; 62 63 e = wpa_blacklist_get(wpa_s, bssid); 64 if (e) { 65 e->count++; 66 wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count " 67 "incremented to %d", 68 MAC2STR(bssid), e->count); 69 return e->count; 70 } 71 72 e = os_zalloc(sizeof(*e)); 73 if (e == NULL) 74 return -1; 75 os_memcpy(e->bssid, bssid, ETH_ALEN); 76 e->count = 1; 77 e->next = wpa_s->blacklist; 78 wpa_s->blacklist = e; 79 wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist", 80 MAC2STR(bssid)); 81 82 return e->count; 83} 84 85 86/** 87 * wpa_blacklist_del - Remove an BSSID from the blacklist 88 * @wpa_s: Pointer to wpa_supplicant data 89 * @bssid: BSSID to be removed from the blacklist 90 * Returns: 0 on success, -1 on failure 91 */ 92int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid) 93{ 94 struct wpa_blacklist *e, *prev = NULL; 95 96 if (wpa_s == NULL || bssid == NULL) 97 return -1; 98 99 e = wpa_s->blacklist; 100 while (e) { 101 if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) { 102 if (prev == NULL) { 103 wpa_s->blacklist = e->next; 104 } else { 105 prev->next = e->next; 106 } 107 wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from " 108 "blacklist", MAC2STR(bssid)); 109 os_free(e); 110 return 0; 111 } 112 prev = e; 113 e = e->next; 114 } 115 return -1; 116} 117 118 119/** 120 * wpa_blacklist_clear - Clear the blacklist of all entries 121 * @wpa_s: Pointer to wpa_supplicant data 122 */ 123void wpa_blacklist_clear(struct wpa_supplicant *wpa_s) 124{ 125 struct wpa_blacklist *e, *prev; 126 int max_count = 0; 127 128 e = wpa_s->blacklist; 129 wpa_s->blacklist = NULL; 130 while (e) { 131 if (e->count > max_count) 132 max_count = e->count; 133 prev = e; 134 e = e->next; 135 wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from " 136 "blacklist (clear)", MAC2STR(prev->bssid)); 137 os_free(prev); 138 } 139 140 wpa_s->extra_blacklist_count += max_count; 141} 142