tags:

views:

109

answers:

1

I am using getifaddrs() and inet_ntop() to get the ip addresses on the system. When the system is set to IPv6 the address returned is in the shortened version (using :: for zeros). Is there any way to expand that address to a full one?

This is the code I am using:

struct ifaddrs *myaddrs, *ifa;
void *in_addr;
char buf[64];

if(getifaddrs(&myaddrs) != 0)
{
    perror("getifaddrs");
    exit(1);
}

for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
{
    if (ifa->ifa_addr == NULL)
        continue;
    if (!(ifa->ifa_flags & IFF_UP))
        continue;

    switch (ifa->ifa_addr->sa_family)
    {
        case AF_INET:
        {
            struct sockaddr_in *s4 = (struct sockaddr_in *)ifa->ifa_addr;
            in_addr = &s4->sin_addr;
            break;
        }

        case AF_INET6:
        {
            struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)ifa->ifa_addr;
            in_addr = &s6->sin6_addr;
            break;
        }

        default:
            continue;
    }

    if (!inet_ntop(ifa->ifa_addr->sa_family, in_addr, buf, sizeof(buf)))
    {
        printf("%s: inet_ntop failed!\n", ifa->ifa_name);
    }
    else
    {
        printf("IP address: %s\n", buf);
    }
}

freeifaddrs(myaddrs);

Code is greatly appreciated.

EDIT:
Since this is apparently very hard to comprehend I will give you an example:

If I get abcd:12::3 I need to expand it to abcd:0012:0000:0000:0000:0000:0000:0003
The reason? because it's part of the requirements. Simple as that.

+2  A: 
void ipv6_to_str_unexpanded(char * str, const struct in6_addr * addr) {
   sprintf(str, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
                 (int)addr->s6_addr[0], (int)addr->s6_addr[1],
                 (int)addr->s6_addr[2], (int)addr->s6_addr[3],
                 (int)addr->s6_addr[4], (int)addr->s6_addr[5],
                 (int)addr->s6_addr[6], (int)addr->s6_addr[7],
                 (int)addr->s6_addr[8], (int)addr->s6_addr[9],
                 (int)addr->s6_addr[10], (int)addr->s6_addr[11],
                 (int)addr->s6_addr[12], (int)addr->s6_addr[13],
                 (int)addr->s6_addr[14], (int)addr->s6_addr[15]);
}
nategoose
fantastic. the first %02x%02: should be %02x%02x: by the way
Jessica
@Jessica: fixed
nategoose