Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103797
  • 博文数量: 18
  • 博客积分: 1425
  • 博客等级: 上尉
  • 技术积分: 236
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-21 20:38
文章分类
文章存档

2011年(6)

2009年(10)

2008年(2)

我的朋友

分类: 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上都对应相同的一套规则

阅读(3701) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~