secgateway/Platform/modules/conntrack_api/test/test.c

277 lines
7.6 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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与base_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;
uint16_t base_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);
printk(KERN_INFO"[test]: test get base_app_id\n");
ret = cmhi_get_conntrack_u16(skb, &base_aid, BASE_APP_ID);
if(ret == CMHI_EXT_ERR){
printk(KERN_INFO"[test]: get base_app_id failed\n");
goto out;
}
printk(KERN_INFO"[test]: get base_app_id: %d successed\n", base_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与base_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;
dpi.base_aid = 3;
printk(KERN_INFO"[Test]dpi_tuple sip=%x, dip=%x, proto=%d, sport=%du, dport=%du,aid=%u, base_aid=%u\n",
dpi.tuple.sip, dpi.tuple.dip, dpi.tuple.protonum, dpi.tuple.sport, dpi.tuple.dport, dpi.aid, dpi.base_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与base_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;
dpi.base_aid = 5;
printk(KERN_INFO"[Test]dpi_set_aid_test_udp: dpi_tuple sip=%x, dip=%x, proto=%d, sport=%d, dport=%d,aid=%u, dpi.base_aid=%u\n",
dpi.tuple.sip, dpi.tuple.dip, dpi.tuple.protonum, dpi.tuple.sport, dpi.tuple.dport, dpi.aid, dpi.base_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");