csocketsnetwork-programming

Tell whether a text string is an IPv6 address or IPv4 address using standard C sockets API


I have a program where an external component passes me a string which contains an IP address. I then need to turn it into a URI. For IPv4 this is easy; I prepend http:// and append /. However, for IPv6 I need to also surround it in brackets [].

Is there a standard sockets API call to determine the address family of the address?


Solution

  • Use getaddrinfo() and set the hint flag AI_NUMERICHOST, family to AF_UNSPEC, upon successfull return from getaddrinfo, the resulting struct addrinfo .ai_family member will be either AF_INET or AF_INET6.

    EDIT, small example

    #include <sys/types.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netdb.h>
    
    int main(int argc, char *argv[])
    {
        struct addrinfo hint, *res = NULL;
        int ret;
    
        memset(&hint, '\0', sizeof hint);
    
        hint.ai_family = PF_UNSPEC;
        hint.ai_flags = AI_NUMERICHOST;
    
        ret = getaddrinfo(argv[1], NULL, &hint, &res);
        if (ret) {
            puts("Invalid address");
            puts(gai_strerror(ret));
            return 1;
        }
        if(res->ai_family == AF_INET) {
            printf("%s is an ipv4 address\n",argv[1]);
        } else if (res->ai_family == AF_INET6) {
            printf("%s is an ipv6 address\n",argv[1]);
        } else {
            printf("%s is an is unknown address format %d\n",argv[1],res->ai_family);
        }
    
       freeaddrinfo(res);
       return 0;
    }
    
    $ ./a.out 127.0.0.1
    127.0.0.1 is an ipv4 address
    $ ./a.out ff01::01
    ff01::01 is an ipv6 address