Back in the IPv4-only days, a LISTEN connection showing in netstat
as listening on 0.0.0.0
would respond to connections on any IPv4 interface in the system.
As I understand it, the new IPv6 idiom ::
listens on all available IPv6 and IPv4 interfaces. Is this correct, for all OSes (Unix, Windows, Mac)? Is there an idiom to listen on just the IPv6 interfaces?
Unfortunately, this differs depending on what operating system you are using.
On Microsoft Windows, binding a socket to
::
only binds to the IPv6 ports. Thus to listen on all addresses on both IPv4 and IPv6, you need to bind to0.0.0.0
as well as::
. The following extract is from a Vista box:The example I give is port 445, used for SMB traffic when NetBIOS isn't used. As you can see, it is binding to both
0.0.0.0
and::
to make, respectively, both IPv4 and IPv6 clients work.On Linux,
::
is inclusive of the IPv4-compatible addresses, as you have correctly guessed, so binding to0.0.0.0
as well is unnecessary. I wrote a simple Python program that only binds to anAF_INET6
socket on::
. Even though I didn't also bind to anAF_INET
(IPv4) socket, it still accepts connections from IPv4 clients. If, say,10.1.1.3
connects to it, it will show up as connecting from::ffff:10.1.1.3
.Except that it gets hairy. The above doesn't apply on Linux if
/proc/sys/net/ipv6/bindv6only
is set to1
, in which case the behaviour is exactly the same as Windows -- binding to::
will only listen for IPv6 requests. If you want to listen for IPv4 requests as well, you will need to create anAF_INET
socket and listen on0.0.0.0
as well. Fortunately, the default forbindv6only
is0
, so there's a very slim chance you'll ever have to deal with this (except if you use Debian, which actually defaults tobindv6only = 1
).All of this is handy to know in checking to see if a service is IPv6-enabled, and whether it is IPv4-enabled as well. Here is my SSH server:
As you can see, SSH is only listening on
::
port 22. However, it is not just listening for IPv6 clients -- it works fine from IPv4 clients, because of the IPv4-compatible binding. To prove this, if you look at this:bindv6only
is disabled (the default). If that were set to1
, then I would have to encourage SSH to listen on0.0.0.0
as well (or instead).Apologies for having no information on the Mac OS X side of things. I have used it in the past, but I prefer the aesthetics of GNOME, so I haven't used it in a very long time. However, I would guess that the behaviour is the same as that of Linux.
Hope this helps.
This isn't possible, as a segment of the IPv6 address space is the same as the IPv4 space, so even if you could somehow disable IPv4 sockets, you'd still be able to send IPv4 packets to the IPv6 socket. Checkout the IPv4 transition section in the IPv4 wikipedia page.
Edit: Ah, bit further down it does say:
You could probably do it with your network ID, AAAA:BBBB:CCCC:DDDD:: or whatever it is for you. That would guarantee that only IPv6 interfaces would pick it up. I think. I'm no IPv6 master.