函数介绍
(1) int register_netdevice_notifier(struct notifier_block *nb)
功能: 在内核通知链netdev_chain上注册消息块,用来接收有关网络设备的注册状态等信息
nb:消息块,在里面自己添加消息处理函数
返回值:成功返回0
头文件:#include <linux/netdevice.h>
(2) int unregister_netdevice_notifier(struct notifier_block *nb)
功能:与上面register_netdevice_notifier为一对,用于在通知链netdev_chain上删除消息块
(3) int register_inetaddr_notifier(struct notifier_block *nb)
功能: 在内核通知链inetaddr_chain上注册消息块,用于接收ip地址的改变等事件
nb:消息块,在里面自己添加消息处理函数
返回值:成功返回0
头文件: #include <linux/inetdevice.h>
(4) int unregister_inetaddr_notifier(struct notifier_block *nb)
功能:与上面register_inetaddr_notifier为一对,用于在通知链inetaddr_chain上删除消息块
部分事件说明
#define NETDEV_UP 0x0001//激活一个网络设备
#define NETDEV_DOWN 0x0002//停止一个网络设备,所有对该设备的引用都应释放
#define NETDEV_REBOOT 0x0003 //检查到网络设备接口硬件崩溃,硬件重启
#define NETDEV_CHANGE 0x0004 //网络设备的数据包队列状态发生改变
#define NETDEV_REGISTER 0x0005//一个网络设备事例注册到系统中,但尚未激活
#define NETDEV_UNREGISTER 0x0006//网络设备驱动已卸载
#define NETDEV_CHANGEMTU 0x0007//MTU发生了改变
#define NETDEV_CHANGEADDR 0x0008//硬件地址发生了改变
#define NETDEV_GOING_DOWN 0x0009//网络设备即将注销,有dev->close报告,通知相关子系统处理
#define NETDEV_CHANGENAME 0x000A//网络设备名改变
#define NETDEV_FEAT_CHANGE 0x000B//网络硬件功能改变
举个栗子
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
//处理网络设备的启动与禁用等事件
int test_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = (struct net_device *)ptr;
switch(event)
{
case NETDEV_UP:
if(dev && dev->name)
printk("dev[%s] is up\n",dev->name);
break;
case NETDEV_DOWN:
if(dev && dev->name)
printk("dev[%s] is down\n",dev->name);
break;
default:
break;
}
return NOTIFY_DONE;
}
//处理ip地址的改变事件
int test_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
struct net_device *dev = NULL;
if(ifa && ifa->ifa_dev)
dev = ifa->ifa_dev->dev;
switch(event)
{
case NETDEV_UP:
if(dev && dev->name)
printk("inet[%p] is up\n",dev->name);
break;
case NETDEV_DOWN:
if(dev && dev->name)
printk("inet[%p] is down\n",dev->name);
default:
break;
}
return NOTIFY_OK;
}
struct notifier_block inethandle={
.notifier_call = test_inetaddr_event
};
struct notifier_block devhandle={
.notifier_call = test_netdev_event
};
static int __init test_init(void)
{
/*
在netdev_chain通知链上注册消息块
netdev_chain通知链是内核中用于传递有关网络设备注册状态的通知信息
*/
register_netdevice_notifier(&devhandle);
/*
在inetaddr_chain通知链上注册消息块
inetaddr_chain通知链是内核中用于传递有关本地接口上的ipv4地址的插入,删除以及变更的通知信息
*/
register_inetaddr_notifier(&inethandle);
return 0;
}
static void __exit test_exit(void)
{
unregister_netdevice_notifier(&devhandle);
unregister_inetaddr_notifier(&inethandle);
return;
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");