diff --git a/Makefile.am b/Makefile.am index 2266fa27..75a9828e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -564,6 +564,7 @@ EXTRA_DIST = \ linux/or1k/set_scno.c \ linux/or1k/syscallent.h \ linux/or1k/userent.h \ + linux/packet_diag.h \ linux/personality.h \ linux/powerpc/arch_regs.c \ linux/powerpc/arch_regs.h \ diff --git a/defs.h b/defs.h index 3b60d3d4..f7d25f0c 100644 --- a/defs.h +++ b/defs.h @@ -291,6 +291,7 @@ extern const struct xlat addrfams[]; 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 msg_flags[]; extern const struct xlat netlink_protocols[]; diff --git a/linux/packet_diag.h b/linux/packet_diag.h new file mode 100644 index 00000000..10f48d9c --- /dev/null +++ b/linux/packet_diag.h @@ -0,0 +1,29 @@ +#ifndef STRACE_LINUX_PACKET_DIAG_H +#define STRACE_LINUX_PACKET_DIAG_H + +struct packet_diag_req { + uint8_t sdiag_family; + uint8_t sdiag_protocol; + uint16_t pad; + uint32_t pdiag_ino; + uint32_t pdiag_show; + uint32_t pdiag_cookie[2]; +}; + +#define PACKET_SHOW_INFO 0x00000001 +#define PACKET_SHOW_MCLIST 0x00000002 +#define PACKET_SHOW_RING_CFG 0x00000004 +#define PACKET_SHOW_FANOUT 0x00000008 +#define PACKET_SHOW_MEMINFO 0x00000010 +#define PACKET_SHOW_FILTER 0x00000020 + +struct packet_diag_msg { + uint8_t pdiag_family; + uint8_t pdiag_type; + uint16_t pdiag_num; + + uint32_t pdiag_ino; + uint32_t pdiag_cookie[2]; +}; + +#endif /* !STRACE_LINUX_PACKET_DIAG_H */ diff --git a/netlink_sock_diag.c b/netlink_sock_diag.c index f4829572..91749dd4 100644 --- a/netlink_sock_diag.c +++ b/netlink_sock_diag.c @@ -32,6 +32,7 @@ #include <sys/socket.h> #include <linux/netlink.h> #include <linux/netlink_diag.h> +#include <linux/packet_diag.h> #include <linux/unix_diag.h> #include "xlat/tcp_states.h" @@ -40,6 +41,8 @@ #include "xlat/netlink_diag_show.h" #include "xlat/netlink_states.h" +#include "xlat/packet_diag_show.h" + #include "xlat/unix_diag_show.h" static void @@ -202,6 +205,68 @@ decode_netlink_diag_msg(struct tcb *const tcp, tprints("}"); } +static void +decode_packet_diag_req(struct tcb *const tcp, + const struct nlmsghdr *const nlmsghdr, + const uint8_t family, + const kernel_ulong_t addr, + const kernel_ulong_t len) +{ + struct packet_diag_req req = { .sdiag_family = family }; + const size_t offset = sizeof(req.sdiag_family); + + tprints("{sdiag_family="); + printxval(addrfams, req.sdiag_family, "AF_???"); + tprints(", "); + if (len >= sizeof(req)) { + if (!umoven_or_printaddr(tcp, addr + offset, + sizeof(req) - offset, + (void *) &req + offset)) { + tprints("sdiag_protocol="); + printxval(ethernet_protocols, req.sdiag_protocol, + "ETH_P_???"); + tprintf(", pdiag_ino=%" PRIu32 ", pdiag_show=", + req.pdiag_ino); + printflags(packet_diag_show, req.pdiag_show, + "PACKET_SHOW_???"); + tprintf(", pdiag_cookie=[%" PRIu32 ", %" PRIu32 "]", + req.pdiag_cookie[0], req.pdiag_cookie[1]); + } + } else + tprints("..."); + tprints("}"); +} + +static void +decode_packet_diag_msg(struct tcb *const tcp, + const struct nlmsghdr *const nlmsghdr, + const uint8_t family, + const kernel_ulong_t addr, + const kernel_ulong_t len) +{ + struct packet_diag_msg msg = { .pdiag_family = family }; + const size_t offset = sizeof(msg.pdiag_family); + + tprints("{pdiag_family="); + printxval(addrfams, msg.pdiag_family, "AF_???"); + + tprints(", "); + if (len >= sizeof(msg)) { + if (!umoven_or_printaddr(tcp, addr + offset, + sizeof(msg) - offset, + (void *) &msg + offset)) { + tprints("pdiag_type="); + printxval(socktypes, msg.pdiag_type, "SOCK_???"); + tprintf(", pdiag_num=%" PRIu16 ", pdiag_ino=%" PRIu32 + ", pdiag_cookie=[%" PRIu32 ", %" PRIu32 "]", + msg.pdiag_num, msg.pdiag_ino, msg.pdiag_cookie[0], + msg.pdiag_cookie[1]); + } + } else + tprints("..."); + tprints("}"); +} + typedef void (*netlink_diag_decoder_t)(struct tcb *, const struct nlmsghdr *, uint8_t family, @@ -212,6 +277,7 @@ static const struct { const netlink_diag_decoder_t request, response; } diag_decoders[] = { [AF_NETLINK] = { decode_netlink_diag_req, decode_netlink_diag_msg }, + [AF_PACKET] = { decode_packet_diag_req, decode_packet_diag_msg }, [AF_UNIX] = { decode_unix_diag_req, decode_unix_diag_msg } }; diff --git a/xlat/packet_diag_show.in b/xlat/packet_diag_show.in new file mode 100644 index 00000000..b495af81 --- /dev/null +++ b/xlat/packet_diag_show.in @@ -0,0 +1,6 @@ +PACKET_SHOW_INFO +PACKET_SHOW_MCLIST +PACKET_SHOW_RING_CFG +PACKET_SHOW_FANOUT +PACKET_SHOW_MEMINFO +PACKET_SHOW_FILTER