Repository : ssh://git@diktynna/batctl
On branch : master
commit 57cc3c472a7d5766443322b2df665ce914c1c3c6 Author: Alexander Sarmanow asarmanow@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@gmail.com [sven@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@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 */