2018年(21)
分类: LINUX
2018-09-19 15:48:48
1、连接跟踪是根据报文的L3,L4层头信息来标识一条连接的。我们先来看一下具体根据哪些信息来标识的。
数据结构
这个是非常重要的一个数据结构,整个连接跟踪的查找,建立,关联,更新都是依据该结构体的。该结构体包含了用来标识一条连接的全部信息,我们这里把这些信息称为元组。
/include/net/netfilter/nf_conntrack_tuple.h
struct nf_conntrack_tuple
{
struct nf_conntrack_man src; //源端信息
//目的端信息。
/* These are the parts of the tuple which are fixed. */
struct {
union nf_inet_addr u3; //目的IP地址
//目的端口的信息,不同协议使用不同的报文字段
union {
/* Add other protocols here. */
__be16 all;
struct {
__be16 port;//TCP报文就使用目的端口
} tcp;
struct {
__be16 port;//UDP报文就使用目的端口
} udp;
struct {
u_int8_t type, code;//ICMPP报文使用type,cod两个字段
} icmp;
。。。。。。。 //其他协议此处省略
} u;
//传输层协议类型,既L4协议类型
u_int8_t protonum;
//标识连接的方向,一条连接分两个方向,一来一回
/* The direction (for tuplehash) */
u_int8_t dir;
} dst;
};
struct nf_conntrack_man
{
union nf_inet_addr u3; //IP地址
//L4协议源端信息
union nf_conntrack_man_proto u;
//L3协议类型
u_int16_t l3num;
};
//L4层源端的信息。
union nf_conntrack_man_proto
{
/* Add other protocols here. */
__be16 all;
struct {
__be16 port;
} tcp;
struct {
__be16 port;
} udp;
struct {
__be16 id;
} icmp;
。。。。。。//其他协议此处省略
};
从上面数据结构定义看,标识一条连接的元组为:
TCP 源IP,源端口,L3协议类型,目的IP,目的端口号,L4协议类型
UDP 源IP,源端口,L3协议类型,目的IP,目的端口号,L4协议类型
ICMP 源IP,L3协议类型,目的IP,id,type,code,,L4协议类型
其他协议这里就不介绍了。我也不熟
二、conntrack的定义
一个连接包含正反两个方向的两条报文流。
struct nf_conn {
//对连接的引用计数
struct nf_conntrack ct_general;
spinlock_t lock;
//正向和反向的连接元组信息。
struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
//该连接的连接状态
unsigned long status;
//如果该连接是期望连接,指向跟其关联的主连接
struct nf_conn *master;
//连接垃圾回收定时器
struct timer_list timeout;
/*存储特定协议的连接跟踪信息*/
union nf_conntrack_proto proto;
/*指向扩展结构,该结构中包含一些基于连接的功能扩展处理函数 */
struct nf_ct_ext *ext;
//网络命名空间
struct net *ct_net;
};
struct nf_conntrack_tuple_hash {
struct hlist_nulls_node hnnode;
struct nf_conntrack_tuple tuple;
};
每个struct nf_conn实例代表一个连接。每个skb都有一个指针,指向和它相关联的连接。
struct sk_buff {
struct nf_conntrack *nfct;//指向struct nf_conn实例
kmemcheck_bitfield_begin(flags1);
__u8 local_df:1,
cloned:1,
ip_summed:2,
nohdr:1,
nfctinfo:3; //记录报文的连接状态。
kmemcheck_bitfield_end(flags1);
};
/include/net/netns/conntrack.h
每个网络命名空间有如下一个数据结构的实例,来管理和存放生成的连接的一些信息。
struct netns_ct
{
atomic_t count;
unsigned int expect_count;
unsigned int htable_size;
struct kmem_cache *nf_conntrack_cachep;
struct hlist_nulls_head *hash;//存放已经经过确认的连接hash表
struct hlist_head *expect_hash;//期望连接hash表
struct hlist_nulls_head unconfirmed; //存放没经过确认的连接hash表
struct hlist_nulls_head dying;
struct ip_conntrack_stat *stat;
int hash_vmalloc;
int expect_vmalloc;
char *slabname;
};
(未完待续)