* nlattr.h (nla_decoder_t): New typedef.
(DECL_NLA): New macro.
(decode_nlattr): Add decoders, size and opaque_data argument.
* nlattr.c: (decode_nlattr_with_data): Likewise.
(decode_nla_*): New functions.
* netlink_sock_diag.c (decode_inet_diag_req_compat)
(decode_inet_diag_req_v2, decode_inet_diag_msg)
(decode_netlink_diag_msg, (decode_packet_diag_msg)
(decode_smc_diag_msg, decode_unix_diag_msg): Add decoders,
size and opaque_data arguments. All callers updated.

Co-authored-by: Fabien Siron <fabien.si...@epita.fr>
---
 netlink_sock_diag.c | 21 ++++++++++++------
 nlattr.c            | 63 +++++++++++++++++++++++++++++++++++++++++++++++++----
 nlattr.h            | 27 +++++++++++++++++++++--
 3 files changed, 98 insertions(+), 13 deletions(-)

diff --git a/netlink_sock_diag.c b/netlink_sock_diag.c
index 8b5d156..314edf7 100644
--- a/netlink_sock_diag.c
+++ b/netlink_sock_diag.c
@@ -148,7 +148,8 @@ decode_unix_diag_msg(struct tcb *const tcp,
        if (decode_nla && len > offset) {
                tprints(", ");
                decode_nlattr(tcp, addr + offset, len - offset,
-                             unix_diag_attrs, "UNIX_DIAG_???");
+                             unix_diag_attrs, "UNIX_DIAG_???",
+                             NULL, 0, NULL);
        }
 }
 
@@ -237,7 +238,8 @@ decode_netlink_diag_msg(struct tcb *const tcp,
        if (decode_nla && len > offset) {
                tprints(", ");
                decode_nlattr(tcp, addr + offset, len - offset,
-                             netlink_diag_attrs, "NETLINK_DIAG_???");
+                             netlink_diag_attrs, "NETLINK_DIAG_???",
+                             NULL, 0, NULL);
        }
 }
 
@@ -308,7 +310,8 @@ decode_packet_diag_msg(struct tcb *const tcp,
        if (decode_nla && len > offset) {
                tprints(", ");
                decode_nlattr(tcp, addr + offset, len - offset,
-                             packet_diag_attrs, "PACKET_DIAG_???");
+                             packet_diag_attrs, "PACKET_DIAG_???",
+                             NULL, 0, NULL);
        }
 }
 
@@ -372,7 +375,8 @@ decode_inet_diag_req_compat(struct tcb *const tcp,
        if (decode_nla && len > offset) {
                tprints(", ");
                decode_nlattr(tcp, addr + offset, len - offset,
-                             inet_diag_req_attrs, "INET_DIAG_REQ_???");
+                             inet_diag_req_attrs, "INET_DIAG_REQ_???",
+                             NULL, 0, NULL);
        }
 }
 
@@ -416,7 +420,8 @@ decode_inet_diag_req_v2(struct tcb *const tcp,
        if (decode_nla && len > offset) {
                tprints(", ");
                decode_nlattr(tcp, addr + offset, len - offset,
-                             inet_diag_req_attrs, "INET_DIAG_REQ_???");
+                             inet_diag_req_attrs, "INET_DIAG_REQ_???",
+                             NULL, 0, NULL);
        }
 }
 
@@ -482,7 +487,8 @@ decode_inet_diag_msg(struct tcb *const tcp,
        if (decode_nla && len > offset) {
                tprints(", ");
                decode_nlattr(tcp, addr + offset, len - offset,
-                             inet_diag_attrs, "INET_DIAG_???");
+                             inet_diag_attrs, "INET_DIAG_???",
+                             NULL, 0, NULL);
        }
 }
 
@@ -562,7 +568,8 @@ decode_smc_diag_msg(struct tcb *const tcp,
        if (decode_nla && len > offset) {
                tprints(", ");
                decode_nlattr(tcp, addr + offset, len - offset,
-                             smc_diag_attrs, "SMC_DIAG_???");
+                             smc_diag_attrs, "SMC_DIAG_???",
+                             NULL, 0, NULL);
        }
 }
 #endif
diff --git a/nlattr.c b/nlattr.c
index 8c51629..3a3a0d7 100644
--- a/nlattr.c
+++ b/nlattr.c
@@ -29,6 +29,7 @@
 
 #include "defs.h"
 #include "netlink.h"
