DEV Community

Fomalhaut Weisszwerg
Fomalhaut Weisszwerg

Posted on

[C/C++] How to get all interface addresses on the local device.

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;
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Discussion (0)