netfilter hook实验

    上一篇点击打开链接介绍了netfilter的机制,本篇通过一个极简单的内核模块实践一下该机制。module代码nf_hook.c如下,在NF_INET_LOCAL_IN上挂hook_func钩子并判断如果报文目的地址是10.10.10.10就打印一下,仅此而已。

#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/module.h>
#include <linux/ip.h>
static struct nf_hook_ops nfho;
//function to be called by hook
unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*            okfn)(struct sk_buff *))
{
    int ret = 0;
    struct iphdr *iph = NULL;
    struct udphdr *udp = NULL;
    iph = (struct iphdr *)skb_network_header(skb);
    if (ntohl(iph->daddr) == 0x0A0A0A0A) //10.10.10.10
    {   
        printk("%s rcv packet \n\r",__func__);
    }   
    return NF_ACCEPT;
}

int nf_hook_install(void)
{
    nfho.hook = hook_func;                       //function to call when conditions below met
    nfho.hooknum = NF_INET_LOCAL_IN;             //called right after packet recieved, first hook in Netfilter
    nfho.pf = PF_INET;                           //IPV4 packets
    nfho.priority = NF_IP_PRI_FIRST;             //set to highest priority over all other hook functions
    nf_register_hook(&nfho);                     //register hook

    return 0;                                    //return 0 for success 
}
int nf_hook_remove(void)
{
    nfho.hook = hook_func;                       //function to call when conditions below met
    nfho.hooknum = NF_INET_LOCAL_IN;             //called right after packet recieved, first hook in Netfilter
    nfho.pf = PF_INET;                           //IPV4 packets
    nfho.priority = NF_IP_PRI_FIRST;             //set to highest priority over all other hook functions
    nf_unregister_hook(&nfho);                     //register hook

    return 0;                                    //return 0 for success 
}
static int __init mymodule_init(void)
{
    printk("module init\n\r");
    nf_hook_install();
    return 0;
}
static int __exit mymodule_exit(void)
{
    printk("module exit\n\r");
    nf_hook_remove();
    return 0;
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("River");
MODULE_DESCRIPTION("nf_test");
module_init(mymodule_init);
module_exit(mymodule_exit);

makefile

ifneq ($(KERNELRELEASE),)
obj-m:=nf_hook.o
else
KERNELDIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
default:
	$(MAKE) -C $(KERNELDIR)  M=$(PWD) modules
clean:
	rm -rf *.o *.mod.c *.mod.o *.ko
endif

在主机上配置10.10.10.10地址,ping 10.10.10.10。 dmesg 查看内核日志可以看到自己的打印。

扩展:之前产品的gtp报文(udp port 2152)处理的方案是修改内核代码重出内核,用此方案可以不修改标准内核。

猜你喜欢

转载自blog.csdn.net/kklvsports/article/details/80287151
今日推荐