在 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 上获取有关网络接口更改的通知的主要内容,如果未能解决你的问题,请参考以下文章