Перечисление каждого IP-адреса, назначенного сетевым интерфейсам. - PullRequest
3 голосов
/ 12 октября 2010

Я думаю, что нет способа перечислить каждый сетевой интерфейс в моей системе и назначенный им IP-адрес, используя только сокеты.Это правильно?

Я имею в виду, что в Linux это может быть:

eth0: 192.168.1.5
wlan0: 192.168.0.5
lo: 127.0.0.1

Меня не волнуют имена интерфейсов, только назначенные IP-адреса.

IНапомним, что раньше это делалось в Windows, используя Win32 (хотя я не помню, как).Но есть ли способ сделать это портативным способом?

Ответы [ 4 ]

10 голосов
/ 12 октября 2010

Вот хорошее начало:

#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;
}
0 голосов
/ 12 октября 2010

Посмотрите на функцию ioctl().Если я правильно помню, вы можете использовать его для получения информации о любом интерфейсе, а также для получения доступных интерфейсов.

Хотя я не помню правильный вызов.Как и в случае fcntl(), он принимает аргумент запроса и переменные параметры, которые определяют его поведение.

0 голосов
/ 12 октября 2010

В Linux эта информация доступна через сокеты NETLINK.См. Справочные страницы для libnetlink (3), netlink (7) и rtnetlink (7).

Несколько более портативный способ сделать это - через ioctl ().SIOCGIFCONF это тот, который вы хотите.Смотрите страницу руководства для netdevice (7).Этот работает на некоторых других * никс.

0 голосов
/ 12 октября 2010

Используйте gethostname(), чтобы получить локальное DNS-имя компьютера, а затем передайте это имя gethostbyname(), чтобы получить его локальные IP-адреса.

Если ОС поддерживает IPv6, посмотрите на функцию getaddrinfo() вместо gethostbyname().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...