Linux получает все имена сетевых интерфейсов

Мне нужно собрать все имена интерфейсов, даже те, которые на данный момент отсутствуют. Как ifconfig -a.

getifaddrs() повторяется через одно и то же имя интерфейса несколько раз. Как я могу собрать все имена интерфейсов только один раз, используя getifaddrs()?

Ответ 1

Вы можете проверить, какие записи из getifaddr принадлежат семейству AF_PACKET. В моей системе, которая, как представляется, перечисляет все интерфейсы:

struct ifaddrs *addrs,*tmp;

getifaddrs(&addrs);
tmp = addrs;

while (tmp)
{
    if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_PACKET)
        printf("%s\n", tmp->ifa_name);

    tmp = tmp->ifa_next;
}

freeifaddrs(addrs);

Ответ 2

getifaddrs() будет возвращать только адреса интерфейсов, а не сами интерфейсы.

Что если какой-либо из ваших интерфейсов не имеет адреса или адреса запрошенного семейства, как предложено для адреса AF_PACKET?

Вот пример, где у меня есть туннельный интерфейс (с подключением OpenVPN), и где я перечисляю все записи из getifaddrs() для каждого из моих сетевых интерфейсов:

[0] 1: lo                address family: 17 (AF_PACKET) b4:11:00:00:00:01
                         address family: 2 (AF_INET)    address: <127.0.0.1>
                         address family: 10 (AF_INET6)  address: <::1>
[...]

[5] 10: tun0             address family: 2 (AF_INET)    address: <172.16.0.14>
[EOF]

Bam. Нет AF_PACKET на интерфейсе "tun0", но он существует в системе.

Вместо этого вы должны использовать системный вызов if_nameindex(), который делает именно то, что вы хотите. Другими словами, без аргументов, он возвращает список всех интерфейсов в вашей системе:

#include <net/if.h>
#include <stdio.h>

void main (void)
{
    struct if_nameindex *if_nidxs, *intf;

    if_nidxs = if_nameindex();
    if ( if_nidxs != NULL )
    {
        for (intf = if_nidxs; intf->if_index != 0 || intf->if_name != NULL; intf++)
        {
            printf("%s\n", intf->if_name);
        }

        if_freenameindex(if_nidxs);
    }

    return ;
}

И вуаля.

Ответ 3

Кажется, что ifconfig -a содержит только активные интерфейсы (по крайней мере, на Fedora 19). Я знаю, что у меня есть хотя бы еще одна сетевая карта, которую я не вижу. Во всяком случае, я получаю тот же список, что и:

ls -1 /sys/class/net

Это может быть легко реализовано программно.

Ответ 4

Вы на правильном пути (это getifaddrs). Он возвращает каждый интерфейс один раз в каждой семье, поэтому вы получаете eth0 для ipv4 и один для ipv6. Если вам просто нужен каждый интерфейс, когда вам нужно будет самостоятельно выполнить вывод.

Ответ 5

Мне кажется, это показывает вам весь интерфейс, по крайней мере для меня

ip link show

ls -1 /sys/class/net

отображать только имя интерфейса

lo
p4p1

Ответ 6

Мне нужно основное устройство, которое используется системой (при условии, что существует только одна), например eth0 wlan0 или что-то, что RHEL7 пытается сделать...

Лучшее, что я взломал, было следующим:

#!/bin/bash
# -- Get me the interface for the main ip on system

for each in $(ls -1 /sys/class/net) ;do 

    result=$(ip addr show $each | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}' | grep "$(hostname -I | cut -d' ' -f1)")

    if [ ! -z "${result// }" ] && [ -d /sys/class/net/${each// } ] ;then
            echo "Device: $each IP: $result"
            break;
    fi

done

Пример вывода:

    ./maineth.sh  
    Device: enp0s25 IP: 192.168.1.6