* rtnl_addr.c: Include <arpa/inet.h> and <linux/netdevice.h>. (decode_ifa_address, decode_ifa_cacheinfo, decode_ifa_flags): New functions. (ifaddrmsg_nla_decoders): New array. (decode_ifaddrmsg): Use it. --- rtnl_addr.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-)
diff --git a/rtnl_addr.c b/rtnl_addr.c index c7e37ea..c4bde06 100644 --- a/rtnl_addr.c +++ b/rtnl_addr.c @@ -32,16 +32,106 @@ #include "nlattr.h" #include "print_fields.h" +#include <arpa/inet.h> + #include "netlink.h" #include <linux/rtnetlink.h> #ifdef HAVE_LINUX_IF_ADDR_H # include <linux/if_addr.h> #endif +#include <linux/netdevice.h> #include "xlat/ifaddrflags.h" #include "xlat/routing_scopes.h" #include "xlat/rtnl_addr_attrs.h" +static bool +decode_ifa_address(struct tcb *const tcp, + const kernel_ulong_t addr, + const unsigned int len, + const void *const opaque_data) +{ + const struct ifaddrmsg *const ifaddr = opaque_data; + const unsigned int addr_len = + len < MAX_ADDR_LEN ? len : MAX_ADDR_LEN; + char buf[MAX_ADDR_LEN]; + + if (!umoven_or_printaddr(tcp, addr, addr_len, buf)) { + switch (ifaddr->ifa_family) { + case AF_INET: { + char str[INET_ADDRSTRLEN]; + + if (addr_len < sizeof(struct in_addr) + || !inet_ntop(AF_INET, buf, str, sizeof(str))) + return false; + tprints(str); + break; + } + case AF_INET6: { + char str[INET6_ADDRSTRLEN]; + + if (addr_len < sizeof(struct in6_addr) + || !inet_ntop(AF_INET6, buf, str, sizeof(str))) + break; + tprints(str); + break; + } + default: + return false; + } + } + + return true; +} + +static bool +decode_ifa_cacheinfo(struct tcb *const tcp, + const kernel_ulong_t addr, + const unsigned int len, + const void *const opaque_data) +{ + struct ifa_cacheinfo ci; + + if (len < sizeof(ci)) + return false; + else if (!umove_or_printaddr(tcp, addr, &ci)) { + PRINT_FIELD_U("{", ci, ifa_prefered); + PRINT_FIELD_U(", ", ci, ifa_valid); + PRINT_FIELD_U(", ", ci, cstamp); + PRINT_FIELD_U(", ", ci, tstamp); + tprintf("}"); + } + + return true; +} + +static bool +decode_ifa_flags(struct tcb *const tcp, + const kernel_ulong_t addr, + const unsigned int len, + const void *const opaque_data) +{ + uint32_t ifa_flags; + + if (len < sizeof(ifa_flags)) + return false; + else if (!umove_or_printaddr(tcp, addr, &ifa_flags)) + printflags(ifaddrflags, ifa_flags, "IFA_F_???"); + + return true; +} + +static const nla_decoder_t ifaddrmsg_nla_decoders[] = { + [IFA_ADDRESS] = decode_ifa_address, + [IFA_LOCAL] = decode_ifa_address, + [IFA_LABEL] = decode_nla_str, + [IFA_BROADCAST] = decode_ifa_address, + [IFA_ANYCAST] = decode_ifa_address, + [IFA_CACHEINFO] = decode_ifa_cacheinfo, + [IFA_MULTICAST] = decode_ifa_address, + [IFA_FLAGS] = decode_ifa_flags +}; + DECL_NETLINK_ROUTE_DECODER(decode_ifaddrmsg) { struct ifaddrmsg ifaddr = { .ifa_family = family }; @@ -71,6 +161,8 @@ DECL_NETLINK_ROUTE_DECODER(decode_ifaddrmsg) if (decode_nla && len > offset) { tprints(", "); decode_nlattr(tcp, addr + offset, len - offset, - rtnl_addr_attrs, "IFA_???", NULL, 0, NULL); + rtnl_addr_attrs, "IFA_???", + ifaddrmsg_nla_decoders, + ARRAY_SIZE(ifaddrmsg_nla_decoders), &ifaddr); } } -- 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