* defs.h (arp_hardware_types, iffflags): New xlat prototypes.
* netlink_route.c: Include "print_fields.h" and <linux/rtnetlink.h>.
(decode_ifinfomsg): New function.
(netlink_route_decoder_t): New typedef.
(route_decoders): New array.
(decode_netlink_route): Use it.

Co-authored-by: Fabien Siron <fabien.si...@epita.fr>
---
 defs.h          |  2 ++
 netlink_route.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/defs.h b/defs.h
index a9d0b00..dec87bf 100644
--- a/defs.h
+++ b/defs.h
@@ -287,11 +287,13 @@ struct tcb {
 #include "xlat.h"
 
 extern const struct xlat addrfams[];
+extern const struct xlat arp_hardware_types[];
 extern const struct xlat at_flags[];
 extern const struct xlat clocknames[];
 extern const struct xlat dirent_types[];
 extern const struct xlat ethernet_protocols[];
 extern const struct xlat evdev_abs[];
+extern const struct xlat iffflags[];
 extern const struct xlat inet_protocols[];
 extern const struct xlat msg_flags[];
 extern const struct xlat netlink_protocols[];
diff --git a/netlink_route.c b/netlink_route.c
index dc5a13f..3da6dfb 100644
--- a/netlink_route.c
+++ b/netlink_route.c
@@ -29,6 +29,9 @@
 
 #include "defs.h"
 #include "netlink.h"
+#include "print_fields.h"
+
+#include <linux/rtnetlink.h>
 
 #include "xlat/nl_route_types.h"
 
@@ -46,19 +49,69 @@ decode_family(struct tcb *const tcp, const uint8_t family,
        tprints("}");
 }
 
+static void
+decode_ifinfomsg(struct tcb *tcp,
+                const struct nlmsghdr *nlmsghdr,
+                const uint8_t family,
+                const kernel_ulong_t addr,
+                const unsigned int len)
+{
+       struct ifinfomsg ifinfo = { .ifi_family = family };
+       const size_t offset = sizeof(ifinfo.ifi_family);
+
+       PRINT_FIELD_XVAL("{", ifinfo, ifi_family, addrfams, "AF_???");
+
+       tprints(", ");
+       if (len >= sizeof(ifinfo)) {
+               if (!umoven_or_printaddr(tcp, addr + offset,
+                                        sizeof(ifinfo) - offset,
+                                        (void *) &ifinfo + offset)) {
+                       PRINT_FIELD_XVAL("", ifinfo, ifi_type,
+                                        arp_hardware_types, "ARPHRD_???");
+                       PRINT_FIELD_IFINDEX(", ", ifinfo, ifi_index);
+                       PRINT_FIELD_FLAGS(", ", ifinfo, ifi_flags,
+                                         iffflags, "IFF_???");
+                       PRINT_FIELD_X(", ", ifinfo, ifi_change);
+               }
+       } else
+               tprints("...");
+       tprints("}");
+}
+
+typedef void (*netlink_route_decoder_t)(struct tcb *,
+                                       const struct nlmsghdr *,
+                                       uint8_t family,
+                                       kernel_ulong_t addr,
+                                       unsigned int len);
+
+static const netlink_route_decoder_t route_decoders[] = {
+       [RTM_DELLINK - RTM_BASE] = decode_ifinfomsg,
+       [RTM_GETLINK - RTM_BASE] = decode_ifinfomsg,
+       [RTM_NEWLINK - RTM_BASE] = decode_ifinfomsg,
+       [RTM_SETLINK - RTM_BASE] = decode_ifinfomsg
+};
+
 bool
 decode_netlink_route(struct tcb *const tcp,
                     const struct nlmsghdr *const nlmsghdr,
                     const kernel_ulong_t addr,
                     const unsigned int len)
 {
+       unsigned int type = nlmsghdr->nlmsg_type;
        uint8_t family;
 
        if (nlmsghdr->nlmsg_type == NLMSG_DONE)
                return false;
 
-       if (!umove_or_printaddr(tcp, addr, &family))
-               decode_family(tcp, family, addr, len);
+       if (!umove_or_printaddr(tcp, addr, &family)) {
+               if (type > RTM_BASE
+                   && type - RTM_BASE < ARRAY_SIZE(route_decoders)
+                   && route_decoders[type - RTM_BASE]) {
+                       route_decoders[type - RTM_BASE](tcp, nlmsghdr,
+                                                       family, addr, len);
+               } else
+                       decode_family(tcp, family, addr, len);
+       }
 
        return true;
 }
-- 
2.7.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Strace-devel mailing list
Strace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to