Repository : ssh://git@diktynna/batctl
On branch : master
>---------------------------------------------------------------
commit 57cc3c472a7d5766443322b2df665ce914c1c3c6
Author: Alexander Sarmanow <asarmanow(a)gmail.com>
Date: Thu May 13 16:10:34 2021 +0200
batctl: Introduce handler for JSON_* command types
The JSON_MIF, JSON_HIF and JSON_VID command types will share most of their
code. The handler can therefore take over the initialization of the netlink
message, send the request and receive (+print) the returned data.
The actual JSON query implemenations can then be done using two structs and
a registration in the command list array.
Signed-off-by: Alexander Sarmanow <asarmanow(a)gmail.com>
[sven(a)narfation.org: fix commit message, cleanup changes, move changes to
correct file, introduce common initialization of netlink message and
shared print code]
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
>---------------------------------------------------------------
57cc3c472a7d5766443322b2df665ce914c1c3c6
README.rst | 4 +++
genl_json.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
genl_json.h | 7 ++++
3 files changed, 119 insertions(+)
diff --git a/README.rst b/README.rst
index ab5fa84..3d191f5 100644
--- a/README.rst
+++ b/README.rst
@@ -702,6 +702,10 @@ Example::
15.0 MBit
+JSON netlink query helper
+=========================
+
+
Advanced Analytics
==================
diff --git a/genl_json.c b/genl_json.c
index 967790c..9bdfcd5 100644
--- a/genl_json.c
+++ b/genl_json.c
@@ -11,6 +11,7 @@
#include <arpa/inet.h>
#include <ctype.h>
+#include <getopt.h>
#include <inttypes.h>
#include <netinet/in.h>
#include <netlink/netlink.h>
@@ -18,7 +19,9 @@
#include <stdbool.h>
#include <stdio.h>
#include <sys/socket.h>
+#include <unistd.h>
+#include "functions.h"
#include "batadv_packet.h"
#include "batman_adv.h"
#include "netlink.h"
@@ -496,3 +499,108 @@ void netlink_print_json_entries(struct nlattr *attrs[], struct json_opts *json_o
putchar('}');
}
+
+static void json_query_usage(struct state *state)
+{
+ fprintf(stderr, "Usage: batctl [options] %s|%s [parameters]\n",
+ state->cmd->name, state->cmd->abbr);
+ fprintf(stderr, "parameters:\n");
+ fprintf(stderr, " \t -h print this help\n");
+}
+
+static int netlink_print_query_json_cb(struct nl_msg *msg, void *arg)
+{
+ struct nlattr *attrs[BATADV_ATTR_MAX+1];
+ struct nlmsghdr *nlh = nlmsg_hdr(msg);
+ struct nlquery_opts *query_opts = arg;
+ struct json_opts *json_opts;
+ struct genlmsghdr *ghdr;
+
+ json_opts = container_of(query_opts, struct json_opts, query_opts);
+
+ if (!genlmsg_valid_hdr(nlh, 0)) {
+ fputs("Received invalid data from kernel.\n", stderr);
+ exit(1);
+ }
+
+ ghdr = nlmsg_data(nlh);
+
+ 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);
+ }
+
+ netlink_print_json_entries(attrs, json_opts);
+
+ return NL_OK;
+}
+
+static int netlink_print_query_json_attributes(struct nl_msg *msg, void *arg)
+{
+ struct state *state = arg;
+
+ switch (state->selector) {
+ case SP_NONE_OR_MESHIF:
+ case SP_MESHIF:
+ break;
+ case SP_VLAN:
+ nla_put_u16(msg, BATADV_ATTR_VLANID, state->vid);
+ break;
+ case SP_HARDIF:
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, state->hif);
+ break;
+ }
+
+ return 0;
+}
+
+static int netlink_print_query_json(struct state *state,
+ struct json_query_data *json_query)
+{
+ int ret;
+ struct json_opts json_opts = {
+ .is_first = true,
+ .query_opts = {
+ .err = 0,
+ },
+ };
+
+ if (json_query->nlm_flags & NLM_F_DUMP)
+ putchar('[');
+
+ ret = netlink_query_common(state, state->mesh_ifindex,
+ json_query->cmd,
+ netlink_print_query_json_cb,
+ netlink_print_query_json_attributes,
+ json_query->nlm_flags,
+ &json_opts.query_opts);
+
+ if (json_query->nlm_flags & NLM_F_DUMP)
+ puts("]");
+ else
+ putchar('\n');
+
+ return ret;
+}
+
+int handle_json_query(struct state *state, int argc, char **argv)
+{
+ struct json_query_data *json_query = state->cmd->arg;
+ int optchar;
+ int err;
+
+ while ((optchar = getopt(argc, argv, "h")) != -1) {
+ switch (optchar) {
+ case 'h':
+ json_query_usage(state);
+ return EXIT_SUCCESS;
+ }
+ }
+
+ check_root_or_die("batctl");
+
+ err = netlink_print_query_json(state, json_query);
+
+ return err;
+}
diff --git a/genl_json.h b/genl_json.h
index 87f4d6f..54f7995 100644
--- a/genl_json.h
+++ b/genl_json.h
@@ -11,6 +11,7 @@
#include <stdint.h>
+#include "batman_adv.h"
#include "netlink.h"
struct json_opts {
@@ -18,6 +19,12 @@ struct json_opts {
struct nlquery_opts query_opts;
};
+struct json_query_data {
+ int nlm_flags;
+ enum batadv_nl_commands cmd;
+};
+
void netlink_print_json_entries(struct nlattr *attrs[], struct json_opts *json_opts);
+int handle_json_query(struct state *state, int argc, char **argv);
#endif /* _BATCTL_GENLJSON_H */