hostapd: Support showing neighbor list through hostapd_cli

This lets one know the current neighbor list, and could be used
to populate the neighbor list of other hostapd processes.

For instance:

$ hostapd_cli -i vap0001 show_neighbor
04:f0:21:1e:ae:b0 ssid=04f0211eaeb0af190000802809 nr=04f0211eaeb0af1900008028090603022a00
$ hostapd_cli -i vap0000 set_neighbor 04:f0:21:1e:ae:b0 ssid=04f0211eaeb0af190000802809 nr=04f0211eaeb0af1900008028090603022a00
OK
$ hostapd_cli -i vap0000 show_neighbor
04:f0:21:1e:ae:b0 ssid=04f0211eaeb0af190000802809 nr=04f0211eaeb0af1900008028090603022a00
04:f0:21:c3:b2:b0 ssid=04f021c3b2b0af190000802809 nr=04f021c3b2b0af1900008028090603022a00

Signed-off-by: Ben Greear <greearb@candelatech.com>
This commit is contained in:
Ben Greear 2019-03-19 10:09:50 -07:00 committed by Jouni Malinen
parent 0dfa6ea529
commit ee48f48ba1
4 changed files with 81 additions and 0 deletions

View file

@ -2707,6 +2707,20 @@ static int hostapd_ctrl_iface_req_beacon(struct hostapd_data *hapd,
} }
static int hostapd_ctrl_iface_show_neighbor(struct hostapd_data *hapd,
char *buf, size_t buflen)
{
if (!(hapd->conf->radio_measurements[0] &
WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
wpa_printf(MSG_ERROR,
"CTRL: SHOW_NEIGHBOR: Neighbor report is not enabled");
return -1;
}
return hostapd_neighbor_show(hapd, buf, buflen);
}
static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf) static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf)
{ {
struct wpa_ssid_value ssid; struct wpa_ssid_value ssid;
@ -3255,6 +3269,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
} else if (os_strncmp(buf, "SET_NEIGHBOR ", 13) == 0) { } else if (os_strncmp(buf, "SET_NEIGHBOR ", 13) == 0) {
if (hostapd_ctrl_iface_set_neighbor(hapd, buf + 13)) if (hostapd_ctrl_iface_set_neighbor(hapd, buf + 13))
reply_len = -1; reply_len = -1;
} else if (os_strcmp(buf, "SHOW_NEIGHBOR") == 0) {
reply_len = hostapd_ctrl_iface_show_neighbor(hapd, reply,
reply_size);
} else if (os_strncmp(buf, "REMOVE_NEIGHBOR ", 16) == 0) { } else if (os_strncmp(buf, "REMOVE_NEIGHBOR ", 16) == 0) {
if (hostapd_ctrl_iface_remove_neighbor(hapd, buf + 16)) if (hostapd_ctrl_iface_remove_neighbor(hapd, buf + 16))
reply_len = -1; reply_len = -1;

View file

@ -1312,6 +1312,13 @@ static int hostapd_cli_cmd_set_neighbor(struct wpa_ctrl *ctrl, int argc,
} }
static int hostapd_cli_cmd_show_neighbor(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
return wpa_ctrl_command(ctrl, "SHOW_NEIGHBOR");
}
static int hostapd_cli_cmd_remove_neighbor(struct wpa_ctrl *ctrl, int argc, static int hostapd_cli_cmd_remove_neighbor(struct wpa_ctrl *ctrl, int argc,
char *argv[]) char *argv[])
{ {
@ -1622,6 +1629,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
{ "set_neighbor", hostapd_cli_cmd_set_neighbor, NULL, { "set_neighbor", hostapd_cli_cmd_set_neighbor, NULL,
"<addr> <ssid=> <nr=> [lci=] [civic=] [stat]\n" "<addr> <ssid=> <nr=> [lci=] [civic=] [stat]\n"
" = add AP to neighbor database" }, " = add AP to neighbor database" },
{ "show_neighbor", hostapd_cli_cmd_show_neighbor, NULL,
" = show neighbor database entries" },
{ "remove_neighbor", hostapd_cli_cmd_remove_neighbor, NULL, { "remove_neighbor", hostapd_cli_cmd_remove_neighbor, NULL,
"<addr> [ssid=<hex>] = remove AP from neighbor database" }, "<addr> [ssid=<hex>] = remove AP from neighbor database" },
{ "req_lci", hostapd_cli_cmd_req_lci, hostapd_complete_stations, { "req_lci", hostapd_cli_cmd_req_lci, hostapd_complete_stations,

View file

@ -34,6 +34,60 @@ hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid,
} }
int hostapd_neighbor_show(struct hostapd_data *hapd, char *buf, size_t buflen)
{
struct hostapd_neighbor_entry *nr;
char *pos, *end;
pos = buf;
end = buf + buflen;
dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
list) {
int ret;
char nrie[2 * 255 + 1];
char lci[2 * 255 + 1];
char civic[2 * 255 + 1];
char ssid[SSID_MAX_LEN * 2 + 1];
ssid[0] = '\0';
wpa_snprintf_hex(ssid, sizeof(ssid), nr->ssid.ssid,
nr->ssid.ssid_len);
nrie[0] = '\0';
if (nr->nr)
wpa_snprintf_hex(nrie, sizeof(nrie),
wpabuf_head(nr->nr),
wpabuf_len(nr->nr));
lci[0] = '\0';
if (nr->lci)
wpa_snprintf_hex(lci, sizeof(lci),
wpabuf_head(nr->lci),
wpabuf_len(nr->lci));
civic[0] = '\0';
if (nr->civic)
wpa_snprintf_hex(civic, sizeof(civic),
wpabuf_head(nr->civic),
wpabuf_len(nr->civic));
ret = os_snprintf(pos, end - pos, MACSTR
" ssid=%s%s%s%s%s%s%s%s\n",
MAC2STR(nr->bssid), ssid,
nr->nr ? " nr=" : "", nrie,
nr->lci ? " lci=" : "", lci,
nr->civic ? " civic=" : "", civic,
nr->stationary ? " stat" : "");
if (os_snprintf_error(end - pos, ret))
break;
pos += ret;
}
return pos - buf;
}
static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr) static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr)
{ {
wpabuf_free(nr->nr); wpabuf_free(nr->nr);

View file

@ -13,6 +13,7 @@
struct hostapd_neighbor_entry * struct hostapd_neighbor_entry *
hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid, hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid,
const struct wpa_ssid_value *ssid); const struct wpa_ssid_value *ssid);
int hostapd_neighbor_show(struct hostapd_data *hapd, char *buf, size_t buflen);
int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid, int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
const struct wpa_ssid_value *ssid, const struct wpa_ssid_value *ssid,
const struct wpabuf *nr, const struct wpabuf *lci, const struct wpabuf *nr, const struct wpabuf *lci,