本文对netfilter中NAT部分的源码进行分析,读者需要先对NAT的基本概念有一个大致了解。
1. NAT模块的初始化
NAT模块的初始化过程主要是初始化一些全局变量以及注册NAT相关的hook函数。在下面nf_nat_init()函数和nf_nat_standalone_init()函数的流程图中用红色标记了要初始化的全局数据结构。
nf_nat_init()函数:nf_nat_standalone_init()函数:
NAT表是一个xt_table,定义如下:
static struct xt_table nat_table = {
.name = "nat",
.valid_hooks = NAT_VALID_HOOKS,
.me = THIS_MODULE,
.af = AF_INET,
};
iptables的表如filter, nat,mangle表都是通过ipt_register_table()注册的,在netfilter中被使用。我们需要知道iptables的表中的每条规则都包括三部分:
entry:规则的入口,同时做一些匹配数据包的工作。
match:匹配数据包的条件大多放在这里。
target:对于符合条件的数据包要执行的动作放在这里。
NAT表中的每条规则就包括上面三个部分。
注册NAT表时传入的第三个参数nat_initial_table定义如下:
static struct
{
struct ipt_replace repl;
struct ipt_standard entries[3];
struct ipt_error term;
} nat_initial_table __net_initdata = {
.repl = {
.name = "nat",
.valid_hooks = NAT_VALID_HOOKS,
.num_entries = 4,
.size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
.hook_entry = {
[NF_INET_PRE_ROUTING] = 0,
[NF_INET_POST_ROUTING] = sizeof(struct ipt_standard),
[NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
},
.underflow = {
[NF_INET_PRE_ROUTING] = 0,
[NF_INET_POST_ROUTING] = sizeof(struct ipt_standard),
[NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard