[C/C++] How to get scope_id of IPv6 Link local Address on Linux.

fmtweisszwerg

Fomalhaut Weisszwerg

Posted on November 8, 2021

[C/C++] How to get scope_id of IPv6 Link local Address on Linux.

A well-known way is to use getaddrinfo() such like:

#include <arpa/inet.h>
#include <cerrno>
#include <cstring>
#include <iostream>
#include <netdb.h>
#include <string>
#include <sys/socket.h>
#include <sysexits.h>

int main(void)
{
    struct addrinfo hints;
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_INET6;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_protocol = IPPROTO_UDP;

    struct addrinfo* result_addrinfo = nullptr;
    auto result = getaddrinfo("fe80::dabb:c1ff:fe0a:17f2%enp39s0", std::to_string(12345).c_str(), &hints, &result_addrinfo);
    if( result != 0 ){
        std::cout << "`getaddrinfo()` failed: " << gai_strerror(errno) << std::endl;
        return result;
    }

    for(
        struct addrinfo* info = result_addrinfo;
        info != nullptr;
        info = info->ai_next
    ){
        char ipv6addr_human_readable_form[INET6_ADDRSTRLEN] = {0, };
        inet_ntop(info->ai_family, &((struct sockaddr_in6*)(info->ai_addr))->sin6_addr, ipv6addr_human_readable_form, info->ai_addrlen);
        auto ipv6_scope_id = ((struct sockaddr_in6*)(info->ai_addr))->sin6_scope_id;

        std::cout << "IPv6 address = " << ipv6addr_human_readable_form << std::endl;
        std::cout << "Scope-ID = " << std::to_string(ipv6_scope_id) << std::endl;
    }

    freeaddrinfo(result_addrinfo);
    return EX_OK;
}
Enter fullscreen mode Exit fullscreen mode

Of course, the Scope-ID can also be obtained as previously. But is there an easier and shorter?

Solution using if_nametoindex()

Fortunately, Linux provides a function called if_nametoindex(). It returns the index number of the network interface, which is currently equal to the Scope-ID.

#include <net/if.h>
#include <iostream>
#include <sysexits.h>

int main(void)
{
    auto scope_id = if_nametoindex("enp39s0");
    std::cout << scope_id << std::endl;

    return EX_OK;
}
Enter fullscreen mode Exit fullscreen mode

Now, the code became much shorter and easier. Also, there is no need to care to free memory!

💖 💪 🙅 🚩
fmtweisszwerg
Fomalhaut Weisszwerg

Posted on November 8, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related