linux - 如何在 linux 上使用 libnl3(netlink 版本 3)获取接口(interface)的 ipv4 地址?

标签 linux netlink

我正在学习 netlink 库版本 3,我想知道如何获取指定网络接口(interface)的 ipv4 地址。我可以获取 mac 地址,甚至可以从链接数据结构中重新查询接口(interface)名称,但我不知道如何使用 libnl 和 libnl-route 库获取 ip 地址。我确实找到了一些使用 libnl-cli 库获取 ip 地址的代码,但那是为了将结果转储到文件描述符(想想 stdout)。我已将邮件发送到该图书馆的邮件列表,但尚未收到回复。

这是我的代码: https://gist.github.com/netskink/4f554ed6657954b17ab255ad5bc6d1f0

这是我的结果:

./stats 
Returned link name is enp6s0
Returned link addr is a0:36:9f:66:93:13

我见过使用 ioctls 检索 ip 地址的机制,但由于 netlink lib 可以使用 cli 子库返回 ip 地址,我认为它可以完成,但我想不出办法。

最佳答案

接口(interface)可以有多个地址(ipv4 和 ipv6 地址——代码示例给了我一个 ipv4 和一个 ipv6),所以没有为接口(interface)返回一个地址的函数。如果只有你有特定的本地地址,你可以调用 rtnl_addr_get。相反,您可以迭代地址。

#include <libnl3/netlink/cache.h>

void addr_cb(struct nl_object *o, void *data)
{
    int ifindex = (int)(intptr_t)data;
    struct rtnl_addr *addr = (rtnl_addr *)o;
    if (NULL == addr) {
        /* error */
        printf("addr is NULL %d\n", errno);
        return;
    }

    int cur_ifindex = rtnl_addr_get_ifindex(addr);
    if(cur_ifindex != ifindex)
        return;

    const struct nl_addr *local = rtnl_addr_get_local(addr);
    if (NULL == local) {
        /* error */
        printf("rtnl_addr_get failed\n");
        return;
    }

    char addr_str[ADDR_STR_BUF_SIZE];
    const char *addr_s = nl_addr2str(local, addr_str, sizeof(addr_str));
    if (NULL == addr_s) {
        /* error */
        printf("nl_addr2str failed\n");
        return;
    }
    fprintf(stdout, "\naddr is: %s\n", addr_s);
}

您可以从缓存中迭代地址并查看它们是否包含所需的地址(查看 ifindex)。请看https://www.infradead.org/~tgr/libnl/doc/api/cache_8c_source.html用于有用的功能(有一些过滤功能)。

int ifindex = rtnl_link_get_ifindex(p_rtnl_link);
printf("ifindex: %d\n", ifindex);

bool empty = nl_cache_is_empty(addr_cache);
printf("empty: %d\n", empty);

nl_cache_foreach(addr_cache,
        addr_cb, (void*)(intptr_t)ifindex);

并检查 ip 版本使用 rtnl_addr_get_family。

关于linux - 如何在 linux 上使用 libnl3(netlink 版本 3)获取接口(interface)的 ipv4 地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42307658/

相关文章:

linux - 创建/写入文件 x86 Linux

c++ - 无法理解这个 "message sequence mismatch error"

命令行错误

android - 如何通过蓝牙将 Android 应用程序连接到 Raspberry Pi,以便发送数字文本文件?

linux - 一种确定进程的 "real"内存使用情况的方法,即私有(private)脏 RSS?

linux - 轮询/选择从用户空间复制到内核空间

linux - 为什么路由表中的路由项(通过 netlink 套接字获取)没有网络掩码信息?

c - 监听 PF_NETLINK 套接字时获取所有链接和地址信息

android - 以 Android API 30 为目标时无法绑定(bind) () netlink 套接字