266 lines
7.2 KiB
C
Executable File
266 lines
7.2 KiB
C
Executable File
#include "../api/conntrack_api.h"
|
||
|
||
/*
|
||
说明: 测试前提:
|
||
1、之前必须有相应的流经过,而且链接跟踪必须没有老化,否则
|
||
根据五元组是获取不到ct的,获取不到ct,就无法设置ct里的aid
|
||
比如tcp,比如在调用之前要先建立三次握手,只要状态为ESTABLISHED
|
||
则ct不会老化.
|
||
2、根据五元组获取到ct之后,必须有相应的流经过,才会找到
|
||
对应的ct,才能将之前设置的aid查找出来.
|
||
测试步骤
|
||
1、加载conntrack_api.ko
|
||
2、建立tcp三次握手,看状态为ESTABLISHED
|
||
3、test中的设置aid的函数dpi_set_aid_test_tcp放在init中
|
||
在加载模块的时候只运行一次,get_aid_test放在netfilter的钩子
|
||
中,因为这个在将来业务模块调用时会由报文触发
|
||
4、加载test.ko(此处的test为在init函数中只设置一次aid,所以
|
||
如果未设置tcp三次握手,也就是说没有在链接跟踪中记录到
|
||
这个五元组对应的流,则test找不到ct,设置aid失败;
|
||
如果dpi_set_aid_test_tcp放在netfilter的钩子中,由报文触发,
|
||
则加载test.ko和链接跟踪创建的时序就无所谓了)
|
||
|
||
keypoint: 流触发建立链接跟踪和test的加载顺序,如果设置aid
|
||
放在init,只设置一次,那么执行顺序很重要;如果设置aid在netfilter
|
||
钩子中,由报文触发,又不断有这个流经过,则执行顺序无所谓,因为只
|
||
要找到有一次,设置进去就可以了
|
||
|
||
测试的时候可以写个tcp程序,server端一直循环recv,不close fd,
|
||
client端也不close fd,等待终端输入调用send;三次握手创建ct,后续
|
||
查询靠send触发.
|
||
|
||
TCP报文记录链接跟踪的前提是建立三次握手成功,如果单方面打流是
|
||
不行的.但是UDP可以单方面打流来创建ct.
|
||
输入:无
|
||
输出:无
|
||
返回值: 0或-1
|
||
*/
|
||
|
||
|
||
enum test_proto_type{
|
||
TEST_PROTO_TCP,
|
||
TEST_PROTO_UDP,
|
||
};
|
||
|
||
/**********************************************************
|
||
* 函数功能:测试获取应用aid,挂在netfilter的hook上
|
||
* 输入:void *, struct sk_buff *, const struct nf_hook_state *
|
||
* 输出: 无
|
||
* 返回值: 无
|
||
**********************************************************/
|
||
static unsigned int get_aid_test(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
|
||
{
|
||
int ret;
|
||
uint16_t aid;
|
||
printk(KERN_INFO"[test]: test get app_id\n");
|
||
ret = cmhi_get_conntrack_u16(skb, &aid, APP_ID);
|
||
if(ret == CMHI_EXT_ERR){
|
||
printk(KERN_INFO"[test]: get app_id failed\n");
|
||
goto out;
|
||
}
|
||
printk(KERN_INFO"[test]: get app_id: %d successed\n", aid);
|
||
goto out;
|
||
|
||
out:
|
||
return NF_ACCEPT;
|
||
|
||
}
|
||
|
||
/**********************************************************
|
||
* 函数功能:测试根据TCP的DPI五元组获取链接跟踪指针ct
|
||
* 输入: 无
|
||
* 输出: 无
|
||
* 返回值: 0或-1
|
||
**********************************************************/
|
||
int dpi_get_ct_test_tcp(void)
|
||
{
|
||
int ret;
|
||
struct nf_conn *ct;
|
||
struct dpi_tuple dpi_tuple;
|
||
dpi_tuple.sip = htonl(0xc0a840bc);//192.168.64.188
|
||
dpi_tuple.dip = htonl(0xc0a840c2);//192.168.64.194
|
||
dpi_tuple.protonum = IPPROTO_TCP;
|
||
dpi_tuple.sport = htons(179);
|
||
dpi_tuple.dport = htons(10020);
|
||
printk(KERN_INFO"[Test-tcp]dpi_tuple sip=%u, dip=%u, proto=%d, sport=%du, dport=%du\n",
|
||
dpi_tuple.sip, dpi_tuple.dip, dpi_tuple.protonum, dpi_tuple.sport, dpi_tuple.dport);
|
||
ct = get_conntrack_from_tuple(&dpi_tuple);
|
||
if(!ct){
|
||
printk(KERN_ERR"[Test-tcp]get ct failed!!\n");
|
||
ret = CMHI_EXT_ERR;
|
||
}
|
||
else {
|
||
printk(KERN_INFO"[Test-tcp]Find it!!\n");
|
||
ret = CMHI_EXT_OK;
|
||
|
||
}
|
||
goto out;
|
||
|
||
out:
|
||
return ret;
|
||
|
||
}
|
||
|
||
/**********************************************************
|
||
* 函数功能:测试根据UDP的DPI五元组获取链接跟踪指针ct
|
||
* 输入: 无
|
||
* 输出: 无
|
||
* 返回值: 0或-1
|
||
**********************************************************/
|
||
|
||
int dpi_get_ct_test_udp(void)
|
||
{
|
||
int ret;
|
||
struct nf_conn *ct;
|
||
struct dpi_tuple dpi_tuple;
|
||
dpi_tuple.sip = htonl(0xc0a840c7);//192.168.64.199
|
||
dpi_tuple.dip = htonl(0xc0a840c2);//192.168.64.194
|
||
dpi_tuple.protonum = IPPROTO_UDP;
|
||
dpi_tuple.sport = htons(7);
|
||
dpi_tuple.dport = htons(520);
|
||
printk(KERN_INFO"[Test-udp]dpi_tuple sip=%x, dip=%x, proto=%d, sport=%x, dport=%x\n",
|
||
dpi_tuple.sip, dpi_tuple.dip, dpi_tuple.protonum, dpi_tuple.sport, dpi_tuple.dport);
|
||
ct = get_conntrack_from_tuple(&dpi_tuple);
|
||
if(!ct){
|
||
printk(KERN_ERR"[Test-udp]get ct failed!!\n");
|
||
ret = CMHI_EXT_ERR;
|
||
}
|
||
else {
|
||
printk(KERN_INFO"[Test-udp]Find it!!\n");
|
||
ret = CMHI_EXT_OK;
|
||
|
||
}
|
||
goto out;
|
||
|
||
out:
|
||
return ret;
|
||
|
||
}
|
||
|
||
/**********************************************************
|
||
* 函数功能:测试根据TCP的DPI五元组设置链接跟踪ct里的aid
|
||
* 输入: 无
|
||
* 输出: 无
|
||
* 返回值: 0或-1
|
||
**********************************************************/
|
||
int dpi_set_aid_test_tcp(void)
|
||
{
|
||
int ret;
|
||
// uint16_t aid;
|
||
struct dpi dpi;
|
||
dpi.tuple.sip = htonl(0xc0a840bc);//192.168.64.188
|
||
dpi.tuple.dip = htonl(0xc0a840c2);//192.168.64.194
|
||
dpi.tuple.protonum = IPPROTO_TCP;
|
||
dpi.tuple.sport = htons(179);
|
||
dpi.tuple.dport = htons(10020);
|
||
dpi.aid = 3;
|
||
printk(KERN_INFO"[Test]dpi_tuple sip=%x, dip=%x, proto=%d, sport=%du, dport=%du,aid=%d\n",
|
||
dpi.tuple.sip, dpi.tuple.dip, dpi.tuple.protonum, dpi.tuple.sport, dpi.tuple.dport, dpi.aid);
|
||
ret = set_aid_by_dpi_tuple(&dpi);
|
||
if(CMHI_EXT_OK != ret){
|
||
printk(KERN_ERR"[Test]set_aid_by_dpi_tuple failed.\n");
|
||
return CMHI_EXT_ERR;
|
||
}
|
||
return CMHI_EXT_OK;
|
||
}
|
||
|
||
/**********************************************************
|
||
* 函数功能:测试根据UDP的DPI五元组设置链接跟踪ct里的aid
|
||
* 输入: 无
|
||
* 输出: 无
|
||
* 返回值: 0或-1
|
||
**********************************************************/
|
||
int dpi_set_aid_test_udp(void)
|
||
{
|
||
int ret;
|
||
// uint16_t aid;
|
||
struct dpi dpi;
|
||
dpi.tuple.sip = htonl(0xc0a840c7);//192.168.64.199
|
||
dpi.tuple.dip = htonl(0xc0a840c2);//192.168.64.194
|
||
dpi.tuple.protonum = IPPROTO_UDP;
|
||
dpi.tuple.sport = htons(7);
|
||
dpi.tuple.dport = htons(520);
|
||
dpi.aid = 5;
|
||
printk(KERN_INFO"[Test]dpi_set_aid_test_udp: dpi_tuple sip=%x, dip=%x, proto=%d, sport=%d, dport=%d,aid=%d\n",
|
||
dpi.tuple.sip, dpi.tuple.dip, dpi.tuple.protonum, dpi.tuple.sport, dpi.tuple.dport, dpi.aid);
|
||
ret = set_aid_by_dpi_tuple(&dpi);
|
||
if(CMHI_EXT_OK != ret){
|
||
printk(KERN_ERR"[Test]dpi_set_aid_test_udp: set_aid_by_dpi_tuple failed.\n");
|
||
return CMHI_EXT_ERR;
|
||
}
|
||
return CMHI_EXT_OK;
|
||
}
|
||
|
||
|
||
/**********************************************************
|
||
* 函数功能:测试根据协议类型是TCP还是UDP来调用TCP或UDP的设置
|
||
* aid的函数
|
||
* 输入: 协议类型enum test_proto_type
|
||
* 输出: 无
|
||
* 返回值: 无
|
||
**********************************************************/
|
||
void dpi_set_aid_test(enum test_proto_type type)
|
||
{
|
||
if(TEST_PROTO_TCP == type){
|
||
dpi_set_aid_test_tcp();
|
||
}
|
||
else if(TEST_PROTO_UDP == type){
|
||
dpi_set_aid_test_udp();
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
/**********************************************************
|
||
* 函数功能:测试根据协议类型是TCP还是UDP来调用TCP或UDP的获取
|
||
* 链接跟踪指针ct
|
||
* 输入: 协议类型enum test_proto_type
|
||
* 输出: 无
|
||
* 返回值: 无
|
||
**********************************************************/
|
||
void dpi_get_ct_test(enum test_proto_type type)
|
||
{
|
||
if(TEST_PROTO_TCP == type){
|
||
dpi_get_ct_test_tcp();
|
||
}
|
||
else if(TEST_PROTO_UDP == type){
|
||
dpi_get_ct_test_udp();
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
static struct nf_hook_ops nfho[] __read_mostly = {
|
||
//{
|
||
//.hook = (nf_hookfn *)demoB,
|
||
//.hooknum = NF_INET_PRE_ROUTING,
|
||
//.pf = NFPROTO_IPV4,
|
||
//.priority = (NF_IP_PRI_FILTER-1),
|
||
//},
|
||
{
|
||
.hook = (nf_hookfn *)get_aid_test,
|
||
.hooknum = NF_INET_PRE_ROUTING,
|
||
.pf = NFPROTO_IPV4,
|
||
.priority = NF_IP_PRI_FILTER,
|
||
},
|
||
};
|
||
|
||
static int __init test_init(void)
|
||
{
|
||
dpi_set_aid_test(TEST_PROTO_TCP);
|
||
nf_register_net_hooks(&init_net, nfho, ARRAY_SIZE(nfho));
|
||
printk(KERN_INFO"[Test] Module_init\n");
|
||
return 0;
|
||
}
|
||
|
||
static void __exit test_clean(void)
|
||
{
|
||
nf_unregister_net_hooks(&init_net, nfho, ARRAY_SIZE(nfho));
|
||
printk(KERN_INFO"[Test]Module_clean\n");
|
||
return;
|
||
}
|
||
|
||
module_init(test_init);
|
||
module_exit(test_clean);
|
||
MODULE_LICENSE("GPL");
|