编写Netfilter模块过滤ARP数据包
参考书:《Linux内核模块开发技术指南》
1.ARP数据包过滤
Netfilter框架不仅仅可以实现IP数据包的过滤,还可以过滤ARP数据包、DECnet数据包等。与IP数据包的过滤不同,ARP数据包过滤仅存在三条链:IN链、OUT链和FORWARD链,分别对应ARP数据包的进入、发出和转发。这几条链的值在内核源码的uapi/linux/netfilter_arp.h头文件中定义,如下所示。
#define NF_ARP_IN 0 //IN链
#define NF_ARP_OUT 1 //OUT链
#define NF_ARP_FORWARD 2 //FORWARD链
可以在这几条链上注册钩子函数来过滤ARP数据包。注册和注销的方式见我的文章:实现最简单的Netfilter模块(Linux网络数据包过滤模块),只是需要将注册时参数的协议信息配置成NFPROTO_ARP,链信息配置成上述三条链中的一条。
2.示例
一个最简单的ARP数据包过滤示例如下所示。
#include <linux/module.h>
#include <uapi/linux/netfilter_arp.h> //需引入该头文件以用于过滤ARP数据包
//将要注册的钩子函数
static unsigned int hook_input(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{return NF_DROP; //丢弃所有的ARP数据包
}//钩子操作数组,只有一个成员,用于注册在INPUT链上
static const struct nf_hook_ops netfilter_mod_ops[] = {{.hook = hook_input, //钩子函数//需要将协议配置为NFPROTO_ARP,表示过滤ARP数据包.pf = NFPROTO_ARP,.hooknum = NF_ARP_IN, //钩子函数挂在IN链上.priority = 1, //优先级配置为1},
};
//内核模块加载函数
static int test_drop_arp_init(void)
{//调用nf_register_net_hooks注册钩子函数数组return nf_register_net_hooks(&init_net, netfilter_mod_ops, ARRAY_SIZE(netfilter_mod_ops));return 0;
}
//内核模块卸载函数
static void test_drop_arp_exit(void)
{//注销netfilter钩子函数数组nf_unregister_net_hooks(&init_net, netfilter_mod_ops, ARRAY_SIZE(netfilter_mod_ops));
}
module_init(test_drop_arp_init);
module_exit(test_drop_arp_exit);
编译、加载上述源码后,进入系统的所有arp数据包将被丢弃。
