Print name of resolved genl family name by type

Signed-off-by: Vadim Kochan <[email protected]>
---
 dissector_netlink.c |  3 ++
 proto.h             | 15 ++++++++++
 proto_nlmsg.c       | 82 +++++++++++++++++++++++++++++++++++++++++++++++++----
 protos.h            |  2 +-
 4 files changed, 96 insertions(+), 6 deletions(-)

diff --git a/dissector_netlink.c b/dissector_netlink.c
index 2b23a99..b4de112 100644
--- a/dissector_netlink.c
+++ b/dissector_netlink.c
@@ -19,10 +19,13 @@ static inline void dissector_init_exit(int type)
 
 void dissector_init_netlink(int fnttype)
 {
+       proto_ops_init(&nlmsg_ops);
+
        dissector_init_entry(fnttype);
        dissector_init_exit(fnttype);
 }
 
 void dissector_cleanup_netlink(void)
 {
+       proto_ops_uninit(&nlmsg_ops);
 }
diff --git a/proto.h b/proto.h
index 0cc1fd8..03a07e2 100644
--- a/proto.h
+++ b/proto.h
@@ -10,6 +10,7 @@
 
 #include <ctype.h>
 #include <stdint.h>
+#include <stddef.h>
 
 #include "tprintf.h"
 
@@ -20,6 +21,8 @@ struct protocol {
        const unsigned int key;
        void (*print_full)(struct pkt_buff *pkt);
        void (*print_less)(struct pkt_buff *pkt);
+       void (*init)(void);
+       void (*uninit)(void);
        /* Used by program logic */
        struct protocol *next;
        void (*process)   (struct pkt_buff *pkt);
@@ -32,4 +35,16 @@ extern void _ascii(uint8_t *ptr, size_t len);
 extern void ascii(struct pkt_buff *pkt);
 extern void hex_ascii(struct pkt_buff *pkt);
 
+static inline void proto_ops_init(struct protocol *prot)
+{
+       if (prot->init)
+               prot->init();
+}
+
+static inline void proto_ops_uninit(struct protocol *prot)
+{
+       if (prot->uninit)
+               prot->uninit();
+}
+
 #endif /* PROTO_H */
diff --git a/proto_nlmsg.c b/proto_nlmsg.c
index 6b43335..f641c83 100644
--- a/proto_nlmsg.c
+++ b/proto_nlmsg.c
@@ -12,6 +12,8 @@
 #include <netlink/msg.h>
 #include <netlink/route/link.h>
 #include <netlink/route/addr.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/genl/family.h>
 #include <linux/if_arp.h>
 #include <arpa/inet.h>
 
@@ -95,6 +97,9 @@
 
 #define nla_fmt_nested_end() tprintf("\n")
 
+static struct nl_cache *genl_af_cache;
+static struct nl_sock *genl_sock;
+
 struct flag_name {
        const char *name;
        unsigned int flag;
@@ -239,11 +244,21 @@ static const char *nlmsg_rtnl_type2str(uint16_t type)
 
 static const char *nlmsg_genl_type2str(uint16_t type)
 {
-       switch (type) {
-       case GENL_ID_GENERATE:  return "id gen";
-       case GENL_ID_CTRL:      return "id ctrl";
-       default:                return NULL;
-       }
+       struct genl_family *fam;
+
+       if (type == GENL_ID_GENERATE)
+               return "id gen";
+       if (type == GENL_ID_CTRL)
+               return "id ctrl";
+
+       if (!genl_af_cache)
+               return NULL;
+
+       fam = genl_ctrl_search(genl_af_cache, type);
+       if (!fam)
+               return NULL;
+
+       return genl_family_get_name(fam);
 }
 
 static char *nlmsg_type2str(uint16_t proto, uint16_t type, char *buf, int len)
@@ -946,6 +961,16 @@ static void genl_msg_print(struct nlmsghdr *hdr)
        genl_print_ctrl_attrs(hdr);
 }
 
+static bool nlmsg_skip(struct nlmsghdr *hdr)
+{
+       if (genl_sock) {
+               if (nl_socket_get_local_port(genl_sock) == hdr->nlmsg_pid)
+                       return true;
+       }
+
+       return false;
+}
+
 static void nlmsg_print(uint16_t family, struct nlmsghdr *hdr)
 {
        u16 nlmsg_flags = hdr->nlmsg_flags;
@@ -953,6 +978,9 @@ static void nlmsg_print(uint16_t family, struct nlmsghdr 
*hdr)
        char flags[128];
        char procname[PATH_MAX];
 
+       if (nlmsg_skip(hdr))
+               return;
+
        /* Look up the process name if message is not coming from the kernel.
         *
         * Note that the port id is not necessarily equal to the PID of the
@@ -1046,7 +1074,51 @@ static void nlmsg_less(struct pkt_buff *pkt)
                colorize_end());
 }
 
+static void genl_init(void)
+{
+       int err;
+
+       genl_sock = nl_socket_alloc();
+       if (!genl_sock) {
+               fprintf(stderr, "Could not allocate genl socket\n");
+               return;
+       }
+
+       err = nl_connect(genl_sock, NETLINK_GENERIC);
+       if (err < 0) {
+               fprintf(stderr, "Could not connect genl socket\n");
+               return;
+       }
+
+       err = genl_ctrl_alloc_cache(genl_sock, &genl_af_cache);
+       if (err < 0) {
+               fprintf(stderr, "Could not allocate genl family cache\n");
+               return;
+       }
+}
+
+static void genl_uninit(void)
+{
+       nl_cache_clear(genl_af_cache);
+       nl_cache_free(genl_af_cache);
+
+       nl_close(genl_sock);
+       nl_socket_free(genl_sock);
+}
+
+static void nlmsg_init(void)
+{
+       genl_init();
+}
+
+static void nlmsg_uninit(void)
+{
+       genl_uninit();
+}
+
 struct protocol nlmsg_ops = {
+       .init       = nlmsg_init,
+       .uninit     = nlmsg_uninit,
        .print_full = nlmsg,
        .print_less = nlmsg_less,
 };
diff --git a/protos.h b/protos.h
index 201439a..e077657 100644
--- a/protos.h
+++ b/protos.h
@@ -1,7 +1,7 @@
 #ifndef PROTOS_H
 #define PROTOS_H
 
-struct protocol;
+#include "proto.h"
 
 extern struct protocol arp_ops;
 extern struct protocol ethernet_ops;
-- 
2.6.2

-- 
You received this message because you are subscribed to the Google Groups 
"netsniff-ng" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to