There are two ways that a dual stack listening socket can be implemented;
In the latter case the kernel will convert the IPv4 addresses into a
special type of IPv6 addresses called 'IPv4-mapped IPv6 addresses'.
For this purpose, it appends the IPv4 address to '::ffff:'.
Below a 'visual' description;
Convert each of the four bytes of the IPv4 address into a two-digit
hexadecimal number;
192.168.1.8 -> c0.a8.01.08
Merge two bytes to 16 bits;
c0.a8.01.08
-> c0a8.0108
Replace dot by colon;
c0a8.0108
-> c0a8:0108
Remove the leading zeros of each 16-bit number;
c0a8:0108
-> c0a8:108
Prepend prefix '::ffff:';
c0a8:108 -> ::ffff:c0a8:108
Note: This is usually written as ::ffff:192.168.1.8. The notation used above is a more regular IPv6 notation.
As an illustration, the examples below also include netmasks;
IPv4 address | IPv6 mapped |
---|---|
127.0.0.1 | ::ffff:7f00:1 |
10.0.0.0/8 | ::ffff:a00:0/104 |
172.16.0.0/12 | ::ffff:ac10:0/108 |
192.168.0.0/16 | ::ffff:c0a8:0/112 |
192.168.1.0/24 | ::ffff:c0a8:100/120 |
192.168.1.1 | ::ffff:c0a8:101 |
Note: The IPv6 netmask is the IPv4 netmask plus 96.
Just in case you ever need to do the conversion yourself,
a form that does the conversion for you. If the strings starts with '::ffff:'
it will do the conversion the other way around.
You can include netmasks if you like;
Note: The software tries to clean up network/netmask combinations if it
thinks they are wrong.
E.G.: Convert '192.168.1.1/24' to '192.168.1.0/24' and
'192.168.1.1/16' to '192.168.0.0/16'.
See:
Valid IPv4 network addresses
and
Valid IPv6 network addresses
for more info.