shirou / gopsutil

psutil for golang
Other
10.68k stars 1.59k forks source link

network interface card speed value #465

Open monotone opened 6 years ago

monotone commented 6 years ago

Hi,

I found the python psutil package have the psutil.net_if_stats() to get the network interface card speed.

>>> import psutil
>>> psutil.net_if_stats()
{'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
 'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)}

How gopsutil get this?

shirou commented 6 years ago

Unfortunately, current gopsutil does not have this function. I will implement but I can not say a schedule. Of curse, PR is always welcome!

monotone commented 6 years ago

I have found in the python psutil package source code.

And try to use this C code for test in Linux.

It seems like if ethtool eth0 work ,this code will work right. Otherwise it will failed.

#include <errno.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <linux/ethtool.h>
#include <linux/sockios.h>

int main() {
    int ret;
    int sock = 0;
    struct ethtool_cmd ethcmd;
    struct ifreq ifr;

    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock == -1) {
        perror("socket AF_INET failed");
        goto error;
    }
    strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));

    // duplex and speed
    memset(&ethcmd, 0, sizeof ethcmd);
    ethcmd.cmd = ETHTOOL_GSET;
    ifr.ifr_data = (void *)&ethcmd;
    ret = ioctl(sock, SIOCETHTOOL, &ifr);

    if (ret == -1) {
        perror("ioctl SIOCETHTOOL failed");
        goto error;
    }

    printf("duplex=%d,speed=%d\n", ethcmd.duplex, ethcmd.speed);

error:
    if (sock != -1) close(sock);
    return 0;
}
shirou commented 6 years ago

Thanks, but gopsutil aims to pure golang library. I found https://github.com/safchain/ethtool. This is for only linux, but it should be a first step.

monotone commented 6 years ago

yeah. Golang use syscall function to call the function ioctl of C.

I think you have used cgo in gopsutil, so it`s not a pure golang library already.

But It`s all right.

pytimer commented 6 years ago

@shirou I want to know the progress of this feature, because my project need to network interface information, and i use gopsutil on my project.

Thanks.

shirou commented 6 years ago

Perhaps, no one is working for this. We will very appreciate if you will send PR on it!

pytimer commented 6 years ago

I want know If implement this feature, which package will add this feature? net、host or other package?

shirou commented 6 years ago

I think under net is good.

pytimer commented 6 years ago

I have an idea about it. Maybe it not right.

Usage like this:

import "github.com/shirou/gopsutil/net"

stats, err := net.GetInterfaces()
speed = net.GetInterfaceByName("eth0").Speed()

net.GetInterfaces() return this host all network interfaces info. net.GetInterfaceByName() return the specified network interface info, such as ethtool eth0, include fields: link detected, speed.

Lomanic commented 6 years ago

There already is a net.Interfaces function in the stdlib that returns a list of Interface, I think the way to implement that would be to define a function accepting a (stdlib's) net.Interface (we can't extend types defined in foreign packages in Go).

pytimer commented 6 years ago

Can we define a new Interface struct in the net package? Like below code:

import "net"

type Interface struct{
  net.Interface
  Speed int64
}
carldunham commented 6 years ago

Would also be useful to include other values from ethtool, like link status.

smalljop commented 4 years ago

Is there a solution now

omar391 commented 2 years ago

@shirou any update, please?

shirou commented 2 years ago

No update. PR is welcome!