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;
}
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;
}
Now, the code became much shorter and easier. Also, there is no need to care to free memory!
Top comments (0)