Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1560987
  • 博文数量: 61
  • 博客积分: 472
  • 博客等级: 下士
  • 技术积分: 548
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-26 11:52
文章分类
文章存档

2018年(1)

2017年(2)

2016年(6)

2015年(3)

2014年(19)

2013年(10)

2012年(20)

分类: 网络与安全

2012-07-26 17:40:07

二、ipt_table数据结构和表的初始化

 

2.1  include/linux/netfilter_ipv4/ip_tables.h   struct  ipt_table 表结构

struct ipt_table
{
struct list_head list;
/* 
表链 */
char name[IPT_TABLE_MAXNAMELEN];
/* 
表名,如"filter""nat"等,为了满足自动模块加载的设计,包含该表的模块应命名为iptable_'name'.o */
struct ipt_replace *table;
/* 
表模子,初始为initial_table.repl */
unsigned int valid_hooks;
/* 
位向量,标示本表所影响的HOOK */
rwlock_t lock;
/* 
读写锁,初始为打开状态 */
struct ipt_table_info *private;
/* iptable
的数据区,见下 */
struct module *me;
/* 
是否在模块中定义 */
};

 

 

 

2.2  struct ipt_table_info是实际描述表的数据结构 ip_tables.c

struct ipt_table_info
{
unsigned int size;
/* 
表大小 */
unsigned int number;
/* 
表中的规则数 */
unsigned int initial_entries;
/* 
初始的规则数,用于模块计数 */
unsigned int hook_entry[NF_IP_NUMHOOKS];
/* 
记录所影响的HOOK的规则入口相对于下面的entries变量的偏移量 */
unsigned int underflow[NF_IP_NUMHOOKS];
/* 
hook_entry相对应的规则表上限偏移量,当无规则录入时,相应的hook_entryunderflow均为0 */
char entries[0] ____cacheline_aligned;
/* 
规则表入口 */
};

 

2.3   include/linux/netfilter_ipv4  规则用struct ipt_entry结构表示,包含匹配用的IP头部分、一个Target0个或多个Match。由于Match数不定,所以一条规则实际的占用空间是可变的。结构定义如下

 

struct ipt_entry
{
struct ipt_ip ip;
/* 
所要匹配的报文的IP头信息 */
unsigned int nfcache;
/* 
位向量,标示本规则关心报文的什么部分,暂未使用 */
u_int16_t target_offset;
/* target
区的偏移,通常target区位于match区之后,而match区则在ipt_entry的末尾;
初始化为sizeof(struct ipt_entry),即假定没有match */
u_int16_t next_offset;
/* 
下一条规则相对于本规则的偏移,也即本规则所用空间的总和,
初始化为sizeof(struct ipt_entry)+sizeof(struct ipt_target),即没有match */
unsigned int comefrom;
/* 
规则返回点,标记调用本规则的HOOK号,可用于检查规则的有效性 */
struct ipt_counters counters;
/* 
记录该规则处理过的报文数和报文总字节数 */
unsigned char elems[0];
/*target
或者是match的起始位置 */
}

 

 

2.4  iptables的初始化init(void) ,以filter表为例 iptable_filter.c

 

static int __init init(void)

{

       int ret;

 

       if (forward < 0 || forward > NF_MAX_VERDICT) {

              printk("iptables forward must be 0 or 1\n");

              return -EINVAL;

       }

 

       /* Entry 1 is the FORWARD hook */

       initial_table.entries[1].target.verdict = -forward - 1;

 

       /* Register table */

       ret = ipt_register_table(&packet_filter);     //注册filter

       if (ret < 0)

              return ret;

 

       /* Register hooks */

       ret = nf_register_hook(&ipt_ops[0]);       //注册三个HOOK

       if (ret < 0)

              goto cleanup_table;

 

       ret = nf_register_hook(&ipt_ops[1]);

       if (ret < 0)

              goto cleanup_hook0;

 

       ret = nf_register_hook(&ipt_ops[2]);

       if (ret < 0)

              goto cleanup_hook1;

 

       return ret;

 

 cleanup_hook1:

       nf_unregister_hook(&ipt_ops[1]);

 cleanup_hook0:

       nf_unregister_hook(&ipt_ops[0]);

 cleanup_table:

       ipt_unregister_table(&packet_filter);

 

       return ret;

}

 

 

/* ipt_register_table函数的参数packet_filter包含了待注册表的各个参数 */

static struct ipt_table packet_filter = {

       .name            = "filter",

       .table             = &initial_table.repl,

       .valid_hooks  = FILTER_VALID_HOOKS,

       .lock              = RW_LOCK_UNLOCKED,

       .me         = THIS_MODULE

};

 

/* 上面的&initial_table.repl是一个ipt_replace结构,也就是ipt_table-*table的初始值。

下面是ipt_replace结构的定义,它和ipt_table_info很相似,基本上就是用来初始化ipt_table中的ipt_table_info *private的,这个结构不同于ipt_table_info之处在于,它还要保存表的旧的规则信息 */

struct ipt_replace

{

       char name[IPT_TABLE_MAXNAMELEN];   /* 表名 */

       unsigned int valid_hooks;                   /* 影响的hook */

       unsigned int num_entries;                   /* entry */

       unsigned int size;                          /* entry的总大小 */

       unsigned int hook_entry[NF_IP_NUMHOOKS];   /* 规则入口的偏移值 */

       unsigned int underflow[NF_IP_NUMHOOKS];  /* 规则的最大偏移值 */

       unsigned int num_counters;                  /* 规则数 */

       struct ipt_counters __user *counters;           

       struct ipt_entry entries[0];                   /* 规则入口 */

};

 

/* 下面是initial_table.repl的初始化 */

static struct

{

       struct ipt_replace repl;

       struct ipt_standard entries[3];

       struct ipt_error term;

} initial_table __initdata

= { { "filter", FILTER_VALID_HOOKS, 4,

      sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),

      { [NF_IP_LOCAL_IN] = 0,

       [NF_IP_FORWARD] = sizeof(struct ipt_standard),

       [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },

      { [NF_IP_LOCAL_IN] = 0,

       [NF_IP_FORWARD] = sizeof(struct ipt_standard),

       [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },

      0, NULL, { } },

    {

           /* LOCAL_IN */

           { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },

              0,

              sizeof(struct ipt_entry),

              sizeof(struct ipt_standard),

              0, { 0, 0 }, { } },

             { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },

              -NF_ACCEPT - 1 } },

           /* FORWARD */

           { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },

              0,

              sizeof(struct ipt_entry),

              sizeof(struct ipt_standard),

              0, { 0, 0 }, { } },

             { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },

              -NF_ACCEPT - 1 } },

           /* LOCAL_OUT */

           { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },

              0,

              sizeof(struct ipt_entry),

              sizeof(struct ipt_standard),

              0, { 0, 0 }, { } },

             { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },

              -NF_ACCEPT - 1 } }

    },

    /* ERROR */

    { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },

       0,

       sizeof(struct ipt_entry),

       sizeof(struct ipt_error),

       0, { 0, 0 }, { } },

      { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },

         { } },

       "ERROR"

      }

    }

};

 


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