¿Cómo obtener estadísticas del adaptador de red en linux/Mac OSX?

4 minutos de lectura

Estoy buscando una manera de obtener estadísticas de red en C en Linux y MacOSX. Específicamente, necesito monitorear la cantidad de bytes cargados y descargados de cada adaptador de red en el sistema; no necesito hacer una inspección de paquetes o diferenciar entre protocolos, solo un contador de “bytes totales” que puedo sondear a intervalos. estar bien. En Windows, puedo hacer esto usando la biblioteca iphlpapi.dll a través de GetIfTable (para enumerar los adaptadores de red) y GetIfEntry (para leer las estadísticas), pero no puedo encontrar los equivalentes de Linux/OSX. Mi conocimiento de C es bastante básico, por lo que agradecería una solución que no sea demasiado complicada. ¡Cualquier ayuda sería muy apreciada!

  • Por lo que he encontrado hasta ahora, no podrá usar código común en ambas plataformas. Parece que Linux usa el sistema de archivos para retener esta información, y el método normal de consultar los sistemas es leer los archivos. En OSX, la información se guarda en la memoria y en archivos oscuros.

    – Armando

    28 de junio de 2013 a las 16:27

El código fuente de Darwin netstat utiliza sysctl. Aquí hay un código que imprime la cantidad de bytes que entran y salen en OSX:

#import <Foundation/Foundation.h>
#include <sys/sysctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/route.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int mib[] = {
        CTL_NET,
        PF_ROUTE,
        0,
        0,
        NET_RT_IFLIST2,
        0
    };
    size_t len;
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        fprintf(stderr, "sysctl: %s\n", strerror(errno));
        exit(1);
    }
    char *buf = (char *)malloc(len);
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        fprintf(stderr, "sysctl: %s\n", strerror(errno));
        exit(1);
    }
    char *lim = buf + len;
    char *next = NULL;
    u_int64_t totalibytes = 0;
    u_int64_t totalobytes = 0;
    for (next = buf; next < lim; ) {
        struct if_msghdr *ifm = (struct if_msghdr *)next;
        next += ifm->ifm_msglen;
        if (ifm->ifm_type == RTM_IFINFO2) {
            struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm;
            totalibytes += if2m->ifm_data.ifi_ibytes;
            totalobytes += if2m->ifm_data.ifi_obytes;
        }
    }
    printf("total ibytes %qu\tobytes %qu\n", totalibytes, totalobytes);
    [pool drain];
    return 0;
}

  • Esto funciona bien en el simulador. pero da error en el dispositivo. el error es- /Users/praveendala/Desktop/all in one3/app2/app2/main.m:13:10: error fatal: no se encontró el archivo ‘net/route.h’.

    – virata

    20 de diciembre de 2012 a las 7:07


  • Sé que esto es para OSX. pero necesito ejecutar en dispositivos iOS. ¿Alguna idea?

    – virata

    20 de diciembre de 2012 a las 7:13

  • Bien hecho. Me gusta que también proporcione una solución Objective-C.

    – Armando

    28 de junio de 2013 a las 16:28

  • ¿Cómo puedo hacer esto con bash?

    – noɥʇʎ ʎzɐɹƆ

    13 de junio de 2017 a las 19:42

  • ¡Gracias por este ejemplo! Lo convertí a C++ cambiando el NSAutoreleasePool a un std::vector para el búfer.

    – Hal Canarias

    31 de marzo de 2021 a las 14:40

avatar de usuario
Pato

No puedo hablar con OSX, pero en Linux echa un vistazo a /proc/net/dev.

Si hace ‘cat /proc/net/dev’, debería ver estadísticas que incluyen ‘bytes’: el número total de bytes de datos transmitidos o recibidos por la interfaz. Puede leer el archivo dentro de su propio programa.

EDITAR:

No leí toda tu pregunta. Este artículo debería ayudarlo a comenzar con /proc y tiene una sección sobre /proc/net/dev.

Además, para enumerar las interfaces a las que puede llamar ioctl con el SIOCGIFCONF opción. Puede buscar en Google un ejemplo de código decente sobre cómo recorrer los datos devueltos. O simplemente puede extraerlo de los datos de /proc.net/dev mencionados anteriormente, lo que debería ser más fácil.

  • O, según la respuesta de Javier, mire los archivos debajo /sys/class/net/{your network interface}/statisticsdonde {your network interface} es el nombre de la interfaz de red que desea ver, por ejemplo eth0 para la primera interfaz Ethernet. sysfs (en /sys) es más reciente que procfs (en /proc).

    usuario862787

    21 de mayo de 2012 a las 17:28

avatar de usuario
Javier

en Linux:

  • nivel bajo: comprobar /sys/class/net/eth0/statistics/
  • nivel ligeramente superior: ip -s link show eth0
  • gráfico: si arriba
  • interactivo: iptraf

  • El título de la pregunta es OSX. Los dos primeros no funcionan en OSX. Los dos últimos tampoco son adecuados para cuestionar, ya que son gráficos e interactivos.

    – Purrell

    23 de julio de 2013 a las 21:07

  • tanto el mosaico como el cuerpo de la pregunta mencionan Linux y OSX. esto es sobre la parte de Linux

    – Javier

    22 de noviembre de 2013 a las 6:34

¿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