]> granicus.if.org Git - strace/commitdiff
Print protocol name of socket descriptors with -yy option
authorMasatake YAMATO <yamato@redhat.com>
Sat, 22 Nov 2014 10:03:33 +0000 (19:03 +0900)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 27 Nov 2014 23:48:02 +0000 (23:48 +0000)
For those socket descriptors that have no associated ip:port pairs
(or when this information is not available), -yy option prints
the same <socket:[INODE]> information as -y option, e.g.

$ strace -e sendto -yy ip l > /dev/null
sendto(3<socket:[23456789]>, ...

This change makes -yy output more informative: instead of just
printing "socket", the name of protocol behind the socket descriptor
will be printed, e.g.

sendto(3<NETLINK:[23456789]>, ...

* configure.ac (AC_CHECK_HEADERS): Add sys/xattr.h.
* tests/net-yy-accept.awk: Update to support protocol names.
* tests/net-yy-connect.awk: Likewise.
* util.c [HAVE_SYS_XATTR_H]: Include <sys/xattr.h>.
(getfdproto): New function.
(printfd): Use it.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
configure.ac
tests/net-yy-accept.awk
tests/net-yy-connect.awk
util.c

index f9b056d51da6c91ec1fa9f13a7e790a818f006de..4732778776e17800e85326d06bceae52580e0115 100644 (file)
@@ -251,6 +251,7 @@ AC_CHECK_HEADERS(m4_normalize([
        sys/ptrace.h
        sys/reg.h
        sys/vfs.h
+       sys/xattr.h
 ]))
 AC_CHECK_HEADERS([linux/icmp.h linux/in6.h linux/netlink.h linux/if_packet.h],
                  [], [], [#include <stddef.h>
index 3ea4afe1c121a8841ae8374d254460757afcb0dc..ac3c19afd5d6526f3c2700da6e87c6911be12e12 100644 (file)
@@ -9,7 +9,7 @@ BEGIN {
   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<socket:\\[(" r_i ")\\]>, {sa_family=AF_INET, sin_port=htons\\(0\\), sin_addr=inet_addr\\(\"" r_localhost "\"\\)}, " r_i "\\) += 0$"
+  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 = "^/$"
@@ -23,8 +23,8 @@ NR == 1 && /^socket\(PF_INET, SOCK_STREAM, IPPROTO_IP\) += 0$/ {next}
 
 NR == 2 {
   if (match($0, r_bind, a)) {
-    inode = a[1]
-    r_listen = "^listen\\(0<socket:\\[" inode "\\]>, 5\\) += 0$"
+    inode = a[2]
+    r_listen = "^listen\\(0<(TCP|socket):\\[" inode "\\]>, 5\\) += 0$"
     next
   }
 }
index 18c1a28d06a8e3c9370d23602202e5ae7c7b50e7..c7c63af2896bd59ab9fd2bf3fdb1af90104c2af6 100644 (file)
@@ -8,7 +8,7 @@ BEGIN {
   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<socket:\\[" r_i "\\]>, {sa_family=AF_INET, sin_port=htons\\((" r_port ")\\), sin_addr=inet_addr\\(\"" r_localhost "\"\\)}, " r_i ") += 0$"
+  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 = "^/$"
@@ -18,7 +18,7 @@ NR == 1 && /^socket\(PF_INET, SOCK_STREAM, IPPROTO_IP\) += 0$/ {next}
 
 NR == 2 {
   if (match($0, r_connect, a)) {
-    port_r = a[1]
+    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$"
     next
diff --git a/util.c b/util.c
index 4f637e839921879026224de260035748c000ea06..cd4b802230a7b650ef965c0f0551923592da3bae 100644 (file)
--- a/util.c
+++ b/util.c
@@ -35,6 +35,9 @@
 #include <sys/user.h>
 #include <sys/param.h>
 #include <fcntl.h>
+#if HAVE_SYS_XATTR_H
+# include <sys/xattr.h>
+#endif
 #include <sys/uio.h>
 
 #if defined(IA64)
@@ -418,6 +421,33 @@ printnum_int(struct tcb *tcp, long addr, const char *fmt)
        tprints("]");
 }
 
+static char *
+getfdproto(struct tcb *tcp, int fd, char *buf, unsigned bufsize)
+{
+#if HAVE_SYS_XATTR_H
+       ssize_t r;
+       char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
+
+       if (fd < 0)
+               return NULL;
+
+       sprintf(path, "/proc/%u/fd/%u", tcp->pid, fd);
+       r = getxattr(path, "system.sockprotoname", buf, bufsize - 1);
+       if (r <= 0)
+               return NULL;
+       else {
+               /*
+                * This is a protection for the case when the kernel
+                * side does not append a null byte to the buffer.
+                */
+               buf[r] = '\0';
+               return buf;
+       }
+#else
+       return NULL;
+#endif
+}
+
 void
 printfd(struct tcb *tcp, int fd)
 {
@@ -433,8 +463,17 @@ printfd(struct tcb *tcp, int fd)
                        unsigned long inodenr;
                        inodenr = strtoul(path + socket_prefix_len, NULL, 10);
                        tprintf("%d<", fd);
-                       if (!print_sockaddr_by_inode(inodenr))
-                               tprints(path);
+                       if (!print_sockaddr_by_inode(inodenr)) {
+#define PROTO_NAME_LEN 32
+                               char proto_buf[PROTO_NAME_LEN];
+                               const char *proto =
+                                       getfdproto(tcp, fd, proto_buf, PROTO_NAME_LEN);
+
+                               if (proto)
+                                       tprintf("%s:[%lu]", proto, inodenr);
+                               else
+                                       tprints(path);
+                       }
                        tprints(">");
                } else {
                        tprintf("%d<%s>", fd, path);