Enumerating each IP address assigned to network in

2019-02-11 00:35发布

I think there is no way to enumerate each network interface on my system and their assigned IP address using just sockets. Is this correct?

I mean, in Linux this could be:

eth0: 192.168.1.5
wlan0: 192.168.0.5
lo: 127.0.0.1

I don't care about interface names, just the IP addresses assigned.

I recall to have done this in the past in Windows, using Win32 (though I don't remember how). But is there a method to do this in a portable way?

4条回答
劫难
2楼-- · 2019-02-11 01:00

Take a look at the ioctl() function. If I recall correctly, you can use it to obtain information on any interface, as well as obtaining the available interfaces.

I don't remember the correct invocation though. As with fcntl(), it takes a request argument plus variable parameters that determine its behaviour.

查看更多
Animai°情兽
3楼-- · 2019-02-11 01:04

On Linux, that information is accessed through NETLINK sockets. See the manual pages for libnetlink(3), netlink(7) and rtnetlink(7).

A somewhat more portable way of doing this is via ioctl()'s. SIOCGIFCONF is the one you want. See the manual page for netdevice(7). This one works on some other *nixes.

查看更多
Lonely孤独者°
4楼-- · 2019-02-11 01:08

Here's a good start:

#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <stdio.h>
void
print_sockaddr(struct sockaddr* addr,const char *name)
{
    char addrbuf[128] ;

    addrbuf[0] = 0;
    if(addr->sa_family == AF_UNSPEC)
        return;
    switch(addr->sa_family) {
        case AF_INET:
            inet_ntop(addr->sa_family,&((struct sockaddr_in*)addr)->sin_addr,addrbuf,sizeof(addrbuf));
            break;
        case AF_INET6:
            inet_ntop(addr->sa_family,&((struct sockaddr_in6*)addr)->sin6_addr,addrbuf,sizeof(addrbuf));
            break;
        default:
            sprintf(addrbuf,"Unknown (%d)",(int)addr->sa_family);
            break;

    }
    printf("%-16s %s\n",name,addrbuf);
}

void
print_ifaddr(struct ifaddrs *addr)
{
    char addrbuf[128] ;

    addrbuf[0] = 0;
    printf("%-16s %s\n","Name",addr->ifa_name);
    if(addr->ifa_addr != NULL)
        print_sockaddr(addr->ifa_addr,"Address");
    if(addr->ifa_netmask != NULL)
        print_sockaddr(addr->ifa_netmask,"Netmask");
    if(addr->ifa_broadaddr != NULL)
        print_sockaddr(addr->ifa_broadaddr,"Broadcast addr.");
    if(addr->ifa_dstaddr != NULL)
        print_sockaddr(addr->ifa_dstaddr,"Peer addr.");
    puts("");
}

int main(int argc,char *argv[])
{
    struct ifaddrs *addrs,*tmp;

    if(getifaddrs(&addrs) != 0) {
        perror("getifaddrs");
        return 1;
    }
    for(tmp = addrs; tmp ; tmp = tmp->ifa_next) {
        print_ifaddr(tmp);
    }

    freeifaddrs(addrs);

    return 0;
}
查看更多
Explosion°爆炸
5楼-- · 2019-02-11 01:08

Use gethostname() to retreive the machine's local DNS name, and then pass that name to gethostbyname() to get its local IP addresses.

If the OS supports IPv6, then look at the getaddrinfo() function instead of gethostbyname().

查看更多
登录 后发表回答