分类: LINUX
2009-09-21 20:29:43
本章所涉及的数据结构均为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为:
/*#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
(1 << NF_INET_FORWARD) | \
(1 << NF_INET_LOCAL_OUT))*/
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 *);
/*一个match具体的执行者,根据是否匹配返回true或这false*/
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 *);
/*每个target的具体执行函数,返回对数据包的最终处理结果*/
其他的数据成员与xt_match的含义相同。
2.4、所有相关数据结构的完成定义
struct xt_entry_match
{
union {
struct {
u_int16_t match_size;//match尺寸
/* Used by userspace */
char name[XT_FUNCTION_MAXNAMELEN-1];//match名称
u_int8_t revision;
} user;
struct {
u_int16_t match_size;//match尺寸
/* Used inside the kernel */
struct xt_match *match;//具体的match
} kernel;
/* Total length */
u_int16_t match_size;//match尺寸
} u;
unsigned char data[0];//match信息,可变数据区
};
struct xt_entry_target
{
union {
struct {
u_int16_t target_size;//target尺寸
/* Used by userspace */
char name[XT_FUNCTION_MAXNAMELEN-1];//target名称
u_int8_t revision;
} user;//用户空间使用的target信息
struct {
u_int16_t target_size;//target尺寸
/* Used inside the kernel */
struct xt_target *target;//具体的target
} kernel;//内核空间使用的targe信息
/* Total length */
u_int16_t target_size;
} u;
unsigned char data[0];//target信息,可变数据区域
};
/*
*由模块扩展出来的match数据结构抽象
*/
struct xt_match
{
struct list_head list;
const char name[XT_FUNCTION_MAXNAMELEN-1];//match的名字
/* Return true or false: return FALSE and set *hotdrop = 1 to
force immediate packet drop. */
/* Arguments changed since 2.6.9, as this must now handle
non-linear skb, using skb_header_pointer and
skb_ip_make_writable. */
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);
/* Called when user tries to insert an entry of this type. */
/* Should return true or false. */
bool (*checkentry)(const char *tablename,
const void *ip,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask);//检验match是否在指定的表中
/* Called when entry of this type deleted. */
void (*destroy)(const struct xt_match *match, void *matchinfo);
/* Called when userspace align differs from kernel space one */
void (*compat_from_user)(void *dst, void *src);
int (*compat_to_user)(void __user *dst, void *src);
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
/* Free to use by each match */
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;
};
/*
*由模块扩展target的数据抽象
*/
struct xt_target
{
struct list_head list;
const char name[XT_FUNCTION_MAXNAMELEN-1];
/* Returns verdict. Argument order changed since 2.6.9, as this
must now handle non-linear skbs, using skb_copy_bits and
skb_ip_make_writable. */
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);
/* Called when user tries to insert an entry of this type:
hook_mask is a bitmask of hooks from which it can be
called. */
/* Should return true or false. */
bool (*checkentry)(const char *tablename,
const void *entry,
const struct xt_target *target,
void *targinfo,
unsigned int hook_mask);
/* Called when entry of this type deleted. */
void (*destroy)(const struct xt_target *target, void *targinfo);
/* Called when userspace align differs from kernel space one */
void (*compat_from_user)(void *dst, void *src);
int (*compat_to_user)(void __user *dst, void *src);
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
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;
/* A unique name... */
char name[XT_TABLE_MAXNAMELEN];//表名
/* What hooks you will enter on */
unsigned int valid_hooks;//表所支持的hook操作
/* Lock for the curtain */
rwlock_t lock;
/* Man behind the curtain... */
//struct ip6t_table_info *private;
void *private;//table的数据区,为ipt_table_info或者ipt6_table_info
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
int af; /* address/protocol family */
};
struct xt_table_info//table真正的数据区
{
/* Size per table */
unsigned int size;
/* Number of entries: FIXME. --RR */
unsigned int number;
/* Initial number of entries. Needed for module usage count */
unsigned int initial_entries;
/* Entry points and underflows */
unsigned int hook_entry[NF_IP_NUMHOOKS];//每类hook对应的规则的入口
unsigned int underflow[NF_IP_NUMHOOKS];
/* ipt_entry tables: one per CPU */
char *entries[NR_CPUS];//每个cpu上都对应相同的一套规则