在 Linux 上获取有关网络接口更改的通知

Posted

技术标签:

【中文标题】在 Linux 上获取有关网络接口更改的通知【英文标题】:Get notified about network interface change on Linux 【发布时间】:2011-01-16 17:36:19 【问题描述】:

我需要一种方法来在启用或禁用网络接口时通知我的用户空间应用。我希望在不诉诸民意调查的情况下做到这一点。当网络相关事件发生时,内核是否提供了某种钩子来触发回调函数?

【问题讨论】:

关于“rtnetlink”,您可能需要查看此链接以获取示例代码:***.com/a/2353441/1435026 【参考方案1】:

我相信 netlink (man 7 netlink) 工具通过NETLINK_ROUTE 系列 (man 7 rtnetlink) 提供有关网络接口的信息。您可能能够在 netlink 套接字上 select()poll() 以获取您想要的信息。不过,我不确定这一点;我自己没用过。

在更高级别上,如果系统正在运行NetworkManager,当系统的网络状态发生变化时,它将通过 D-Bus 广播事件。 Epiphany 浏览器使用这些事件,例如,当系统失去网络连接时自动激活“离线工作”模式,并在网络连接恢复时切换回在线模式。有多种语言的 D-Bus 客户端库,它的平台特定性不如 netlink,所以这是我推荐使用的。

【讨论】:

例如,请参阅this answer 到 SO 问题“如何在 Linux 中以编程方式检测 IP 地址更改?”【参考方案2】:

选项:

ifplugd 将在电缆插入或拔出网络接口时运行您选择的脚本。

如果您使用的是 Debian,您可以将脚本添加到 /etc/network 的子目录中,每次界面启动或关闭时都会运行脚本。

如果以上都不适合您的需求,请查看D-Bus。我从来没有成功使用过它,但它就是为这种事情而设计的。

【讨论】:

【参考方案3】:

无需像 Norman Ramsey 建议的那样轮询或依赖操作系统挂钩,您唯一的选择是定期检查工作界面与几秒钟前的状态。如果想法是在链接不可用时排队/阻止等待聊天,那只会导致事件/rx/tx 队列地狱。

此外,Debian 脚本与 init 脚本一起工作,它们提供的钩子不会告诉您 root 是否使用 ifconfig 来关闭或修改已配置的接口,或者配置了未在 init 中描述的新接口。它们只会告诉您用户是否通过 /etc/init.d/networking 执行了某些操作,或者 init 是否执行了相同操作。

启动一个线程来轮询更改有什么可怕的?

除此之外,是的,您可以启动一个“netnicmond”进程,向订阅者列表发出信号,让他们知道某事发生了变化,或者更复杂的实际传达了这些变化。您可能会为此使用 netlink ...

你考虑过只使用 netlink 吗?

【讨论】:

【参考方案4】:

为什么不在代码中使用fork,使用popen 来做:

问题tail -f /var/log/messages 寻找eth* 接口 发出ifconfig 以查看上升或下降的适配器列表

并使用pregex 解析数据,执行一段时间sleep() 并再次检查。或者您可以使用“syslog.h”函数监控系统日志工具。

如果您坚持 Posix 标准,代码将可移植到不同风格的 Unix/Linux/BSD...

【讨论】:

ifconfig 不是 POSIX,输出实际上从一个 UNIX 到另一个变化很大。当然,它(大部分)在所有 Linux 上都是相同的,但即使有两个常用的不同版本(Busybox 和 net-tools)。 /var/log/messages 不是您可以依赖任何类型的 API 的文件。它用于人类可读的日志记录。在某些系统上,日志转到 /var/log/syslog。谁知道日志的文件名是否可能与预期不同、被禁用或文本格式不同。程序可能会被引用eth* 的其他日志条目混淆。

以上是关于在 Linux 上获取有关网络接口更改的通知的主要内容,如果未能解决你的问题,请参考以下文章

Linux 获取有关重点 gui 窗口更改的通知

Linux内核中网络数据包的接收-第一部分 概念和框架

获取有关 cgroup 进程更改的通知?

如何获取有关数据库列更改的通知

如何在 Flutter 中获取有关提供者上下文更改的网络数据

在 Java 中接收 eth 链接状态通知的更改(在 Linux 中)