[PATCH 4/5] netlink: add a basic rtnetlink parser of link messages
JingPiao Chen
chenjingpiao at gmail.com
Tue Jul 25 14:30:02 UTC 2017
* 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.siron at 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
More information about the Strace-devel
mailing list