[v2] batctl: add dat_dht command

Message ID 20240911051813.23550-1-linus.luessing@c0d3.blue (mailing list archive)
State New
Delegated to: Antonio Quartulli
Headers
Series [v2] batctl: add dat_dht command |

Commit Message

Linus Lüssing Sept. 11, 2024, 5:18 a.m. UTC
  This adds a dat_dht command to query the DHT part of DAT
in batman-adv.

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
---

Changelog v2:
- rebased to current main branch:
  -> removed now obsolete debugfs code

 Makefile        |   2 +
 README.rst      |  27 +++++++++-
 batadv_packet.h |   4 +-
 batman_adv.h    |   5 ++
 dat_cache.c     |   2 +-
 dat_dht.c       | 131 ++++++++++++++++++++++++++++++++++++++++++++++++
 dat_dht_json.c  |  20 ++++++++
 man/batctl.8    |   6 +++
 8 files changed, 194 insertions(+), 3 deletions(-)
 create mode 100644 dat_dht.c
 create mode 100644 dat_dht_json.c
  

Patch

diff --git a/Makefile b/Makefile
index c1212c444971..92f84e5bf012 100755
--- a/Makefile
+++ b/Makefile
@@ -47,6 +47,8 @@  $(eval $(call add_command,bridge_loop_avoidance,y))
 $(eval $(call add_command,claimtable,y))
 $(eval $(call add_command,dat_cache,y))
 $(eval $(call add_command,dat_cache_json,y))
+$(eval $(call add_command,dat_dht,y))
+$(eval $(call add_command,dat_dht_json,y))
 $(eval $(call add_command,distributed_arp_table,y))
 $(eval $(call add_command,elp_interval,y))
 $(eval $(call add_command,event,y))
diff --git a/README.rst b/README.rst
index 3495fba02e0e..dc1852068e0d 100644
--- a/README.rst
+++ b/README.rst
@@ -278,7 +278,32 @@  Usage::
 
 Example::
 
-  Distributed ARP Table (bat0):
+  Distributed ARP Table Cache (bat0):
+            IPv4             MAC           last-seen
+   *     172.100.0.1 b6:9b:d0:ea:b1:13      0:00
+
+where
+
+IPv4:
+  is the IP address of a client in the mesh network
+MAC:
+  is the MAC address associated to that IP
+last-seen:
+  is the amount of time since last refresh of this entry
+
+
+batctl dat_dht
+=================
+
+display the local D.A.T. DHT
+
+Usage::
+
+  batctl dat_dht|dd
+
+Example::
+
+  Distributed ARP Table DHT (bat0):
             IPv4             MAC           last-seen
    *     172.100.0.1 b6:9b:d0:ea:b1:13      0:00
 
