knetstat is a simple Linux kernel module that adds four new files to /proc/net
: tcpstat
, tcp6stat
, udpstat
and udp6stat
. The content of these files is roughly equivalent to the output of netstat
with options -t4an
, -t6an
, -u4an
and -u6an
respectively, i.e. they provide information about TCP and UDP sockets in human readable form. The difference with the corresponding netstat
output is that they have an additional column that displays (a subset of) the socket options. This was the primary motivation for writing the knetstat kernel module: currently, on Linux there is no way for an administrator to inspect the options set on a socket created by some process (other than using strace
or an equivalent tool on that process at socket creation/configuration time), because this information is not exposed through the /proc
file system.
knetstat internally reuses the infrastructure that is used by the kernel to generate the content of the /proc/net/tcp
, /proc/net/tcp6
, /proc/net/udp
and /proc/net/udp6
files. This means that there is a one-to-one correspondence between the entries in these files and the entries in the files generated by knetstat. Only the formatting and information content is different between the two.
Here is some sample output:
$ cat /proc/net/tcpstat
Recv-Q Send-Q Local Address Foreign Address Stat Diag Options
0 0 127.0.0.1:6010 0.0.0.0:* LSTN SO_REUSEADDR=1,SO_KEEPALIVE=0,TCP_NODELAY=0
0 0 0.0.0.0:22 0.0.0.0:* LSTN SO_REUSEADDR=1,SO_KEEPALIVE=0,TCP_NODELAY=0
0 0 192.168.1.18:22 192.168.1.6:49537 ESTB SO_REUSEADDR=1,SO_KEEPALIVE=1,TCP_NODELAY=1
0 0 127.0.0.1:6010 127.0.0.1:45462 ESTB SO_REUSEADDR=1,SO_KEEPALIVE=0,TCP_NODELAY=1
0 0 127.0.0.1:45462 127.0.0.1:6010 ESTB SO_REUSEADDR=0,SO_KEEPALIVE=1,TCP_NODELAY=1
The "Diag" column can display the following diagnostic indicators:
Indicator | Meaning |
---|---|
>| |
The sender window (i.e. the window advertised by the remote endpoint) is 0. No data can be sent to the peer. |
|< |
The receiver window (i.e. the window advertised by the local endpoint) is 0. No data can be received from the peer. |
># |
There are unacknowledged packets and the last ACK was received more than one second ago. This may be an indication that there are network problems or that the peer crashed. |
- Protocols: TCP and UDP (IPv4 and IPv6)
- Socket options:
SO_REUSEADDR
,SO_REUSEPORT
,SO_KEEPALIVE
(TCP),TCP_KEEPIDLE
(TCP),TCP_KEEPCNT
(TCP),TCP_KEEPINTVL
(TCP),SO_RCVBUF
,SO_SNDBUF
,SO_RCVTIMEO
,SO_SNDTIMEO
,SO_LINGER
(TCP),TCP_NODELAY
,TCP_FASTOPEN
,TCP_DEFER_ACCEPT
,SO_BROADCAST
(UDP)
TCP_KEEPIDLE, TCP_KEEPCNT and TCP_KEEPINTVL correspond to tcp_keepalive_time, tcp_keepalive_probes and tcp_keepalive_intvl values described in tcp(7) and the respective sysctls. If those values are overridden at the socket level (by setting them to something other than zero), they will be printed by knetstat, otherwise, the kernel will use sysctls and the module will ignore them while printing the output.
The current knetstat code has been successfully tested with kernel versions 3.13, 3.18, 4.4, 4.8, 4.9 and 4.15. It may work with other versions as well.
To build the module, ensure that you have the headers for the currently running kernel as well as the basic build tools such as make and GCC. E.g. on Ubuntu:
# apt-get install linux-headers-$(uname -r) make gcc
Then check out the knetstat source code and execute make
. This should create knetstat.ko
which can be loaded using insmod
.
The following table shows the correspondence between socket options reported by knetstat and setter methods defined by the java.net.Socket
class. This information can be used to infer the configuration that a Java process applied to a java.net.Socket
instance based on the output of knetstat. The mapping is straightforward, except for setSoTimeout
.
Java method | Socket option reported by knetstat |
---|---|
setKeepAlive |
SO_KEEPALIVE |
setReceiveBufferSize |
SO_RCVBUF |
setReuseAddress |
SO_REUSEADDR |
setSendBufferSize |
SO_SNDBUF |
setSoLinger |
SO_LINGER |
setSoTimeout |
none [*] |
setTcpNoDelay |
TCP_NODELAY |
[*] In contrast to what the Javadoc suggests, the setSoTimeout
method doesn't actually set any socket option on Linux. By default, java.net.Socket
instances are backed by java.net.SocksSocketImpl
(even if no SOCKS proxy is configured). This class extends java.net.AbstractPlainSocketImpl
which stores the timeout internally for later use by the read methods in java.net.SocketInputStream
. They in turn pass the timeout to an invocation of the poll
system call that waits until data is available for reading (or an error occurs).