If you have been working with netstat on GNU/Linux for some time you’ve probably already noticed, that more often than not, applications that actually are used exclusively or almost exclusively via IPv4, show up as if we were using IPv6. A typical example is the Squid Proxy on
$ netstat -tn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 xx.xxx.xx.xxx:22 yyy.yyy.yyy.yy:56542 ESTABLISHED
tcp6 0 0 xx.xxx.xx.xxx:3128 yyy.yyy.yyy.yy:3134 ESTABLISHED
yyy.yyy.yyy.yy being IPv4 addresses, two questions arise:
- Why are IPv4 connections tagged with tcp6 by netstat?
- What makes the SSH connection to
To answer these questions we have to make a brief excursion to the Linux Socket API. Using the socket() function we can either create
- a plain old IPv4 socket,
- an IPv6 socket,
- or a dual mode IPv6 socket.
Dual mode IPv6 sockets handle IPv4 connections using IPv4-Mapped IPv6 Addresses. Unfortunately, at least on Linux, there seems to be no clean way to distinguish pure IPv6 from dual mode IPv6 sockets for outside programs. They both show up in
/proc/net/tcp6, where netstat finds them and displays them accordingly. The status of plain old IPv4 sockets on the other hand, is made available to user space via
Using this information our two questions are easily answered:
- Information related to dual mode IPv6 sockets, as they are used by Squid, is tagged with tcp6.
- Information related to plain old IPv4 sockets, like the SSH connection above, is tagged with tcp.
Note that dual-mode sockets are not only supported by Linux, but by most modern operating systems. They are preferred by the Java socket implementation unless you set the system property
java.net.preferIPv4Stack to true. I have written a small C program that demonstrates the different types of sockets discussed above. You can play around with it if you are interested in the gory details.