diff --git a/Makefile b/Makefile index 9e9c3e4..117c2da 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/bin/kniconf/kni.conf b/bin/kniconf/kni.conf index 67c2fac..3a4a75a 100644 --- a/bin/kniconf/kni.conf +++ b/bin/kniconf/kni.conf @@ -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 diff --git a/bin/kniconf/maat_table_info.conf b/bin/kniconf/maat_table_info.conf index 0f98f97..c8cd9d0 100644 --- a/bin/kniconf/maat_table_info.conf +++ b/bin/kniconf/maat_table_info.conf @@ -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} -- diff --git a/bin/kniconf/maat_test.json b/bin/kniconf/maat_test.json index 66d2678..e144d6a 100644 --- a/bin/kniconf/maat_test.json +++ b/bin/kniconf/maat_test.json @@ -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" + ] + } + ] + } diff --git a/kni_comm.c b/kni_comm.c index 9ad72ff..30d82d2 100644 --- a/kni_comm.c +++ b/kni_comm.c @@ -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;iaction == 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; diff --git a/kni_entry.h b/kni_entry.h index 03e6928..f3b82be 100644 --- a/kni_entry.h +++ b/kni_entry.h @@ -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 diff --git a/kni_ratelimit.c b/kni_ratelimit.c index fe566c6..f68c42f 100644 --- a/kni_ratelimit.c +++ b/kni_ratelimit.c @@ -1,6 +1,8 @@ #include #include #include +#include + #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); } diff --git a/kni_redirect.c b/kni_redirect.c new file mode 100644 index 0000000..9bd3512 --- /dev/null +++ b/kni_redirect.c @@ -0,0 +1,638 @@ +#include +#include +#include +#include +#include + + +#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; + +} + + + + diff --git a/kni_redirect.h b/kni_redirect.h new file mode 100644 index 0000000..d6f3c26 --- /dev/null +++ b/kni_redirect.h @@ -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 + diff --git a/kni_replace.c b/kni_replace.c index 88b104d..a89fa17 100644 --- a/kni_replace.c +++ b/kni_replace.c @@ -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) diff --git a/kni_sendlog.c b/kni_sendlog.c index 441bad0..77e29c6 100644 --- a/kni_sendlog.c +++ b/kni_sendlog.c @@ -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; iresult_num; i++) { diff --git a/kni_sendlog.h b/kni_sendlog.h index d105c63..939950c 100644 --- a/kni_sendlog.h +++ b/kni_sendlog.h @@ -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);