diff --git a/Makefile.am b/Makefile.am index 23ce121f..7e7d3db6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -194,6 +194,7 @@ strace_SOURCES = \ netlink_netlink_diag.c \ netlink_packet_diag.c \ netlink_route.c \ + netlink_route.h \ netlink_selinux.c \ netlink_smc_diag.c \ netlink_sock_diag.c \ @@ -246,6 +247,7 @@ strace_SOURCES = \ rt_sigframe.c \ rt_sigreturn.c \ rtc.c \ + rtnl_link.c \ sched.c \ sched_attr.h \ scsi.c \ diff --git a/defs.h b/defs.h index 5b09f2e3..2efbfa36 100644 --- a/defs.h +++ b/defs.h @@ -284,11 +284,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 dc5a13f4..f6d569ba 100644 --- a/netlink_route.c +++ b/netlink_route.c @@ -29,6 +29,9 @@ #include "defs.h" #include "netlink.h" +#include "netlink_route.h" + +#include #include "xlat/nl_route_types.h" @@ -46,6 +49,15 @@ decode_family(struct tcb *const tcp, const uint8_t family, tprints("}"); } +typedef DECL_NETLINK_ROUTE_DECODER((*netlink_route_decoder_t)); + +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, @@ -57,8 +69,16 @@ decode_netlink_route(struct tcb *const tcp, 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)) { + const unsigned int index = nlmsghdr->nlmsg_type - RTM_BASE; + + if (index < ARRAY_SIZE(route_decoders) + && route_decoders[index]) { + route_decoders[index](tcp, nlmsghdr, family, addr, len); + } else { + decode_family(tcp, family, addr, len); + } + } return true; } diff --git a/netlink_route.h b/netlink_route.h new file mode 100644 index 00000000..cc2b5c2c --- /dev/null +++ b/netlink_route.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 Fabien Siron + * Copyright (c) 2017 JingPiao Chen + * Copyright (c) 2016-2017 The strace developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef STRACE_NETLINK_ROUTE_H +#define STRACE_NETLINK_ROUTE_H + +#define DECL_NETLINK_ROUTE_DECODER(route_decode_name) \ +void \ +route_decode_name(struct tcb *tcp, \ + const struct nlmsghdr *nlmsghdr, \ + uint8_t family, \ + kernel_ulong_t addr, \ + unsigned int len) \ +/* End of DECL_NETLINK_ROUTE_DECODER definition. */ + +extern DECL_NETLINK_ROUTE_DECODER(decode_ifinfomsg); + +#endif /* !STRACE_NETLINK_ROUTE_H */ diff --git a/rtnl_link.c b/rtnl_link.c new file mode 100644 index 00000000..876baffe --- /dev/null +++ b/rtnl_link.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 Fabien Siron + * Copyright (c) 2017 JingPiao Chen + * Copyright (c) 2016-2017 The strace developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "defs.h" +#include "netlink_route.h" +#include "print_fields.h" + +#include + +DECL_NETLINK_ROUTE_DECODER(decode_ifinfomsg) +{ + 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("}"); +}