gpt4 book ai didi

c++ - ethtool ioctl 返回未填充的 ethtool_link_settings

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:35:35 24 4
gpt4 key购买 nike

我正在尝试使用 Ethtool ioctl API 从我的 NIC 检索链接速度数据,但我只是在 ethtool_link_settings 实例中取回零。使用 ethtool 命令行工具返回预期值,我的 NIC 驱动程序支持更新的 ETHTOOL_GLINKSETTINGS API。

#include <iostream>
#include <cstring>

#include <linux/ethtool.h>
#include <linux/sockios.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <unistd.h>

int main()
{
auto ifn = if_nameindex();
auto fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);

for (auto i = ifn; i->if_name; ++i) {
// Skip the loopback
if (i->if_index == 1) {
continue;
}

std::cout << "Testing: " << i->if_name << std::endl;

auto ifr = ifreq{};
std::strncpy(ifr.ifr_name, i->if_name, IF_NAMESIZE);

auto msg = ethtool_link_settings{};
msg.cmd = ETHTOOL_GLINKSETTINGS;
ifr.ifr_data = reinterpret_cast<char*>(&msg);

if (ioctl(fd, SIOCETHTOOL, &ifr) == -1) {
std::cerr << "ioctl fail: " << strerror(errno) << std::endl;
}

std::cout << "\tSpeed: " << msg.speed
<< "\n\tDuplex: " << static_cast<int>(msg.duplex)
<< "\n\tPort: " << static_cast<int>(msg.port)
<< std::endl;
}

close(fd);
if_freenameindex(ifn);
return EXIT_SUCCESS;
}

结果:

Testing: enp0s3
Speed: 0
Duplex: 0
Port: 0
Testing: enp0s8
Speed: 0
Duplex: 0
Port: 0
Testing: enp0s9
Speed: 0
Duplex: 0
Port: 0
Testing: enp0s10
Speed: 0
Duplex: 0
Port: 0

我确定我在做一些愚蠢的事情,但我看不到。

最佳答案

/usr/include/linux/ethtool.hstruct ethtool_link_settingslink_mode_masks_nwords 字段的注释中隐藏着一些令人钦佩的神秘评论说 ETHTOOL_GLINKSETTINGS 会进行一些握手,因此您需要多次调用它。

我已经使用 ethtool command 的代码调整了您的代码到执行 ETHTOOL_GLINKSETTINGS 命令:

#include <iostream>
#include <cstring>

#include <linux/ethtool.h>
#include <linux/sockios.h>
#include <linux/netlink.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <unistd.h>

int main()
{
auto ifn = if_nameindex();
auto fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);

for (auto i = ifn; i->if_name; ++i) {
struct {
struct ethtool_link_settings req;
__u32 link_mode_data[3 * 127];
} ecmd;

// Skip the loopback
if (i->if_index == 1) {
continue;
}

std::cout << "Testing: " << i->if_name << std::endl;

auto ifr = ifreq{};
std::strncpy(ifr.ifr_name, i->if_name, IF_NAMESIZE);

ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
ifr.ifr_data = reinterpret_cast<char*>(&ecmd);

if (ioctl(fd, SIOCETHTOOL, &ifr) == -1) {
std::cerr << "ioctl fail: " << strerror(errno) << std::endl;
return 1;
}

if (ecmd.req.link_mode_masks_nwords >= 0 || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS)
return 1;

ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;

if (ioctl(fd, SIOCETHTOOL, &ifr) == -1) {
std::cerr << "ioctl fail: " << strerror(errno) << std::endl;
return 1;
}

std::cout << "\tSpeed: " << ecmd.req.speed
<< "\n\tDuplex: " << static_cast<int>(ecmd.req.duplex)
<< "\n\tPort: " << static_cast<int>(ecmd.req.port)
<< std::endl;
}

close(fd);
if_freenameindex(ifn);
return EXIT_SUCCESS;
}

关于c++ - ethtool ioctl 返回未填充的 ethtool_link_settings,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49573499/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com