首页 > 解决方案 > 如何在 ubuntu 18.04 中安装我的 netfilter 模块

问题描述

我尝试编写一个基于 netfilter 钩子的简单 linux 模块。我的代码(pcap.c)如下所示:

#include <linux/time.h> 
#include <linux/init.h>  
#include <linux/netfilter.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>  
#include <linux/netfilter_ipv4.h>
#include <linux/net.h>
#include <net/ip.h>
#include <linux/if_ether.h>
#include <net/protocol.h>
#include <net/icmp.h>
#include <net/tcp.h>
#include <linux/if_vlan.h>

struct net *net;

static unsigned int pcap_func (void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
    printk(KERN_INFO "hook\n");

    return NF_DROP;
}

static struct nf_hook_ops nfho = {
    .hook       = pcap_func,
    .hooknum    = 1,
    .pf         = PF_INET,
    .priority   = NF_IP_PRI_FIRST,
};

static int __init pcap_init(void)
{
    if (nf_register_net_hook(net, &nfho)) {
        printk(KERN_ERR "nf_register_hook() failed\n");
        return -1;
    }
    return 0;
}

static void __exit pcap_exit(void)
{
    printk(KERN_INFO "unregister pcap module.\n");
    nf_unregister_net_hook(net, &nfho);
}

module_init(pcap_init);
module_exit(pcap_exit);
MODULE_LICENSE("GPL");

我的makefile如下所示:

obj-m := pcap.o
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
 
modules:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

install:
    insmod pcap.ko

uninstall:
    -rmmod pcap.ko
    rm -rf *.o *.ko *.mod.o *.mod.c *.symvers *.order *.mod

我无法安装我的模块。

并且 dmesg 显示: Netfilter: version magic '4.18.11 SMP mod_unload ' 应该是 '5.3.0-59-generic SMP mod_unload '

我无法解决这个问题。请帮我。非常感谢。

标签: linuxmodule

解决方案


我解决了这个问题。该问题是由于网络设备的命名空间引起的。首先,我们应该删除以下代码:

struct net *net;

然后更正nf_register_net_hook和nf_unregister_net_hook函数如下:

nf_register_net_hook(&init_net, &nfho);
nf_unregister_net_hook(&init_net, &nfho);

我的最终代码如下所示:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <net/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>

static struct nf_hook_ops *nfho = NULL;

unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
    printk(KERN_INFO "hook\n");
    return NF_DROP;
}

static int __init pcap_init(void)
{
    nfho = (struct nf_hook_ops*) kcalloc(1, sizeof(struct nf_hook_ops), GFP_KERNEL);

    nfho->hook = (nf_hookfn*) hook_func;
    nfho->hooknum = NF_INET_PRE_ROUTING;
    nfho->pf = PF_INET;
    nfho->priority = NF_IP_PRI_FIRST;

    nf_register_net_hook(&init_net, nfho);
    return 0;
}

static void __exit pcap_exit(void)
{
    nf_unregister_net_hook(&init_net, nfho);
    kfree(nfho);
}

module_init(pcap_init);
module_exit(pcap_exit);

推荐阅读