* netlink_sock_diag.c: Include "xlat/inet_diag_bytecodes.h". (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 | 176 +++++++++++++++++++++++++++++++++++++++++++- xlat/inet_diag_bytecodes.in | 11 +++ 3 files changed, 217 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 a90dda7..eb8bf45 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" @@ -634,6 +635,175 @@ print_inet_diag_sockid(const struct inet_diag_sockid *id, const uint8_t family) id->idiag_if, id->idiag_cookie[0], id->idiag_cookie[1]); } + +static void +decode_inet_addr(struct tcb *tcp, kernel_ulong_t addr, + kernel_ulong_t len, int family) +{ + switch (family) { + case AF_INET: { + struct in_addr in_addr; + + if (len < sizeof(in_addr)) { + printstrn(tcp, addr, len); + break; + } + + if (umove_or_printaddr(tcp, addr, &in_addr)) + break; + + print_inet_addr(family, &in_addr.s_addr, + sizeof(in_addr.s_addr), "addr.s_addr"); + break; + } + case AF_INET6: { + struct in6_addr in6_addr; + + if (len < sizeof(in6_addr)) { + printstrn(tcp, addr, len); + break; + } + if (umove_or_printaddr(tcp, addr, &in6_addr)) + break; + + print_inet_addr(family, in6_addr.s6_addr, + sizeof(in6_addr.s6_addr),"addr.s6_addr"); + break; + } + default: + tprints("addr="); + printstrn(tcp, addr, len); + break; + } +} + +static void +decode_inet_diag_hostcond(struct tcb *tcp, kernel_ulong_t addr, + kernel_ulong_t len) +{ + struct inet_diag_hostcond cond; + + if (len < sizeof(cond)) { + printstrn(tcp, addr, len); + return; + } + if (umove_or_printaddr(tcp, addr, &cond)) + return; + + tprints("{family="); + printxval(addrfams, cond.family, "AF_???"); + tprintf(", prefix_len=%u, port=%d", cond.prefix_len, 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(struct inet_diag_bc_op *op) +{ + tprints("{code="); + printxval(inet_diag_bytecodes, op->code, "INET_DIAG_BC_???"); + tprintf(", yes=%u, no=%hu}", op->yes, op->no); +} + +static void +decode_inet_diag_markcond(struct tcb *tcp, kernel_ulong_t addr, + kernel_ulong_t len) +{ + struct inet_diag_markcond markcond; + + if (len < sizeof(markcond)) { + printstrn(tcp, addr, len); + return; + } + if (umove_or_printaddr(tcp, addr, &markcond)) + return; + + tprintf("{mark=%" PRIu32 ", mask=%" PRIu32 "}", + markcond.mark, markcond.mask); +} + +static void +decode_bytecode_data(struct tcb *tcp, kernel_ulong_t addr, + kernel_ulong_t len, 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)) { + printstrn(tcp, addr, len); + break; + } + if (umove_or_printaddr(tcp, addr, &ifindex)) + break; + + tprintf("%" PRIu32, 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)) { + printstrn(tcp, addr, len); + break; + } + if (umove_or_printaddr(tcp, addr, &op)) + break; + + print_inet_diag_bc_op(&op); + 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: + printstrn(tcp, addr, len); + break; + } +} + +static bool +decode_inet_diag_bc_op(struct tcb *tcp, kernel_ulong_t addr, + kernel_ulong_t len, 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; + + 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, @@ -677,7 +847,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); } } @@ -722,7 +893,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..e75f424 --- /dev/null +++ b/xlat/inet_diag_bytecodes.in @@ -0,0 +1,11 @@ +INET_DIAG_BC_NOP 0 +INET_DIAG_BC_JMP 1 +INET_DIAG_BC_S_GE 2 +INET_DIAG_BC_S_LE 3 +INET_DIAG_BC_D_GE 4 +INET_DIAG_BC_D_LE 5 +INET_DIAG_BC_AUTO 6 +INET_DIAG_BC_S_COND 7 +INET_DIAG_BC_D_COND 8 +INET_DIAG_BC_DEV_COND 9 +INET_DIAG_BC_MARK_COND 10 -- 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