user3395974
user3395974

Reputation: 47

how to insmod my netfilter module in ubuntu 18.04

I try to write a simple linux module based on netfilter hooks. My code (pcap.c) is shown as follows:

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

My makefile is shown as follows:

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

I cannot insmod my module.

And the dmesg shows: Netfilter: version magic '4.18.11 SMP mod_unload ' should be '5.3.0-59-generic SMP mod_unload '

I cannot fix this problem. Please help me. Thanks a lot.

Upvotes: 1

Views: 922

Answers (1)

user3395974
user3395974

Reputation: 47

I fixed the problem. The problem is caused because of the namespace of network device. At first, we should delete the following code:

struct net *net;

Then correct the nf_register_net_hook and nf_unregister_net_hook functions as follows:

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

My final code is shown as follows:

#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);

Upvotes: 2

Related Questions