Linux netfilter源码分析(2)

转贴自http://alexanderlaw.blog.hexun.com/8968771_d.html

 

二、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"

      }

    }

};

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux IPsec是一种在Linux系统中实现IPsec(Internet协议安全)的技术。IPsec用于保护网络通信的机密性、完整性和真实性。对于问题要求的源码分析,以下是我可以提供的300字回答。 Linux IPsec的主要源码位于内核的网络协议栈中,其实现主要以C语言编写。在分析IPsec源码时,需要关注以下几个关键组件和函数: 1. XFRM框架:XFRM是Linux内核中的IPsec子系统,负责安全策略和转发规则的管理。它的源码位于`net/netfilter/xfrm`目录下。通过分析XFRM的源码,可以了解IPsec中安全策略和变换规则的创建、更新和删除过程,并可以了解与XFRM相关的数据结构和算法。 2. IPSec SA和SP:IPsec安全关联(SA)和安全策略(SP)是IPsec实现的核心概念。SA用于描述两个网络节点之间的安全通信参数,SP用于定义哪些数据包需要进行IPsec保护。在源码中,SA和SP的创建和管理涉及相关数据结构和算法,可以在XFRM源码中找到它们的实现。 3. 加密算法和哈希算法:IPsec中使用的加密和哈希算法在Linux内核中也有实现。可以在`crypto`目录中找到它们的源码分析加密算法和哈希算法的源码可以了解其实现细节和性能特征,并验证其安全性和可靠性。 4. 网络协议栈:IPsec是在网络协议栈中实现的,因此对内核网络协议栈的源码分析也是重要的。网络协议栈的源码位于`net`目录下。可以通过分析协议栈的源码,了解IPsec与其他网络层协议(如IP、TCP和UDP)之间的交互过程,以及数据包的处理流程。 综上所述,分析Linux IPsec的源码需要关注XFRM框架、IPSec SA和SP、加密算法和哈希算法,以及网络协议栈。通过深入研究这些关键组件和函数的源码,可以更好地理解IPsec在Linux系统中的实现原理和工作机制。同时,这也为我们在实际应用中使用和调试IPsec提供了有价值的参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值