Using AF_INET6 address family
AF_INET6 sockets provide support for Internet Protocol version 6 (IPv6) 128 bit (16 byte) address structures. Programmers can write applications using the AF_INET6 address family to accept client requests from either IPv4 or IPv6 nodes, or from IPv6 nodes only.
Like AF_INET sockets, AF_INET6 sockets can be either connection-oriented (type SOCK_STREAM) or connectionless (type SOCK_DGRAM). Connection-oriented AF_INET6 sockets use TCP as the transport protocol. Connectionless AF_INET6 sockets use User Datagram Protocol (UDP) as the transport protocol. When you create an AF_INET6 domain socket, you specify AF_INET6 for the address family in the socket program. AF_INET6 sockets can also use a type of SOCK_RAW. If this type is set, the application connects directly to the IP layer and does not use either the TCP or UDP transport.
IPv6 applications compatibility with IPv4 applications
Socket applications written with AF_INET6 address family allow Internet Protocol version 6 (IPv6) applications to work with Internet Protocol version 4 (IPv4) applications (those applications that use AF_INET address family). This feature allows socket programmers to use an IPv4-mapped IPv6 address format. This address format represents the IPv4 address of an IPv4 node to be represented as an IPv6 address. The IPv4 address is encoded into the low-order 32 bits of the IPv6 address, and the high-order 96 bits hold the fixed prefix 0:0:0:0:0:FFFF. For example, an IPv4-mapped address can look like this:
These addresses can be generated automatically by the getaddrinfo() API, when the specified host has only IPv4 addresses.
You can create applications that use AF_INET6 sockets to open TCP connections to IPv4 nodes. To accomplish this task, you can encode the destination's IPv4 address as an IPv4–mapped IPv6 address and pass that address within a sockaddr_in6 structure in the connect() or sendto() call. When applications use AF_INET6 sockets to accept TCP connections from IPv4 nodes, or receive UDP packets from IPv4 nodes, the system returns the peer's address to the application in the accept(), recvfrom(), or getpeername() calls using a sockaddr_in6 structure encoded this way.
While the bind() API allows applications to select the source IP address of UDP packets and TCP connections, applications often want the system to select the source address for them. Applications use in6addr_any similarly to the way they use the INADDR_ANY macro in IPv4 for this purpose. An additional feature of binding in this way is that it allows an AF_INET6 socket to communicate with both IPv4 and IPv6 nodes. For example, an application issuing an accept() on a listening socket bound to in6addr_any accepts connections from either IPv4 or IPv6 nodes. This behavior can be modified through the use of the IPPROTO_IPV6 level socket option IPV6_V6ONLY. Few applications need to know which type of node with which they are interoperating. However, for those applications that do need to know, the IN6_IS_ADDR_V4MAPPED() macro defined in <netinet/in.h> is provided.