内核网络通知链的使用netdev_chain和inetaddr_chain

函数介绍

(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");

猜你喜欢

转载自blog.csdn.net/yldfree/article/details/84067098