273 lines
7.5 KiB
C
273 lines
7.5 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include "kni_sendlog.h"
|
|
#include "kni_replace.h"
|
|
#include "kni_entry.h"
|
|
|
|
|
|
|
|
extern "C" int sendpacket_do_checksum(unsigned char* buf,int protocol,int len);
|
|
|
|
|
|
|
|
int kni_get_replace(int cfg_id,int ser_def_len,char* service_defined,struct kni_replace_info* replace_info)
|
|
{
|
|
int original_len =0;
|
|
int replace_len = 0;
|
|
char* original = NULL;
|
|
char* replace = NULL;
|
|
char* tmp = NULL;
|
|
|
|
tmp = kni_memncasemem(service_defined, ser_def_len,(char*)"zone=pkt_payload;substitute=", strlen("zone=pkt_payload;substitute="));
|
|
if(tmp == NULL)
|
|
{
|
|
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"REPLACE","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined);
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
original = kni_memncasemem(service_defined, ser_def_len,(char*)"/", strlen("/"));
|
|
if(original == NULL)
|
|
{
|
|
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"REPLACE","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined);
|
|
return -1;
|
|
}
|
|
|
|
original += 1;
|
|
original_len = strlen(original);
|
|
|
|
replace = kni_memncasemem(original+1,original_len-1,(char*)"/", strlen("/"));
|
|
if(replace == NULL)
|
|
{
|
|
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"REPLACE","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined);
|
|
return -1;
|
|
}
|
|
|
|
replace += 1;
|
|
replace_len = strlen(replace);
|
|
|
|
replace_info->original_len = replace - original -1;
|
|
assert((int)sizeof(replace_info->find)>=replace_info->original_len);
|
|
memcpy(replace_info->find,original,replace_info->original_len);
|
|
|
|
replace_info->replace_len = replace_len;
|
|
assert((int)sizeof(replace_info->replace)>=replace_info->replace_len);
|
|
memcpy(replace_info->replace,replace,replace_info->replace_len);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
int kni_build_send_ipv4(unsigned char dir,int thread_seq,struct ip* a_packet,struct kni_pme_info* pmeinfo,struct kni_replace_info* replace_info)
|
|
{
|
|
// char ret = APP_STATE_DROPPKT | APP_STATE_DROPME;
|
|
char ret = APP_STATE_DROPPKT | APP_STATE_GIVEME;
|
|
|
|
struct ip* iphdr = NULL;
|
|
struct kni_udp_hdr* udphdr = NULL;
|
|
|
|
char* payload = ((char*)a_packet+4*(a_packet->ip_hl));
|
|
unsigned short iplen = ntohs(a_packet->ip_len);
|
|
unsigned short udplen = 0;
|
|
|
|
int payload_len = iplen - 4*(a_packet->ip_hl);
|
|
|
|
char* pos = NULL;
|
|
char* sendbuf = NULL;
|
|
unsigned short sendbuf_len = 0;
|
|
int tmp_len = 0;
|
|
|
|
pos = (char*)memmem(payload, payload_len,(replace_info->find), replace_info->original_len);
|
|
if(pos != NULL)
|
|
{
|
|
sendbuf_len = iplen - replace_info->original_len + replace_info->replace_len;
|
|
sendbuf = (char*)malloc(sendbuf_len);
|
|
|
|
memcpy(sendbuf,(char*)a_packet,(pos-(char*)a_packet));
|
|
tmp_len += pos-(char*)a_packet;
|
|
|
|
memcpy(sendbuf+tmp_len,replace_info->replace,replace_info->replace_len);
|
|
tmp_len += replace_info->replace_len;
|
|
|
|
memcpy(sendbuf+tmp_len,(pos+replace_info->original_len),sendbuf_len-tmp_len);
|
|
|
|
iphdr = (struct ip*)sendbuf;
|
|
iphdr->ip_len = ntohs(sendbuf_len);
|
|
|
|
// if(iphdr->ip_p == PROTO_TYPE_UDP)
|
|
{
|
|
udphdr = (struct kni_udp_hdr*)(sendbuf + 4*(iphdr->ip_hl));
|
|
udplen = ntohs(udphdr->uh_ulen);
|
|
udphdr->uh_ulen = htons(udplen - replace_info->original_len + replace_info->replace_len);
|
|
}
|
|
|
|
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_UDP,(sendbuf_len-4*(iphdr->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;
|
|
}
|
|
else
|
|
{
|
|
ret = APP_STATE_FAWPKT | APP_STATE_GIVEME;
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int kni_build_send_ipv6(unsigned char dir,int thread_seq,struct kni_ipv6_hdr* ipv6_hdr,struct kni_pme_info* pmeinfo,struct kni_replace_info* replace_info)
|
|
{
|
|
/*
|
|
char ret = APP_STATE_DROPPKT | APP_STATE_DROPME;
|
|
|
|
return ret;
|
|
*/
|
|
|
|
// char ret = APP_STATE_DROPPKT | APP_STATE_DROPME;
|
|
if((ipv6_hdr == NULL) || (ipv6_hdr->ip6_nex_hdr != NEXTHDR_UDP))
|
|
{
|
|
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"kni_build_send_ipv6():ipv6_hdr->ip6_nex_hdr != NEXTHDR_UDP");
|
|
return APP_STATE_DROPPKT | APP_STATE_DROPME;
|
|
}
|
|
|
|
char ret = APP_STATE_DROPPKT | APP_STATE_GIVEME;
|
|
|
|
struct kni_ipv6_hdr* send_ipv6_hdr=NULL;
|
|
struct kni_udp_hdr* send_udphdr =NULL;
|
|
unsigned short send_udplen = 0;
|
|
|
|
char* payload = ((char*)((unsigned char*)ipv6_hdr + sizeof(struct kni_ipv6_hdr)));
|
|
int payload_len = ntohs(ipv6_hdr->ip6_payload_len);
|
|
int iplen = ntohs(ipv6_hdr->ip6_payload_len) + sizeof(struct kni_ipv6_hdr);
|
|
|
|
|
|
char* pos = NULL;
|
|
char* sendbuf = NULL;
|
|
unsigned short sendbuf_len = 0;
|
|
int tmp_len = 0;
|
|
|
|
pos = (char*)memmem(payload, payload_len,(replace_info->find), replace_info->original_len);
|
|
if(pos != NULL)
|
|
{
|
|
sendbuf_len = iplen - replace_info->original_len + replace_info->replace_len;
|
|
sendbuf = (char*)malloc(sendbuf_len);
|
|
|
|
memcpy(sendbuf,(char*)ipv6_hdr,(pos-(char*)ipv6_hdr));
|
|
tmp_len += pos-(char*)ipv6_hdr;
|
|
|
|
memcpy(sendbuf+tmp_len,replace_info->replace,replace_info->replace_len);
|
|
tmp_len += replace_info->replace_len;
|
|
|
|
memcpy(sendbuf+tmp_len,(pos+replace_info->original_len),sendbuf_len-tmp_len);
|
|
|
|
send_ipv6_hdr = (struct kni_ipv6_hdr*)sendbuf;
|
|
send_ipv6_hdr->ip6_payload_len = ntohs(sendbuf_len)-sizeof(struct kni_ipv6_hdr);
|
|
|
|
// if(iphdr->ip_p == PROTO_TYPE_UDP)
|
|
{
|
|
send_udphdr = (struct kni_udp_hdr*)(sendbuf + sizeof(struct kni_ipv6_hdr));
|
|
send_udplen = ntohs(send_udphdr->uh_ulen);
|
|
send_udphdr->uh_ulen = htons(send_udplen - replace_info->original_len + replace_info->replace_len);
|
|
}
|
|
|
|
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_UDP,(sendbuf_len-sizeof(struct kni_ipv6_hdr)));
|
|
// sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_IP,sizeof(struct ip));
|
|
|
|
MESA_sendpacket_iplayer(thread_seq,sendbuf,sendbuf_len,dir);
|
|
|
|
free(sendbuf);
|
|
sendbuf = NULL;
|
|
}
|
|
else
|
|
{
|
|
ret = APP_STATE_FAWPKT | APP_STATE_GIVEME;
|
|
}
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
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)
|
|
{
|
|
if(g_kni_switch_info.replace_switch == 0)
|
|
{
|
|
return APP_STATE_DROPME;
|
|
}
|
|
|
|
|
|
kni_filestate2_set(thread_seq,FS_REPLACE_UDP,0,1);
|
|
|
|
// char ret = APP_STATE_DROPPKT | APP_STATE_DROPME;
|
|
char ret = APP_STATE_DROPPKT | APP_STATE_GIVEME;
|
|
|
|
struct kni_replace_info replace_info;
|
|
memset(&replace_info,0,sizeof(struct kni_replace_info));
|
|
|
|
if(kni_get_replace(pmeinfo->cfg_id,pmeinfo->ser_def_len,pmeinfo->service_defined,&replace_info) < 0)
|
|
{
|
|
kni_log_debug(RLOG_LV_FATAL,(char*)"REPLACE",a_packet,(char*)"kni_get_replace error");
|
|
return APP_STATE_DROPME;
|
|
}
|
|
|
|
|
|
if(*(char*)a_packet == 0x45)
|
|
{
|
|
ret = kni_build_send_ipv4(dir,thread_seq,(struct ip*)a_packet,pmeinfo,&replace_info);
|
|
}
|
|
else
|
|
{
|
|
ret = kni_build_send_ipv6(dir,thread_seq,(struct kni_ipv6_hdr*)a_packet,pmeinfo,&replace_info);
|
|
}
|
|
|
|
|
|
if(ret & APP_STATE_DROPPKT)
|
|
{
|
|
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);
|
|
replace_sendlog(pstream, pmeinfo, replace_info.find,replace_info.replace);
|
|
}
|
|
|
|
|
|
//20181030 modify for muti replace
|
|
Maat_clean_status(&(pmeinfo->mid));
|
|
pmeinfo->ipsscan_action = KNI_ACTION_NONE;
|
|
//end
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|