]> granicus.if.org Git - strace/blobdiff - rtnl_mdb.c
nlattr: add UID/GID netlink attribute decoders
[strace] / rtnl_mdb.c
index f0171fbc8d8ae07f5635ce144ac5a959bac772a9..c28b9e0d6fa519002e2968aded2255b9735381f9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
  * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
- * Copyright (c) 2016-2017 The strace developers.
+ * Copyright (c) 2016-2018 The strace developers.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #ifdef HAVE_STRUCT_BR_PORT_MSG
 
 # include "netlink_route.h"
+# include "nlattr.h"
 # include "print_fields.h"
 
 # include <netinet/in.h>
 # include <linux/if_bridge.h>
+# include "netlink.h"
+
+# ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
+#  include "xlat/mdb_flags.h"
+# endif
+# include "xlat/mdb_states.h"
+# include "xlat/multicast_router_types.h"
+# include "xlat/rtnl_mdb_attrs.h"
+# include "xlat/rtnl_mdba_mdb_attrs.h"
+# include "xlat/rtnl_mdba_mdb_eattr_attrs.h"
+# include "xlat/rtnl_mdba_mdb_entry_attrs.h"
+# include "xlat/rtnl_mdba_router_attrs.h"
+# include "xlat/rtnl_mdba_router_pattr_attrs.h"
+
+static const nla_decoder_t mdba_mdb_eattr_nla_decoders[] = {
+       [MDBA_MDB_EATTR_TIMER]  = decode_nla_u32
+};
+
+static bool
+decode_mdba_mdb_entry_info(struct tcb *const tcp,
+                          const kernel_ulong_t addr,
+                          const unsigned int len,
+                          const void *const opaque_data)
+{
+# ifdef HAVE_STRUCT_BR_MDB_ENTRY
+       struct br_mdb_entry entry;
+
+       if (len < sizeof(entry))
+               return false;
+       else if (!umove_or_printaddr(tcp, addr, &entry)) {
+               PRINT_FIELD_IFINDEX("{", entry, ifindex);
+               PRINT_FIELD_XVAL(", ", entry, state, mdb_states, "MDB_???");
+#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
+               PRINT_FIELD_FLAGS(", ", entry, flags,
+                                 mdb_flags, "MDB_FLAGS_???");
+#  endif
+#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
+               PRINT_FIELD_U(", ", entry, vid);
+#  endif
+
+               const int proto = ntohs(entry.addr.proto);
+
+               tprints(", addr={");
+               print_inet_addr(proto, &entry.addr.u,
+                               sizeof(entry.addr.u), "u");
+               tprints(", proto=htons(");
+               printxval(addrfams, proto, "AF_???");
+               tprints(")}}");
+       }
+
+       const size_t offset = NLMSG_ALIGN(sizeof(entry));
+       if (len > offset) {
+               tprints(", ");
+               decode_nlattr(tcp, addr + offset, len - offset,
+                             rtnl_mdba_mdb_eattr_attrs, "MDBA_MDB_EATTR_???",
+                             mdba_mdb_eattr_nla_decoders,
+                             ARRAY_SIZE(mdba_mdb_eattr_nla_decoders), NULL);
+       }
+
+       return true;
+# else
+       return false;
+# endif /* HAVE_STRUCT_BR_MDB_ENTRY */
+}
+
+static const nla_decoder_t mdba_mdb_entry_nla_decoders[] = {
+       [MDBA_MDB_ENTRY_INFO]   = decode_mdba_mdb_entry_info
+};
+
+static bool
+decode_mdba_mdb_entry(struct tcb *const tcp,
+                     const kernel_ulong_t addr,
+                     const unsigned int len,
+                     const void *const opaque_data)
+{
+       decode_nlattr(tcp, addr, len, rtnl_mdba_mdb_entry_attrs,
+                     "MDBA_MDB_ENTRY_???", mdba_mdb_entry_nla_decoders,
+                     ARRAY_SIZE(mdba_mdb_entry_nla_decoders), NULL);
+
+       return true;
+}
+
+static const nla_decoder_t mdba_mdb_nla_decoders[] = {
+       [MDBA_MDB_ENTRY]        = decode_mdba_mdb_entry
+};
+
+static bool
+decode_mdba_mdb(struct tcb *const tcp,
+               const kernel_ulong_t addr,
+               const unsigned int len,
+               const void *const opaque_data)
+{
+       decode_nlattr(tcp, addr, len, rtnl_mdba_mdb_attrs, "MDBA_MDB_???",
+                     mdba_mdb_nla_decoders,
+                     ARRAY_SIZE(mdba_mdb_nla_decoders), NULL);
+
+       return true;
+}
+
+static bool
+decode_multicast_router_type(struct tcb *const tcp,
+                            const kernel_ulong_t addr,
+                            const unsigned int len,
+                            const void *const opaque_data)
+{
+       uint8_t type;
+
+       if (!umove_or_printaddr(tcp, addr, &type))
+               printxval(multicast_router_types, type, "MDB_RTR_TYPE_???");
+
+       return true;
+}
+
+static const nla_decoder_t mdba_router_pattr_nla_decoders[] = {
+       [MDBA_ROUTER_PATTR_TIMER]       = decode_nla_u32,
+       [MDBA_ROUTER_PATTR_TYPE]        = decode_multicast_router_type
+};
+
+static bool
+decode_mdba_router_port(struct tcb *const tcp,
+                       const kernel_ulong_t addr,
+                       const unsigned int len,
+                       const void *const opaque_data)
+{
+       uint32_t ifindex;
+
+       if (len < sizeof(ifindex))
+               return false;
+       else if (!umove_or_printaddr(tcp, addr, &ifindex))
+               print_ifindex(ifindex);
+
+       const size_t offset = NLMSG_ALIGN(sizeof(ifindex));
+       if (len > offset) {
+               tprints(", ");
+               decode_nlattr(tcp, addr + offset, len - offset,
+                             rtnl_mdba_router_pattr_attrs,
+                             "MDBA_ROUTER_PATTR_???",
+                             mdba_router_pattr_nla_decoders,
+                             ARRAY_SIZE(mdba_router_pattr_nla_decoders), NULL);
+       }
+
+       return true;
+}
+
+static const nla_decoder_t mdba_router_nla_decoders[] = {
+       [MDBA_ROUTER_PORT]      = decode_mdba_router_port
+};
+
+static bool
+decode_mdba_router(struct tcb *const tcp,
+                  const kernel_ulong_t addr,
+                  const unsigned int len,
+                  const void *const opaque_data)
+{
+       decode_nlattr(tcp, addr, len, rtnl_mdba_router_attrs, "MDBA_ROUTER_???",
+                     mdba_router_nla_decoders,
+                     ARRAY_SIZE(mdba_router_nla_decoders), NULL);
+
+       return true;
+}
+
+static const nla_decoder_t br_port_msg_nla_decoders[] = {
+       [MDBA_MDB]      = decode_mdba_mdb,
+       [MDBA_ROUTER]   = decode_mdba_router
+};
 
 DECL_NETLINK_ROUTE_DECODER(decode_br_port_msg)
 {
        struct br_port_msg bpm = { .family = family };
-       const size_t offset = sizeof(bpm.family);
+       size_t offset = sizeof(bpm.family);
+       bool decode_nla = false;
 
        PRINT_FIELD_XVAL("{", bpm, family, addrfams, "AF_???");
 
@@ -48,12 +215,22 @@ DECL_NETLINK_ROUTE_DECODER(decode_br_port_msg)
        if (len >= sizeof(bpm)) {
                if (!umoven_or_printaddr(tcp, addr + offset,
                                         sizeof(bpm) - offset,
-                                        (void *) &bpm + offset)) {
+                                        (char *) &bpm + offset)) {
                        PRINT_FIELD_IFINDEX("", bpm, ifindex);
+                       decode_nla = true;
                }
        } else
                tprints("...");
        tprints("}");
+
+       offset = NLMSG_ALIGN(sizeof(bpm));
+       if (decode_nla && len > offset) {
+               tprints(", ");
+               decode_nlattr(tcp, addr + offset, len - offset,
+                             rtnl_mdb_attrs, "MDBA_???",
+                             br_port_msg_nla_decoders,
+                             ARRAY_SIZE(br_port_msg_nla_decoders), NULL);
+       }
 }
 
 #endif