How to detect global vs. link local IPv6 address

Viewed 566

I am obtaining the address via the following code:

pcap_addr_t* addrs_ptr = device->addresses;
std::vector<std::string> deviceAddresses;

// Collect the device addresses into a string vector
while(addrs_ptr != nullptr)
{
    if(addrs_ptr->addr->sa_family == AF_INET) // IPv4
    {
        char address_string4[INET_ADDRSTRLEN];
        struct sockaddr_in *sa_in = (struct sockaddr_in*)addrs_ptr->addr;

        struct in_addr i_a = sa_in->sin_addr;
        inet_ntop(AF_INET, &(i_a), address_string4, INET_ADDRSTRLEN);
        deviceAddresses.push_back(address_string4);
    }
    else if(addrs_ptr->addr->sa_family == AF_INET6) // IPv6
    {
        char address_string6[INET6_ADDRSTRLEN];
        struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6*)addrs_ptr->addr;
        struct in6_addr i_a = sa_in6->sin6_addr;
        sa_in6->sin6_flowinfo
        inet_ntop(AF_INET6, &(i_a), address_string6, INET6_ADDRSTRLEN);
        deviceAddresses.push_back(address_string6);
    }
    addrs_ptr = addrs_ptr->next;
}

For IPv6 I obtain two addresses, one global and one link-local. How do I differentiate between the two in the code?

2 Answers

You may categorise IPv6 addresses by using the IN6_IS_ADDR_* set of macros. In your case, you want IN6_IS_ADDR_LINKLOCAL:

#include <netinet/in.h>
...
struct in6_addr i_a = sa_in6->sin6_addr;
if(IN6_IS_ADDR_LINKLOCAL(&i_a)) {
    addrs_ptr = addrs_ptr->next;
    continue;
}
...

The link local address starts with the bytes 'fe80'.

Related