Reputation: 47
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
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