【小知识点】一个netfilter forward hook的例子

下面是一个基于Netfilter的forward hook的例子:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>

static struct nf_hook_ops nfho;

/* This function will be called for each incoming packet */
unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) {

    struct iphdr *iph;

    /* Get the IP header of the incoming packet */
    iph = ip_hdr(skb);

    /* Check if the packet is an IPv4 packet */
    if (iph->version == 4) {
        /* If it's an IPv4 packet, drop it */
        printk(KERN_INFO "Dropping IPv4 packet from %d.%d.%d.%d to %d.%d.%d.%d\n",
               NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
        return NF_DROP;
    }

    /* If the packet is not IPv4, let it pass */
    return NF_ACCEPT;
}

int init_module() {

    /* Register the hook function */
    nfho.hook = hook_func;
    nfho.pf = PF_INET; /* IPv4 */
    nfho.hooknum = NF_INET_FORWARD; /* Hook into the forward chain */
    nfho.priority = NF_IP_PRI_FIRST; /* Set the highest priority */
    nf_register_hook(&nfho);

    printk(KERN_INFO "netfilter forward hook loaded\n");
    return 0;
}

void cleanup_module() {

    /* Unregister the hook function */
    nf_unregister_hook(&nfho);

    printk(KERN_INFO "netfilter forward hook unloaded\n");
}

该代码示例中,定义了一个名为nfho的结构体,其中包含了一个指向hook_func的钩子函数、网络协议族(PF_INET)和钩子挂载的位置(NF_INET_FORWARD)。在init_module函数中,使用nf_register_hook函数将该钩子函数注册到Netfilter中。当有数据包通过网络接口时,Netfilter会将数据包传递给hook_func函数进行处理。在这个例子中,我们将仅仅处理IPv4数据包,并将其丢弃。

需要注意的是,hook_func函数的返回值必须是一个枚举类型nf_hookah_ret,表示Netfilter对该数据包的处理结果,它有三种取值:NF_ACCEPT、NF_DROP和NF_STOLEN。NF_ACCEPT表示让数据包继续传递;NF_DROP表示丢弃数据包;NF_STOLEN表示hook_func函数已经处理了数据包,并且不再需要传递给下一个hook函数进行处理。

此外,在init_module函数中,我们还使用printk函数输出了一些信息,用于调试和诊断代码。在cleanup_module函数中,我们取消注册该hook函数。

原文链接:,转发请注明来源!