Linux网络防火墙【2】 Linux内核网络netfilter module

本文详细介绍了Linux内核中netfilter框架的模块实现过程,包括hook点定义、协议与优先级设置,以及如何通过nf_register_hook函数注册自定义模块。并通过示例展示了如何使用netfilter模块定制功能,适用于网络编程与内核开发人员。

上篇中讲到了 netfilter的基本框架,现在 我写个 netfilter 框架下的module, 演示一下如何使用 netfilter module定制 自己的功能模块。 我个人使用的是linux 版本是3.13.5.不同的版本,内核可能会有差异,但是 总体是还是没有变化的。


netfilter 框架提供了 5个hook点。如下图

/* 这是hook点的定义, 对应于 上图中的NF_IP_xxxxx*/
enum nf_inet_hooks {
	NF_INET_PRE_ROUTING, 
	NF_INET_LOCAL_IN,
	NF_INET_FORWARD,
	NF_INET_LOCAL_OUT,
	NF_INET_POST_ROUTING,
	NF_INET_NUMHOOKS
};
/*这是 协议的定义*/
enum {
	NFPROTO_UNSPEC =  0,
	NFPROTO_IPV4   =  2,
	NFPROTO_ARP    =  3,
	NFPROTO_BRIDGE =  7,
	NFPROTO_IPV6   = 10,
	NFPROTO_DECNET = 12,
	NFPROTO_NUMPROTO,
};

/*同一hook点上的module 优先级, 数值越小,优先级越高*/
enum nf_ip_hook_priorities {
	NF_IP_PRI_FIRST = INT_MIN,
	NF_IP_PRI_CONNTRACK_DEFRAG = -400,
	NF_IP_PRI_RAW = -300,
	NF_IP_PRI_SELINUX_FIRST = -225,
	NF_IP_PRI_CONNTRACK = -200,
	NF_IP_PRI_MANGLE = -150,
	NF_IP_PRI_NAT_DST = -100,
	NF_IP_PRI_FILTER = 0,
	NF_IP_PRI_SECURITY = 50,
	NF_IP_PRI_NAT_SRC = 100,
	NF_IP_PRI_SELINUX_LAST = 225,
	NF_IP_PRI_CONNTRACK_HELPER = 300,
	NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
	NF_IP_PRI_LAST = INT_MAX,
};



我们再看下 nf_hook_ops的定义。

struct nf_hook_ops {
	struct list_head list;

	/* User fills in from here down. */
	nf_hookfn	*hook;             /*这里是 我们要定义处理的函数指针*/
	struct module	*owner;  
	void		*priv; 
	u_int8_t	pf;               /*对应上图的协议NFPOTO_XXXXX*/
	unsigned int	hooknum;          /*对应上图中的NF_INET_XXXXX*/
	/* Hooks are ordered in ascending priority. */
	int		priority;        /*优先级定义 , hook module并不是只有我们的module,所以用这个优先级安排模块的顺序。 对应上图NF_IP_PRI_XXXXX*/
};
/*nf_hookfn	 的返回值类型*/
/* Responses from hook functions. */
#define NF_DROP 0
#define NF_ACCEPT 1
#define NF_STOLEN 2
#define NF_QUEUE 3
#define NF_REPEAT 4
#define NF_STOP 5
#define NF_MAX_VERDICT NF_STOP


只要使用这些参数,注意上面的返回值类型。 现在 我们就可以利用  nf_register_hook  函数注册我们自己的module了。 下面是一个简单的例子

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

static struct nf_hook_ops nfho;         //struct holding set of hook function options

//function to be called by hook
static 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 *))
{
  printk(KERN_INFO "get packet\n");                                             //dmesg 可以看到
  return NF_ACCPET;                                                                   //accept the packet
}

//Called when module loaded using 'insmod'
static int init_module()
{
  nfho.hook = hook_func;                       //function to call when conditions below met
  nfho.hooknum = NF_INET_PRE_ROUTING; //called right after packet recieved, first hook in Netfilter
  nfho.pf = INETPROTO_IPV4;                           //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
}

//Called when module unloaded using 'rmmod'
static void cleanup_module()
{
  nf_unregister_hook(&nfho);                     //cleanup – unregister hook
}

module_init(init_module);
module_exit(cleanup_module);



这是 Makefile


ifneq ($(KERNELRELEASE),)                                                                                           
    obj-m += xxxxxx.o   /*对应的.c文件的名称*/
else
PWD := $(shell pwd);
KVER:= $(shell uname -r)
KDIR:=/lib/modules/$(KVER)/build


all:
    $(MAKE) -C $(KDIR) M=$(PWD)
clean:
    rm -rf *.o *.mod.c *.ko 
endif



这样 就可以了。然后编译执行 insmod xxx.ko 就可以了。 先到这里, 改天写一个比较完整的 带用户层管理的例子。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值