2014-08-21 07:17:48 +04:00
# include "defs.h"
# include <netinet/in.h>
# include <sys/socket.h>
# include <arpa/inet.h>
# include <linux/netlink.h>
# include <linux/sock_diag.h>
# include <linux/inet_diag.h>
Support unix domain sockets in -yy option
This change extends -yy option to handle unix domain sockets:
their peer addresses will be printed, similar to inet sockets.
For a listening socket, its socket inode and socket path are printed.
For an accepted socket, its socket inode, the peer inode, and the
socket path are printed.
For a client socket, its socket inode and the peer inode are printed.
An example of a server side communication using netcat:
$ ./strace -yy -e network nc -l -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
setsockopt(3<UNIX:[14728348]>, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3<UNIX:[14728348]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
listen(3<UNIX:[14728348,"/tmp/example.sock"]>, 10) = 0
accept(3<UNIX:[14728348,"/tmp/example.sock"]>, {sa_family=AF_LOCAL, NULL}, [2]) = 4<UNIX:[14727246->14727245,"/tmp/example.sock"]>
recvfrom(4<UNIX:[14727246->14727245,"/tmp/example.sock"]>, "INPUT\n", 8192, 0, NULL, NULL) = 6
INPUT
An example of a client side communication using netcat:
$ ./strace -yy -e network nc -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3<UNIX:[14727245]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
getsockopt(3<UNIX:[14727245]>, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
INPUT
...
sendto(3<UNIX:[14727245->14727246]>, "INPUT\n", 6, 0, NULL, 0) = 6
* linux/unix_diag.h: New file.
* socketutils.c (send_query): Rename to inet_send_query.
(parse_response): Rename to inet_parse_response.
(unix_print, unix_send_query, unix_parse_response): New functions.
(receive_responses): Add a new argument named parser: a function for
handling protocol specific data parts of diag messages.
(print_sockaddr_by_inode): Call unix_print.
Replace NETLINK_INET_DIAG with NETLINK_SOCK_DIAG, they are equal
but NETLINK_SOCK_DIAG looks more generic.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2014-12-24 14:59:31 +03:00
# include <linux/unix_diag.h>
# include <linux/rtnetlink.h>
# include <sys/un.h>
# ifndef UNIX_PATH_MAX
# define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) 0)->sun_path)
# endif
2014-08-21 07:17:48 +04:00
static bool
Support unix domain sockets in -yy option
This change extends -yy option to handle unix domain sockets:
their peer addresses will be printed, similar to inet sockets.
For a listening socket, its socket inode and socket path are printed.
For an accepted socket, its socket inode, the peer inode, and the
socket path are printed.
For a client socket, its socket inode and the peer inode are printed.
An example of a server side communication using netcat:
$ ./strace -yy -e network nc -l -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
setsockopt(3<UNIX:[14728348]>, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3<UNIX:[14728348]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
listen(3<UNIX:[14728348,"/tmp/example.sock"]>, 10) = 0
accept(3<UNIX:[14728348,"/tmp/example.sock"]>, {sa_family=AF_LOCAL, NULL}, [2]) = 4<UNIX:[14727246->14727245,"/tmp/example.sock"]>
recvfrom(4<UNIX:[14727246->14727245,"/tmp/example.sock"]>, "INPUT\n", 8192, 0, NULL, NULL) = 6
INPUT
An example of a client side communication using netcat:
$ ./strace -yy -e network nc -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3<UNIX:[14727245]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
getsockopt(3<UNIX:[14727245]>, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
INPUT
...
sendto(3<UNIX:[14727245->14727246]>, "INPUT\n", 6, 0, NULL, 0) = 6
* linux/unix_diag.h: New file.
* socketutils.c (send_query): Rename to inet_send_query.
(parse_response): Rename to inet_parse_response.
(unix_print, unix_send_query, unix_parse_response): New functions.
(receive_responses): Add a new argument named parser: a function for
handling protocol specific data parts of diag messages.
(print_sockaddr_by_inode): Call unix_print.
Replace NETLINK_INET_DIAG with NETLINK_SOCK_DIAG, they are equal
but NETLINK_SOCK_DIAG looks more generic.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2014-12-24 14:59:31 +03:00
inet_send_query ( const int fd , const int family , const int proto )
2014-08-21 07:17:48 +04:00
{
2014-11-21 22:59:16 +03:00
struct sockaddr_nl nladdr = {
. nl_family = AF_NETLINK
} ;
2014-08-21 07:17:48 +04:00
struct {
struct nlmsghdr nlh ;
struct inet_diag_req_v2 idr ;
2014-11-21 22:59:16 +03:00
} req = {
. nlh = {
. nlmsg_len = sizeof ( req ) ,
. nlmsg_type = SOCK_DIAG_BY_FAMILY ,
. nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST
} ,
. idr = {
. sdiag_family = family ,
. sdiag_protocol = proto ,
. idiag_states = - 1
}
} ;
2014-08-21 07:17:48 +04:00
struct iovec iov = {
. iov_base = & req ,
. iov_len = sizeof ( req )
} ;
struct msghdr msg = {
. msg_name = ( void * ) & nladdr ,
. msg_namelen = sizeof ( nladdr ) ,
. msg_iov = & iov ,
. msg_iovlen = 1
} ;
for ( ; ; ) {
if ( sendmsg ( fd , & msg , 0 ) < 0 ) {
if ( errno = = EINTR )
continue ;
return false ;
}
return true ;
}
}
static bool
2014-12-27 02:29:26 +03:00
inet_parse_response ( const char * proto_name , const void * data , int data_len ,
const unsigned long inode )
2014-08-21 07:17:48 +04:00
{
Support unix domain sockets in -yy option
This change extends -yy option to handle unix domain sockets:
their peer addresses will be printed, similar to inet sockets.
For a listening socket, its socket inode and socket path are printed.
For an accepted socket, its socket inode, the peer inode, and the
socket path are printed.
For a client socket, its socket inode and the peer inode are printed.
An example of a server side communication using netcat:
$ ./strace -yy -e network nc -l -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
setsockopt(3<UNIX:[14728348]>, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3<UNIX:[14728348]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
listen(3<UNIX:[14728348,"/tmp/example.sock"]>, 10) = 0
accept(3<UNIX:[14728348,"/tmp/example.sock"]>, {sa_family=AF_LOCAL, NULL}, [2]) = 4<UNIX:[14727246->14727245,"/tmp/example.sock"]>
recvfrom(4<UNIX:[14727246->14727245,"/tmp/example.sock"]>, "INPUT\n", 8192, 0, NULL, NULL) = 6
INPUT
An example of a client side communication using netcat:
$ ./strace -yy -e network nc -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3<UNIX:[14727245]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
getsockopt(3<UNIX:[14727245]>, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
INPUT
...
sendto(3<UNIX:[14727245->14727246]>, "INPUT\n", 6, 0, NULL, 0) = 6
* linux/unix_diag.h: New file.
* socketutils.c (send_query): Rename to inet_send_query.
(parse_response): Rename to inet_parse_response.
(unix_print, unix_send_query, unix_parse_response): New functions.
(receive_responses): Add a new argument named parser: a function for
handling protocol specific data parts of diag messages.
(print_sockaddr_by_inode): Call unix_print.
Replace NETLINK_INET_DIAG with NETLINK_SOCK_DIAG, they are equal
but NETLINK_SOCK_DIAG looks more generic.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2014-12-24 14:59:31 +03:00
const struct inet_diag_msg * diag_msg = data ;
2014-08-21 07:17:48 +04:00
static const char zero_addr [ sizeof ( struct in6_addr ) ] ;
socklen_t addr_size , text_size ;
if ( diag_msg - > idiag_inode ! = inode )
return false ;
switch ( diag_msg - > idiag_family ) {
case AF_INET :
addr_size = sizeof ( struct in_addr ) ;
text_size = INET_ADDRSTRLEN ;
break ;
case AF_INET6 :
addr_size = sizeof ( struct in6_addr ) ;
text_size = INET6_ADDRSTRLEN ;
break ;
default :
return false ;
}
char src_buf [ text_size ] ;
if ( ! inet_ntop ( diag_msg - > idiag_family , diag_msg - > id . idiag_src ,
src_buf , text_size ) )
return false ;
if ( diag_msg - > id . idiag_dport | |
memcmp ( zero_addr , diag_msg - > id . idiag_dst , addr_size ) ) {
char dst_buf [ text_size ] ;
if ( ! inet_ntop ( diag_msg - > idiag_family , diag_msg - > id . idiag_dst ,
dst_buf , text_size ) )
return false ;
2014-12-27 02:29:26 +03:00
tprintf ( " %s:[%s:%u->%s:%u] " ,
proto_name ,
2014-08-21 07:17:48 +04:00
src_buf , ntohs ( diag_msg - > id . idiag_sport ) ,
dst_buf , ntohs ( diag_msg - > id . idiag_dport ) ) ;
} else {
2014-12-27 02:29:26 +03:00
tprintf ( " %s:[%s:%u] " , proto_name , src_buf ,
ntohs ( diag_msg - > id . idiag_sport ) ) ;
2014-08-21 07:17:48 +04:00
}
return true ;
}
static bool
Support unix domain sockets in -yy option
This change extends -yy option to handle unix domain sockets:
their peer addresses will be printed, similar to inet sockets.
For a listening socket, its socket inode and socket path are printed.
For an accepted socket, its socket inode, the peer inode, and the
socket path are printed.
For a client socket, its socket inode and the peer inode are printed.
An example of a server side communication using netcat:
$ ./strace -yy -e network nc -l -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
setsockopt(3<UNIX:[14728348]>, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3<UNIX:[14728348]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
listen(3<UNIX:[14728348,"/tmp/example.sock"]>, 10) = 0
accept(3<UNIX:[14728348,"/tmp/example.sock"]>, {sa_family=AF_LOCAL, NULL}, [2]) = 4<UNIX:[14727246->14727245,"/tmp/example.sock"]>
recvfrom(4<UNIX:[14727246->14727245,"/tmp/example.sock"]>, "INPUT\n", 8192, 0, NULL, NULL) = 6
INPUT
An example of a client side communication using netcat:
$ ./strace -yy -e network nc -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3<UNIX:[14727245]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
getsockopt(3<UNIX:[14727245]>, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
INPUT
...
sendto(3<UNIX:[14727245->14727246]>, "INPUT\n", 6, 0, NULL, 0) = 6
* linux/unix_diag.h: New file.
* socketutils.c (send_query): Rename to inet_send_query.
(parse_response): Rename to inet_parse_response.
(unix_print, unix_send_query, unix_parse_response): New functions.
(receive_responses): Add a new argument named parser: a function for
handling protocol specific data parts of diag messages.
(print_sockaddr_by_inode): Call unix_print.
Replace NETLINK_INET_DIAG with NETLINK_SOCK_DIAG, they are equal
but NETLINK_SOCK_DIAG looks more generic.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2014-12-24 14:59:31 +03:00
receive_responses ( const int fd , const unsigned long inode ,
2014-12-27 02:29:26 +03:00
const char * proto_name ,
bool ( * parser ) ( const char * , const void * , int , const unsigned long ) )
2014-08-21 07:17:48 +04:00
{
static char buf [ 8192 ] ;
2014-11-21 22:59:16 +03:00
struct sockaddr_nl nladdr = {
. nl_family = AF_NETLINK
} ;
2014-08-21 07:17:48 +04:00
struct iovec iov = {
. iov_base = buf ,
. iov_len = sizeof ( buf )
} ;
for ( ; ; ) {
ssize_t ret ;
struct nlmsghdr * h ;
struct msghdr msg = {
. msg_name = ( void * ) & nladdr ,
. msg_namelen = sizeof ( nladdr ) ,
. msg_iov = & iov ,
2014-11-21 22:59:16 +03:00
. msg_iovlen = 1
2014-08-21 07:17:48 +04:00
} ;
ret = recvmsg ( fd , & msg , 0 ) ;
if ( ret < 0 ) {
if ( errno = = EINTR )
continue ;
return false ;
}
if ( ! ret )
return false ;
for ( h = ( struct nlmsghdr * ) buf ;
NLMSG_OK ( h , ret ) ;
h = NLMSG_NEXT ( h , ret ) ) {
switch ( h - > nlmsg_type ) {
case NLMSG_DONE :
case NLMSG_ERROR :
return false ;
}
2014-12-27 02:29:26 +03:00
if ( parser ( proto_name , NLMSG_DATA ( h ) , h - > nlmsg_len , inode ) )
2014-08-21 07:17:48 +04:00
return true ;
}
}
}
2014-12-10 06:55:06 +03:00
static bool
2014-12-27 02:29:26 +03:00
inet_print ( const int fd , const int family , const int protocol ,
const unsigned long inode , const char * proto_name )
2014-12-10 06:55:06 +03:00
{
Support unix domain sockets in -yy option
This change extends -yy option to handle unix domain sockets:
their peer addresses will be printed, similar to inet sockets.
For a listening socket, its socket inode and socket path are printed.
For an accepted socket, its socket inode, the peer inode, and the
socket path are printed.
For a client socket, its socket inode and the peer inode are printed.
An example of a server side communication using netcat:
$ ./strace -yy -e network nc -l -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
setsockopt(3<UNIX:[14728348]>, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3<UNIX:[14728348]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
listen(3<UNIX:[14728348,"/tmp/example.sock"]>, 10) = 0
accept(3<UNIX:[14728348,"/tmp/example.sock"]>, {sa_family=AF_LOCAL, NULL}, [2]) = 4<UNIX:[14727246->14727245,"/tmp/example.sock"]>
recvfrom(4<UNIX:[14727246->14727245,"/tmp/example.sock"]>, "INPUT\n", 8192, 0, NULL, NULL) = 6
INPUT
An example of a client side communication using netcat:
$ ./strace -yy -e network nc -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3<UNIX:[14727245]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
getsockopt(3<UNIX:[14727245]>, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
INPUT
...
sendto(3<UNIX:[14727245->14727246]>, "INPUT\n", 6, 0, NULL, 0) = 6
* linux/unix_diag.h: New file.
* socketutils.c (send_query): Rename to inet_send_query.
(parse_response): Rename to inet_parse_response.
(unix_print, unix_send_query, unix_parse_response): New functions.
(receive_responses): Add a new argument named parser: a function for
handling protocol specific data parts of diag messages.
(print_sockaddr_by_inode): Call unix_print.
Replace NETLINK_INET_DIAG with NETLINK_SOCK_DIAG, they are equal
but NETLINK_SOCK_DIAG looks more generic.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2014-12-24 14:59:31 +03:00
return inet_send_query ( fd , family , protocol )
2014-12-27 02:29:26 +03:00
& & receive_responses ( fd , inode , proto_name , inet_parse_response ) ;
Support unix domain sockets in -yy option
This change extends -yy option to handle unix domain sockets:
their peer addresses will be printed, similar to inet sockets.
For a listening socket, its socket inode and socket path are printed.
For an accepted socket, its socket inode, the peer inode, and the
socket path are printed.
For a client socket, its socket inode and the peer inode are printed.
An example of a server side communication using netcat:
$ ./strace -yy -e network nc -l -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
setsockopt(3<UNIX:[14728348]>, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3<UNIX:[14728348]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
listen(3<UNIX:[14728348,"/tmp/example.sock"]>, 10) = 0
accept(3<UNIX:[14728348,"/tmp/example.sock"]>, {sa_family=AF_LOCAL, NULL}, [2]) = 4<UNIX:[14727246->14727245,"/tmp/example.sock"]>
recvfrom(4<UNIX:[14727246->14727245,"/tmp/example.sock"]>, "INPUT\n", 8192, 0, NULL, NULL) = 6
INPUT
An example of a client side communication using netcat:
$ ./strace -yy -e network nc -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3<UNIX:[14727245]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
getsockopt(3<UNIX:[14727245]>, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
INPUT
...
sendto(3<UNIX:[14727245->14727246]>, "INPUT\n", 6, 0, NULL, 0) = 6
* linux/unix_diag.h: New file.
* socketutils.c (send_query): Rename to inet_send_query.
(parse_response): Rename to inet_parse_response.
(unix_print, unix_send_query, unix_parse_response): New functions.
(receive_responses): Add a new argument named parser: a function for
handling protocol specific data parts of diag messages.
(print_sockaddr_by_inode): Call unix_print.
Replace NETLINK_INET_DIAG with NETLINK_SOCK_DIAG, they are equal
but NETLINK_SOCK_DIAG looks more generic.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2014-12-24 14:59:31 +03:00
}
static bool
unix_send_query ( const int fd , const unsigned long inode )
{
struct sockaddr_nl nladdr = {
. nl_family = AF_NETLINK
} ;
struct {
struct nlmsghdr nlh ;
struct unix_diag_req udr ;
} req = {
. nlh = {
. nlmsg_len = sizeof ( req ) ,
. nlmsg_type = SOCK_DIAG_BY_FAMILY ,
. nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST
} ,
. udr = {
. sdiag_family = AF_UNIX ,
. udiag_ino = inode ,
. udiag_states = - 1 ,
. udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER
}
} ;
struct iovec iov = {
. iov_base = & req ,
. iov_len = sizeof ( req )
} ;
struct msghdr msg = {
. msg_name = ( void * ) & nladdr ,
. msg_namelen = sizeof ( nladdr ) ,
. msg_iov = & iov ,
. msg_iovlen = 1
} ;
for ( ; ; ) {
if ( sendmsg ( fd , & msg , 0 ) < 0 ) {
if ( errno = = EINTR )
continue ;
return false ;
}
return true ;
}
}
static bool
2014-12-27 02:29:26 +03:00
unix_parse_response ( const char * proto_name , const void * data , int data_len ,
const unsigned long inode )
Support unix domain sockets in -yy option
This change extends -yy option to handle unix domain sockets:
their peer addresses will be printed, similar to inet sockets.
For a listening socket, its socket inode and socket path are printed.
For an accepted socket, its socket inode, the peer inode, and the
socket path are printed.
For a client socket, its socket inode and the peer inode are printed.
An example of a server side communication using netcat:
$ ./strace -yy -e network nc -l -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
setsockopt(3<UNIX:[14728348]>, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3<UNIX:[14728348]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
listen(3<UNIX:[14728348,"/tmp/example.sock"]>, 10) = 0
accept(3<UNIX:[14728348,"/tmp/example.sock"]>, {sa_family=AF_LOCAL, NULL}, [2]) = 4<UNIX:[14727246->14727245,"/tmp/example.sock"]>
recvfrom(4<UNIX:[14727246->14727245,"/tmp/example.sock"]>, "INPUT\n", 8192, 0, NULL, NULL) = 6
INPUT
An example of a client side communication using netcat:
$ ./strace -yy -e network nc -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3<UNIX:[14727245]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
getsockopt(3<UNIX:[14727245]>, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
INPUT
...
sendto(3<UNIX:[14727245->14727246]>, "INPUT\n", 6, 0, NULL, 0) = 6
* linux/unix_diag.h: New file.
* socketutils.c (send_query): Rename to inet_send_query.
(parse_response): Rename to inet_parse_response.
(unix_print, unix_send_query, unix_parse_response): New functions.
(receive_responses): Add a new argument named parser: a function for
handling protocol specific data parts of diag messages.
(print_sockaddr_by_inode): Call unix_print.
Replace NETLINK_INET_DIAG with NETLINK_SOCK_DIAG, they are equal
but NETLINK_SOCK_DIAG looks more generic.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2014-12-24 14:59:31 +03:00
{
const struct unix_diag_msg * diag_msg = data ;
struct rtattr * attr ;
int rta_len = data_len - NLMSG_LENGTH ( sizeof ( * diag_msg ) ) ;
uint32_t peer = 0 ;
size_t path_len = 0 ;
char path [ UNIX_PATH_MAX + 1 ] ;
if ( diag_msg - > udiag_ino ! = inode )
return false ;
if ( diag_msg - > udiag_family ! = AF_UNIX )
return false ;
for ( attr = ( struct rtattr * ) ( diag_msg + 1 ) ;
RTA_OK ( attr , rta_len ) ;
attr = RTA_NEXT ( attr , rta_len ) ) {
switch ( attr - > rta_type ) {
case UNIX_DIAG_NAME :
if ( ! path_len ) {
path_len = RTA_PAYLOAD ( attr ) ;
if ( path_len > UNIX_PATH_MAX )
path_len = UNIX_PATH_MAX ;
memcpy ( path , RTA_DATA ( attr ) , path_len ) ;
path [ path_len ] = ' \0 ' ;
}
break ;
case UNIX_DIAG_PEER :
if ( RTA_PAYLOAD ( attr ) > = 4 )
peer = * ( uint32_t * ) RTA_DATA ( attr ) ;
break ;
}
}
/*
* print obtained information in the following format :
* " UNIX:[ " SELF_INODE [ " -> " PEER_INODE ] [ " , " SOCKET_FILE ] " ] "
*/
if ( peer | | path_len ) {
2014-12-27 02:29:26 +03:00
tprintf ( " %s:[%lu " , proto_name , inode ) ;
Support unix domain sockets in -yy option
This change extends -yy option to handle unix domain sockets:
their peer addresses will be printed, similar to inet sockets.
For a listening socket, its socket inode and socket path are printed.
For an accepted socket, its socket inode, the peer inode, and the
socket path are printed.
For a client socket, its socket inode and the peer inode are printed.
An example of a server side communication using netcat:
$ ./strace -yy -e network nc -l -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
setsockopt(3<UNIX:[14728348]>, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3<UNIX:[14728348]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
listen(3<UNIX:[14728348,"/tmp/example.sock"]>, 10) = 0
accept(3<UNIX:[14728348,"/tmp/example.sock"]>, {sa_family=AF_LOCAL, NULL}, [2]) = 4<UNIX:[14727246->14727245,"/tmp/example.sock"]>
recvfrom(4<UNIX:[14727246->14727245,"/tmp/example.sock"]>, "INPUT\n", 8192, 0, NULL, NULL) = 6
INPUT
An example of a client side communication using netcat:
$ ./strace -yy -e network nc -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3<UNIX:[14727245]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
getsockopt(3<UNIX:[14727245]>, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
INPUT
...
sendto(3<UNIX:[14727245->14727246]>, "INPUT\n", 6, 0, NULL, 0) = 6
* linux/unix_diag.h: New file.
* socketutils.c (send_query): Rename to inet_send_query.
(parse_response): Rename to inet_parse_response.
(unix_print, unix_send_query, unix_parse_response): New functions.
(receive_responses): Add a new argument named parser: a function for
handling protocol specific data parts of diag messages.
(print_sockaddr_by_inode): Call unix_print.
Replace NETLINK_INET_DIAG with NETLINK_SOCK_DIAG, they are equal
but NETLINK_SOCK_DIAG looks more generic.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2014-12-24 14:59:31 +03:00
if ( peer )
tprintf ( " ->%u " , peer ) ;
if ( path_len ) {
if ( path [ 0 ] = = ' \0 ' ) {
char * outstr = alloca ( 4 * path_len - 1 ) ;
string_quote ( path + 1 , outstr , - 1 , path_len ) ;
tprintf ( " ,@%s " , outstr ) ;
} else {
char * outstr = alloca ( 4 * path_len + 3 ) ;
string_quote ( path , outstr , - 1 , path_len + 1 ) ;
tprintf ( " ,%s " , outstr ) ;
}
}
tprints ( " ] " ) ;
return true ;
}
else
return false ;
}
static bool
unix_print ( int fd , const unsigned long inode )
{
return unix_send_query ( fd , inode )
2014-12-27 02:29:26 +03:00
& & receive_responses ( fd , inode , " UNIX " , unix_parse_response ) ;
2014-12-10 06:55:06 +03:00
}
2014-08-21 07:17:48 +04:00
/* Given an inode number of a socket, print out the details
* of the ip address and port . */
bool
2014-12-10 06:55:06 +03:00
print_sockaddr_by_inode ( const unsigned long inode , const char * proto_name )
2014-08-21 07:17:48 +04:00
{
int fd ;
2014-12-10 06:55:06 +03:00
bool r = false ;
2014-08-21 07:17:48 +04:00
Support unix domain sockets in -yy option
This change extends -yy option to handle unix domain sockets:
their peer addresses will be printed, similar to inet sockets.
For a listening socket, its socket inode and socket path are printed.
For an accepted socket, its socket inode, the peer inode, and the
socket path are printed.
For a client socket, its socket inode and the peer inode are printed.
An example of a server side communication using netcat:
$ ./strace -yy -e network nc -l -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
setsockopt(3<UNIX:[14728348]>, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3<UNIX:[14728348]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
listen(3<UNIX:[14728348,"/tmp/example.sock"]>, 10) = 0
accept(3<UNIX:[14728348,"/tmp/example.sock"]>, {sa_family=AF_LOCAL, NULL}, [2]) = 4<UNIX:[14727246->14727245,"/tmp/example.sock"]>
recvfrom(4<UNIX:[14727246->14727245,"/tmp/example.sock"]>, "INPUT\n", 8192, 0, NULL, NULL) = 6
INPUT
An example of a client side communication using netcat:
$ ./strace -yy -e network nc -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3<UNIX:[14727245]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
getsockopt(3<UNIX:[14727245]>, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
INPUT
...
sendto(3<UNIX:[14727245->14727246]>, "INPUT\n", 6, 0, NULL, 0) = 6
* linux/unix_diag.h: New file.
* socketutils.c (send_query): Rename to inet_send_query.
(parse_response): Rename to inet_parse_response.
(unix_print, unix_send_query, unix_parse_response): New functions.
(receive_responses): Add a new argument named parser: a function for
handling protocol specific data parts of diag messages.
(print_sockaddr_by_inode): Call unix_print.
Replace NETLINK_INET_DIAG with NETLINK_SOCK_DIAG, they are equal
but NETLINK_SOCK_DIAG looks more generic.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2014-12-24 14:59:31 +03:00
fd = socket ( AF_NETLINK , SOCK_RAW , NETLINK_SOCK_DIAG ) ;
2014-08-21 07:17:48 +04:00
if ( fd < 0 )
return false ;
2014-12-10 06:55:06 +03:00
if ( proto_name ) {
if ( strcmp ( proto_name , " TCP " ) = = 0 )
2014-12-27 02:29:26 +03:00
r = inet_print ( fd , AF_INET , IPPROTO_TCP , inode , " TCP " ) ;
2014-12-10 06:55:06 +03:00
else if ( strcmp ( proto_name , " UDP " ) = = 0 )
2014-12-27 02:29:26 +03:00
r = inet_print ( fd , AF_INET , IPPROTO_UDP , inode , " UDP " ) ;
2014-12-10 06:55:06 +03:00
else if ( strcmp ( proto_name , " TCPv6 " ) = = 0 )
2014-12-27 02:29:26 +03:00
r = inet_print ( fd , AF_INET6 , IPPROTO_TCP , inode , " TCPv6 " ) ;
2014-12-10 06:55:06 +03:00
else if ( strcmp ( proto_name , " UDPv6 " ) = = 0 )
2014-12-27 02:29:26 +03:00
r = inet_print ( fd , AF_INET6 , IPPROTO_UDP , inode , " UDPv6 " ) ;
Support unix domain sockets in -yy option
This change extends -yy option to handle unix domain sockets:
their peer addresses will be printed, similar to inet sockets.
For a listening socket, its socket inode and socket path are printed.
For an accepted socket, its socket inode, the peer inode, and the
socket path are printed.
For a client socket, its socket inode and the peer inode are printed.
An example of a server side communication using netcat:
$ ./strace -yy -e network nc -l -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
setsockopt(3<UNIX:[14728348]>, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3<UNIX:[14728348]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
listen(3<UNIX:[14728348,"/tmp/example.sock"]>, 10) = 0
accept(3<UNIX:[14728348,"/tmp/example.sock"]>, {sa_family=AF_LOCAL, NULL}, [2]) = 4<UNIX:[14727246->14727245,"/tmp/example.sock"]>
recvfrom(4<UNIX:[14727246->14727245,"/tmp/example.sock"]>, "INPUT\n", 8192, 0, NULL, NULL) = 6
INPUT
An example of a client side communication using netcat:
$ ./strace -yy -e network nc -U /tmp/example.sock
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3<UNIX:[14727245]>, {sa_family=AF_LOCAL, sun_path="/tmp/example.sock"}, 19) = 0
getsockopt(3<UNIX:[14727245]>, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
INPUT
...
sendto(3<UNIX:[14727245->14727246]>, "INPUT\n", 6, 0, NULL, 0) = 6
* linux/unix_diag.h: New file.
* socketutils.c (send_query): Rename to inet_send_query.
(parse_response): Rename to inet_parse_response.
(unix_print, unix_send_query, unix_parse_response): New functions.
(receive_responses): Add a new argument named parser: a function for
handling protocol specific data parts of diag messages.
(print_sockaddr_by_inode): Call unix_print.
Replace NETLINK_INET_DIAG with NETLINK_SOCK_DIAG, they are equal
but NETLINK_SOCK_DIAG looks more generic.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2014-12-24 14:59:31 +03:00
else if ( strcmp ( proto_name , " UNIX " ) = = 0 )
r = unix_print ( fd , inode ) ;
2014-12-10 06:55:06 +03:00
} else {
2014-12-27 02:29:26 +03:00
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 ;
2014-12-10 06:55:06 +03:00
2014-12-27 02:29:26 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( protocols ) ; + + i ) {
if ( ( r = inet_print ( fd , protocols [ i ] . family ,
protocols [ i ] . protocol , inode ,
protocols [ i ] . name ) ) )
break ;
2014-08-21 07:17:48 +04:00
}
}
2014-12-27 02:29:26 +03:00
2014-08-21 07:17:48 +04:00
close ( fd ) ;
2014-12-10 06:55:06 +03:00
return r ;
2014-08-21 07:17:48 +04:00
}