diff mbox series

[v2] hostapd: Support showing neighbor list through hostapd_cli

Message ID 1552687734-25399-1-git-send-email-greearb@candelatech.com
State Superseded
Headers show
Series [v2] hostapd: Support showing neighbor list through hostapd_cli | expand

Commit Message

Ben Greear March 15, 2019, 10:08 p.m. UTC
From: Ben Greear <greearb@candelatech.com>

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@candelatech.com>
---

v2:  Add ssid to dump, use [blank] for empty things instead of printing 00 hex as previous version.

 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 mbox series

Patch

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..f54b065 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->nr->buf[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,