This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
tango-kni/kni_replace.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;
}