1
votes

I'm working on migrating some code from IPv4 only to IPv6, and of course I need to retain backwards compatibility for IPv4.

I have read through some documents and guides for converting my code, and have seen it written that using many of the newer APIs (like inet_pton() instead of inet_addr()) will just work in both IPv4 and IPv6.

However, in some cases it still isn't clear when I need to write code to handle each protocol in a different way. Specifically, I don't know whether a IPv6 address (family AF_INET6 using sockaddr_storage structure) will work on a local network.

So for example, let's say I create such an address using the built in constant in6addr_loopback, and then I try to use that for a parameter to a bind() call.

Will this work in both IPv4 and IPv6, or I need to create the right address type (AF_INET vs AF_INET6) for each case? Does it matter whether I am connecting to a local socket (i.e. the loopback as in this case) as opposed to a socket on an external device?

My client code is running on iPhone/iPad hardware in case it matters.

1

1 Answers

2
votes

Every interface will derive a link local ipv6 address using mac address. This address is sufficient for communication within local network. Regarding creation of socket, you need to specify the family (AF_INET and AF_INET6) and initialize and bind it.

IPv4:

     struct sockaddr_in serv_addr, cli_addr;
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);

     if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)

IPv6:

     struct sockaddr_in6 serv_addr, cli_addr;
     sockfd = socket(AF_INET6, SOCK_STREAM, 0);
     serv_addr.sin6_family = AF_INET6;
     serv_addr.sin6_addr = in6addr_any;
     serv_addr.sin6_port = htons(portno);

     if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)

hope this helps!