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 (1)
Is there any similar function, that can return ip or structure with ip of interface with specific name?