2010-05-20 19 views
9

Estoy escribiendo una aplicación que informa los atributos de los dispositivos de red en la máquina local. Necesito la dirección MAC, mtu, velocidad de enlace y algunos otros. Estoy usando udev para esto. Ya he descubierto cómo obtener la dirección MAC y mtu, pero no cómo obtener la velocidad del enlace. Puedo obtenerlo con ethtool desde la terminal, pero necesito una forma de hacerlo programáticamente.¿Obtiene la velocidad de enlace mediante programación?

¿Alguien sabe cómo puedo obtener el atributo de velocidad de enlace con udev u otra biblioteca?

+0

¿Con udev? ¿Cómo lograste eso? –

+0

Usando la llamada 'udev_device_get_sysattr_value' con los atributos" dirección "para la dirección Mac y" mtu "para la MTU. – StackedCrooked

Respuesta

24

Debe usar la llamada SIOCETHTOOL ioctl(). Hay una agradable llamada introduction to ioctl/SIOCETHTOOL en LinuxJournal, y el siguiente código (que no pretende ser un ejemplo de buenas prácticas de C) debería mostrarle cómo usarlo para obtener la velocidad.

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/ioctl.h> 
#include <netinet/in.h> 
#include <linux/sockios.h> 
#include <linux/if.h> 
#include <linux/ethtool.h> 
#include <string.h> 
#include <stdlib.h> 

int main (int argc, char **argv) 
{ 
    int sock; 
    struct ifreq ifr; 
    struct ethtool_cmd edata; 
    int rc; 

    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 
    if (sock < 0) { 
     perror("socket"); 
     exit(1); 
    } 

    strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name)); 
    ifr.ifr_data = &edata; 

    edata.cmd = ETHTOOL_GSET; 

    rc = ioctl(sock, SIOCETHTOOL, &ifr); 
    if (rc < 0) { 
     perror("ioctl"); 
     exit(1); 
    } 
    switch (ethtool_cmd_speed(&edata)) { 
     case SPEED_10: printf("10Mbps\n"); break; 
     case SPEED_100: printf("100Mbps\n"); break; 
     case SPEED_1000: printf("1Gbps\n"); break; 
     case SPEED_2500: printf("2.5Gbps\n"); break; 
     case SPEED_10000: printf("10Gbps\n"); break; 
     default: printf("Speed returned is %d\n", edata.speed); 
    } 

    return (0); 
} 
+0

¡Gracias! Lo probaré mañana. (De hecho, pirateé una solución de trabajo usando código snippits del código fuente de 'ethtool'. Es muy similar a esto.) – StackedCrooked

+0

Esto da un error de" Operación no permitida "cuando se ejecuta como un usuario no privilegiado en RHEL 5/6. ¿Hay alguna manera de obtener esta información sin necesidad de acceso a la raíz? –

+0

Debe usar ethtool_cmd_speed (& edata) para obtener una respuesta de velocidad de edata, ya que hay algunos bits altos que ignora aquí. – MappaM

Cuestiones relacionadas