Within the UNIX environment, it is common practice to pass open sockets between applications using exec. With a mixture of IPv4 and IPv6 applications running on the same host, passing open sockets becomes more complicated. An IPv4 socket references the sockadd_in structure, but an IPv6 socket references sockaddr_in6. To combat this problem a new socket option, IPV6_ADDRFORM, has been introduced.
IPV6_ADDRFORM provides socket transformation between IPv4 and IPv6, enabling sockets to be passed between IPv4 and IPv6 applications. All IPv4/IPv6 socket transformation should be performed by IPv6 applications. However, during the transition between IPv4 and IPv6, you may still need to develop pure IPv4 applications. Use IPV6_ADDRFORM to check, and if necessary transform any incoming IPv6 sockets into IPv4 sockets, and vice versa. This will ensure that your application will work effectively in a mixed IPv4/IPv6 environment.
IPV6_ADDRFORM has one argument, an integer pointer. This pointer must point to a value of either PF_INET or PF_INET6. The example below shows how to check an open socket, and if necessary, convert it so that subsequent system calls using that socket will return IPv4 address structures (sockaddr_in).
int addrform_in; int addrform_out = PF_INET; size_t len = sizeof(int);
/* Find out if the open socket is already an IPv4 socket */
if (getsockopt(s, IPPROTO_IP, IPV6_ADDRFORM, &addrform_in, &len) == -1) perror ("getsockopt IPV6_ADDRFORM");
/* If the open socket is PF_INET6, convert it */
if (addrform_in == PF_INET6) if (setsockopt(s, IPPROTO_IP, IPV6_ADDRFORM, &addrform_out, sizeof(addrform_out)) == -1) perror ("setsockopt IPV6_ADDFORM");