リンク速度取得関数

ネットワーク・インタフェース毎のリンク速度はethtoolコマンドを使えば以下の様に確認できるが、

# ethtool eth0
Settings for eth0:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Advertised auto-negotiation: Yes
        Speed: 1000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 1
        Transceiver: internal
        Auto-negotiation: on
        Supports Wake-on: pumbag
        Wake-on: g
        Current message level: 0x00000001 (1)
        Link detected: yes

プログラムから同様の事を行うには、ioctl(SIOCETHTOOL)を以下の様に叩けば良い。

#include  <linux/ethtool.h>
int getlinkspeed(char *ifname)
{
    struct ethtool_value  ethval;
    struct ethtool_cmd    ethcmd;
    struct ifreq          ifr;
    int fd_tmp, linkspd = 1000; /* A unit is Mbps. */
    /* open control socket */
    fd_tmp = socket(AF_INET, SOCK_DGRAM, 0);
    if ( fd_tmp < ZERO ){
        return ZERO;
    }
    /* init query structure */
    memset(&ifr, 0x00, sizeof(struct ifreq));
    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
    /* Query:LinkUp ?  */
    ethval.cmd = ETHTOOL_GLINK;
    ifr.ifr_data = (caddr_t)&ethval;
    if ( !ioctl(fd_tmp, SIOCETHTOOL, &ifr) && ethval.data ){
        /* LinkUp !! */
        /* Query:GetSettings  */
        ethcmd.cmd = ETHTOOL_GSET;
        ifr.ifr_data = (caddr_t)&ethcmd;
        if( !ioctl(fd_tmp, SIOCETHTOOL, &ifr) ){
            linkspd = ethcmd.speed;
        }
    } else {
        /* Query failed */
        linkspd = ZERO;
    }
    close(fd_tmp);
    return linkspd;
}

参照

スラッシュドット・ジャパン http://slashdot.jp/