#include #include #include #include #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; } return ret; } int kni_build_send_ipv6(unsigned char dir,int thread_seq,struct kni_ipv6_hdr* a_packet,struct kni_pme_info* pmeinfo,struct kni_replace_info* replace_info) { char ret = APP_STATE_DROPPKT | APP_STATE_DROPME; return ret; } char kni_process_replace(unsigned char dir,int thread_seq,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,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; } 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) { 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); } //20181030 modify for muti replace Maat_clean_status(&(pmeinfo->mid)); pmeinfo->ipsscan_action = KNI_ACTION_NONE; //end return ret; }