DEV Community

Fomalhaut Weisszwerg
Fomalhaut Weisszwerg

Posted on

13 1

[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

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay