web-dev-qa-db-ja.com

Linuxがすべてのネットワークインターフェース名を取得

現在稼働していないものも含め、すべてのインターフェース名を収集する必要があります。 _ifconfig -a_のように。

getifaddrs()は、同じインターフェイス名を複数回反復しています。 getifaddrs()を使用してすべてのインターフェイス名を一度だけ収集するにはどうすればよいですか?

13
tez

Getifaddrsのどのエントリが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);
22
brm

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]

バム。 「tun0」インターフェースにはAF_PACKETはありませんが、システムには存在します。

代わりに、if_nameindex()syscallを使用する必要があります。つまり、引数なしで、システム上のすべてのインターフェースのリストを返します。

#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 ;
}

そして、ほら。

13
Hugues

のようだ ifconfig -aはアクティブなインターフェースのみをリストします(少なくともFedora 19では)。表示されていないネットワークカードが少なくとも1つあることはわかっています。とにかく、私は同じリストを取得します:

ls -1 /sys/class/net

これはプログラムで簡単に実行できます。

5
ldav1s

あなたは正しい軌道に乗っています(getifaddrsです)。ファミリごとに1回各インターフェイスを返すため、ipv4にはeth0、ipv6には1つのeth0を取得します。各インターフェースが必要な場合は、出力を自分で一意にする必要があります。

2
aet

これは、少なくとも私にとっては、すべてのインターフェースを示しています

iPリンクショー

ls -1 /sys/class/net

インターフェース名のみを表示

lo
p4p1
2
Makaro

Eth0 wlan0やRHEL7が実行しようとしているものなど、システムで使用されているメインデバイス(1つしかない場合)が必要です...

私が一緒にハッキングした最高のものはこれでした:

#!/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
1
Mike Q