On Fri, Jun 16, 2017 at 01:35:07PM +0800, JingPiao Chen wrote: > * defs.h (decode_nlattr): New prototype. > * linux/unix_diag.h (UNIX_DIAG_*): New enum. > * netlink.c (fetch_nlattr, print_nlattr, > decode_nlattr_with_data, decode_nlattr): New functions.
Looks like there is no necessity to place these new nlattr related functions into netlink.c, what do you think about creating a new source file for this purpose, e.g. nlattr.c? > * netlink_sock_diag.c: Include "xlat/unix_diag_attrs.h". > (decode_unix_diag_msg): Use decode_nlattr. > * xlat/unix_diag_attrs.in: New file. > > co-authored-by: Fabien Siron <fabien.si...@epita.fr> > --- > defs.h | 3 ++ > linux/unix_diag.h | 11 +++++-- > netlink.c | 76 > +++++++++++++++++++++++++++++++++++++++++++++++++ > netlink_sock_diag.c | 4 +++ > xlat/unix_diag_attrs.in | 7 +++++ > 5 files changed, 99 insertions(+), 2 deletions(-) > create mode 100644 xlat/unix_diag_attrs.in > > diff --git a/defs.h b/defs.h > index 487e51b..7e3912d 100644 > --- a/defs.h > +++ b/defs.h > @@ -632,6 +632,9 @@ tprint_iov_upto(struct tcb *, kernel_ulong_t len, > kernel_ulong_t addr, > > extern void > decode_netlink(struct tcb *, int fd, kernel_ulong_t addr, kernel_ulong_t > len); > +extern void > +decode_nlattr(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t len, > + int, const struct xlat *, const char *); > > extern void tprint_open_modes(unsigned int); > extern const char *sprint_open_modes(unsigned int); > diff --git a/linux/unix_diag.h b/linux/unix_diag.h > index a6b62ba..3c9d99f 100644 > --- a/linux/unix_diag.h > +++ b/linux/unix_diag.h > @@ -27,7 +27,14 @@ struct unix_diag_msg { > uint32_t udiag_cookie[2]; > }; > > -#define UNIX_DIAG_NAME 0 > -#define UNIX_DIAG_PEER 2 > +enum { > + UNIX_DIAG_NAME, > + UNIX_DIAG_VFS, > + UNIX_DIAG_PEER, > + UNIX_DIAG_ICONS, > + UNIX_DIAG_RQLEN, > + UNIX_DIAG_MEMINFO, > + UNIX_DIAG_SHUTDOWN, > +}; > > #endif /* !STRACE_LINUX_UNIX_DIAG_H */ > diff --git a/netlink.c b/netlink.c > index 4bef949..52f3806 100644 > --- a/netlink.c > +++ b/netlink.c > @@ -49,6 +49,82 @@ > #undef NLMSG_HDRLEN > #define NLMSG_HDRLEN NLMSG_ALIGN(sizeof(struct nlmsghdr)) > > +static bool > +fetch_nlattr(struct tcb *tcp, struct nlattr *nlattr, You can add some const qualifiers here, like in fetch_nlmsghdr that was used as a template for this new function. > + const kernel_ulong_t addr, const kernel_ulong_t len) > +{ > + if (len < sizeof(struct nlattr)) { > + printstrn(tcp, addr, len); > + return false; > + } > + > + if (umove_or_printaddr(tcp, addr, nlattr)) > + return false; > + > + return true; > +} > + > +static void > +print_nlattr(const struct nlattr *const nla, > + const struct xlat *table, const char *dflt) > +{ > + tprintf("{nla_len=%u, nla_type=", nla->nla_len); > + if (nla->nla_type & NLA_F_NESTED) > + tprints("NLA_F_NESTED|"); > + if (nla->nla_type & NLA_F_NET_BYTEORDER) > + tprints("NLA_F_NET_BYTEORDER|"); > + printxval(table, nla->nla_type & NLA_TYPE_MASK, dflt); > + tprints("}"); > +} > + > +static void > +decode_nlattr_with_data(struct tcb *tcp, kernel_ulong_t addr, > + kernel_ulong_t len, const struct xlat *table, > + const char *dflt) > +{ > + struct nlattr nlattr; > + > + while (fetch_nlattr(tcp, &nlattr, addr, len)) { > + unsigned long nlattr_len = NLA_ALIGN(nlattr.nla_len); > + kernel_ulong_t next_addr = 0; > + kernel_ulong_t next_len = 0; This new function is made after decode_netlink, which is fine, but it misses the abbrev(tcp) logic which is present in decode_netlink. Could you reintroduce it here, too, please? > + > + if (nlattr.nla_len >= sizeof(struct nlattr)) { > + next_len = (len >= nlattr_len) ? len - nlattr_len : 0; > + > + if (next_len && addr + nlattr_len > addr) > + next_addr = addr + nlattr_len; > + } > + > + tprints("{"); > + print_nlattr(&nlattr, table, dflt); > + if (nlattr.nla_len > NLA_HDRLEN) { > + tprints(", "); > + printstrn(tcp, addr + NLA_HDRLEN, > + nlattr.nla_len - NLA_HDRLEN); > + } > + tprints("}"); > + > + if (!next_addr) > + break; > + > + tprints(", "); > + addr = next_addr; > + len = next_len; > + } > +} > + > +void > +decode_nlattr(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t len, > + int hdrlen, const struct xlat *table, const char *dflt) > +{ > + if (len > NLMSG_ALIGN(hdrlen)) { > + tprints(", "); > + decode_nlattr_with_data(tcp, addr + NLMSG_ALIGN(hdrlen), > + len - NLMSG_ALIGN(hdrlen), table, dflt); > + } I'm not sure we need this proxy function, the caller is capable of performing the check and invoking the decoder with the right address and length. > +} > + > /* > * Fetch a struct nlmsghdr from the given address. > */ > diff --git a/netlink_sock_diag.c b/netlink_sock_diag.c > index 8dbfd07..6d79ba4 100644 > --- a/netlink_sock_diag.c > +++ b/netlink_sock_diag.c > @@ -55,6 +55,7 @@ > # include "xlat/smc_states.h" > #endif > > +#include "xlat/unix_diag_attrs.h" > #include "xlat/unix_diag_show.h" > > static void > @@ -109,32 +110,35 @@ static void > decode_unix_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 unix_diag_msg msg = { .udiag_family = family }; > const size_t offset = sizeof(msg.udiag_family); > > tprints("{udiag_family="); > printxval(addrfams, msg.udiag_family, "AF_???"); > > tprints(", "); > if (len >= sizeof(msg)) { > if (!umoven_or_printaddr(tcp, addr + offset, > sizeof(msg) - offset, > (void *) &msg + offset)) { > tprints("udiag_type="); > printxval(socktypes, msg.udiag_type, "SOCK_???"); > tprintf(", udiag_state="); > printxval(tcp_states, msg.udiag_state, "TCP_???"); > tprintf(", udiag_ino=%" PRIu32 > ", udiag_cookie=[%" PRIu32 ", %" PRIu32 "]", > msg.udiag_ino, > msg.udiag_cookie[0], msg.udiag_cookie[1]); The invocation of nlattr decoder should be placed here: offset = NLMSG_ALIGN(sizeof(msg)); if (len > offset) { tprints(", "); decode_nlattr(tcp, addr + offset, len - offset, unix_diag_attrs, "UNIX_DIAG_???"); } > } > } else > tprints("..."); > tprints("}"); > + > + decode_nlattr(tcp, addr, len, sizeof(msg), unix_diag_attrs, > + "UNIX_DIAG_???"); > } > > static void > diff --git a/xlat/unix_diag_attrs.in b/xlat/unix_diag_attrs.in > new file mode 100644 > index 0000000..0fb2f23 > --- /dev/null > +++ b/xlat/unix_diag_attrs.in > @@ -0,0 +1,7 @@ > +UNIX_DIAG_NAME 0 > +UNIX_DIAG_VFS 1 > +UNIX_DIAG_PEER 2 > +UNIX_DIAG_ICONS 3 > +UNIX_DIAG_RQLEN 4 > +UNIX_DIAG_MEMINFO 5 > +UNIX_DIAG_SHUTDOWN 6 As these constants are guaranteed to be defined by local linux/unix_diag.h file, there is no need to provide fallback definitions, just the opposite, these xlat entries should be unconditional: --- /dev/null +++ b/xlat/unix_diag_attrs.in @@ -0,0 +1,8 @@ +#unconditional +UNIX_DIAG_NAME +UNIX_DIAG_VFS +UNIX_DIAG_PEER +UNIX_DIAG_ICONS +UNIX_DIAG_RQLEN +UNIX_DIAG_MEMINFO +UNIX_DIAG_SHUTDOWN -- ldv
signature.asc
Description: PGP signature
------------------------------------------------------------------------------ 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