Netfilter之AF_INET协议族rule、match、target

在笔记Netfilter之table、match、target中,有看到框架对table、match、target的定义,分别是struct xt_table、struct xt_match和struct xt_target。如果要扩展match和target,只需要实现对应的结构,然后将其注册给Netfilter框架即可被用户态程序使用(当然也需要扩展用户态的iptables工具)。

这篇笔记并不是要说明如何定义一个新的target或者match,而是要弄清楚一条规则到底是如何表示的。我们知道,table是用来保存规则的(struct xt_table_info的entries字段),而规则是由0个或者多个match和一个target组成的,虽然框架已经定义了struct xt_match和struct xt_target来表示匹配和target,但是在真正形成规则时,还需要一些额外的信息,而且不同的协议族会有所不同,下面以AF_INET协议族为例,我们来看下rule到底是什么。

1. struct ipt_entry

struct ipt_entry代表了一条规则,其定义如下:

/* This structure defines each of the firewall rules.  Consists of 3
   parts which are 1) general IP header stuff 2) match specific
   stuff 3) the target to perform if the rule matches */
struct ipt_entry
{
	//规则的基本匹配条件,如IP地址等
	struct ipt_ip ip;
	/* Mark with fields that we care about. */
	unsigned int nfcache;
	//这条规则的target距离规则起点的偏移量
	u_int16_t target_offset;
	//下一条规则距离这条规则起点的偏移量
	u_int16_t next_offset;
	/* Back pointer */
	unsigned int comefrom;
	//计数器,每条规则都有计数器,一旦skb匹配这条规则,那么计数器累加,
	//计数器有字节数和包数两个统计量
	struct xt_counters counters;
	//这条规则中的match和target,因为不确定到底有几个match,所以使用零长度数组
	unsigned char elems[0];
};
#define ipt_counters xt_counters
struct xt_counters
{
	u_int64_t pcnt, bcnt;			/* Packet and byte counters */
};

1.1 标准匹配:struct ipt_ip

struct ipt_ip {
	//源IP、目的IP以及对应的掩码,skb和该条件匹配时,比较的是和掩码相与后的结果
	struct in_addr src, dst;
	/* Mask for src and dest IP addr */
	struct in_addr smsk, dmsk;
	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
	/* Protocol, 0 = ANY */
	u_int16_t proto;
	/* Flags word */
	u_int8_t flags;
	/* Inverse flags */
	u_int8_t invflags;
};

从定义中可以看出,标准匹配到底包含哪些内容:源IP/目的IP、输入/输出网卡、协议(可以是任意层次的协议编号)。

2. struct ipt_match_entry

该结构表示了规则中的一个match,定义如下:

#define XT_FUNCTION_MAXNAMELEN 30
#define ipt_entry_match xt_entry_match

struct xt_entry_match
{
	//用户态和内核态使用不同的结构表示match。它们的第一个成员都是match的总大小
	union {
		struct {
			u_int16_t match_size;
			/* Used by userspace */
			char name[XT_FUNCTION_MAXNAMELEN-1];
			u_int8_t revision;
		} user;
		struct {
			u_int16_t match_size;
			//指向扩展的match信息(每一个扩展match都是一个xt_match对象)
			struct xt_match *match;
		} kernel;
		/* Total length */
		u_int16_t match_size;
	} u;
	unsigned char data[0];
};

我们知道,匹配也分为标准匹配和扩展匹配,但是标准匹配的内容使用struct ipt_ip表示的,该成员就在struct ipt_entry中。

3. struct ipt_entry_target

#define ipt_entry_target xt_entry_target
struct xt_entry_target
{
	//和ipt_entry_match的定义非常的类似
	union {
		struct {
			u_int16_t target_size;
			/* Used by userspace */
			char name[XT_FUNCTION_MAXNAMELEN-1];
			u_int8_t revision;
		} user;
		struct {
			u_int16_t target_size;
			//target信息,如果target->target()函数指针为NULL,
			//那么是一个标准target,否则为扩展target
			struct xt_target *target;
		} kernel;
		/* Total length */
		u_int16_t target_size;
	} u;
	//对于扩展target,该指针指向内容会传给其target()回调,这个指针内容由
	//扩展target自由使用,只要内核态和用户态保持一致就可以
	unsigned char data[0];
};

对于标准target,实际上使用struct ipt_standard_target定义的:

#define ipt_standard_target xt_standard_target
struct xt_standard_target
{
	struct xt_entry_target target;
	int verdict;
};

该结构的第一个成员是xt_entry_target,用面向对象中多态的思想来看,ipt_standard_target也是一个ipt_entry_target。处理target时,先判定ipt_entry_target的target指针成员为NULL后,说明这是一个标准target,此时再按照ipt_starndard_target的格式解释该target,具体见规则遍历函数ipt_do_table()的实现。

标准匹配有ACCEPT、DROP、RETURN和跳转到自定义链四种情况。特别注意:REJECT属于扩展target。

3.1 关于标准target的verdict

对于标准target,其verdict取值具有多样性,而且不同的取值代表的含义不同,其对规则的遍历很重要,下面分情况讨论。

  • verdict小于0。这种情况下,表示target是ACCEPT、DROP和RETURN中的一种。
取值含义
-1对应NF_DROP
-2对应NF_ACCEPT
-5对应IPT_RETURN
  • verdict大于等于0。此时表示跳转到自定义链,verdict的值表示自定义链第一条规则距离表第一条规则的偏移量。

4. 其他结构

4.1 struct ipt_standard

#define ipt_standard_target xt_standard_target
struct ipt_standard
{
	struct ipt_entry entry;
	struct ipt_standard_target target;
};

对一条使用标准target的规则的定义。

struct ipt_error

struct ipt_error_target
{
	struct ipt_entry_target target;
	char errorname[IPT_FUNCTION_MAXNAMELEN];
};

struct ipt_error
{
	struct ipt_entry entry;
	struct ipt_error_target target;
};

错误规则在使用标准target的规则的基础上增加了一个错误名字字段。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值