If you want to retrieve all interfaces addresses, getifaddrs()
might be your friend.
getifaddrs()
creates a linked list of structures that contain information of the network interfaces of the local machine. You can retrieve all interface addresses by using this funciton.
#include <arpa/inet.h>
#include <cerrno>
#include <ifaddrs.h>
#include <iostream>
#include <net/if.h>
#include <string>
#include <string.h>
#include <sysexits.h>
#include <sys/socket.h>
#include <sys/types.h>
int main(void)
{
struct ifaddrs* ptr_ifaddrs = nullptr;
auto result = getifaddrs(&ptr_ifaddrs);
if( result != 0 ){
std::cout << "`getifaddrs()` failed: " << strerror(errno) << std::endl;
return EX_OSERR;
}
for(
struct ifaddrs* ptr_entry = ptr_ifaddrs;
ptr_entry != nullptr;
ptr_entry = ptr_entry->ifa_next
){
std::string ipaddress_human_readable_form;
std::string netmask_human_readable_form;
std::string interface_name = std::string(ptr_entry->ifa_name);
sa_family_t address_family = ptr_entry->ifa_addr->sa_family;
if( address_family == AF_INET ){
// IPv4
// Be aware that the `ifa_addr`, `ifa_netmask` and `ifa_data` fields might contain nullptr.
// Dereferencing nullptr causes "Undefined behavior" problems.
// So it is need to check these fields before dereferencing.
if( ptr_entry->ifa_addr != nullptr ){
char buffer[INET_ADDRSTRLEN] = {0, };
inet_ntop(
address_family,
&((struct sockaddr_in*)(ptr_entry->ifa_addr))->sin_addr,
buffer,
INET_ADDRSTRLEN
);
ipaddress_human_readable_form = std::string(buffer);
}
if( ptr_entry->ifa_netmask != nullptr ){
char buffer[INET_ADDRSTRLEN] = {0, };
inet_ntop(
address_family,
&((struct sockaddr_in*)(ptr_entry->ifa_netmask))->sin_addr,
buffer,
INET_ADDRSTRLEN
);
netmask_human_readable_form = std::string(buffer);
}
std::cout << interface_name << ": IP address = " << ipaddress_human_readable_form << ", netmask = " << netmask_human_readable_form << std::endl;
}
else if( address_family == AF_INET6 ){
// IPv6
uint32_t scope_id = 0;
if( ptr_entry->ifa_addr != nullptr ){
char buffer[INET6_ADDRSTRLEN] = {0, };
inet_ntop(
address_family,
&((struct sockaddr_in6*)(ptr_entry->ifa_addr))->sin6_addr,
buffer,
INET6_ADDRSTRLEN
);
ipaddress_human_readable_form = std::string(buffer);
scope_id = ((struct sockaddr_in6*)(ptr_entry->ifa_addr))->sin6_scope_id;
}
if( ptr_entry->ifa_netmask != nullptr ){
char buffer[INET6_ADDRSTRLEN] = {0, };
inet_ntop(
address_family,
&((struct sockaddr_in6*)(ptr_entry->ifa_netmask))->sin6_addr,
buffer,
INET6_ADDRSTRLEN
);
netmask_human_readable_form = std::string(buffer);
}
std::cout << interface_name << ": IP address = " << ipaddress_human_readable_form << ", netmask = " << netmask_human_readable_form << ", Scope-ID = " << scope_id << std::endl;
}
else {
// AF_UNIX, AF_UNSPEC, AF_PACKET etc.
// If ignored, delete this section.
}
}
freeifaddrs(ptr_ifaddrs);
return EX_OK;
}
Result of my laptop:
$ g++ -std=c++20 -Wall -g test_niclist.cpp -o niclist
$ ./niclist
lo: IP address = 127.0.0.1, netmask = 255.0.0.0
wlp1s0: IP address = 192.168.1.131, netmask = 255.255.255.0
lo: IP address = ::1, netmask = ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff, Scope-ID = 0
wlp1s0: IP address = fe80::9197:ad52:928a:6a76, netmask = ffff:ffff:ffff:ffff::, Scope-ID = 2
Top comments (0)