diff --git a/batadv_packet.h b/batadv_packet.h
index 6e25753015df..93df068b00f3 100644
--- a/batadv_packet.h
+++ b/batadv_packet.h
@@ -60,13 +60,15 @@  enum batadv_packettype {
  * @BATADV_P_DATA: user payload
  * @BATADV_P_DAT_DHT_GET: DHT request message
  * @BATADV_P_DAT_DHT_PUT: DHT store message
- * @BATADV_P_DAT_CACHE_REPLY: ARP reply generated by DAT
+ * @BATADV_P_DAT_CACHE_REPLY: deprecated: use BATADV_P_DAT_DHT_REPLY instead
+ * @BATADV_P_DAT_DHT_REPLY: ARP reply generated by DAT
  */
 enum batadv_subtype {
 	BATADV_P_DATA			= 0x01,
 	BATADV_P_DAT_DHT_GET		= 0x02,
 	BATADV_P_DAT_DHT_PUT		= 0x03,
 	BATADV_P_DAT_CACHE_REPLY	= 0x04,
+	BATADV_P_DAT_DHT_REPLY          = 0x04,
 };
 
 /* this file is included by batctl which needs these defines */
diff --git a/batman_adv.h b/batman_adv.h
index 35dc016c9bb4..9498ccb09d67 100644
--- a/batman_adv.h
+++ b/batman_adv.h
@@ -613,6 +613,11 @@  enum batadv_nl_commands {
 	 */
 	BATADV_CMD_SET_VLAN,
 
+	/**
+	 * @BATADV_CMD_GET_DAT_DHT: Query list of DAT DHT entries
+	 */
+	BATADV_CMD_GET_DAT_DHT,
+
 	/* add new commands above here */
 
 	/**
diff --git a/dat_cache.c b/dat_cache.c
index 8d471718e4b3..d34375563aad 100644
--- a/dat_cache.c
+++ b/dat_cache.c
@@ -106,7 +106,7 @@  static int netlink_print_dat_cache(struct state *state, char *orig_iface,
 	char *header;
 	int ret;
 
-	ret = asprintf(&header, "Distributed ARP Table (%s):\n%s\n",
+	ret = asprintf(&header, "Distributed ARP Table Cache (%s):\n%s\n",
 		       state->mesh_iface,
 		       "          IPv4             MAC        VID   last-seen");
 
diff --git a/dat_dht.c b/dat_dht.c
new file mode 100644
index 000000000000..b9619ec00a73
--- /dev/null
+++ b/dat_dht.c
@@ -0,0 +1,131 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner <mareklindner@neomailbox.ch>
+ *
+ * License-Filename: LICENSES/preferred/GPL-2.0
+ */
+
+#include <arpa/inet.h>
+#include <netinet/if_ether.h>
+#include <netinet/in.h>
+#include <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/socket.h>
+
+#include "batadv_packet.h"
+#include "batman_adv.h"
+#include "bat-hosts.h"
+#include "debug.h"
+#include "functions.h"
+#include "main.h"
+#include "netlink.h"
+
+static const int dat_dht_mandatory[] = {
+	BATADV_ATTR_DAT_CACHE_IP4ADDRESS,
+	BATADV_ATTR_DAT_CACHE_HWADDRESS,
+	BATADV_ATTR_DAT_CACHE_VID,
+	BATADV_ATTR_LAST_SEEN_MSECS,
+};
+
+static int dat_dht_callback(struct nl_msg *msg, void *arg)
+{
+	int last_seen_msecs, last_seen_secs, last_seen_mins;
+	struct nlattr *attrs[BATADV_ATTR_MAX+1];
+	struct nlmsghdr *nlh = nlmsg_hdr(msg);
+	struct print_opts *opts = arg;
+	struct bat_host *bat_host;
+	struct genlmsghdr *ghdr;
+	struct in_addr in_addr;
+	uint8_t *hwaddr;
+	int16_t vid;
+	char *addr;
+
+	if (!genlmsg_valid_hdr(nlh, 0)) {
+		fputs("Received invalid data from kernel.\n", stderr);
+		exit(1);
+	}
+
+	ghdr = nlmsg_data(nlh);
+
+	if (ghdr->cmd != BATADV_CMD_GET_DAT_DHT)
+		return NL_OK;
+
+	if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
+		      genlmsg_len(ghdr), batadv_netlink_policy)) {
+		fputs("Received invalid data from kernel.\n", stderr);
+		exit(1);
+	}
+
+	if (missing_mandatory_attrs(attrs, dat_dht_mandatory,
+				    ARRAY_SIZE(dat_dht_mandatory))) {
+		fputs("Missing attributes from kernel\n", stderr);
+		exit(1);
+	}
+
+	in_addr.s_addr = nla_get_u32(attrs[BATADV_ATTR_DAT_CACHE_IP4ADDRESS]);
+	addr = inet_ntoa(in_addr);
+	hwaddr = nla_data(attrs[BATADV_ATTR_DAT_CACHE_HWADDRESS]);
+	vid = nla_get_u16(attrs[BATADV_ATTR_DAT_CACHE_VID]);
+
+	last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]);
+	last_seen_mins = last_seen_msecs / 60000;
+	last_seen_msecs = last_seen_msecs % 60000;
+	last_seen_secs = last_seen_msecs / 1000;
+
+	if (opts->read_opt & MULTICAST_ONLY && !(addr[0] & 0x01))
+		return NL_OK;
+
+	if (opts->read_opt & UNICAST_ONLY && (addr[0] & 0x01))
+		return NL_OK;
+
+	printf(" * %15s ", addr);
+
+	bat_host = bat_hosts_find_by_mac((char *)hwaddr);
+	if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host)
+		printf("%02x:%02x:%02x:%02x:%02x:%02x ",
+		       hwaddr[0], hwaddr[1], hwaddr[2],
+		       hwaddr[3], hwaddr[4], hwaddr[5]);
+	else
+		printf("%17s ", bat_host->name);
+
+	printf("%4i %6i:%02i\n",
+	       BATADV_PRINT_VID(vid), last_seen_mins, last_seen_secs);
+
+	return NL_OK;
+}
+
+static int netlink_print_dat_dht(struct state *state, char *orig_iface,
+				 int read_opts, float orig_timeout,
+				 float watch_interval)
+{
+	char *header;
+	int ret;
+
+	ret = asprintf(&header, "Distributed ARP Table DHT (%s):\n%s\n",
+		       state->mesh_iface,
+		       "          IPv4             MAC        VID   last-seen");
+
+	if (ret < 0)
+		return ret;
+
+	ret = netlink_print_common(state, orig_iface, read_opts,
+				   orig_timeout, watch_interval, header,
+				   BATADV_CMD_GET_DAT_DHT,
+				   dat_dht_callback);
+
+	free(header);
+	return ret;
+}
+
+static struct debug_table_data batctl_debug_table_dat_dht = {
+	.netlink_fn = netlink_print_dat_dht,
+};
+
+COMMAND_NAMED(DEBUGTABLE, dat_dht, "dd", handle_debug_table,
+	      COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
+	      &batctl_debug_table_dat_dht, "");
diff --git a/dat_dht_json.c b/dat_dht_json.c
new file mode 100644
index 000000000000..43eb3c586d74
--- /dev/null
+++ b/dat_dht_json.c
@@ -0,0 +1,20 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing <linus.luessing@c0d3.blue>
+ *
+ * License-Filename: LICENSES/preferred/GPL-2.0
+ */
+
+#include "main.h"
+
+#include "genl_json.h"
+
+static struct json_query_data batctl_json_query_dat_dht = {
+	.nlm_flags = NLM_F_DUMP,
+	.cmd = BATADV_CMD_GET_DAT_DHT,
+};
+
+COMMAND_NAMED(JSON_MIF, dat_dht_json, "ddj", handle_json_query,
+	      COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
+	      &batctl_json_query_dat_dht, "");
diff --git a/man/batctl.8 b/man/batctl.8
index b5be0b801708..417f5412c885 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -388,6 +388,10 @@  The local and global translation tables also support the "\-u" and "\-m" option
 [\fBmeshif\fP \fInetdev\fP] \fBdat_cache\fP|\fBdc\fP [\fB-n\fP] [\fB-H\fP] [\fB-w\fP \fIinterval\fP]
 (compile time option)
 .TP
+.TP
+[\fBmeshif\fP \fInetdev\fP] \fBdat_dht\fP|\fBdd\fP [\fB-n\fP] [\fB-H\fP] [\fB-w\fP \fIinterval\fP]
+(compile time option)
+.TP
 [\fBmeshif\fP \fInetdev\fP] \fBgateways\fP|\fBgwl\fP [\fB-n\fP] [\fB-H\fP] [\fB-w\fP \fIinterval\fP]
 .TP
 [\fBmeshif\fP \fInetdev\fP] \fBmcast_flags\fP|\fBmf\fP [\fB-n\fP] [\fB-H\fP] [\fB-w\fP \fIinterval\fP]
@@ -416,6 +420,8 @@  the freeform debug tables or the native netlink messages.
 .TP
 [\fBmeshif\fP \fInetdev\fP] \fBdat_cache_json\fP|\fBdcj\fP
 .TP
+[\fBmeshif\fP \fInetdev\fP] \fBdat_dht_json\fP|\fBdcj\fP
+.TP
 [\fBmeshif\fP \fInetdev\fP] \fBgateways_json\fP|\fBgwj\fP
 .TP
 \fBhardif\fP \fIhardif\fP \fBhardif_json\fP|\fBhj\fP