18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant - Temporary BSSID blacklist 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "blacklist.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_blacklist_get - Get the blacklist entry for a BSSID 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bssid: BSSID 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Matching blacklist entry for the BSSID or %NULL if not found 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s, 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid) 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_blacklist *e; 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26b8fdecbfd0a0cdbbb17b902a6be87c84227b9b11Sasha Levitskiy if (wpa_s == NULL || bssid == NULL) 27b8fdecbfd0a0cdbbb17b902a6be87c84227b9b11Sasha Levitskiy return NULL; 28b8fdecbfd0a0cdbbb17b902a6be87c84227b9b11Sasha Levitskiy 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e = wpa_s->blacklist; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (e) { 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return e; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e = e->next; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_blacklist_add - Add an BSSID to the blacklist 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bssid: BSSID to be added to the blacklist 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Current blacklist count on success, -1 on failure 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds the specified BSSID to the blacklist or increases the 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * blacklist count if the BSSID was already listed. It should be called when 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an association attempt fails either due to the selected BSS rejecting 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * association or due to timeout. 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This blacklist is used to force %wpa_supplicant to go through all available 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * BSSes before retrying to associate with an BSS that rejected or timed out 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * association. It does not prevent the listed BSS from being used; it only 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * changes the order in which they are tried. 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid) 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_blacklist *e; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60b8fdecbfd0a0cdbbb17b902a6be87c84227b9b11Sasha Levitskiy if (wpa_s == NULL || bssid == NULL) 61b8fdecbfd0a0cdbbb17b902a6be87c84227b9b11Sasha Levitskiy return -1; 62b8fdecbfd0a0cdbbb17b902a6be87c84227b9b11Sasha Levitskiy 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e = wpa_blacklist_get(wpa_s, bssid); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (e) { 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->count++; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count " 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "incremented to %d", 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), e->count); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return e->count; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e = os_zalloc(sizeof(*e)); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (e == NULL) 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(e->bssid, bssid, ETH_ALEN); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->count = 1; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->next = wpa_s->blacklist; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->blacklist = e; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist", 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid)); 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return e->count; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_blacklist_del - Remove an BSSID from the blacklist 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bssid: BSSID to be removed from the blacklist 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid) 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_blacklist *e, *prev = NULL; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 96b8fdecbfd0a0cdbbb17b902a6be87c84227b9b11Sasha Levitskiy if (wpa_s == NULL || bssid == NULL) 97b8fdecbfd0a0cdbbb17b902a6be87c84227b9b11Sasha Levitskiy return -1; 98b8fdecbfd0a0cdbbb17b902a6be87c84227b9b11Sasha Levitskiy 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e = wpa_s->blacklist; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (e) { 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) { 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev == NULL) { 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->blacklist = e->next; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = e->next; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from " 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "blacklist", MAC2STR(bssid)); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(e); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = e; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e = e->next; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_blacklist_clear - Clear the blacklist of all entries 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_blacklist_clear(struct wpa_supplicant *wpa_s) 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_blacklist *e, *prev; 126d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int max_count = 0; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e = wpa_s->blacklist; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->blacklist = NULL; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (e) { 131d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (e->count > max_count) 132d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt max_count = e->count; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = e; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e = e->next; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from " 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "blacklist (clear)", MAC2STR(prev->bssid)); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev); 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 139d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 140d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->extra_blacklist_count += max_count; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 142