Search code examples
linuxnetwork-programmingioctl

how to use ethtool_drvinfo to collect driver information for a network interface?


I have a network interface that shows data as under:

driver: r8152 
version: v1.12.12
firmware-version: rtl8153a-4 v2 02/07/20
expansion-rom-version:
bus-info: usb-0000:00:14.0-9
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no

However I am unable to collect driver information via an ioctl call like this:

socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (socketfd == -1)
    printf ("error:socketfd no open");

struct ethtool_drvinfo drvrinfo = {0};
drvrinfo.cmd = ETHTOOL_GDRVINFO;
int x = ioctl(socketfd, SIOCETHTOOL, &drvrinfo);`

I am not sure of the exact flow as I am using it for the first time. Please help


Solution

  • Simple Linux dump of this info. Change enp0s5 to your interface name.

    Sample output:

    % ./get-driver-info
    driver: virtio_net
    version: 1.0.0
    firmware-version:
    expansion-rom-version:
    bus-info: 0000:00:05.0
    supports-statistics: yes
    supports-test: no
    supports-eeprom-access: no
    supports-priv-flags: no
    

    Linux source:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/ioctl.h>
    #include <linux/ethtool.h>
    #include <linux/sockios.h>
    #include <net/if.h>
    
    int main() {
      char *devname = "enp0s5";
      struct ifreq sif;
      struct ethtool_drvinfo d;
      int ret;
    
      int sd = socket(AF_INET, SOCK_DGRAM, 0);
    
      if (sd < 0){
        printf("Error socket\n");
        exit(1);
      }
    
      memset(&sif, 0, sizeof(struct ifreq));
      strncpy(sif.ifr_name, devname, strlen(devname));
    
      d.cmd = ETHTOOL_GDRVINFO;
      sif.ifr_data = (caddr_t)&d;
      ret = ioctl(sd, SIOCETHTOOL, &sif);
    
      if(ret == -1){
        perror("ioctl");
        return 1;
      }
    
      printf("driver: %s\nversion: %s\n", d.driver, d.version);
      printf("firmware-version: %s\n", d.fw_version);
      printf("expansion-rom-version: %s\n", d.fw_version);
      printf("bus-info: %s\n", d.bus_info);
      printf("supports-statistics: %s\n", d.n_stats ? "yes" : "no");
      printf("supports-test: %s\n", d.testinfo_len ? "yes" : "no");
      printf("supports-eeprom-access: %s\n", d.eedump_len ? "yes" : "no");
      printf("supports-priv-flags: %s\n", d.n_priv_flags ? "yes" : "no");
    }
    

    This information isn't stored in the socket, but having an open socket is a convenient way to query for information from the kernel about a specific network interface.