分类: LINUX
2010-04-17 12:32:45
当S_L收到数据包后,返回以下分组:
src: S_L:80
dst: C_W:xx
到达G_L所在端口,然后进入钩子PREROUTING.
进入钩子函数:
return (dev_net(), , , );
进入到nf_conntrack_in
ct = (net, , , , protonum,
l3proto, l4proto, &, &ctinfo);
然后
if (!nf_ct_get_tuple(, (),
, , protonum, &, l3proto,
l4proto))
tuple=
src:
S_L:80
dst: C_W:xx
h
= nf_conntrack_find_get(net, &);
由于上次在ipv4_confirm时,已经把ct
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
添加到了net->ct.hash中,所以,h不为null.
且:tuple==
ct->tuplehash[IP_CT_DIR_REPLY].tuple,所以:
if ((h) == ) {
*ctinfo = + ;
/*
Please set reply bit if this packet OK */
* = 1;
然后执行:
-> = &ct->;
-> = *ctinfo;
之后回到nf_conntrack_in:
执行完成udp_packet后
进入
if ( && !(, &ct->))
于是ct->status
ctinfo +
之后再次进入nf_nat_in
同样
ret
= (, , , , );
然后:
return (ct, ctinfo, , );
由于是reply包enum = ();=REPLY
enum = ();=DST
所以;
statusbit = ;
if (dir == )
statusbit ^= ;
因为=1<<5, =1<<4; = ( | ),并且statusbit=IPS_DST_NAT,所以相^结果为;
由前可知,ct->status为DNAT,所以不会进入:
/* Non-atomic: these bits don't change. */
408 if (ct-> & statusbit)
返回到nf_nat_in.至此执行完毕。
目的ip为 dst: C_W:xx,所以数据包传送到G_W接口。
进入POSTROUTING钩子。
同样
ret = (, , , , );
又会进入:
return (ct, ctinfo, , );
394 enum
= ();=REPLY
396 enum
= ();=SRC
if ( == )
statusbit = ;
if (dir == )
statusbit ^= ;
因为=1<<5, =1<<4; = ( | ),并且statusbit=IPS_SRC_NAT,所以相^结果为;如前所述,ct->status设置成IPS_DST_NAT位,
于是进入:
/* Non-atomic: these bits don't change. */
408 if
(ct-> & statusbit) {
409 struct ;
410
411 /* We are aiming to
look like inverse of other direction. */
412 (&target, &ct->[!dir].);
413
414 if (!(target.., , 0, &target, ))
415 return ;
416 }
target=invert(ct->tuplehash[orig].tuple);
src:G_W:80
dst:C_W:xx
进入manip_pkt;
378 if
( == ) {
379 (&->, ->, target->..);
380 -> = target->..;
381 } else
{
于是ip数据包变成:
src:G_W:80
dst:C_W:xx
nf_nat_out执行结束:
数据包已经confirm。