0

I want to know the proper way to determine which sockaddr variant to use.

From Beej's Guide to Network Programming:

if (p->ai_family == AF_INET) { // IPv4
    struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
    addr = &(ipv4->sin_addr);
    ipver = "IPv4";
} else { // IPv6
    struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
    addr = &(ipv6->sin6_addr);
    ipver = "IPv6";
}

Here he is checking if the address family is AF_INET and using sockaddr_in if it is. If it isn't he is using sockaddr_in6. Isn't that unsafe? What if it was some other address family that is not IPv6?

Is there a sanctioned, standard way of determining which structure maps to the corresponding address family?

Tim Mattison
  • 152
  • 10

1 Answers1

0

Well to be safe, you could use an else if for AF_INET6 and a final else to fail with unsupported address family. I would avoid attempting to have support for other families unless you have actual requirements to support them. Following YAGNI, it's unwise to code to a spec if you have no plans to support or test it.

if (p->ai_family == AF_INET) { // IPv4
    struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
    addr = &(ipv4->sin_addr);
    ipver = "IPv4";
} else if (p->ai_family == AF_INET6) { // IPv6
    struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
    addr = &(ipv6->sin6_addr);
    ipver = "IPv6";
} else {
    // UNSUPPORTED! FAIL! FAIL!
}
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • In my case I need to pass through calls even with unfamiliar address families. In those cases I would just ignore the data and copy it as a void pointer. Why it isn't a void pointer in the first place confuses me but I guess it is just legacy code. – Tim Mattison Apr 10 '14 at 15:34
  • Also, I would recommend using `sockaddr_storage`. [Here's](http://stackoverflow.com/questions/8835322/api-using-sockaddr-storage) why – Sanketh Apr 10 '14 at 21:23