18

我需要收集所有的接口名称,即使是那些目前还没有启动的接口名称。喜欢ifconfig -a

getifaddrs()多次迭代相同的接口名称。如何使用一次就收集所有接口名称getifaddrs()

4

7 回答 7

27

您可以检查来自 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);
于 2013-10-07T15:00:47.213 回答
22

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() 系统调用,这正是您想要的。换句话说,没有参数,它返回系统上所有接口的列表:

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

int 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 0;
}

瞧。

于 2017-08-21T11:56:15.650 回答
6

似乎ifconfig -a只列出了活动接口(至少在 Fedora 19 上)。我知道我至少还有一张我没有看到的网卡。无论如何,我得到与以下相同的列表:

ls -1 /sys/class/net

这可以很容易地以编程方式完成。

于 2013-10-07T15:46:10.650 回答
2

您走在正确的轨道上(它是 getifaddrs)。它为每个系列返回每个接口一次,因此您将获得 eth0 用于 ipv4 和一个用于 ipv6。如果您只需要每个接口,则必须自己对输出进行 uniq。

于 2013-10-07T14:50:55.863 回答
2

我认为这会向您展示所有界面,至少对我而言

ip链接显示

ls -1 /sys/class/net

只显示接口名称

lo
p4p1
于 2013-10-08T07:17:07.223 回答
1

我需要系统正在使用的主设备(假设只有一个),例如 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
于 2016-02-16T21:26:32.747 回答
0

使用这个。为了便于理解,我添加了适当的注释。

void extract_network_interface_names()
{
    /* DEFINITION
     *  #include <net/if.h>
     *  struct if_nameindex * if_nameindex() :  function that returns a pointer.
     *  The if_nameindex()  function returns an array of if_nameindex structs. There is one struct for each network interface
     *  The if_nameindex struct contains at least the following members:
     *      unsigned int if_index : which is the index of each network interface {1,2,..n}
     *      char * if_name : which is the name of the interface=the C style string= an array of characters terminated in the NULL character \0
     *
     *  The end of the array of struct is indicated by an entry with if_index=0 && if_name=NULL
     *  The if_nameindex() function returns an array of structs if successful, or NULL if some error occurred or not enough memory is available
     */
    puts("Extracting network interface names...");
    puts("Listing all available network interface names on this machine...");
    puts("********************************");

    int counter_network_interfaces=0;

    struct if_nameindex * interface_indexes;
    struct if_nameindex * interface;

    interface_indexes=if_nameindex();

    if(interface_indexes==NULL) //Some error occurred during the execution of if_nameindex() function or there is no enough memory available
    {
        perror("If_nameindex");
        printf("Ooops...error while extracting the network interface names.\n");
        exit(EXIT_FAILURE);
    }

    //Loop through the elements of the array of if_nameindex structs

    for(interface=interface_indexes;interface->if_index!=0 && interface->if_name!=NULL;interface++)
        {
            counter_network_interfaces++;
            printf("There exists a network interface called \"%s\" with index %d. \n",interface->if_name, interface->if_index);
        }

        puts("*******************************");
        printf("In total, there is a number of %d network interfaces on this machine.\n",counter_network_interfaces);


}
于 2021-06-10T11:48:38.160 回答