LINUX.ORG.RU

Как определить текущие ip-адреса, назначенные сетевым интерфейсам?

 ,


0

4

Посоветуйте какой-нибудь простой, но желательно не костыльный способ. Думал, что где-нибудь в /proc что-то должно быть. Нашел таблицу маршрутизации. Но это не совсем то. Может плохо искал? Ну понятно, что через netlink можно. Но исходники iproute2 что-то тяжело ковыряются. Скажем, как получать через netlink события, связанные с изменением сетевых параметров понятно (мониторинг). Но не могу пока понять, как запросить текущее состояние.

Ответ на: комментарий от vvn_black

Да, вызывать ifconfig, или ip и парсить вывод как-то неспортивно в данном конкретном случае. Прога пишется на Си, и уже через netlink мониторятся изменения сетевых интерфейсов.

zloy_starper ★★★ ()
Ответ на: комментарий от monk

«Семен Семныч ...» Когда прочел man, то возникло впечатление, что раньше я этой функцией пользовался, и может быть даже и спрашивал так же, как сейчас прямо тут. Или это уже дежавю. Правда я уже фактически получил аналогичный результат через netlink. Но там описание всяких типов такое скудное, что нет уверенности, что делаю все правильно. Интересно было бы глянуть, что там у getifaddrs во внутренностях. Она в libc что-ли живет?

zloy_starper ★★★ ()
Ответ на: комментарий от zloy_starper

Интересно было бы глянуть, что там у getifaddrs во внутренностях.

Там что-то вроде

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>

int fd;

int get_iface_list(struct ifconf *ifconf)
{
    int rval;
    if((rval = ioctl(fd, SIOCGIFCONF , (char*) ifconf  )) < 0 )
        perror("ioctl(SIOGIFCONF)");

    return rval;
}

int main()
{
    static struct ifreq ifreqs[100];
    static struct ifconf ifc;
    char *ptr;

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0)
        return 1;

    ifc.ifc_buf = (char*) (ifreqs);
    ifc.ifc_len = sizeof(ifreqs);

    if(get_iface_list(&ifc) < 0) return -1;

    /* Go through the list of interfaces */
    for (ptr = ifc.ifc_buf; ptr < ifc.ifc_buf + ifc.ifc_len;)
    {
        struct ifreq *ifr = (struct ifreq*)ptr;
        int len = (sizeof(struct sockaddr) > ifr->ifr_addr.sa_len) ?
                sizeof(struct sockaddr) : ifr->ifr_addr.sa_len;

        ptr += sizeof(ifr->ifr_name) + len;

            /* Do what you need with the ifr-structure.
             * ifr->ifr_addr contains either sockaddr_dl,
             * sockaddr_in or sockaddr_in6 depending on
             * what addresses and L2 protocols the interface
             * has associated in it.
             */
    }

    close(fd);
    return 0;
}
monk ★★★★★ ()

Вообще в OpenVPN-install, скрипте для поднятия VPN, была регулярка для распаршивания выхлопа то ли ip, то ли ipconfig. Суть в том, что это работало.

Deleted ()
Ответ на: комментарий от monk

Это все устаревшие варианты. Работа через ioctl уже признана не отвечающей современным реалиям. Отчего так - не спрашивайте, не я это придумал. Собственно поэтому появился iproute2. Там все делается через netlink socket. А это как говорится две большие разницы. Там все гораздо кучерявее, прежде всего потому, что вменяемой документации пока что не шибко много. Ну я, по крайней мере, пока не встретил. Что-то описано, а что-то, похоже, только ковырянием ядра можно разобрать.

Ну вот вам getifaddrs: https://code.woboq.org/userspace/glibc/sysdeps/unix/sysv/linux/ifaddrs.c.html

zloy_starper ★★★ ()