From 959205c2a8a7c559b40204a1d33336d6800d1f1e Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Fri, 26 Dec 2014 23:29:26 +0000 Subject: [PATCH] Make -yy output for inet sockets consistent with unix domain sockets Prepend -yy output generated for INET/INET6 TCP/UDP sockets with their protocol name obtained using getxattr. * socketutils.c (inet_parse_response): Add proto_name argument. Print proto_name for connected and unconnected sockets. (receive_responses): Add proto_name argument, pass it to the parser. (inet_print): Add proto_name argument, pass it to receive_responses. (unix_parse_response): Add proto_name argument. (print_sockaddr_by_inode): Pass protocol name to inet_print calls. * tests/net-yy-accept.awk: Update to match new output format. * tests/net-yy-connect.awk: Likewise. --- socketutils.c | 62 ++++++++++++++++++++++++---------------- tests/net-yy-accept.awk | 40 ++++++++++---------------- tests/net-yy-connect.awk | 22 ++++++-------- 3 files changed, 60 insertions(+), 64 deletions(-) diff --git a/socketutils.c b/socketutils.c index 8b0d6159..0605aad2 100644 --- a/socketutils.c +++ b/socketutils.c @@ -56,7 +56,8 @@ inet_send_query(const int fd, const int family, const int proto) } static bool -inet_parse_response(const void *data, int data_len, const unsigned long inode) +inet_parse_response(const char *proto_name, const void *data, int data_len, + const unsigned long inode) { const struct inet_diag_msg *diag_msg = data; static const char zero_addr[sizeof(struct in6_addr)]; @@ -92,11 +93,13 @@ inet_parse_response(const void *data, int data_len, const unsigned long inode) dst_buf, text_size)) return false; - tprintf("%s:%u->%s:%u", + tprintf("%s:[%s:%u->%s:%u]", + proto_name, src_buf, ntohs(diag_msg->id.idiag_sport), dst_buf, ntohs(diag_msg->id.idiag_dport)); } else { - tprintf("%s:%u", src_buf, ntohs(diag_msg->id.idiag_sport)); + tprintf("%s:[%s:%u]", proto_name, src_buf, + ntohs(diag_msg->id.idiag_sport)); } return true; @@ -104,7 +107,8 @@ inet_parse_response(const void *data, int data_len, const unsigned long inode) static bool receive_responses(const int fd, const unsigned long inode, - bool (* parser) (const void*, int, const unsigned long)) + const char *proto_name, + bool (* parser) (const char *, const void *, int, const unsigned long)) { static char buf[8192]; struct sockaddr_nl nladdr = { @@ -141,17 +145,18 @@ receive_responses(const int fd, const unsigned long inode, case NLMSG_ERROR: return false; } - if (parser(NLMSG_DATA(h), h->nlmsg_len, inode)) + if (parser(proto_name, NLMSG_DATA(h), h->nlmsg_len, inode)) return true; } } } static bool -inet_print(int fd, int family, int protocol, const unsigned long inode) +inet_print(const int fd, const int family, const int protocol, + const unsigned long inode, const char *proto_name) { return inet_send_query(fd, family, protocol) - && receive_responses(fd, inode, inet_parse_response); + && receive_responses(fd, inode, proto_name, inet_parse_response); } static bool @@ -198,7 +203,8 @@ unix_send_query(const int fd, const unsigned long inode) } static bool -unix_parse_response(const void *data, int data_len, const unsigned long inode) +unix_parse_response(const char *proto_name, const void *data, int data_len, + const unsigned long inode) { const struct unix_diag_msg *diag_msg = data; struct rtattr *attr; @@ -237,7 +243,7 @@ unix_parse_response(const void *data, int data_len, const unsigned long inode) * "UNIX:[" SELF_INODE [ "->" PEER_INODE ][ "," SOCKET_FILE ] "]" */ if (peer || path_len) { - tprintf("UNIX:[%lu", inode); + tprintf("%s:[%lu", proto_name, inode); if (peer) tprintf("->%u", peer); if (path_len) { @@ -262,7 +268,7 @@ static bool unix_print(int fd, const unsigned long inode) { return unix_send_query(fd, inode) - && receive_responses(fd, inode, unix_parse_response); + && receive_responses(fd, inode, "UNIX", unix_parse_response); } /* Given an inode number of a socket, print out the details @@ -279,30 +285,36 @@ print_sockaddr_by_inode(const unsigned long inode, const char *proto_name) if (proto_name) { if (strcmp(proto_name, "TCP") == 0) - r = inet_print(fd, AF_INET, IPPROTO_TCP, inode); + r = inet_print(fd, AF_INET, IPPROTO_TCP, inode, "TCP"); else if (strcmp(proto_name, "UDP") == 0) - r = inet_print(fd, AF_INET, IPPROTO_UDP, inode); + r = inet_print(fd, AF_INET, IPPROTO_UDP, inode, "UDP"); else if (strcmp(proto_name, "TCPv6") == 0) - r = inet_print(fd, AF_INET6, IPPROTO_TCP, inode); + r = inet_print(fd, AF_INET6, IPPROTO_TCP, inode, "TCPv6"); else if (strcmp(proto_name, "UDPv6") == 0) - r = inet_print(fd, AF_INET6, IPPROTO_UDP, inode); + r = inet_print(fd, AF_INET6, IPPROTO_UDP, inode, "UDPv6"); else if (strcmp(proto_name, "UNIX") == 0) r = unix_print(fd, inode); } else { - const int families[] = {AF_INET, AF_INET6}; - const int protocols[] = {IPPROTO_TCP, IPPROTO_UDP}; - const size_t flen = ARRAY_SIZE(families); - const size_t plen = ARRAY_SIZE(protocols); - size_t fi, pi; + const struct { + const int family; + const int protocol; + const char *name; + } protocols[] = { + { AF_INET, IPPROTO_TCP, "TCP" }, + { AF_INET, IPPROTO_UDP, "UDP" }, + { AF_INET6, IPPROTO_TCP, "TCPv6" }, + { AF_INET6, IPPROTO_UDP, "UDPv6" } + }; + size_t i; - for (fi = 0; fi < flen; ++fi) { - for (pi = 0; pi < plen; ++pi) { - if ((r = inet_print(fd, families[fi], protocols[pi], inode))) - goto out; - } + for (i = 0; i < ARRAY_SIZE(protocols); ++i) { + if ((r = inet_print(fd, protocols[i].family, + protocols[i].protocol, inode, + protocols[i].name))) + break; } } -out: + close(fd); return r; } diff --git a/tests/net-yy-accept.awk b/tests/net-yy-accept.awk index ac3c19af..b3743ef2 100644 --- a/tests/net-yy-accept.awk +++ b/tests/net-yy-accept.awk @@ -2,61 +2,51 @@ BEGIN { lines = 9 fail = 0 - inode = "?" - port_l = "?" - port_r = "?" - r_i = "[1-9][0-9]*" r_port = "[1-9][0-9][0-9][0-9]+" r_localhost = "127\\.0\\.0\\.1" - r_bind = "^bind\\(0<(TCP|socket):\\[(" r_i ")\\]>, {sa_family=AF_INET, sin_port=htons\\(0\\), sin_addr=inet_addr\\(\"" r_localhost "\"\\)}, " r_i "\\) += 0$" - r_listen = "^/$" - r_getsockname = "^getsockname\\(0<" r_localhost ":(" r_port ")>, {sa_family=AF_INET, sin_port=htons\\((" r_port ")\\), sin_addr=inet_addr\\(\"" r_localhost "\"\\)}, \\[" r_i "\\]\\) += 0$" - r_accept = "^/$" - r_close0 = "^/$" - r_recv = "^/$" - r_recvfrom = "^/$" - r_close1 = "^/$" + r_bind = "^bind\\(0, {sa_family=AF_INET, sin_port=htons\\(0\\), sin_addr=inet_addr\\(\"" r_localhost "\"\\)}, " r_i "\\) += 0$" + r_getsockname = "^getsockname\\(0, {sa_family=AF_INET, sin_port=htons\\((" r_port ")\\), sin_addr=inet_addr\\(\"" r_localhost "\"\\)}, \\[" r_i "\\]\\) += 0$" } NR == 1 && /^socket\(PF_INET, SOCK_STREAM, IPPROTO_IP\) += 0$/ {next} NR == 2 { if (match($0, r_bind, a)) { - inode = a[2] - r_listen = "^listen\\(0<(TCP|socket):\\[" inode "\\]>, 5\\) += 0$" + inode = a[1] + r_listen = "^listen\\(0, 5\\) += 0$" next } } -NR == 3 {if (match($0, r_listen)) next} +NR == 3 {if (r_listen != "" && match($0, r_listen)) next} NR == 4 { if (match($0, r_getsockname, a) && a[1] == a[2]) { port_l = a[1] - r_accept = "^accept\\(0<" r_localhost ":" port_l ">, {sa_family=AF_INET, sin_port=htons\\((" r_port ")\\), sin_addr=inet_addr\\(\"" r_localhost "\"\\)}, \\[" r_i "\\]\\) += 1<" r_localhost ":" port_l "->" r_localhost ":(" r_port ")>$" - r_close0 = "^close\\(0<" r_localhost ":" port_l ">) += 0$" + r_accept = "^accept\\(0, {sa_family=AF_INET, sin_port=htons\\((" r_port ")\\), sin_addr=inet_addr\\(\"" r_localhost "\"\\)}, \\[" r_i "\\]\\) += 1" r_localhost ":(" r_port ")\\]>$" + r_close0 = "^close\\(0) += 0$" next } } NR == 5 { - if (match($0, r_accept, a) && a[1] == a[2]) { + if (r_accept != "" && match($0, r_accept, a) && a[1] == a[2]) { port_r = a[1] - r_recv = "^recv\\(1<" r_localhost ":" port_l "->" r_localhost ":" port_r ">, \"data\", 5, MSG_WAITALL\\) += 4$" - r_recvfrom = "^recvfrom\\(1<" r_localhost ":" port_l "->" r_localhost ":" port_r ">, \"data\", 5, MSG_WAITALL, NULL, NULL\\) += 4$" - r_close1 = "^close\\(1<" r_localhost ":" port_l "->" r_localhost ":" port_r ">) += 0$" + r_recv = "^recv\\(1" r_localhost ":" port_r "\\]>, \"data\", 5, MSG_WAITALL\\) += 4$" + r_recvfrom = "^recvfrom\\(1" r_localhost ":" port_r "\\]>, \"data\", 5, MSG_WAITALL, NULL, NULL\\) += 4$" + r_close1 = "^close\\(1" r_localhost ":" port_r "\\]>) += 0$" next } } -NR == 6 {if (match($0, r_close0)) next} +NR == 6 {if (r_close0 != "" && match($0, r_close0)) next} -NR == 7 {if (match($0, r_recv) || match($0, r_recvfrom)) next} +NR == 7 {if (r_recv != "" && (match($0, r_recv) || match($0, r_recvfrom))) next} -NR == 8 {if (match($0, r_close1)) next} +NR == 8 {if (r_close1 != "" && match($0, r_close1)) next} -NR == lines && /^\+\+\+ exited with 0 \+\+\+$/ {next} +NR == lines && $0 == "+++ exited with 0 +++" {next} { print "Line " NR " does not match: " $0 diff --git a/tests/net-yy-connect.awk b/tests/net-yy-connect.awk index c7c63af2..81ef47e6 100644 --- a/tests/net-yy-connect.awk +++ b/tests/net-yy-connect.awk @@ -2,40 +2,34 @@ BEGIN { lines = 5 fail = 0 - port_l = "?" - port_r = "?" - r_i = "[1-9][0-9]*" r_port = "[1-9][0-9][0-9][0-9]+" r_localhost = "127\\.0\\.0\\.1" - r_connect = "^connect\\(0<(TCP|socket):\\[" r_i "\\]>, {sa_family=AF_INET, sin_port=htons\\((" r_port ")\\), sin_addr=inet_addr\\(\"" r_localhost "\"\\)}, " r_i ") += 0$" - r_send = "^/$" - r_sendto = "^/$" - r_close = "^/$" + r_connect = "^connect\\(0, {sa_family=AF_INET, sin_port=htons\\((" r_port ")\\), sin_addr=inet_addr\\(\"" r_localhost "\"\\)}, " r_i ") += 0$" } NR == 1 && /^socket\(PF_INET, SOCK_STREAM, IPPROTO_IP\) += 0$/ {next} NR == 2 { if (match($0, r_connect, a)) { - port_r = a[2] - r_send = "^send\\(0<" r_localhost ":(" r_port ")->" r_localhost ":" port_r ">, \"data\", 4, MSG_DONTROUTE\\) += 4$" - r_sendto = "^sendto\\(0<" r_localhost ":(" r_port ")->" r_localhost ":" port_r ">, \"data\", 4, MSG_DONTROUTE, NULL, 0\\) += 4$" + port_r = a[1] + r_send = "^send\\(0" r_localhost ":" port_r "\\]>, \"data\", 4, MSG_DONTROUTE\\) += 4$" + r_sendto = "^sendto\\(0" r_localhost ":" port_r "\\]>, \"data\", 4, MSG_DONTROUTE, NULL, 0\\) += 4$" next } } NR == 3 { - if (match($0, r_send, a) || match($0, r_sendto, a)) { + if (r_send != "" && (match($0, r_send, a) || match($0, r_sendto, a))) { port_l = a[1] - r_close = "^close\\(0<" r_localhost ":" port_l "->" r_localhost ":" port_r ">\\) += 0$" + r_close = "^close\\(0" r_localhost ":" port_r "\\]>\\) += 0$" next } } -NR == 4 {if (match($0, r_close)) next} +NR == 4 {if (r_close != "" && match($0, r_close)) next} -NR == lines && /^\+\+\+ exited with 0 \+\+\+$/ {next} +NR == lines && $0 == "+++ exited with 0 +++" {next} { print "Line " NR " does not match: " $0 -- 2.34.1