Linux obteniendo todos los nombres de interfaz de red

5 minutos de lectura

avatar de usuario
tez

Necesito recopilar todos los nombres de las interfaces, incluso las que no están activas en este momento. Me gusta ifconfig -a.

getifaddrs() está iterando a través del mismo nombre de interfaz varias veces. ¿Cómo puedo recopilar todos los nombres de interfaz solo una vez usando getifaddrs()?

  • ¿Agregar a una tabla y eliminar duplicados?

    – Un tipo programador

    7 oct 2013 a las 14:45

  • Gracias Joachim, pero ¿no hay otra manera sin un procesamiento adicional?

    – tez

    7 oct 2013 a las 14:49

Puede verificar qué entradas de getifaddrs pertenecen a la familia AF_PACKET. En mi sistema que parece enumerar todas las 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);

avatar de usuario
Hugues

getifaddrs() solo devolverá las direcciones de sus interfaces, no las interfaces en sí.

¿Qué sucede si alguna de sus interfaces no tiene dirección, o no tiene dirección de la familia solicitada, como se sugiere con el ‘AF_PACKET’?

Aquí, un ejemplo en el que tengo una interfaz de túnel (con una conexión OpenVPN), y en el que estoy enumerando todas las entradas de getifaddrs() para cada una de mis interfaces de red:

[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 hay AF_PACKET en la interfaz “tun0”, pero SÍ existe en el sistema.

En su lugar, debe usar if_nameindex() syscall, que hace exactamente lo que desea. En otras palabras, sin argumentos, devuelve una lista de todas las interfaces de su sistema:

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

Y voilá.

  • Su código de ejemplo está perdiendo la memoria. Según la documentación (if_nameindex) La función if_nameindex() asigna dinámicamente la memoria que luego debería liberarse llamando a if_freenameindex().

    – ha podido recuperar

    30/09/2017 a las 13:35


  • ¡Gracias por el lugar! Actualicé mi código de muestra en consecuencia.

    – Hugues

    6 de junio de 2019 a las 8:57

  • Hola void main (void) es impropio Deberías usar int main() o int main(void) También main debería devolver un valor.

    – f3xy

    3 abr 2020 a las 17:02


  • Acabo de actualizar y revisé el gcc -Wall no produce más errores. Gracias 😉

    – Hugues

    15 de abril de 2020 a las 8:23

avatar de usuario
ldav1s

Parece que ifconfig -a solo enumera las interfaces activas (al menos en Fedora 19). Sé que tengo al menos una tarjeta de red más que no veo. De todos modos, obtengo la misma lista que:

ls -1 /sys/class/net

Lo cual podría hacerse fácilmente programáticamente.

Creo que esto te muestra toda la interfaz, al menos para mí.

mostrar enlace ip

ls -1 /sys/class/net

solo muestra el nombre de la interfaz

lo
p4p1

Necesito el dispositivo principal que está utilizando el sistema (suponiendo que solo haya uno), como eth0 wlan0 o lo que RHEL7 esté tratando de hacer…

Lo mejor que hackeé juntos fue esto:

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

Salida de muestra:

    ./maineth.sh  
    Device: enp0s25 IP: 192.168.1.6

avatar de usuario
Jorge

Usa este. Agregué los comentarios apropiados para facilitar la comprensión.

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);


}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad