读取本地json配置文件,可以进行SNAT的IP替换;DNAT暂未测试;未进行回归测试;

This commit is contained in:
liuyang
2018-12-17 08:13:46 +08:00
parent f62fc44b70
commit dba56c9e4b
14 changed files with 881 additions and 111 deletions

View File

@@ -1,6 +1,6 @@
CC = g++
CFLAGS = -g -Wall -fPIC
OBJECTS = kni_entry.o kni_comm.o kni_intercept.o kni_ratelimit.o kni_replace.o cJSON.o kni_sendlog.o
OBJECTS = kni_entry.o kni_comm.o kni_intercept.o kni_ratelimit.o kni_replace.o cJSON.o kni_sendlog.o kni_redirect.o
TARGET = kni.so
INCS = -I./
@@ -27,6 +27,7 @@ kni_ratelimit.o:kni_ratelimit.c
kni_replace.o:kni_replace.c
cJSON.o:cJSON.c
kni_sendlog.o:kni_sendlog.c
kni_redirect.o:kni_redirect.c
clean:
rm -f $(TARGET) $(OBJECTS)

View File

@@ -1,3 +1,60 @@
[main]
######0:intercept;1:bypass
default_work_mode=1
######0:not replay;1:replay
replay_win_update=1
######0:G 1:two network card
sendpkt_mode=0
#####0:not join pkts in listq;1:join pkts in listq
write_listqueue_switch=0
#####0:join fds in listq;1:not join fds in listq
send_fds_mode=0
ratelimit_switch=1
replace_switch=1
domain_path=/home/server_unixsocket_file
socketopt_mark=101
logger_level=10
logger_filepath=./log/kni.log
[tun]
tun_path=/dev/net/tun
tun_name=tun0
[field_stat]
filestat2_filename=./log/kni_fs2.log
filestat2_sip=0.0.0.0
filestat2_sport=0
[dynmic_maat]
#0:iris;1:json;2:redis
dyn_maat_readconf_mode=1
dyn_redis_server=10.3.34.1
dyn_redis_port=6379
dyn_redis_db_index=5
dyn_scandir_interval=1000
dyn_effect_interval=60000
dyn_stat_file_path=./log/kni_dyn_maat_stat
dyn_table_info_path=./kniconf/maat_table_info.conf
[static_maat]
#0:iris;1:json;2:redis
maat_readconf_mode=1
redis_server=10.3.34.1
redis_port=6379
redis_db_index=4
scandir_interval=1000
effect_interval=1000
stat_file_path=./log/kni_static_maat_stat
table_info_path=./kniconf/maat_table_info.conf
full_cfg_dir=/home/mesasoft/tango_rules/full/index
inc_cfg_dir=/home/mesasoft/tango_rules/inc/index
[Module]
table_info_path=./kniconf/maat_table_info.conf
full_cfg_dir=/home/mesasoft/tango_rules/full/index
@@ -23,3 +80,6 @@ dyn_maat_readconf_mode=1
dyn_redis_server=192.168.11.243
dyn_redis_port=6379
dyn_redis_db_index=5
write_listqueue_switch=0
send_fds_mode=1

View File

@@ -1,12 +1,13 @@
1 WHITE_LIST_COMPILE compile GBK GBK no 0
1 PXY_INTERCEPT_COMPILE compile GBK GBK no 0
2 WHITE_LIST_GROUP group GBK GBK no 0
2 PXY_INTERCEPT_GROUP group GBK GBK no 0
3 WHITE_LIST_IP ip GBK GBK no 0
3 PXY_INTERCEPT_IP ip GBK GBK no 0
1 WHITE_LIST_COMPILE compile escape --
1 PXY_INTERCEPT_COMPILE compile escape --
2 WHITE_LIST_GROUP group --
2 PXY_INTERCEPT_GROUP group --
3 WHITE_LIST_IP ip --
3 PXY_INTERCEPT_IP ip --
4 WHITE_LIST_DOMAIN expr GBK GBK yes 0
4 PXY_INTERCEPT_DOMAIN expr GBK GBK yes 0
5 PXY_INTERCEPT_PKT_BIN expr GBK GBK yes 0
6 IPD_DYN_COMPILE compile GBK GBK no 0
6 IPD_DYN_COMPILE compile GBK GBK no 0
7 IPD_DYN_GROUP group GBK GBK no 0
8 IPD_RELATED_DOMAIN expr GBK GBK yes 0
9 PXY_OBJ_SPOOFING_IP_POOL plugin {"key":11,"valid":9} --

View File

@@ -1,26 +1,26 @@
{
"compile_table": "WHITE_LIST_COMPILE",
"group_table": "WHITE_LIST_GROUP",
"compile_table": "PXY_INTERCEPT_COMPILE",
"group_table": "PXY_INTERCEPT_GROUP",
"rules": [
{
"compile_id": 1,
"service": 1,
"action":123,
"action":48,
"do_blacklist": 1,
"do_log": 1,
"effective_rage": 0,
"user_region": "anything",
"user_region": "spoofing_ip_pool=10;nat_type=snat;",
"is_valid": "yes",
"groups": [
{
"group_name": "group_1",
"group_name": "Untitled",
"regions": [
{
"table_name": "WHITE_LIST_IP",
"table_name": "PXY_INTERCEPT_IP",
"table_type": "ip",
"table_content": {
"addr_type": "ipv4",
"src_ip": "192.168.11.119",
"src_ip": "192.168.11.80",
"mask_src_ip": "255.255.255.255",
"src_port": "0",
"mask_src_port": "65535",
@@ -35,33 +35,14 @@
]
}
]
},
{
"compile_id": 2,
"service": 48,
"action": 123,
"do_blacklist": 1,
"do_log": 1,
"effective_rage": 0,
"user_region": "anything",
"is_valid": "yes",
"groups": [
{
"group_name": "group_2",
"regions": [
{
"table_name": "WHITE_LIST_DOMAIN",
"table_type": "string",
"table_content": {
"keywords": "www.baidu.com",
"expr_type": "regex",
"match_method": "sub",
"format":"uncase plain"
}
}
]
}
]
}
]
}
],
"plugin_table": [
{
"table_name": "PXY_OBJ_SPOOFING_IP_POOL",
"table_content": [
"1\t4\t0\t192.168.11.127\t0\t0\t\t0\t0\t1\t123\t10\t{}\t20181217-0:22"
]
}
]
}

View File

@@ -14,54 +14,6 @@
#include "kni_comm.h"
/*
const char *g_kni_fs2_name[FS2_COLUMN_NUM] =
{
"TCPALL",
"UDP",
"IP",
"WHITE_IP",
"WHITE_DOMAIN",
"INTERCEPT",
"RATELIMIT",
"REPLACE",
"HTTP",
"SSL",
"NOT_PROC",
"TUN_WRITE",
"TUN_READ",
"SEND_MARSIO",
"CLIENT_HELLO",
"SSL_SNI(P)",
"D_IPV6_OPT",
"D_NOT_HTABLE",
"D_NOT_IPV4/6_S",
"D_NOT_IPV4/6_T",
"D_E_ADDHTABLE",
"D_OTHER",
"REPR_TOTAL",
"REPR_E_SOCK",
"REPR_E_SET",
"REPR_E_QIN",
"REPR_E_QOUT",
"REPR_SND",
"REPR_E_SND",
"PKT_QIN",
"PKT_E_QIN",
"PKT_QOUT",
"PKT_E_QOUT",
"PKT_WR",
"PKT_E_WR",
"LINK_OPENED",
"LINK_CLS_TO",
"LINK_CLS_FIN",
"LINK_CLS_DROPME",
"PME_NUM",
"WINPROB_REPLY",
"HTABLE_ADD",
"HTABLE_DEL"
};
*/
char* kni_memncasemem(const char *strsrc,int len1,const char *substr,int len2)
{
@@ -509,12 +461,6 @@ int kni_filestate2_init()
FS_set_para(g_kni_fs2_info.handler, STATS_SERVER_IP, fs2_sip, strlen(fs2_sip)+1);
FS_set_para(g_kni_fs2_info.handler, STATS_SERVER_PORT,&fs2_sport,sizeof(int));
}
/*
for(i=0;i<FS2_COLUMN_NUM;i++)
{
g_kni_fs2_info.column_id[i]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,g_kni_fs2_name[i]);
}
*/
g_kni_fs2_info.field_id[FS_PENDING]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_pending");
@@ -528,6 +474,8 @@ int kni_filestate2_init()
g_kni_fs2_info.field_id[FS_NOT_HTTP_SSL]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_not_identify");
g_kni_fs2_info.field_id[FS_WHITELIST]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_whitelist");
g_kni_fs2_info.field_id[FS_INTERCEPT]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_intercept");
g_kni_fs2_info.field_id[FS_REDIRECT]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_redirect");
g_kni_fs2_info.field_id[FS_REDIRECT_REPLY]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_redirect_reply");
g_kni_fs2_info.field_id[FS_RATELIMIT]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_ratelimit");
g_kni_fs2_info.field_id[FS_NOT_HIT]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_not_hit");
g_kni_fs2_info.field_id[FS_RATELIMIT_UDP]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"ratelimit_udp_pkt");
@@ -624,6 +572,10 @@ int kni_order_action(int old_action,int new_action)
{
return KNI_ACTION_MONITOR;
}
else if((old_action == KNI_ACTION_REDIRECT) || (new_action == KNI_ACTION_REDIRECT))
{
return KNI_ACTION_REDIRECT;
}
else if((old_action == KNI_ACTION_REPLACE) || (new_action == KNI_ACTION_REPLACE))
{
return KNI_ACTION_REPLACE;

View File

@@ -24,6 +24,8 @@ enum kni_FS_COLUME
FS_WHITELIST,
FS_INTERCEPT,
FS_RATELIMIT,
FS_REDIRECT,
FS_REDIRECT_REPLY,
FS_NOT_HIT,
FS_RATELIMIT_UDP,
FS_REPLACE_UDP,

View File

@@ -12,7 +12,8 @@
int g_kni_version_VERSION_20181211;
int g_kni_version_VERSION_20181217;
struct kni_var_comm g_kni_comminfo;
struct kni_var_struct g_kni_structinfo;
@@ -702,6 +703,19 @@ char kni_pending_opstate(const struct streaminfo* pstream,struct kni_pme_info* p
kni_filestate2_set(thread_seq,FS_WHITELIST,0,1);
return ret;
}
//add kni_action_redirect 20181216 start
else if(pmeinfo->action == KNI_ACTION_REDIRECT)
{
ret = process_redirect_pending(pstream,pmeinfo,thread_seq,a_packet,protocol,pstream->routedir);
return ret;
}
else if(redirect_search_htable(pstream->addr.addrtype,pmeinfo,thread_seq,a_packet,protocol) == 1)
{
ret = process_redirect_data(pstream,pmeinfo,thread_seq,a_packet,protocol,pstream->routedir);
return ret;
}
//end
pmeinfo->protocol=KNI_FLAG_UNKNOW;
@@ -766,6 +780,14 @@ char kni_data_opstate(const struct streaminfo* pstream,struct kni_pme_info* pmei
struct kni_ipv6_hdr* ipv6_hdr = NULL;
struct kni_tcp_hdr* tcphdr=NULL;
//add kni_action_redirect 20181216 start
if(pmeinfo->action == KNI_ACTION_REDIRECT)
{
ret = process_redirect_data(pstream,pmeinfo,thread_seq,a_packet,protocol,pstream->routedir);
return ret;
}
//end
data=kni_get_payload(pstream,&datalen);
if(pstream->addr.addrtype==ADDR_TYPE_IPV4)
@@ -860,6 +882,15 @@ char kni_close_opstate(const struct streaminfo* pstream,struct kni_pme_info* pme
int htable_ret = 0;
//add kni_action_redirect 20181216 start
if(pmeinfo->action == KNI_ACTION_REDIRECT)
{
ret = process_redirect_close(pstream,pmeinfo,thread_seq,a_packet,protocol,pstream->routedir);
return ret;
}
//end
if(a_packet==NULL)
{
if(pmeinfo->action == KNI_ACTION_MONITOR)
@@ -885,6 +916,7 @@ char kni_close_opstate(const struct streaminfo* pstream,struct kni_pme_info* pme
{
kni_htable_del(pstream,a_packet);
}
return ret|APP_STATE_DROPME;
}
@@ -1501,12 +1533,25 @@ int init_kni_static_maat_info()
g_kni_maatinfo.tableid_ip=Maat_table_register(g_kni_maatinfo.maat_feather,KNI_TABLENAME_IP);
g_kni_maatinfo.tableid_domain=Maat_table_register(g_kni_maatinfo.maat_feather,KNI_TABLENAME_DOMAIN);
g_kni_maatinfo.tableid_pktbin=Maat_table_register(g_kni_maatinfo.maat_feather,KNI_TABLENAME_PKTBIN);
if((g_kni_maatinfo.tableid_ip<0)||(g_kni_maatinfo.tableid_domain<0)||(g_kni_maatinfo.tableid_pktbin<0))
g_kni_maatinfo.tableid_spoofing_ip=Maat_table_register(g_kni_maatinfo.maat_feather,KNI_TABLENAME_SPOOFING_IP);
if((g_kni_maatinfo.tableid_ip<0)||(g_kni_maatinfo.tableid_domain<0)||(g_kni_maatinfo.tableid_pktbin<0)||(g_kni_maatinfo.tableid_spoofing_ip<0))
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"Maat_table_register() error!ip_tableid:%d,sni_tableid:%d,action:%s",g_kni_maatinfo.tableid_ip,g_kni_maatinfo.tableid_domain,KNI_ACTION_EXIT);
return -1;
}
ret=Maat_plugin_EX_register(g_kni_maatinfo.maat_feather, g_kni_maatinfo.tableid_spoofing_ip,
plugin_EX_new_cb,
plugin_EX_free_cb,
plugin_EX_dup_cb,
NULL,
0,NULL);
if(ret < 0)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"Maat_plugin_EX_register() error!");
return -1;
}
return 0;
}
@@ -1637,6 +1682,8 @@ extern "C" char kni_init()
}
kni_init_redirect_htable();
if(init_kni_tun() < 0)
{
return -1;

View File

@@ -13,6 +13,8 @@
#include "kni_intercept.h"
#include "kni_ratelimit.h"
#include "kni_utils.h"
#include "kni_redirect.h"
#ifndef TH_FIN
@@ -94,6 +96,7 @@
//maat
#define KNI_ACTION_NONE 0x00
#define KNI_ACTION_MONITOR 0x01
#define KNI_ACTION_REDIRECT 0X30
#define KNI_ACTION_RATELIMIT 0x40
#define KNI_ACTION_REPLACE 0x50
#define KNI_ACTION_WHITELIST 0x80
@@ -104,6 +107,7 @@
#define KNI_TABLENAME_IP "WHITE_LIST_IP"
#define KNI_TABLENAME_DOMAIN "WHITE_LIST_DOMAIN"
#define KNI_TABLENAME_PKTBIN "PXY_INTERCEPT_PKT_BIN"
#define KNI_TABLENAME_SPOOFING_IP "PXY_OBJ_SPOOFING_IP_POOL"
#define KNI_TABLENAME_DNY_DOMAIN "IPD_RELATED_DOMAIN"
@@ -285,6 +289,7 @@ struct kni_var_struct
{
MESA_htable_handle htable_to_tun_v4;
MESA_htable_handle htable_to_tun_v6;
MESA_htable_handle htable_redirect;
MESA_lqueue_head lqueue_send_fds;
MESA_lqueue_head lqueue_write_tun[KNI_MAX_THREADNUM];
};
@@ -298,6 +303,7 @@ struct kni_var_maat
short tableid_area;
short tableid_domain;
short tableid_pktbin;
short tableid_spoofing_ip;
short tableid_dynamic_domain;
};
@@ -363,8 +369,11 @@ struct kni_pme_info
char service_defined[KNI_SERVICE_LEN]; //for replace and ratelimited
struct Maat_rule_t maat_result[KNI_MAX_SAMENUM];
struct kni_ratelimit_info ratelimit_info;
struct redirect_htable_data redirect_info;
struct kni_tcpopt_info tcpopt_info[KNI_DIR_DOUBLE]; //for monitor,tcp repair
struct kni_wndpro_reply_info lastpkt_info[KNI_DIR_DOUBLE]; //for monitor,reply windows update
void* redirect_htable_key;
int redirect_key_len;
};
//htable_data_info ipv4

View File

@@ -1,6 +1,8 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include "kni_entry.h"
#include "kni_sendlog.h"
#include "kni_ratelimit.h"
@@ -106,7 +108,7 @@ char kni_process_ratelimit(int thread_seq,const struct streaminfo* pstream,const
sendlog_msg.result = pmeinfo->maat_result;
sendlog_msg.result_num = pmeinfo->maat_result_num;
kni_send_log(&sendlog_msg);
kni_send_log(&sendlog_msg,NULL,NULL);
kni_log_debug(RLOG_LV_INFO,(char*)"RATELIMIT",a_packet,(char*)"config_id:%d,molecule:%d,denominator:%d",pmeinfo->cfg_id,ratelimit_info->molecule,ratelimit_info->denominator);
}

638
kni_redirect.c Normal file
View File

@@ -0,0 +1,638 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <arpa/inet.h>
#include "stream.h"
#include "Maat_rule.h"
#include "kni_redirect.h"
#include "kni_sendlog.h"
#include "kni_entry.h"
#include "kni_comm.h"
extern "C" int sendpacket_do_checksum(unsigned char* buf,int protocol,int len);
long redirect_htable_search_cb(void* data,const unsigned char* key,unsigned int size,void* user_arg)
{
long result=0;
if(data!=NULL)
{
memcpy(user_arg,data,sizeof(struct redirect_htable_data));
result = 1;
}
return result;
}
//only snat_replay_pending or dnat_replay_pending call this function
//1:exit;0:not exit -1:error
int redirect_search_htable(unsigned char addr_type,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol)
{
struct ip* ipv4_hdr = NULL;
struct kni_ipv6_hdr* ipv6_hdr = NULL;
struct kni_tcp_hdr* tcphdr=NULL;
long result = 0;
struct stream_tuple4_v4 htable_key_v4;
struct stream_tuple4_v6 htable_key_v6;
if(addr_type==ADDR_TYPE_IPV4)
{
ipv4_hdr = (struct ip*)a_packet;
tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
htable_key_v4.saddr=(ipv4_hdr->ip_src).s_addr;
htable_key_v4.daddr=(ipv4_hdr->ip_dst).s_addr;
htable_key_v4.source=tcphdr->th_sport;
htable_key_v4.dest=tcphdr->th_dport;
MESA_htable_search_cb(g_kni_structinfo.htable_redirect,(unsigned char*)&htable_key_v4,sizeof(htable_key_v4),redirect_htable_search_cb,(void*)&(pmeinfo->redirect_info),&result);
}
else if(addr_type==ADDR_TYPE_IPV6)
{
ipv6_hdr = (struct kni_ipv6_hdr*)a_packet;
tcphdr =(struct kni_tcp_hdr*)( (unsigned char*)a_packet + sizeof(struct kni_ipv6_hdr));
memcpy(htable_key_v6.saddr,&(ipv6_hdr->ip6_src),sizeof(htable_key_v6.saddr));
memcpy(htable_key_v6.daddr,&(ipv6_hdr->ip6_dst),sizeof(htable_key_v6.daddr));
htable_key_v6.source=tcphdr->th_sport;
htable_key_v6.dest=tcphdr->th_dport;
MESA_htable_search_cb(g_kni_structinfo.htable_redirect,(unsigned char*)&htable_key_v6,sizeof(htable_key_v6),redirect_htable_search_cb,(void*)&(pmeinfo->redirect_info),&result);
}
if(result == 1)
{
pmeinfo->action=KNI_ACTION_REDIRECT;
kni_log_debug(RLOG_LV_DEBUG,(char*)"redirect",a_packet,"redirect_search_htable()");
kni_filestate2_set(thread_seq,FS_REDIRECT_REPLY,0,1);
}
return result;
}
int redirect_add_htable(unsigned char addr_type,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol)
{
int ret =0;
struct ip* ipv4_hdr = NULL;
struct kni_ipv6_hdr* ipv6_hdr = NULL;
struct kni_tcp_hdr* tcphdr=NULL;
struct stream_tuple4_v4 htable_key_v4;
struct stream_tuple4_v6 htable_key_v6;
struct redirect_htable_data* htable_data=(struct redirect_htable_data*)malloc(sizeof(struct redirect_htable_data));
memset(htable_data,0,sizeof(struct redirect_htable_data));
htable_data->addr_type=addr_type;
if(addr_type==4)
{
ipv4_hdr = (struct ip*)a_packet;
tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
if(pmeinfo->redirect_info.nat_type == REDIRECT_SNAT_TYPE)
{
htable_data->nat_type=REDIRECT_SNAT_REPLAY;
htable_data->ipv4=(ipv4_hdr->ip_src).s_addr;
htable_key_v4.saddr=(ipv4_hdr->ip_dst).s_addr;
htable_key_v4.daddr=pmeinfo->redirect_info.ipv4;
htable_key_v4.source=tcphdr->th_dport;
htable_key_v4.dest=tcphdr->th_sport;
}
else if(pmeinfo->redirect_info.nat_type == REDIRECT_DNAT_TYPE)
{
htable_data->nat_type=REDIRECT_DNAT_REPLAY;
htable_data->ipv4=(ipv4_hdr->ip_dst).s_addr;
htable_key_v4.saddr=pmeinfo->redirect_info.ipv4;
htable_key_v4.daddr=(ipv4_hdr->ip_src).s_addr;
htable_key_v4.source=tcphdr->th_dport;
htable_key_v4.dest=tcphdr->th_sport;
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"redirect","redirect_add_htable err,nat_type:%d",pmeinfo->redirect_info.nat_type);
return -1;
}
pmeinfo->redirect_key_len=sizeof(htable_key_v4);
pmeinfo->redirect_htable_key=(char*)malloc(pmeinfo->redirect_key_len);
memcpy(pmeinfo->redirect_htable_key,&htable_key_v4,pmeinfo->redirect_key_len);
ret = MESA_htable_add(g_kni_structinfo.htable_redirect,(unsigned char*)pmeinfo->redirect_htable_key,pmeinfo->redirect_key_len,(const void *)htable_data);
kni_log_debug(RLOG_LV_DEBUG,(char*)"redirect_htable_add",a_packet,"key:%u,%d,%u,%d,data:%u",
htable_key_v4.saddr,htable_key_v4.source,htable_key_v4.daddr,htable_key_v4.dest,htable_data->ipv4);
}
else if(addr_type==6)
{
ipv6_hdr = (struct kni_ipv6_hdr*)a_packet;
tcphdr =(struct kni_tcp_hdr*)( (unsigned char*)a_packet + sizeof(struct kni_ipv6_hdr));
if(pmeinfo->redirect_info.nat_type == REDIRECT_SNAT_TYPE)
{
htable_data->nat_type=REDIRECT_SNAT_REPLAY;
memcpy(htable_data->ipv6,&(ipv6_hdr->ip6_src),sizeof(htable_data->ipv6));
memcpy(htable_key_v6.saddr,&(ipv6_hdr->ip6_dst),sizeof(htable_key_v6.saddr));
memcpy(htable_key_v6.daddr,pmeinfo->redirect_info.ipv6,sizeof(htable_key_v6.daddr));
htable_key_v6.source=tcphdr->th_dport;
htable_key_v6.dest=tcphdr->th_sport;
}
else if(pmeinfo->redirect_info.nat_type == REDIRECT_DNAT_TYPE)
{
htable_data->nat_type=REDIRECT_DNAT_REPLAY;
memcpy(htable_data->ipv6,&(ipv6_hdr->ip6_dst),sizeof(htable_data->ipv6));
memcpy(htable_key_v6.saddr,pmeinfo->redirect_info.ipv6,sizeof(htable_key_v6.saddr));
memcpy(htable_key_v6.daddr,&(ipv6_hdr->ip6_src),sizeof(htable_key_v6.daddr));
htable_key_v6.source=tcphdr->th_dport;
htable_key_v6.dest=tcphdr->th_sport;
htable_key_v4.saddr=pmeinfo->redirect_info.ipv4;
htable_key_v4.daddr=(ipv4_hdr->ip_src).s_addr;
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"redirect","redirect_add_htable err,nat_type:%d",pmeinfo->redirect_info.nat_type);
return -1;
}
pmeinfo->redirect_key_len=sizeof(htable_key_v6);
pmeinfo->redirect_htable_key=(char*)malloc(pmeinfo->redirect_key_len);
memcpy(pmeinfo->redirect_htable_key,&htable_key_v6,pmeinfo->redirect_key_len);
ret = MESA_htable_add(g_kni_structinfo.htable_redirect,(unsigned char*)pmeinfo->redirect_htable_key,pmeinfo->redirect_key_len,(const void *)htable_data);
}
return ret;
}
void redirect_free_htable_data(void* data)
{
if(data != NULL)
{
free(data);
}
data=NULL;
return;
}
int redirect_del_htable(void* htable_key,int key_len)
{
MESA_htable_del(g_kni_structinfo.htable_redirect,(const unsigned char*)htable_key,key_len,redirect_free_htable_data);
return 0;
}
/*
int redirect_get_service_define(char* service_defined,int ser_def_len,struct redirect_serdef_info* out)
{
int ip_pool_len =0;
int nat_type_len = 0;
char* ip_pool = NULL;
char* nat_type = NULL;
// char* tmp = NULL;
ip_pool = kni_memncasemem(service_defined, ser_def_len,(char*)"spoofing_ip_pool=", strlen("spoofing_ip_pool="));
if(ip_pool == NULL)
{
return -1;
}
ip_pool += 1;
ip_pool_len = strlen(ip_pool);
nat_type = kni_memncasemem(ip_pool,ip_pool_len,(char*)"nat_type=", strlen("nat_type="));
if(nat_type == NULL)
{
return -1;
}
nat_type += 1;
nat_type_len = strlen(nat_type);
out->ip_pool_len= nat_type - ip_pool -1;
assert((int)sizeof(out->ip_pool)>=out->ip_pool_len);
memcpy(out->ip_pool,ip_pool,out->ip_pool_len);
out->nat_type_len= nat_type_len-1;
assert((int)sizeof(out->nat_type)>=out->nat_type_len);
memcpy(out->nat_type,nat_type,out->nat_type_len);
return 0;
}
*/
int redirect_get_service_define(char* service_defined,int ser_def_len,struct redirect_serdef_info* out)
{
int ip_pool_len =0;
int nat_type_len = 0;
char* ip_pool = NULL;
char* nat_type = NULL;
char* tmp = NULL;
ip_pool = kni_memncasemem(service_defined, ser_def_len,(char*)"=", strlen("="));
if(ip_pool == NULL)
{
return -1;
}
ip_pool += 1;
ip_pool_len = strlen(ip_pool);
nat_type = kni_memncasemem(ip_pool,ip_pool_len,(char*)"=", strlen("="));
if(nat_type == NULL)
{
return -1;
}
nat_type += 1;
nat_type_len = strlen(nat_type);
tmp = kni_memncasemem(ip_pool, ip_pool_len,(char*)";", strlen(";"));
if(ip_pool == NULL)
{
return -1;
}
out->ip_pool_len= tmp-ip_pool;
assert((int)sizeof(out->ip_pool)>=out->ip_pool_len);
memcpy(out->ip_pool,ip_pool,out->ip_pool_len);
out->nat_type_len= nat_type_len-1;
assert((int)sizeof(out->nat_type)>=out->nat_type_len);
memcpy(out->nat_type,nat_type,out->nat_type_len);
return 0;
}
void plugin_EX_new_cb(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp)
{
struct redirect_plugin_ex_data* add_data = (struct redirect_plugin_ex_data*)calloc(sizeof(struct redirect_plugin_ex_data), 1);
int policy_group=0;
int id,protocol,direction,location,is_valid,service,ret;
char port[REDIRECT_SERDEF_LEN];
char user_region[REDIRECT_SERDEF_LEN];
char effective_range[REDIRECT_SERDEF_LEN];
char op_time[REDIRECT_SERDEF_LEN];
ret=sscanf(table_line, "%d\t%d\t%d\t%s\t%s\t%d\t%s\t%d\t%d\t%d\t%d\t%s\t%s",
&id,&(add_data->addr_type),&protocol,add_data->spoofing_ip,port,&direction,user_region,&location,&is_valid,&service,&policy_group,effective_range,op_time);
if(ret < 0)
{
*ad=NULL;
return ;
}
*ad=add_data;
return;
}
void plugin_EX_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp)
{
struct redirect_plugin_ex_data* free_data=(struct redirect_plugin_ex_data*)(*ad);
free(free_data);
*ad=NULL;
return ;
}
void plugin_EX_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA *to, MAAT_PLUGIN_EX_DATA *from, long argl, void *argp)
{
struct redirect_plugin_ex_data* dup_data=(struct redirect_plugin_ex_data*)malloc(sizeof(struct redirect_plugin_ex_data));
memcpy(dup_data,*from,sizeof(struct redirect_plugin_ex_data));
*to=dup_data;
return;
}
int redirect_sendpkt_v4(int protocol,unsigned char dir,int thread_seq,struct ip* a_packet,struct redirect_htable_data* sendpkt_args)
{
int ret = 0;
unsigned short sendbuf_len = ntohs(a_packet->ip_len);
struct ip* iphdr_sendbuf = NULL;
char* sendbuf = (char*)malloc(sendbuf_len);
memcpy(sendbuf,(char*)a_packet,sendbuf_len);
iphdr_sendbuf=(struct ip*)sendbuf;
if((sendpkt_args->nat_type == REDIRECT_SNAT_TYPE)||(sendpkt_args->nat_type == REDIRECT_DNAT_REPLAY))
{
iphdr_sendbuf->ip_src.s_addr=sendpkt_args->ipv4;
}
else
{
iphdr_sendbuf->ip_dst.s_addr=sendpkt_args->ipv4;
}
if(protocol == PROTO_TYPE_TCP)
{
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_TCP,(sendbuf_len-4*(a_packet->ip_hl)));
}
else if(protocol == PROTO_TYPE_UDP)
{
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_UDP,(sendbuf_len-4*(a_packet->ip_hl)));
}
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_IP,sizeof(struct ip));
MESA_sendpacket_iplayer(thread_seq,sendbuf,sendbuf_len,dir);
free(sendbuf);
sendbuf = NULL;
return ret;
}
int redirect_sendpkt_v6(int protocol,unsigned char dir,int thread_seq,struct kni_ipv6_hdr* ipv6_hdr,struct redirect_htable_data* sendpkt_args)
{
struct kni_ipv6_hdr* ipv6_hdr_sendbuf=NULL;
int sendbuf_len = ntohs(ipv6_hdr->ip6_payload_len) + sizeof(struct kni_ipv6_hdr);
char* sendbuf = (char*)malloc(sendbuf_len);
memcpy(sendbuf,ipv6_hdr,sendbuf_len);
ipv6_hdr_sendbuf = (struct kni_ipv6_hdr*)sendbuf;
if((sendpkt_args->nat_type == REDIRECT_SNAT_TYPE)||(sendpkt_args->nat_type == REDIRECT_DNAT_REPLAY))
{
memcpy(&(ipv6_hdr_sendbuf->ip6_src),sendpkt_args->ipv6,sizeof(ipv6_hdr_sendbuf->ip6_src));
}
else
{
memcpy(&(ipv6_hdr_sendbuf->ip6_dst),sendpkt_args->ipv6,sizeof(ipv6_hdr_sendbuf->ip6_dst));
}
if(protocol == PROTO_TYPE_TCP)
{
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_TCP,ntohs(ipv6_hdr->ip6_payload_len));
}
else if(protocol == PROTO_TYPE_UDP)
{
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_UDP,ntohs(ipv6_hdr->ip6_payload_len));
}
// sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_IP,sizeof(struct ip));
MESA_sendpacket_iplayer(thread_seq,sendbuf,sendbuf_len,dir);
free(sendbuf);
sendbuf = NULL;
return 0;
}
int redirect_sendlog(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,struct redirect_plugin_ex_data* dup_data,const void* a_packet)
{
struct kni_log log_msg;
struct ip* ipv4_hdr = (struct ip*)a_packet;
struct kni_ipv6_hdr* ipv6_hdr = (struct kni_ipv6_hdr*)a_packet;
char content[1024]={0};
char orginal_ip[INET6_ADDRSTRLEN]={0};
if(pmeinfo->redirect_info.nat_type ==REDIRECT_SNAT_TYPE)
{
if(dup_data->addr_type == 4)
{
inet_ntop(AF_INET, (void *)&((ipv4_hdr->ip_src).s_addr), orginal_ip, INET_ADDRSTRLEN);
}
else
{
inet_ntop(AF_INET, (void *)&(ipv6_hdr->ip6_src), orginal_ip, INET6_ADDRSTRLEN);
}
}
else if(pmeinfo->redirect_info.nat_type ==REDIRECT_DNAT_TYPE)
{
if(dup_data->addr_type == 4)
{
inet_ntop(AF_INET, (void *)&((ipv4_hdr->ip_dst).s_addr), orginal_ip, INET_ADDRSTRLEN);
}
else
{
inet_ntop(AF_INET, (void *)&(ipv6_hdr->ip6_dst), orginal_ip, INET6_ADDRSTRLEN);
}
}
sprintf(content,"%s->%s",orginal_ip,dup_data->spoofing_ip);
log_msg.stream = pstream;
log_msg.result = pmeinfo->maat_result;
log_msg.result_num = pmeinfo->maat_result_num;
kni_send_log(&log_msg,(char*)"redirect",content);
kni_log_debug(RLOG_LV_DEBUG,(char*)"redirect",a_packet,"process_redirect_pending(),%s",content);
kni_filestate2_set(thread_seq,FS_REDIRECT,0,1);
return 0;
}
char process_redirect_pending(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir)
{
char ret=APP_STATE_FAWPKT|APP_STATE_DROPME;
int result=0;
struct in_addr ipv4_addr;
struct in6_addr ipv6_addr;
struct redirect_plugin_ex_data* dup_data=NULL;
struct redirect_serdef_info redirect_args;
memset(&redirect_args,0,sizeof(redirect_args));
//get service_defined
// result=sscanf(pmeinfo->service_defined,"spoofing_ip_pool=%s;nat_type=%s",redirect_args.ip_pool,redirect_args.nat_type);
result=redirect_get_service_define(pmeinfo->service_defined,pmeinfo->ser_def_len,&redirect_args);
if(result < 0)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","redirect_get_service_define() error,cfg_id:%d,service_def:%s",pmeinfo->cfg_id,pmeinfo->service_defined);
return ret;
}
//get dup_data
dup_data=(struct redirect_plugin_ex_data*)Maat_plugin_get_EX_data(g_kni_maatinfo.maat_feather,g_kni_maatinfo.tableid_spoofing_ip,redirect_args.ip_pool);
if(dup_data == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","Maat_plugin_get_EX_data() get NULL,key:%s!",redirect_args.ip_pool);
return ret;
}
//set pmeinfo->redirect_info
if(memcmp(redirect_args.nat_type,"snat",strlen("snat")) == 0)
{
pmeinfo->redirect_info.nat_type=REDIRECT_SNAT_TYPE;
}
else if(memcmp(redirect_args.nat_type,"dnat",strlen("dnat")) == 0)
{
pmeinfo->redirect_info.nat_type=REDIRECT_DNAT_TYPE;
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","nat_type:%s,error!",redirect_args.nat_type);
return ret;
}
pmeinfo->redirect_info.addr_type=dup_data->addr_type;
if(pmeinfo->redirect_info.addr_type == 4)
{
inet_pton(AF_INET,dup_data->spoofing_ip,&ipv4_addr);
pmeinfo->redirect_info.ipv4 = ipv4_addr.s_addr;
redirect_sendpkt_v4(protocol,dir,thread_seq,(struct ip*)a_packet,&(pmeinfo->redirect_info));
}
else if(pmeinfo->redirect_info.addr_type == 6)
{
inet_pton(AF_INET6,dup_data->spoofing_ip,&ipv6_addr);
memcpy(pmeinfo->redirect_info.ipv6 ,&(ipv6_addr),sizeof(pmeinfo->redirect_info.ipv6));
redirect_sendpkt_v6(protocol,dir,thread_seq,(struct kni_ipv6_hdr*)a_packet,&pmeinfo->redirect_info);
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","addr_type:%d,error!",pmeinfo->redirect_info.addr_type);
return ret;
}
//send_log
redirect_sendlog(pstream,pmeinfo,thread_seq,dup_data,a_packet);
//add htable
result=redirect_add_htable(pmeinfo->redirect_info.addr_type,pmeinfo,thread_seq,a_packet,protocol);
if(result < 0)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","redirect_add_htable() error,ret:%d",result);
return ret;
}
return APP_STATE_GIVEME|APP_STATE_DROPPKT;
}
char process_redirect_data(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir)
{
char ret=APP_STATE_GIVEME|APP_STATE_DROPPKT;
if(pmeinfo->redirect_info.addr_type==4)
{
redirect_sendpkt_v4(protocol,dir,thread_seq,(struct ip*)a_packet,&pmeinfo->redirect_info);
}
else if(pmeinfo->redirect_info.addr_type==6)
{
redirect_sendpkt_v6(protocol,dir,thread_seq,(struct kni_ipv6_hdr*)a_packet,&pmeinfo->redirect_info);
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","process_redirect_data() error,addr_type:%d",pmeinfo->redirect_info.addr_type);
return APP_STATE_DROPPKT|APP_STATE_DROPME;
}
return ret;
}
char process_redirect_close(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir)
{
char ret=APP_STATE_GIVEME|APP_STATE_DROPPKT;
if(a_packet != NULL)
{
process_redirect_data(pstream,pmeinfo,thread_seq,a_packet,protocol,dir);
}
redirect_del_htable(pmeinfo->redirect_htable_key,pmeinfo->redirect_key_len);
free(pmeinfo->redirect_htable_key);
pmeinfo->redirect_htable_key=NULL;
return ret;
}
int kni_init_redirect_htable()
{
MESA_htable_create_args_t hash_frags;
memset(&hash_frags,0,sizeof(hash_frags));
hash_frags.thread_safe=KNI_THREAD_SAFE;
hash_frags.recursive=1;
hash_frags.hash_slot_size=KNI_HTABLE_SIZE;
hash_frags.max_elem_num=KNI_HTABLE_MAXNUM;
hash_frags.eliminate_type=HASH_ELIMINATE_ALGO_FIFO;
hash_frags.expire_time=0;
hash_frags.key_comp=NULL;
hash_frags.key2index=NULL;
hash_frags.data_free=NULL;
hash_frags.data_expire_with_condition=NULL;
g_kni_structinfo.htable_redirect=MESA_htable_create(&hash_frags,sizeof(MESA_htable_create_args_t));
if(g_kni_structinfo.htable_redirect==NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"htable_redirect MESA_htable_create() error!");
return -1;
}
return 0;
}

58
kni_redirect.h Normal file
View File

@@ -0,0 +1,58 @@
#ifndef KNI_REDIRECT_H
#define KNI_REDIRECT_H
#ifndef IPV6_ADDR_LEN
#define IPV6_ADDR_LEN (sizeof(struct in6_addr))
#endif
#define REDIRECT_SERDEF_LEN 16
#define REDIRECT_SNAT_TYPE 1
#define REDIRECT_DNAT_TYPE 2
#define REDIRECT_SNAT_REPLAY 3
#define REDIRECT_DNAT_REPLAY 4
//maat plugin ex data
struct redirect_plugin_ex_data
{
int addr_type;
char spoofing_ip[INET6_ADDRSTRLEN];
};
//redirect htable data
struct redirect_htable_data
{
int nat_type;
int addr_type;
unsigned int ipv4;
char ipv6[IPV6_ADDR_LEN];
};
struct redirect_serdef_info
{
int ip_pool_len;
int nat_type_len;
char ip_pool[REDIRECT_SERDEF_LEN];
char nat_type[REDIRECT_SERDEF_LEN];
};
int redirect_search_htable(unsigned char addr_type,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol);
char process_redirect_pending(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir);
char process_redirect_data(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir);
char process_redirect_close(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir);
void plugin_EX_new_cb(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp);
void plugin_EX_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp);
void plugin_EX_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA *to, MAAT_PLUGIN_EX_DATA *from, long argl, void *argp);
int kni_init_redirect_htable();
#endif

View File

@@ -188,7 +188,25 @@ int kni_build_send_ipv6(unsigned char dir,int thread_seq,struct kni_ipv6_hdr* ip
}
int replace_sendlog(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,char* orginal,char* replace)
{
struct kni_log log_msg;
char content[1024]={0};
if(strlen(orginal)+strlen(replace)+2>1024)
{
return 0;
}
sprintf(content,"%s->%s",orginal,replace);
log_msg.stream = pstream;
log_msg.result = pmeinfo->maat_result;
log_msg.result_num = pmeinfo->maat_result_num;
kni_send_log(&log_msg,(char*)"replace",content);
return 0;
}
char kni_process_replace(unsigned char dir,int thread_seq,const struct streaminfo* pstream,const void* a_packet,struct kni_pme_info* pmeinfo)
{
@@ -202,7 +220,6 @@ char kni_process_replace(unsigned char dir,int thread_seq,const struct streaminf
// char ret = APP_STATE_DROPPKT | APP_STATE_DROPME;
char ret = APP_STATE_DROPPKT | APP_STATE_GIVEME;
struct kni_log log_msg;
struct kni_replace_info replace_info;
@@ -214,11 +231,6 @@ char kni_process_replace(unsigned char dir,int thread_seq,const struct streaminf
return APP_STATE_DROPME;
}
log_msg.stream = pstream;
log_msg.result = pmeinfo->maat_result;
log_msg.result_num = pmeinfo->maat_result_num;
kni_send_log(&log_msg);
kni_log_debug(RLOG_LV_FATAL,(char*)"REPLACE",a_packet,(char*)"config id:%d,original:%s,replace:%s",pmeinfo->cfg_id,replace_info.find,replace_info.replace);
if(*(char*)a_packet == 0x45)

View File

@@ -118,7 +118,7 @@ error_out:
return NULL;
}
int kni_send_log(const struct kni_log* log_msg)
int kni_send_log(const struct kni_log* log_msg,char* user_region,char* content)
{
if(g_kni_switch_info.send_log_switch == 0)
{
@@ -178,7 +178,15 @@ int kni_send_log(const struct kni_log* log_msg)
cJSON_AddStringToObject(common_obj, "cap_ip", g_kni_sendlog->local_ip_str);
cJSON_AddNumberToObject(common_obj, "entrance_id", g_kni_sendlog->entry_id);
cJSON_AddNumberToObject(common_obj, "device_id", 0);
cJSON_AddStringToObject(common_obj, "user_region", "null");
if(user_region !=NULL)
{
cJSON_AddStringToObject(common_obj, "user_region", user_region);
cJSON_AddStringToObject(common_obj, "version", content);
}
else
{
cJSON_AddStringToObject(common_obj, "user_region", "null");
}
for(size_t i=0; i<log_msg->result_num; i++)
{

View File

@@ -28,7 +28,6 @@ struct kni_logger
struct kni_logger* kni_sendlog_init(const char* profile, const char* section, void* local_logger);
//return 0 if SUCCESS, otherwise return -1
int kni_send_log(const struct kni_log* log_msg);
int kni_send_log(const struct kni_log* log_msg,char* user_region,char* content);