+#include "nlattr.h"
 
 static bool
 fetch_nlattr(struct tcb *const tcp, struct nlattr *const nlattr,
@@ -65,7 +66,10 @@ decode_nlattr_with_data(struct tcb *tcp,
                        kernel_ulong_t addr,
                        kernel_ulong_t len,
                        const struct xlat *const table,
-                       const char *const dflt)
+                       const char *const dflt,
+                       const nla_decoder_t *const decoders,
+                       const unsigned int size,
+                       const void *const opaque_data)
 {
        const unsigned int nla_len = nla->nla_len > len ? len : nla->nla_len;
 
@@ -76,7 +80,13 @@ decode_nlattr_with_data(struct tcb *tcp,
 
        if (nla_len > NLA_HDRLEN) {
                tprints(", ");
-               printstrn(tcp, addr + NLA_HDRLEN, nla_len - NLA_HDRLEN);
+               if (!decoders
+                   || nla->nla_type >= size
+                   || !decoders[nla->nla_type]
+                   || !decoders[nla->nla_type](tcp, addr + NLA_HDRLEN,
+                                               nla_len - NLA_HDRLEN,
+                                               opaque_data))
+                       printstrn(tcp, addr + NLA_HDRLEN, len - NLA_HDRLEN);
                tprints("}");
        }
 }
@@ -86,7 +96,10 @@ decode_nlattr(struct tcb *const tcp,
              kernel_ulong_t addr,
              kernel_ulong_t len,
              const struct xlat *const table,
-             const char *const dflt)
+             const char *const dflt,
+             const nla_decoder_t *const decoders,
+             const unsigned int size,
+             const void *const opaque_data)
 {
        struct nlattr nla;
        bool print_array = false;
@@ -114,7 +127,8 @@ decode_nlattr(struct tcb *const tcp,
                        print_array = true;
                }
 
-               decode_nlattr_with_data(tcp, &nla, addr, len, table, dflt);
+               decode_nlattr_with_data(tcp, &nla, addr, len, table, dflt,
+                                       decoders, size, opaque_data);
 
                if (!next_addr)
                        break;
@@ -128,3 +142,44 @@ decode_nlattr(struct tcb *const tcp,
                tprints("]");
        }
 }
+
+bool
+decode_nla_str(struct tcb *tcp, kernel_ulong_t addr,
+              kernel_ulong_t len, const void *const opaque_data)
+{
+       printstr_ex(tcp, addr, len, QUOTE_0_TERMINATED);
+
+       return true;
+}
+
+bool
+decode_nla_strn(struct tcb *tcp, kernel_ulong_t addr,
+               kernel_ulong_t len, const void *const opaque_data)
+{
+       printstrn(tcp, addr, len);
+
+       return true;
+}
+
+#define DECODE_NLA_INTEGER(name, type, fmt)                            \
+bool                                                                   \
+decode_nla_ ## name(struct tcb *tcp, kernel_ulong_t addr,              \
+                   kernel_ulong_t len, const void *const opaque_data)  \
+{                                                                      \
+       type num;                                                       \
+                                                                       \
+       if (len < sizeof(num))                                          \
+               return false;                                           \
+       if (!umove_or_printaddr(tcp, addr, &num))                       \
+               tprintf(fmt, num);                                      \
+       return true;                                                    \
+}
+
+DECODE_NLA_INTEGER(u8, uint8_t, "%" PRIu8)
+DECODE_NLA_INTEGER(u16, uint16_t, "%" PRIu16)
+DECODE_NLA_INTEGER(u32, uint32_t, "%" PRIu32)
+DECODE_NLA_INTEGER(u64, uint64_t, "%" PRIu64)
+DECODE_NLA_INTEGER(s8, int8_t, "%" PRId8)
+DECODE_NLA_INTEGER(s16, int16_t, "%" PRId16)
+DECODE_NLA_INTEGER(s32, int32_t, "%" PRId32)
+DECODE_NLA_INTEGER(s64, int64_t, "%" PRId64)
diff --git a/nlattr.h b/nlattr.h
index ade2271..84b9abc 100644
--- a/nlattr.h
+++ b/nlattr.h
@@ -30,8 +30,31 @@
 #ifndef STRACE_NLATTR_H
 #define STRACE_NLATTR_H
 
+typedef bool (*nla_decoder_t)(struct tcb *, kernel_ulong_t addr,
+                             kernel_ulong_t len, const void *opaque_data);
 extern void
-decode_nlattr(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len,
-             const struct xlat *, const char *);
+decode_nlattr(struct tcb *,
+             kernel_ulong_t addr,
+             kernel_ulong_t len,
+             const struct xlat *,
+             const char *dflt,
+             const nla_decoder_t *,
+             const unsigned int size,
+             const void *opaque_data);
+
+#define DECL_NLA(name)                                 \
+extern bool                                            \
+decode_nla_ ## name(struct tcb *, kernel_ulong_t addr, \
+                   kernel_ulong_t len, const void *)
+DECL_NLA(u8);
+DECL_NLA(u16);
+DECL_NLA(u32);
+DECL_NLA(u64);
+DECL_NLA(s8);
+DECL_NLA(s16);
+DECL_NLA(s32);
+DECL_NLA(s64);
+DECL_NLA(str);
+DECL_NLA(strn);
 
 #endif /* !STRACE_NLATTR_H */
-- 
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

Reply via email to