分类: LINUX
2010-04-17 12:31:38
由于目的地址为S_L:80,所以当数据包传递给上层时,会被路由到G_L所
在端口。
然后进入挂钩点:
,。
于图1.进入,,再进入,
同
样进入:
ret = (, , , , );
于是:
enum
= ();
=0,即maniptype=,
同
样,由于连接状态没有改变:
case :
/* Seen it before? This can happen for loopback, retrans,
or local packets.. */
if (!(ct, )) {
unsigned int ;
if ( == )
/*
LOCAL_IN hook doesn't have a chain! */
ret
= (ct, );
else
ret
= (, , , ,
ct);
if (ret != ) {
return ret;
}
因
为刚才初始化的是,所以会
进入if语句,再进入nf_nat_rule_find;
同
样会:
ret
= (, , , , ->.);
由于不存在一个SNAT的target所
以,直接返回。
然后执行到:
if (!(ct, ()))
/*
NUL mapping */
ret
= (ct, );
}
进
入到alloc_null_binding,分配一个null的bind;
unsigned int
(struct *ct, unsigned int )
{
/* Force range to this IP; let proto
decide
mapping for
per-proto parts (hence not
IP_NAT_RANGE_PROTO_SPECIFIED).
Use reply in case it's already been mangled
(eg local packet).
*/
=
(() ==
? ct->[]....
: ct->[]....);
struct
=
{ , , , { 0 }, { 0 } };
("Allocating
NULL binding for %p (%pI4)\n",
ct,
&);
return
(ct, &, ());
}
由于ct->[]....=C_W,所以:
range={ ,C_W,C_W,{0},{0}}
然后进入了nf_nat_setup_info;
int = !(ct-> & );
由于之前设置了,所以
得到have_to_hash=0;
(&curr_tuple,
&ct->[].);
curr_tuple=:
src:
C_W:xx
dst:
S_L:80
然后:
(&, &curr_tuple, , ct, );
-----
-- - >
进而调用:
(, , ct, );
这个参数tuple就是curr_tuple;
if
( == )
= &->..;
* = ->;
执行完后curr_tuple木有改变。
curr_tuple:
src:C_W:xx
dst:S_L:80
所以,回到中,
if (!(&, &curr_tuple))
不会得以执行。
最后
(, &ct->);
。
回到nf_nat_fn
进入
return (ct, ctinfo, , );
enum = ();
enum = ();
dir为ORIG,mtype为SRC。
所以:
if
( == )
statusbit
= ;
ct->status没有设置了
& statusbit)不会得以执行。
然后结束执行。
钩子执行完毕。
于是进入,
调用
return
();
if
( && != &) {
if (!() && !())
= ();
然后,在__nf_conntrack_confirm中:
hlist_nulls_del_rcu(&ct->[].);
hash
= (&ct->[].);
repl_hash
= (&ct->[].);
(ct, hash, repl_hash);
将skb中保存的ct->tuplehash分
别添加到net->ct.hash,完成confirmed;
(, &ct->);
ctinfo
ct->status
, ,
ct->tuplehash[IP_CT_DIR_ORIGNAL].tuple=
src:C_W:xx
dst:G_W:80
ct->tuplehash[IP_CT_DIR_REPLY].tuple=
src:S_L:80
dst:C_W:xx