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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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
#include "defs.h"
#include "netlink.h"
+#include "nlattr.h"
static bool
fetch_nlattr(struct tcb *const tcp, struct nlattr *const nlattr,
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;
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("}");
}
}
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;
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;
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)
#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 *,
+ 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 */