* defs.h (inet_protocols): New xlat prototype. * linux/inet_diag.h (inet_diag_req): New structure. (INET_DIAG_*): New enum. * netlink_sock_diag.c: Include <arpa/inet.h>, <linux/inet_diag.h> and "xlat/inet_diag_extended_flags.h". (print_inet_diag_sockid, decode_inet_diag_req_compat) (decode_inet_diag_req_v2, decode_inet_diag_req) (decode_inet_diag_msg): New functions. (diag_decoders): Add AF_INET. * xlat/inet_diag_extended_flags.in: New file.
Co-authored-by: Fabien Siron <fabien.si...@epita.fr> --- defs.h | 1 + linux/inet_diag.h | 36 +++++++++++- netlink_sock_diag.c | 122 +++++++++++++++++++++++++++++++++++++++ xlat/inet_diag_extended_flags.in | 16 +++++ 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 xlat/inet_diag_extended_flags.in diff --git a/defs.h b/defs.h index f7d25f0..0b32b24 100644 --- a/defs.h +++ b/defs.h @@ -293,6 +293,7 @@ extern const struct xlat clocknames[]; extern const struct xlat dirent_types[]; extern const struct xlat ethernet_protocols[]; extern const struct xlat evdev_abs[]; +extern const struct xlat inet_protocols[]; extern const struct xlat msg_flags[]; extern const struct xlat netlink_protocols[]; extern const struct xlat open_access_modes[]; diff --git a/linux/inet_diag.h b/linux/inet_diag.h index 69012af..7302c87 100644 --- a/linux/inet_diag.h +++ b/linux/inet_diag.h @@ -14,7 +14,17 @@ struct inet_diag_sockid { uint32_t idiag_cookie[2]; }; -/* Request structure */ +/* Request structures */ +struct inet_diag_req { + uint8_t idiag_family; + uint8_t idiag_src_len; + uint8_t idiag_dst_len; + uint8_t idiag_ext; + struct inet_diag_sockid id; + uint32_t idiag_states; + uint32_t idiag_dbs; +}; + struct inet_diag_req_v2 { uint8_t sdiag_family; uint8_t sdiag_protocol; @@ -40,4 +50,28 @@ struct inet_diag_msg { uint32_t idiag_inode; }; +/* Extensions */ +enum { + INET_DIAG_NONE, + INET_DIAG_MEMINFO, + INET_DIAG_INFO, + INET_DIAG_VEGASINFO, + INET_DIAG_CONG, + INET_DIAG_TOS, + INET_DIAG_TCLASS, + INET_DIAG_SKMEMINFO, + INET_DIAG_SHUTDOWN, + INET_DIAG_DCTCPINFO, + INET_DIAG_PROTOCOL, /* response attribute only */ + INET_DIAG_SKV6ONLY, + INET_DIAG_LOCALS, + INET_DIAG_PEERS, + INET_DIAG_PAD, + INET_DIAG_MARK, + INET_DIAG_BBRINFO, + __INET_DIAG_MAX, +}; + +#define INET_DIAG_MAX (__INET_DIAG_MAX - 1) + #endif /* !STRACE_LINUX_INET_DIAG_H */ diff --git a/netlink_sock_diag.c b/netlink_sock_diag.c index 3f153a8..7467d1a 100644 --- a/netlink_sock_diag.c +++ b/netlink_sock_diag.c @@ -30,11 +30,15 @@ #include "defs.h" #include <sys/socket.h> +#include <arpa/inet.h> +#include <linux/inet_diag.h> #include <linux/netlink.h> #include <linux/netlink_diag.h> #include <linux/packet_diag.h> #include <linux/unix_diag.h> +#include "xlat/inet_diag_extended_flags.h" + #include "xlat/tcp_states.h" #include "xlat/tcp_state_flags.h" @@ -210,9 +214,127 @@ decode_packet_diag_msg(struct tcb *const tcp, return true; } +static void +print_inet_diag_sockid(const struct inet_diag_sockid *id, const uint8_t family) +{ + tprintf("{idiag_sport=htons(%u), idiag_dport=htons(%u)", + ntohs(id->idiag_sport), ntohs(id->idiag_dport)); + int text_size = family == AF_INET ? + INET_ADDRSTRLEN : INET6_ADDRSTRLEN; + char buf[text_size]; + + inet_ntop(family, id->idiag_src, buf, text_size); + tprintf(", inet_pton(%s, \"%s\", idiag_src)", + family == AF_INET ? "AF_INET" : "AF_INET6", buf); + + inet_ntop(family, id->idiag_dst, buf, text_size); + tprintf(", inet_pton(%s, \"%s\", idiag_dst)", + family == AF_INET ? "AF_INET" : "AF_INET6", buf); + + tprintf(", idiag_if=%" PRIu32 ", idiag_cookie=[%" PRIu32 + ", %" PRIu32 "]}", id->idiag_if, id->idiag_cookie[0], + id->idiag_cookie[1]); +} + +static bool +decode_inet_diag_req_compat(struct tcb *const tcp, + const struct nlmsghdr *const nlmsghdr, + const kernel_ulong_t addr, + const kernel_ulong_t len) +{ + struct inet_diag_req req; + + if (len < sizeof(req) || umove(tcp, addr, &req) < 0) + return false; + + tprints("{idiag_family="); + printxval(addrfams, req.idiag_family, "AF_???"); + tprintf(", idiag_src_len=%" PRIu8 ", idiag_dst_len=%" PRIu8, + req.idiag_src_len, req.idiag_dst_len); + tprints(", idiag_ext="); + printflags(inet_diag_extended_flags, req.idiag_ext, + "1<<(INET_DIAG_\?\?\?-1)"); + tprints(", id="); + print_inet_diag_sockid(&req.id, req.idiag_family); + tprints(", idiag_states="); + printflags(tcp_state_flags, req.idiag_states, "1<<TCP_???"); + tprintf(", idiag_dbs=%" PRIu32 "}", req.idiag_dbs); + + return true; +} + +static bool +decode_inet_diag_req_v2(struct tcb *const tcp, + const struct nlmsghdr *const nlmsghdr, + const kernel_ulong_t addr, + const kernel_ulong_t len) +{ + struct inet_diag_req_v2 req; + + if (len < sizeof(req) || umove(tcp, addr, &req) < 0) + return false; + + tprints("{sdiag_family="); + printxval(addrfams, req.sdiag_family, "AF_???"); + tprints(", sdiag_protocol="); + printxval(inet_protocols, req.sdiag_protocol, "IPPROTO_???"); + tprints(", idiag_ext="); + printflags(inet_diag_extended_flags, req.idiag_ext, + "1<<(INET_DIAG_\?\?\?-1)"); + tprints(", idiag_states="); + printflags(tcp_state_flags, req.idiag_states, "1<<TCP_???"); + tprints(", id="); + print_inet_diag_sockid(&req.id, req.sdiag_family); + tprints("}"); + + return true; +} + +static bool +decode_inet_diag_req(struct tcb *const tcp, + const struct nlmsghdr *const nlmsghdr, + const kernel_ulong_t addr, + const kernel_ulong_t len) +{ + if (nlmsghdr->nlmsg_type == TCPDIAG_GETSOCK + || nlmsghdr->nlmsg_type == DCCPDIAG_GETSOCK) + return decode_inet_diag_req_compat(tcp, nlmsghdr, addr, len); + else + return decode_inet_diag_req_v2(tcp, nlmsghdr, addr, len); +} + +static bool +decode_inet_diag_msg(struct tcb *const tcp, + const struct nlmsghdr *const nlmsghdr, + const kernel_ulong_t addr, + const kernel_ulong_t len) +{ + struct inet_diag_msg msg; + + if (len < sizeof(msg) || umove(tcp, addr, &msg) < 0) + return false; + + tprints("{idiag_family="); + printxval(addrfams, msg.idiag_family, "AF_???"); + tprints(", idiag_state="); + printxval(tcp_states, msg.idiag_state, "TCP_???"); + tprintf(", idiag_timer=%" PRIu8 ", idiag_retrans=%" PRIu8, + msg.idiag_timer, msg.idiag_retrans); + tprints(", id="); + print_inet_diag_sockid(&msg.id, msg.idiag_family); + tprintf(", idiag_expires=%" PRIu32 ", idiag_rqueue=%" PRIu32 + ", idiag_wqueue=%" PRIu32 ", idiag_uid=%" PRIu32 + ", idiag_inode=%" PRIu32 "}", + msg.idiag_expires, msg.idiag_rqueue, msg.idiag_wqueue, + msg.idiag_uid, msg.idiag_inode); + + return true; +} + static const struct { const netlink_decoder_t request, response; } diag_decoders[] = { + [AF_INET] = { decode_inet_diag_req, decode_inet_diag_msg }, [AF_NETLINK] = { decode_netlink_diag_req, decode_netlink_diag_msg }, [AF_PACKET] = { decode_packet_diag_req, decode_packet_diag_msg }, [AF_UNIX] = { decode_unix_diag_req, decode_unix_diag_msg } diff --git a/xlat/inet_diag_extended_flags.in b/xlat/inet_diag_extended_flags.in new file mode 100644 index 0000000..2466696 --- /dev/null +++ b/xlat/inet_diag_extended_flags.in @@ -0,0 +1,16 @@ +{ 1<<(INET_DIAG_MEMINFO-1) , "(1<<(INET_DIAG_MEMINFO-1))" }, +{ 1<<(INET_DIAG_INFO-1) , "(1<<(INET_DIAG_INFO-1))" }, +{ 1<<(INET_DIAG_VEGASINFO-1) , "(1<<(INET_DIAG_VEGASINFO-1))" }, +{ 1<<(INET_DIAG_CONG-1) , "(1<<(INET_DIAG_CONG-1))" }, +{ 1<<(INET_DIAG_TOS-1) , "(1<<(INET_DIAG_TOS-1))" }, +{ 1<<(INET_DIAG_TCLASS-1) , "(1<<(INET_DIAG_TCLASS-1))" }, +{ 1<<(INET_DIAG_SKMEMINFO-1) , "(1<<(INET_DIAG_SKMEMINFO-1))" }, +{ 1<<(INET_DIAG_SHUTDOWN-1) , "(1<<(INET_DIAG_SHUTDOWN-1))" }, +{ 1<<(INET_DIAG_DCTCPINFO-1) , "(1<<(INET_DIAG_DCTCPINFO-1))" }, +{ 1<<(INET_DIAG_PROTOCOL-1) , "(1<<(INET_DIAG_PROTOCOL-1))" }, +{ 1<<(INET_DIAG_SKV6ONLY-1) , "(1<<(INET_DIAG_SKV6ONLY-1))" }, +{ 1<<(INET_DIAG_LOCALS-1) , "(1<<(INET_DIAG_LOCALS-1))" }, +{ 1<<(INET_DIAG_PEERS-1) , "(1<<(INET_DIAG_PEERS-1))" }, +{ 1<<(INET_DIAG_PAD-1) , "(1<<(INET_DIAG_PAD-1))" }, +{ 1<<(INET_DIAG_MARK-1) , "(1<<(INET_DIAG_MARK-1))" }, +{ 1<<(INET_DIAG_BBRINFO-1) , "(1<<(INET_DIAG_BBRINFO-1))" }, -- 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