1

I am able to get the IPv4 address of a given interface with following code

int fd;
char ipv4[33];
char ifname[] = "eth0";
struct ifreq ifr;

fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
ioctl(fd, SIOCGIFADDR, &ifr);
close(fd);

snprintf(ipv4, 33, "%s", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));

What is the easiest way to get the IPv6 address of a given interface, using C ?

*** I AM POSTING THE CODE WHICH I COULD USE TO MAKE IT BELOW ..

int8_t find_device_ipv6(const char *ifname, char *ipv6, int8_t ipv6_size)
{
    FILE *f;
    int ret, scope, prefix;
    unsigned char _ipv6[16];
    char dname[IFNAMSIZ];
    char address[INET6_ADDRSTRLEN];
    char *scopestr;

    f = fopen("/proc/net/if_inet6", "r");
    if (f == NULL) {
        return -1;
    }
    while (19 == fscanf(f,
                        " %2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx %*x %x %x %*x %s",
                        &_ipv6[0],
                        &_ipv6[1],
                        &_ipv6[2],
                        &_ipv6[3],
                        &_ipv6[4],
                        &_ipv6[5],
                        &_ipv6[6],
                        &_ipv6[7],
                        &_ipv6[8],
                        &_ipv6[9],
                        &_ipv6[10],
                        &_ipv6[11],
                        &_ipv6[12],
                        &_ipv6[13],
                        &_ipv6[14],
                        &_ipv6[15],
                        &prefix,
                        &scope,
                        dname)) {
        if (strcmp(ifname, dname) != 0) {
            continue;
        }
        if (inet_ntop(AF_INET6, _ipv6, address, sizeof(address)) == NULL) {
            continue;
        }
        snprintf(ipv6, ipv6_size, "%s", address);
    }
    fclose(f);

    return 0;
}
Muneer
  • 7,384
  • 7
  • 38
  • 62
  • This is operating system specific. Sockets or network interfaces do not exist in standard C. You probably want to add a `Posix` or `Linux` tag – Basile Starynkevitch Feb 23 '16 at 10:16
  • It is on OpenWRT platform, based on Linux. – Muneer Feb 23 '16 at 10:18
  • 4
    Maybe a duplicate of http://stackoverflow.com/questions/20743709/get-ipv6-addresses-in-linux-using-ioctl – Frankie_C Feb 23 '16 at 10:19
  • Do you really need the v6-address(es) of a specific interface or will the primary address of the system do? (e.g. the address, which is used for outgoing connections) – Ctx Feb 23 '16 at 10:49

2 Answers2

1

I assume your OS is Linux.

To find out how it is done, try strace ifconfig eth0.

You see that it is using /proc/net/if_inet6 and some ioctl, notably SIOCGIFADDR

As Ctx commented, you probably want getifaddrs(3)

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 1
    The problem with strace is, that the solution is often quite low-level (since it shows only the calls through the kernel interface), where a cleaner (and more version-stable) might exist in userland. In this case for example `getifaddrs()` should be preferred whenever possible. – Ctx Feb 23 '16 at 10:32
  • I can see it is getting through that proc file. The value in proc file is `fe80000000000000228984fffea6c63d` while my ip6 is `fe80::2289:84ff:fea6:c63d`. Do you know how to convert it? – Muneer Feb 23 '16 at 10:54
  • I could do it with your idea. Thanks. I will post the code. – Muneer Feb 23 '16 at 11:14
1

The easiest way is definitely using getifaddrs(), in case your glibc supports it.

If it doesn't you better don't want to know.....

tofro
  • 5,640
  • 14
  • 31