]> granicus.if.org Git - strace/commitdiff
netlink: add a basic socket diag parser of AF_PACKET messages
authorJingPiao Chen <chenjingpiao@gmail.com>
Tue, 13 Jun 2017 03:50:15 +0000 (11:50 +0800)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 15 Jun 2017 22:44:04 +0000 (22:44 +0000)
* linux/packet_diag.h: New file.
* Makefile.am (EXTRA_DIST): Add it.
* defs.h (ethernet_protocols): New xlat prototype.
* netlink_sock_diag.c: Include <linux/packet_diag.h>
and "xlat/packet_diag_show.h".
(decode_packet_diag_req, decode_packet_diag_msg): New functions.
(diag_decoders): Add AF_PACKET.
* xlat/packet_diag_show.in: New file.

Co-authored-by: Fabien Siron <fabien.siron@epita.fr>
Makefile.am
defs.h
linux/packet_diag.h [new file with mode: 0644]
netlink_sock_diag.c
xlat/packet_diag_show.in [new file with mode: 0644]

index 2266fa278c74f8a93b522ce12e7c31f1f0d5be36..75a9828eab1d54225db940b8b7641cef02f240fa 100644 (file)
@@ -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 3b60d3d4dc30dd834a967bac76e08f3b8060b058..f7d25f0ce98c88bcc856e58e604483cb0db9f8db 100644 (file)
--- 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 (file)
index 0000000..10f48d9
--- /dev/null
@@ -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 */
index f4829572d3b9d97a1406c2028fcad433b35a4e3f..91749dd4e77c0f84b33f41d329c42421c35eb710 100644 (file)
@@ -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 (file)
index 0000000..b495af8
--- /dev/null
@@ -0,0 +1,6 @@
+PACKET_SHOW_INFO
+PACKET_SHOW_MCLIST
+PACKET_SHOW_RING_CFG
+PACKET_SHOW_FANOUT
+PACKET_SHOW_MEMINFO
+PACKET_SHOW_FILTER