分类: LINUX
2013-03-06 22:48:27
本章所涉及的数据结构均为Netfilter框架中的核心数据结构,不与具体的规则相联系,同时为了保证分析的完整性,本章以ipv4的相关规则定义为基础,对框架的核心数据结构的关系进行完整的分析,ipv6,arp,netbriget与此类似。
2.1、xt_table及xt_table_info
xt_table是Netfilter中的核心数据结构,它包含了每个表的所有规则信息,数据包进入Netfilter后通过查表,匹配相应的规则来决定对数据包的处理结果。其成员布局如下图所示:
图2.1 xt_table结构布局
每个成员的含义如下:
unsigned int
valid_hooks//所有支持的hook点操作,例如filter表有三处设置了hook操作,则对应的//valid_hooks为:
struct
xt_table_info *private //xt_table的数据区,下面详细介绍
struct module
*me;//如果是个模型设置成THIS_MODULE,否则为NULL
u_int8_t af //地址/协议族
const char
name[XT_TABLE_MAXNAMELEN];//表的名字
xt_table的所有数据都存在private的成员变量中,private是结构体struct
xt_table_info,它的布局如下图所示,每个规则后面会跟随一个target,及对匹配的数据包的处理方式:
图2.2
xt_table_info结构体布局
每个成员的含义如下:
unsigned int size //每个表的尺寸
unsigned int
number //表中存了多少规则
unsigned int initial_entries
//表中存放的初始规则数,用于模型计数
unsigned int
hook_entry[NF_INET_NUMHOOKS]//不同hook点规则的偏移
void
*entries[1];//具体的规则存储在这里,这个成员包含了具体的规则信息
entries本质上是一个ipt_standard结构体,ipt_standard中包含了具体的规则及处理方法,ipt_standard的结构定义为:
struct
ipt_standard
{
struct ipt_entry entry;
struct ipt_standard_target
target;
};
2.2、entry相关数据结构
ipt_entry的结构体的布局如下:
图2.3
ipt_match及xt_match布局
每个成员的含义如下:
struct ipt_ip ip //源和目的IP地址
u_int16_t
target_offset //target的偏移量,其值为ipt_entry + match的尺寸值
u_int16_t next_offset
//下一个match的偏移量,其值为ipt_entry + matches + target的尺寸
struct xt_counters counters
//记录数据包(packet)和字节(byte)的数目
unsigned char
elems[0];可变数据区域,存放具体的match
在ipt_entry中,每个elmes本质上是一个xt_entry_match,它包含了一个xt_match和xt_match的执行函数所需要的参数。
一个具体的match的布局如上图所示的xt_match,它的各个成员的含义如下:
const
char name[XT_FUNCTION_MAXNAMELEN-1]//每个match的名字
u_int8_t revision;
//修订的版本号
bool (*match)(const struct sk_buff *skb, const struct xt_match_param
*);
const char *table //这个match所属的表的名字
unsigned int
hooks;//match在哪个hook注册
unsigned short proto;//协议号
unsigned short
family//地址族
struct module *me//模型,同xt_table
2.3、target数据结构
图2.4
xt_target及相关结构布局
ipt_standard的另一个成员是xt_standard_target,这个结构体包含了两个类别的target即:标准的target和扩展的target,xt_standard_target的结构定义如下:
struct
xt_standard_target
{
struct xt_entry_target
target;
int
verdict;
};
其中xt_entry_target包含了一个具体可扩展的target,它包含了两个主要的数据成员,u存储了一个具体的结构体xt_target,xt_target的布局如上图所示,data存放了,xt_target的执行函数所需要的参数信息。xt_target每个成员的具体含义如下:
const
char name[XT_FUNCTION_MAXNAMELEN-1]//target的名称
unsigned int (*target)(struct
sk_buff *skb, const struct xt_target_param
*);
其他的数据成员与xt_match的含义相同。
2.4、所有相关数据结构的完成定义
struct
xt_entry_match
{
union {
struct {
u_int16_t match_size;//match尺寸
char
name[XT_FUNCTION_MAXNAMELEN-1];//match名称
u_int8_t revision;
} user;
struct {
u_int16_t
match_size;//match尺寸
struct
xt_match *match;//具体的match
}
kernel;
u_int16_t match_size;//match尺寸
}
u;
unsigned char
data[0];//match信息,可变数据区
};
struct xt_entry_target
{
union {
struct {
u_int16_t
target_size;//target尺寸
char
name[XT_FUNCTION_MAXNAMELEN-1];//target名称
u_int8_t revision;
} user;//用户空间使用的target信息
struct
{
u_int16_t
target_size;//target尺寸
struct
xt_target *target;//具体的target
}
kernel;//内核空间使用的targe信息
u_int16_t
target_size;
} u;
unsigned char
data[0];//target信息,可变数据区域
};
struct xt_match
{
struct list_head list;
const char
name[XT_FUNCTION_MAXNAMELEN-1];//match的名字
bool (*match)(const struct
sk_buff *skb,//一个match的真正执行者
const struct net_device
*in,
const struct net_device *out,
const struct xt_match
*match,
const void *matchinfo,
int offset,
unsigned int
protoff,
bool *hotdrop);
bool (*checkentry)(const char
*tablename,
const void *ip,
const struct xt_match
*match,
void *matchinfo,
unsigned int hook_mask);//检验match是否在指定的表中
void (*destroy)(const struct xt_match *match, void
*matchinfo);
void
(*compat_from_user)(void *dst, void *src);
int
(*compat_to_user)(void __user *dst, void *src);
struct module *me;
unsigned long data;
char
*table;//表名
unsigned int matchsize;
unsigned int compatsize;
unsigned int
hooks;//hook类型
unsigned short proto;
unsigned short family;//协议族
u_int8_t
revision;
};
struct xt_target
{
struct
list_head list;
const char
name[XT_FUNCTION_MAXNAMELEN-1];
unsigned int (*target)(struct sk_buff *skb,
const struct net_device *in,
const struct
net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void
*targinfo);
bool (*checkentry)(const char *tablename,
const void
*entry,
const struct xt_target *target,
void *targinfo,
unsigned int
hook_mask);
void
(*destroy)(const struct xt_target *target, void *targinfo);
void (*compat_from_user)(void *dst, void
*src);
int (*compat_to_user)(void __user *dst, void
*src);
struct module
*me;
char *table;
unsigned int
targetsize;
unsigned int compatsize;
unsigned int hooks;
unsigned short
proto;
unsigned short family;
u_int8_t revision;
};
struct
xt_table
{
struct list_head list;
char
name[XT_TABLE_MAXNAMELEN];//表名
unsigned int valid_hooks;//表所支持的hook操作
rwlock_t lock;
//struct ip6t_table_info *private;
void
*private;//table的数据区,为ipt_table_info或者ipt6_table_info
struct module *me;
int
af;
};
struct
xt_table_info//table真正的数据区
{
unsigned int size;
unsigned int number;
unsigned int initial_entries;
unsigned int
hook_entry[NF_IP_NUMHOOKS];//每类hook对应的规则的入口
unsigned int
underflow[NF_IP_NUMHOOKS];
char
*entries[NR_CPUS];//每个cpu上都对应相同的一套规则