On Thu, Jul 06, 2017 at 09:57:35AM +0800, JingPiao Chen wrote: > * netlink_sock_diag.c: Include "xlat/inet_diag_bytecodes.h". > (decode_inet_addr, decode_inet_diag_hostcond, > print_inet_diag_bc_op, decode_inet_diag_markcond, > decode_bytecode_data, decode_inet_diag_bc_op): New functions. > (inet_diag_req_nla_decoders): New array. > (decode_inet_diag_req_compat, decode_inet_diag_req_v2): Use it. > * linux/inet_diag.h (inet_diag_bc_op, inet_diag_hostcond, > inet_diag_markcond): New structures. > (INET_DIAG_BC_*): New enum. > * xlat/inet_diag_bytecodes.in: New file. > --- > linux/inet_diag.h | 32 ++++++++ > netlink_sock_diag.c | 188 > +++++++++++++++++++++++++++++++++++++++++++- > xlat/inet_diag_bytecodes.in | 12 +++ > 3 files changed, 230 insertions(+), 2 deletions(-) > create mode 100644 xlat/inet_diag_bytecodes.in > > diff --git a/linux/inet_diag.h b/linux/inet_diag.h > index 24302db..ec6356c 100644 > --- a/linux/inet_diag.h > +++ b/linux/inet_diag.h > @@ -39,6 +39,38 @@ enum { > INET_DIAG_REQ_BYTECODE, > }; > > +struct inet_diag_bc_op { > + unsigned char code; > + unsigned char yes; > + unsigned short no; > +}; > + > +enum { > + INET_DIAG_BC_NOP, > + INET_DIAG_BC_JMP, > + INET_DIAG_BC_S_GE, > + INET_DIAG_BC_S_LE, > + INET_DIAG_BC_D_GE, > + INET_DIAG_BC_D_LE, > + INET_DIAG_BC_AUTO, > + INET_DIAG_BC_S_COND, > + INET_DIAG_BC_D_COND, > + INET_DIAG_BC_DEV_COND, /* u32 ifindex */ > + INET_DIAG_BC_MARK_COND, > +}; > + > +struct inet_diag_hostcond { > + uint8_t family; > + uint8_t prefix_len; > + int port; > + uint32_t addr[0]; > +}; > + > +struct inet_diag_markcond { > + uint32_t mark; > + uint32_t mask; > +}; > + > /* Info structure */ > struct inet_diag_msg { > uint8_t idiag_family; > diff --git a/netlink_sock_diag.c b/netlink_sock_diag.c > index 42860aa..29d61cb 100644 > --- a/netlink_sock_diag.c > +++ b/netlink_sock_diag.c > @@ -43,6 +43,7 @@ > #include <linux/unix_diag.h> > > #include "xlat/inet_diag_attrs.h" > +#include "xlat/inet_diag_bytecodes.h" > #include "xlat/inet_diag_extended_flags.h" > #include "xlat/inet_diag_req_attrs.h" > > @@ -620,6 +621,187 @@ print_inet_diag_sockid(const struct inet_diag_sockid > *id, const uint8_t family) > } > > static void > +decode_inet_addr(struct tcb *const tcp, > + const kernel_ulong_t addr, > + const kernel_ulong_t len, > + const int family) > +{ > + switch (family) { > + case AF_INET: { > + struct in_addr in_addr; > + > + if (len < sizeof(in_addr)) { > + printstrn(tcp, addr, len);
The "addr=" prefix is lost. Don't you think QUOTE_FORCE_HEX would be better? > + break; > + } > + > + if (umove_or_printaddr(tcp, addr, &in_addr)) > + break; The "addr=" prefix is lost. > + > + print_inet_addr(family, &in_addr.s_addr, > + sizeof(in_addr.s_addr), "addr.s_addr"); Why .s_addr? > + break; > + } > + case AF_INET6: { > + struct in6_addr in6_addr; > + > + if (len < sizeof(in6_addr)) { > + printstrn(tcp, addr, len); The "addr=" prefix is lost. Don't you think QUOTE_FORCE_HEX would be better? > + break; > + } > + if (umove_or_printaddr(tcp, addr, &in6_addr)) > + break; The "addr=" prefix is lost. > + > + print_inet_addr(family, in6_addr.s6_addr, > + sizeof(in6_addr.s6_addr),"addr.s6_addr"); Why .s6_addr? > + break; > + } > + default: > + tprints("addr="); > + printstrn(tcp, addr, len); > + break; > + } > +} union { struct in_addr a4; struct in6_addr a6; } addr; size_t size = 0; switch (family) { case AF_INET: size = sizeof(addr.a4); break; case AF_INET6: size = sizeof(addr.a6); break; } if (!size || len < size) { tprints("addr="); printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX); return; } if (umoven(tcp, addr, size, &addr) < 0) { tprints("addr="); printaddr(addr); return; } print_inet_addr(family, &addr, size, "addr");, > +static void > +decode_inet_diag_hostcond(struct tcb *const tcp, > + const kernel_ulong_t addr, > + const kernel_ulong_t len) > +{ > + struct inet_diag_hostcond cond; > + > + if (len < sizeof(cond)) { > + printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX); > + return; > + } > + if (umove_or_printaddr(tcp, addr, &cond)) > + return; > + > + PRINT_FIELD_XVAL("{", cond, family, addrfams, "AF_???"); > + PRINT_FIELD_U(", ", cond, prefix_len); > + PRINT_FIELD_U(", ", cond, port); > + > + if (len > sizeof(cond)) { > + tprints(", "); > + decode_inet_addr(tcp, addr + sizeof(cond), > + len - sizeof(cond), cond.family); > + } > + tprints("}"); > +} > + > +static void > +print_inet_diag_bc_op(const struct inet_diag_bc_op *const op) > +{ > + PRINT_FIELD_XVAL("{", *op, code, inet_diag_bytecodes, > + "INET_DIAG_BC_???"); > + PRINT_FIELD_U(", ", *op, yes); > + PRINT_FIELD_U(", ", *op, no); > + tprints("}"); > +} > + > +static void > +decode_inet_diag_markcond(struct tcb *const tcp, > + const kernel_ulong_t addr, > + const kernel_ulong_t len) > +{ > + struct inet_diag_markcond markcond; > + > + if (len < sizeof(markcond)) { > + printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX); > + return; > + } > + if (umove_or_printaddr(tcp, addr, &markcond)) > + return; > + > + PRINT_FIELD_U("{", markcond, mark); > + PRINT_FIELD_U(", ", markcond, mask); > + tprints("}"); > +} > + > +static void > +decode_bytecode_data(struct tcb *const tcp, > + const kernel_ulong_t addr, > + const kernel_ulong_t len, > + const unsigned char code) > +{ > + switch (code) { > + case INET_DIAG_BC_S_COND: > + case INET_DIAG_BC_D_COND: > + decode_inet_diag_hostcond(tcp, addr, len); > + break; > + case INET_DIAG_BC_DEV_COND: { > + uint32_t ifindex; > + > + if (len < sizeof(ifindex)) { > + printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX); > + break; > + } > + if (umove_or_printaddr(tcp, addr, &ifindex)) > + break; > + > + tprintf("%" PRIu32, ifindex); Use print_ifindex. > + break; > + } > + case INET_DIAG_BC_S_GE: > + case INET_DIAG_BC_S_LE: > + case INET_DIAG_BC_D_GE: > + case INET_DIAG_BC_D_LE: { > + struct inet_diag_bc_op op; > + > + if (len < sizeof(op)) { > + printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX); > + break; > + } > + if (umove_or_printaddr(tcp, addr, &op)) > + break; > + > + print_inet_diag_bc_op(&op); if (len < sizeof(op)) printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX); else if (!umove_or_printaddr(tcp, addr, &op)) print_inet_diag_bc_op(&op); This is shorter, isn't it? > + break; > + } > + case INET_DIAG_BC_MARK_COND: > + decode_inet_diag_markcond(tcp, addr, len); > + break; > + case INET_DIAG_BC_AUTO: > + case INET_DIAG_BC_JMP: > + case INET_DIAG_BC_NOP: > + default: > + printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX); > + break; > + } > +} > + > +static bool > +decode_inet_diag_bc_op(struct tcb *const tcp, > + const kernel_ulong_t addr, > + const kernel_ulong_t len, > + const void *const opaque_data) > +{ > + struct inet_diag_bc_op op; > + > + if (len < sizeof(op)) > + return false; > + if (umove_or_printaddr(tcp, addr, &op)) > + return true; > + > + if (len > sizeof(op)) > + tprints("{"); > + > + print_inet_diag_bc_op(&op); > + if (len > sizeof(op)) { > + tprints(", "); > + decode_bytecode_data(tcp, addr + sizeof(op), > + len - sizeof(op), op.code); > + tprints("}"); > + } > + > + return true; > +} > + > +static const nla_decoder_t inet_diag_req_nla_decoders[] = { > + [INET_DIAG_REQ_BYTECODE] = decode_inet_diag_bc_op > +}; > + > +static void > decode_inet_diag_req_compat(struct tcb *const tcp, > const struct nlmsghdr *const nlmsghdr, > const uint8_t family, > @@ -657,7 +839,8 @@ decode_inet_diag_req_compat(struct tcb *const tcp, > tprints(", "); > decode_nlattr(tcp, addr + offset, len - offset, > inet_diag_req_attrs, "INET_DIAG_REQ_???", > - NULL, 0, NULL); > + inet_diag_req_nla_decoders, > + ARRAY_SIZE(inet_diag_req_nla_decoders), NULL); > } > } > > @@ -698,7 +881,8 @@ decode_inet_diag_req_v2(struct tcb *const tcp, > tprints(", "); > decode_nlattr(tcp, addr + offset, len - offset, > inet_diag_req_attrs, "INET_DIAG_REQ_???", > - NULL, 0, NULL); > + inet_diag_req_nla_decoders, > + ARRAY_SIZE(inet_diag_req_nla_decoders), NULL); > } > } > > diff --git a/xlat/inet_diag_bytecodes.in b/xlat/inet_diag_bytecodes.in > new file mode 100644 > index 0000000..ccaf0da > --- /dev/null > +++ b/xlat/inet_diag_bytecodes.in > @@ -0,0 +1,12 @@ > +#unconditional > +INET_DIAG_BC_NOP > +INET_DIAG_BC_JMP > +INET_DIAG_BC_S_GE > +INET_DIAG_BC_S_LE > +INET_DIAG_BC_D_GE > +INET_DIAG_BC_D_LE > +INET_DIAG_BC_AUTO > +INET_DIAG_BC_S_COND > +INET_DIAG_BC_D_COND > +INET_DIAG_BC_DEV_COND > +INET_DIAG_BC_MARK_COND In summary, not bad but needs corrections. -- 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