683 lines
19 KiB
C
683 lines
19 KiB
C
#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;
|
|
struct kni_udp_hdr* udphdr=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;
|
|
|
|
htable_key_v4.saddr=(ipv4_hdr->ip_src).s_addr;
|
|
htable_key_v4.daddr=(ipv4_hdr->ip_dst).s_addr;
|
|
|
|
if(protocol==PROTO_TYPE_TCP)
|
|
{
|
|
tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
|
|
htable_key_v4.source=tcphdr->th_sport;
|
|
htable_key_v4.dest=tcphdr->th_dport;
|
|
}
|
|
else if(protocol == PROTO_TYPE_UDP)
|
|
{
|
|
udphdr=(struct kni_udp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
|
|
htable_key_v4.source=udphdr->uh_sport;
|
|
htable_key_v4.dest=udphdr->uh_dport;
|
|
}
|
|
else
|
|
{
|
|
htable_key_v4.source=0;
|
|
htable_key_v4.dest=0;
|
|
}
|
|
|
|
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;
|
|
|
|
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));
|
|
|
|
if(protocol==PROTO_TYPE_TCP)
|
|
{
|
|
// tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
|
|
tcphdr =(struct kni_tcp_hdr*)( (unsigned char*)ipv6_hdr + sizeof(struct kni_ipv6_hdr));
|
|
htable_key_v6.source=tcphdr->th_sport;
|
|
htable_key_v6.dest=tcphdr->th_dport;
|
|
}
|
|
else if(protocol == PROTO_TYPE_UDP)
|
|
{
|
|
// udphdr=(struct kni_udp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
|
|
udphdr==(struct kni_tcp_hdr*)( (unsigned char*)ipv6_hdr + sizeof(struct kni_ipv6_hdr));
|
|
htable_key_v6.source=udphdr->uh_sport;
|
|
htable_key_v6.dest=udphdr->uh_dport;
|
|
}
|
|
else
|
|
{
|
|
htable_key_v6.source=0;
|
|
htable_key_v6.dest=0;
|
|
}
|
|
|
|
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_search_htable",a_packet,"search htable_data succ!");
|
|
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 kni_udp_hdr* udphdr=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;
|
|
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
|
|
|
|
if(protocol==PROTO_TYPE_TCP)
|
|
{
|
|
tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
|
|
htable_key_v4.source=tcphdr->th_dport;
|
|
htable_key_v4.dest=tcphdr->th_sport;
|
|
}
|
|
else if(protocol == PROTO_TYPE_UDP)
|
|
{
|
|
udphdr=(struct kni_udp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
|
|
htable_key_v4.source=udphdr->uh_dport;
|
|
htable_key_v4.dest=udphdr->uh_sport;
|
|
}
|
|
else
|
|
{
|
|
htable_key_v4.source=0;
|
|
htable_key_v4.dest=0;
|
|
}
|
|
|
|
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;
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
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));
|
|
|
|
}
|
|
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;
|
|
}
|
|
|
|
|
|
if(protocol==PROTO_TYPE_TCP)
|
|
{
|
|
tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
|
|
htable_key_v6.source=tcphdr->th_dport;
|
|
htable_key_v6.dest=tcphdr->th_sport;
|
|
}
|
|
else if(protocol == PROTO_TYPE_UDP)
|
|
{
|
|
udphdr=(struct kni_udp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
|
|
htable_key_v6.source=udphdr->uh_dport;
|
|
htable_key_v6.dest=udphdr->uh_sport;
|
|
}
|
|
else
|
|
{
|
|
htable_key_v6.source=0;
|
|
htable_key_v6.dest=0;
|
|
}
|
|
|
|
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 ret = sscanf(service_defined, "nat_type=%[^;];spoofing_ip_pool=%[^\n]", out->nat_type, out->ip_pool);
|
|
assert(ret == 2);
|
|
return 0;
|
|
}
|
|
static int get_column_pos(const char* line, int column_seq, size_t *offset, size_t *len)
|
|
{
|
|
const char* seps=" \t";
|
|
char* saveptr=NULL, *subtoken=NULL, *str=NULL;
|
|
char* dup_line = (char *)malloc(strlen(line) + 1);
|
|
strcpy(dup_line, line);
|
|
|
|
int i=0, ret=-1;
|
|
for (str = dup_line; ; str = NULL)
|
|
{
|
|
subtoken = strtok_r(str, seps, &saveptr);
|
|
if (subtoken == NULL)
|
|
break;
|
|
if(i==column_seq-1)
|
|
{
|
|
*offset=subtoken-dup_line;
|
|
*len=strlen(subtoken);
|
|
ret=0;
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
free(dup_line);
|
|
return ret;
|
|
}
|
|
|
|
|
|
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 ret = 0;
|
|
size_t offset=0, len=0;
|
|
*ad=NULL;
|
|
ret=get_column_pos(table_line, 2, &offset, &len);
|
|
if(ret<0)
|
|
{
|
|
return;
|
|
}
|
|
sscanf(table_line+offset, "%d", &(add_data->addr_type));
|
|
ret=get_column_pos(table_line, 4, &offset, &len);
|
|
if(ret<0)
|
|
{
|
|
return;
|
|
}
|
|
assert(len<=sizeof(add_data->spoofing_ip));
|
|
strncpy(add_data->spoofing_ip, table_line+offset, len);
|
|
*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_pending",a_packet,"content:%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(strcasecmp(redirect_args.nat_type,"snat") == 0)
|
|
{
|
|
pmeinfo->redirect_info.nat_type=REDIRECT_SNAT_TYPE;
|
|
}
|
|
else if(strcasecmp(redirect_args.nat_type,"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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|