如何通过netlink获得网络链路L2地址

How to get network link L2 address via netlink?

本文关键字:链路 L2 地址 网络 何通过 netlink      更新时间:2023-10-16

我使用netlink来获取接口,其名称,类型等,但我无法获得L2地址(ugly_datanlmsghdr*):

struct ifinfomsg *iface;
struct rtattr *attribute;
int len;
iface = (struct ifinfomsg *) NLMSG_DATA(ugly_data);
len = ugly_data->nlmsg_len - NLMSG_LENGTH(sizeof(*iface));
for (attribute = IFLA_RTA(iface);
     RTA_OK(attribute, len);
     attribute = RTA_NEXT(attribute, len))
{
  id_ = iface->ifi_index;
  // get type
  switch (iface->ifi_type)
  {
  case ARPHRD_ETHER:
    type_ = "Ethernet";
    break;
  case ...
  }
  // get attributes
  switch (attribute->rta_type)
  {
  case IFLA_IFNAME:
    name_ = (char *) RTA_DATA(attribute);
    break;
  case IFLA_ADDRESS:
    address_ = (char *) RTA_DATA(attribute);
    break;
   ...
  }
}

type_, id_name_包含正确的值,与我从ifconfig得到的相同,但address_总是空的。我做错了什么,如何获得地址?

可能问题是这里的硬件地址不是字符串。试着像这样获取address_:

case IFLA_ADDRESS:
  char buffer[64];
  unsigned char* ptr = (unsigned char*)RTA_DATA(attribute);
  snprintf(buffer, 64, " %02x:%02x:%02x:%02x:%02x:%02x", 
      ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
  std::cout << "address : " << buffer << std::endl;

Python (Linux)'solution'(可能对某人有帮助):
这是来自Python Netlink库中的第一个示例:
参见:https://pypi.python.org/pypi/pyroute2/0.2.16
非常简单的安装:

$ sudo pip install pyroute2  

将其放入一个文件(我称之为netlink1.py)并使其可执行:

#!/usr/bin/env python
from pyroute2 import IPRoute
# get access to the netlink socket
ip = IPRoute()
# print interfaces
print ip.get_links()
# stop working with netlink and release all sockets
# ip.release() (deprecated)
ip.close()

将所有内容打印到一行,然后:

$ ./netlink1.py | sed 's/], /n/g' | grep IFLA_ADD