Linux连接跟踪源码分析报告Word文件下载.docx
- 文档编号:20078480
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:40
- 大小:37.45KB
Linux连接跟踪源码分析报告Word文件下载.docx
《Linux连接跟踪源码分析报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《Linux连接跟踪源码分析报告Word文件下载.docx(40页珍藏版)》请在冰豆网上搜索。
structtimer_listtimeout;
/*所谓“预期的连接”的链表,其中存放的是我们所期望的其它相关连接*/
structlist_headsibling_list;
/*目前的预期连接数量*/
unsignedintexpecting;
/*结构ip_conntrack_expect位于ip_conntrack.h,这个结构用于将一个预期的连接分配给现有的连接,也就是说本连接是这个master的一个预期连接*/
structip_conntrack_expect*master;
/*helper模块。
这个结构定义于ip_conntrack_helper.h,这个模块提供了一个可以用于扩展Conntrack功能的接口。
经过连接跟踪HOOK的每个数据报都将被发给每个已经注册的helper模块(注册以及卸载函数分别为ip_conntrack_helper_register()以及ip_conntrack_helper_unregister(),分别位于ip_conntrack_core.c)。
这样我们就可以进行一些动态的连接管理了*/
structip_conntrack_helper*helper;
/*一系列的nf_ct_info类型(定义于include/linux/skbuff.h,Line92,实际上就是nf_conntrack结构)的结构,每个结构对应于某种状态的连接。
这一系列的结构会被sk_buff结构的nfct指针所引用,描述了所有与此连接有关系的数据报。
其状态由枚举类型ip_conntrack_info定义(位于include/linux/netfilter_ipv4/ip_conntrack.h,Line12)共有5个成员:
IP_CT_ESTABLISHED:
数据报属于已经完全建立的连接
IP_CT_RELATED:
数据报属于一个新的连接,但此连接与一个现有连接相关(预期连接);
或者是ICMP错误
IP_CT_NEW:
数据报属于一个新的连接
IP_CT_IS_REPLY:
数据报属于一个连接的回复
IP_CT_NUMBER:
不同IP_CT类型的数量,这里为7,NEW仅存于一个方向上*/
structnf_ct_infoinfos[IP_CT_NUMBER];
/*为其他模块保留的部分*/
unionip_conntrack_protoproto;
unionip_conntrack_helphelp;
#ifdefCONFIG_IP_NF_NAT_NEEDED
struct{
structip_nat_infoinfo;
unionip_conntrack_nat_helphelp;
#ifdefined(CONFIG_IP_NF_TARGET_MASQUERADE)||\
defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
intmasq_index;
#endif
#ifdefined(CONFIG_IP_NF_RTSP)||defined(CONFIG_IP_NF_RTSP_MODULE)
structip_nat_rtsp_infortsp_info;
}nat;
#endif/*CONFIG_IP_NF_NAT_NEEDED*/
#ifdefined(CONFIG_IP_NF_CONNTRACK_MARK)
unsignedlongmark;
};
structip_conntrack_tuple_hash结构描述链表中的节点,这个数组包含“初始”和“应答”两个成员(tuplehash[IP_CT_DIR_ORIGINAL]和tuplehash[IP_CT_DIR_REPLY]),所以,当一个数据包进入连接跟踪模块后,先根据这个数据包的套接字对转换成一个“初始的”tuple,赋值给tuplehash[IP_CT_DIR_ORIGINAL],然后对这个数据包“取反”,计算出“应答”的tuple,赋值给tuplehash[IP_CT_DIR_REPLY],这样,一条完整的连接已经跃然纸上了。
enumip_conntrack_dir
IP_CT_DIR_ORIGINAL,
IP_CT_DIR_REPLY,
IP_CT_DIR_MAX
2.连接跟踪表
Netfilter用“来源地址/来源端口+目的地址/目的端口”,即一个“tuple”,来唯一标识一个连接。
用一张连接跟踪表来描述所有的连接状态,该表用了hash算法。
hash表用一个全局指针来描述(ip_conntrack_core.c)
structlist_head*ip_conntrack_hash;
表的大小,即hash节点的个数由ip_conntrack_htable_size全局变量决定,默认是根据内存计算出来的。
而每个hash节点又是一条链表的首部,所以,连接跟踪表就是一个由ip_conntrack_htable_size条链表构成的一个hash表,整个连接跟踪表大小使用全局变量ip_conntrack_max描述,与hash表的关系是ip_conntrack_max=8*ip_conntrack_htable_size。
链表的每个节点,都是一个ip_conntrack_tuple_hash结构:
structip_conntrack_tuple_hash
/*用来组织链表*/
structlist_headlist;
/*用来描述一个tuple*/
structip_conntrack_tupletuple;
/*this==&
ctrack->
tuplehash[DIRECTION(this)].*/
structip_conntrack*ctrack;
实际描述一个tuple的是ip_conntrack_tuple结构ip_conntrack_tuple.h
structip_conntrack_tuple
/*源*/
structip_conntrack_manipsrc;
/*Thesearethepartsofthetuplewhicharefixed.*/
/*目的地址*/
u_int32_tip;
union{
/*Addotherprotocolshere.*/
u_int64_tall;
struct{
u_int16_tport;
}tcp;
}udp;
u_int8_ttype,code;
}icmp;
u_int16_tprotocol;
u_int8_tversion;
u_int32_tkey;
}gre;
u_int16_tspi;
}esp;
}u;
/*协议类型*/
u_int16_tprotonum;
}dst;
对于所有IP协议,协议类型、源地址、目的地址这三个参数是识别连接所必须的,具体到各个协议,就要提取出各协议的唯一特征数据,如TCP、UDP的源端口、目的端口,ICMP的ID、TYPE、CODE等值,这些值就是tuple结构要处理的数据。
各协议相关数据是以联合(union)形式定义在tuple结构中的,netfilter缺省支持TCP、UDP和ICMP协议,如果还要支持其他IP协议,如GRE、ESP、AH、SCTP等,需要在联合中添加相应的协议参数值。
ip_conntrack_manip和ip_conntrack_manip_protoip_conntrack_tuple.h
structip_conntrack_manip
u_int32_tip;
unionip_conntrack_manip_protou;
unionip_conntrack_manip_proto
/*Addotherprotocolshere.*/
u_int32_tall;
u_int16_tport;
}tcp;
}udp;
u_int16_tid;
}icmp;
u_int32_tkey;
}gre;
Netfilter将每一个数据包转换成tuple,再根据tuple计算出hash值,这样,就可以使用ip_conntrack_hash[hash_id]找到hash表中链表的入口,并组织链表;
找到hash表中链表入口后,如果链表中不存在此“tuple”,则是一个新连接,就把tuple插入到链表的合适位置;
两个节点tuple[ORIGINAL]和tuple[REPLY]虽然是分开的,在两个链表当中,但是如前所述,它们同时又被封装在ip_conntrack结构的tuplehash数组中
3.
连接跟踪初始化
初始化函数init()调用init_or_cleanup
(1)函数ip_conntrack_standalone.c
staticint__initinit(void)
returninit_or_cleanup
(1);
}
3.1init_or_cleanup()函数
intinit_or_cleanup函数,(ip_conntrack_standalone.c)参数为1则执行init,为0则执行clean,它主要做三件工作:
1.
调用ip_conntrack_init()初始化连接跟踪表的相关变量,见3.2
2.
初始化proc文件系统节点
3.
为连接跟踪注册hook
staticintinit_or_cleanup(intinit)
structproc_dir_entry*proc;
intret=0;
if(!
init)gotocleanup;
/*初始化连接跟踪的一些变量和数据结构,如连接跟踪表的大小,Hash表的大小等*/
ret=ip_conntrack_init();
if(ret<
0)
gotocleanup_nothing;
/*初始化proc文件系统*/
proc=proc_net_create("
ip_conntrack"
0440,list_conntracks);
ip_clear_dnsconntrack"
0644,clear_dns_conntracks);
proc)gotocleanup_init;
proc->
owner=THIS_MODULE;
/*为连接跟踪注册hook,一共六个,所在的hook点、注册的hook函数和优先级分别如下(和最开始的图是一致的):
NF_IP_PRE_ROUTING:
ip_conntrack_defragNF_IP_PRI_CONNTRACK_DEFRAG
ip_conntrack_inNF_IP_PRI_CONNTRACK
NF_IP_LOCAL_OUT:
ip_conntrack_localNF_IP_PRI_CONNTRACK
NF_IP_POST_ROUTING:
ip_refragNF_IP_PRI_LAST
NF_IP_LOCAL_IN:
ip_confirmNF_IP_PRI_LAST-1
优先级的顺序为:
NF_IP_PRI_FIRST(最高)
NF_IP_PRI_CONNTRACK_DEFRAG
NF_IP_PRI_CONNTRACK
NF_IP_PRI_MANGLE
NF_IP_PRI_NAT_DST
NF_IP_PRI_FILTER
NF_IP_PRI_NAT_SRC
NF_IP_PRI_LAST(最低)
我们知道,LOCAL_OUT和PRE_ROUTING点可以看作是netfilter的入口,而POST_ROUTING和LOCAL_IN可以看作是出口。
也就是说,在每个数据包刚一进入netfilter之后首先都会调用ip_conntrack_defrag做分片处理,紧接着就是对收到的和发出的数据包分别进行ip_conntrack_in和ip_conntrack_loacl(ip_conntrack_loacl里还是调用了ip_conntrack_in)。
而在数据包即将离开netfilter之前,会对进入主机的数据包进行ip_confirm处理,对发出的数据包进行ip_refrag处理(ip_refrag里也会调用ip_confirm)。
这就是整个连接跟踪模块在netfilter中的分布情况。
另外,我们分析的是2.6.8的内核,在linux2.6.12中,这个地方还增加了两个hook,分别是ip_conntrack_helper_out_ops和ip_conntrack_helper_in_ops。
将helper模块相关的处理提前了。
*/
ret=nf_register_hook(&
ip_conntrack_defrag_ops);
0){
printk("
ip_conntrack:
can'
tregisterpre-routingdefraghook.\n"
);
gotocleanup_proc;
}
ip_conntrack_defrag_local_out_ops);
tregisterlocal_outdefraghook.\n"
gotocleanup_defragops;
ip_conntrack_in_ops);
tregisterpre-routinghook.\n"
gotocleanup_defraglocalops;
ip_conntrack_local_out_ops);
tregisterlocalouthook.\n"
gotocleanup_inops;
ip_conntrack_out_ops);
tregisterpost-routinghook.\n"
gotocleanup_inandlocalops;
ip_conntrack_local_in_ops);
tregisterlocalinhook.\n"
gotocleanup_inoutandlocalops;
#ifdefCONFIG_SYSCTL
ip_ct_sysctl_header=register_sysctl_table(ip_ct_net_table,0);
if(ip_ct_sysctl_header==NULL){
tregistertosysctl.\n"
gotocleanup;
returnret;
cleanup:
unregister_sysctl_table(ip_ct_sysctl_header);
nf_unregister_hook(&
cleanup_inoutandlocalops:
cleanup_inandlocalops:
cleanup_inops:
cleanup_defraglocalops:
cleanup_defragops:
cleanup_proc:
proc_net_remove("
cleanup_init:
ip_conntrack_cleanup();
cleanup_nothing:
3.2ip_conntrack_init()函数
ip_conntrack_init函数(ip_conntrack_core.c)用于初始化连接跟踪的包括hash表相关参数在内一些重要的变量:
int__initip_conntrack_init(void)
unsignedinti;
intret;
/*Ideafromtcp.c:
use1/16384ofmemory.Oni386:
32MB
*machinehas256buckets.>
=1GBmachineshave8192buckets.*/
/*如果指定hash表的大小则用制定值,否则根据内存计算*/
if(hashsize){
ip_conntrack_htable_size=hashsize;
}else{
ip_conntrack_htable_size
=(((num_physpages<
<
PAGE_SHIFT)/16384)
/sizeof(structlist_head));
if(num_physpages>
(1024*1024*1024/PAGE_SIZE))
ip_conntrack_htable_size=8192;
if(ip_conntrack_htable_size<
16)
ip_conntrack_htable_size=16;
ip_conntrack_max=8*ip_conntrack_htable_size;
#ifdefCONFIG_MIPS_BRCM
ip_conntrack_max=0;
printk("
ip_conntrackversion%s(%ubuckets,%dmax)"
"
-%Zdbytesperconntrack\n"
IP_CONNTRACK_VERSION,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 连接 跟踪 源码 分析 报告