Linux getting all network interface names

前端 未结 6 1918
傲寒
傲寒 2020-12-01 08:30

I need to collect all the interface names, even the ones that aren\'t up at the moment. Like ifconfig -a.

getifaddrs() is iterating through

相关标签:
6条回答
  • 2020-12-01 08:53

    You could check which entries from getifaddrs belong to the AF_PACKET family. On my system that seems to list all interfaces:

    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);
    
    0 讨论(0)
  • 2020-12-01 08:54

    It seems that ifconfig -a only lists active interfaces (at least on Fedora 19). I know I have at least one more network card that I'm not seeing. Anyway, I get the same list as:

    ls -1 /sys/class/net
    

    Which could easily be done programatically.

    0 讨论(0)
  • 2020-12-01 08:56

    I thing this show you all interface, at least for me

    ip link show

    ls -1 /sys/class/net
    

    only show interface name

    lo
    p4p1
    
    0 讨论(0)
  • 2020-12-01 08:57

    You are on the right track (it is getifaddrs). It returns each interface once per family, so you get eth0 for ipv4 and one for ipv6. If you just want each interface once you will have to uniq the output yourself.

    0 讨论(0)
  • 2020-12-01 09:05

    I need the main device that is being used by the system (assuming there is only one) such as eth0 wlan0 or whatever RHEL7 is trying to do...

    The best I hacked together was this:

    #!/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
    

    Sample output:

        ./maineth.sh  
        Device: enp0s25 IP: 192.168.1.6
    
    0 讨论(0)
  • 2020-12-01 09:12

    getifaddrs() will only return your interfaces addresses, not the interfaces themselves.

    What if any of your interface has no address, or no address of the requested family, as suggested with the 'AF_PACKET' one ?

    Here, an example where I’ve got a tunnel interface (with an OpenVPN connexion), and where I’m listing all entries from getifaddrs() for each of my network interfaces:

    [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. No AF_PACKET on the "tun0" interface, but it DOES exist on the system.

    You should, instead, use if_nameindex() syscall, which does exactly what you want. In other words, with no arguments, it returns a list of all interfaces on your system:

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

    And voilà.

    0 讨论(0)
提交回复
热议问题