From: Ben Greear <greearb@xxxxxxxxxxxxxxx> 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 lci=[BLANK] civic=[BLANK] stationary=0 # 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 lci=[BLANK] civic=[BLANK] stationary=0 04:f0:21:c3:b2:b0 ssid=04f021c3b2b0af190000802809 nr=04f021c3b2b0af1900008028090603022a00 lci=[BLANK] civic=[BLANK] stationary=0 # Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx> --- v2: Fix ssid printout, earlier patch was grabbing 'nr' data instead of the ssid hostapd/ctrl_iface.c | 19 +++++++++++++++ hostapd/hostapd_cli.c | 8 ++++++ src/ap/neighbor_db.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/ap/neighbor_db.h | 1 + 4 files changed, 95 insertions(+) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index df2524a..f47d21e 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -2655,6 +2655,23 @@ static int hostapd_ctrl_iface_req_beacon(struct hostapd_data *hapd, return ret; } +static int hostapd_ctrl_iface_show_neighbor(struct hostapd_data *hapd, + char *buf, size_t buflen) +{ + struct hostapd_iface *iface = hapd->iface; + struct hostapd_sta_info *info; + struct os_reltime now; + + 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) { @@ -3174,6 +3191,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, } else if (os_strncmp(buf, "SET_NEIGHBOR ", 13) == 0) { if (hostapd_ctrl_iface_set_neighbor(hapd, buf + 13)) 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) { if (hostapd_ctrl_iface_remove_neighbor(hapd, buf + 16)) reply_len = -1; diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c index 23c592a..4b1c877 100644 --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c @@ -1303,6 +1303,12 @@ static int hostapd_cli_cmd_set_neighbor(struct wpa_ctrl *ctrl, int argc, return wpa_ctrl_command(ctrl, cmd); } +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, char *argv[]) @@ -1628,6 +1634,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = { { "set_neighbor", hostapd_cli_cmd_set_neighbor, NULL, "<addr> <ssid=> <nr=> [lci=] [civic=] [stat]\n" " = 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, "<addr> <ssid=> = remove AP from neighbor database" }, { "req_lci", hostapd_cli_cmd_req_lci, hostapd_complete_stations, diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c index 2b6f727..14a7f13 100644 --- a/src/ap/neighbor_db.c +++ b/src/ap/neighbor_db.c @@ -33,6 +33,73 @@ hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid, return NULL; } +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[120]; + char lci[120]; + char civic[120]; + char ssid[SSID_MAX_LEN * 2 + 1]; + int i = 0; + static const char* blank = "[BLANK]"; + + for (i = 0; i<nr->ssid.ssid_len; i++) { + os_snprintf(ssid + i * 2, 3, "%02hx", nr->ssid.ssid[i]); + } + if (i == 0) + os_snprintf(ssid, sizeof(ssid), "%s", blank); + + i = 0; + if (nr->nr) { + for (i = 0; i<nr->nr->used; i++) { + if (i * 2 + 2 >= sizeof(nrie)) + break; + os_snprintf(nrie + i * 2, 3, "%02hx", nr->nr->buf[i]); + } + } + if (i == 0) + os_snprintf(nrie, sizeof(nrie), "%s", blank); + + i = 0; + if (nr->lci) { + for (i = 0; i<nr->lci->used; i++) { + if (i * 2 + 2 >= sizeof(lci)) + break; + os_snprintf(lci + i * 2, 3, "%02hx", nr->lci->buf[i]); + } + } + if (i == 0) + os_snprintf(lci, sizeof(lci), "%s", blank); + + i = 0; + if (nr->civic) { + for (i = 0; i<nr->civic->used; i++) { + if (i * 2 + 2 >= sizeof(civic)) + break; + os_snprintf(civic + i * 2, 3, "%02hx", nr->civic->buf[i]); + } + } + if (i == 0) + os_snprintf(civic, sizeof(civic), "%s", blank); + + ret = os_snprintf(pos, end - pos, MACSTR " ssid=%s nr=%s lci=%s civic=%s stationary=%i\n", + MAC2STR(nr->bssid), ssid, nrie, lci, civic, nr->stationary); + if (os_snprintf_error(end - pos, ret)) + break; + pos += ret; + } + return pos - buf; +} + static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr) { diff --git a/src/ap/neighbor_db.h b/src/ap/neighbor_db.h index 9c8f4f2..e269310 100644 --- a/src/ap/neighbor_db.h +++ b/src/ap/neighbor_db.h @@ -13,6 +13,7 @@ struct hostapd_neighbor_entry * hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid, 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, const struct wpa_ssid_value *ssid, const struct wpabuf *nr, const struct wpabuf *lci, -- 2.7.5 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap