I need a way to notify my user space app when a network interface is enabled or disabled. I'm hoping to do this without resorting to polling. Does th开发者_开发知识库e kernel offer some sort of hook for triggering callback functions when network-related events occur?
I believe the netlink (man 7 netlink
) facility provides information about network interfaces via the NETLINK_ROUTE
family (man 7 rtnetlink
). You may be able to select()
or poll()
on a netlink socket to get the information you want. I'm not certain of this, though; I haven't used it myself.
At a higher level, if the system is running NetworkManager, that'll broadcast events via D-Bus when the system's network status changes. The Epiphany browser uses these events, for example, to automatically activate "Work Offline" mode when the system loses its network connection, and switch back to online mode when network connectivity resumes. There are D-Bus client libraries for a variety of languages, and it's less platform-specific than netlink, so this is what I'd recommend using.
Options:
ifplugd
will run the script of your choice when a cable is plugged into or unplugged from your network interface.If you are using Debian you can add a script to the subdirectories of
/etc/network
, where there are scripts that are run every time an interface goes up or down.If neither of the above are suitable for your needs, look into D-Bus. I've never had much luck using it successfully, but this is the sort of thing it was designed for.
Without polling or relying on OS hooks like Norman Ramsey suggested, your only option is to periodically check the working interface against what it was a few seconds ago. That only leads to event / rx / tx queue hell, if the idea is to queue / block waiting for the chatter when the link is unavailable.
Also, the Debian scripts work in conjunction with the init scripts, the hooks they provide won't tell you if root used ifconfig to down or modify a configured interface, or configured a new one that wasn't described to init. They only tell you if the user did something via /etc/init.d/networking, or if init did the same.
What is so terribly wretched about starting a thread to poll for changes?
Short of that, yes, you could start a 'netnicmond' process that signaled a list of subscribers to let them know that something changed, or a more complex one that actually conveyed the changes. You'd probably use netlink for that ...
Have you considered just using netlink?
Why not do a fork
in the code, using popen
to do either:
- Issue
tail -f /var/log/messages
looking foreth*
interfaces - Issue
ifconfig
to see the list of adapters going up or down
and parse the data using a pregex
, do a sleep()
for a period of time and recheck again.. Or you could go monitor the system log facility using the 'syslog.h' functions.
If you stick to the Posix standard, the code will be portable across different flavours of Unix/Linux/BSD...
精彩评论