diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 499d3e837..1b2b766f0 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -39,6 +39,7 @@ #include "scan.h" #include "ctrl_iface.h" #include "interworking.h" +#include "blacklist.h" extern struct wpa_driver_ops *wpa_drivers[]; @@ -920,6 +921,59 @@ static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s, } +static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s, + char *cmd, char *buf, + size_t buflen) +{ + u8 bssid[ETH_ALEN]; + struct wpa_blacklist *e; + char *pos, *end; + int ret; + + /* cmd: "BLACKLIST []" */ + if (*cmd == '\0') { + pos = buf; + end = buf + buflen; + e = wpa_s->blacklist; + while (e) { + ret = os_snprintf(pos, end - pos, MACSTR "\n", + MAC2STR(e->bssid)); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + e = e->next; + } + return pos - buf; + } + + cmd++; + if (os_strncmp(cmd, "clear", 5) == 0) { + wpa_blacklist_clear(wpa_s); + os_memcpy(buf, "OK\n", 3); + return 3; + } + + wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd); + 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 -1; + ret = wpa_blacklist_add(wpa_s, bssid); + if (ret != 0) + return -1; + os_memcpy(buf, "OK\n", 3); + return 3; +} + + extern int wpa_debug_level; extern int wpa_debug_timestamp; @@ -3402,6 +3456,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "BSSID ", 6) == 0) { if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) reply_len = -1; + } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) { + reply_len = wpa_supplicant_ctrl_iface_blacklist( + wpa_s, buf + 9, reply, reply_size); } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) { reply_len = wpa_supplicant_ctrl_iface_log_level( wpa_s, buf + 9, reply, reply_size); diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 8461a7479..02670fefb 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1224,6 +1224,32 @@ static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[]) } +static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + char cmd[256], *pos, *end; + int i, ret; + + end = cmd + sizeof(cmd); + pos = cmd; + ret = os_snprintf(pos, end - pos, "BLACKLIST"); + if (ret < 0 || ret >= end - pos) { + printf("Too long BLACKLIST command.\n"); + return -1; + } + pos += ret; + for (i = 0; i < argc; i++) { + ret = os_snprintf(pos, end - pos, " %s", argv[i]); + if (ret < 0 || ret >= end - pos) { + printf("Too long BLACKLIST command.\n"); + return -1; + } + pos += ret; + } + + return wpa_ctrl_command(ctrl, cmd); +} + + static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) { char cmd[256], *pos, *end; @@ -2497,6 +2523,11 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { { "bssid", wpa_cli_cmd_bssid, cli_cmd_flag_none, " = set preferred BSSID for an SSID" }, + { "blacklist", wpa_cli_cmd_blacklist, + cli_cmd_flag_none, + " = add a BSSID to the blacklist\n" + "blacklist clear = clear the blacklist\n" + "blacklist = display the blacklist" }, { "log_level", wpa_cli_cmd_log_level, cli_cmd_flag_none, " [] = update the log level/timestamp\n"