Dump Generic netlink ops & mcast groups nested attributes.

Signed-off-by: Vadim Kochan <vadi...@gmail.com>
---
 proto_nlmsg.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 92 insertions(+), 14 deletions(-)

diff --git a/proto_nlmsg.c b/proto_nlmsg.c
index c9238c8..cd3b8c4 100644
--- a/proto_nlmsg.c
+++ b/proto_nlmsg.c
@@ -85,6 +85,16 @@
        tprintf("\tA: "fmt, ##__VA_ARGS__); \
        tprintf(", Len %d\n", NLA_LEN(attr));
 
+#define nla_fmt_nested(attr, fmt, ...) \
+       tprintf("[ "fmt, ##__VA_ARGS__); \
+       tprintf(", Len %d] ", NLA_LEN(attr));
+
+#define nla_fmt_nested_start(attr, fmt, ...)    \
+       tprintf("\t    A: "fmt, ##__VA_ARGS__); \
+       tprintf(", Len %d ", NLA_LEN(attr));
+
+#define nla_fmt_nested_end() tprintf("\n")
+
 struct flag_name {
        const char *name;
        unsigned int flag;
@@ -808,7 +818,77 @@ static const char *genl_cmd2str(uint8_t table)
        }
 }
 
-static void genl_print_ctrl_family(struct nlmsghdr *hdr)
+static struct flag_name genl_ops_flags[] = {
+       { "admin", GENL_ADMIN_PERM },
+       { "doit", GENL_CMD_CAP_DO },
+       { "dumpit", GENL_CMD_CAP_DUMP },
+       { "policy", GENL_CMD_CAP_HASPOL },
+       { NULL, 0 },
+};
+
+static void genl_print_ops_attr(struct nlattr *attr, uint32_t attr_len)
+{
+       char str[256];
+       uint32_t flags;
+
+       for (; NLA_OK(attr, attr_len); attr = NLA_NEXT(attr, attr_len)) {
+               switch (attr->nla_type) {
+               case CTRL_ATTR_OP_ID:
+                       nla_fmt_nested(attr, "Id 0x%x", NLA_UINT32(attr));
+                       break;
+
+               case CTRL_ATTR_OP_FLAGS:
+                       flags = NLA_UINT32(attr);
+
+                       nla_fmt_nested(attr, "Flags 0x%x (%s%s%s)", flags,
+                       colorize_start(bold),
+                       flags2str(genl_ops_flags, flags, str, sizeof(str)),
+                       colorize_end());
+                       break;
+               default:
+                       nla_fmt_nested(attr, "0x%x", attr->nla_type);
+                       break;
+               }
+       }
+}
+
+static void genl_print_ops_list(struct nlattr *attr, uint32_t attr_len)
+{
+       for (; NLA_OK(attr, attr_len); attr = NLA_NEXT(attr, attr_len)) {
+               nla_fmt_nested_start(attr, "0x%x", attr->nla_type);
+               genl_print_ops_attr(NLA_DATA(attr), NLA_LEN(attr));
+               nla_fmt_nested_end();
+       }
+}
+
+static void genl_print_mcast_group(struct nlattr *attr, uint32_t attr_len)
+{
+       for (; NLA_OK(attr, attr_len); attr = NLA_NEXT(attr, attr_len)) {
+               switch (attr->nla_type) {
+               case CTRL_ATTR_MCAST_GRP_ID:
+                       nla_fmt_nested(attr, "Id 0x%x", NLA_UINT32(attr));
+                       break;
+
+               case CTRL_ATTR_MCAST_GRP_NAME:
+                       nla_fmt_nested(attr, "Name %s", NLA_STR(attr));
+                       break;
+               default:
+                       nla_fmt_nested(attr, "0x%x", attr->nla_type);
+                       break;
+               }
+       }
+}
+
+static void genl_print_mc_groups(struct nlattr *attr, uint32_t attr_len)
+{
+       for (; NLA_OK(attr, attr_len); attr = NLA_NEXT(attr, attr_len)) {
+               nla_fmt_nested_start(attr, "0x%x", attr->nla_type);
+               genl_print_mcast_group(NLA_DATA(attr), NLA_LEN(attr));
+               nla_fmt_nested_end();
+       }
+}
+
+static void genl_print_ctrl_attrs(struct nlmsghdr *hdr)
 {
        struct genlmsghdr *genl = NLMSG_DATA(hdr);
        struct nlattr *attr = GEN_NLA(genl);
@@ -836,6 +916,16 @@ static void genl_print_ctrl_family(struct nlmsghdr *hdr)
                        nla_fmt(attr, "Max attr value 0x%x", NLA_UINT32(attr));
                        break;
 
+               case CTRL_ATTR_OPS:
+                       nla_fmt(attr, "Ops list");
+                       genl_print_ops_list(NLA_DATA(attr), NLA_LEN(attr));
+                       break;
+
+               case CTRL_ATTR_MCAST_GROUPS:
+                       nla_fmt(attr, "Mcast groups");
+                       genl_print_mc_groups(NLA_DATA(attr), NLA_LEN(attr));
+                       break;
+
                default:
                        nla_fmt(attr, "0x%x", attr->nla_type);
                        break;
@@ -843,18 +933,6 @@ static void genl_print_ctrl_family(struct nlmsghdr *hdr)
        }
 }
 
-static void genl_print_ctrl(struct nlmsghdr *hdr)
-{
-       struct genlmsghdr *genl = NLMSG_DATA(hdr);
-
-       switch (genl->cmd) {
-       case CTRL_CMD_NEWFAMILY:
-       case CTRL_CMD_DELFAMILY:
-       case CTRL_CMD_GETFAMILY:
-               genl_print_ctrl_family(hdr);
-       }
-}
-
 static void genl_msg_print(struct nlmsghdr *hdr)
 {
        struct genlmsghdr *genl;
@@ -872,7 +950,7 @@ static void genl_msg_print(struct nlmsghdr *hdr)
        tprintf(", Reserved %u", genl->reserved);
        tprintf(" ]\n");
 
-       genl_print_ctrl(hdr);
+       genl_print_ctrl_attrs(hdr);
 }
 
 static void nlmsg_print(uint16_t family, struct nlmsghdr *hdr)
-- 
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 netsniff-ng+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to