使用 Netfilter 非常简单。我们只需将自定义函数(位于内核模块中)挂载到相应的 Netfilter 钩子上。以下示例展示了如何实现(代码位于 Labsetup/packet_filter 文件夹中,但可能与此示例略有不同)。

代码的结构与前面实现的内核模块类似。当内核模块被添加到内核中时,代码中的 registerFilter() 函数会被调用。在此函数内,我们向 Netfilter 注册了两个钩子。

为了注册一个钩子,你需要准备一个钩子数据结构,并设置所有必要的参数,其中最重要的是函数名(行 🄰)和钩子编号(行 🄱)。钩子编号是 Netfilter 中的 5 个钩子之一,指定的函数将在数据包到达该钩子时被调用。在本例中,当数据包到达  LOCAL_IN 钩子时,函数 printInfo() 会被调用(该函数稍后会给出)。当钩子数据结构准备好后,我们在行 🄲 将其注册到 Netfilter 上。

// 向 Netfilter 注册钩子函数
static struct nf_hook_ops hook1, hook2;

int registerFilter(void) {
   printk(KERN_INFO "Registering filters.\n");
   
   // 钩子 1
   hook1.hook = printInfo;                    🄰
   hook1.hooknum = NF_INET_LOCAL_IN;          🄱
   hook1.pf = PF_INET;
   hook1.priority = NF_IP_PRI_FIRST;
   nf_register_net_hook(&init_net, &hook1);   🄲


   // 钩子 2
   hook2.hook = blockUDP;
   hook2.hooknum = NF_INET_POST_ROUTING;
   hook2.pf = PF_INET;
   hook2.priority = NF_IP_PRI_FIRST;
   nf_register_net_hook(&init_net, &hook2);

   return 0;
}

void removeFilter(void) {
   printk(KERN_INFO "The filters are being removed.\n");
   nf_unregister_net_hook(&init_net, &hook1);
   nf_unregister_net_hook(&init_net, &hook2);
}

module_init(registerFilter);
module_exit(removeFilter);
最后修改: 2025年05月9日 星期五 22:53