所有接口的C/C++ Linux MAC地址

use*_*626 7 c linux ioctl mac-address ifconfig

我使用以下代码检索当前计算机的所有MAC地址:

ifreq ifr;
ifconf ifc;
char buf[1024];

int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sock == -1) { ... };

ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) { ... }

ifreq *it = ifc.ifc_req;
const ifreq* const end = it + (ifc.ifc_len / sizeof(ifreq));

for (; it != end; ++it) {
    strcpy(ifr.ifr_name, it->ifr_name);
    if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
        if (!(ifr.ifr_flags & IFF_LOOPBACK)) {
            if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
               unsigned char mac_address[6];
               memcpy(mac_address, ifr.ifr_hwaddr.sa_data, 6);
               ...
            }
        }
    }
    else { ... }
}
Run Code Online (Sandbox Code Playgroud)

通过运行简单的shell命令ifconfig我可以看到lo,eth0和wlan0.我想通过我的C/C++代码检索eth0和wlan0的MAC地址.但只返回wlan0 - 缺少eth0(我得到ifr_names lo,lo,wlan0).可能是因为eth0没有激活(没有连接以太网电缆,电缆会被退回).我可以以某种方式改变ioctl(SIOCGIFCONF)命令来检索eth0,即使它被"关闭"了吗?

我可以通过直接使用来获取其HW地址

  struct ifreq s;
  int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);

  strcpy(s.ifr_name, "eth0");
  if (0 == ioctl(fd, SIOCGIFHWADDR, &s)) { ... }
Run Code Online (Sandbox Code Playgroud)

但如果名称不是eth0而是其他东西(eth1,em0,......)怎么办?我想得到所有这些.感谢帮助.

jør*_*sen 9

您应该停止使用net-tools和古老的ioctl接口,并开始使用现代的Netlink/sysfs接口.你有不少于5种可能性:

  • 编写自己的Netlink接口代码
  • 自己NL代码,并结合利用libmnl( - >见rtnl链接转储例子
  • 或者使用像libnl3这样的自治库
  • 解析文本输出ip -o link(-o是获取用于文本解析的输出,与ifconfig不同)
  • 或者使用sysfs然后看看 /sys/class/net/eth0/address