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>
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>
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 = "^/$"
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
}
}
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 = "^/$"
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
#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)
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)
{
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);